summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/SConscript7
-rw-r--r--src/gallium/auxiliary/Makefile4
-rw-r--r--src/gallium/auxiliary/SConscript4
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.c21
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h16
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c83
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_decompose.h40
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h38
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c158
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.c20
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.h4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.c132
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.c15
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c41
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c935
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c164
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h50
-rw-r--r--src/gallium/auxiliary/target-helpers/wrap_screen.c65
-rw-r--r--src/gallium/auxiliary/target-helpers/wrap_screen.h16
-rw-r--r--src/gallium/auxiliary/util/u_blit.c16
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c23
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h8
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c12
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c1
-rw-r--r--src/gallium/auxiliary/util/u_format.h25
-rw-r--r--src/gallium/auxiliary/util/u_format_pack.py209
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py10
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py4
-rw-r--r--src/gallium/auxiliary/util/u_format_tests.c544
-rw-r--r--src/gallium/auxiliary/util/u_format_tests.h69
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c13
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c16
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c31
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h2
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c126
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h4
-rw-r--r--src/gallium/docs/source/context.rst2
-rw-r--r--src/gallium/docs/source/cso/velems.rst24
-rw-r--r--src/gallium/drivers/cell/ppu/Makefile1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.c118
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.h (renamed from src/gallium/drivers/cell/ppu/cell_winsys.h)42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c66
-rw-r--r--src/gallium/drivers/cell/ppu/cell_fence.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_public.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c49
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.h22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c5
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c18
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c128
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h17
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.h3
-rw-r--r--src/gallium/drivers/failover/fo_state.c65
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c10
-rw-r--r--src/gallium/drivers/i915/i915_context.h15
-rw-r--r--src/gallium/drivers/i915/i915_debug_fp.c1
-rw-r--r--src/gallium/drivers/i915/i915_screen.c6
-rw-r--r--src/gallium/drivers/i915/i915_state.c38
-rw-r--r--src/gallium/drivers/i915/i915_texture.c116
-rw-r--r--src/gallium/drivers/i915/intel_winsys.h39
-rw-r--r--src/gallium/drivers/i965/brw_context.h5
-rw-r--r--src/gallium/drivers/i965/brw_draw_upload.c208
-rw-r--r--src/gallium/drivers/i965/brw_pipe_vertex.c247
-rw-r--r--src/gallium/drivers/i965/brw_screen.c6
-rw-r--r--src/gallium/drivers/i965/brw_screen.h9
-rw-r--r--src/gallium/drivers/i965/brw_screen_texture.c237
-rw-r--r--src/gallium/drivers/i965/brw_structs.h4
-rw-r--r--src/gallium/drivers/i965/brw_winsys.h32
-rw-r--r--src/gallium/drivers/identity/id_context.c54
-rw-r--r--src/gallium/drivers/identity/id_drm.c59
-rw-r--r--src/gallium/drivers/identity/id_screen.c68
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_public.h10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c31
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c129
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c35
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c49
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c51
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h13
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c75
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h12
-rw-r--r--src/gallium/drivers/nouveau/nouveau_util.h100
-rw-r--r--src/gallium/drivers/nv30/nv30_context.h8
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c7
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c34
-rw-r--r--src/gallium/drivers/nv30/nv30_state.h4
-rw-r--r--src/gallium/drivers/nv30/nv30_vbo.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h9
-rw-r--r--src/gallium/drivers/nv40/nv40_miptree.c7
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c34
-rw-r--r--src/gallium/drivers/nv40/nv40_state.h4
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c8
-rw-r--r--src/gallium/drivers/nv50/Makefile3
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c43
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h99
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c40
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c326
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c34
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c39
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c436
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c35
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c1113
-rw-r--r--src/gallium/drivers/r300/Makefile3
-rw-r--r--src/gallium/drivers/r300/SConscript1
-rw-r--r--src/gallium/drivers/r300/r300_blit.c1
-rw-r--r--src/gallium/drivers/r300/r300_context.c21
-rw-r--r--src/gallium/drivers/r300/r300_context.h36
-rw-r--r--src/gallium/drivers/r300/r300_emit.c44
-rw-r--r--src/gallium/drivers/r300/r300_flush.c6
-rw-r--r--src/gallium/drivers/r300/r300_fs.c1
-rw-r--r--src/gallium/drivers/r300/r300_render.c43
-rw-r--r--src/gallium/drivers/r300/r300_screen.c80
-rw-r--r--src/gallium/drivers/r300/r300_screen.h22
-rw-r--r--src/gallium/drivers/r300/r300_state.c342
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c200
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h53
-rw-r--r--src/gallium/drivers/r300/r300_texture.c135
-rw-r--r--src/gallium/drivers/r300/r300_texture.h6
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c270
-rw-r--r--src/gallium/drivers/r300/r300_transfer.h31
-rw-r--r--src/gallium/drivers/r300/r300_vs.c163
-rw-r--r--src/gallium/drivers/r300/r300_vs.h13
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h5
-rw-r--r--src/gallium/drivers/softpipe/Makefile4
-rw-r--r--src/gallium/drivers/softpipe/SConscript4
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.c118
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.h (renamed from src/gallium/state_trackers/egl/x11/sw_winsys.h)41
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c97
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_public.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c52
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h17
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c18
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c36
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c126
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h19
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.c245
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.h73
-rw-r--r--src/gallium/drivers/svga/svga_context.h8
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c38
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c133
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.h2
-rw-r--r--src/gallium/drivers/svga/svga_state_need_swtnl.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c13
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c8
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c4
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c4
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h33
-rw-r--r--src/gallium/drivers/trace/tr_context.c91
-rw-r--r--src/gallium/drivers/trace/tr_drm.c67
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c1
-rw-r--r--src/gallium/drivers/trace/tr_public.h45
-rw-r--r--src/gallium/drivers/trace/tr_screen.c85
-rw-r--r--src/gallium/drivers/trace/tr_screen.h3
-rw-r--r--src/gallium/include/pipe/p_compiler.h5
-rw-r--r--src/gallium/include/pipe/p_context.h9
-rw-r--r--src/gallium/include/pipe/p_defines.h5
-rw-r--r--src/gallium/include/pipe/p_screen.h49
-rw-r--r--src/gallium/include/pipe/p_state.h11
-rw-r--r--src/gallium/include/state_tracker/drm_api.h57
-rw-r--r--src/gallium/include/state_tracker/sw_winsys.h (renamed from src/gallium/drivers/llvmpipe/lp_winsys.h)47
-rw-r--r--src/gallium/include/state_tracker/xlib_sw_winsys.h29
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c12
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c8
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c24
-rw-r--r--src/gallium/state_trackers/egl/common/native.h3
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h2
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c14
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c9
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c13
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h3
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c270
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript2
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c116
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h18
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_public.h (renamed from src/gallium/state_trackers/glx/xlib/xm_winsys.h)16
-rw-r--r--src/gallium/state_trackers/python/SConscript31
-rw-r--r--src/gallium/state_trackers/python/p_context.i8
-rw-r--r--src/gallium/state_trackers/python/st_device.c52
-rw-r--r--src/gallium/state_trackers/python/st_device.h9
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c16
-rw-r--r--src/gallium/state_trackers/python/st_llvmpipe_winsys.c141
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c55
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h14
-rw-r--r--src/gallium/state_trackers/vega/Makefile2
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c2
-rw-r--r--src/gallium/state_trackers/vega/polygon.c4
-rw-r--r--src/gallium/state_trackers/vega/renderer.c5
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c8
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h1
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c6
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h3
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c14
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c19
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c10
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c13
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h1
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c2
-rw-r--r--src/gallium/targets/Makefile12
-rw-r--r--src/gallium/targets/SConscript16
-rw-r--r--src/gallium/targets/libgl-gdi/SConscript51
-rw-r--r--src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c124
-rw-r--r--src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c124
-rw-r--r--src/gallium/targets/libgl-xlib/Makefile100
-rw-r--r--src/gallium/targets/libgl-xlib/SConscript69
-rw-r--r--src/gallium/targets/libgl-xlib/xlib.c (renamed from src/gallium/winsys/xlib/xlib.c)114
-rw-r--r--src/gallium/winsys/drm/Makefile.egl9
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_api.c126
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c75
-rw-r--r--src/gallium/winsys/drm/i965/xlib/xlib_i965.c2
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c96
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c63
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c74
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c71
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c121
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h22
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_winsys.h12
-rw-r--r--src/gallium/winsys/drm/radeon/python/README15
-rw-r--r--src/gallium/winsys/drm/radeon/python/SConscript33
-rw-r--r--src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c132
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dri.c605
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dri.h123
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dristr.h389
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c79
-rw-r--r--src/gallium/winsys/gdi/SConscript50
-rw-r--r--src/gallium/winsys/gdi/gdi_softpipe_winsys.c318
-rw-r--r--src/gallium/winsys/gdi/gdi_sw_winsys.c (renamed from src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c)162
-rw-r--r--src/gallium/winsys/gdi/gdi_sw_winsys.h16
-rw-r--r--src/gallium/winsys/null/Makefile16
-rw-r--r--src/gallium/winsys/null/SConscript21
-rw-r--r--src/gallium/winsys/null/null_sw_winsys.c124
-rw-r--r--src/gallium/winsys/null/null_sw_winsys.h40
-rw-r--r--src/gallium/winsys/xlib/Makefile94
-rw-r--r--src/gallium/winsys/xlib/SConscript71
-rw-r--r--src/gallium/winsys/xlib/xlib.h13
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_context.c209
-rw-r--r--src/gallium/winsys/xlib/xlib_cell.c401
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c508
-rw-r--r--src/gallium/winsys/xlib/xlib_sw_winsys.c (renamed from src/gallium/winsys/xlib/xlib_llvmpipe.c)261
-rw-r--r--src/gallium/winsys/xlib/xmesa.h424
-rw-r--r--src/gallium/winsys/xlib/xmesa_x.h86
275 files changed, 8036 insertions, 9478 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index d56c5c8461..c833d83e65 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -7,6 +7,9 @@ SConscript('auxiliary/SConscript')
for driver in env['drivers']:
SConscript(os.path.join('drivers', driver, 'SConscript'))
+# Needed by some state trackers
+SConscript('winsys/null/SConscript')
+
SConscript('state_trackers/python/SConscript')
if platform != 'embedded':
SConscript('state_trackers/glx/xlib/SConscript')
@@ -15,3 +18,7 @@ if platform != 'embedded':
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
+
+SConscript('winsys/SConscript')
+
+SConscript('targets/SConscript')
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 1d0930e024..0ac18426d9 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -107,6 +107,7 @@ C_SOURCES = \
util/u_draw_quad.c \
util/u_format_access.c \
util/u_format_table.c \
+ util/u_format_tests.c \
util/u_gen_mipmap.c \
util/u_handle_table.c \
util/u_hash_table.c \
@@ -130,7 +131,8 @@ C_SOURCES = \
vl/vl_mpeg12_mc_renderer.c \
vl/vl_compositor.c \
vl/vl_csc.c \
- vl/vl_shader_build.c
+ vl/vl_shader_build.c \
+ target-helpers/wrap_screen.c
GALLIVM_SOURCES = \
gallivm/lp_bld_alpha.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index f365c4bbdd..2be16776fb 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -7,6 +7,8 @@ env.Append(CPPPATH = [
'util',
])
+env.Tool('udis86')
+
env.CodeGenerate(
target = 'indices/u_indices_gen.c',
script = 'indices/u_indices_gen.py',
@@ -149,6 +151,7 @@ source = [
'util/u_draw_quad.c',
'util/u_format_access.c',
'util/u_format_table.c',
+ 'util/u_format_tests.c',
'util/u_gen_mipmap.c',
'util/u_handle_table.c',
'util/u_hash.c',
@@ -172,6 +175,7 @@ source = [
'vl/vl_compositor.c',
'vl/vl_csc.c',
'vl/vl_shader_build.c',
+ 'target-helpers/wrap_screen.c',
]
if drawllvm:
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index a6a07e72c2..900c64df4b 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -43,6 +43,7 @@ struct cso_cache {
struct cso_hash *vs_hash;
struct cso_hash *rasterizer_hash;
struct cso_hash *sampler_hash;
+ struct cso_hash *velements_hash;
int max_size;
cso_sanitize_callback sanitize_cb;
@@ -108,6 +109,9 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
+ case CSO_VELEMENTS:
+ hash = sc->velements_hash;
+ break;
}
return hash;
@@ -161,6 +165,13 @@ static void delete_vs_state(void *state, void *data)
FREE(state);
}
+static void delete_velements(void *state, void *data)
+{
+ struct cso_velements *cso = (struct cso_velements *)state;
+ if (cso->delete_state)
+ cso->delete_state(cso->context, cso->data);
+ FREE(state);
+}
static INLINE void delete_cso(void *state, enum cso_cache_type type)
{
@@ -183,6 +194,9 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
case CSO_VERTEX_SHADER:
delete_vs_state(state, 0);
break;
+ case CSO_VELEMENTS:
+ delete_velements(state, 0);
+ break;
default:
assert(0);
FREE(state);
@@ -294,6 +308,7 @@ struct cso_cache *cso_cache_create(void)
sc->rasterizer_hash = cso_hash_create();
sc->fs_hash = cso_hash_create();
sc->vs_hash = cso_hash_create();
+ sc->velements_hash = cso_hash_create();
sc->sanitize_cb = sanitize_cb;
sc->sanitize_data = 0;
@@ -325,6 +340,9 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
+ case CSO_VELEMENTS:
+ hash = sc->velements_hash;
+ break;
}
iter = cso_hash_first_node(hash);
@@ -351,6 +369,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0);
cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0);
cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0);
+ cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0);
cso_hash_delete(sc->blend_hash);
cso_hash_delete(sc->sampler_hash);
@@ -358,6 +377,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_hash_delete(sc->rasterizer_hash);
cso_hash_delete(sc->fs_hash);
cso_hash_delete(sc->vs_hash);
+ cso_hash_delete(sc->velements_hash);
FREE(sc);
}
@@ -372,6 +392,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
+ sanitize_hash(sc, sc->velements_hash, CSO_VELEMENTS, sc->max_size);
}
int cso_maximum_cache_size(const struct cso_cache *sc)
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h
index eea60b940b..fb09b83c62 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.h
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.h
@@ -53,6 +53,7 @@
* - rasterizer (old setup)
* - sampler
* - vertex shader
+ * - vertex elements
*
* Things that are not constant state objects include:
* - blend_color
@@ -90,7 +91,8 @@ enum cso_cache_type {
CSO_DEPTH_STENCIL_ALPHA,
CSO_RASTERIZER,
CSO_FRAGMENT_SHADER,
- CSO_VERTEX_SHADER
+ CSO_VERTEX_SHADER,
+ CSO_VELEMENTS
};
typedef void (*cso_state_callback)(void *ctx, void *obj);
@@ -144,6 +146,18 @@ struct cso_sampler {
struct pipe_context *context;
};
+struct cso_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS];
+};
+
+struct cso_velements {
+ struct cso_velems_state state;
+ void *data;
+ cso_state_callback delete_state;
+ struct pipe_context *context;
+};
+
unsigned cso_construct_key(void *item, int item_size);
struct cso_cache *cso_cache_create(void);
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index a7335c340c..6500891a10 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -89,6 +89,7 @@ struct cso_context {
void *rasterizer, *rasterizer_saved;
void *fragment_shader, *fragment_shader_saved, *geometry_shader;
void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
+ void *velements, *velements_saved;
struct pipe_clip_state clip;
struct pipe_clip_state clip_saved;
@@ -174,6 +175,20 @@ static boolean delete_vs_state(struct cso_context *ctx, void *state)
return FALSE;
}
+static boolean delete_vertex_elements(struct cso_context *ctx,
+ void *state)
+{
+ struct cso_velements *cso = (struct cso_velements *)state;
+
+ if (ctx->velements == cso->data)
+ return FALSE;
+
+ if (cso->delete_state)
+ cso->delete_state(cso->context, cso->data);
+ FREE(state);
+ return TRUE;
+}
+
static INLINE boolean delete_cso(struct cso_context *ctx,
void *state, enum cso_cache_type type)
@@ -197,6 +212,9 @@ static INLINE boolean delete_cso(struct cso_context *ctx,
case CSO_VERTEX_SHADER:
return delete_vs_state(ctx, state);
break;
+ case CSO_VELEMENTS:
+ return delete_vertex_elements(ctx, state);
+ break;
default:
assert(0);
FREE(state);
@@ -271,6 +289,7 @@ void cso_release_all( struct cso_context *ctx )
ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
ctx->pipe->bind_fs_state( ctx->pipe, NULL );
ctx->pipe->bind_vs_state( ctx->pipe, NULL );
+ ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
}
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
@@ -1130,7 +1149,6 @@ void cso_restore_geometry_shader(struct cso_context *ctx)
ctx->geometry_shader_saved = NULL;
}
-
/* clip state */
static INLINE void
@@ -1180,3 +1198,66 @@ cso_restore_clip(struct cso_context *ctx)
ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved);
}
}
+
+enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *states)
+{
+ unsigned key_size, hash_key;
+ struct cso_hash_iter iter;
+ void *handle;
+ struct cso_velems_state velems_state;
+
+ /* need to include the count into the stored state data too.
+ Otherwise first few count pipe_vertex_elements could be identical even if count
+ is different, and there's no guarantee the hash would be different in that
+ case neither */
+ key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
+ velems_state.count = count;
+ memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count);
+ hash_key = cso_construct_key((void*)&velems_state, key_size);
+ iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size);
+
+ if (cso_hash_iter_is_null(iter)) {
+ struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
+ if (!cso)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ memcpy(&cso->state, &velems_state, key_size);
+ cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state.velems[0]);
+ cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state;
+ cso->context = ctx->pipe;
+
+ iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
+ if (cso_hash_iter_is_null(iter)) {
+ FREE(cso);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle = cso->data;
+ }
+ else {
+ handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
+ }
+
+ if (ctx->velements != handle) {
+ ctx->velements = handle;
+ ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
+ }
+ return PIPE_OK;
+}
+
+void cso_save_vertex_elements(struct cso_context *ctx)
+{
+ assert(!ctx->velements_saved);
+ ctx->velements_saved = ctx->velements;
+}
+
+void cso_restore_vertex_elements(struct cso_context *ctx)
+{
+ if (ctx->velements != ctx->velements_saved) {
+ ctx->velements = ctx->velements_saved;
+ ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
+ }
+ ctx->velements_saved = NULL;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 251a9a644f..9c16abd28d 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -122,6 +122,12 @@ 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);
+void cso_save_vertex_elements(struct cso_context *ctx);
+void cso_restore_vertex_elements(struct cso_context *ctx);
+
/* These aren't really sensible -- most of the time the api provides
* object semantics for shaders anyway, and the cases where it doesn't
@@ -157,7 +163,6 @@ void cso_save_geometry_shader(struct cso_context *cso);
void cso_restore_geometry_shader(struct cso_context *cso);
-
enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb);
void cso_save_framebuffer(struct cso_context *cso);
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 6d90a6c42f..a8cdc57ad9 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -307,9 +307,8 @@ draw_arrays_instanced(struct draw_context *draw,
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
- debug_printf(" format=%s comps=%u\n",
- util_format_name(draw->pt.vertex_element[i].src_format),
- draw->pt.vertex_element[i].nr_components);
+ debug_printf(" format=%s\n",
+ util_format_name(draw->pt.vertex_element[i].src_format));
}
debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h
index 4ca5b52020..3c44f7c11e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_decompose.h
+++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h
@@ -105,40 +105,20 @@ static void FUNC( ARGS,
case PIPE_PRIM_QUADS:
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 4) {
- QUAD( (i + 1),
- (i + 2),
- (i + 3),
- (i + 0) );
- }
- }
- else {
- for (i = 0; i+3 < count; i += 4) {
- QUAD( (i + 0),
- (i + 1),
- (i + 2),
- (i + 3));
- }
+ for (i = 0; i+3 < count; i += 4) {
+ QUAD( (i + 0),
+ (i + 1),
+ (i + 2),
+ (i + 3));
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 2) {
- QUAD( (i + 1),
- (i + 3),
- (i + 2),
- (i + 0) );
- }
- }
- else {
- for (i = 0; i+3 < count; i += 2) {
- QUAD( (i + 2),
- (i + 0),
- (i + 1),
- (i + 3));
- }
+ for (i = 0; i+3 < count; i += 2) {
+ QUAD( (i + 2),
+ (i + 0),
+ (i + 1),
+ (i + 3));
}
break;
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
index 62822a3d56..7cba8547f1 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
@@ -118,39 +118,21 @@ static void FUNC( struct draw_pt_front_end *frontend,
case PIPE_PRIM_QUADS:
for (i = 0; i+3 < count; i += 4) {
- if (flatfirst) {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3) );
- }
- else {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3) );
- }
+ QUAD( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 3) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i+3 < count; i += 2) {
- if (flatfirst) {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3),
- get_elt(elts, i + 2) );
- }
- else {
- QUAD( vcache,
- get_elt(elts, i + 2),
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3) );
- }
+ QUAD( vcache,
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 3) );
}
break;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 32f9e5201c..f55d2b6d15 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -644,13 +644,26 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) {
/* Mask out the sign bit */
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- unsigned long long absMask = ~(1ULL << (type.width - 1));
- LLVMValueRef mask = lp_build_int_const_scalar(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, "");
- return a;
+ if (type.length == 1) {
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ LLVMTypeRef float_type = LLVMFloatType();
+ unsigned long long absMask = ~(1ULL << (type.width - 1));
+ LLVMValueRef mask = LLVMConstInt(int_type, absMask, 0);
+ a = LLVMBuildBitCast(bld->builder, a, int_type, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildBitCast(bld->builder, a, float_type, "");
+ return a;
+ }
+ else {
+ /* 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));
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+ return a;
+ }
}
if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) {
@@ -753,7 +766,7 @@ lp_build_set_sign(struct lp_build_context *bld,
/**
- * Convert vector of int to vector of float.
+ * Convert vector of (or scalar) int to vector of (or scalar) float.
*/
LLVMValueRef
lp_build_int_to_float(struct lp_build_context *bld,
@@ -764,7 +777,11 @@ lp_build_int_to_float(struct lp_build_context *bld,
assert(type.floating);
/*assert(lp_check_value(type, a));*/
- {
+ if (type.length == 1) {
+ LLVMTypeRef float_type = LLVMFloatType();
+ return LLVMBuildSIToFP(bld->builder, a, float_type, "");
+ }
+ else {
LLVMTypeRef vec_type = lp_build_vec_type(type);
/*LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);*/
LLVMValueRef res;
@@ -866,6 +883,10 @@ lp_build_floor(struct lp_build_context *bld,
assert(type.floating);
+ if (type.length == 1) {
+ return LLVMBuildFPTrunc(bld->builder, a, LLVMFloatType(), "");
+ }
+
if(util_cpu_caps.has_sse4_1)
return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR);
else {
@@ -921,15 +942,24 @@ lp_build_itrunc(struct lp_build_context *bld,
LLVMValueRef a)
{
const struct lp_type type = bld->type;
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(type.floating);
- assert(lp_check_value(type, a));
- return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+ if (type.length == 1) {
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ return LLVMBuildFPTrunc(bld->builder, a, int_type, "");
+ }
+ else {
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ assert(lp_check_value(type, a));
+ return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+ }
}
+/**
+ * Convert float[] to int[] with round().
+ */
LLVMValueRef
lp_build_iround(struct lp_build_context *bld,
LLVMValueRef a)
@@ -939,6 +969,15 @@ lp_build_iround(struct lp_build_context *bld,
LLVMValueRef res;
assert(type.floating);
+
+ if (type.length == 1) {
+ /* scalar float to int */
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ /* XXX we want rounding here! */
+ res = LLVMBuildFPToSI(bld->builder, a, int_type, "");
+ return res;
+ }
+
assert(lp_check_value(type, a));
if(util_cpu_caps.has_sse4_1) {
@@ -981,6 +1020,14 @@ lp_build_ifloor(struct lp_build_context *bld,
LLVMValueRef res;
assert(type.floating);
+
+ if (type.length == 1) {
+ /* scalar float to int */
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ res = LLVMBuildFPToSI(bld->builder, a, int_type, "");
+ return res;
+ }
+
assert(lp_check_value(type, a));
if(util_cpu_caps.has_sse4_1) {
@@ -1207,6 +1254,7 @@ lp_build_polynomial(struct lp_build_context *bld,
unsigned num_coeffs)
{
const struct lp_type type = bld->type;
+ LLVMTypeRef float_type = LLVMFloatType();
LLVMValueRef res = NULL;
unsigned i;
@@ -1216,7 +1264,13 @@ lp_build_polynomial(struct lp_build_context *bld,
__FUNCTION__);
for (i = num_coeffs; i--; ) {
- LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]);
+ LLVMValueRef coeff;
+
+ if (type.length == 1)
+ coeff = LLVMConstReal(float_type, coeffs[i]);
+ else
+ coeff = lp_build_const_scalar(type, coeffs[i]);
+
if(res)
res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
else
@@ -1410,11 +1464,87 @@ lp_build_log2_approx(struct lp_build_context *bld,
}
+/** scalar version of above function */
+static void
+lp_build_float_log2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp,
+ LLVMValueRef *p_floor_log2,
+ LLVMValueRef *p_log2)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef float_type = LLVMFloatType();
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+
+ LLVMValueRef expmask = LLVMConstInt(int_type, 0x7f800000, 0);
+ LLVMValueRef mantmask = LLVMConstInt(int_type, 0x007fffff, 0);
+ LLVMValueRef one = LLVMConstBitCast(bld->one, int_type);
+
+ LLVMValueRef i = NULL;
+ LLVMValueRef exp = NULL;
+ LLVMValueRef mant = NULL;
+ LLVMValueRef logexp = NULL;
+ LLVMValueRef logmant = NULL;
+ LLVMValueRef res = NULL;
+
+ if(p_exp || p_floor_log2 || p_log2) {
+ /* TODO: optimize the constant case */
+ if(LLVMIsConstant(x))
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
+
+ assert(type.floating && type.width == 32);
+
+ i = LLVMBuildBitCast(bld->builder, x, int_type, "");
+
+ /* exp = (float) exponent(x) */
+ exp = LLVMBuildAnd(bld->builder, i, expmask, "");
+ }
+
+ if(p_floor_log2 || p_log2) {
+ LLVMValueRef c23 = LLVMConstInt(int_type, 23, 0);
+ LLVMValueRef c127 = LLVMConstInt(int_type, 127, 0);
+ logexp = LLVMBuildLShr(bld->builder, exp, c23, "");
+ logexp = LLVMBuildSub(bld->builder, logexp, c127, "");
+ logexp = LLVMBuildSIToFP(bld->builder, logexp, float_type, "");
+ }
+
+ if(p_log2) {
+ /* mant = (float) mantissa(x) */
+ mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
+ mant = LLVMBuildOr(bld->builder, mant, one, "");
+ mant = LLVMBuildBitCast(bld->builder, mant, float_type, "");
+
+ logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
+ Elements(lp_build_log2_polynomial));
+
+ /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
+ logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
+
+ res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
+ }
+
+ if(p_exp)
+ *p_exp = exp;
+
+ if(p_floor_log2)
+ *p_floor_log2 = logexp;
+
+ if(p_log2)
+ *p_log2 = res;
+}
+
+
LLVMValueRef
lp_build_log2(struct lp_build_context *bld,
LLVMValueRef x)
{
LLVMValueRef res;
- lp_build_log2_approx(bld, x, NULL, NULL, &res);
+ if (bld->type.length == 1) {
+ lp_build_float_log2_approx(bld, x, NULL, NULL, &res);
+ }
+ else {
+ lp_build_log2_approx(bld, x, NULL, NULL, &res);
+ }
return res;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index c8eaa8c394..8a275fa72f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -221,8 +221,16 @@ lp_build_undef(struct lp_type type)
LLVMValueRef
lp_build_zero(struct lp_type type)
{
- LLVMTypeRef vec_type = lp_build_vec_type(type);
- return LLVMConstNull(vec_type);
+ if (type.length == 1) {
+ if (type.floating)
+ return LLVMConstReal(LLVMFloatType(), 0.0);
+ else
+ return LLVMConstInt(LLVMIntType(type.width), 0, 0);
+ }
+ else {
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ return LLVMConstNull(vec_type);
+ }
}
@@ -264,10 +272,16 @@ lp_build_one(struct lp_type type)
for(i = 1; i < type.length; ++i)
elems[i] = elems[0];
- return LLVMConstVector(elems, type.length);
+ if (type.length == 1)
+ return elems[0];
+ else
+ return LLVMConstVector(elems, type.length);
}
+/**
+ * Build constant-valued vector from a scalar value.
+ */
LLVMValueRef
lp_build_const_scalar(struct lp_type type,
double val)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
index bc83138908..c2f35419ec 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
@@ -308,7 +308,7 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow)
* Note: this function has no dependencies on the flow code and could
* be used elsewhere.
*/
-static LLVMBasicBlockRef
+LLVMBasicBlockRef
lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)
{
LLVMBasicBlockRef current_block;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
index 4c225a0d4f..8bb22543ee 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
@@ -145,7 +145,9 @@ lp_build_else(struct lp_build_if_state *ctx);
void
lp_build_endif(struct lp_build_if_state *ctx);
-
+
+LLVMBasicBlockRef
+lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
#endif /* !LP_BLD_FLOW_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index 2726747eae..fa65895367 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -42,6 +42,26 @@
#include "lp_bld_logic.h"
+/*
+ * XXX
+ *
+ * Selection with vector conditional like
+ *
+ * select <4 x i1> %C, %A, %B
+ *
+ * is valid IR (e.g. llvm/test/Assembler/vector-select.ll), but it is not
+ * supported on any backend.
+ *
+ * Expanding the boolean vector to full SIMD register width, as in
+ *
+ * sext <4 x i1> %C to <4 x i32>
+ *
+ * is valid and supported (e.g., llvm/test/CodeGen/X86/vec_compare.ll), but
+ * it causes assertion failures in LLVM 2.6. It appears to work correctly on
+ * LLVM 2.7.
+ */
+
+
/**
* Build code to compare two values 'a' and 'b' of 'type' using the given func.
* \param func one of PIPE_FUNC_x
@@ -74,6 +94,7 @@ lp_build_compare(LLVMBuilderRef builder,
/* XXX: It is not clear if we should use the ordered or unordered operators */
+#if !defined(HAVE_LLVM) || HAVE_LLVM < 0x0207
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
if(type.width * type.length == 128) {
if(type.floating && util_cpu_caps.has_sse) {
@@ -198,8 +219,9 @@ lp_build_compare(LLVMBuilderRef builder,
return res;
}
- }
+ } /* if (type.width * type.length == 128) */
#endif
+#endif /* HAVE_LLVM < 0x0207 */
if(type.floating) {
LLVMRealPredicate op;
@@ -233,25 +255,29 @@ lp_build_compare(LLVMBuilderRef builder,
return lp_build_undef(type);
}
-#if 0
- /* XXX: Although valid IR, no LLVM target currently support this */
+#if HAVE_LLVM >= 0x0207
cond = LLVMBuildFCmp(builder, op, a, b, "");
- res = LLVMBuildSelect(builder, cond, ones, zeros, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
#else
- debug_printf("%s: warning: using slow element-wise vector comparison\n",
- __FUNCTION__);
res = LLVMGetUndef(int_vec_type);
- for(i = 0; i < type.length; ++i) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- cond = LLVMBuildFCmp(builder, op,
- LLVMBuildExtractElement(builder, a, index, ""),
- LLVMBuildExtractElement(builder, b, index, ""),
- "");
- cond = LLVMBuildSelect(builder, cond,
- LLVMConstExtractElement(ones, index),
- LLVMConstExtractElement(zeros, index),
- "");
- res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ if (type.length == 1) {
+ res = LLVMBuildFCmp(builder, op, a, b, "");
+ }
+ else {
+ debug_printf("%s: warning: using slow element-wise float"
+ " vector comparison\n", __FUNCTION__);
+ for (i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildFCmp(builder, op,
+ LLVMBuildExtractElement(builder, a, index, ""),
+ LLVMBuildExtractElement(builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ }
}
#endif
}
@@ -281,25 +307,30 @@ lp_build_compare(LLVMBuilderRef builder,
return lp_build_undef(type);
}
-#if 0
- /* XXX: Although valid IR, no LLVM target currently support this */
+#if HAVE_LLVM >= 0x0207
cond = LLVMBuildICmp(builder, op, a, b, "");
- res = LLVMBuildSelect(builder, cond, ones, zeros, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
#else
- debug_printf("%s: warning: using slow element-wise int vector comparison\n",
- __FUNCTION__);
res = LLVMGetUndef(int_vec_type);
- for(i = 0; i < type.length; ++i) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- cond = LLVMBuildICmp(builder, op,
- LLVMBuildExtractElement(builder, a, index, ""),
- LLVMBuildExtractElement(builder, b, index, ""),
- "");
- cond = LLVMBuildSelect(builder, cond,
- LLVMConstExtractElement(ones, index),
- LLVMConstExtractElement(zeros, index),
- "");
- res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ if (type.length == 1) {
+ res = LLVMBuildICmp(builder, op, a, b, "");
+ }
+ else {
+ debug_printf("%s: warning: using slow element-wise int"
+ " vector comparison\n", __FUNCTION__);
+
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildICmp(builder, op,
+ LLVMBuildExtractElement(builder, a, index, ""),
+ LLVMBuildExtractElement(builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ }
}
#endif
}
@@ -339,26 +370,31 @@ lp_build_select(struct lp_build_context *bld,
if(a == b)
return a;
- if(type.floating) {
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
- b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+ if (type.length == 1) {
+ res = LLVMBuildSelect(bld->builder, mask, a, b, "");
}
+ else {
+ if(type.floating) {
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+ }
- a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
- /* This often gets translated to PANDN, but sometimes the NOT is
- * pre-computed and stored in another constant. The best strategy depends
- * on available registers, so it is not a big deal -- hopefully LLVM does
- * the right decision attending the rest of the program.
- */
- b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
+ /* This often gets translated to PANDN, but sometimes the NOT is
+ * pre-computed and stored in another constant. The best strategy depends
+ * on available registers, so it is not a big deal -- hopefully LLVM does
+ * the right decision attending the rest of the program.
+ */
+ b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
- res = LLVMBuildOr(bld->builder, a, b, "");
+ res = LLVMBuildOr(bld->builder, a, b, "");
- if(type.floating) {
- LLVMTypeRef vec_type = lp_build_vec_type(type);
- res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ if(type.floating) {
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ }
}
return res;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
index bc360ad77a..4c61d10749 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
@@ -256,7 +256,9 @@ lp_build_pack2(LLVMBuilderRef builder,
LLVMValueRef lo,
LLVMValueRef hi)
{
+#if !(HAVE_LLVM >= 0x0207)
LLVMTypeRef src_vec_type = lp_build_vec_type(src_type);
+#endif
LLVMTypeRef dst_vec_type = lp_build_vec_type(dst_type);
LLVMValueRef shuffle;
LLVMValueRef res;
@@ -272,11 +274,14 @@ lp_build_pack2(LLVMBuilderRef builder,
switch(src_type.width) {
case 32:
if(dst_type.sign) {
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", src_vec_type, lo, hi);
+#endif
}
else {
if (util_cpu_caps.has_sse4_1) {
- /* PACKUSDW is the only instrinsic with a consistent signature */
return lp_build_intrinsic_binary(builder, "llvm.x86.sse41.packusdw", dst_vec_type, lo, hi);
}
else {
@@ -288,9 +293,17 @@ lp_build_pack2(LLVMBuilderRef builder,
case 16:
if(dst_type.sign)
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packsswb.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packsswb.128", src_vec_type, lo, hi);
+#endif
else
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packuswb.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packuswb.128", src_vec_type, lo, hi);
+#endif
break;
default:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 6a026e468e..543fd5fea3 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -62,6 +62,18 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
if(!sampler)
return;
+ /*
+ * We don't copy sampler state over unless it is actually enabled, to avoid
+ * spurious recompiles, as the sampler static state is part of the shader
+ * key.
+ *
+ * Ideally the state tracker or cso_cache module would make all state
+ * canonical, but until that happens it's better to be safe than sorry here.
+ *
+ * XXX: Actually there's much more than can be done here, especially
+ * regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
+ */
+
state->format = texture->format;
state->target = texture->target;
state->pot_width = util_is_pot(texture->width0);
@@ -74,8 +86,12 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->min_img_filter = sampler->min_img_filter;
state->min_mip_filter = sampler->min_mip_filter;
state->mag_img_filter = sampler->mag_img_filter;
+
state->compare_mode = sampler->compare_mode;
- state->compare_func = sampler->compare_func;
+ if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
+ state->compare_func = sampler->compare_func;
+ }
+
state->normalized_coords = sampler->normalized_coords;
state->lod_bias = sampler->lod_bias;
state->min_lod = sampler->min_lod;
@@ -139,15 +155,16 @@ lp_build_gather(LLVMBuilderRef builder,
/**
* Compute the offset of a pixel.
*
- * x, y, y_stride are vectors
+ * x, y, z, y_stride, z_stride are vectors
*/
LLVMValueRef
lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef z_stride)
{
LLVMValueRef x_stride;
LLVMValueRef offset;
@@ -163,6 +180,10 @@ lp_build_sample_offset(struct lp_build_context *bld,
LLVMValueRef y_offset_lo, y_offset_hi;
LLVMValueRef offset_lo, offset_hi;
+ /* XXX 1D & 3D addressing not done yet */
+ assert(!z);
+ assert(!z_stride);
+
x_lo = LLVMBuildAnd(bld->builder, x, bld->one, "");
y_lo = LLVMBuildAnd(bld->builder, y, bld->one, "");
@@ -186,13 +207,17 @@ lp_build_sample_offset(struct lp_build_context *bld,
offset = lp_build_add(bld, offset_hi, offset_lo);
}
else {
- LLVMValueRef x_offset;
- LLVMValueRef y_offset;
+ offset = lp_build_mul(bld, x, x_stride);
- x_offset = lp_build_mul(bld, x, x_stride);
- y_offset = lp_build_mul(bld, y, y_stride);
+ if (y && y_stride) {
+ LLVMValueRef y_offset = lp_build_mul(bld, y, y_stride);
+ offset = lp_build_add(bld, offset, y_offset);
+ }
- offset = lp_build_add(bld, x_offset, y_offset);
+ if (z && z_stride) {
+ LLVMValueRef z_offset = lp_build_mul(bld, z, z_stride);
+ offset = lp_build_add(bld, offset, z_offset);
+ }
}
return offset;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 5ba0925bb6..5b8da5dbf2 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -148,8 +148,9 @@ lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr);
+ LLVMValueRef z_stride);
void
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9058f76c1d..dadae61115 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -65,6 +65,14 @@ struct lp_build_sample_context
const struct util_format_description *format_desc;
+ /** regular scalar float type */
+ struct lp_type float_type;
+ struct lp_build_context float_bld;
+
+ /** regular scalar float type */
+ struct lp_type int_type;
+ struct lp_build_context int_bld;
+
/** Incoming coordinates type and build context */
struct lp_type coord_type;
struct lp_build_context coord_bld;
@@ -108,9 +116,50 @@ wrap_mode_uses_border_color(unsigned mode)
}
+static LLVMValueRef
+lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
+ LLVMValueRef data_array, LLVMValueRef level)
+{
+ LLVMValueRef indexes[2], data_ptr;
+ indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indexes[1] = level;
+ data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+ data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+ return data_ptr;
+}
+
+
+static LLVMValueRef
+lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
+ LLVMValueRef data_array, int level)
+{
+ LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
+ return lp_build_get_mipmap_level(bld, data_array, lvl);
+}
+
+
+static int
+texture_dims(enum pipe_texture_target tex)
+{
+ switch (tex) {
+ case PIPE_TEXTURE_1D:
+ return 1;
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_CUBE:
+ return 2;
+ case PIPE_TEXTURE_3D:
+ return 3;
+ default:
+ assert(0 && "bad texture target in texture_dims()");
+ return 2;
+ }
+}
+
+
/**
- * Gen code to fetch a texel from a texture at int coords (x, y).
+ * Generate code to fetch a texel from a texture at int coords (x, y, z).
+ * The computation depends on whether the texture is 1D, 2D or 3D.
* The result, texel, will be:
* texel[0] = red values
* texel[1] = green values
@@ -121,12 +170,16 @@ static void
lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
+ LLVMValueRef depth,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
+ LLVMValueRef z_stride,
LLVMValueRef data_ptr,
LLVMValueRef *texel)
{
+ const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef offset;
LLVMValueRef packed;
@@ -140,7 +193,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
}
- if (wrap_mode_uses_border_color(bld->static_state->wrap_t)) {
+ if (dims >= 2 && wrap_mode_uses_border_color(bld->static_state->wrap_t)) {
LLVMValueRef b1, b2;
b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, y, int_coord_bld->zero);
b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, y, height);
@@ -153,6 +206,19 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
}
}
+ if (dims == 3 && wrap_mode_uses_border_color(bld->static_state->wrap_r)) {
+ LLVMValueRef b1, b2;
+ b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, z, int_coord_bld->zero);
+ b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, z, depth);
+ if (use_border) {
+ use_border = LLVMBuildOr(bld->builder, use_border, b1, "ub_or_b1");
+ use_border = LLVMBuildOr(bld->builder, use_border, b2, "ub_or_b2");
+ }
+ else {
+ use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
+ }
+ }
+
/*
* Note: if we find an app which frequently samples the texture border
* we might want to implement a true conditional here to avoid sampling
@@ -168,11 +234,10 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
* the texel color results with the border color.
*/
- /* convert x,y coords to linear offset from start of texture, in bytes */
+ /* convert x,y,z coords to linear offset from start of texture, in bytes */
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, z, y_stride, z_stride);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
@@ -185,6 +250,8 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
bld->texel_type.width,
data_ptr, offset);
+ texel[0] = texel[1] = texel[2] = texel[3] = NULL;
+
/* convert texels to float rgba */
lp_build_unpack_rgba_soa(bld->builder,
bld->format_desc,
@@ -210,19 +277,22 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef data_array)
{
LLVMValueRef offset;
+ LLVMValueRef data_ptr;
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, NULL, y_stride, NULL);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
assert(bld->format_desc->block.bits <= bld->texel_type.width);
+ /* get pointer to mipmap level 0 data */
+ data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
+
return lp_build_gather(bld->builder,
bld->texel_type.length,
bld->format_desc->block.bits,
@@ -711,76 +781,566 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
/**
- * Sample 2D texture with nearest filtering.
+ * Codegen equivalent for u_minify().
+ * Return max(1, base_size >> level);
+ */
+static LLVMValueRef
+lp_build_minify(struct lp_build_sample_context *bld,
+ LLVMValueRef base_size,
+ LLVMValueRef level)
+{
+ LLVMValueRef size = LLVMBuildAShr(bld->builder, base_size, level, "minify");
+ size = lp_build_max(&bld->int_coord_bld, size, bld->int_coord_bld.one);
+ return size;
+}
+
+
+/**
+ * Generate code to compute texture level of detail (lambda).
+ * \param s vector of texcoord s values
+ * \param t vector of texcoord t values
+ * \param r vector of texcoord r values
+ * \param width scalar int texture width
+ * \param height scalar int texture height
+ * \param depth scalar int texture depth
+ */
+static LLVMValueRef
+lp_build_lod_selector(struct lp_build_sample_context *bld,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef depth)
+
+{
+ const int dims = texture_dims(bld->static_state->target);
+ struct lp_build_context *float_bld = &bld->float_bld;
+ LLVMValueRef lod_bias = LLVMConstReal(LLVMFloatType(), bld->static_state->lod_bias);
+ LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
+ LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(), bld->static_state->max_lod);
+
+ LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
+ LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
+
+ LLVMValueRef s0, s1, s2;
+ LLVMValueRef t0, t1, t2;
+ LLVMValueRef r0, r1, r2;
+ LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
+ LLVMValueRef rho, lod;
+
+ /*
+ * dsdx = abs(s[1] - s[0]);
+ * dsdy = abs(s[2] - s[0]);
+ * dtdx = abs(t[1] - t[0]);
+ * dtdy = abs(t[2] - t[0]);
+ * drdx = abs(r[1] - r[0]);
+ * drdy = abs(r[2] - r[0]);
+ * XXX we're assuming a four-element quad in 2x2 layout here.
+ */
+ s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
+ s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
+ s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
+ dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
+ dsdx = lp_build_abs(float_bld, dsdx);
+ dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
+ dsdy = lp_build_abs(float_bld, dsdy);
+ if (dims > 1) {
+ t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
+ t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
+ t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
+ dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
+ dtdx = lp_build_abs(float_bld, dtdx);
+ dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
+ dtdy = lp_build_abs(float_bld, dtdy);
+ if (dims > 2) {
+ r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
+ r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
+ r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
+ drdx = LLVMBuildSub(bld->builder, r1, r0, "");
+ drdx = lp_build_abs(float_bld, drdx);
+ drdy = LLVMBuildSub(bld->builder, r2, r0, "");
+ drdy = lp_build_abs(float_bld, drdy);
+ }
+ }
+
+ /* Compute rho = max of all partial derivatives scaled by texture size.
+ * XXX this could be vectorized somewhat
+ */
+ rho = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, dsdx, dsdy),
+ lp_build_int_to_float(float_bld, width), "");
+ if (dims > 1) {
+ LLVMValueRef max;
+ max = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, dtdx, dtdy),
+ lp_build_int_to_float(float_bld, height), "");
+ rho = lp_build_max(float_bld, rho, max);
+ if (dims > 2) {
+ max = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, drdx, drdy),
+ lp_build_int_to_float(float_bld, depth), "");
+ rho = lp_build_max(float_bld, rho, max);
+ }
+ }
+
+ /* compute lod = log2(rho) */
+ lod = lp_build_log2(float_bld, rho);
+
+ /* add lod bias */
+ lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "LOD bias");
+
+ /* clamp lod */
+ lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
+
+ return lod;
+}
+
+
+/**
+ * For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
+ * mipmap level index.
+ * Note: this is all scalar code.
+ * \param lod scalar float texture level of detail
+ * \param level_out returns integer
*/
static void
-lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
- LLVMValueRef s,
- LLVMValueRef t,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef stride,
- LLVMValueRef data_ptr,
- LLVMValueRef *texel)
+lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef lod,
+ LLVMValueRef *level_out)
{
- LLVMValueRef x, y;
+ struct lp_build_context *float_bld = &bld->float_bld;
+ struct lp_build_context *int_bld = &bld->int_bld;
+ LLVMValueRef last_level, level;
- x = lp_build_sample_wrap_nearest(bld, s, width,
- bld->static_state->pot_width,
- bld->static_state->wrap_s);
- y = lp_build_sample_wrap_nearest(bld, t, height,
- bld->static_state->pot_height,
- bld->static_state->wrap_t);
+ LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, 0);
- lp_build_name(x, "tex.x.wrapped");
- lp_build_name(y, "tex.y.wrapped");
+ last_level = bld->dynamic_state->last_level(bld->dynamic_state,
+ bld->builder, unit);
+
+ /* convert float lod to integer */
+ level = lp_build_iround(float_bld, lod);
+
+ /* clamp level to legal range of levels */
+ *level_out = lp_build_clamp(int_bld, level, zero, last_level);
+}
+
+
+/**
+ * For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
+ * two (adjacent) mipmap level indexes. Later, we'll sample from those
+ * two mipmap levels and interpolate between them.
+ */
+static void
+lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef lod,
+ LLVMValueRef *level0_out,
+ LLVMValueRef *level1_out,
+ LLVMValueRef *weight_out)
+{
+ struct lp_build_context *float_bld = &bld->float_bld;
+ struct lp_build_context *int_bld = &bld->int_bld;
+ LLVMValueRef last_level, level;
+
+ last_level = bld->dynamic_state->last_level(bld->dynamic_state,
+ bld->builder, unit);
+
+ /* convert float lod to integer */
+ level = lp_build_ifloor(float_bld, lod);
+
+ /* compute level 0 and clamp to legal range of levels */
+ *level0_out = lp_build_clamp(int_bld, level,
+ int_bld->zero,
+ last_level);
+ /* compute level 1 and clamp to legal range of levels */
+ *level1_out = lp_build_add(int_bld, *level0_out, int_bld->one);
+ *level1_out = lp_build_min(int_bld, *level1_out, int_bld->zero);
- lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_ptr, texel);
+ *weight_out = lp_build_fract(float_bld, lod);
}
/**
- * Sample 2D texture with bilinear filtering.
+ * Generate code to sample a mipmap level with nearest filtering.
*/
static void
-lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
+lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_vec,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_ptr,
LLVMValueRef s,
LLVMValueRef t,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef stride,
- LLVMValueRef data_ptr,
- LLVMValueRef *texel)
+ LLVMValueRef r,
+ LLVMValueRef colors_out[4])
{
- LLVMValueRef s_fpart;
- LLVMValueRef t_fpart;
- LLVMValueRef x0, x1;
- LLVMValueRef y0, y1;
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef x, y, z;
+
+ /*
+ * Compute integer texcoords.
+ */
+ x = lp_build_sample_wrap_nearest(bld, s, width_vec,
+ bld->static_state->pot_width,
+ bld->static_state->wrap_s);
+ lp_build_name(x, "tex.x.wrapped");
+
+ if (dims >= 2) {
+ y = lp_build_sample_wrap_nearest(bld, t, height_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_t);
+ lp_build_name(y, "tex.y.wrapped");
+
+ if (dims == 3) {
+ z = lp_build_sample_wrap_nearest(bld, r, depth_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_r);
+ lp_build_name(z, "tex.z.wrapped");
+ }
+ else {
+ z = NULL;
+ }
+ }
+ else {
+ y = NULL;
+ }
+
+ /*
+ * Get texture colors.
+ */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x, y, z,
+ row_stride_vec, img_stride_vec,
+ data_ptr, colors_out);
+}
+
+
+/**
+ * Generate code to sample a mipmap level with linear filtering.
+ * 1D, 2D and 3D images are suppored.
+ */
+static void
+lp_build_sample_image_linear(struct lp_build_sample_context *bld,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_vec,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_ptr,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef colors_out[4])
+{
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef x0, y0, z0, x1, y1, z1;
+ LLVMValueRef s_fpart, t_fpart, r_fpart;
LLVMValueRef neighbors[2][2][4];
- unsigned chan;
+ int chan;
- lp_build_sample_wrap_linear(bld, s, width, bld->static_state->pot_width,
- bld->static_state->wrap_s, &x0, &x1, &s_fpart);
- lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height,
- bld->static_state->wrap_t, &y0, &y1, &t_fpart);
+ /*
+ * Compute integer texcoords.
+ */
+ lp_build_sample_wrap_linear(bld, s, width_vec,
+ bld->static_state->pot_width,
+ bld->static_state->wrap_s,
+ &x0, &x1, &s_fpart);
+ lp_build_name(x0, "tex.x0.wrapped");
+ lp_build_name(x1, "tex.x1.wrapped");
+
+ if (dims >= 2) {
+ lp_build_sample_wrap_linear(bld, t, height_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_t,
+ &y0, &y1, &t_fpart);
+ lp_build_name(y0, "tex.y0.wrapped");
+ lp_build_name(y1, "tex.y1.wrapped");
+
+ if (dims == 3) {
+ lp_build_sample_wrap_linear(bld, r, depth_vec,
+ bld->static_state->pot_depth,
+ bld->static_state->wrap_r,
+ &z0, &z1, &r_fpart);
+ lp_build_name(z0, "tex.z0.wrapped");
+ lp_build_name(z1, "tex.z1.wrapped");
+ }
+ else {
+ z0 = z1 = r_fpart = NULL;
+ }
+ }
+ else {
+ y0 = y1 = t_fpart = NULL;
+ }
- lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_ptr, neighbors[0][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_ptr, neighbors[0][1]);
- lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_ptr, neighbors[1][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_ptr, neighbors[1][1]);
+ /*
+ * Get texture colors.
+ */
+ /* get x0/x1 texels */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y0, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[0][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y0, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[0][1]);
+
+ if (dims == 1) {
+ /* Interpolate two samples from 1D image to produce one color */
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld, s_fpart,
+ neighbors[0][0][chan],
+ neighbors[0][1][chan]);
+ }
+ else {
+ /* 2D/3D texture */
+ LLVMValueRef colors0[4];
+
+ /* get x0/x1 texels at y1 */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y1, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[1][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y1, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[1][1]);
+
+ /* Bilinear interpolate the four samples from the 2D image / 3D slice */
+ for (chan = 0; chan < 4; chan++) {
+ colors0[chan] = lp_build_lerp_2d(&bld->texel_bld,
+ s_fpart, t_fpart,
+ neighbors[0][0][chan],
+ neighbors[0][1][chan],
+ neighbors[1][0][chan],
+ neighbors[1][1][chan]);
+ }
- /* TODO: Don't interpolate missing channels */
- for(chan = 0; chan < 4; ++chan) {
- texel[chan] = lp_build_lerp_2d(&bld->texel_bld,
- s_fpart, t_fpart,
- neighbors[0][0][chan],
- neighbors[0][1][chan],
- neighbors[1][0][chan],
- neighbors[1][1][chan]);
+ if (dims == 3) {
+ LLVMValueRef neighbors1[2][2][4];
+ LLVMValueRef colors1[4];
+
+ /* get x0/x1/y0/y1 texels at z1 */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y0, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[0][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y0, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[0][1]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y1, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[1][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y1, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[1][1]);
+
+ /* Bilinear interpolate the four samples from the second Z slice */
+ for (chan = 0; chan < 4; chan++) {
+ colors1[chan] = lp_build_lerp_2d(&bld->texel_bld,
+ s_fpart, t_fpart,
+ neighbors1[0][0][chan],
+ neighbors1[0][1][chan],
+ neighbors1[1][0][chan],
+ neighbors1[1][1][chan]);
+ }
+
+ /* Linearly interpolate the two samples from the two 3D slices */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld,
+ r_fpart,
+ colors0[chan], colors1[chan]);
+ }
+ }
+ else {
+ /* 2D tex */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = colors0[chan];
+ }
+ }
}
}
+
+/**
+ * General texture sampling codegen.
+ * This function handles texture sampling for all texture targets (1D,
+ * 2D, 3D, cube) and all filtering modes.
+ */
+static void
+lp_build_sample_general(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef depth,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_vec,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_array,
+ LLVMValueRef *colors_out)
+{
+ const unsigned mip_filter = bld->static_state->min_mip_filter;
+ const unsigned min_filter = bld->static_state->min_img_filter;
+ const unsigned mag_filter = bld->static_state->mag_img_filter;
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef lod, lod_fpart;
+ LLVMValueRef ilevel0, ilevel1, ilevel0_vec, ilevel1_vec;
+ LLVMValueRef width0_vec, height0_vec, depth0_vec;
+ LLVMValueRef width1_vec, height1_vec, depth1_vec;
+ LLVMValueRef row_stride0_vec, row_stride1_vec;
+ LLVMValueRef img_stride0_vec, img_stride1_vec;
+ LLVMValueRef data_ptr0, data_ptr1;
+ int chan;
+
+ /*
+ printf("%s mip %d min %d mag %d\n", __FUNCTION__,
+ mip_filter, min_filter, mag_filter);
+ */
+
+ /*
+ * Compute the level of detail (mipmap level index(es)).
+ */
+ if (mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+ /* always use mip level 0 */
+ ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ }
+ else {
+ /* compute float LOD */
+ lod = lp_build_lod_selector(bld, s, t, r, width, height, depth);
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
+ lp_build_nearest_mip_level(bld, unit, lod, &ilevel0);
+ }
+ else {
+ assert(mip_filter == PIPE_TEX_MIPFILTER_LINEAR);
+ lp_build_linear_mip_levels(bld, unit, lod, &ilevel0, &ilevel1,
+ &lod_fpart);
+ lod_fpart = lp_build_broadcast_scalar(&bld->coord_bld, lod_fpart);
+ }
+ }
+
+ /*
+ * Convert scalar integer mipmap levels into vectors.
+ */
+ ilevel0_vec = lp_build_broadcast_scalar(&bld->int_coord_bld, ilevel0);
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR)
+ ilevel1_vec = lp_build_broadcast_scalar(&bld->int_coord_bld, ilevel1);
+
+ /*
+ * Compute width, height at mipmap level 'ilevel0'
+ */
+ width0_vec = lp_build_minify(bld, width_vec, ilevel0_vec);
+ if (dims >= 2) {
+ height0_vec = lp_build_minify(bld, height_vec, ilevel0_vec);
+ row_stride0_vec = lp_build_minify(bld, row_stride_vec, ilevel0_vec);
+ if (dims == 3) {
+ depth0_vec = lp_build_minify(bld, depth_vec, ilevel0_vec);
+ }
+ }
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* compute width, height, depth for second mipmap level at ilevel1 */
+ width1_vec = lp_build_minify(bld, width_vec, ilevel1_vec);
+ if (dims >= 2) {
+ height1_vec = lp_build_minify(bld, height_vec, ilevel1_vec);
+ row_stride1_vec = lp_build_minify(bld, row_stride_vec, ilevel1_vec);
+ if (dims == 3) {
+ depth1_vec = lp_build_minify(bld, depth_vec, ilevel1_vec);
+ }
+ }
+ }
+
+ /*
+ * Choose cube face, recompute texcoords.
+ */
+ if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+
+ }
+
+ /*
+ * Get pointer(s) to image data for mipmap level(s).
+ */
+ data_ptr0 = lp_build_get_mipmap_level(bld, data_array, ilevel0);
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ data_ptr1 = lp_build_get_mipmap_level(bld, data_array, ilevel1);
+ }
+
+ /*
+ * Get/interpolate texture colors.
+ */
+ /* XXX temporarily force this path: */
+ if (1 /*min_filter == mag_filter*/) {
+ /* same filter for minification or magnification */
+ LLVMValueRef colors0[4], colors1[4];
+
+ if (min_filter == PIPE_TEX_FILTER_NEAREST) {
+ lp_build_sample_image_nearest(bld,
+ width0_vec, height0_vec, depth0_vec,
+ row_stride0_vec, img_stride0_vec,
+ data_ptr0, s, t, r, colors0);
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* sample the second mipmap level, and interp */
+ lp_build_sample_image_nearest(bld,
+ width1_vec, height1_vec, depth1_vec,
+ row_stride1_vec, img_stride1_vec,
+ data_ptr1, s, t, r, colors1);
+ }
+ }
+ else {
+ assert(min_filter == PIPE_TEX_FILTER_LINEAR);
+
+ lp_build_sample_image_linear(bld,
+ width0_vec, height0_vec, depth0_vec,
+ row_stride0_vec, img_stride0_vec,
+ data_ptr0, s, t, r, colors0);
+
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* sample the second mipmap level, and interp */
+ lp_build_sample_image_linear(bld,
+ width1_vec, height1_vec, depth1_vec,
+ row_stride1_vec, img_stride1_vec,
+ data_ptr1, s, t, r, colors1);
+ }
+ }
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* interpolate samples from the two mipmap levels */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart,
+ colors0[chan], colors1[chan]);
+ }
+ }
+ else {
+ /* use first/only level's colors */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = colors0[chan];
+ }
+ }
+ }
+ else {
+ /* emit conditional to choose min image filter or mag image filter
+ * depending on the lod being >0 or <= 0, respectively.
+ */
+ abort();
+ }
+}
+
+
+
static void
lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
struct lp_type dst_type,
@@ -818,7 +1378,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMBuilderRef builder = bld->builder;
@@ -835,7 +1395,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef packed, packed_lo, packed_hi;
LLVMValueRef unswizzled[4];
- lp_build_context_init(&i32, builder, lp_type_int(32));
+ lp_build_context_init(&i32, builder, lp_type_int_vec(32));
lp_build_context_init(&h16, builder, lp_type_ufixed(16));
lp_build_context_init(&u8n, builder, lp_type_unorm(8));
@@ -958,10 +1518,10 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
* The higher 8 bits of the resulting elements will be zero.
*/
- neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_ptr);
- neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_ptr);
- neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_ptr);
- neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_ptr);
+ neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_array);
+ neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_array);
+ neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_array);
+ neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_array);
neighbors[0][0] = LLVMBuildBitCast(builder, neighbors[0][0], u8n_vec_type, "");
neighbors[0][1] = LLVMBuildBitCast(builder, neighbors[0][1], u8n_vec_type, "");
@@ -1044,194 +1604,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
}
-static int
-texture_dims(enum pipe_texture_target tex)
-{
- switch (tex) {
- case PIPE_TEXTURE_1D:
- return 1;
- case PIPE_TEXTURE_2D:
- case PIPE_TEXTURE_CUBE:
- return 2;
- case PIPE_TEXTURE_3D:
- return 3;
- default:
- assert(0 && "bad texture target in texture_dims()");
- return 2;
- }
-}
-
-
-/**
- * Generate code to compute texture level of detail (lambda).
- * \param s vector of texcoord s values
- * \param t vector of texcoord t values
- * \param r vector of texcoord r values
- * \param width scalar int texture width
- * \param height scalar int texture height
- * \param depth scalar int texture depth
- */
-static LLVMValueRef
-lp_build_lod_selector(struct lp_build_sample_context *bld,
- LLVMValueRef s,
- LLVMValueRef t,
- LLVMValueRef r,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef depth)
-
-{
- const int dims = texture_dims(bld->static_state->target);
- struct lp_build_context *coord_bld = &bld->coord_bld;
-
- LLVMValueRef lod_bias = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->lod_bias);
- LLVMValueRef min_lod = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->min_lod);
- LLVMValueRef max_lod = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->max_lod);
-
- LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
- LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
- LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-
- LLVMValueRef s0, s1, s2;
- LLVMValueRef t0, t1, t2;
- LLVMValueRef r0, r1, r2;
- LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
- LLVMValueRef rho, lod;
-
- /*
- * dsdx = abs(s[1] - s[0]);
- * dsdy = abs(s[2] - s[0]);
- * dtdx = abs(t[1] - t[0]);
- * dtdy = abs(t[2] - t[0]);
- * drdx = abs(r[1] - r[0]);
- * drdy = abs(r[2] - r[0]);
- * XXX we're assuming a four-element quad in 2x2 layout here.
- */
- s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
- s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
- s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
- dsdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s1, s0));
- dsdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s2, s0));
- if (dims > 1) {
- t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
- t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
- t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
- dtdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t1, t0));
- dtdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t2, t0));
- if (dims > 2) {
- r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
- r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
- r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
- drdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r1, r0));
- drdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r2, r0));
- }
- }
-
- /* Compute rho = max of all partial derivatives scaled by texture size.
- * XXX this can be vectorized somewhat
- */
- rho = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, dsdx, dsdy),
- lp_build_int_to_float(coord_bld, width));
- if (dims > 1) {
- LLVMValueRef max;
- max = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, dtdx, dtdy),
- lp_build_int_to_float(coord_bld, height));
- rho = lp_build_max(coord_bld, rho, max);
- if (dims > 2) {
- max = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, drdx, drdy),
- lp_build_int_to_float(coord_bld, depth));
- rho = lp_build_max(coord_bld, rho, max);
- }
- }
-
- /* compute lod = log2(rho) */
- lod = lp_build_log2(coord_bld, rho);
-
- /* add lod bias */
- lod = lp_build_add(coord_bld, lod, lod_bias);
-
- /* clamp lod */
- lod = lp_build_clamp(coord_bld, lod, min_lod, max_lod);
-
- return lod;
-}
-
-
-/**
- * For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
- * mipmap level index.
- * \param lod scalar float texture level of detail
- * \param level_out returns integer
- */
-static void
-lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
- unsigned unit,
- LLVMValueRef lod,
- LLVMValueRef *level_out)
-{
- struct lp_build_context *coord_bld = &bld->coord_bld;
- struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
- LLVMValueRef last_level, level;
-
- last_level = bld->dynamic_state->last_level(bld->dynamic_state,
- bld->builder, unit);
-
- /* convert float lod to integer */
- level = lp_build_iround(coord_bld, lod);
-
- /* clamp level to legal range of levels */
- *level_out = lp_build_clamp(int_coord_bld, level,
- int_coord_bld->zero,
- last_level);
-}
-
-
-/**
- * For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
- * two (adjacent) mipmap level indexes. Later, we'll sample from those
- * two mipmap levels and interpolate between them.
- */
-static void
-lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
- unsigned unit,
- LLVMValueRef lod,
- LLVMValueRef *level0_out,
- LLVMValueRef *level1_out,
- LLVMValueRef *weight_out)
-{
- struct lp_build_context *coord_bld = &bld->coord_bld;
- struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
- LLVMValueRef last_level, level;
-
- last_level = bld->dynamic_state->last_level(bld->dynamic_state,
- bld->builder, unit);
-
- /* convert float lod to integer */
- level = lp_build_ifloor(coord_bld, lod);
-
- /* compute level 0 and clamp to legal range of levels */
- *level0_out = lp_build_clamp(int_coord_bld, level,
- int_coord_bld->zero,
- last_level);
- /* compute level 1 and clamp to legal range of levels */
- *level1_out = lp_build_add(int_coord_bld, *level0_out, int_coord_bld->one);
- *level1_out = lp_build_min(int_coord_bld, *level1_out, int_coord_bld->zero);
-
- *weight_out = lp_build_fract(coord_bld, lod);
-}
-
-
-
/**
* Build texture sampling code.
* 'texel' will return a vector of four LLVMValueRefs corresponding to
* R, G, B, A.
+ * \param type vector float type to use for coords, etc.
*/
void
lp_build_sample_soa(LLVMBuilderRef builder,
@@ -1245,10 +1622,11 @@ lp_build_sample_soa(LLVMBuilderRef builder,
LLVMValueRef *texel)
{
struct lp_build_sample_context bld;
- LLVMValueRef width;
- LLVMValueRef height;
- LLVMValueRef stride;
- LLVMValueRef data_ptr;
+ LLVMValueRef width, width_vec;
+ LLVMValueRef height, height_vec;
+ LLVMValueRef depth, depth_vec;
+ LLVMValueRef stride, stride_vec;
+ LLVMValueRef data_array;
LLVMValueRef s;
LLVMValueRef t;
LLVMValueRef r;
@@ -1256,6 +1634,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
(void) lp_build_lod_selector; /* temporary to silence warning */
(void) lp_build_nearest_mip_level;
(void) lp_build_linear_mip_levels;
+ (void) lp_build_minify;
/* Setup our build context */
memset(&bld, 0, sizeof bld);
@@ -1263,10 +1642,16 @@ lp_build_sample_soa(LLVMBuilderRef builder,
bld.static_state = static_state;
bld.dynamic_state = dynamic_state;
bld.format_desc = util_format_description(static_state->format);
+
+ bld.float_type = lp_type_float(32);
+ bld.int_type = lp_type_int(32);
bld.coord_type = type;
bld.uint_coord_type = lp_uint_type(type);
bld.int_coord_type = lp_int_type(type);
bld.texel_type = type;
+
+ lp_build_context_init(&bld.float_bld, builder, bld.float_type);
+ lp_build_context_init(&bld.int_bld, builder, bld.int_type);
lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
lp_build_context_init(&bld.uint_coord_bld, builder, bld.uint_coord_type);
lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
@@ -1275,41 +1660,37 @@ lp_build_sample_soa(LLVMBuilderRef builder,
/* Get the dynamic state */
width = dynamic_state->width(dynamic_state, builder, unit);
height = dynamic_state->height(dynamic_state, builder, unit);
+ depth = dynamic_state->depth(dynamic_state, builder, unit);
stride = dynamic_state->stride(dynamic_state, builder, unit);
- data_ptr = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ /* Note that data_array is an array[level] of pointers to texture images */
s = coords[0];
t = coords[1];
r = coords[2];
- width = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
- height = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
- stride = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride);
-
- if(static_state->target == PIPE_TEXTURE_1D)
- t = bld.coord_bld.zero;
-
- switch (static_state->min_img_filter) {
- case PIPE_TEX_FILTER_NEAREST:
- lp_build_sample_2d_nearest_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
- break;
- case PIPE_TEX_FILTER_LINEAR:
- if(lp_format_is_rgba8(bld.format_desc) &&
- is_simple_wrap_mode(static_state->wrap_s) &&
- is_simple_wrap_mode(static_state->wrap_t))
- lp_build_sample_2d_linear_aos(&bld, s, t, width, height,
- stride, data_ptr, texel);
- else
- lp_build_sample_2d_linear_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
- break;
- default:
- assert(0);
+ width_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
+ height_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
+ depth_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, depth);
+ stride_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride);
+
+ if (lp_format_is_rgba8(bld.format_desc) &&
+ static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE &&
+ is_simple_wrap_mode(static_state->wrap_s) &&
+ is_simple_wrap_mode(static_state->wrap_t)) {
+ /* special case */
+ lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
+ stride_vec, data_array, texel);
+ }
+ else {
+ lp_build_sample_general(&bld, unit, s, t, r,
+ width, height, depth,
+ width_vec, height_vec, depth_vec,
+ stride_vec, NULL, data_array,
+ texel);
}
-
- /* FIXME: respect static_state->min_mip_filter */;
- /* FIXME: respect static_state->mag_img_filter */;
lp_build_sample_compare(&bld, r, texel);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 5f2c2a54ee..b3a0fe7d9b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -95,6 +95,19 @@ struct lp_exec_mask {
int cond_stack_size;
LLVMValueRef cond_mask;
+ LLVMValueRef break_stack[LP_TGSI_MAX_NESTING];
+ int break_stack_size;
+ LLVMValueRef break_mask;
+
+ LLVMValueRef cont_stack[LP_TGSI_MAX_NESTING];
+ int cont_stack_size;
+ LLVMValueRef cont_mask;
+
+ LLVMBasicBlockRef loop_stack[LP_TGSI_MAX_NESTING];
+ int loop_stack_size;
+ LLVMBasicBlockRef loop_block;
+
+
LLVMValueRef exec_mask;
};
@@ -145,15 +158,33 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
mask->bld = bld;
mask->has_mask = FALSE;
mask->cond_stack_size = 0;
+ mask->loop_stack_size = 0;
+ mask->break_stack_size = 0;
+ mask->cont_stack_size = 0;
mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
}
static void lp_exec_mask_update(struct lp_exec_mask *mask)
{
- mask->exec_mask = mask->cond_mask;
- if (mask->cond_stack_size > 0)
- mask->has_mask = TRUE;
+ if (mask->loop_stack_size) {
+ /*for loops we need to update the entire mask at
+ * runtime */
+ LLVMValueRef tmp;
+ tmp = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask,
+ mask->break_mask,
+ "maskcb");
+ mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cond_mask,
+ tmp,
+ "maskfull");
+ } else
+ mask->exec_mask = mask->cond_mask;
+
+
+ mask->has_mask = (mask->cond_stack_size > 0 ||
+ mask->loop_stack_size > 0);
}
static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
@@ -190,6 +221,89 @@ static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
lp_exec_mask_update(mask);
}
+static void lp_exec_bgnloop(struct lp_exec_mask *mask)
+{
+
+ if (mask->cont_stack_size == 0)
+ mask->cont_mask = LLVMConstAllOnes(mask->int_vec_type);
+ if (mask->cont_stack_size == 0)
+ mask->break_mask = LLVMConstAllOnes(mask->int_vec_type);
+ if (mask->cond_stack_size == 0)
+ mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type);
+ mask->loop_stack[mask->loop_stack_size++] = mask->loop_block;
+ mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
+ LLVMBuildBr(mask->bld->builder, mask->loop_block);
+ LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
+
+ lp_exec_mask_update(mask);
+}
+
+static void lp_exec_break(struct lp_exec_mask *mask)
+{
+ LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ mask->exec_mask,
+ "break");
+
+ mask->break_stack[mask->break_stack_size++] = mask->break_mask;
+ if (mask->break_stack_size > 1) {
+ mask->break_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->break_mask,
+ exec_mask, "break_full");
+ } else
+ mask->break_mask = exec_mask;
+
+ lp_exec_mask_update(mask);
+}
+
+static void lp_exec_continue(struct lp_exec_mask *mask)
+{
+ LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ mask->exec_mask,
+ "");
+
+ mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask;
+ if (mask->cont_stack_size > 1) {
+ mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask,
+ exec_mask, "");
+ } else
+ mask->cont_mask = exec_mask;
+
+ lp_exec_mask_update(mask);
+}
+
+
+static void lp_exec_endloop(struct lp_exec_mask *mask)
+{
+ LLVMBasicBlockRef endloop;
+ LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
+ mask->bld->type.length);
+ /* i1cond = (mask == 0) */
+ LLVMValueRef i1cond = LLVMBuildICmp(
+ mask->bld->builder,
+ LLVMIntNE,
+ LLVMBuildBitCast(mask->bld->builder, mask->break_mask, reg_type, ""),
+ LLVMConstNull(reg_type), "");
+
+ endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
+
+ LLVMBuildCondBr(mask->bld->builder,
+ i1cond, mask->loop_block, endloop);
+
+ LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
+
+ mask->loop_block = mask->loop_stack[--mask->loop_stack_size];
+ /* pop the break mask */
+ if (mask->cont_stack_size) {
+ mask->cont_mask = mask->cont_stack[--mask->cont_stack_size];
+ }
+ if (mask->break_stack_size) {
+ mask->break_mask = mask->cont_stack[--mask->break_stack_size];
+ }
+
+ lp_exec_mask_update(mask);
+}
+
static void lp_exec_mask_store(struct lp_exec_mask *mask,
LLVMValueRef val,
LLVMValueRef dst)
@@ -384,6 +498,11 @@ emit_store(
assert(0);
break;
+ case TGSI_FILE_PREDICATE:
+ /* FIXME */
+ assert(0);
+ break;
+
default:
assert( 0 );
}
@@ -581,6 +700,17 @@ emit_instruction(
if (indirect_temp_reference(inst))
return FALSE;
+ /*
+ * Stores and write masks are handled in a general fashion after the long
+ * instruction opcode switch statement.
+ *
+ * Although not stricitly necessary, we avoid generating instructions for
+ * channels which won't be stored, in cases where's that easy. For some
+ * complex instructions, like texture sampling, it is more convenient to
+ * assume a full writemask and then let LLVM optimization passes eliminate
+ * redundant code.
+ */
+
assert(info->num_dst <= 1);
if(info->num_dst) {
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
@@ -1126,7 +1256,6 @@ emit_instruction(
break;
case TGSI_OPCODE_TEX:
- /* XXX what about dst0 writemask? */
emit_tex( bld, inst, FALSE, FALSE, dst0 );
break;
@@ -1349,14 +1478,15 @@ emit_instruction(
case TGSI_OPCODE_TXP:
emit_tex( bld, inst, FALSE, TRUE, dst0 );
break;
-
+
case TGSI_OPCODE_BRK:
- /* FIXME */
- return 0;
+ lp_exec_break(&bld->exec_mask);
break;
case TGSI_OPCODE_IF:
tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
+ tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
+ tmp0, bld->base.zero);
lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
break;
@@ -1366,6 +1496,10 @@ emit_instruction(
return 0;
break;
+ case TGSI_OPCODE_BGNLOOP:
+ lp_exec_bgnloop(&bld->exec_mask);
+ break;
+
case TGSI_OPCODE_REP:
/* deprecated */
assert(0);
@@ -1386,6 +1520,10 @@ emit_instruction(
return 0;
break;
+ case TGSI_OPCODE_ENDLOOP:
+ lp_exec_endloop(&bld->exec_mask);
+ break;
+
case TGSI_OPCODE_ENDREP:
/* deprecated */
assert(0);
@@ -1485,8 +1623,7 @@ emit_instruction(
break;
case TGSI_OPCODE_CONT:
- /* FIXME */
- return 0;
+ lp_exec_continue(&bld->exec_mask);
break;
case TGSI_OPCODE_EMIT:
@@ -1589,7 +1726,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
assert( 0 );
}
}
-
+ if (0) {
+ LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+ LLVMValueRef function = LLVMGetBasicBlockParent(block);
+ debug_printf("11111111111111111111111111111 \n");
+ tgsi_dump(tokens, 0);
+ LLVMDumpValue(function);
+ debug_printf("2222222222222222222222222222 \n");
+ }
tgsi_parse_free( &parse );
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index 16946cc28a..4daa904e63 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -103,7 +103,7 @@ struct lp_type {
unsigned width:14;
/**
- * Vector length.
+ * Vector length. If length==1, this is a scalar (float/int) type.
*
* width*length should be a power of two greater or equal to eight.
*
@@ -139,6 +139,7 @@ struct lp_build_context
};
+/** Create scalar float type */
static INLINE struct lp_type
lp_type_float(unsigned width)
{
@@ -148,12 +149,29 @@ lp_type_float(unsigned width)
res_type.floating = TRUE;
res_type.sign = TRUE;
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector of float type */
+static INLINE struct lp_type
+lp_type_float_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.floating = TRUE;
+ res_type.sign = TRUE;
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
}
+/** Create scalar int type */
static INLINE struct lp_type
lp_type_int(unsigned width)
{
@@ -162,12 +180,28 @@ lp_type_int(unsigned width)
memset(&res_type, 0, sizeof res_type);
res_type.sign = TRUE;
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector int type */
+static INLINE struct lp_type
+lp_type_int_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.sign = TRUE;
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
}
+/** Create scalar uint type */
static INLINE struct lp_type
lp_type_uint(unsigned width)
{
@@ -175,6 +209,20 @@ lp_type_uint(unsigned width)
memset(&res_type, 0, sizeof res_type);
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector uint type */
+static INLINE struct lp_type
+lp_type_uint_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
diff --git a/src/gallium/auxiliary/target-helpers/wrap_screen.c b/src/gallium/auxiliary/target-helpers/wrap_screen.c
new file mode 100644
index 0000000000..5fe3013938
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/wrap_screen.c
@@ -0,0 +1,65 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ */
+
+#include "target-helpers/wrap_screen.h"
+#include "trace/tr_public.h"
+#include "identity/id_public.h"
+#include "util/u_debug.h"
+
+
+/* Centralized code to inject common wrapping layers:
+ */
+struct pipe_screen *
+gallium_wrap_screen( struct pipe_screen *screen )
+{
+ /* Screen wrapping functions are required not to fail. If it is
+ * impossible to wrap a screen, the unwrapped screen should be
+ * returned instead. Any failure condition should be returned in
+ * an OUT argument.
+ *
+ * Otherwise it is really messy trying to clean up in this code.
+ */
+ if (debug_get_bool_option("GALLIUM_WRAP", FALSE)) {
+ screen = identity_screen_create(screen);
+ }
+
+ if (debug_get_bool_option("GALLIUM_TRACE", FALSE)) {
+ screen = trace_screen_create( screen );
+ }
+
+ return screen;
+}
+
+
+
+
diff --git a/src/gallium/auxiliary/target-helpers/wrap_screen.h b/src/gallium/auxiliary/target-helpers/wrap_screen.h
new file mode 100644
index 0000000000..7e76beb7c5
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/wrap_screen.h
@@ -0,0 +1,16 @@
+#ifndef WRAP_SCREEN_HELPER_H
+#define WRAP_SCREEN_HELPER_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_screen;
+
+/* Centralized code to inject common wrapping layers. Other layers
+ * can be introduced by specific targets, but these are the generally
+ * helpful ones we probably want everywhere.
+ */
+struct pipe_screen *
+gallium_wrap_screen( struct pipe_screen *screen );
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 0b263a9db5..4d0737ccd3 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -63,6 +63,7 @@ struct blit_state
struct pipe_sampler_state sampler;
struct pipe_viewport_state viewport;
struct pipe_clip_state clip;
+ struct pipe_vertex_element velem[2];
void *vs;
void *fs[TGSI_WRITEMASK_XYZW + 1];
@@ -114,6 +115,15 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
ctx->sampler.mag_img_filter = 0; /* set later */
ctx->sampler.normalized_coords = 1;
+ /* vertex elements state */
+ memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ ctx->velem[i].src_offset = i * 4 * sizeof(float);
+ ctx->velem[i].instance_divisor = 0;
+ ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
/* vertex shader - still required to provide the linkage between
* fragment shader input semantics and vertex_element/buffers.
*/
@@ -410,12 +420,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */
ctx->sampler.min_img_filter = filter;
@@ -480,6 +492,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
pipe_texture_reference(&tex, NULL);
}
@@ -564,12 +577,14 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */
ctx->sampler.min_img_filter = filter;
@@ -628,4 +643,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 0ba09d33bf..33d09085f0 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -88,6 +88,8 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
+ void *velem_state;
+
/* Sampler state for clamping to a miplevel. */
void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
@@ -108,6 +110,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
struct pipe_depth_stencil_alpha_state dsa = { { 0 } };
struct pipe_rasterizer_state rs_state = { 0 };
struct pipe_sampler_state *sampler_state;
+ struct pipe_vertex_element velem[2];
unsigned i;
ctx = CALLOC_STRUCT(blitter_context_priv);
@@ -122,6 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR;
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_states = ~0;
@@ -170,6 +174,16 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
+ /* vertex elements state */
+ memset(&velem[0], 0, sizeof(velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ velem[i].src_offset = i * 4 * sizeof(float);
+ velem[i].instance_divisor = 0;
+ velem[i].vertex_buffer_index = 0;
+ velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+ ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
+
/* fragment shaders are created on-demand */
/* vertex shaders */
@@ -219,6 +233,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col);
pipe->delete_vs_state(pipe, ctx->vs_tex);
+ pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
if (ctx->fs_texfetch_col[i])
@@ -246,7 +261,8 @@ static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_dsa_state != INVALID_PTR &&
ctx->blitter.saved_rs_state != INVALID_PTR &&
ctx->blitter.saved_fs != INVALID_PTR &&
- ctx->blitter.saved_vs != INVALID_PTR);
+ ctx->blitter.saved_vs != INVALID_PTR &&
+ ctx->blitter.saved_velem_state != INVALID_PTR);
}
static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
@@ -259,12 +275,14 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
+ pipe->bind_vertex_elements_state(pipe, ctx->blitter.saved_velem_state);
ctx->blitter.saved_blend_state = INVALID_PTR;
ctx->blitter.saved_dsa_state = INVALID_PTR;
ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR;
ctx->blitter.saved_vs = INVALID_PTR;
+ ctx->blitter.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
@@ -569,6 +587,7 @@ void util_blitter_clear(struct blitter_context *blitter,
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
pipe->bind_vs_state(pipe, ctx->vs_col);
@@ -634,6 +653,7 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
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_framebuffer_state(pipe, &fb_state);
@@ -807,6 +827,7 @@ void util_blitter_fill(struct blitter_context *blitter,
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
fb_state.width = dst->width;
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 92008fce99..ecafdabafa 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -43,6 +43,7 @@ struct blitter_context
/* Private members, really. */
void *saved_blend_state; /**< blend state */
void *saved_dsa_state; /**< depth stencil alpha state */
+ void *saved_velem_state; /**< vertex elements state */
void *saved_rs_state; /**< rasterizer state */
void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
@@ -173,6 +174,13 @@ void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
}
static INLINE
+void util_blitter_save_vertex_elements(struct blitter_context *blitter,
+ void *state)
+{
+ blitter->saved_velem_state = state;
+}
+
+static INLINE
void util_blitter_save_stencil_ref(struct blitter_context *blitter,
const struct pipe_stencil_ref *state)
{
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 14506e8451..8c194102bf 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -45,8 +45,6 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
uint num_attribs)
{
struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
- uint i;
assert(num_attribs <= PIPE_MAX_ATTRIBS);
@@ -58,15 +56,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
vbuffer.max_index = num_verts - 1;
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
- /* 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;
- velements[i].nr_components = 4;
- }
- pipe->set_vertex_elements(pipe, num_attribs, velements);
+ /* note: vertex elements already set by caller */
/* draw */
pipe->draw_arrays(pipe, prim_type, 0, num_verts);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index ae7afd7311..52cf3ef4ce 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -700,7 +700,6 @@ util_dump_vertex_element(struct os_stream *stream, const struct pipe_vertex_elem
util_dump_member(stream, uint, state, src_offset);
util_dump_member(stream, uint, state, vertex_buffer_index);
- util_dump_member(stream, uint, state, nr_components);
util_dump_member(stream, format, state, src_format);
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index e8fa0022b5..c08fdcafcc 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -120,9 +120,15 @@ struct util_format_channel_description
struct util_format_description
{
enum pipe_format format;
+
const char *name;
/**
+ * Short name, striped of the prefix, lower case.
+ */
+ const char *short_name;
+
+ /**
* Pixel block dimensions.
*/
struct util_format_block block;
@@ -140,6 +146,15 @@ struct util_format_description
unsigned is_array:1;
/**
+ * Whether the pixel format can be described as a bitfield structure.
+ *
+ * In particular:
+ * - pixel depth must be 8, 16, or 32 bits;
+ * - all channels must be unsigned, signed, or void
+ */
+ unsigned is_bitmask:1;
+
+ /**
* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
*/
unsigned is_mixed:1;
@@ -400,6 +415,16 @@ util_format_has_alpha(enum pipe_format format)
}
}
+/**
+ * Return the number of components stored.
+ * Formats with block size != 1x1 will always have 1 component (the block).
+ */
+static INLINE unsigned
+util_format_get_nr_components(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ return desc->nr_channels;
+}
/*
* Format access functions.
diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py
index 3f33f7cc02..409d024c63 100644
--- a/src/gallium/auxiliary/util/u_format_pack.py
+++ b/src/gallium/auxiliary/util/u_format_pack.py
@@ -252,9 +252,6 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
if src_channel.type == FLOAT and dst_channel.type == FLOAT:
return '(%s)%s' % (dst_native_type, value)
- if not src_channel.norm and not dst_channel.norm:
- return '(%s)%s' % (dst_native_type, value)
-
if clamp:
value = clamp_expr(src_channel, dst_channel, dst_native_type, value)
@@ -280,15 +277,15 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
value = '(%s * %s)' % (value, scale)
return '(%s)%s' % (dst_native_type, value)
- if not src_channel.norm and not dst_channel.norm:
- # neither is normalized -- just cast
- return '(%s)%s' % (dst_native_type, value)
-
if src_channel.type in (SIGNED, UNSIGNED) and dst_channel.type in (SIGNED, UNSIGNED):
+ if not src_channel.norm and not dst_channel.norm:
+ # neither is normalized -- just cast
+ return '(%s)%s' % (dst_native_type, value)
+
src_one = get_one(src_channel)
dst_one = get_one(dst_channel)
- if src_one > dst_one and src_channel.norm:
+ if src_one > dst_one and src_channel.norm and dst_channel.norm:
# We can just bitshift
src_shift = get_one_shift(src_channel)
dst_shift = get_one_shift(dst_channel)
@@ -296,7 +293,7 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
else:
# We need to rescale using an intermediate type big enough to hold the multiplication of both
tmp_native_type = intermediate_native_type(src_channel.size + dst_channel.size, src_channel.sign and dst_channel.sign)
- value = '(%s)%s' % (tmp_native_type, value)
+ value = '((%s)%s)' % (tmp_native_type, value)
value = '(%s * 0x%x / 0x%x)' % (value, dst_one, src_one)
value = '(%s)%s' % (dst_native_type, value)
return value
@@ -307,6 +304,8 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix):
'''Generate the function to unpack pixels from a particular format'''
+ assert format.layout == PLAIN
+
name = format.short_name()
src_native_type = native_type(format)
@@ -314,32 +313,99 @@ def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix):
print 'static INLINE void'
print 'util_format_%s_unpack_%s(%s *dst, const void *src)' % (name, dst_suffix, dst_native_type)
print '{'
- print ' union util_format_%s pixel;' % format.short_name()
- print ' memcpy(&pixel, src, sizeof pixel);'
- bswap_format(format)
+
+ if format.is_bitmask():
+ depth = format.block_size()
+ print ' uint%u_t value = *(uint%u_t *)src;' % (depth, depth)
- assert format.layout == PLAIN
+ # Declare the intermediate variables
+ for i in range(format.nr_channels()):
+ src_channel = format.channels[i]
+ if src_channel.type == UNSIGNED:
+ print ' uint%u_t %s;' % (depth, src_channel.name)
+ elif src_channel.type == SIGNED:
+ print ' int%u_t %s;' % (depth, src_channel.name)
- for i in range(4):
- swizzle = format.swizzles[i]
- if swizzle < 4:
- src_channel = format.channels[swizzle]
- value = 'pixel.chan.%s' % src_channel.name
- value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
- elif swizzle == SWIZZLE_0:
- value = '0'
- elif swizzle == SWIZZLE_1:
- value = get_one(dst_channel)
- elif swizzle == SWIZZLE_NONE:
- value = '0'
- else:
- assert False
- if format.colorspace == ZS:
- if i == 3:
+ print '#ifdef PIPE_ARCH_BIG_ENDIAN'
+ print ' value = util_bswap%u(value);' % depth
+ print '#endif'
+
+ # Compute the intermediate unshifted values
+ shift = 0
+ for i in range(format.nr_channels()):
+ src_channel = format.channels[i]
+ value = 'value'
+ if src_channel.type == UNSIGNED:
+ if shift:
+ value = '%s >> %u' % (value, shift)
+ if shift + src_channel.size < depth:
+ value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1)
+ elif src_channel.type == SIGNED:
+ if shift + src_channel.size < depth:
+ # Align the sign bit
+ lshift = depth - (shift + src_channel.size)
+ value = '%s << %u' % (value, lshift)
+ # Cast to signed
+ value = '(int%u_t)(%s) ' % (depth, value)
+ if src_channel.size < depth:
+ # Align the LSB bit
+ rshift = depth - src_channel.size
+ value = '(%s) >> %u' % (value, rshift)
+ else:
+ value = None
+
+ if value is not None:
+ print ' %s = %s;' % (src_channel.name, value)
+
+ shift += src_channel.size
+
+ # Convert, swizzle, and store final values
+ for i in range(4):
+ swizzle = format.swizzles[i]
+ if swizzle < 4:
+ src_channel = format.channels[swizzle]
+ value = src_channel.name
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
+ value = get_one(dst_channel)
+ elif swizzle == SWIZZLE_NONE:
+ value = '0'
+ else:
+ assert False
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = 'dst[0]'
+ print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
+
+ else:
+ print ' union util_format_%s pixel;' % format.short_name()
+ print ' memcpy(&pixel, src, sizeof pixel);'
+ bswap_format(format)
+
+ for i in range(4):
+ swizzle = format.swizzles[i]
+ if swizzle < 4:
+ src_channel = format.channels[swizzle]
+ value = 'pixel.chan.%s' % src_channel.name
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
value = get_one(dst_channel)
- elif i >= 1:
- value = 'dst[0]'
- print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
+ elif swizzle == SWIZZLE_NONE:
+ value = '0'
+ else:
+ assert False
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = 'dst[0]'
+ print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
print '}'
print
@@ -352,31 +418,70 @@ def generate_format_pack(format, src_channel, src_native_type, src_suffix):
dst_native_type = native_type(format)
- print 'static INLINE void'
- print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
- print '{'
- print ' union util_format_%s pixel;' % format.short_name()
-
assert format.layout == PLAIN
inv_swizzle = format.inv_swizzles()
+
+ print 'static INLINE void'
+ print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
+ print '{'
+
+ if format.is_bitmask():
+ depth = format.block_size()
+ print ' uint%u_t value = 0;' % depth
+
+ shift = 0
+ for i in range(4):
+ dst_channel = format.channels[i]
+ if inv_swizzle[i] is not None:
+ value = 'rgba'[inv_swizzle[i]]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = '0'
+ if dst_channel.type in (UNSIGNED, SIGNED):
+ if shift + dst_channel.size < depth:
+ value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1)
+ if shift:
+ value = '(%s) << %u' % (value, shift)
+ if dst_channel.type == SIGNED:
+ # Cast to unsigned
+ value = '(uint%u_t)(%s) ' % (depth, value)
+ else:
+ value = None
+ if value is not None:
+ print ' value |= %s;' % (value)
+
+ shift += dst_channel.size
- for i in range(4):
- dst_channel = format.channels[i]
- width = dst_channel.size
- if inv_swizzle[i] is None:
- continue
- value = 'rgba'[inv_swizzle[i]]
- value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
- if format.colorspace == ZS:
- if i == 3:
- value = get_one(dst_channel)
- elif i >= 1:
- value = '0'
- print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
+ print '#ifdef PIPE_ARCH_BIG_ENDIAN'
+ print ' value = util_bswap%u(value);' % depth
+ print '#endif'
+
+ print ' *(uint%u_t *)dst = value;' % depth
- bswap_format(format)
- print ' memcpy(dst, &pixel, sizeof pixel);'
+ else:
+ print ' union util_format_%s pixel;' % format.short_name()
+
+ for i in range(4):
+ dst_channel = format.channels[i]
+ width = dst_channel.size
+ if inv_swizzle[i] is None:
+ continue
+ value = 'rgba'[inv_swizzle[i]]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = '0'
+ print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
+
+ bswap_format(format)
+ print ' memcpy(dst, &pixel, sizeof pixel);'
+
print '}'
print
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
index 250926418e..f74dc5e88a 100755
--- a/src/gallium/auxiliary/util/u_format_parse.py
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -78,7 +78,7 @@ class Channel:
if self.type == UNSIGNED:
return (1 << self.size) - 1
if self.type == SIGNED:
- return self.size - 1
+ return (1 << (self.size - 1)) - 1
assert False
def min(self):
@@ -166,17 +166,11 @@ class Format:
return True
def is_bitmask(self):
- if self.block_size() > 32:
- return False
- if not self.is_pot():
+ if self.block_size() not in (8, 16, 32):
return False
for channel in self.channels:
- if not is_pot(channel.size):
- return True
if channel.type not in (VOID, UNSIGNED, SIGNED):
return False
- if channel.size >= 32:
- return False
return True
def inv_swizzles(self):
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 4e29d15f3b..fb68852a53 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -90,11 +90,13 @@ def write_format_table(formats):
print 'util_format_none_description = {'
print " PIPE_FORMAT_NONE,"
print " \"PIPE_FORMAT_NONE\","
+ print " \"none\","
print " {0, 0, 0},"
print " 0,"
print " 0,"
print " 0,"
print " 0,"
+ print " 0,"
print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
print " {0, 0, 0, 0},"
print " 0"
@@ -105,10 +107,12 @@ def write_format_table(formats):
print 'util_format_%s_description = {' % (format.short_name(),)
print " %s," % (format.name,)
print " \"%s\"," % (format.name,)
+ print " \"%s\"," % (format.short_name(),)
print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
print " %s," % (layout_map(format.layout),)
print " %u,\t/* nr_channels */" % (format.nr_channels(),)
print " %s,\t/* is_array */" % (bool_map(format.is_array()),)
+ print " %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)
print " %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)
print " {"
for i in range(4):
diff --git a/src/gallium/auxiliary/util/u_format_tests.c b/src/gallium/auxiliary/util/u_format_tests.c
new file mode 100644
index 0000000000..182a474044
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_tests.c
@@ -0,0 +1,544 @@
+/**************************************************************************
+ *
+ * Copyright 2009-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_memory.h"
+#include "u_format_tests.h"
+
+
+/*
+ * Helper macros to create the packed bytes for longer words.
+ */
+
+#define PACKED_1x8(x) {x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x8(x, y) {x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x8(x, y, z) {x, y, z, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_4x8(x, y, z, w) {x, y, z, w, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+#define PACKED_1x16(x) {(x) & 0xff, (x) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x16(x, y) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x16(x, y, z) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_4x16(x, y, z, w) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, (w) & 0xff, (w) >> 8, 0, 0, 0, 0, 0, 0, 0, 0}
+
+#define PACKED_1x32(x) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x32(x, y) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x32(x, y, z) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, 0, 0, 0, 0}
+#define PACKED_4x32(x, y, z, w) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, (w) & 0xff, ((w) >> 8) & 0xff, ((w) >> 16) & 0xff, (w) >> 24}
+
+
+/**
+ * Test cases.
+ *
+ * These were manually entered. We could generate these
+ *
+ * To keep this to a we cover only the corner cases, which should produce
+ * good enough coverage since that pixel format transformations are afine for
+ * non SRGB formats.
+ */
+const struct util_format_test_case
+util_format_test_cases[] =
+{
+
+ /*
+ * 32-bit rendertarget formats
+ */
+
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000003ff), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000ffc00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x3ff00000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * 16-bit rendertarget formats
+ */
+
+ {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}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00f0), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0f00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x07e0), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf800), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * Luminance/intensity/alpha formats
+ */
+
+ {PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {0.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00ff), {1.0, 1.0, 1.0, 0.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xff00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * TODO: SRGB formats
+ */
+
+ /*
+ * Mixed-signed formats
+ */
+
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x81, 0x00, 0x00, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x81, 0x00, 0x00), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0xff, 0x00), { 0.0, 0.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0011), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x01e0), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0220), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0xfc00), { 0.0, 0.0, 1.0, 1.0}},
+
+ /*
+ * TODO: Depth-stencil formats
+ */
+
+ /*
+ * TODO: YUV formats
+ */
+
+ /*
+ * TODO: Compressed formats
+ */
+
+ /*
+ * Standard 8-bit integer formats
+ */
+
+ {PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0xff), {255.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), {255.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), { 0.0, 255.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), {255.0, 255.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), {255.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), { 0.0, 255.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), { 0.0, 0.0, 255.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), {255.0, 255.0, 255.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), {255.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), { 0.0, 255.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), { 0.0, 0.0, 255.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), { 0.0, 0.0, 0.0, 255.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), {255.0, 255.0, 255.0, 255.0}},
+
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x7f), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x81), {-1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x81, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x81), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x81, 0x00, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x81, 0x00), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x81), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x81, 0x00, 0x00, 0x00), {-1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x81, 0x00, 0x00), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x81, 0x00), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x81), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x7f), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x80), {-128.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x80, 0x00), {-128.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), { 0.0, 127.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x80), { 0.0, -128.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x80, 0x00, 0x00), {-128.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), { 0.0, 127.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x80, 0x00), { 0.0, -128.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), { 0.0, 0.0, 127.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x80), { 0.0, 0.0, -128.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 127.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0x00, 0x00, 0x00), {-128.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 127.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x80, 0x00, 0x00), { 0.0, -128.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), { 0.0, 0.0, 127.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x80, 0x00), { 0.0, 0.0, -128.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), { 0.0, 0.0, 0.0, 127.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x80), { 0.0, 0.0, 0.0, -128.0}},
+
+ /*
+ * Standard 16-bit integer formats
+ */
+
+ {PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {65535.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), {65535.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), { 0.0, 65535.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), {65535.0, 65535.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), {65535.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), { 0.0, 65535.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), { 0.0, 0.0, 65535.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), {65535.0, 65535.0, 65535.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), {65535.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), { 0.0, 65535.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), { 0.0, 0.0, 65535.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), { 0.0, 0.0, 0.0, 65535.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), {65535.0, 65535.0, 65535.0, 65535.0}},
+
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8001), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8001, 0x0000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8001), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8001, 0x0000, 0x0000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8001, 0x0000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8001), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8001, 0x0000, 0x0000, 0x0000), { -1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8001, 0x0000, 0x0000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8001, 0x0000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8001), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x8000), {-32768.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8000, 0x0000), {-32768.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), { 0.0, 32767.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8000), { 0.0, -32768.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8000, 0x0000, 0x0000), {-32768.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), { 0.0, 32767.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8000, 0x0000), { 0.0, -32768.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 32767.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8000), { 0.0, 0.0, -32768.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), { 32767.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8000, 0x0000, 0x0000, 0x0000), {-32768.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), { 0.0, 32767.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8000, 0x0000, 0x0000), { 0.0, -32768.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), { 0.0, 0.0, 32767.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8000, 0x0000), { 0.0, 0.0, -32768.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 0.0, 32767.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8000), { 0.0, 0.0, 0.0, -32768.0}},
+
+ /*
+ * Standard 32-bit integer formats
+ *
+ * NOTE: We can't accurately represent integers larger than +/-0x1000000
+ * with single precision floats, so that's as far as we test.
+ */
+
+ {PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0x00000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xffffffff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0xffffffff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0x00000000, 0x00000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xffffffff, 0x00000000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xffffffff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0x00000000, 0x00000000, 0x00000000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xffffffff, 0x00000000, 0x00000000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xffffffff, 0x00000000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xffffffff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), {16777216.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), {16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x01000000), {16777216.0, 16777216.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), {16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 16777216.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x01000000, 0x01000000), {16777216.0, 16777216.0, 16777216.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), {16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), { 0.0, 16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), { 0.0, 0.0, 16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 0.0, 16777216.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x01000000, 0x01000000, 0x01000000), {16777216.0, 16777216.0, 16777216.0, 16777216.0}},
+
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x7fffffff), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x80000001), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x7fffffff, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x80000001, 0x00000000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x7fffffff), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x80000001), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x7fffffff, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x80000001, 0x00000000, 0x00000000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x7fffffff, 0x00000000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x80000001, 0x00000000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x7fffffff), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x80000001), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x7fffffff, 0x00000000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x80000001, 0x00000000, 0x00000000, 0x00000000), { -1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x7fffffff, 0x00000000, 0x00000000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x80000001, 0x00000000, 0x00000000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x7fffffff, 0x00000000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x80000001, 0x00000000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x7fffffff), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x80000001), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {-16777216.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xff000000, 0x00000000), {-16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xff000000), { 0.0, -16777216.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xff000000, 0x00000000, 0x00000000), {-16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xff000000, 0x00000000), { 0.0, -16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 16777216.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xff000000), { 0.0, 0.0, -16777216.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), { 16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xff000000, 0x00000000, 0x00000000, 0x00000000), {-16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), { 0.0, 16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xff000000, 0x00000000, 0x00000000), { 0.0, -16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), { 0.0, 0.0, 16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xff000000, 0x00000000), { 0.0, 0.0, -16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 0.0, 16777216.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xff000000), { 0.0, 0.0, 0.0, -16777216.0}},
+
+ /*
+ * Standard 32-bit float formats
+ */
+
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x3f800000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0xbf800000), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xbf800000, 0x00000000), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x3f800000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xbf800000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x3f800000), { 1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xbf800000, 0x00000000, 0x00000000), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x3f800000, 0x00000000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xbf800000, 0x00000000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x3f800000), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xbf800000), { 0.0, 0.0, -1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x3f800000, 0x3f800000), { 1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x00000000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xbf800000, 0x00000000, 0x00000000, 0x00000000), {-1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x3f800000, 0x00000000, 0x00000000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xbf800000, 0x00000000, 0x00000000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x3f800000, 0x00000000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xbf800000, 0x00000000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x3f800000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xbf800000), { 0.0, 0.0, 0.0, -1.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000), { 1.0, 1.0, 1.0, 1.0}},
+};
+
+
+const unsigned util_format_nr_test_cases = Elements(util_format_test_cases);
diff --git a/src/gallium/auxiliary/util/u_format_tests.h b/src/gallium/auxiliary/util/u_format_tests.h
new file mode 100644
index 0000000000..2d4d9d5fa9
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_tests.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * 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 SOFTWARE IS PROVIDED "AS 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.
+ *
+ **************************************************************************/
+
+
+#ifndef U_FORMAT_TESTS_H_
+#define U_FORMAT_TESTS_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+
+#define UTIL_FORMAT_MAX_PACKED_BYTES 16
+
+
+/**
+ * A (packed, unpacked) color pair.
+ */
+struct util_format_test_case
+{
+ enum pipe_format format;
+
+ /**
+ * Mask of the bits that actually meaningful data. Used to mask out the
+ * "X" channels.
+ */
+ uint8_t mask[UTIL_FORMAT_MAX_PACKED_BYTES];
+
+ uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
+
+ /**
+ * RGBA.
+ */
+ double unpacked[4];
+};
+
+
+extern const struct util_format_test_case
+util_format_test_cases[];
+
+
+extern const unsigned util_format_nr_test_cases;
+
+
+#endif /* U_FORMAT_TESTS_H_ */
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index fc027e48e4..d421bee8ef 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -62,6 +62,7 @@ struct gen_mipmap_state
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
struct pipe_clip_state clip;
+ struct pipe_vertex_element velem[2];
void *vs;
void *fs2d, *fsCube;
@@ -1307,6 +1308,15 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
ctx->sampler.normalized_coords = 1;
+ /* vertex elements state */
+ memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ ctx->velem[i].src_offset = i * 4 * sizeof(float);
+ ctx->velem[i].instance_divisor = 0;
+ ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
/* vertex shader - still needed to specify mapping from fragment
* shader input semantics to vertex elements
*/
@@ -1501,12 +1511,14 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_save_vertex_shader(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* bind our state */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
cso_set_fragment_shader_handle(ctx->cso, fs);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
@@ -1593,4 +1605,5 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 53f3c16dbc..9203cb6580 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -59,22 +59,7 @@ pass_user_buffer_create(struct pipe_screen *screen,
return buffer;
}
-static struct pipe_buffer *
-pass_surface_buffer_create(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- struct pipe_buffer *buffer =
- screen->winsys->surface_buffer_create(screen->winsys, width, height,
- format, usage, tex_usage, stride);
- buffer->screen = screen;
-
- return buffer;
-}
static void *
pass_buffer_map(struct pipe_screen *screen,
@@ -135,7 +120,6 @@ u_simple_screen_init(struct pipe_screen *screen)
{
screen->buffer_create = pass_buffer_create;
screen->user_buffer_create = pass_user_buffer_create;
- screen->surface_buffer_create = pass_surface_buffer_create;
screen->buffer_map = pass_buffer_map;
screen->buffer_unmap = pass_buffer_unmap;
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index ba23435f69..6d461cb880 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -230,6 +230,7 @@ static bool
init_pipe_state(struct vl_compositor *c)
{
struct pipe_sampler_state sampler;
+ struct pipe_vertex_element vertex_elems[2];
assert(c);
@@ -251,15 +252,27 @@ init_pipe_state(struct vl_compositor *c)
/*sampler.border_color[i] = ;*/
/*sampler.max_anisotropy = ;*/
c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
-
+
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ vertex_elems[1].src_offset = 0;
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 1;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ c->vertex_elems = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
+
+
return true;
}
static void cleanup_pipe_state(struct vl_compositor *c)
{
assert(c);
-
+
c->pipe->delete_sampler_state(c->pipe, c->sampler);
+ c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems);
}
static bool
@@ -314,12 +327,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer);
- c->vertex_elems[0].src_offset = 0;
- c->vertex_elems[0].instance_divisor = 0;
- c->vertex_elems[0].vertex_buffer_index = 0;
- c->vertex_elems[0].nr_components = 2;
- c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
/*
* Create our texcoord buffer and texcoord buffer element
* Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices
@@ -344,12 +351,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer);
- c->vertex_elems[1].src_offset = 0;
- c->vertex_elems[1].instance_divisor = 0;
- c->vertex_elems[1].vertex_buffer_index = 1;
- c->vertex_elems[1].nr_components = 2;
- c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
/*
* Create our vertex shader's constant buffer
* Const buffer contains scaling and translation vectors
@@ -483,7 +484,7 @@ void vl_compositor_render(struct vl_compositor *compositor,
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
- compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems);
+ compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index 6a9a3fd7af..51755554da 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -43,10 +43,10 @@ struct vl_compositor
void *sampler;
void *vertex_shader;
void *fragment_shader;
+ void *vertex_elems;
struct pipe_viewport_state viewport;
struct pipe_scissor_state scissor;
struct pipe_vertex_buffer vertex_bufs[2];
- struct pipe_vertex_element vertex_elems[2];
struct pipe_buffer *vs_const_buf, *fs_const_buf;
};
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index f323de0ea5..0763b5bb0e 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -708,6 +708,7 @@ static bool
init_pipe_state(struct vl_mpeg12_mc_renderer *r)
{
struct pipe_sampler_state sampler;
+ struct pipe_vertex_element vertex_elems[8];
unsigned filters[5];
unsigned i;
@@ -771,6 +772,59 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
}
+ /* Position element */
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Luma, texcoord element */
+ vertex_elems[1].src_offset = sizeof(struct vertex2f);
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 0;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cr texcoord element */
+ vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
+ vertex_elems[2].instance_divisor = 0;
+ vertex_elems[2].vertex_buffer_index = 0;
+ vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cb texcoord element */
+ vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
+ vertex_elems[3].instance_divisor = 0;
+ vertex_elems[3].vertex_buffer_index = 0;
+ vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface top field texcoord element */
+ vertex_elems[4].src_offset = 0;
+ vertex_elems[4].instance_divisor = 0;
+ vertex_elems[4].vertex_buffer_index = 1;
+ vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface bottom field texcoord element */
+ vertex_elems[5].src_offset = sizeof(struct vertex2f);
+ vertex_elems[5].instance_divisor = 0;
+ vertex_elems[5].vertex_buffer_index = 1;
+ vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface top field texcoord element */
+ vertex_elems[6].src_offset = 0;
+ vertex_elems[6].instance_divisor = 0;
+ vertex_elems[6].vertex_buffer_index = 2;
+ vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface bottom field texcoord element */
+ vertex_elems[7].src_offset = sizeof(struct vertex2f);
+ vertex_elems[7].instance_divisor = 0;
+ vertex_elems[7].vertex_buffer_index = 2;
+ vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* need versions with 4,6 and 8 vertex elems */
+ r->vertex_elems[0] = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
+ r->vertex_elems[1] = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
+ r->vertex_elems[2] = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
+
return true;
}
@@ -783,6 +837,8 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
for (i = 0; i < 5; ++i)
r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
+ for (i = 0; i < 3; i++)
+ r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems[i]);
}
static bool
@@ -888,62 +944,6 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
);
}
- /* Position element */
- r->vertex_elems[0].src_offset = 0;
- r->vertex_elems[0].instance_divisor = 0;
- r->vertex_elems[0].vertex_buffer_index = 0;
- r->vertex_elems[0].nr_components = 2;
- r->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Luma, texcoord element */
- r->vertex_elems[1].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[1].instance_divisor = 0;
- r->vertex_elems[1].vertex_buffer_index = 0;
- r->vertex_elems[1].nr_components = 2;
- r->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cr texcoord element */
- r->vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
- r->vertex_elems[2].instance_divisor = 0;
- r->vertex_elems[2].vertex_buffer_index = 0;
- r->vertex_elems[2].nr_components = 2;
- r->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cb texcoord element */
- r->vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
- r->vertex_elems[3].instance_divisor = 0;
- r->vertex_elems[3].vertex_buffer_index = 0;
- r->vertex_elems[3].nr_components = 2;
- r->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface top field texcoord element */
- r->vertex_elems[4].src_offset = 0;
- r->vertex_elems[4].instance_divisor = 0;
- r->vertex_elems[4].vertex_buffer_index = 1;
- r->vertex_elems[4].nr_components = 2;
- r->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface bottom field texcoord element */
- r->vertex_elems[5].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[5].instance_divisor = 0;
- r->vertex_elems[5].vertex_buffer_index = 1;
- r->vertex_elems[5].nr_components = 2;
- r->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface top field texcoord element */
- r->vertex_elems[6].src_offset = 0;
- r->vertex_elems[6].instance_divisor = 0;
- r->vertex_elems[6].vertex_buffer_index = 2;
- r->vertex_elems[6].nr_components = 2;
- r->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface bottom field texcoord element */
- r->vertex_elems[7].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[7].instance_divisor = 0;
- r->vertex_elems[7].vertex_buffer_index = 2;
- r->vertex_elems[7].nr_components = 2;
- r->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
r->vs_const_buf = pipe_buffer_create
(
r->pipe->screen,
@@ -1307,7 +1307,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[0]);
r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->i_vs);
@@ -1320,7 +1320,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1334,7 +1334,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1348,7 +1348,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1362,7 +1362,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1376,7 +1376,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
@@ -1391,7 +1391,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
index f00b8c7b8b..a11a3e7307 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
@@ -66,8 +66,8 @@ struct vl_mpeg12_mc_renderer
struct pipe_buffer *vs_const_buf;
struct pipe_buffer *fs_const_buf;
struct pipe_framebuffer_state fb_state;
- struct pipe_vertex_element vertex_elems[8];
-
+ void *vertex_elems[3];
+
union
{
void *all[5];
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 9080addba4..4608e97adb 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -24,6 +24,7 @@ CSO objects handled by the context object:
* :ref:`Depth, Stencil, & Alpha`: ``*_depth_stencil_alpha_state``
* :ref:`Shader`: These have two sets of methods. ``*_fs_state`` is for
fragment shaders, and ``*_vs_state`` is for vertex shaders.
+* :ref:`Vertex Elements`: ``*_vertex_elements_state``
Resource Binding State
@@ -60,7 +61,6 @@ objects. They all follow simple, one-method binding calls, e.g.
not have the scissor test enabled, then the scissor bounds never need to
be set since they will not be used.
* ``set_viewport_state``
-* ``set_vertex_elements``
Clearing
diff --git a/src/gallium/docs/source/cso/velems.rst b/src/gallium/docs/source/cso/velems.rst
new file mode 100644
index 0000000000..8e758fae10
--- /dev/null
+++ b/src/gallium/docs/source/cso/velems.rst
@@ -0,0 +1,24 @@
+.. _vertex,elements
+
+Vertex Elements
+===============
+
+This state controls format etc. of the input attributes contained
+in the pipe_vertex_buffer(s). There's one pipe_vertex_element array member
+for each input attribute.
+
+Members
+-------
+
+src_offset
+ The byte offset of the attribute in the buffer given by
+ vertex_buffer_index for the first vertex.
+instance_divisor
+ The instance data rate divisor, used for instancing.
+ 0 means this is per-vertex data, n means per-instance data used for
+ n consecutive instances (n > 0).
+vertex_buffer_index
+ The vertex buffer this attribute lives in. Several attributes may
+ live in the same vertex buffer.
+src_format
+ The format of the attribute data. One of the PIPE_FORMAT tokens.
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile
index c92f8e5cba..8769b826b5 100644
--- a/src/gallium/drivers/cell/ppu/Makefile
+++ b/src/gallium/drivers/cell/ppu/Makefile
@@ -21,6 +21,7 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a
SOURCES = \
cell_batch.c \
+ cell_buffer.c \
cell_clear.c \
cell_context.c \
cell_draw_arrays.c \
diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.c b/src/gallium/drivers/cell/ppu/cell_buffer.c
new file mode 100644
index 0000000000..f56a28d62e
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "cell_screen.h"
+#include "cell_buffer.h"
+
+
+static void *
+cell_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct cell_buffer *cell_buf = cell_buffer(buf);
+ return cell_buf->data;
+}
+
+
+static void
+cell_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+cell_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct cell_buffer *sbuf = cell_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+cell_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct cell_buffer *buffer = CALLOC_STRUCT(cell_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+cell_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct cell_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(cell_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = cell_buffer_create;
+ screen->user_buffer_create = cell_user_buffer_create;
+ screen->buffer_map = cell_buffer_map;
+ screen->buffer_unmap = cell_buffer_unmap;
+ screen->buffer_destroy = cell_buffer_destroy;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/drivers/cell/ppu/cell_buffer.h
index e227e065ff..ef0a8a70e5 100644
--- a/src/gallium/drivers/cell/ppu/cell_winsys.h
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * 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
@@ -10,38 +10,46 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * 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 CELL_WINSYS_H
-#define CELL_WINSYS_H
+#ifndef SP_BUFFER_H
+#define SP_BUFFER_H
#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
-/**
- * Very simple winsys at this time.
- * Will probably eventually add SPU control info.
- */
-struct cell_winsys
+struct cell_buffer
{
- uint dummy;
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
};
+/** Cast wrapper */
+static INLINE struct cell_buffer *
+cell_buffer( struct pipe_buffer *buf )
+{
+ return (struct cell_buffer *)buf;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen);
-#endif
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 5bff9869fd..afcea616d5 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -36,7 +36,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_screen.h"
#include "draw/draw_context.h"
@@ -137,7 +136,7 @@ cell_create_context(struct pipe_screen *screen,
memset(cell, 0, sizeof(*cell));
cell->winsys = NULL; /* XXX: fixme - get this from screen? */
- cell->pipe.winsys = screen->winsys;
+ cell->pipe.winsys = NULL;
cell->pipe.screen = screen;
cell->pipe.priv = priv;
cell->pipe.destroy = cell_destroy_context;
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index a77cc5b906..28f80b82cd 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -34,7 +34,7 @@
#include "pipe/p_defines.h"
#include "draw/draw_vertex.h"
#include "draw/draw_vbuf.h"
-#include "cell_winsys.h"
+/*#include "cell_winsys.h"*/
#include "cell/common.h"
#include "rtasm/rtasm_ppc_spe.h"
#include "tgsi/tgsi_scan.h"
@@ -93,6 +93,11 @@ struct cell_buffer_list
struct cell_buffer_node *head;
};
+struct cell_velems_state
+{
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+}
/**
* Per-context state, subclass of pipe_context.
@@ -110,6 +115,7 @@ struct cell_context
const struct pipe_rasterizer_state *rasterizer;
const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs;
+ const struct cell_velems_state *velems;
struct spe_function logic_op;
@@ -125,8 +131,6 @@ struct cell_context
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- uint num_vertex_elements;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index bffd0fac6f..15d4e8338f 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -33,48 +33,18 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_state.h"
#include "cell_flush.h"
+#include "cell_buffer.h"
#include "draw/draw_context.h"
-static void
-cell_map_constant_buffers(struct cell_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- for (i = 0; i < 2; i++) {
- if (sp->constants[i] && sp->constants[i]->size) {
- sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i],
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, sp->mapped_constants[i],
- sp->constants[i]->size);
- }
- }
-
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0,
- sp->mapped_constants[PIPE_SHADER_VERTEX],
- sp->constants[PIPE_SHADER_VERTEX]->size);
-}
-
-static void
-cell_unmap_constant_buffers(struct cell_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- for (i = 0; i < 2; i++) {
- if (sp->constants[i] && sp->constants[i]->size)
- ws->buffer_unmap(ws, sp->constants[i]);
- sp->mapped_constants[i] = NULL;
- }
-}
@@ -93,33 +63,27 @@ cell_draw_range_elements(struct pipe_context *pipe,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
{
- struct cell_context *sp = cell_context(pipe);
- struct draw_context *draw = sp->draw;
+ struct cell_context *cell = cell_context(pipe);
+ struct draw_context *draw = cell->draw;
unsigned i;
- if (sp->dirty)
- cell_update_derived( sp );
+ if (cell->dirty)
+ cell_update_derived( cell );
#if 0
- cell_map_surfaces(sp);
+ cell_map_surfaces(cell);
#endif
- cell_map_constant_buffers(sp);
/*
* Map vertex buffers
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
+ void *buf = cell_buffer(cell->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = cell_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -134,17 +98,19 @@ cell_draw_range_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- cell_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c
index e10071529a..035ef41b89 100644
--- a/src/gallium/drivers/cell/ppu/cell_fence.c
+++ b/src/gallium/drivers/cell/ppu/cell_fence.c
@@ -92,7 +92,6 @@ cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list,
struct pipe_buffer *buffer)
{
- struct pipe_screen *ps = cell->pipe.screen;
struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node);
/* create new list node which references the buffer, insert at head */
if (node) {
@@ -157,8 +156,13 @@ cell_add_fenced_textures(struct cell_context *cell)
printf("Adding texture %p buffer %p to list\n",
ct, ct->tiled_buffer[level]);
#endif
- if (ct->buffer)
+#if 00
+ /* XXX this needs to be fixed/restored!
+ * Maybe keep pointers to textures, not buffers.
+ */
+ if (ct->base.buffer)
cell_add_buffer_to_list(cell, list, ct->buffer);
+#endif
}
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 3d8b4409c7..dce10ae7f8 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -292,17 +292,23 @@ cell_set_sampler_textures(struct pipe_context *pipe,
static void
cell_map_surfaces(struct cell_context *cell)
{
+#if 0
struct pipe_screen *screen = cell->pipe.screen;
+#endif
uint i;
for (i = 0; i < 1; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->cbuf_map[i] = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->cbuf_map[i] = ct->data;
+#endif
}
}
@@ -310,10 +316,14 @@ cell_map_surfaces(struct cell_context *cell)
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->zsbuf_map = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->zsbuf_map = ct->data;
+#endif
}
}
}
@@ -325,17 +335,17 @@ cell_map_surfaces(struct cell_context *cell)
static void
cell_unmap_surfaces(struct cell_context *cell)
{
- struct pipe_screen *screen = cell->pipe.screen;
+ /*struct pipe_screen *screen = cell->pipe.screen;*/
uint i;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps && cell->cbuf_map[i]) {
- struct cell_texture *ct = cell_texture(ps->texture);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
assert(ps->texture);
- assert(ct->buffer);
+ /*assert(ct->buffer);*/
- screen->buffer_unmap(screen, ct->buffer);
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->cbuf_map[i] = NULL;
}
}
@@ -343,8 +353,8 @@ cell_unmap_surfaces(struct cell_context *cell)
{
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps && cell->zsbuf_map) {
- struct cell_texture *ct = cell_texture(ps->texture);
- screen->buffer_unmap(screen, ct->buffer);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->zsbuf_map = NULL;
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_public.h b/src/gallium/drivers/cell/ppu/cell_public.h
new file mode 100644
index 0000000000..7e2e093565
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_public.h
@@ -0,0 +1,10 @@
+#ifndef CELL_PUBLIC_H
+#define CELL_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+cell_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index a43f8638dc..31fd963d19 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -28,7 +28,6 @@
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -36,7 +35,10 @@
#include "cell_context.h"
#include "cell_screen.h"
#include "cell_texture.h"
-#include "cell_winsys.h"
+#include "cell_buffer.h"
+#include "cell_public.h"
+
+#include "state_tracker/sw_winsys.h"
static const char *
@@ -134,19 +136,28 @@ cell_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
- /* cell supports most formats, XXX for now anyway */
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+
if (format == PIPE_FORMAT_DXT5_RGBA ||
format == PIPE_FORMAT_A8B8G8R8_SRGB)
return FALSE;
- else
- return TRUE;
+
+ if (tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if (!winsys->is_displaytarget_format_supported(winsys, format))
+ return FALSE;
+ }
+
+ /* This is often a lie. Pull in logic from llvmpipe to fix.
+ */
+ return TRUE;
}
static void
cell_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct cell_screen *sp_screen = cell_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -155,32 +166,34 @@ cell_destroy_screen( struct pipe_screen *screen )
}
+
/**
* Create a new pipe_screen object
* Note: we're not presently subclassing pipe_screen (no cell_screen) but
* that would be the place to put SPU thread/context info...
*/
struct pipe_screen *
-cell_create_screen(struct pipe_winsys *winsys)
+cell_create_screen(struct sw_winsys *winsys)
{
- struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+ struct cell_screen *screen = CALLOC_STRUCT(cell_screen);
if (!screen)
return NULL;
screen->winsys = winsys;
+ screen->base.winsys = NULL;
- screen->destroy = cell_destroy_screen;
+ screen->base.destroy = cell_destroy_screen;
- screen->get_name = cell_get_name;
- screen->get_vendor = cell_get_vendor;
- screen->get_param = cell_get_param;
- screen->get_paramf = cell_get_paramf;
- screen->is_format_supported = cell_is_format_supported;
- screen->context_create = cell_create_context;
+ screen->base.get_name = cell_get_name;
+ screen->base.get_vendor = cell_get_vendor;
+ screen->base.get_param = cell_get_param;
+ screen->base.get_paramf = cell_get_paramf;
+ screen->base.is_format_supported = cell_is_format_supported;
+ screen->base.context_create = cell_create_context;
- cell_init_screen_texture_funcs(screen);
- u_simple_screen_init(screen);
+ cell_init_screen_texture_funcs(&screen->base);
+ cell_init_screen_buffer_funcs(&screen->base);
- return screen;
+ return &screen->base;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.h b/src/gallium/drivers/cell/ppu/cell_screen.h
index c7e15889d6..baff9d3b7d 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.h
+++ b/src/gallium/drivers/cell/ppu/cell_screen.h
@@ -30,12 +30,26 @@
#define CELL_SCREEN_H
-struct pipe_screen;
-struct pipe_winsys;
+#include "pipe/p_screen.h"
+struct sw_winsys;
-extern struct pipe_screen *
-cell_create_screen(struct pipe_winsys *winsys);
+struct cell_screen {
+ struct pipe_screen base;
+
+ struct sw_winsys *winsys;
+
+ /* Increments whenever textures are modified. Contexts can track
+ * this.
+ */
+ unsigned timestamp;
+};
+
+static INLINE struct cell_screen *
+cell_screen( struct pipe_screen *pipe )
+{
+ return (struct cell_screen *)pipe;
+}
#endif /* CELL_SCREEN_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index a59c7828ac..424e2628a9 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -245,16 +245,13 @@ cell_emit_state(struct cell_context *cell)
uint i, j;
float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float)));
uint32_t *ibuf = (uint32_t *) buf;
- const float *constants = pipe_buffer_map(cell->pipe.screen,
- cell->constants[shader],
- PIPE_BUFFER_USAGE_CPU_READ);
+ const float *constants = cell->mapped_constants[shader];
ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS;
ibuf[4] = num_const;
j = 8;
for (i = 0; i < num_const; i++) {
buf[j++] = constants[i];
}
- pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader]);
}
if (cell->dirty & (CELL_NEW_FRAMEBUFFER |
diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index 9b2f86fdfb..9e29ddc2d4 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -28,13 +28,13 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_parse.h"
#include "cell_context.h"
#include "cell_state.h"
#include "cell_gen_fp.h"
+#include "cell_buffer.h"
/** cast wrapper */
@@ -183,17 +183,29 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs)
static void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct cell_context *cell = cell_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? cell_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
+ if (cell->constants[shader] == constants)
+ return;
+
draw_flush(cell->draw);
/* note: reference counting */
- pipe_buffer_reference(&cell->constants[shader], buf);
+ pipe_buffer_reference(&cell->constants[shader], constants);
+
+ if(shader == PIPE_SHADER_VERTEX) {
+ draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0,
+ data, size);
+ }
+
+ cell->mapped_constants[shader] = data;
if (shader == PIPE_SHADER_VERTEX)
cell->dirty |= CELL_NEW_VS_CONSTANTS;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index fbe55c8472..9510ea9ac2 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -32,24 +32,44 @@
#include "cell_context.h"
#include "cell_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
-static void
-cell_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+void *
+cell_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct cell_context *cell = cell_context(pipe);
-
+ struct cell_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct cell_velems_state *) MALLOC(sizeof(struct cell_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+void
+cell_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct cell_context *cell = cell_context(pipe);
+ struct cell_velems_state *cell_velems = (struct cell_velems_state *) velems;
- memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
- cell->num_vertex_elements = count;
+ cell->velems = cell_velems;
cell->dirty |= CELL_NEW_VERTEX;
- draw_set_vertex_elements(cell->draw, count, elements);
+ if (cell_velems)
+ draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem);
+}
+
+void
+cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
}
@@ -75,5 +95,7 @@ void
cell_init_vertex_functions(struct cell_context *cell)
{
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
- cell->pipe.set_vertex_elements = cell_set_vertex_elements;
+ cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
+ cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
+ cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index fad290dfa0..c8a1acd86a 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -34,20 +34,23 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "cell_context.h"
+#include "cell_screen.h"
#include "cell_state.h"
#include "cell_texture.h"
+#include "state_tracker/sw_winsys.h"
-static void
-cell_texture_layout(struct cell_texture *ct)
+
+static boolean
+cell_texture_layout(struct pipe_screen *screen,
+ struct cell_texture *ct)
{
struct pipe_texture *pt = &ct->base;
unsigned level;
@@ -83,9 +86,34 @@ cell_texture_layout(struct cell_texture *ct)
height = u_minify(height, 1);
depth = u_minify(depth, 1);
}
+
+ ct->data = align_malloc(ct->buffer_size, 16);
+
+ return ct->data != NULL;
}
+/**
+ * Texture layout for simple color buffers.
+ */
+static boolean
+cell_displaytarget_layout(struct pipe_screen *screen,
+ struct cell_texture * ct)
+{
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ ct->dt = winsys->displaytarget_create(winsys,
+ ct->base.format,
+ ct->base.width0,
+ ct->base.height0,
+ 16,
+ &ct->dt_stride );
+
+ return ct->dt != NULL;
+}
+
static struct pipe_texture *
cell_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
@@ -98,31 +126,46 @@ cell_texture_create(struct pipe_screen *screen,
pipe_reference_init(&ct->base.reference, 1);
ct->base.screen = screen;
- cell_texture_layout(ct);
+ /* Create both a displaytarget (linear) and regular texture
+ * (twiddled). Convert twiddled->linear at flush_frontbuffer time.
+ */
+ if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!cell_displaytarget_layout(screen, ct))
+ goto fail;
+ }
- ct->buffer = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_PIXEL,
- ct->buffer_size);
+ if (!cell_texture_layout(screen, ct))
+ goto fail;
- if (!ct->buffer) {
- FREE(ct);
- return NULL;
+ return &ct->base;
+
+fail:
+ if (ct->dt) {
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- return &ct->base;
+ FREE(ct);
+
+ return NULL;
}
static void
cell_texture_destroy(struct pipe_texture *pt)
{
+ struct cell_screen *screen = cell_screen(pt->screen);
+ struct sw_winsys *winsys = screen->winsys;
struct cell_texture *ct = cell_texture(pt);
- if (ct->mapped) {
- pipe_buffer_unmap(ct->buffer->screen, ct->buffer);
- ct->mapped = NULL;
+ if (ct->dt) {
+ /* display target */
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- pipe_buffer_reference(&ct->buffer, NULL);
+ align_free(ct->data);
FREE(ct);
}
@@ -389,10 +432,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
assert(transfer->texture);
- if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- pipe_transfer_buffer_flags(transfer));
+ if (ct->mapped == NULL) {
+ ct->mapped = ct->data;
}
/*
@@ -442,9 +483,8 @@ cell_transfer_unmap(struct pipe_screen *screen,
const uint stride = ct->stride[level];
if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ assert(0);
+ return;
}
if (transfer->usage & PIPE_TRANSFER_WRITE) {
@@ -467,6 +507,50 @@ cell_transfer_unmap(struct pipe_screen *screen,
}
+
+/* This used to be overriden by the co-state tracker, but really needs
+ * to be active with sw_winsys.
+ *
+ * Contrasting with llvmpipe and softpipe, this is the only place
+ * where we use the ct->dt display target in any real sense.
+ *
+ * Basically just untwiddle our local data into the linear
+ * displaytarget.
+ */
+static void
+cell_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct cell_screen *screen = cell_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct cell_texture *ct = cell_texture(surface->texture);
+
+ if (!ct->dt)
+ return;
+
+ /* Need to untwiddle from our internal representation here:
+ */
+ {
+ unsigned *map = winsys->displaytarget_map(winsys, ct->dt,
+ (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE));
+ unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]);
+
+ untwiddle_image_uint(surface->width,
+ surface->height,
+ TILE_SIZE,
+ map,
+ ct->dt_stride,
+ src);
+
+ winsys->displaytarget_unmap(winsys, ct->dt);
+ }
+
+ winsys->displaytarget_display(winsys, ct->dt, context_private);
+}
+
+
void
cell_init_screen_texture_funcs(struct pipe_screen *screen)
{
@@ -481,4 +565,6 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
screen->transfer_map = cell_transfer_map;
screen->transfer_unmap = cell_transfer_unmap;
+
+ screen->flush_frontbuffer = cell_flush_frontbuffer;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index 3ffc0bfdb5..2be0579312 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -28,6 +28,7 @@
#ifndef CELL_TEXTURE_H
#define CELL_TEXTURE_H
+#include "cell/common.h"
struct cell_context;
struct pipe_texture;
@@ -43,8 +44,20 @@ struct cell_texture
unsigned long level_offset[CELL_MAX_TEXTURE_LEVELS];
unsigned long stride[CELL_MAX_TEXTURE_LEVELS];
- /** The tiled texture data is held in this buffer */
- struct pipe_buffer *buffer;
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
+ */
+ struct sw_displaytarget *dt;
+ unsigned dt_stride;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
+
+ /* Size of the linear buffer??
+ */
unsigned long buffer_size;
/** The buffer above, mapped. This is the memory from which the
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index cf8cd41159..3d389d6ea3 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -31,7 +31,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_math.h"
#include "cell_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 2ccc5d3e60..659e40cbf0 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -27,7 +27,6 @@
#include "pipe/p_defines.h"
-#include "util/u_simple_screen.h"
#include "util/u_memory.h"
#include "pipe/p_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index bb1a168ea7..4a754465bb 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -78,6 +78,7 @@ struct failover_context {
const struct fo_state *rasterizer;
const struct fo_state *fragment_shader;
const struct fo_state *vertex_shader;
+ const struct fo_state *vertex_elements;
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
@@ -89,10 +90,8 @@ struct failover_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- uint num_vertex_elements;
void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS];
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index 970606a3f5..0247fb803b 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -255,9 +255,52 @@ failover_delete_vs_state(struct pipe_context *pipe,
free(state);
}
+
+
+static void *
+failover_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *velems )
+{
+ struct fo_state *state = malloc(sizeof(struct fo_state));
+ struct failover_context *failover = failover_context(pipe);
+
+ state->sw_state = failover->sw->create_vertex_elements_state(failover->sw, count, velems);
+ state->hw_state = failover->hw->create_vertex_elements_state(failover->hw, count, velems);
+
+ return state;
+}
+
+static void
+failover_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems )
+{
+ struct failover_context *failover = failover_context(pipe);
+ struct fo_state *state = (struct fo_state*)velems;
+
+ failover->vertex_elements = state;
+ failover->dirty |= FO_NEW_VERTEX_ELEMENT;
+ failover->sw->bind_vertex_elements_state( failover->sw, velems );
+ failover->hw->bind_vertex_elements_state( failover->hw, velems );
+}
+
+static void
+failover_delete_vertex_elements_state( struct pipe_context *pipe,
+ void *velems )
+{
+ struct fo_state *state = (struct fo_state*)velems;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->delete_vertex_elements_state(failover->sw, state->sw_state);
+ failover->hw->delete_vertex_elements_state(failover->hw, state->hw_state);
+ state->sw_state = 0;
+ state->hw_state = 0;
+ free(state);
+}
+
static void
failover_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
+ const struct pipe_poly_stipple *stipple )
{
struct failover_context *failover = failover_context(pipe);
@@ -490,22 +533,6 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
}
-static void
-failover_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct failover_context *failover = failover_context(pipe);
-
- memcpy(failover->vertex_elements, vertex_elements,
- count * sizeof(vertex_elements[0]));
-
- failover->dirty |= FO_NEW_VERTEX_ELEMENT;
- failover->num_vertex_elements = count;
- failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
- failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
-}
-
void
failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
@@ -543,6 +570,9 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.create_vs_state = failover_create_vs_state;
failover->pipe.bind_vs_state = failover_bind_vs_state;
failover->pipe.delete_vs_state = failover_delete_vs_state;
+ failover->pipe.create_vertex_elements_state = failover_create_vertex_elements_state;
+ failover->pipe.bind_vertex_elements_state = failover_bind_vertex_elements_state;
+ failover->pipe.delete_vertex_elements_state = failover_delete_vertex_elements_state;
failover->pipe.set_blend_color = failover_set_blend_color;
failover->pipe.set_stencil_ref = failover_set_stencil_ref;
@@ -554,6 +584,5 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
- failover->pipe.set_vertex_elements = failover_set_vertex_elements;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
}
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index 5c00080842..09ca194497 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -81,6 +81,10 @@ failover_state_emit( struct failover_context *failover )
failover->sw->bind_vs_state( failover->sw,
failover->vertex_shader->sw_state );
+ if (failover->dirty & FO_NEW_VERTEX_ELEMENT)
+ failover->sw->bind_vertex_elements_state( failover->sw,
+ failover->vertex_elements->sw_state );
+
if (failover->dirty & FO_NEW_STIPPLE)
failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple );
@@ -116,11 +120,5 @@ failover_state_emit( struct failover_context *failover )
failover->vertex_buffers );
}
- if (failover->dirty & FO_NEW_VERTEX_ELEMENT) {
- failover->sw->set_vertex_elements( failover->sw,
- failover->num_vertex_elements,
- failover->vertex_elements );
- }
-
failover->dirty = 0;
}
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index da769e7b29..4994537683 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -148,7 +148,7 @@ struct i915_state
/** Describes the current hardware vertex layout */
struct vertex_info vertex_info;
-
+
unsigned id; /* track lost context events */
};
@@ -187,6 +187,14 @@ struct i915_sampler_state {
unsigned maxlod;
};
+struct i915_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
+#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct i915_texture {
struct pipe_texture base;
@@ -199,7 +207,7 @@ struct i915_texture {
unsigned sw_tiled; /**< tiled with software flags */
unsigned hw_tiled; /**< tiled with hardware fences */
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS];
/* Explicitly store the offset of each image for each cube face or
* depth value. Pretty much have to accept that hardware formats
@@ -207,7 +215,7 @@ struct i915_texture {
* compute the offsets of depth/cube images within a mipmap level,
* so have to store them as a lookup table:
*/
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+ unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */
/* The data is held here:
*/
@@ -247,7 +255,6 @@ struct i915_context
unsigned num_samplers;
unsigned num_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
struct intel_batchbuffer *batch;
diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c
index 066e7392d1..f41c51f299 100644
--- a/src/gallium/drivers/i915/i915_debug_fp.c
+++ b/src/gallium/drivers/i915/i915_debug_fp.c
@@ -28,7 +28,6 @@
#include "i915_reg.h"
#include "i915_debug.h"
-#include "util/u_simple_screen.h"
#include "util/u_debug.h"
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 72bd263550..e5bf4a20bd 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -116,11 +116,11 @@ i915_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return I915_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 62169918e2..377d8425a5 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -742,21 +742,45 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(i915->draw, count, buffers);
}
-static void i915_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+static void *
+i915_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct i915_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+static void
+i915_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct i915_context *i915 = i915_context(pipe);
+ struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
+
/* Because we change state before the draw_set_vertex_buffers call
* we need a flush here, just to be sure.
*/
draw_flush(i915->draw);
- i915->num_vertex_elements = count;
/* pass-through to draw module */
- draw_set_vertex_elements(i915->draw, count, elements);
+ if (i915_velems) {
+ draw_set_vertex_elements(i915->draw,
+ i915_velems->count, i915_velems->velem);
+ }
}
+static void
+i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
i915_init_state_functions( struct i915_context *i915 )
@@ -782,6 +806,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.create_vs_state = i915_create_vs_state;
i915->base.bind_vs_state = i915_bind_vs_state;
i915->base.delete_vs_state = i915_delete_vs_state;
+ i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
+ i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
+ i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
i915->base.set_blend_color = i915_set_blend_color;
i915->base.set_stencil_ref = i915_set_stencil_ref;
@@ -794,5 +821,4 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
- i915->base.set_vertex_elements = i915_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index 7ba222c78b..3ce52cdcdb 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -96,7 +96,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
unsigned nr_images,
unsigned w, unsigned h, unsigned d)
{
- assert(level < PIPE_MAX_TEXTURE_LEVELS);
+ assert(level < Elements(tex->nr_images));
tex->nr_images[level] = nr_images;
@@ -219,12 +219,12 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
/* used for scanouts that need special layouts */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use something very like scanout */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -369,12 +369,12 @@ i945_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
/* used for scanouts that need special layouts */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use some very like scanout */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -642,7 +642,7 @@ i915_texture_create(struct pipe_screen *screen,
/* for scanouts and cursors, cursors arn't scanouts */
- if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64)
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
buf_usage = INTEL_NEW_SCANOUT;
else
buf_usage = INTEL_NEW_TEXTURE;
@@ -673,19 +673,24 @@ fail:
}
static struct pipe_texture *
-i915_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+i915_texture_from_handle(struct pipe_screen * screen,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle)
{
-#if 0
+ struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex;
+ struct intel_winsys *iws = is->iws;
+ struct intel_buffer *buffer;
+ unsigned stride;
+
assert(screen);
+ buffer = iws->buffer_from_handle(iws, whandle, &stride);
+
/* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
+ if (templat->target != PIPE_TEXTURE_2D ||
+ templat->last_level != 0 ||
+ templat->depth0 != 1) {
return NULL;
}
@@ -693,23 +698,33 @@ i915_texture_blanket(struct pipe_screen * screen,
if (!tex)
return NULL;
- tex->base = *base;
+ tex->base = *templat;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
- tex->stride = stride[0];
+ tex->stride = stride;
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
+ i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
- pipe_buffer_reference(&tex->buffer, buffer);
+ tex->buffer = buffer;
return &tex->base;
-#else
- return NULL;
-#endif
}
+static boolean
+i915_texture_get_handle(struct pipe_screen * screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct i915_screen *is = i915_screen(screen);
+ struct i915_texture *tex = (struct i915_texture *)texture;
+ struct intel_winsys *iws = is->iws;
+
+ return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
+}
+
+
static void
i915_texture_destroy(struct pipe_texture *pt)
{
@@ -723,7 +738,7 @@ i915_texture_destroy(struct pipe_texture *pt)
iws->buffer_destroy(iws, tex->buffer);
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ for (i = 0; i < Elements(tex->image_offset); i++)
if (tex->image_offset[i])
FREE(tex->image_offset[i]);
@@ -869,7 +884,8 @@ void
i915_init_screen_texture_functions(struct i915_screen *is)
{
is->base.texture_create = i915_texture_create;
- is->base.texture_blanket = i915_texture_blanket;
+ is->base.texture_from_handle = i915_texture_from_handle;
+ is->base.texture_get_handle = i915_texture_get_handle;
is->base.texture_destroy = i915_texture_destroy;
is->base.get_tex_surface = i915_get_tex_surface;
is->base.tex_surface_destroy = i915_tex_surface_destroy;
@@ -878,53 +894,3 @@ i915_init_screen_texture_functions(struct i915_screen *is)
is->base.transfer_unmap = i915_transfer_unmap;
is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
}
-
-struct pipe_texture *
-i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *base,
- unsigned stride,
- struct intel_buffer *buffer)
-{
- struct i915_texture *tex;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- tex = CALLOC_STRUCT(i915_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- tex->stride = stride;
-
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
- i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
-
- tex->buffer = buffer;
-
- return &tex->base;
-}
-
-boolean
-i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride)
-{
- struct i915_texture *tex = (struct i915_texture *)texture;
-
- if (!texture)
- return FALSE;
-
- *stride = tex->stride;
- *buffer = tex->buffer;
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/intel_winsys.h
index b3a802b0e2..00fd0c1efe 100644
--- a/src/gallium/drivers/i915/intel_winsys.h
+++ b/src/gallium/drivers/i915/intel_winsys.h
@@ -33,6 +33,7 @@ struct intel_buffer;
struct intel_batchbuffer;
struct pipe_texture;
struct pipe_fence_handle;
+struct winsys_handle;
enum intel_buffer_usage
{
@@ -129,6 +130,25 @@ struct intel_winsys {
enum intel_buffer_type type);
/**
+ * Creates a buffer from a handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ * 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);
+
+ /**
+ * 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,
+ struct winsys_handle *whandle,
+ unsigned stride);
+
+ /**
* Fence a buffer with a fence reg.
* Not to be confused with pipe_fence_handle.
*/
@@ -204,23 +224,4 @@ struct intel_winsys {
struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
-/**
- * Get the intel_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride);
-
-/**
- * Wrap a intel_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *tmplt,
- unsigned pitch,
- struct intel_buffer *buffer);
-
#endif
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index 12cfa7b049..f5b1a06576 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -351,7 +351,7 @@ struct brw_vs_prog_data {
/* Size == 0 if output either not written, or always [0,0,0,1]
*/
-struct brw_vs_ouput_sizes {
+struct brw_vs_output_sizes {
GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
};
@@ -546,14 +546,13 @@ struct brw_context
const struct brw_blend_state *blend;
const struct brw_rasterizer_state *rast;
const struct brw_depth_stencil_state *zstencil;
+ const struct brw_vertex_element_packet *velems;
const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
unsigned num_samplers;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- unsigned num_vertex_elements;
unsigned num_textures;
unsigned num_vertex_buffers;
diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c
index 9f136eec71..0820ba20a0 100644
--- a/src/gallium/drivers/i965/brw_draw_upload.c
+++ b/src/gallium/drivers/i965/brw_draw_upload.c
@@ -42,141 +42,6 @@
-static unsigned brw_translate_surface_format( unsigned id )
-{
- switch (id) {
- case PIPE_FORMAT_R64_FLOAT:
- return BRW_SURFACEFORMAT_R64_FLOAT;
- case PIPE_FORMAT_R64G64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64_FLOAT;
- case PIPE_FORMAT_R64G64B64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
- case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
-
- case PIPE_FORMAT_R32_FLOAT:
- return BRW_SURFACEFORMAT_R32_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32_FLOAT;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
-
- case PIPE_FORMAT_R32_UNORM:
- return BRW_SURFACEFORMAT_R32_UNORM;
- case PIPE_FORMAT_R32G32_UNORM:
- return BRW_SURFACEFORMAT_R32G32_UNORM;
- case PIPE_FORMAT_R32G32B32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32_UNORM;
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
-
- case PIPE_FORMAT_R32_USCALED:
- return BRW_SURFACEFORMAT_R32_USCALED;
- case PIPE_FORMAT_R32G32_USCALED:
- return BRW_SURFACEFORMAT_R32G32_USCALED;
- case PIPE_FORMAT_R32G32B32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32_USCALED;
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
-
- case PIPE_FORMAT_R32_SNORM:
- return BRW_SURFACEFORMAT_R32_SNORM;
- case PIPE_FORMAT_R32G32_SNORM:
- return BRW_SURFACEFORMAT_R32G32_SNORM;
- case PIPE_FORMAT_R32G32B32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32_SNORM;
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
-
- case PIPE_FORMAT_R32_SSCALED:
- return BRW_SURFACEFORMAT_R32_SSCALED;
- case PIPE_FORMAT_R32G32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32_SSCALED;
- case PIPE_FORMAT_R32G32B32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
-
- case PIPE_FORMAT_R16_UNORM:
- return BRW_SURFACEFORMAT_R16_UNORM;
- case PIPE_FORMAT_R16G16_UNORM:
- return BRW_SURFACEFORMAT_R16G16_UNORM;
- case PIPE_FORMAT_R16G16B16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16_UNORM;
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
-
- case PIPE_FORMAT_R16_USCALED:
- return BRW_SURFACEFORMAT_R16_USCALED;
- case PIPE_FORMAT_R16G16_USCALED:
- return BRW_SURFACEFORMAT_R16G16_USCALED;
- case PIPE_FORMAT_R16G16B16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16_USCALED;
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
-
- case PIPE_FORMAT_R16_SNORM:
- return BRW_SURFACEFORMAT_R16_SNORM;
- case PIPE_FORMAT_R16G16_SNORM:
- return BRW_SURFACEFORMAT_R16G16_SNORM;
- case PIPE_FORMAT_R16G16B16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16_SNORM;
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
-
- case PIPE_FORMAT_R16_SSCALED:
- return BRW_SURFACEFORMAT_R16_SSCALED;
- case PIPE_FORMAT_R16G16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16_SSCALED;
- case PIPE_FORMAT_R16G16B16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
-
- case PIPE_FORMAT_R8_UNORM:
- return BRW_SURFACEFORMAT_R8_UNORM;
- case PIPE_FORMAT_R8G8_UNORM:
- return BRW_SURFACEFORMAT_R8G8_UNORM;
- case PIPE_FORMAT_R8G8B8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8_UNORM;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
-
- case PIPE_FORMAT_R8_USCALED:
- return BRW_SURFACEFORMAT_R8_USCALED;
- case PIPE_FORMAT_R8G8_USCALED:
- return BRW_SURFACEFORMAT_R8G8_USCALED;
- case PIPE_FORMAT_R8G8B8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8_USCALED;
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
-
- case PIPE_FORMAT_R8_SNORM:
- return BRW_SURFACEFORMAT_R8_SNORM;
- case PIPE_FORMAT_R8G8_SNORM:
- return BRW_SURFACEFORMAT_R8G8_SNORM;
- case PIPE_FORMAT_R8G8B8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8_SNORM;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
- case PIPE_FORMAT_R8_SSCALED:
- return BRW_SURFACEFORMAT_R8_SSCALED;
- case PIPE_FORMAT_R8G8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8_SSCALED;
- case PIPE_FORMAT_R8G8B8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
-
- default:
- assert(0);
- return 0;
- }
-}
-
static unsigned get_index_type(int type)
{
switch (type) {
@@ -315,75 +180,16 @@ static int brw_emit_vertex_buffers( struct brw_context *brw )
-
static int brw_emit_vertex_elements(struct brw_context *brw)
{
- GLuint nr = brw->curr.num_vertex_elements;
- GLuint i;
+ const struct brw_vertex_element_packet *brw_velems = brw->curr.velems;
+ unsigned size = brw_velems->header.length + 2;
+ /* why is this here */
brw_emit_query_begin(brw);
- /* If the VS doesn't read any inputs (calculating vertex position from
- * a state variable for some reason, for example), emit a single pad
- * VERTEX_ELEMENT struct and bail.
- *
- * The stale VB state stays in place, but they don't do anything unless
- * a VE loads from them.
- */
- if (nr == 0) {
- BEGIN_BATCH(3, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
- OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
- (0 << BRW_VE0_SRC_OFFSET_SHIFT));
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
- ADVANCE_BATCH();
- return 0;
- }
-
- /* Now emit vertex element (VEP) state packets.
- *
- */
- BEGIN_BATCH(1 + nr * 2, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr * 2) - 2));
- for (i = 0; i < nr; i++) {
- const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
- uint32_t format = brw_translate_surface_format( input->src_format );
- uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
-
- switch (input->nr_components) {
- case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
- break;
- }
-
- OUT_BATCH((input->vertex_buffer_index << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (input->src_offset << BRW_VE0_SRC_OFFSET_SHIFT));
+ brw_batchbuffer_data(brw->batch, brw_velems, size * 4, IGNORE_CLIPRECTS);
- if (BRW_IS_IGDNG(brw))
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
- else
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
- ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
- }
- ADVANCE_BATCH();
return 0;
}
@@ -396,10 +202,11 @@ static int brw_emit_vertices( struct brw_context *brw )
if (ret)
return ret;
+ /* XXX should separate this? */
ret = brw_emit_vertex_elements( brw );
if (ret)
return ret;
-
+
return 0;
}
@@ -407,7 +214,8 @@ static int brw_emit_vertices( struct brw_context *brw )
const struct brw_tracked_state brw_vertices = {
.dirty = {
.mesa = (PIPE_NEW_INDEX_RANGE |
- PIPE_NEW_VERTEX_BUFFER),
+ PIPE_NEW_VERTEX_BUFFER |
+ PIPE_NEW_VERTEX_ELEMENT),
.brw = BRW_NEW_BATCH,
.cache = 0,
},
diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c
index e3c48e3149..d6a840857e 100644
--- a/src/gallium/drivers/i965/brw_pipe_vertex.c
+++ b/src/gallium/drivers/i965/brw_pipe_vertex.c
@@ -1,22 +1,251 @@
#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
-static void brw_set_vertex_elements( struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements )
+
+static unsigned brw_translate_surface_format( unsigned id )
+{
+ switch (id) {
+ case PIPE_FORMAT_R64_FLOAT:
+ return BRW_SURFACEFORMAT_R64_FLOAT;
+ case PIPE_FORMAT_R64G64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64_FLOAT;
+ case PIPE_FORMAT_R64G64B64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
+ case PIPE_FORMAT_R64G64B64A64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
+
+ case PIPE_FORMAT_R32_FLOAT:
+ return BRW_SURFACEFORMAT_R32_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32_FLOAT;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+ case PIPE_FORMAT_R32_UNORM:
+ return BRW_SURFACEFORMAT_R32_UNORM;
+ case PIPE_FORMAT_R32G32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32_UNORM;
+ case PIPE_FORMAT_R32G32B32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_UNORM;
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
+
+ case PIPE_FORMAT_R32_USCALED:
+ return BRW_SURFACEFORMAT_R32_USCALED;
+ case PIPE_FORMAT_R32G32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32_USCALED;
+ case PIPE_FORMAT_R32G32B32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_USCALED;
+ case PIPE_FORMAT_R32G32B32A32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
+
+ case PIPE_FORMAT_R32_SNORM:
+ return BRW_SURFACEFORMAT_R32_SNORM;
+ case PIPE_FORMAT_R32G32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32_SNORM;
+ case PIPE_FORMAT_R32G32B32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_SNORM;
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
+
+ case PIPE_FORMAT_R32_SSCALED:
+ return BRW_SURFACEFORMAT_R32_SSCALED;
+ case PIPE_FORMAT_R32G32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32_SSCALED;
+ case PIPE_FORMAT_R32G32B32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
+ case PIPE_FORMAT_R32G32B32A32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
+
+ case PIPE_FORMAT_R16_UNORM:
+ return BRW_SURFACEFORMAT_R16_UNORM;
+ case PIPE_FORMAT_R16G16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16_UNORM;
+ case PIPE_FORMAT_R16G16B16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_UNORM;
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
+
+ case PIPE_FORMAT_R16_USCALED:
+ return BRW_SURFACEFORMAT_R16_USCALED;
+ case PIPE_FORMAT_R16G16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16_USCALED;
+ case PIPE_FORMAT_R16G16B16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_USCALED;
+ case PIPE_FORMAT_R16G16B16A16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
+
+ case PIPE_FORMAT_R16_SNORM:
+ return BRW_SURFACEFORMAT_R16_SNORM;
+ case PIPE_FORMAT_R16G16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16_SNORM;
+ case PIPE_FORMAT_R16G16B16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_SNORM;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
+
+ case PIPE_FORMAT_R16_SSCALED:
+ return BRW_SURFACEFORMAT_R16_SSCALED;
+ case PIPE_FORMAT_R16G16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16_SSCALED;
+ case PIPE_FORMAT_R16G16B16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
+ case PIPE_FORMAT_R16G16B16A16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
+
+ case PIPE_FORMAT_R8_UNORM:
+ return BRW_SURFACEFORMAT_R8_UNORM;
+ case PIPE_FORMAT_R8G8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8_UNORM;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+
+ case PIPE_FORMAT_R8_USCALED:
+ return BRW_SURFACEFORMAT_R8_USCALED;
+ case PIPE_FORMAT_R8G8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8_USCALED;
+ case PIPE_FORMAT_R8G8B8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_USCALED;
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
+
+ case PIPE_FORMAT_R8_SNORM:
+ return BRW_SURFACEFORMAT_R8_SNORM;
+ case PIPE_FORMAT_R8G8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8_SNORM;
+ case PIPE_FORMAT_R8G8B8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_SNORM;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+ case PIPE_FORMAT_R8_SSCALED:
+ return BRW_SURFACEFORMAT_R8_SSCALED;
+ case PIPE_FORMAT_R8G8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8_SSCALED;
+ case PIPE_FORMAT_R8G8B8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
+
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void brw_translate_vertex_elements(struct brw_context *brw,
+ struct brw_vertex_element_packet *brw_velems,
+ const struct pipe_vertex_element *attribs,
+ unsigned count)
+{
+ unsigned i;
+
+ /* If the VS doesn't read any inputs (calculating vertex position from
+ * a state variable for some reason, for example), emit a single pad
+ * VERTEX_ELEMENT struct and bail.
+ *
+ * The stale VB state stays in place, but they don't do anything unless
+ * a VE loads from them.
+ */
+ brw_velems->header.opcode = CMD_VERTEX_ELEMENT;
+
+ if (count == 0) {
+ brw_velems->header.length = 1;
+ brw_velems->ve[0].ve0.src_offset = 0;
+ brw_velems->ve[0].ve0.src_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+ brw_velems->ve[0].ve0.valid = 1;
+ brw_velems->ve[0].ve0.vertex_buffer_index = 0;
+ brw_velems->ve[0].ve1.dst_offset = 0;
+ brw_velems->ve[0].ve1.vfcomponent0 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent1 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent2 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ return;
+ }
+
+
+ /* Now emit vertex element (VEP) state packets.
+ *
+ */
+ brw_velems->header.length = (1 + count * 2) - 2;
+ for (i = 0; i < count; i++) {
+ const struct pipe_vertex_element *input = &attribs[i];
+ unsigned nr_components = util_format_get_nr_components(input->src_format);
+
+ uint32_t format = brw_translate_surface_format( input->src_format );
+ uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
+
+ switch (nr_components) {
+ case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ break;
+ }
+
+ brw_velems->ve[i].ve0.src_offset = input->src_offset;
+ brw_velems->ve[i].ve0.src_format = format;
+ brw_velems->ve[i].ve0.valid = 1;
+ brw_velems->ve[i].ve0.vertex_buffer_index = input->vertex_buffer_index;
+ brw_velems->ve[i].ve1.vfcomponent0 = comp0;
+ brw_velems->ve[i].ve1.vfcomponent1 = comp1;
+ brw_velems->ve[i].ve1.vfcomponent2 = comp2;
+ brw_velems->ve[i].ve1.vfcomponent3 = comp3;
+
+ if (BRW_IS_IGDNG(brw))
+ brw_velems->ve[i].ve1.dst_offset = 0;
+ else
+ brw_velems->ve[i].ve1.dst_offset = i * 4;
+ }
+}
+
+static void* brw_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs )
{
+ /* note: for the brw_swtnl.c code (if ever we need draw fallback) we'd also need
+ to store the original data */
struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *velems;
+ assert(count <= BRW_VEP_MAX);
+ velems = (struct brw_vertex_element_packet *) MALLOC(sizeof(struct brw_vertex_element_packet));
+ if (velems) {
+ brw_translate_vertex_elements(brw, velems, attribs, count);
+ }
+ return velems;
+}
- memcpy(brw->curr.vertex_element, elements, count * sizeof(elements[0]));
- brw->curr.num_vertex_elements = count;
+static void brw_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *brw_velems = (struct brw_vertex_element_packet *) velems;
+
+ brw->curr.velems = brw_velems;
brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
}
+static void brw_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
+
static void brw_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_buffer *buffers)
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct brw_context *brw = brw_context(pipe);
unsigned i;
@@ -49,7 +278,9 @@ void
brw_pipe_vertex_init( struct brw_context *brw )
{
brw->base.set_vertex_buffers = brw_set_vertex_buffers;
- brw->base.set_vertex_elements = brw_set_vertex_elements;
+ brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
+ brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
+ brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 66f3aad8b2..cef83ffea8 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -174,11 +174,11 @@ brw_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return BRW_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h
index 7226d9228b..e0f3cd2a9f 100644
--- a/src/gallium/drivers/i965/brw_screen.h
+++ b/src/gallium/drivers/i965/brw_screen.h
@@ -100,6 +100,9 @@ struct brw_surface
};
+#define BRW_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define BRW_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct brw_texture
{
@@ -107,9 +110,9 @@ struct brw_texture
struct brw_winsys_buffer *bo;
struct brw_surface_state ss;
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
- unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned *image_offset[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned nr_images[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned level_offset[BRW_MAX_TEXTURE_2D_LEVELS];
boolean compressed;
unsigned brw_target;
diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c
index e38fdf1869..cc79bfc771 100644
--- a/src/gallium/drivers/i965/brw_screen_texture.c
+++ b/src/gallium/drivers/i965/brw_screen_texture.c
@@ -231,8 +231,8 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
goto fail;
- if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
buffer_type = BRW_BUFFER_TYPE_SCANOUT;
}
else {
@@ -303,14 +303,121 @@ fail:
return NULL;
}
-static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static struct pipe_texture *
+brw_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex;
+ struct brw_winsys_buffer *buffer;
+ unsigned tiling;
+ unsigned pitch;
+
+ if (templ->target != PIPE_TEXTURE_2D ||
+ templ->last_level != 0 ||
+ templ->depth0 != 1)
+ return NULL;
+
+ if (util_format_is_compressed(templ->format))
+ return NULL;
+
+ tex = CALLOC_STRUCT(brw_texture);
+ if (!tex)
+ return NULL;
+
+ if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK)
+ goto fail;
+
+ memcpy(&tex->base, templ, sizeof *templ);
+ pipe_reference_init(&tex->base.reference, 1);
+ tex->base.screen = screen;
+
+ /* XXX: cpp vs. blocksize
+ */
+ tex->cpp = util_format_get_blocksize(tex->base.format);
+ tex->tiling = tiling;
+
+ make_empty_list(&tex->views[0]);
+ make_empty_list(&tex->views[1]);
+
+ if (!brw_texture_layout(bscreen, tex))
+ goto fail;
+
+ /* XXX Maybe some more checks? */
+ if ((pitch / tex->cpp) < tex->pitch)
+ goto fail;
+
+ tex->pitch = pitch / tex->cpp;
+
+ tex->bo = buffer;
+
+ /* fix this warning */
+#if 0
+ if (tex->size > buffer->size)
+ goto fail;
+#endif
+
+ tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
+ tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
+ assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
+
+ /* This is ok for all textures with channel width 8bit or less:
+ */
+/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+
+
+ /* XXX: what happens when tex->bo->offset changes???
+ */
+ tex->ss.ss1.base_addr = 0; /* reloc */
+ tex->ss.ss2.mip_count = tex->base.last_level;
+ tex->ss.ss2.width = tex->base.width0 - 1;
+ tex->ss.ss2.height = tex->base.height0 - 1;
+
+ switch (tex->tiling) {
+ case BRW_TILING_NONE:
+ tex->ss.ss3.tiled_surface = 0;
+ tex->ss.ss3.tile_walk = 0;
+ break;
+ case BRW_TILING_X:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+ break;
+ case BRW_TILING_Y:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+ break;
+ }
+
+ tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
+ tex->ss.ss3.depth = tex->base.depth0 - 1;
+
+ tex->ss.ss4.min_lod = 0;
+
+ return &tex->base;
+
+fail:
+ FREE(tex);
return NULL;
}
+static boolean
+brw_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex = brw_texture(texture);
+ unsigned stride;
+
+ stride = tex->pitch * tex->cpp;
+
+ return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
+}
+
+
+
static void brw_texture_destroy(struct pipe_texture *pt)
{
struct brw_texture *tex = brw_texture(pt);
@@ -451,127 +558,13 @@ brw_tex_transfer_destroy(struct pipe_transfer *trans)
}
-/*
- * Functions exported to the winsys
- */
-
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride)
-{
- struct brw_texture *tex = brw_texture(texture);
-
- *buffer = tex->bo;
- if (stride)
- *stride = tex->pitch * tex->cpp;
-
- return TRUE;
-}
-
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer)
-{
- struct brw_screen *bscreen = brw_screen(screen);
- struct brw_texture *tex;
- GLuint format;
-
- if (templ->target != PIPE_TEXTURE_2D ||
- templ->last_level != 0 ||
- templ->depth0 != 1)
- return NULL;
-
- if (util_format_is_compressed(templ->format))
- return NULL;
-
- tex = CALLOC_STRUCT(brw_texture);
- if (!tex)
- return NULL;
-
- memcpy(&tex->base, templ, sizeof *templ);
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- /* XXX: cpp vs. blocksize
- */
- tex->cpp = util_format_get_blocksize(tex->base.format);
- tex->tiling = tiling;
-
- make_empty_list(&tex->views[0]);
- make_empty_list(&tex->views[1]);
-
- if (!brw_texture_layout(bscreen, tex))
- goto fail;
-
- /* XXX Maybe some more checks? */
- if ((pitch / tex->cpp) < tex->pitch)
- goto fail;
-
- tex->pitch = pitch / tex->cpp;
-
- tex->bo = buffer;
-
- /* fix this warning */
-#if 0
- if (tex->size > buffer->size)
- goto fail;
-#endif
-
- tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
-
- format = translate_tex_format(tex->base.format);
- assert(format != BRW_SURFACEFORMAT_INVALID);
- tex->ss.ss0.surface_format = format;
-
- /* This is ok for all textures with channel width 8bit or less:
- */
-/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-
-
- /* XXX: what happens when tex->bo->offset changes???
- */
- tex->ss.ss1.base_addr = 0; /* reloc */
- tex->ss.ss2.mip_count = tex->base.last_level;
- tex->ss.ss2.width = tex->base.width0 - 1;
- tex->ss.ss2.height = tex->base.height0 - 1;
-
- switch (tex->tiling) {
- case BRW_TILING_NONE:
- tex->ss.ss3.tiled_surface = 0;
- tex->ss.ss3.tile_walk = 0;
- break;
- case BRW_TILING_X:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
- break;
- case BRW_TILING_Y:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
- break;
- }
-
- tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
- tex->ss.ss3.depth = tex->base.depth0 - 1;
-
- tex->ss.ss4.min_lod = 0;
-
- return &tex->base;
-
-fail:
- FREE(tex);
- return NULL;
-}
-
void brw_screen_tex_init( struct brw_screen *brw_screen )
{
brw_screen->base.is_format_supported = brw_is_format_supported;
brw_screen->base.texture_create = brw_texture_create;
+ brw_screen->base.texture_from_handle = brw_texture_from_handle;
+ brw_screen->base.texture_get_handle = brw_texture_get_handle;
brw_screen->base.texture_destroy = brw_texture_destroy;
- brw_screen->base.texture_blanket = brw_texture_blanket;
brw_screen->base.get_tex_transfer = brw_get_tex_transfer;
brw_screen->base.transfer_map = brw_transfer_map;
brw_screen->base.transfer_unmap = brw_transfer_unmap;
diff --git a/src/gallium/drivers/i965/brw_structs.h b/src/gallium/drivers/i965/brw_structs.h
index bf10bc04de..e97ddeb5e1 100644
--- a/src/gallium/drivers/i965/brw_structs.h
+++ b/src/gallium/drivers/i965/brw_structs.h
@@ -28,7 +28,7 @@
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
-
+
#ifndef BRW_STRUCTS_H
#define BRW_STRUCTS_H
@@ -1149,7 +1149,7 @@ struct brw_vertex_element_state
GLuint valid:1;
GLuint vertex_buffer_index:5;
} ve0;
-
+
struct
{
GLuint dst_offset:8;
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
index c82d00f4a4..f30c7f1813 100644
--- a/src/gallium/drivers/i965/brw_winsys.h
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -162,6 +162,16 @@ struct brw_winsys_screen {
unsigned alignment,
struct brw_winsys_buffer **bo_out);
+ enum pipe_error (*bo_from_handle)(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tiling,
+ struct brw_winsys_buffer **bo_out);
+
+ enum pipe_error (*bo_get_handle)(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride);
+
/* Destroy a buffer when our refcount goes to zero:
*/
void (*bo_destroy)(struct brw_winsys_buffer *buffer);
@@ -257,28 +267,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
-/**
- * Get the brw_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-struct pipe_texture;
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride);
-
-/**
- * Wrap a brw_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *template,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer);
-
/*************************************************************************
* Cooperative dumping between winsys and driver. TODO: make this
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 8248b2a413..baf0ae4401 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -377,6 +377,42 @@ identity_delete_vs_state(struct pipe_context *_pipe,
vs);
}
+
+static void *
+identity_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *vertex_elements)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ return pipe->create_vertex_elements_state(pipe,
+ num_elements,
+ vertex_elements);
+}
+
+static void
+identity_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->bind_vertex_elements_state(pipe,
+ velems);
+}
+
+static void
+identity_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->delete_vertex_elements_state(pipe,
+ velems);
+}
+
static void
identity_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *blend_color)
@@ -563,20 +599,6 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers,
buffers);
}
-
-static void
-identity_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct identity_context *id_pipe = identity_context(_pipe);
- struct pipe_context *pipe = id_pipe->pipe;
-
- pipe->set_vertex_elements(pipe,
- num_elements,
- vertex_elements);
-}
-
static void
identity_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *_dst,
@@ -733,6 +755,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.create_vs_state = identity_create_vs_state;
id_pipe->base.bind_vs_state = identity_bind_vs_state;
id_pipe->base.delete_vs_state = identity_delete_vs_state;
+ id_pipe->base.create_vertex_elements_state = identity_create_vertex_elements_state;
+ id_pipe->base.bind_vertex_elements_state = identity_bind_vertex_elements_state;
+ id_pipe->base.delete_vertex_elements_state = identity_delete_vertex_elements_state;
id_pipe->base.set_blend_color = identity_set_blend_color;
id_pipe->base.set_stencil_ref = identity_set_stencil_ref;
id_pipe->base.set_clip_state = identity_set_clip_state;
@@ -744,7 +769,6 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
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_vertex_buffers = identity_set_vertex_buffers;
- id_pipe->base.set_vertex_elements = identity_set_vertex_elements;
id_pipe->base.surface_copy = identity_surface_copy;
id_pipe->base.surface_fill = identity_surface_fill;
id_pipe->base.clear = identity_clear;
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index f258c38cd7..936ccc444a 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -63,62 +63,6 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
return identity_screen_create(screen);
}
-
-static struct pipe_texture *
-identity_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct drm_api *api = id_api->api;
- struct pipe_texture *result;
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = identity_texture_create(identity_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-identity_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-
-static boolean
-identity_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
-}
-
static void
identity_drm_destroy(struct drm_api *_api)
{
@@ -145,9 +89,6 @@ identity_drm_create(struct drm_api *api)
id_api->base.name = api->name;
id_api->base.driver_name = api->driver_name;
id_api->base.create_screen = identity_drm_create_screen;
- id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
- id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
- id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
id_api->base.destroy = identity_drm_destroy;
id_api->api = api;
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index b85492114a..b9d0f003d7 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -135,27 +135,40 @@ identity_screen_texture_create(struct pipe_screen *_screen,
}
static struct pipe_texture *
-identity_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *_buffer)
+identity_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_buffer *id_buffer = identity_buffer(_buffer);
struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *buffer = id_buffer->buffer;
struct pipe_texture *result;
- result = screen->texture_blanket(screen,
- templat,
- stride,
- buffer);
+ /* TODO trace call */
- if (result)
- return identity_texture_create(id_screen, result);
- return NULL;
+ result = screen->texture_from_handle(screen, templ, handle);
+
+ result = identity_texture_create(identity_screen(_screen), result);
+
+ return result;
+}
+
+static boolean
+identity_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct identity_screen *id_screen = identity_screen(_screen);
+ struct identity_texture *id_texture = identity_texture(_texture);
+ struct pipe_screen *screen = id_screen->screen;
+ struct pipe_texture *texture = id_texture->texture;
+
+ /* TODO trace call */
+
+ return screen->texture_get_handle(screen, texture, handle);
}
+
+
static void
identity_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -298,31 +311,6 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen,
return NULL;
}
-static struct pipe_buffer *
-identity_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *result;
-
- result = screen->surface_buffer_create(screen,
- width,
- height,
- format,
- usage,
- tex_usage,
- stride);
-
- if (result)
- return identity_buffer_create(id_screen, result);
- return NULL;
-}
static void *
identity_screen_buffer_map(struct pipe_screen *_screen,
@@ -495,7 +483,8 @@ identity_screen_create(struct pipe_screen *screen)
id_screen->base.is_format_supported = identity_screen_is_format_supported;
id_screen->base.context_create = identity_screen_context_create;
id_screen->base.texture_create = identity_screen_texture_create;
- id_screen->base.texture_blanket = identity_screen_texture_blanket;
+ id_screen->base.texture_from_handle = identity_screen_texture_from_handle;
+ id_screen->base.texture_get_handle = identity_screen_texture_get_handle;
id_screen->base.texture_destroy = identity_screen_texture_destroy;
id_screen->base.get_tex_surface = identity_screen_get_tex_surface;
id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy;
@@ -505,7 +494,6 @@ identity_screen_create(struct pipe_screen *screen)
id_screen->base.transfer_unmap = identity_screen_transfer_unmap;
id_screen->base.buffer_create = identity_screen_buffer_create;
id_screen->base.user_buffer_create = identity_screen_user_buffer_create;
- id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create;
if (screen->buffer_map)
id_screen->base.buffer_map = identity_screen_buffer_map;
if (screen->buffer_map_range)
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c
index 9eda972081..dab20cb639 100644
--- a/src/gallium/drivers/llvmpipe/lp_buffer.c
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.c
@@ -30,10 +30,10 @@
#include "util/u_memory.h"
#include "util/u_math.h"
-#include "lp_winsys.h"
#include "lp_screen.h"
#include "lp_buffer.h"
+#include "state_tracker/sw_winsys.h"
static void *
llvmpipe_buffer_map(struct pipe_screen *screen,
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index e31ae6a3fc..d94efec16a 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -145,6 +145,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
+ llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
+ llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
+ llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
+
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
@@ -157,7 +161,6 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
- llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 955c7eb8e0..217ec59b68 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -46,6 +46,7 @@ struct lp_fragment_shader;
struct lp_vertex_shader;
struct lp_blend_state;
struct setup_context;
+struct lp_velems_state;
struct llvmpipe_context {
struct pipe_context pipe; /**< base class */
@@ -58,6 +59,7 @@ struct llvmpipe_context {
const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs;
const struct lp_vertex_shader *vs;
+ const struct lp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -71,13 +73,11 @@ struct llvmpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_samplers;
unsigned num_vertex_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of LP_NEW_x flags */
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index bacff500d6..08c8f93794 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -58,7 +58,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_TEXTURE_DATA] =
+ LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+ LP_MAX_TEXTURE_2D_LEVELS);
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 0ebb2826fa..5cc7a12c03 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -39,6 +39,7 @@
#include "gallivm/lp_bld_struct.h"
#include "pipe/p_state.h"
+#include "lp_texture.h"
struct llvmpipe_screen;
@@ -51,7 +52,7 @@ struct lp_jit_texture
uint32_t depth;
uint32_t last_level;
uint32_t stride;
- const void *data;
+ const void *data[LP_MAX_TEXTURE_2D_LEVELS];
};
diff --git a/src/gallium/drivers/llvmpipe/lp_public.h b/src/gallium/drivers/llvmpipe/lp_public.h
new file mode 100644
index 0000000000..ec6b660b48
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_public.h
@@ -0,0 +1,10 @@
+#ifndef LP_PUBLIC_H
+#define LP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+llvmpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index f84ede675b..5093f58bb1 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -34,11 +34,13 @@
#include "lp_texture.h"
#include "lp_buffer.h"
#include "lp_fence.h"
-#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
#include "lp_context.h"
#include "lp_debug.h"
+#include "lp_public.h"
+
+#include "state_tracker/sw_winsys.h"
#ifdef DEBUG
int LP_DEBUG = 0;
@@ -107,11 +109,11 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return LP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -167,7 +169,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
unsigned geom_flags )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
const struct util_format_description *format_desc;
format_desc = util_format_description(format);
@@ -238,18 +240,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
}
-static struct pipe_buffer *
-llvmpipe_surface_buffer_create(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned tex_usage,
- unsigned usage,
- unsigned *stride)
-{
- /* This function should never be used */
- assert(0);
- return NULL;
-}
static void
@@ -258,7 +248,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
void *context_private)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
assert(texture->dt);
@@ -271,7 +261,7 @@ static void
llvmpipe_destroy_screen( struct pipe_screen *_screen )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
lp_jit_screen_cleanup(screen);
@@ -288,7 +278,7 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
* Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
*/
struct pipe_screen *
-llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+llvmpipe_create_screen(struct sw_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
@@ -309,7 +299,6 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
screen->base.get_paramf = llvmpipe_get_paramf;
screen->base.is_format_supported = llvmpipe_is_format_supported;
- screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
screen->base.context_create = llvmpipe_create_context;
screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index 4a1b4d6f3e..f4e62cbf08 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -43,14 +43,14 @@
#include "pipe/p_defines.h"
-struct llvmpipe_winsys;
+struct sw_winsys;
struct llvmpipe_screen
{
struct pipe_screen base;
- struct llvmpipe_winsys *winsys;
+ struct sw_winsys *winsys;
LLVMModuleRef module;
LLVMExecutionEngineRef engine;
@@ -76,4 +76,5 @@ llvmpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* LP_SCREEN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b0713c3b71..d6d37c4809 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -46,7 +46,7 @@
#include "lp_rast.h"
#include "lp_setup_context.h"
#include "lp_screen.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
@@ -472,19 +472,25 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
jit_tex->stride = lp_tex->stride[0];
- if(!lp_tex->dt) {
- jit_tex->data = lp_tex->data;
+ if (!lp_tex->dt) {
+ /* regular texture - setup array of mipmap level pointers */
+ int j;
+ for (j = 0; j <= tex->last_level; j++) {
+ jit_tex->data[j] =
+ (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+ }
}
else {
+ /* display target texture/surface */
/*
* XXX: Where should this be unmapped?
*/
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
- jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
+ struct sw_winsys *winsys = screen->winsys;
+ jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_BUFFER_USAGE_CPU_READ);
- assert(jit_tex->data);
+ assert(jit_tex->data[0]);
}
/* the scene references this texture */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index 24291da91e..671e74465c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -231,57 +231,29 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
@@ -415,57 +387,28 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
-
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 9beba32271..6dbdc195bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -119,6 +119,10 @@ struct lp_vertex_shader {
struct draw_vertex_shader *draw_data;
};
+struct lp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
void *
@@ -176,8 +180,14 @@ void *llvmpipe_create_vs_state(struct pipe_context *,
void llvmpipe_bind_vs_state(struct pipe_context *, void *);
void llvmpipe_delete_vs_state(struct pipe_context *, void *);
+void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void llvmpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
@@ -194,10 +204,6 @@ llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void llvmpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void llvmpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index 57ac25ea0c..f6427aa908 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -35,24 +35,41 @@
#include "draw/draw_context.h"
+void *
+llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct lp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct lp_velems_state *) MALLOC(sizeof(struct lp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-llvmpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ struct lp_velems_state *lp_velems = (struct lp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(llvmpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- llvmpipe->num_vertex_elements = count;
+ llvmpipe->velems = lp_velems;
llvmpipe->dirty |= LP_NEW_VERTEX;
- draw_set_vertex_elements(llvmpipe->draw, count, attribs);
+ if (velems)
+ draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
}
+void
+llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 632462460a..5a3cf37d6d 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -51,10 +51,11 @@
/**
- * This provides the bridge between the sampler state store in lp_jit_context
- * and lp_jit_texture and the sampler code generator. It provides the
- * texture layout information required by the texture sampler code generator
- * in terms of the state stored in lp_jit_context and lp_jit_texture in runtime.
+ * This provides the bridge between the sampler state store in
+ * lp_jit_context and lp_jit_texture and the sampler code
+ * generator. It provides the texture layout information required by
+ * the texture sampler code generator in terms of the state stored in
+ * lp_jit_context and lp_jit_texture in runtime.
*/
struct llvmpipe_sampler_dynamic_state
{
@@ -79,6 +80,9 @@ struct lp_llvm_sampler_soa
/**
* Fetch the specified member of the lp_jit_texture structure.
+ * \param emit_load if TRUE, emit the LLVM load instruction to actually
+ * fetch the field's value. Otherwise, just emit the
+ * GEP code to address the field.
*
* @sa http://llvm.org/docs/GetElementPtr.html
*/
@@ -87,9 +91,11 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
LLVMBuilderRef builder,
unsigned unit,
unsigned member_index,
- const char *member_name)
+ const char *member_name,
+ boolean emit_load)
{
- struct llvmpipe_sampler_dynamic_state *state = (struct llvmpipe_sampler_dynamic_state *)base;
+ struct llvmpipe_sampler_dynamic_state *state =
+ (struct llvmpipe_sampler_dynamic_state *)base;
LLVMValueRef indices[4];
LLVMValueRef ptr;
LLVMValueRef res;
@@ -107,7 +113,10 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
- res = LLVMBuildLoad(builder, ptr, "");
+ if (emit_load)
+ res = LLVMBuildLoad(builder, ptr, "");
+ else
+ res = ptr;
lp_build_name(res, "context.texture%u.%s", unit, member_name);
@@ -116,28 +125,30 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
/**
- * Helper macro to instantiate the functions that generate the code to fetch
- * the members of lp_jit_texture to fulfill the sampler code generator requests.
+ * Helper macro to instantiate the functions that generate the code to
+ * fetch the members of lp_jit_texture to fulfill the sampler code
+ * generator requests.
*
- * This complexity is the price we have to pay to keep the texture sampler code
- * generator a reusable module without dependencies to llvmpipe internals.
+ * This complexity is the price we have to pay to keep the texture
+ * sampler code generator a reusable module without dependencies to
+ * llvmpipe internals.
*/
-#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
LLVMBuilderRef builder, \
unsigned unit) \
{ \
- return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+ return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
}
-LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
-LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
-LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH)
-LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL)
-LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
-LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
+LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
+LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
+LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE, TRUE)
+LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
static void
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 7f45635542..74b7b4ec5e 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -42,7 +42,7 @@
#include "lp_screen.h"
#include "lp_texture.h"
#include "lp_tile_size.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
/**
@@ -93,7 +93,7 @@ static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
struct llvmpipe_texture *lpt)
{
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
/* Round up the surface size to a multiple of the tile size to
* avoid tile clipping.
@@ -125,7 +125,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
lpt->base.screen = &screen->base;
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
goto fail;
}
@@ -142,43 +143,6 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
}
-static struct pipe_texture *
-llvmpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- /* FIXME */
-#if 0
- struct llvmpipe_texture *lpt;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- lpt = CALLOC_STRUCT(llvmpipe_texture);
- if (!lpt)
- return NULL;
-
- lpt->base = *base;
- pipe_reference_init(&lpt->base.reference, 1);
- lpt->base.screen = screen;
- lpt->stride[0] = stride[0];
-
- pipe_buffer_reference(&lpt->buffer, buffer);
-
- return &lpt->base;
-#else
- debug_printf("llvmpipe_texture_blanket() not implemented!");
- return NULL;
-#endif
-}
-
-
static void
llvmpipe_texture_destroy(struct pipe_texture *pt)
{
@@ -187,7 +151,7 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpt->dt);
}
else {
@@ -357,7 +321,7 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
map = winsys->displaytarget_map(winsys, lpt->dt,
pipe_transfer_buffer_flags(transfer));
@@ -398,7 +362,7 @@ llvmpipe_transfer_unmap(struct pipe_screen *screen,
if (lpt->dt) {
/* display target */
- struct llvmpipe_winsys *winsys = lp_screen->winsys;
+ struct sw_winsys *winsys = lp_screen->winsys;
winsys->displaytarget_unmap(winsys, lpt->dt);
}
}
@@ -408,7 +372,6 @@ void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = llvmpipe_texture_create;
- screen->texture_blanket = llvmpipe_texture_blanket;
screen->texture_destroy = llvmpipe_texture_destroy;
screen->get_tex_surface = llvmpipe_get_tex_surface;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 87c905bc02..b23f929b16 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -32,24 +32,29 @@
#include "pipe/p_state.h"
+#define LP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K for now */
+#define LP_MAX_TEXTURE_3D_LEVELS 10 /* 512 x 512 x 512 for now */
+
+
struct pipe_context;
struct pipe_screen;
struct llvmpipe_context;
-struct llvmpipe_displaytarget;
+
+struct sw_displaytarget;
struct llvmpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[LP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[LP_MAX_TEXTURE_2D_LEVELS];
/**
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
* usage.
*/
- struct llvmpipe_displaytarget *dt;
+ struct sw_displaytarget *dt;
/**
* Malloc'ed data for regular textures, or a mapping to dt above.
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 3c2f771b51..b1ad686022 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -4,6 +4,7 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_format.h"
#include <stdio.h>
#include <errno.h>
@@ -12,6 +13,9 @@
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
+/* XXX this should go away */
+#include "state_tracker/drm_api.h"
+
static const char *
nouveau_screen_get_name(struct pipe_screen *pscreen)
{
@@ -120,7 +124,7 @@ nouveau_screen_map_flags(unsigned pipe)
if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
flags |= NOUVEAU_BO_NOWAIT;
else
- if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
+ if (pipe & PIPE_BUFFER_USAGE_UNSYNCHRONIZED)
flags |= NOUVEAU_BO_NOSYNC;
return flags;
@@ -231,6 +235,72 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
return 0;
}
+
+/*
+ * Both texture_{from|get}_handle use drm api defines directly which they
+ * shouldn't do. The problem is that from|get are pipe functions and as
+ * such they should be defined in the pipe level. If nouveau had a propper
+ * winsys interface we would have added from|get to that interface using
+ * the winsys_handle struct as done with other drivers. However this code
+ * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
+ * we need to translate the handle into something they understand.
+ */
+static struct pipe_texture *
+nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct pipe_texture *pt;
+ struct pipe_buffer *pb;
+ int ret;
+
+ pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
+ if (!pb)
+ return NULL;
+
+ ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
+ if (ret) {
+ debug_printf("%s: ref name 0x%08x failed with %d\n",
+ __func__, whandle->handle, ret);
+ FREE(pb);
+ return NULL;
+ }
+
+ pipe_reference_init(&pb->reference, 1);
+ pb->screen = pscreen;
+ pb->alignment = 0;
+ pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ pb->size = nouveau_bo(pb)->size;
+ pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ,
+ &whandle->stride, pb);
+ pipe_buffer_reference(&pb, NULL);
+ return pt;
+}
+
+static boolean
+nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
+
+ if (!mt || !mt->bo)
+ return false;
+
+ whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = mt->bo->handle;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -258,6 +328,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;
+ pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
+ pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
+
return 0;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index a7927d88df..f4a7a2bc23 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -6,6 +6,18 @@ struct nouveau_screen {
struct nouveau_device *device;
struct nouveau_channel *channel;
+ /**
+ * Create a new texture object, using the given template info, but on top of
+ * existing memory.
+ *
+ * It is assumed that the buffer data is layed out according to the expected
+ * by the hardware. NULL will be returned if any inconsistency is found.
+ */
+ struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ const unsigned *stride,
+ struct pipe_buffer *buffer);
+
int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
struct pipe_buffer *pb, unsigned usage);
};
diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h
index a10114beab..7f16e31c3f 100644
--- a/src/gallium/drivers/nouveau/nouveau_util.h
+++ b/src/gallium/drivers/nouveau/nouveau_util.h
@@ -88,4 +88,104 @@ static INLINE unsigned log2i(unsigned i)
return r;
}
+struct u_split_prim {
+ void *priv;
+ void (*emit)(void *priv, unsigned start, unsigned count);
+ void (*edge)(void *priv, boolean enabled);
+
+ unsigned mode;
+ unsigned start;
+ unsigned p_start;
+ unsigned p_end;
+
+ int repeat_first:1;
+ int close_first:1;
+ int edgeflag_off:1;
+};
+
+static inline void
+u_split_prim_init(struct u_split_prim *s,
+ unsigned mode, unsigned start, unsigned count)
+{
+ if (mode == PIPE_PRIM_LINE_LOOP) {
+ s->mode = PIPE_PRIM_LINE_STRIP;
+ s->close_first = 1;
+ } else {
+ s->mode = mode;
+ s->close_first = 0;
+ }
+ s->start = start;
+ s->p_start = start;
+ s->p_end = start + count;
+ s->edgeflag_off = 0;
+ s->repeat_first = 0;
+}
+
+static INLINE boolean
+u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
+{
+ int repeat = 0;
+
+ if (s->repeat_first) {
+ s->emit(s->priv, s->start, 1);
+ max_verts--;
+ if (s->edgeflag_off) {
+ s->edge(s->priv, TRUE);
+ s->edgeflag_off = FALSE;
+ }
+ }
+
+ if (s->p_start + s->close_first + max_verts >= s->p_end) {
+ s->emit(s->priv, s->p_start, s->p_end - s->p_start);
+ if (s->close_first)
+ s->emit(s->priv, s->start, 1);
+ return TRUE;
+ }
+
+ switch (s->mode) {
+ case PIPE_PRIM_LINES:
+ max_verts &= ~1;
+ break;
+ case PIPE_PRIM_LINE_STRIP:
+ repeat = 1;
+ break;
+ case PIPE_PRIM_POLYGON:
+ max_verts--;
+ s->emit(s->priv, s->p_start, max_verts);
+ s->edge(s->priv, FALSE);
+ s->emit(s->priv, s->p_start + max_verts, 1);
+ s->p_start += max_verts;
+ s->repeat_first = TRUE;
+ s->edgeflag_off = TRUE;
+ return FALSE;
+ case PIPE_PRIM_TRIANGLES:
+ max_verts = max_verts - (max_verts % 3);
+ break;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ /* to ensure winding stays correct, always split
+ * on an even number of generated triangles
+ */
+ max_verts = max_verts & ~1;
+ repeat = 2;
+ break;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ s->repeat_first = TRUE;
+ repeat = 1;
+ break;
+ case PIPE_PRIM_QUADS:
+ max_verts &= ~3;
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ max_verts &= ~1;
+ repeat = 2;
+ break;
+ default:
+ break;
+ }
+
+ s->emit (s->priv, s->p_start, max_verts);
+ s->p_start += (max_verts - repeat);
+ return FALSE;
+}
+
#endif
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index ea259aadf3..1786460aec 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -107,6 +107,11 @@ struct nv30_state {
struct nouveau_stateobj *hw[NV30_STATE_MAX];
};
+struct nv30_vtxelt_state {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+};
+
struct nv30_context {
struct pipe_context pipe;
@@ -142,8 +147,7 @@ struct nv30_context {
unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
+ struct nv30_vtxelt_state *vtxelt;
};
static INLINE struct nv30_context *
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 697b1b92ff..bfa27b632f 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -18,7 +18,7 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -78,7 +78,7 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
+ if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
@@ -232,8 +232,9 @@ void
nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv30_miptree_create;
- pscreen->texture_blanket = nv30_miptree_blanket;
pscreen->texture_destroy = nv30_miptree_destroy;
pscreen->get_tex_surface = nv30_miptree_surface_new;
pscreen->tex_surface_destroy = nv30_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv30_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index d911c80707..24b15a63ac 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -669,15 +669,34 @@ nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
}
+static void *
+nv30_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv30_vtxelt_state *cso = CALLOC_STRUCT(nv30_vtxelt_state);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+/* nv30_vtxelt_construct(cso);*/
+
+ return (void *)cso;
+}
+
static void
-nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv30_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv30_context *nv30 = nv30_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv30->vtxelt, ve, sizeof(*ve) * count);
- nv30->vtxelt_nr = count;
+static void
+nv30_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv30_context *nv30 = nv30_context(pipe);
+ nv30->vtxelt = hwcso;
nv30->dirty |= NV30_NEW_ARRAYS;
/*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
}
@@ -722,7 +741,10 @@ nv30_init_state_functions(struct nv30_context *nv30)
nv30->pipe.set_scissor_state = nv30_set_scissor_state;
nv30->pipe.set_viewport_state = nv30_set_viewport_state;
+ nv30->pipe.create_vertex_elements_state = nv30_vtxelts_state_create;
+ nv30->pipe.delete_vertex_elements_state = nv30_vtxelts_state_delete;
+ nv30->pipe.bind_vertex_elements_state = nv30_vtxelts_state_bind;
+
nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
- nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
index e42e872de7..66c26360cb 100644
--- a/src/gallium/drivers/nv30/nv30_state.h
+++ b/src/gallium/drivers/nv30/nv30_state.h
@@ -70,6 +70,8 @@ struct nv30_fragment_program {
struct nouveau_stateobj *so;
};
+#define NV30_MAX_TEXTURE_LEVELS 16
+
struct nv30_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
@@ -80,7 +82,7 @@ struct nv30_miptree {
struct {
uint pitch;
uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
+ } level[NV30_MAX_TEXTURE_LEVELS];
};
#endif
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index e48823a913..f3856bb5a5 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -492,16 +492,16 @@ nv30_vbo_validate(struct nv30_context *nv30)
int hw;
vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr);
+ so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr);
+ so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt->num_elements);
- for (hw = 0; hw < nv30->vtxelt_nr; hw++) {
+ for (hw = 0; hw < nv30->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb;
unsigned type, ncomp;
- ve = &nv30->vtxelt[hw];
+ ve = &nv30->vtxelt->pipe[hw];
vb = &nv30->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) {
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index 97fb6a2ef9..2550ec654b 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -107,6 +107,12 @@ struct nv40_state {
struct nouveau_stateobj *hw[NV40_STATE_MAX];
};
+
+struct nv40_vtxelt_state {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+};
+
struct nv40_context {
struct pipe_context pipe;
@@ -157,8 +163,7 @@ struct nv40_context {
unsigned dirty_samplers;
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
+ struct nv40_vtxelt_state *vtxelt;
};
static INLINE struct nv40_context *
diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c
index 85d7e1f197..62e97bcea4 100644
--- a/src/gallium/drivers/nv40/nv40_miptree.c
+++ b/src/gallium/drivers/nv40/nv40_miptree.c
@@ -20,7 +20,7 @@ nv40_miptree_layout(struct nv40_miptree *mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -80,7 +80,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
+ if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
@@ -227,9 +227,10 @@ void
nv40_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv40_miptree_create;
- pscreen->texture_blanket = nv40_miptree_blanket;
pscreen->texture_destroy = nv40_miptree_destroy;
pscreen->get_tex_surface = nv40_miptree_surface_new;
pscreen->tex_surface_destroy = nv40_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv40_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 4f28675e64..ee471e6ce4 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -684,15 +684,34 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
+static void *
+nv40_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv40_vtxelt_state *cso = CALLOC_STRUCT(nv40_vtxelt_state);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+/* nv40_vtxelt_construct(cso);*/
+
+ return (void *)cso;
+}
+
static void
-nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv40_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv40_context *nv40 = nv40_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
- nv40->vtxelt_nr = count;
+static void
+nv40_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv40_context *nv40 = nv40_context(pipe);
+ nv40->vtxelt = hwcso;
nv40->dirty |= NV40_NEW_ARRAYS;
nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
@@ -737,7 +756,10 @@ nv40_init_state_functions(struct nv40_context *nv40)
nv40->pipe.set_scissor_state = nv40_set_scissor_state;
nv40->pipe.set_viewport_state = nv40_set_viewport_state;
+ nv40->pipe.create_vertex_elements_state = nv40_vtxelts_state_create;
+ nv40->pipe.delete_vertex_elements_state = nv40_vtxelts_state_delete;
+ nv40->pipe.bind_vertex_elements_state = nv40_vtxelts_state_bind;
+
nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
- nv40->pipe.set_vertex_elements = nv40_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index 192074e747..e2e69420ea 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -73,6 +73,8 @@ struct nv40_fragment_program {
struct nouveau_stateobj *so;
};
+#define NV40_MAX_TEXTURE_LEVELS 16
+
struct nv40_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
@@ -83,7 +85,7 @@ struct nv40_miptree {
struct {
uint pitch;
uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
+ } level[NV40_MAX_TEXTURE_LEVELS];
};
#endif
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 8990f303ce..297d71f4fa 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -174,7 +174,7 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
- draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
+ draw_set_vertex_elements(draw, nv40->vtxelt->num_elements, nv40->vtxelt->pipe);
}
nv40_state_do_validate(nv40, swtnl_states);
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index 7812460d2e..fabdf4bf23 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -493,16 +493,16 @@ nv40_vbo_validate(struct nv40_context *nv40)
int hw;
vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr);
+ so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr);
+ so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt->num_elements);
- for (hw = 0; hw < nv40->vtxelt_nr; hw++) {
+ for (hw = 0; hw < nv40->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb;
unsigned type, ncomp;
- ve = &nv40->vtxelt[hw];
+ ve = &nv40->vtxelt->pipe[hw];
vb = &nv40->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) {
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index 612aea28a3..5d622e1c13 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
nv50_surface.c \
nv50_tex.c \
nv50_transfer.c \
- nv50_vbo.c
+ nv50_vbo.c \
+ nv50_push.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index e0b2d2880b..8afc95c9fc 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -36,7 +36,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i;
- if (!nv50_state_validate(nv50))
+ if (!nv50_state_validate(nv50, 64))
return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 7be12fcdef..0eb42f323f 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -46,43 +46,13 @@ static void
nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ int i;
- if (nv50->state.fb)
- so_ref(NULL, &nv50->state.fb);
- if (nv50->state.blend)
- so_ref(NULL, &nv50->state.blend);
- if (nv50->state.blend_colour)
- so_ref(NULL, &nv50->state.blend_colour);
- if (nv50->state.zsa)
- so_ref(NULL, &nv50->state.zsa);
- if (nv50->state.rast)
- so_ref(NULL, &nv50->state.rast);
- if (nv50->state.stipple)
- so_ref(NULL, &nv50->state.stipple);
- if (nv50->state.scissor)
- so_ref(NULL, &nv50->state.scissor);
- if (nv50->state.viewport)
- so_ref(NULL, &nv50->state.viewport);
- if (nv50->state.tsc_upload)
- so_ref(NULL, &nv50->state.tsc_upload);
- if (nv50->state.tic_upload)
- so_ref(NULL, &nv50->state.tic_upload);
- if (nv50->state.vertprog)
- so_ref(NULL, &nv50->state.vertprog);
- if (nv50->state.fragprog)
- so_ref(NULL, &nv50->state.fragprog);
- if (nv50->state.geomprog)
- so_ref(NULL, &nv50->state.geomprog);
- if (nv50->state.fp_linkage)
- so_ref(NULL, &nv50->state.fp_linkage);
- if (nv50->state.gp_linkage)
- so_ref(NULL, &nv50->state.gp_linkage);
- if (nv50->state.vtxfmt)
- so_ref(NULL, &nv50->state.vtxfmt);
- if (nv50->state.vtxbuf)
- so_ref(NULL, &nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_ref(NULL, &nv50->state.vtxattr);
+ for (i = 0; i < 64; i++) {
+ if (!nv50->state.hw[i])
+ continue;
+ so_ref(NULL, &nv50->state.hw[i]);
+ }
draw_destroy(nv50->draw);
@@ -123,7 +93,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
screen->base.channel->user_private = nv50;
- screen->base.channel->flush_notify = nv50_state_flush_notify;
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index c540594b94..8793c2aac5 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -72,6 +72,12 @@ struct nv50_sampler_stateobj {
unsigned tsc[8];
};
+struct nv50_vtxelt_stateobj {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+ uint32_t hw[16];
+};
+
static INLINE unsigned
get_tile_height(uint32_t tile_mode)
{
@@ -90,10 +96,12 @@ struct nv50_miptree_level {
unsigned tile_mode;
};
+#define NV50_MAX_TEXTURE_LEVELS 16
+
struct nv50_miptree {
struct nouveau_miptree base;
- struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
+ struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};
@@ -115,30 +123,12 @@ nv50_surface(struct pipe_surface *pt)
}
struct nv50_state {
- unsigned dirty;
+ struct nouveau_stateobj *hw[64];
+ uint64_t hw_dirty;
- struct nouveau_stateobj *fb;
- struct nouveau_stateobj *blend;
- struct nouveau_stateobj *blend_colour;
- struct nouveau_stateobj *zsa;
- struct nouveau_stateobj *stencil_ref;
- struct nouveau_stateobj *rast;
- struct nouveau_stateobj *stipple;
- struct nouveau_stateobj *scissor;
- unsigned scissor_enabled;
- struct nouveau_stateobj *viewport;
- struct nouveau_stateobj *tsc_upload;
- struct nouveau_stateobj *tic_upload;
unsigned miptree_nr[PIPE_SHADER_TYPES];
- struct nouveau_stateobj *vertprog;
- struct nouveau_stateobj *fragprog;
- struct nouveau_stateobj *geomprog;
- struct nouveau_stateobj *fp_linkage;
- struct nouveau_stateobj *gp_linkage;
- struct nouveau_stateobj *vtxfmt;
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
- struct nouveau_stateobj *instbuf;
unsigned vtxelt_nr;
};
@@ -167,14 +157,13 @@ struct nv50_context {
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_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];
- uint16_t vbo_fifo;
+ unsigned vbo_fifo;
};
static INLINE struct nv50_context *
@@ -216,24 +205,36 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned count,
unsigned startInstance,
unsigned instanceCount);
-extern void nv50_vbo_validate(struct nv50_context *nv50);
+extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
+extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
+
+/* nv50_push.c */
+extern void
+nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
+ unsigned idxsize, unsigned mode, unsigned start,
+ unsigned count, unsigned i_start,
+ unsigned i_count);
/* nv50_clear.c */
extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
const float *rgba, double depth, unsigned stencil);
/* nv50_program.c */
-extern void nv50_vertprog_validate(struct nv50_context *nv50);
-extern void nv50_fragprog_validate(struct nv50_context *nv50);
-extern void nv50_geomprog_validate(struct nv50_context *nv50);
-extern void nv50_fp_linkage_validate(struct nv50_context *nv50);
-extern void nv50_gp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_vertprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fragprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_geomprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_gp_linkage_validate(struct nv50_context *nv50);
extern void nv50_program_destroy(struct nv50_context *nv50,
struct nv50_program *p);
/* nv50_state_validate.c */
-extern boolean nv50_state_validate(struct nv50_context *nv50);
-extern void nv50_state_flush_notify(struct nouveau_channel *chan);
+extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
extern void nv50_so_init_sifc(struct nv50_context *nv50,
struct nouveau_stateobj *so,
@@ -241,7 +242,8 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,
unsigned offset, unsigned size);
/* nv50_tex.c */
-extern void nv50_tex_validate(struct nv50_context *);
+extern void nv50_tex_relocs(struct nv50_context *);
+extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
/* nv50_transfer.c */
extern void
@@ -255,4 +257,35 @@ nv50_upload_sifc(struct nv50_context *nv50,
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv);
+static INLINE unsigned
+nv50_prim(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
+ case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
+ case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
+ case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
+ case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
+ case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
+ case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
+ case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
+ case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
+ default:
+ break;
+ }
+
+ NOUVEAU_ERR("invalid primitive type %d\n", mode);
+ return NV50TCL_VERTEX_BEGIN_POINTS;
+}
+
#endif
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 3f9d869d7a..e091cae602 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -104,7 +104,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
tile_flags = 0x7400;
break;
default:
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) &&
util_format_get_blocksizebits(pt->format) == 32)
tile_flags = 0x7a00;
else
@@ -255,9 +255,10 @@ void
nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv50_miptree_create;
- pscreen->texture_blanket = nv50_miptree_blanket;
pscreen->texture_destroy = nv50_miptree_destroy;
pscreen->get_tex_surface = nv50_miptree_surface_new;
pscreen->tex_surface_destroy = nv50_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 2372cbbef6..c857816b31 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -4270,7 +4270,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
FREE(up);
}
-void
+struct nouveau_stateobj *
nv50_vertprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4286,6 +4286,9 @@ nv50_vertprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_VERTPROG))
+ return NULL;
+
so = so_new(5, 7, 2);
so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4301,11 +4304,10 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp);
so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.vertprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_fragprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4321,6 +4323,9 @@ nv50_fragprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_FRAGPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4337,11 +4342,10 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.regs[3]);
so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.fragprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_geomprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4357,6 +4361,9 @@ nv50_geomprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_GEOMPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4373,8 +4380,7 @@ nv50_geomprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.vert_count);
so_method(so, tesla, NV50TCL_GP_START_ID, 1);
so_data (so, 0);
- so_ref(so, &nv50->state.geomprog);
- so_ref(NULL, &so);
+ return so;
}
static uint32_t
@@ -4454,7 +4460,7 @@ nv50_vec4_map(uint32_t *map32, int mid, uint8_t zval, uint32_t lin[4],
return mid;
}
-void
+struct nouveau_stateobj *
nv50_fp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4580,8 +4586,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_GP_ENABLE, 1);
so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0);
- so_ref(so, &nv50->state.fp_linkage);
- so_ref(NULL, &so);
+ return so;
}
static int
@@ -4615,7 +4620,7 @@ construct_vp_gp_mapping(uint32_t *map32, int m,
return m;
}
-void
+struct nouveau_stateobj *
nv50_gp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4625,10 +4630,8 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
uint32_t map[16];
int m = 0;
- if (!gp) {
- so_ref(NULL, &nv50->state.gp_linkage);
- return;
- }
+ if (!gp)
+ return NULL;
memset(map, 0, sizeof(map));
m = construct_vp_gp_mapping(map, m, vp, gp);
@@ -4646,8 +4649,7 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m);
so_datap (so, map, m);
- so_ref(so, &nv50->state.gp_linkage);
- so_ref(NULL, &so);
+ return so;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
new file mode 100644
index 0000000000..96a1f32d30
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -0,0 +1,326 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
+#include "nouveau/nouveau_util.h"
+#include "nv50_context.h"
+
+struct push_context {
+ struct nv50_context *nv50;
+
+ unsigned vtx_size;
+
+ void *idxbuf;
+ unsigned idxsize;
+
+ float edgeflag;
+ int edgeflag_attr;
+
+ struct {
+ void *map;
+ unsigned stride;
+ unsigned divisor;
+ unsigned step;
+ void (*push)(struct nouveau_channel *, void *);
+ } attr[16];
+ unsigned attr_nr;
+};
+
+static void
+emit_b32_1(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b32_2(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+}
+
+static void
+emit_b32_3(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b32_4(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+ OUT_RING(chan, v[3]);
+}
+
+static void
+emit_b16_1(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b16_3(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, (v[1] << 16) | v[0]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b08_1(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b08_3(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
+}
+
+static INLINE void
+emit_vertex(struct push_context *ctx, unsigned n)
+{
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ int i;
+
+ if (ctx->edgeflag_attr < 16) {
+ float *edgeflag = ctx->attr[ctx->edgeflag_attr].map +
+ ctx->attr[ctx->edgeflag_attr].stride * n;
+
+ if (*edgeflag != ctx->edgeflag) {
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, *edgeflag ? 1 : 0);
+ ctx->edgeflag = *edgeflag;
+ }
+ }
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
+ for (i = 0; i < ctx->attr_nr; i++)
+ ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n);
+}
+
+static void
+emit_edgeflag(void *priv, boolean enabled)
+{
+ struct push_context *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+emit_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint8_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt16(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint16_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint32_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_verts(void *priv, unsigned start, unsigned count)
+{
+ while (count--)
+ emit_vertex(priv, start++);
+}
+
+void
+nv50_push_elements_instanced(struct pipe_context *pipe,
+ struct pipe_buffer *idxbuf, unsigned idxsize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned i_start, unsigned i_count)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ struct push_context ctx;
+ const unsigned p_overhead = 4 + /* begin/end */
+ 4; /* potential edgeflag enable/disable */
+ const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */
+ 2; /* potential edgeflag modification */
+ struct u_split_prim s;
+ unsigned vtx_size;
+ boolean nzi = FALSE;
+ int i;
+
+ ctx.nv50 = nv50;
+ ctx.attr_nr = 0;
+ ctx.idxbuf = NULL;
+ ctx.vtx_size = 0;
+ ctx.edgeflag = 0.5f;
+ ctx.edgeflag_attr = nv50->vertprog->cfg.edgeflag_in;
+
+ /* map vertex buffers, determine vertex size */
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
+ struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ unsigned size, nr_components, n;
+
+ if (!(nv50->vbo_fifo & (1 << i)))
+ continue;
+ n = ctx.attr_nr++;
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset;
+ nouveau_bo_unmap(bo);
+
+ ctx.attr[n].stride = vb->stride;
+ ctx.attr[n].divisor = ve->instance_divisor;
+ if (ctx.attr[n].divisor) {
+ ctx.attr[n].step = i_start % ve->instance_divisor;
+ ctx.attr[n].map += i_start * vb->stride;
+ }
+
+ size = util_format_get_component_bits(ve->src_format,
+ UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(ve->src_format);
+ switch (size) {
+ case 8:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b08_1; break;
+ case 2: ctx.attr[n].push = emit_b16_1; break;
+ case 3: ctx.attr[n].push = emit_b08_3; break;
+ case 4: ctx.attr[n].push = emit_b32_1; break;
+ }
+ ctx.vtx_size++;
+ break;
+ case 16:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b16_1; break;
+ case 2: ctx.attr[n].push = emit_b32_1; break;
+ case 3: ctx.attr[n].push = emit_b16_3; break;
+ case 4: ctx.attr[n].push = emit_b32_2; break;
+ }
+ ctx.vtx_size += (nr_components + 1) >> 1;
+ break;
+ case 32:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b32_1; break;
+ case 2: ctx.attr[n].push = emit_b32_2; break;
+ case 3: ctx.attr[n].push = emit_b32_3; break;
+ case 4: ctx.attr[n].push = emit_b32_4; break;
+ }
+ ctx.vtx_size += nr_components;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ }
+ vtx_size = ctx.vtx_size + v_overhead;
+
+ /* map index buffer, if present */
+ if (idxbuf) {
+ struct nouveau_bo *bo = nouveau_bo(idxbuf);
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.idxbuf = bo->map;
+ ctx.idxsize = idxsize;
+ nouveau_bo_unmap(bo);
+ }
+
+ s.priv = &ctx;
+ s.edge = emit_edgeflag;
+ if (idxbuf) {
+ if (idxsize == 1)
+ s.emit = emit_elt08;
+ else
+ if (idxsize == 2)
+ s.emit = emit_elt16;
+ else
+ s.emit = emit_elt32;
+ } else
+ s.emit = emit_verts;
+
+ /* per-instance loop */
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, i_start);
+ while (i_count--) {
+ unsigned max_verts;
+ boolean done;
+
+ for (i = 0; i < ctx.attr_nr; i++) {
+ if (!ctx.attr[i].divisor ||
+ ctx.attr[i].divisor != ++ctx.attr[i].step)
+ continue;
+ ctx.attr[i].step = 0;
+ ctx.attr[i].map += ctx.attr[i].stride;
+ }
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) {
+ assert(0);
+ return;
+ }
+ }
+
+ max_verts = AVAIL_RING(chan);
+ max_verts -= p_overhead;
+ max_verts /= vtx_size;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
+
+ nzi = TRUE;
+ }
+}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index eed6031eaf..7e2e8aa336 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -95,6 +95,8 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
static int
nv50_screen_get_param(struct pipe_screen *pscreen, int param)
{
+ struct nv50_screen *screen = nv50_screen(pscreen);
+
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32;
@@ -132,9 +134,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
case NOUVEAU_CAP_HW_VTXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case NOUVEAU_CAP_HW_IDXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -202,28 +204,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
FREE(screen);
}
-static int
-nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
- unsigned usage)
-{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nv50_context *ctx = screen->cur_ctx;
-
- if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX))
- return 0;
-
- /* Our vtxbuf got mapped, it can no longer be considered part of current
- * state, remove it to avoid emitting reloc markers.
- */
- if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf,
- nouveau_bo(pb))) {
- so_ref(NULL, &ctx->state.vtxbuf);
- ctx->dirty |= NV50_NEW_ARRAYS;
- }
-
- return 0;
-}
-
struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
@@ -252,7 +232,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->get_paramf = nv50_screen_get_paramf;
pscreen->is_format_supported = nv50_screen_is_format_supported;
pscreen->context_create = nv50_create;
- screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
nv50_screen_init_miptree_functions(pscreen);
nv50_transfer_init_screen_functions(pscreen);
@@ -508,10 +487,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
so_data (so, 1);
- /* activate first scissor rectangle */
- so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
- so_data (so, 1);
-
so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
so_data (so, 1); /* default edgeflag to TRUE */
@@ -520,6 +495,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_ref (NULL, &so);
nouveau_pushbuf_flush(chan, 0);
+ 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 2687b72127..d1bc80cb9e 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -28,6 +28,8 @@ struct nv50_screen {
struct nouveau_bo *tsc;
struct nouveau_stateobj *static_init;
+
+ boolean force_push;
};
static INLINE struct nv50_screen *
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7d304907b6..b0e5552eff 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -302,7 +302,7 @@ static void *
nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
- struct nouveau_stateobj *so = so_new(15, 21, 0);
+ struct nouveau_stateobj *so = so_new(16, 22, 0);
struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
struct nv50_rasterizer_stateobj *rso =
CALLOC_STRUCT(nv50_rasterizer_stateobj);
@@ -314,6 +314,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
* - point_sprite / sprite_coord_mode
*/
+ so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
+ so_data (so, cso->scissor);
+
so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
NV50TCL_SHADE_MODEL_SMOOTH);
@@ -720,15 +723,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv50->dirty |= NV50_NEW_ARRAYS;
}
+static void *
+nv50_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+ nv50_vtxelt_construct(cso);
+
+ return (void *)cso;
+}
+
static void
-nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv50_context *nv50 = nv50_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
- nv50->vtxelt_nr = count;
+static void
+nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ nv50->vtxelt = hwcso;
nv50->dirty |= NV50_NEW_ARRAYS;
}
@@ -778,7 +800,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.set_scissor_state = nv50_set_scissor_state;
nv50->pipe.set_viewport_state = nv50_set_viewport_state;
+ nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
+ nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
+ nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
+
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
- nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index c974cc92dc..2c8e7ca798 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -25,8 +25,8 @@
#include "nv50_context.h"
#include "nouveau/nouveau_stateobj.h"
-static void
-nv50_state_validate_fb(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_fb(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(32, 79, 18);
@@ -167,12 +167,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, w << 16);
so_data (so, h << 16);
- /* we set scissors to framebuffer size when they're 'turned off' */
- nv50->dirty |= NV50_NEW_SCISSOR;
- so_ref(NULL, &nv50->state.scissor);
-
- so_ref(so, &nv50->state.fb);
- so_ref(NULL, &so);
+ return so;
}
static void
@@ -199,263 +194,256 @@ nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
}
}
-static void
-nv50_state_emit(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_blend(struct nv50_context *nv50)
{
- struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->blend->so, &so);
+ return so;
+}
- /* XXX: this is racy for multiple contexts active on separate
- * threads.
- */
- if (screen->cur_ctx != nv50) {
- if (nv50->state.fb)
- nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
- if (nv50->state.blend)
- nv50->state.dirty |= NV50_NEW_BLEND;
- if (nv50->state.zsa)
- nv50->state.dirty |= NV50_NEW_ZSA;
- if (nv50->state.vertprog)
- nv50->state.dirty |= NV50_NEW_VERTPROG;
- if (nv50->state.fragprog)
- nv50->state.dirty |= NV50_NEW_FRAGPROG;
- if (nv50->state.geomprog)
- nv50->state.dirty |= NV50_NEW_GEOMPROG;
- if (nv50->state.rast)
- nv50->state.dirty |= NV50_NEW_RASTERIZER;
- if (nv50->state.blend_colour)
- nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
- if (nv50->state.stencil_ref)
- nv50->state.dirty |= NV50_NEW_STENCIL_REF;
- if (nv50->state.stipple)
- nv50->state.dirty |= NV50_NEW_STIPPLE;
- if (nv50->state.scissor)
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- if (nv50->state.viewport)
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
- if (nv50->state.tsc_upload)
- nv50->state.dirty |= NV50_NEW_SAMPLER;
- if (nv50->state.tic_upload)
- nv50->state.dirty |= NV50_NEW_TEXTURE;
- if (nv50->state.vtxfmt && nv50->state.vtxbuf)
- nv50->state.dirty |= NV50_NEW_ARRAYS;
- screen->cur_ctx = nv50;
- }
+static struct nouveau_stateobj *
+validate_zsa(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->zsa->so, &so);
+ return so;
+}
- if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
- so_emit(chan, nv50->state.fb);
- if (nv50->state.dirty & NV50_NEW_BLEND)
- so_emit(chan, nv50->state.blend);
- if (nv50->state.dirty & NV50_NEW_ZSA)
- so_emit(chan, nv50->state.zsa);
- if (nv50->state.dirty & NV50_NEW_VERTPROG)
- so_emit(chan, nv50->state.vertprog);
- if (nv50->state.dirty & NV50_NEW_FRAGPROG)
- so_emit(chan, nv50->state.fragprog);
- if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog)
- so_emit(chan, nv50->state.geomprog);
- if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- so_emit(chan, nv50->state.fp_linkage);
- if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG))
- && nv50->state.gp_linkage)
- so_emit(chan, nv50->state.gp_linkage);
- if (nv50->state.dirty & NV50_NEW_RASTERIZER)
- so_emit(chan, nv50->state.rast);
- if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
- so_emit(chan, nv50->state.blend_colour);
- if (nv50->state.dirty & NV50_NEW_STENCIL_REF)
- so_emit(chan, nv50->state.stencil_ref);
- if (nv50->state.dirty & NV50_NEW_STIPPLE)
- so_emit(chan, nv50->state.stipple);
- if (nv50->state.dirty & NV50_NEW_SCISSOR)
- so_emit(chan, nv50->state.scissor);
- if (nv50->state.dirty & NV50_NEW_VIEWPORT)
- so_emit(chan, nv50->state.viewport);
- if (nv50->state.dirty & NV50_NEW_SAMPLER)
- so_emit(chan, nv50->state.tsc_upload);
- if (nv50->state.dirty & NV50_NEW_TEXTURE)
- so_emit(chan, nv50->state.tic_upload);
- if (nv50->state.dirty & NV50_NEW_ARRAYS) {
- so_emit(chan, nv50->state.vtxfmt);
- so_emit(chan, nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_emit(chan, nv50->state.vtxattr);
- }
- nv50->state.dirty = 0;
+static struct nouveau_stateobj *
+validate_rast(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->rasterizer->so, &so);
+ return so;
}
-void
-nv50_state_flush_notify(struct nouveau_channel *chan)
+static struct nouveau_stateobj *
+validate_blend_colour(struct nv50_context *nv50)
{
- struct nv50_context *nv50 = chan->user_private;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 4, 0);
+
+ so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
+ so_data (so, fui(nv50->blend_colour.color[0]));
+ so_data (so, fui(nv50->blend_colour.color[1]));
+ so_data (so, fui(nv50->blend_colour.color[2]));
+ so_data (so, fui(nv50->blend_colour.color[3]));
+ return so;
+}
- if (nv50->state.tic_upload && !(nv50->dirty & NV50_NEW_TEXTURE))
- so_emit(chan, nv50->state.tic_upload);
+static struct nouveau_stateobj *
+validate_stencil_ref(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so = so_new(2, 2, 0);
- so_emit_reloc_markers(chan, nv50->state.fb);
- so_emit_reloc_markers(chan, nv50->state.vertprog);
- so_emit_reloc_markers(chan, nv50->state.fragprog);
- so_emit_reloc_markers(chan, nv50->state.vtxbuf);
- so_emit_reloc_markers(chan, nv50->screen->static_init);
+ so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[0]);
+ so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[1]);
+ return so;
+}
- if (nv50->state.instbuf)
- so_emit_reloc_markers(chan, nv50->state.instbuf);
+static struct nouveau_stateobj *
+validate_stipple(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 32, 0);
+ int i;
+
+ so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
+ for (i = 0; i < 32; i++)
+ so_data(so, util_bswap32(nv50->stipple.stipple[i]));
+ return so;
}
-boolean
-nv50_state_validate(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_scissor(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct pipe_scissor_state *s = &nv50->scissor;
struct nouveau_stateobj *so;
- unsigned i;
- if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
- nv50_state_validate_fb(nv50);
+ so = so_new(1, 2, 0);
+ so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
+ so_data (so, (s->maxx << 16) | s->minx);
+ so_data (so, (s->maxy << 16) | s->miny);
+ return so;
+}
+
+static struct nouveau_stateobj *
+validate_viewport(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(5, 9, 0);
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
+ so_data (so, fui(nv50->viewport.translate[0]));
+ so_data (so, fui(nv50->viewport.translate[1]));
+ so_data (so, fui(nv50->viewport.translate[2]));
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
+ so_data (so, fui(nv50->viewport.scale[0]));
+ so_data (so, fui(nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[2]));
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+ so_data (so, 1);
+ /* 0x0000 = remove whole primitive only (xyz)
+ * 0x1018 = remove whole primitive only (xy), clamp z
+ * 0x1080 = clip primitive (xyz)
+ * 0x1098 = clip primitive (xy), clamp z
+ */
+ so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+ so_data (so, 0x1080);
+ /* no idea what 0f90 does */
+ so_method(so, tesla, 0x0f90, 1);
+ so_data (so, 0);
+
+ return so;
+}
- if (nv50->dirty & NV50_NEW_BLEND)
- so_ref(nv50->blend->so, &nv50->state.blend);
+static struct nouveau_stateobj *
+validate_sampler(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so;
+ unsigned nr = 0, i;
- if (nv50->dirty & NV50_NEW_ZSA)
- so_ref(nv50->zsa->so, &nv50->state.zsa);
+ for (i = 0; i < PIPE_SHADER_TYPES; ++i)
+ nr += nv50->sampler_nr[i];
- if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
- nv50_vertprog_validate(nv50);
+ so = so_new(1 + 5 * PIPE_SHADER_TYPES,
+ 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
+ PIPE_SHADER_TYPES * 2);
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
- nv50_fragprog_validate(nv50);
+ nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
+ nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB))
- nv50_geomprog_validate(nv50);
+ so_method(so, tesla, 0x1334, 1); /* flush TSC */
+ so_data (so, 0);
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- nv50_fp_linkage_validate(nv50);
+ return so;
+}
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG))
- nv50_gp_linkage_validate(nv50);
+static struct nouveau_stateobj *
+validate_vtxbuf(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxbuf, &so);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_RASTERIZER)
- so_ref(nv50->rasterizer->so, &nv50->state.rast);
+static struct nouveau_stateobj *
+validate_vtxattr(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxattr, &so);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
- so = so_new(1, 4, 0);
- so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
- so_data (so, fui(nv50->blend_colour.color[0]));
- so_data (so, fui(nv50->blend_colour.color[1]));
- so_data (so, fui(nv50->blend_colour.color[2]));
- so_data (so, fui(nv50->blend_colour.color[3]));
- so_ref(so, &nv50->state.blend_colour);
- so_ref(NULL, &so);
- }
+struct state_validate {
+ struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
+ unsigned states;
+} validate_list[] = {
+ { validate_fb , NV50_NEW_FRAMEBUFFER },
+ { validate_blend , NV50_NEW_BLEND },
+ { validate_zsa , NV50_NEW_ZSA },
+ { nv50_vertprog_validate , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB },
+ { nv50_fragprog_validate , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB },
+ { nv50_geomprog_validate , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB },
+ { nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG |
+ NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER },
+ { nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG },
+ { validate_rast , NV50_NEW_RASTERIZER },
+ { validate_blend_colour , NV50_NEW_BLEND_COLOUR },
+ { validate_stencil_ref , NV50_NEW_STENCIL_REF },
+ { validate_stipple , NV50_NEW_STIPPLE },
+ { validate_scissor , NV50_NEW_SCISSOR },
+ { validate_viewport , NV50_NEW_VIEWPORT },
+ { validate_sampler , NV50_NEW_SAMPLER },
+ { nv50_tex_validate , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER },
+ { nv50_vbo_validate , NV50_NEW_ARRAYS },
+ { validate_vtxbuf , NV50_NEW_ARRAYS },
+ { validate_vtxattr , NV50_NEW_ARRAYS },
+ {}
+};
+#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
- if (nv50->dirty & NV50_NEW_STENCIL_REF) {
- so = so_new(2, 2, 0);
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[0]);
- so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[1]);
- so_ref(so, &nv50->state.stencil_ref);
- so_ref(NULL, &so);
- }
+boolean
+nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
+{
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4;
+ int ret, i;
- if (nv50->dirty & NV50_NEW_STIPPLE) {
- so = so_new(1, 32, 0);
- so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, util_bswap32(nv50->stipple.stipple[i]));
- so_ref(so, &nv50->state.stipple);
- so_ref(NULL, &so);
- }
+ for (i = 0; i < validate_list_len; i++) {
+ struct state_validate *validate = &validate_list[i];
+ struct nouveau_stateobj *so;
- if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
- struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
- struct pipe_scissor_state *s = &nv50->scissor;
+ if (!(nv50->dirty & validate->states))
+ continue;
- if (nv50->state.scissor &&
- (rast->scissor == 0 && nv50->state.scissor_enabled == 0))
- goto scissor_uptodate;
- nv50->state.scissor_enabled = rast->scissor;
+ so = validate->func(nv50);
+ if (!so)
+ continue;
- so = so_new(1, 2, 0);
- so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
- if (nv50->state.scissor_enabled) {
- so_data(so, (s->maxx << 16) | s->minx);
- so_data(so, (s->maxy << 16) | s->miny);
- } else {
- so_data(so, (nv50->framebuffer.width << 16));
- so_data(so, (nv50->framebuffer.height << 16));
- }
- so_ref(so, &nv50->state.scissor);
- so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- }
-scissor_uptodate:
-
- if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
- if (nv50->state.viewport &&
- !(nv50->dirty & NV50_NEW_VIEWPORT))
- goto viewport_uptodate;
-
- so = so_new(5, 9, 0);
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
- so_data (so, fui(nv50->viewport.translate[0]));
- so_data (so, fui(nv50->viewport.translate[1]));
- so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
- so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(nv50->viewport.scale[1]));
- so_data (so, fui(nv50->viewport.scale[2]));
-
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
- so_data (so, 1);
- /* 0x0000 = remove whole primitive only (xyz)
- * 0x1018 = remove whole primitive only (xy), clamp z
- * 0x1080 = clip primitive (xyz)
- * 0x1098 = clip primitive (xy), clamp z
- */
- so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
- so_data (so, 0x1080);
- /* no idea what 0f90 does */
- so_method(so, tesla, 0x0f90, 1);
- so_data (so, 0);
+ nr_dwords += (so->total + so->cur);
+ nr_relocs += so->cur_reloc;
- so_ref(so, &nv50->state.viewport);
+ so_ref(so, &nv50->state.hw[i]);
so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
+ nv50->state.hw_dirty |= (1 << i);
}
-viewport_uptodate:
-
- if (nv50->dirty & NV50_NEW_SAMPLER) {
- unsigned nr = 0;
-
- for (i = 0; i < PIPE_SHADER_TYPES; ++i)
- nr += nv50->sampler_nr[i];
+ nv50->dirty = 0;
- so = so_new(1 + 5 * PIPE_SHADER_TYPES,
- 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
- PIPE_SHADER_TYPES * 2);
+ if (nv50->screen->cur_ctx != nv50) {
+ for (i = 0; i < validate_list_len; i++) {
+ if (!nv50->state.hw[i] ||
+ (nv50->state.hw_dirty & (1 << i)))
+ continue;
- nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
- nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
+ nr_dwords += (nv50->state.hw[i]->total +
+ nv50->state.hw[i]->cur);
+ nr_relocs += nv50->state.hw[i]->cur_reloc;
+ nv50->state.hw_dirty |= (1 << i);
+ }
- so_method(so, tesla, 0x1334, 1); /* flush TSC */
- so_data (so, 0);
+ nv50->screen->cur_ctx = nv50;
+ }
- so_ref(so, &nv50->state.tsc_upload);
- so_ref(NULL, &so);
+ ret = MARK_RING(chan, nr_dwords, nr_relocs);
+ if (ret) {
+ debug_printf("MARK_RING(%d, %d) failed: %d\n",
+ nr_dwords, nr_relocs, ret);
+ return FALSE;
}
- if (nv50->dirty & (NV50_NEW_TEXTURE | NV50_NEW_SAMPLER))
- nv50_tex_validate(nv50);
+ while (nv50->state.hw_dirty) {
+ i = ffs(nv50->state.hw_dirty) - 1;
+ nv50->state.hw_dirty &= ~(1 << i);
- if (nv50->dirty & NV50_NEW_ARRAYS)
- nv50_vbo_validate(nv50);
+ so_emit(chan, nv50->state.hw[i]);
+ }
- nv50->state.dirty |= nv50->dirty;
- nv50->dirty = 0;
- nv50_state_emit(nv50);
+ /* Yes, really, we need to do this. If a buffer that is referenced
+ * on the hardware isn't part of changed state above, without doing
+ * this the kernel is given no clue that the buffer is being used
+ * still. This can cause all sorts of fun issues.
+ */
+ nv50_tex_relocs(nv50);
+ so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */
+ 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);
+ /* No idea.. */
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
return TRUE;
}
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index de0560e20c..4c48b12cd8 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -24,6 +24,7 @@
#include "nv50_texture.h"
#include "nouveau/nouveau_stateobj.h"
+#include "nouveau/nouveau_reloc.h"
#include "util/u_format.h"
@@ -195,6 +196,35 @@ nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
}
void
+nv50_tex_relocs(struct nv50_context *nv50)
+{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
+ int p, unit;
+
+ p = PIPE_SHADER_FRAGMENT;
+ for (unit = 0; unit < nv50->miptree_nr[p]; unit++) {
+ if (!nv50->miptree[p][unit])
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50->miptree[p][unit]->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])
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50->miptree[p][unit]->base.bo, 0, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_RD, 0, 0);
+ }
+}
+
+struct nouveau_stateobj *
nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_stateobj *so;
@@ -217,12 +247,11 @@ nv50_tex_validate(struct nv50_context *nv50)
so_ref(NULL, &so);
NOUVEAU_ERR("failed tex validate\n");
- return;
+ return NULL;
}
so_method(so, tesla, 0x1330, 1); /* flush TIC */
so_data (so, 0);
- so_ref(so, &nv50->state.tic_upload);
- so_ref(NULL, &so);
+ return so;
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 1c8ee0b9ad..6b9c1ee231 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -25,53 +25,9 @@
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
-static boolean
-nv50_push_elements_u08(struct nv50_context *, uint8_t *, unsigned);
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *, uint16_t *, unsigned);
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *, uint32_t *, unsigned);
-
-static boolean
-nv50_push_arrays(struct nv50_context *, unsigned, unsigned);
-
-#define NV50_USING_LOATHED_EDGEFLAG(ctx) ((ctx)->vertprog->cfg.edgeflag_in < 16)
-
-static INLINE unsigned
-nv50_prim(unsigned mode)
-{
- switch (mode) {
- case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
- case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
- case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
- case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
- case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
- case PIPE_PRIM_TRIANGLE_STRIP:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
- case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
- case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
- case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
- case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
- case PIPE_PRIM_LINES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
- case PIPE_PRIM_LINE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
- case PIPE_PRIM_TRIANGLES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
- case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
- default:
- break;
- }
-
- NOUVEAU_ERR("invalid primitive type %d\n", mode);
- return NV50TCL_VERTEX_BEGIN_POINTS;
-}
-
static INLINE uint32_t
nv50_vbo_type_to_hw(enum pipe_format format)
{
@@ -139,15 +95,16 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
uint32_t hw_type, hw_size;
enum pipe_format pf = ve->src_format;
const struct util_format_description *desc;
- unsigned size;
+ unsigned size, nr_components;
desc = util_format_description(pf);
assert(desc);
size = util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(pf);
hw_type = nv50_vbo_type_to_hw(pf);
- hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
+ hw_size = nv50_vbo_size_to_hw(size, nr_components);
if (!hw_type || !hw_size) {
NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf));
@@ -161,250 +118,58 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
return (hw_type | hw_size);
}
-/* For instanced drawing from user buffers, hitting the FIFO repeatedly
- * with the same vertex data is probably worse than uploading all data.
- */
-static boolean
-nv50_upload_vtxbuf(struct nv50_context *nv50, unsigned i)
-{
- struct nv50_screen *nscreen = nv50->screen;
- struct pipe_screen *pscreen = &nscreen->base.base;
- struct pipe_buffer *buf = nscreen->strm_vbuf[i];
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- uint8_t *src;
- unsigned size = align(vb->buffer->size, 4096);
-
- if (buf && buf->size < size)
- pipe_buffer_reference(&nscreen->strm_vbuf[i], NULL);
-
- if (!nscreen->strm_vbuf[i]) {
- nscreen->strm_vbuf[i] = pipe_buffer_create(
- pscreen, 0, PIPE_BUFFER_USAGE_VERTEX, size);
- buf = nscreen->strm_vbuf[i];
- }
-
- src = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- if (!src)
- return FALSE;
- src += vb->buffer_offset;
-
- size = (vb->max_index + 1) * vb->stride + 16; /* + 16 is for stride 0 */
- if (vb->buffer_offset + size > vb->buffer->size)
- size = vb->buffer->size - vb->buffer_offset;
-
- pipe_buffer_write(pscreen, buf, vb->buffer_offset, size, src);
- pipe_buffer_unmap(pscreen, vb->buffer);
-
- vb->buffer = buf; /* don't pipe_reference, this is a private copy */
- return TRUE;
-}
-
-static void
-nv50_upload_user_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- if (nv50->vbo_fifo)
- nv50->dirty |= NV50_NEW_ARRAYS;
- if (!(nv50->dirty & NV50_NEW_ARRAYS))
- return;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- if (nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)
- continue;
- nv50_upload_vtxbuf(nv50, i);
- }
-}
-
-static void
-nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data)
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- float v[4];
-
- util_format_read_4f(nv50->vtxelt[i].src_format,
- v, 0, data, 0, 0, 0, 1, 1);
-
- switch (nv50->vtxelt[i].nr_components) {
- case 4:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- OUT_RINGf (chan, v[3]);
- break;
- case 3:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_3F_X(i), 3);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- break;
- case 2:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_2F_X(i), 2);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- break;
- case 1:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_1F(i), 1);
- OUT_RINGf (chan, v[0]);
- break;
- default:
- assert(0);
- break;
- }
-}
-
-static unsigned
-init_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_bo *bo;
- unsigned i, b, count = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
- if (!bo->map)
- nouveau_bo_map(bo, NOUVEAU_BO_RD);
-
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
- }
-
- return count;
-}
-
-static unsigned
-init_per_instance_arrays(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
+struct instance {
struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b, count = 0;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo)
- return init_per_instance_arrays_immd(nv50, startInstance,
- pos, step);
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
-
- if (!startInstance) {
- step[i] = 0;
- continue;
- }
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
- }
-
- if (count && startInstance) {
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_emit(chan, nv50->state.instbuf);
- }
- so_ref (NULL, &so);
-
- return count;
-}
+ unsigned delta;
+ unsigned stride;
+ unsigned step;
+ unsigned divisor;
+};
static void
-step_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
{
- struct nouveau_bo *bo;
- unsigned i, b;
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- if (++step[i] != nv50->vtxelt[i].instance_divisor)
- continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb;
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ a[i].divisor = ve->instance_divisor;
+ if (a[i].divisor) {
+ vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
+ a[i].bo = nouveau_bo(vb->buffer);
+ a[i].stride = vb->stride;
+ a[i].step = first % a[i].divisor;
+ a[i].delta = vb->buffer_offset + ve->src_offset +
+ (first * a[i].stride);
+ }
}
}
static void
-step_per_instance_arrays(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_step(struct nv50_context *nv50, struct instance *a)
{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo) {
- step_per_instance_arrays_immd(nv50, pos, step);
- return;
- }
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ if (!a[i].divisor)
continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- if (++step[i] == nv50->vtxelt[i].instance_divisor) {
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ BEGIN_RING(chan, tesla,
+ NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
+ OUT_RELOCh(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ OUT_RELOCl(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ if (++a[i].step == a[i].divisor) {
+ a[i].step = 0;
+ a[i].delta += a[i].stride;
}
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
}
-
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_ref (NULL, &so);
-
- so_emit(chan, nv50->state.instbuf);
-}
-
-static INLINE void
-nv50_unmap_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
- if (nouveau_bo(nv50->vtxbuf[i].buffer)->map)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
}
void
@@ -415,198 +180,207 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 10 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, NULL, 0, mode, start,
+ count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 7 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, prim);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
OUT_RING (chan, start);
OUT_RING (chan, count);
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; i++) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- boolean ret;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- ret = nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- ret = TRUE;
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- nv50_unmap_vbufs(nv50);
-
- /* XXX: not sure what to do if ret != TRUE: flush and retry?
- */
- assert(ret);
+ nv50_draw_arrays_instanced(pipe, mode, start, count, 0, 1);
}
-static INLINE boolean
-nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
- unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
+struct inline_ctx {
+ struct nv50_context *nv50;
+ void *map;
+};
- if (nv50->vbo_fifo)
- return nv50_push_elements_u08(nv50, map, count);
+static void
+inline_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint8_t *map = (uint8_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
map++;
- count--;
+ count &= ~1;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt16(void *priv, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
-
- if (nv50->vbo_fifo)
- return nv50_push_elements_u16(nv50, map, count);
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint16_t *map = (uint16_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
+ count &= ~1;
map++;
- count--;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count);
+ OUT_RINGp (chan, (uint32_t *)ctx->map + start, count);
+}
+
+static void
+inline_edgeflag(void *priv, boolean enabled)
{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+nv50_draw_elements_inline(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer, unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned startInstance, unsigned instanceCount)
+{
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct instance a[16];
+ struct inline_ctx ctx;
+ struct u_split_prim s;
+ boolean nzi = FALSE;
+ unsigned overhead;
+
+ overhead = 16*3; /* potential instance adjustments */
+ overhead += 4; /* Begin()/End() */
+ overhead += 4; /* potential edgeflag disable/reenable */
+ overhead += 3; /* potentially 3 VTX_ELT_U16/U32 packet headers */
+
+ s.priv = &ctx;
+ if (indexSize == 1)
+ s.emit = inline_elt08;
+ else
+ if (indexSize == 2)
+ s.emit = inline_elt16;
+ else
+ s.emit = inline_elt32;
+ s.edge = inline_edgeflag;
+
+ ctx.nv50 = nv50;
+ ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(ctx.map);
+ if (!ctx.map)
+ return;
- map += start;
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, overhead + 6 + 3))
+ return;
- if (nv50->vbo_fifo)
- return nv50_push_elements_u32(nv50, map, count);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ unsigned max_verts;
+ boolean done;
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < (overhead + 6)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, (overhead + 6))) {
+ assert(0);
+ return;
+ }
+ }
- while (count) {
- unsigned nr = count > 2047 ? 2047 : count;
+ max_verts = AVAIL_RING(chan) - overhead;
+ if (max_verts > 2047)
+ max_verts = 2047;
+ if (indexSize != 4)
+ max_verts <<= 1;
+ instance_step(nv50, a);
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr);
- OUT_RINGp (chan, map, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
- count -= nr;
- map += nr;
+ nzi = TRUE;
}
- return TRUE;
-}
-static INLINE void
-nv50_draw_elements_inline(struct nv50_context *nv50,
- void *map, unsigned indexSize,
- unsigned start, unsigned count)
-{
- switch (indexSize) {
- case 1:
- nv50_draw_elements_inline_u08(nv50, map, start, count);
- break;
- case 2:
- nv50_draw_elements_inline_u16(nv50, map, start, count);
- break;
- case 4:
- nv50_draw_elements_inline_u32(nv50, map, start, count);
- break;
- }
+ pipe_buffer_unmap(pscreen, indexBuffer);
}
void
@@ -617,49 +391,68 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned startInstance, unsigned instanceCount)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
-
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 13 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ } else
+ if (!(indexBuffer->usage & PIPE_BUFFER_USAGE_INDEX) || indexSize == 1) {
+ nv50_draw_elements_inline(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; ++i) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 10 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
+ OUT_RING (chan, prim);
+ if (indexSize == 4) {
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
+ OUT_RING (chan, count);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ start << 2, count << 2);
+ } else
+ if (indexSize == 2) {
+ unsigned vb_start = (start & ~1);
+ unsigned vb_end = (start + count + 1) & ~1;
+ unsigned dwords = (vb_end - vb_start) >> 1;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, ((start & 1) << 31) | count);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
+ OUT_RING (chan, dwords);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ vb_start << 1, dwords << 2);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, 0);
+ }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
@@ -667,51 +460,8 @@ nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (!nv50->vbo_fifo && indexSize == 4) {
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
- OUT_RING (chan, count);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- start << 2, count << 2);
- } else
- if (!nv50->vbo_fifo && indexSize == 2) {
- unsigned vb_start = (start & ~1);
- unsigned vb_end = (start + count + 1) & ~1;
- unsigned dwords = (vb_end - vb_start) >> 1;
-
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, ((start & 1) << 31) | count);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
- OUT_RING (chan, dwords);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- vb_start << 1, dwords << 2);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, 0);
- } else {
- map = pipe_buffer_map(pscreen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
- nv50_unmap_vbufs(nv50);
- pipe_buffer_unmap(pscreen, indexBuffer);
- }
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
+ nv50_draw_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, 0, 1);
}
static INLINE boolean
@@ -726,6 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
float v[4];
int ret;
+ unsigned nr_components = util_format_get_nr_components(ve->src_format);
ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
if (ret)
@@ -736,9 +487,10 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
0, 0, 1, 1);
so = *pso;
if (!so)
- *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
+ *pso = so = so_new(nv50->vtxelt->num_elements,
+ nv50->vtxelt->num_elements * 4, 0);
- switch (ve->nr_components) {
+ switch (nr_components) {
case 4:
so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
so_data (so, fui(v[0]));
@@ -775,6 +527,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
}
void
+nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso)
+{
+ unsigned i;
+
+ for (i = 0; i < cso->num_elements; ++i) {
+ struct pipe_vertex_element *ve = &cso->pipe[i];
+
+ cso->hw[i] = nv50_vbo_vtxelt_to_hw(ve);
+ }
+}
+
+struct nouveau_stateobj *
nv50_vbo_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -783,30 +547,31 @@ nv50_vbo_validate(struct nv50_context *nv50)
/* don't validate if Gallium took away our buffers */
if (nv50->vtxbuf_nr == 0)
- return;
- nv50->vbo_fifo = 0;
+ return NULL;
+
+ if (nv50->screen->force_push ||
+ nv50->vertprog->cfg.edgeflag_in < 16)
+ nv50->vbo_fifo = 0xffff;
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
+ for (i = 0; i < nv50->vtxbuf_nr; i++) {
if (nv50->vtxbuf[i].stride &&
!(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))
nv50->vbo_fifo = 0xffff;
+ }
- if (NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */
-
- n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);
+ n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr);
vtxattr = NULL;
- vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4);
+ vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4);
vtxfmt = so_new(1, n_ve, 0);
so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
- for (i = 0; i < nv50->vtxelt_nr; i++) {
- struct pipe_vertex_element *ve = &nv50->vtxelt[i];
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
- uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
+ uint32_t hw = nv50->vtxelt->hw[i];
if (!vb->stride &&
nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
@@ -821,13 +586,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
}
if (nv50->vbo_fifo) {
- so_data (vtxfmt, hw |
- (ve->instance_divisor ? (1 << 4) : i));
+ so_data (vtxfmt, hw | (ve->instance_divisor ? (1 << 4) : i));
so_method(vtxbuf, tesla,
NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
continue;
}
+
so_data(vtxfmt, hw | i);
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
@@ -855,355 +620,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
}
- nv50->state.vtxelt_nr = nv50->vtxelt_nr;
+ nv50->state.vtxelt_nr = nv50->vtxelt->num_elements;
- so_ref (vtxfmt, &nv50->state.vtxfmt);
so_ref (vtxbuf, &nv50->state.vtxbuf);
so_ref (vtxattr, &nv50->state.vtxattr);
so_ref (NULL, &vtxbuf);
- so_ref (NULL, &vtxfmt);
so_ref (NULL, &vtxattr);
+ return vtxfmt;
}
-typedef void (*pfn_push)(struct nouveau_channel *, void *);
-
-struct nv50_vbo_emitctx
-{
- pfn_push push[16];
- uint8_t *map[16];
- unsigned stride[16];
- unsigned nr_ve;
- unsigned vtx_dwords;
- unsigned vtx_max;
-
- float edgeflag;
- unsigned ve_edgeflag;
-};
-
-static INLINE void
-emit_vtx_next(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i) {
- emit->push[i](chan, emit->map[i]);
- emit->map[i] += emit->stride[i];
- }
-}
-
-static INLINE void
-emit_vtx(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit,
- uint32_t vi)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i)
- emit->push[i](chan, emit->map[i] + emit->stride[i] * vi);
-}
-
-static INLINE boolean
-nv50_map_vbufs(struct nv50_context *nv50)
-{
- int i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- unsigned size = vb->stride * (vb->max_index + 1) + 16;
-
- if (nouveau_bo(vb->buffer)->map)
- continue;
-
- size = vb->stride * (vb->max_index + 1) + 16;
- size = MIN2(size, vb->buffer->size);
- if (!size)
- size = vb->buffer->size;
-
- if (nouveau_bo_map_range(nouveau_bo(vb->buffer),
- 0, size, NOUVEAU_BO_RD))
- break;
- }
-
- if (i == nv50->vtxbuf_nr)
- return TRUE;
- for (; i >= 0; --i)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
- return FALSE;
-}
-
-static void
-emit_b32_1(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b32_2(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
-}
-
-static void
-emit_b32_3(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b32_4(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
- OUT_RING(chan, v[3]);
-}
-
-static void
-emit_b16_1(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b16_3(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, (v[1] << 16) | v[0]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b08_1(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b08_3(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
-}
-
-static boolean
-emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,
- unsigned start)
-{
- unsigned i;
-
- if (nv50_map_vbufs(nv50) == FALSE)
- return FALSE;
-
- emit->ve_edgeflag = nv50->vertprog->cfg.edgeflag_in;
-
- emit->edgeflag = 0.5f;
- emit->nr_ve = 0;
- emit->vtx_dwords = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
- unsigned n, size;
- const struct util_format_description *desc;
-
- ve = &nv50->vtxelt[i];
- vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor)
- continue;
- n = emit->nr_ve++;
-
- emit->stride[n] = vb->stride;
- emit->map[n] = (uint8_t *)nouveau_bo(vb->buffer)->map +
- vb->buffer_offset +
- (start * vb->stride + ve->src_offset);
-
- desc = util_format_description(ve->src_format);
- assert(desc);
-
- size = util_format_get_component_bits(
- ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
-
- assert(ve->nr_components > 0 && ve->nr_components <= 4);
-
- /* It shouldn't be necessary to push the implicit 1s
- * for case 3 and size 8 cases 1, 2, 3.
- */
- switch (size) {
- default:
- NOUVEAU_ERR("unsupported vtxelt size: %u\n", size);
- return FALSE;
- case 32:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b32_1; break;
- case 2: emit->push[n] = emit_b32_2; break;
- case 3: emit->push[n] = emit_b32_3; break;
- case 4: emit->push[n] = emit_b32_4; break;
- }
- emit->vtx_dwords += ve->nr_components;
- break;
- case 16:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b16_1; break;
- case 2: emit->push[n] = emit_b32_1; break;
- case 3: emit->push[n] = emit_b16_3; break;
- case 4: emit->push[n] = emit_b32_2; break;
- }
- emit->vtx_dwords += (ve->nr_components + 1) >> 1;
- break;
- case 8:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b08_1; break;
- case 2: emit->push[n] = emit_b16_1; break;
- case 3: emit->push[n] = emit_b08_3; break;
- case 4: emit->push[n] = emit_b32_1; break;
- }
- emit->vtx_dwords += 1;
- break;
- }
- }
-
- emit->vtx_max = 512 / emit->vtx_dwords;
- if (emit->ve_edgeflag < 16)
- emit->vtx_max = 1;
-
- return TRUE;
-}
-
-static INLINE void
-set_edgeflag(struct nouveau_channel *chan,
- struct nouveau_grobj *tesla,
- struct nv50_vbo_emitctx *emit, uint32_t index)
-{
- unsigned i = emit->ve_edgeflag;
-
- if (i < 16) {
- float f = *((float *)(emit->map[i] + index * emit->stride[i]));
-
- if (emit->edgeflag != f) {
- emit->edgeflag = f;
-
- BEGIN_RING(chan, tesla, 0x15e4, 1);
- OUT_RING (chan, f ? 1 : 0);
- }
- }
-}
-
-static boolean
-nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
- if (emit_prepare(nv50, &emit, start) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx_next(chan, &emit);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index 1f69daec81..61b54af4dd 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -19,7 +19,8 @@ C_SOURCES = \
r300_state_invariant.c \
r300_vs.c \
r300_texture.c \
- r300_tgsi_to_rc.c
+ r300_tgsi_to_rc.c \
+ r300_transfer.c
LIBRARY_INCLUDES = \
-I$(TOP)/src/mesa/drivers/dri/r300/compiler \
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 183aa17f9b..27b2e30993 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -30,6 +30,7 @@ r300 = env.ConvenienceLibrary(
'r300_vs.c',
'r300_texture.c',
'r300_tgsi_to_rc.c',
+ 'r300_transfer.c',
] + r300compiler) + r300compiler
Export('r300')
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 513cc0f5d4..b7ad6b2020 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -36,6 +36,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_clip(r300->blitter, &r300->clip);
+ util_blitter_save_vertex_elements(r300->blitter, r300->velems);
}
/* Clear currently bound buffers. */
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 86b98a4ba5..923e1e541f 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -60,7 +60,6 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
FREE(r300->textures_state.state);
- FREE(r300->vertex_stream_state.state);
FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
@@ -72,11 +71,8 @@ r300_is_texture_referenced(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level)
{
- struct pipe_buffer* buf = 0;
-
- r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
-
- return pipe->is_buffer_referenced(pipe, buf);
+ return pipe->is_buffer_referenced(pipe,
+ ((struct r300_texture *)texture)->buffer);
}
static unsigned int
@@ -86,7 +82,14 @@ r300_is_buffer_referenced(struct pipe_context *pipe,
/* 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. */
+ * 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;
}
@@ -143,7 +146,6 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
- r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
@@ -159,6 +161,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300)
return NULL;
+ r300screen->ctx = (struct pipe_context*)r300;
+
r300->winsys = radeon_winsys;
r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
@@ -212,7 +216,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->invariant_state.dirty = TRUE;
r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
- r300->dirty_state = R300_NEW_KITCHEN_SINK;
r300->dirty_hw++;
r300->blitter = util_blitter_create(&r300->context);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 0d1518a05b..985e339112 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -124,13 +124,15 @@ 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[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
+ uint32_t colorpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
uint32_t us_out_fmt; /* R300_US_OUT_FMT[0-3] */
/* Zbuffer. */
- uint32_t depthpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
+ uint32_t depthpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
uint32_t zb_format; /* R300_ZB_FORMAT */
};
@@ -236,16 +238,16 @@ struct r300_texture {
struct pipe_texture tex;
/* Offsets into the buffer. */
- unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned offset[R300_MAX_TEXTURE_LEVELS];
/* A pitch for each mip-level */
- unsigned pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned pitch[R300_MAX_TEXTURE_LEVELS];
/* Size of one zslice or face based on the texture target */
- unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned layer_size[R300_MAX_TEXTURE_LEVELS];
/* Whether the mipmap level is macrotiled. */
- enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS];
+ enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS];
/**
* If non-zero, override the natural texture layout with
@@ -276,6 +278,23 @@ struct r300_texture {
enum r300_buffer_tiling microtile, macrotile;
};
+struct r300_vertex_info {
+ /* Parent class */
+ struct vertex_info vinfo;
+
+ /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+ uint32_t vap_prog_stream_cntl[8];
+ /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+ uint32_t vap_prog_stream_cntl_ext[8];
+};
+
+struct r300_vertex_element_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+
+ struct r300_vertex_stream_state vertex_stream;
+};
+
extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
@@ -348,8 +367,7 @@ struct r300_context {
int vertex_buffer_count;
int vertex_buffer_max_index;
/* Vertex elements for Gallium. */
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- int vertex_element_count;
+ struct r300_vertex_element_state *velems;
/* Vertex info for Draw. */
struct vertex_info vertex_info;
@@ -368,6 +386,8 @@ struct r300_context {
boolean polygon_offset_enabled;
/* Z buffer bit depth. */
uint32_t zbuffer_bpp;
+ /* Whether scissor is enabled. */
+ boolean scissor_enabled;
};
/* Convenience cast wrapper. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index addb28bded..55e9217fd3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -675,7 +675,7 @@ void r300_emit_scissor_state(struct r300_context* r300,
maxx = fb->width;
maxy = fb->height;
- if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
+ if (r300->scissor_enabled) {
minx = MAX2(minx, scissor->minx);
miny = MAX2(miny, scissor->miny);
maxx = MIN2(maxx, scissor->maxx);
@@ -757,9 +757,9 @@ void r300_emit_textures_state(struct r300_context *r300,
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
- unsigned size1, size2, aos_count = r300->vertex_element_count;
+ unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
@@ -794,6 +794,30 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.size);
+ /* Set the pointer to our vertex buffer. The emitted values are this:
+ * PACKET3 [3D_LOAD_VBPNTR]
+ * COUNT [1]
+ * FORMAT [size | stride << 8]
+ * OFFSET [offset into BO]
+ * VBPNTR [relocated BO]
+ */
+ BEGIN_CS(7);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
+ OUT_CS(1);
+ OUT_CS(r300->vertex_info.size |
+ (r300->vertex_info.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state)
{
@@ -868,7 +892,7 @@ 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_vertex_shader called,"
+ debug_printf("r300: Implementation error: emit_vs_state called,"
" but has_tcl is FALSE!\n");
return;
}
@@ -907,7 +931,7 @@ void r300_emit_vs_constant_buffer(struct r300_context* r300,
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vertex_shader called,"
+ debug_printf("r300: Implementation error: emit_vs_constant_buffer called,"
" but has_tcl is FALSE!\n");
return;
}
@@ -980,7 +1004,7 @@ void r300_emit_buffer_validate(struct r300_context *r300,
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture* tex;
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
struct pipe_buffer *pbuf;
unsigned i;
boolean invalid = FALSE;
@@ -1038,7 +1062,7 @@ validate:
}
/* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers) {
- for (i = 0; i < r300->vertex_element_count; i++) {
+ for (i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
if (!r300->winsys->add_buffer(r300->winsys, pbuf,
@@ -1135,8 +1159,10 @@ void r300_emit_dirty_state(struct r300_context* r300)
assert(r300->dirty_state == 0);
*/
- /* Finally, emit the VBO. */
- /* r300_emit_vertex_buffer(r300); */
+ /* Emit the VBO for SWTCL. */
+ if (!r300screen->caps->has_tcl) {
+ r300_emit_vertex_buffer(r300);
+ }
r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index e37d309270..70de152713 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -61,6 +61,12 @@ static void r300_flush(struct pipe_context* pipe,
atom->dirty = TRUE;
}
}
+
+ /* Unmark HWTCL state for SWTCL. */
+ if (!r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = FALSE;
+ r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
+ }
}
/* reset flushed query */
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 3c2625269b..9e71e61c30 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -207,6 +207,7 @@ static void r300_translate_fragment_shader(
DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
compiler.Base.ErrorMsg);
assert(0);
+ abort();
}
/* And, finally... */
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 6c891029a5..9c001ae186 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -143,7 +143,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
- unsigned vertex_element_count = r300->vertex_element_count;
+ unsigned vertex_element_count = r300->velems->count;
unsigned i, v, vbi, dw, elem_offset, dwords;
/* Size of the vertex, in dwords. */
@@ -166,7 +166,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
offset[i] = velem->src_offset / 4;
size[i] = util_format_get_blocksize(velem->src_format) / 4;
vertex_size += size[i];
@@ -183,18 +183,19 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
}
}
- dwords = 10 + count * vertex_size;
+ dwords = 9 + count * vertex_size;
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
- r300_emit_buffer_validate(r300, FALSE, 0);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode));
@@ -202,7 +203,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Emit vertices. */
for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
vbi = velem->vertex_buffer_index;
elem_offset = offset[i] + stride[vbi] * (v + start);
@@ -215,7 +216,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) {
- vbi = r300->vertex_element[i].vertex_buffer_index;
+ vbi = r300->velems->velem[i].vertex_buffer_index;
if (map[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
@@ -238,15 +239,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
if (alt_num_verts) {
assert(count < (1 << 24));
- BEGIN_CS(10);
+ BEGIN_CS(9);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(8);
+ BEGIN_CS(7);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode) |
@@ -278,18 +280,19 @@ static void r300_emit_draw_elements(struct r300_context *r300,
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
count, minIndex, maxIndex);
- maxIndex = MIN2(maxIndex, ((1 << 24) - 1));
+ maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
if (alt_num_verts) {
- BEGIN_CS(16);
+ BEGIN_CS(15);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(14);
+ BEGIN_CS(13);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(maxIndex);
+ OUT_CS(minIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
count_dwords = count;
@@ -450,7 +453,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Make sure there are at least 128 spare dwords in the command buffer.
* (most of it being consumed by emit_aos) */
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
if (alt_num_verts || count <= 65535) {
@@ -468,7 +471,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Again, we emit both AOS and draw_arrays so there should be
* at least 128 spare dwords. */
if (count && r300_reserve_cs_space(r300, 128)) {
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
}
} while (count);
@@ -688,6 +691,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -711,6 +715,7 @@ static void r300_render_draw(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index d397a8eb2b..5880eecd5f 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,14 +21,13 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
#include "r300_context.h"
-#include "r300_screen.h"
#include "r300_texture.h"
+#include "r300_transfer.h"
#include "radeon_winsys.h"
#include "r300_winsys.h"
@@ -231,14 +231,16 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
/* Check colorbuffer format support. */
if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) &&
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) &&
/* 2101010 cannot be rendered to on non-r5xx. */
(is_r500 || !is_color2101010) &&
r300_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED);
}
/* Check depth-stencil format support. */
@@ -250,70 +252,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
return retval == usage;
}
-static struct pipe_transfer*
-r300_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
-{
- struct r300_texture *tex = (struct r300_texture *)texture;
- struct r300_transfer *trans;
- struct r300_screen *rscreen = r300_screen(screen);
- unsigned offset;
-
- offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */
-
- trans = CALLOC_STRUCT(r300_transfer);
- if (trans) {
- pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.x = x;
- trans->transfer.y = y;
- trans->transfer.width = w;
- trans->transfer.height = h;
- trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level);
- trans->transfer.usage = usage;
- trans->transfer.zslice = zslice;
- trans->transfer.face = face;
-
- trans->offset = offset;
- }
- return &trans->transfer;
-}
-
-static void
-r300_tex_transfer_destroy(struct pipe_transfer *trans)
-{
- pipe_texture_reference(&trans->texture, NULL);
- FREE(trans);
-}
-
-static void* r300_transfer_map(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- char* map;
- enum pipe_format format = tex->tex.format;
-
- map = pipe_buffer_map(screen, tex->buffer,
- pipe_transfer_buffer_flags(transfer));
-
- if (!map) {
- return NULL;
- }
-
- return map + r300_transfer(transfer)->offset +
- transfer->y / util_format_get_blockheight(format) * transfer->stride +
- transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
-}
-
-static void r300_transfer_unmap(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- pipe_buffer_unmap(screen, tex->buffer);
-}
-
static void r300_destroy_screen(struct pipe_screen* pscreen)
{
struct r300_screen* r300screen = r300_screen(pscreen);
@@ -350,13 +288,11 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
r300screen->screen.get_paramf = r300_get_paramf;
r300screen->screen.is_format_supported = r300_is_format_supported;
r300screen->screen.context_create = r300_create_context;
- r300screen->screen.get_tex_transfer = r300_get_tex_transfer;
- r300screen->screen.tex_transfer_destroy = r300_tex_transfer_destroy;
- r300screen->screen.transfer_map = r300_transfer_map;
- r300screen->screen.transfer_unmap = r300_transfer_unmap;
r300_init_screen_texture_functions(&r300screen->screen);
+ r300_init_screen_transfer_functions(&r300screen->screen);
u_simple_screen_init(&r300screen->screen);
return &r300screen->screen;
}
+
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 502fbfa5a2..484bde6a6b 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -27,6 +28,8 @@
#include "r300_chipset.h"
+#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM
+
struct radeon_winsys;
struct r300_screen {
@@ -35,6 +38,10 @@ struct r300_screen {
struct radeon_winsys* radeon_winsys;
+ /* XXX This hack will be removed once texture transfers become part of
+ * pipe_context. */
+ struct pipe_context* ctx;
+
/* Chipset capabilities */
struct r300_capabilities* caps;
@@ -42,25 +49,14 @@ struct r300_screen {
unsigned debug;
};
-struct r300_transfer {
- /* Parent class */
- struct pipe_transfer transfer;
-
- /* Offset from start of buffer. */
- unsigned offset;
-};
/* Convenience cast wrapper. */
static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
return (struct r300_screen*)screen;
}
-/* Convenience cast wrapper. */
-static INLINE struct r300_transfer*
-r300_transfer(struct pipe_transfer* transfer)
-{
- return (struct r300_transfer*)transfer;
-}
+/* Creates a new r300 screen. */
+struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
/* Debug functionality. */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 1f6f99d3e5..bd4c2766cb 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -571,6 +571,7 @@ static void
{
struct r300_context* r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
+ struct pipe_framebuffer_state *old_state = r300->fb_state.state;
unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
@@ -595,23 +596,30 @@ static void
return;
}
-
if (r300->draw) {
draw_flush(r300->draw);
}
- memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+ r300->fb_state.dirty = TRUE;
- r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
- (state->zsbuf ? 10 : 0) + 8;
+ /* If nr_cbufs is changed from zero to non-zero or vice versa... */
+ if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
+ r300->blend_state.dirty = TRUE;
+ }
+ /* If zsbuf is set from NULL to non-NULL or vice versa.. */
+ if (!!old_state->zsbuf != !!state->zsbuf) {
+ r300->dsa_state.dirty = TRUE;
+ }
+ if (!r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
- /* XXX wait what */
- r300->blend_state.dirty = TRUE;
- r300->dsa_state.dirty = TRUE;
- r300->fb_state.dirty = TRUE;
- r300->scissor_state.dirty = TRUE;
+ memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+
+ r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
+ (state->zsbuf ? 10 : 0) + 8;
/* Polygon offset depends on the zbuffer bit depth. */
if (state->zsbuf && r300->polygon_offset_enabled) {
@@ -716,8 +724,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->vap_control_status = R300_VC_32BIT_SWAP;
#endif
- /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
- * Else, enable HW TCL and force Draw's TCL off. */
+ /* If no TCL engine is present, turn off the HW TCL. */
if (!r300screen->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
@@ -807,6 +814,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ boolean scissor_was_enabled = r300->scissor_enabled;
if (r300->draw) {
draw_flush(r300->draw);
@@ -815,20 +823,17 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
+ r300->scissor_enabled = rs->rs.scissor;
} else {
r300->polygon_offset_enabled = FALSE;
+ r300->scissor_enabled = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
- /* XXX Why is this still needed, dammit!? */
- r300->scissor_state.dirty = TRUE;
- r300->viewport_state.dirty = TRUE;
-
- /* XXX Clean these up when we move to atom emits */
- if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ if (scissor_was_enabled != r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
}
}
@@ -973,7 +978,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
memcpy(r300->scissor_state.state, state,
sizeof(struct pipe_scissor_state));
- r300->scissor_state.dirty = TRUE;
+ if (r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -1039,19 +1046,17 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers);
- } else {
- r300->vertex_stream_state.dirty = TRUE;
}
}
static boolean r300_validate_aos(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ 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->vertex_element_count; i++) {
+ 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;
@@ -1060,20 +1065,209 @@ static boolean r300_validate_aos(struct r300_context *r300)
return TRUE;
}
-static void r300_set_vertex_elements(struct pipe_context* pipe,
- unsigned count,
- const struct pipe_vertex_element* elements)
+static void r300_draw_emit_attrib(struct r300_context* r300,
+ enum attrib_emit emit,
+ enum interp_mode interp,
+ int index)
{
- struct r300_context* r300 = r300_context(pipe);
+ 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. */
- memcpy(r300->vertex_element,
- elements,
- sizeof(struct pipe_vertex_element) * count);
- r300->vertex_element_count = 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++;
+ }
+ }
+
+ /* 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. */
+static void r300_vertex_psc(struct r300_vertex_element_state *velems)
+{
+ struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
+ uint16_t type, swizzle;
+ enum pipe_format format;
+ unsigned i;
+
+ assert(velems->count <= 16);
+
+ /* Vertex shaders have no semantics on their inputs,
+ * so PSC should just route stuff based on the vertex elements,
+ * and not on attrib information. */
+ for (i = 0; i < velems->count; i++) {
+ format = velems->velem[i].src_format;
+
+ type = r300_translate_vertex_data_type(format) |
+ (i << R300_DST_VEC_LOC_SHIFT);
+ swizzle = r300_translate_vertex_data_swizzle(format);
+
+ 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;
+}
+
+/* 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;
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = CALLOC_STRUCT(r300_vertex_element_state);
+ if (velems != NULL) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
+
+ if (r300screen->caps->has_tcl) {
+ 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;
+}
+
+static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *state)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_vertex_element_state *velems = state;
+
+ if (velems == NULL) {
+ return;
+ }
+
+ r300->velems = velems;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_vertex_elements(r300->draw, count, elements);
+ draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
}
if (!r300_validate_aos(r300)) {
@@ -1081,6 +1275,14 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
assert(0);
abort();
}
+
+ UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
+ r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
+}
+
+static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1088,68 +1290,71 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
- /* Copy state directly into shader. */
- vs->state = *shader;
- vs->state.tokens = tgsi_dup_tokens(shader->tokens);
-
- tgsi_scan_shader(shader->tokens, &vs->info);
+ struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
+ r300_vertex_shader_common_init(vs, shader);
- return (void*)vs;
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300_translate_vertex_shader(r300, vs);
} else {
- return draw_create_vertex_shader(r300->draw, shader);
+ vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
+
+ return vs;
}
static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
+ if (vs == NULL) {
+ r300->vs_state.state = NULL;
+ return;
+ }
+ if (vs == r300->vs_state.state) {
+ return;
+ }
+ r300->vs_state.state = vs;
- if (vs == NULL) {
- r300->vs_state.state = NULL;
- return;
- } else if (!vs->translated) {
- r300_translate_vertex_shader(r300, vs);
- }
+ // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
+ if (r300->fs) {
+ r300_vertex_shader_setup_wpos(r300);
+ }
+ memcpy(r300->vap_output_state.state, &vs->vap_out,
+ sizeof(struct r300_vap_output_state));
+ r300->vap_output_state.dirty = TRUE;
- UPDATE_STATE(shader, r300->vs_state);
+ /* The majority of the RS block bits is dependent on the vertex shader. */
+ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
+
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = TRUE;
r300->vs_state.size = vs->code.length + 9;
- r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
- r300->vap_output_state.dirty = TRUE;
- r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */
r300->pvs_flush.dirty = TRUE;
- if (r300->fs) {
- r300_vertex_shader_setup_wpos(r300);
- }
-
r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
}
static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
-
rc_constants_destroy(&vs->code.constants);
- FREE((void*)vs->state.tokens);
- FREE(shader);
} else {
draw_delete_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
+
+ FREE((void*)vs->state.tokens);
+ FREE(shader);
}
static void r300_set_constant_buffer(struct pipe_context *pipe,
@@ -1201,8 +1406,10 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
pipe_buffer_unmap(pipe->screen, buf);
if (shader == PIPE_SHADER_VERTEX) {
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
- r300->pvs_flush.dirty = TRUE;
+ if (r300screen->caps->has_tcl) {
+ r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ r300->pvs_flush.dirty = TRUE;
+ }
}
else if (shader == PIPE_SHADER_FRAGMENT)
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
@@ -1250,7 +1457,10 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
- r300->context.set_vertex_elements = r300_set_vertex_elements;
+
+ r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
+ r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
+ r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;
r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 9c8e907fdf..6b9f61acd7 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -37,187 +37,6 @@
/* 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. */
-/* XXX move this function into r300_state.c after TCL-bypass gets removed
- * XXX because this one is dependent only on vertex elements. */
-static void r300_vertex_psc(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
- uint16_t type, swizzle;
- enum pipe_format format;
- unsigned i;
- int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- int* stream_tab;
-
- memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
-
- stream_tab = identity;
-
- /* Vertex shaders have no semantics on their inputs,
- * so PSC should just route stuff based on the vertex elements,
- * and not on attrib information. */
- DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
- " in psc\n",
- vs->info.num_inputs,
- r300->vertex_element_count);
-
- for (i = 0; i < r300->vertex_element_count; i++) {
- format = r300->vertex_element[i].src_format;
-
- type = r300_translate_vertex_data_type(format) |
- (stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
- swizzle = r300_translate_vertex_data_swizzle(format);
-
- if (i & 1) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- assert(i <= 15);
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vformat->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
-}
-
-/* Update the PSC tables for SW TCL, using Draw. */
-static void r300_swtcl_vertex_psc(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_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;
-
- memset(vformat, 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]);
- }
-
- 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) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vformat->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
-}
-
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001)
{
@@ -432,23 +251,8 @@ static void r300_update_rs_block(struct r300_context* r300,
static void r300_update_derived_shader_state(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vap_output_state *vap_out =
- (struct r300_vap_output_state*)r300->vap_output_state.state;
-
- /* XXX Mmm, delicious hax */
- memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
- memcpy(vap_out, vs->hwfmt, sizeof(uint)*4);
r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
-
- if (r300screen->caps->has_tcl) {
- r300_vertex_psc(r300);
- } else {
- r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info);
- r300_swtcl_vertex_psc(r300);
- }
}
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@@ -581,9 +385,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
void r300_update_derived_state(struct r300_context* r300)
{
- if (r300->rs_block_state.dirty ||
- r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */
- r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */
+ if (r300->rs_block_state.dirty) {
r300_update_derived_shader_state(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 2f3a56e1fb..a32924ed0a 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -348,39 +348,12 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
return 0;
}
-/* Utility function to count the number of components in RGBAZS formats.
- * XXX should go to util or p_format.h */
-static INLINE unsigned pf_component_count(enum pipe_format format) {
- unsigned count = 0;
-
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
- count++;
- }
-
- return count;
-}
-
/* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
uint32_t result = 0;
const struct util_format_description *desc;
- unsigned components = pf_component_count(format);
+ unsigned components = util_format_get_nr_components(format);
desc = util_format_description(format);
@@ -453,7 +426,6 @@ r300_translate_vertex_data_type(enum pipe_format format) {
static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
const struct util_format_description *desc = util_format_description(format);
- unsigned swizzle[4], i;
assert(format);
@@ -463,25 +435,10 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
return 0;
}
- /* Swizzles for 8bits formats are in the reversed order, not sure why. */
- if (desc->channel[0].size == 8) {
- for (i = 0; i < 4; i++) {
- if (desc->swizzle[i] <= 3) {
- swizzle[i] = 3 - desc->swizzle[i];
- } else {
- swizzle[i] = desc->swizzle[i];
- }
- }
- } else {
- for (i = 0; i < 4; i++) {
- swizzle[i] = desc->swizzle[i];
- }
- }
-
- return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
- (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
- (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
- (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
+ return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
+ (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
+ (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
+ (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
(0xf << R300_WRITE_ENA_SHIFT));
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index c0144f64b4..04124afd4d 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -617,18 +617,23 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture *tex,
unsigned level,
- boolean rv350_mode)
+ boolean rv350_mode,
+ int dim)
{
- unsigned tile_width, width;
+ unsigned tile, texdim;
- tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
- width = u_minify(tex->tex.width0, level);
+ tile = r300_texture_get_tile_size(tex, dim, TRUE);
+ if (dim == TILE_WIDTH) {
+ texdim = u_minify(tex->tex.width0, level);
+ } else {
+ texdim = u_minify(tex->tex.height0, level);
+ }
/* See TX_FILTER1_n.MACRO_SWITCH. */
if (rv350_mode) {
- return width >= tile_width;
+ return texdim >= tile;
} else {
- return width > tile_width;
+ return texdim > tile;
}
}
@@ -692,9 +697,10 @@ static void r300_setup_miptree(struct r300_screen* screen,
for (i = 0; i <= base->last_level; i++) {
/* 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)) ?
- R300_BUFFER_TILED : R300_BUFFER_LINEAR;
+ tex->mip_macrotile[i] =
+ (tex->macrotile == R300_BUFFER_TILED &&
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH)) ?
+ R300_BUFFER_TILED : R300_BUFFER_LINEAR;
stride = r300_texture_get_stride(screen, tex, i);
nblocksy = r300_texture_get_nblocksy(tex, i);
@@ -724,10 +730,46 @@ static void r300_setup_flags(struct r300_texture* tex)
!util_is_power_of_two(tex->tex.height0);
}
+static void r300_setup_tiling(struct pipe_screen *screen,
+ struct r300_texture *tex)
+{
+ enum pipe_format format = tex->tex.format;
+ boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350;
+
+ if (util_format_is_compressed(format)) {
+ return;
+ }
+
+ if (tex->tex.width0 == 1 ||
+ tex->tex.height0 == 1) {
+ return;
+ }
+
+ /* Set microtiling. */
+ switch (util_format_get_blocksize(format)) {
+ case 1:
+ case 4:
+ 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 8:
+ tex->microtile = R300_BUFFER_SQUARETILED;
+ break;*/
+ }
+
+ /* Set macrotiling. */
+ if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
+ r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
+ tex->macrotile = R300_BUFFER_TILED;
+ }
+}
+
/* Create a new texture. */
-static struct pipe_texture*
- r300_texture_create(struct pipe_screen* screen,
- const struct pipe_texture* template)
+static struct pipe_texture* r300_texture_create(struct pipe_screen* screen,
+ const struct pipe_texture* template)
{
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
struct r300_screen* rscreen = r300_screen(screen);
@@ -742,6 +784,9 @@ static struct pipe_texture*
tex->tex.screen = screen;
r300_setup_flags(tex);
+ if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) {
+ r300_setup_tiling(screen, tex);
+ }
r300_setup_miptree(rscreen, tex);
r300_setup_texture_state(rscreen, tex);
@@ -806,14 +851,17 @@ static void r300_tex_surface_destroy(struct pipe_surface* s)
FREE(s);
}
+
static struct pipe_texture*
- r300_texture_blanket(struct pipe_screen* screen,
- const struct pipe_texture* base,
- const unsigned* stride,
- struct pipe_buffer* buffer)
+ r300_texture_from_handle(struct pipe_screen* screen,
+ const struct pipe_texture* base,
+ struct winsys_handle *whandle)
{
- struct r300_texture* tex;
+ struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
struct r300_screen* rscreen = r300_screen(screen);
+ struct pipe_buffer *buffer;
+ struct r300_texture* tex;
+ unsigned stride;
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D ||
@@ -822,6 +870,11 @@ static struct pipe_texture*
return NULL;
}
+ buffer = winsys->buffer_from_handle(winsys, screen, whandle, &stride);
+ if (!buffer) {
+ return NULL;
+ }
+
tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
return NULL;
@@ -831,17 +884,38 @@ static struct pipe_texture*
pipe_reference_init(&tex->tex.reference, 1);
tex->tex.screen = screen;
- tex->stride_override = *stride;
- tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
+ tex->stride_override = stride;
+ tex->pitch[0] = stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
r300_setup_texture_state(rscreen, tex);
- pipe_buffer_reference(&tex->buffer, buffer);
+ /* one ref already taken */
+ tex->buffer = buffer;
return (struct pipe_texture*)tex;
}
+static boolean
+ r300_texture_get_handle(struct pipe_screen* screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
+ struct r300_texture* tex = (struct r300_texture*)texture;
+ unsigned stride;
+
+ if (!tex) {
+ return FALSE;
+ }
+
+ stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
+
+ winsys->buffer_get_handle(winsys, tex->buffer, stride, whandle);
+
+ return TRUE;
+}
+
static struct pipe_video_surface *
r300_video_surface_create(struct pipe_screen *screen,
enum pipe_video_chroma_format chroma_format,
@@ -893,30 +967,13 @@ static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
void r300_init_screen_texture_functions(struct pipe_screen* screen)
{
screen->texture_create = r300_texture_create;
+ screen->texture_from_handle = r300_texture_from_handle;
+ screen->texture_get_handle = r300_texture_get_handle;
screen->texture_destroy = r300_texture_destroy;
screen->get_tex_surface = r300_get_tex_surface;
screen->tex_surface_destroy = r300_tex_surface_destroy;
- screen->texture_blanket = r300_texture_blanket;
screen->video_surface_create = r300_video_surface_create;
screen->video_surface_destroy= r300_video_surface_destroy;
}
-boolean r300_get_texture_buffer(struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride)
-{
- struct r300_texture* tex = (struct r300_texture*)texture;
- if (!tex) {
- return FALSE;
- }
-
- pipe_buffer_reference(buffer, tex->buffer);
-
- if (stride) {
- *stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
- }
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 46a5fb6188..138b62784e 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -60,13 +60,11 @@ r300_video_surface(struct pipe_video_surface *pvs)
return (struct r300_video_surface *)pvs;
}
-#ifndef R300_WINSYS_H
-
+/* Used internally for texture_is_referenced()
+ */
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
-#endif /* R300_WINSYS_H */
-
#endif /* R300_TEXTURE_H */
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
new file mode 100644
index 0000000000..ec89681a3c
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "r300_context.h"
+#include "r300_transfer.h"
+#include "r300_texture.h"
+#include "r300_screen.h"
+
+#include "util/u_memory.h"
+#include "util/u_format.h"
+
+struct r300_transfer {
+ /* Parent class */
+ struct pipe_transfer transfer;
+
+ /* Pipe context. */
+ struct pipe_context *ctx;
+
+ /* Parameters of get_tex_transfer. */
+ unsigned x, y, level, zslice, face;
+
+ /* Offset from start of buffer. */
+ unsigned offset;
+
+ /* Detiled texture. */
+ struct r300_texture *detiled_texture;
+
+ /* Transfer and format flags. */
+ unsigned buffer_usage, render_target_usage;
+};
+
+/* Convenience cast wrapper. */
+static INLINE struct r300_transfer*
+r300_transfer(struct pipe_transfer* transfer)
+{
+ return (struct r300_transfer*)transfer;
+}
+
+/* Copy from a tiled texture to a detiled one. */
+static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL |
+ r300transfer->buffer_usage);
+
+ ctx->surface_copy(ctx, dst, 0, 0, src, r300transfer->x, r300transfer->y,
+ transfer->width, transfer->height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/* Copy a detiled texture to a tiled one. */
+static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ /* XXX this flush prevents the following DRM error from occuring:
+ * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation !
+ * Reproducible with perf/copytex. */
+ ctx->flush(ctx, 0, NULL);
+
+ ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0,
+ transfer->width, transfer->height);
+
+ /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */
+ ctx->flush(ctx, 0, NULL);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+static struct pipe_transfer*
+r300_get_tex_transfer(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
+{
+ struct r300_texture *tex = (struct r300_texture *)texture;
+ struct r300_transfer *trans;
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct pipe_texture template;
+
+ trans = CALLOC_STRUCT(r300_transfer);
+ if (trans) {
+ /* Initialize the transfer object. */
+ pipe_texture_reference(&trans->transfer.texture, texture);
+ trans->transfer.usage = usage;
+ trans->transfer.width = w;
+ trans->transfer.height = h;
+ trans->ctx = r300screen->ctx;
+ trans->x = x;
+ trans->y = y;
+ trans->level = level;
+ trans->zslice = zslice;
+ trans->face = face;
+
+ /* If the texture is tiled, we must create a temporary detiled texture
+ * for this transfer. */
+ if (tex->microtile || tex->macrotile) {
+ trans->buffer_usage = pipe_transfer_buffer_flags(&trans->transfer);
+ trans->render_target_usage =
+ util_format_is_depth_or_stencil(texture->format) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ template.target = PIPE_TEXTURE_2D;
+ template.format = texture->format;
+ template.width0 = w;
+ template.height0 = h;
+ template.depth0 = 0;
+ template.last_level = 0;
+ template.nr_samples = 0;
+ template.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
+ R300_TEXTURE_USAGE_TRANSFER;
+
+ /* For texture reading, the temporary (detiled) texture is used as
+ * a render target when blitting from a tiled texture. */
+ if (usage & PIPE_TRANSFER_READ) {
+ template.tex_usage |= trans->render_target_usage;
+ }
+ /* For texture writing, the temporary texture is used as a sampler
+ * when blitting into a tiled texture. */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER;
+ }
+
+ /* Create the temporary texture. */
+ trans->detiled_texture =
+ (struct r300_texture*)screen->texture_create(screen, &template);
+ assert(!trans->detiled_texture->microtile &&
+ !trans->detiled_texture->macrotile);
+
+ /* Set the stride.
+ * Parameters x, y, level, zslice, and face remain zero. */
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, trans->detiled_texture, 0);
+
+ if (usage & PIPE_TRANSFER_READ) {
+ /* We cannot map a tiled texture directly because the data is
+ * in a different order, therefore we do detiling using a blit. */
+ r300_copy_from_tiled_texture(r300screen->ctx, trans);
+ }
+ } else {
+ trans->transfer.x = x;
+ trans->transfer.y = y;
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, tex, level);
+ trans->transfer.level = level;
+ trans->transfer.zslice = zslice;
+ trans->transfer.face = face;
+ trans->offset = r300_texture_get_offset(tex, level, zslice, face);
+ }
+ }
+ return &trans->transfer;
+}
+
+static void r300_tex_transfer_destroy(struct pipe_transfer *trans)
+{
+ struct r300_transfer *r300transfer = r300_transfer(trans);
+
+ if (r300transfer->detiled_texture) {
+ if (trans->usage & PIPE_TRANSFER_WRITE) {
+ r300_copy_into_tiled_texture(r300transfer->ctx, r300transfer);
+ }
+
+ pipe_texture_reference(
+ (struct pipe_texture**)&r300transfer->detiled_texture, NULL);
+ }
+ pipe_texture_reference(&trans->texture, NULL);
+ FREE(trans);
+}
+
+static void* r300_transfer_map(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
+{
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+ char *map;
+ enum pipe_format format = tex->tex.format;
+
+ if (r300transfer->detiled_texture) {
+ /* The detiled texture is of the same size as the region being mapped
+ * (no offset needed). */
+ return pipe_buffer_map(screen,
+ r300transfer->detiled_texture->buffer,
+ pipe_transfer_buffer_flags(transfer));
+ } else {
+ /* Tiling is disabled. */
+ map = pipe_buffer_map(screen, tex->buffer,
+ pipe_transfer_buffer_flags(transfer));
+
+ if (!map) {
+ return NULL;
+ }
+
+ return map + r300_transfer(transfer)->offset +
+ transfer->y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ }
+}
+
+static void r300_transfer_unmap(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
+{
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+
+ if (r300transfer->detiled_texture) {
+ pipe_buffer_unmap(screen, r300transfer->detiled_texture->buffer);
+ } else {
+ pipe_buffer_unmap(screen, tex->buffer);
+ }
+}
+
+void r300_init_screen_transfer_functions(struct pipe_screen *screen)
+{
+ screen->get_tex_transfer = r300_get_tex_transfer;
+ screen->tex_transfer_destroy = r300_tex_transfer_destroy;
+ screen->transfer_map = r300_transfer_map;
+ screen->transfer_unmap = r300_transfer_unmap;
+}
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
new file mode 100644
index 0000000000..60d1d3dc85
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef R300_TRANSFER
+#define R300_TRANSFER
+
+#include "pipe/p_screen.h"
+
+void r300_init_screen_transfer_functions(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 60a04bbfed..379939ac75 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -89,95 +89,41 @@ static void r300_shader_read_vs_outputs(
assert(0);
}
}
+
+ /* WPOS is a straight copy of POSITION and it's always emitted. */
+ vs_outputs->wpos = i;
}
-static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
+/* This function sets up:
+ * - VAP mapping, which maps VS registers to output semantics and
+ * at the same time it indicates which attributes are enabled and should
+ * be rasterized.
+ * - Stream mapping to VS outputs if TCL is not present. */
+static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs)
{
struct r300_shader_semantics* vs_outputs = &vs->outputs;
- uint32_t* hwfmt = vs->hwfmt;
- int i, gen_count;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
+ int *stream_loc = vs->stream_loc_notcl;
+ int i, gen_count, tabi = 0;
boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
vs_outputs->bcolor[1] != ATTR_UNUSED;
- /* Do the actual vertex_info setup.
- *
- * vertex_info has four uints of hardware-specific data in it.
- * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
- * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
- * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
- * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
-
- hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+ vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */
/* Position. */
if (vs_outputs->pos != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_POS;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
+ stream_loc[tabi++] = 0;
} else {
assert(0);
}
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- }
-
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
- vs_outputs->color[1] != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
- }
- }
-
- /* Back-face colors. */
- if (any_bcolor_used) {
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
- }
- }
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
- }
-
- /* Fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
-
- /* XXX magic */
- assert(gen_count <= 8);
-
- /* WPOS. */
- vs->wpos_tex_output = gen_count;
-}
-
-/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
- * or isn't present. */
-static void r300_stream_locations_notcl(
- struct r300_shader_semantics* vs_outputs,
- int* stream_loc)
-{
- int i, tabi = 0, gen_count;
- boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
- vs_outputs->bcolor[1] != ATTR_UNUSED;
-
- /* Position. */
- stream_loc[tabi++] = 0;
-
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
stream_loc[tabi++] = 1;
}
@@ -185,6 +131,9 @@ static void r300_stream_locations_notcl(
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
vs_outputs->color[1] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+
stream_loc[tabi++] = 2 + i;
}
}
@@ -192,6 +141,9 @@ static void r300_stream_locations_notcl(
/* Back-face colors. */
if (any_bcolor_used) {
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+
stream_loc[tabi++] = 4 + i;
}
}
@@ -200,6 +152,9 @@ static void r300_stream_locations_notcl(
gen_count = 0;
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->generic[i] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
@@ -208,17 +163,22 @@ static void r300_stream_locations_notcl(
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
}
+ /* XXX magic */
+ assert(gen_count <= 8);
+
/* WPOS. */
- if (vs_outputs->wpos != ATTR_UNUSED) {
- assert(tabi < 16);
- stream_loc[tabi++] = 6 + gen_count;
- gen_count++;
- }
+ vs->wpos_tex_output = gen_count;
+
+ assert(tabi < 16);
+ stream_loc[tabi++] = 6 + gen_count;
for (; tabi < 16;) {
stream_loc[tabi++] = -1;
@@ -294,26 +254,16 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
}
}
-static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
- struct r300_shader_semantics* outputs)
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader)
{
- int i, lastOutput = 0;
-
- /* Find the max output index. */
- lastOutput = MAX2(lastOutput, outputs->psize);
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->color[i]);
- lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
- }
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->generic[i]);
- }
- lastOutput = MAX2(lastOutput, outputs->fog);
+ /* Copy state directly into shader. */
+ vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
+ tgsi_scan_shader(shader->tokens, &vs->info);
- /* Set WPOS after the last output. */
- lastOutput++;
- rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
- outputs->wpos = lastOutput;
+ r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+ r300_init_vs_output_mapping(vs);
}
void r300_translate_vertex_shader(struct r300_context* r300,
@@ -322,9 +272,6 @@ void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_program_compiler compiler;
struct tgsi_to_rc ttr;
- /* Initialize. */
- r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
-
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -348,10 +295,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
/* Insert the WPOS output. */
- r300_insert_wpos(&compiler, &vs->outputs);
-
- r300_shader_vap_output_fmt(vs);
- r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
+ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
/* Invoke the compiler */
r3xx_compile_vertex_program(&compiler);
@@ -363,30 +307,29 @@ void r300_translate_vertex_shader(struct r300_context* r300,
/* And, finally... */
rc_destroy(&compiler.Base);
- vs->translated = TRUE;
}
boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
int tex_output = vs->wpos_tex_output;
uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
- uint32_t* hwfmt = vs->hwfmt;
if (r300->fs->inputs.wpos != ATTR_UNUSED) {
/* Enable WPOS in VAP. */
- if (!(hwfmt[1] & tex_fmt)) {
- hwfmt[1] |= tex_fmt;
- hwfmt[3] |= (4 << (3 * tex_output));
+ if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) {
+ vap_out->vap_vsm_vtx_assm |= tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output));
assert(tex_output < 8);
return TRUE;
}
} else {
/* Disable WPOS in VAP. */
- if (hwfmt[1] & tex_fmt) {
- hwfmt[1] &= ~tex_fmt;
- hwfmt[3] &= ~(4 << (3 * tex_output));
+ if (vap_out->vap_vsm_vtx_assm & tex_fmt) {
+ vap_out->vap_vsm_vtx_assm &= ~tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output));
return TRUE;
}
}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 18cfeee3cd..f6f0b86b68 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -28,6 +28,7 @@
#include "tgsi/tgsi_scan.h"
#include "radeon_code.h"
+#include "r300_context.h"
#include "r300_shader_semantics.h"
struct r300_context;
@@ -38,7 +39,7 @@ struct r300_vertex_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics outputs;
- uint hwfmt[4];
+ struct r300_vap_output_state vap_out;
/* Stream locations for SWTCL or if TCL is bypassed. */
int stream_loc_notcl[16];
@@ -46,13 +47,17 @@ struct r300_vertex_shader {
/* Output stream location for WPOS. */
int wpos_tex_output;
- /* Has this shader been translated yet? */
- boolean translated;
-
+ /* HWTCL-specific. */
/* Machine code (if translated) */
struct r300_vertex_program_code code;
+
+ /* SWTCL-specific. */
+ void *draw_vs;
};
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader);
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 40fb8a95ca..ddf2b79003 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -40,11 +40,6 @@ struct radeon_winsys;
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
-boolean r300_get_texture_buffer(struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index e4ac49fa85..1c6e4ae076 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -6,6 +6,7 @@ LIBNAME = softpipe
C_SOURCES = \
sp_fs_exec.c \
sp_fs_sse.c \
+ sp_buffer.c \
sp_clear.c \
sp_flush.c \
sp_query.c \
@@ -32,7 +33,6 @@ C_SOURCES = \
sp_tex_tile_cache.c \
sp_tile_cache.c \
sp_surface.c \
- sp_video_context.c \
- sp_winsys.c
+ sp_video_context.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index 3042e556c6..27ab00b036 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -7,6 +7,7 @@ softpipe = env.ConvenienceLibrary(
source = [
'sp_fs_exec.c',
'sp_fs_sse.c',
+ 'sp_buffer.c',
'sp_clear.c',
'sp_context.c',
'sp_draw_arrays.c',
@@ -33,8 +34,7 @@ softpipe = env.ConvenienceLibrary(
'sp_tex_tile_cache.c',
'sp_texture.c',
'sp_tile_cache.c',
- 'sp_video_context.c',
- 'sp_winsys.c'
+ 'sp_video_context.c'
])
Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c
new file mode 100644
index 0000000000..8f39025086
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "sp_screen.h"
+#include "sp_buffer.h"
+
+
+static void *
+softpipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf);
+ return softpipe_buf->data;
+}
+
+
+static void
+softpipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+softpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct softpipe_buffer *sbuf = softpipe_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+softpipe_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+softpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct softpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(softpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = softpipe_buffer_create;
+ screen->user_buffer_create = softpipe_user_buffer_create;
+ screen->buffer_map = softpipe_buffer_map;
+ screen->buffer_unmap = softpipe_buffer_unmap;
+ screen->buffer_destroy = softpipe_buffer_destroy;
+}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/drivers/softpipe/sp_buffer.h
index f96c5a14b0..9d8e56a176 100644
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_buffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * 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
@@ -10,31 +10,46 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * 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 SP_BUFFER_H
+#define SP_BUFFER_H
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
-struct pipe_winsys;
+struct softpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
-extern struct pipe_winsys *
-create_sw_winsys(void);
+/** Cast wrapper */
+static INLINE struct softpipe_buffer *
+softpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct softpipe_buffer *)buf;
+}
-#endif /* SW_WINSYS_H */
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index ddc35bcd62..30494719f7 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -210,7 +210,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
- softpipe->pipe.winsys = screen->winsys;
+ softpipe->pipe.winsys = NULL;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
softpipe->pipe.priv = priv;
@@ -245,6 +245,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
+ softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state;
+ softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
+ softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
+
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
@@ -257,7 +261,6 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
- softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 95def72c54..9a8158e6a2 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -45,6 +45,7 @@ struct softpipe_tile_cache;
struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
+struct sp_velems_state;
struct softpipe_context {
@@ -59,6 +60,7 @@ struct softpipe_context {
struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
+ struct sp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -72,13 +74,11 @@ struct softpipe_context {
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_samplers;
unsigned num_vertex_textures;
- unsigned num_vertex_elements;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */
@@ -93,7 +93,7 @@ struct softpipe_context {
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
- void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
+ const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
/** Vertex format */
struct vertex_info vertex_info;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index b2acc36bf7..7b77eb239f 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -33,90 +33,19 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "util/u_prim.h"
#include "sp_context.h"
#include "sp_query.h"
#include "sp_state.h"
+#include "sp_buffer.h"
#include "draw/draw_context.h"
-static void
-softpipe_map_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- sp->mapped_constants[i][j] = ws->buffer_map(ws,
- sp->constants[i][j],
- PIPE_BUFFER_USAGE_CPU_READ);
- }
- }
- }
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- if (sp->constants[PIPE_SHADER_VERTEX][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- sp->mapped_constants[PIPE_SHADER_VERTEX][i],
- sp->constants[PIPE_SHADER_VERTEX][i]->size);
- }
- if (sp->constants[PIPE_SHADER_GEOMETRY][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- sp->mapped_constants[PIPE_SHADER_GEOMETRY][i],
- sp->constants[PIPE_SHADER_GEOMETRY][i]->size);
- }
- }
-}
-
-
-static void
-softpipe_unmap_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- /* really need to flush all prims since the vert/frag shaders const buffers
- * are going away now.
- */
- draw_flush(sp->draw);
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- NULL,
- 0);
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- NULL,
- 0);
- }
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- ws->buffer_unmap(ws, sp->constants[i][j]);
- }
- sp->mapped_constants[i][j] = NULL;
- }
- }
-}
/**
@@ -261,25 +190,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
softpipe_map_transfers(sp);
- softpipe_map_constant_buffers(sp);
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf;
-
- buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes;
-
- mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = softpipe_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer_range(draw,
indexSize,
minIndex,
@@ -300,15 +220,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- softpipe_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
+ /* Note: leave drawing surfaces mapped */
sp->dirty_render_cache = TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 27fa126b7c..67e2c8f8bc 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -145,8 +145,13 @@ exec_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index acee213670..daa158df7c 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -156,8 +156,13 @@ fs_sse_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 98c08eaffa..6749243ab4 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -264,57 +264,29 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
@@ -448,56 +420,28 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_public.h b/src/gallium/drivers/softpipe/sp_public.h
new file mode 100644
index 0000000000..62d0903d87
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_public.h
@@ -0,0 +1,10 @@
+#ifndef SP_PUBLIC_H
+#define SP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+softpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6ec63fe698..e0a2ef604e 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -27,15 +27,16 @@
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "state_tracker/sw_winsys.h"
+
#include "sp_texture.h"
-#include "sp_winsys.h"
#include "sp_screen.h"
#include "sp_context.h"
+#include "sp_buffer.h"
+#include "sp_public.h"
static const char *
@@ -83,11 +84,11 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return SP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -145,6 +146,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
assert(target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
@@ -166,15 +169,25 @@ softpipe_is_format_supported( struct pipe_screen *screen,
case PIPE_FORMAT_NONE:
return FALSE;
default:
- return TRUE;
+ break;
}
+
+ if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ if(!winsys->is_displaytarget_format_supported(winsys, format))
+ return FALSE;
+ }
+
+ /* XXX: this is often a lie. Pull in logic from llvmpipe to fix.
+ */
+ return TRUE;
}
static void
softpipe_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct softpipe_screen *sp_screen = softpipe_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -183,21 +196,37 @@ softpipe_destroy_screen( struct pipe_screen *screen )
}
+/* This is often overriden by the co-state tracker.
+ */
+static void
+softpipe_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct softpipe_screen *screen = softpipe_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct softpipe_texture *texture = softpipe_texture(surface->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ winsys->displaytarget_display(winsys, texture->dt, context_private);
+}
/**
* Create a new pipe_screen object
* Note: we're not presently subclassing pipe_screen (no softpipe_screen).
*/
struct pipe_screen *
-softpipe_create_screen(struct pipe_winsys *winsys)
+softpipe_create_screen(struct sw_winsys *winsys)
{
struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
if (!screen)
return NULL;
- screen->base.winsys = winsys;
+ screen->winsys = winsys;
+ screen->base.winsys = NULL;
screen->base.destroy = softpipe_destroy_screen;
screen->base.get_name = softpipe_get_name;
@@ -206,9 +235,10 @@ softpipe_create_screen(struct pipe_winsys *winsys)
screen->base.get_paramf = softpipe_get_paramf;
screen->base.is_format_supported = softpipe_is_format_supported;
screen->base.context_create = softpipe_create_context;
+ screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
softpipe_init_screen_texture_funcs(&screen->base);
- u_simple_screen_init(&screen->base);
+ softpipe_init_screen_buffer_funcs(&screen->base);
return &screen->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h
index 3d4bfd3e84..f741454c9e 100644
--- a/src/gallium/drivers/softpipe/sp_screen.h
+++ b/src/gallium/drivers/softpipe/sp_screen.h
@@ -35,10 +35,13 @@
#include "pipe/p_defines.h"
+struct sw_winsys;
struct softpipe_screen {
struct pipe_screen base;
+ struct sw_winsys *winsys;
+
/* Increments whenever textures are modified. Contexts can track
* this.
*/
@@ -55,4 +58,5 @@ softpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* SP_SCREEN_H */
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 4370bbeaee..6b01c0f4d7 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -100,6 +100,11 @@ struct sp_geometry_shader {
struct draw_geometry_shader *draw_data;
};
+struct sp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
void *
softpipe_create_blend_state(struct pipe_context *,
@@ -160,8 +165,14 @@ void *softpipe_create_gs_state(struct pipe_context *,
void softpipe_bind_gs_state(struct pipe_context *, void *);
void softpipe_delete_gs_state(struct pipe_context *, void *);
+void *softpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void softpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void softpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void softpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
@@ -178,10 +189,6 @@ softpipe_set_vertex_sampler_textures(struct pipe_context *,
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void softpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void softpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index c88e213751..2b089c2831 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -28,6 +28,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_fs.h"
+#include "sp_buffer.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -163,26 +164,33 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( state );
}
-
-
void
softpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? softpipe_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+ assert(index == 0);
draw_flush(softpipe->draw);
/* note: reference counting */
- pipe_buffer_reference(&softpipe->constants[shader][index], buf);
+ 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);
+ }
+
+ softpipe->mapped_constants[shader][index] = data;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
+
void *
softpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index b491d92ed1..462f4d2655 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -32,27 +32,45 @@
#include "sp_context.h"
#include "sp_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
+void *
+softpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct sp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct sp_velems_state *) MALLOC(sizeof(struct sp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-softpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_velems_state *sp_velems = (struct sp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(softpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- softpipe->num_vertex_elements = count;
+ softpipe->velems = sp_velems;
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_elements(softpipe->draw, count, attribs);
+ if (sp_velems)
+ draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem);
}
+void
+softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
softpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 32d261b5ff..11d184effb 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -36,11 +36,13 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_simple_screen.h"
#include "sp_context.h"
#include "sp_texture.h"
#include "sp_screen.h"
-#include "sp_winsys.h"
+
+#include "state_tracker/sw_winsys.h"
/**
@@ -72,11 +74,9 @@ softpipe_texture_layout(struct pipe_screen *screen,
depth = u_minify(depth, 1);
}
- spt->buffer = screen->buffer_create(screen, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- buffer_size);
+ spt->data = align_malloc(buffer_size, 16);
- return spt->buffer != NULL;
+ return spt->data != NULL;
}
@@ -87,19 +87,18 @@ static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
{
- unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ_WRITE);
- unsigned tex_usage = spt->base.tex_usage;
-
- spt->buffer = screen->surface_buffer_create( screen,
- spt->base.width0,
- spt->base.height0,
- spt->base.format,
- usage,
- tex_usage,
- &spt->stride[0]);
-
- return spt->buffer != NULL;
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ spt->dt = winsys->displaytarget_create(winsys,
+ spt->base.format,
+ spt->base.width0,
+ spt->base.height0,
+ 16,
+ &spt->stride[0] );
+
+ return spt->dt != NULL;
}
@@ -123,7 +122,8 @@ softpipe_texture_create(struct pipe_screen *screen,
util_is_power_of_two(template->depth0));
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@@ -140,46 +140,24 @@ softpipe_texture_create(struct pipe_screen *screen,
}
-/**
- * Create a new pipe_texture which wraps an existing buffer.
- */
-static struct pipe_texture *
-softpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- struct softpipe_texture *spt;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- spt = CALLOC_STRUCT(softpipe_texture);
- if (!spt)
- return NULL;
-
- spt->base = *base;
- pipe_reference_init(&spt->base.reference, 1);
- spt->base.screen = screen;
- spt->stride[0] = stride[0];
-
- pipe_buffer_reference(&spt->buffer, buffer);
-
- return &spt->base;
-}
static void
softpipe_texture_destroy(struct pipe_texture *pt)
{
+ struct softpipe_screen *screen = softpipe_screen(pt->screen);
struct softpipe_texture *spt = softpipe_texture(pt);
- pipe_buffer_reference(&spt->buffer, NULL);
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = screen->winsys;
+ winsys->displaytarget_destroy(winsys, spt->dt);
+ }
+ else {
+ /* regular texture */
+ align_free(spt->data);
+ }
+
FREE(spt);
}
@@ -359,9 +337,20 @@ softpipe_transfer_map( struct pipe_screen *screen,
spt = softpipe_texture(transfer->texture);
format = transfer->texture->format;
- map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
- if (map == NULL)
- return NULL;
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+ map = winsys->displaytarget_map(winsys, spt->dt,
+ pipe_transfer_buffer_flags(transfer));
+ if (map == NULL)
+ return NULL;
+ }
+ else {
+ map = spt->data;
+ if (map == NULL)
+ return NULL;
+ }
/* May want to different things here depending on read/write nature
* of the map:
@@ -393,7 +382,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
assert(transfer->texture);
spt = softpipe_texture(transfer->texture);
- pipe_buffer_unmap( screen, spt->buffer );
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ winsys->displaytarget_unmap(winsys, spt->dt);
+ }
if (transfer->usage & PIPE_TRANSFER_WRITE) {
/* Mark the texture as dirty to expire the tile caches. */
@@ -458,7 +451,6 @@ void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
- screen->texture_blanket = softpipe_texture_blanket;
screen->texture_destroy = softpipe_texture_destroy;
screen->get_tex_surface = softpipe_get_tex_surface;
@@ -474,24 +466,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
}
-/**
- * Return pipe_buffer handle and stride for given texture object.
- * XXX used for???
- */
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride )
-{
- struct softpipe_texture *tex = (struct softpipe_texture *) texture;
- if (!tex)
- return FALSE;
-
- pipe_buffer_reference(buf, tex->buffer);
-
- if (stride)
- *stride = tex->stride[0];
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 2ef64e1e7c..1c8636d1d5 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -33,6 +33,10 @@
#include "pipe/p_video_state.h"
+#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */
+#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */
+
+
struct pipe_context;
struct pipe_screen;
struct softpipe_context;
@@ -42,12 +46,19 @@ struct softpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[SP_MAX_TEXTURE_2D_LEVELS];
- /* The data is held here:
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
+ */
+ struct sw_displaytarget *dt;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
*/
- struct pipe_buffer *buffer;
+ void *data;
/* True if texture images are power-of-two in all dimensions:
*/
diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c
deleted file mode 100644
index 0a6245ed2c..0000000000
--- a/src/gallium/drivers/softpipe/sp_winsys.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Malloc softpipe winsys. Uses malloc for all memory allocations.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include "util/u_simple_screen.h"/* port to just p_screen */
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "sp_winsys.h"
-
-
-struct st_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct st_softpipe_buffer *
-st_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct st_softpipe_buffer *)buf;
-}
-
-
-static void *
-st_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = st_softpipe_buf->data;
- return st_softpipe_buf->mapped;
-}
-
-
-static void
-st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-st_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static void
-st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surf,
- void *context_private)
-{
-}
-
-
-
-static const char *
-st_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-st_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct st_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(st_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-st_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-st_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-st_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-st_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-struct pipe_screen *
-softpipe_create_screen_malloc(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = st_softpipe_destroy;
-
- winsys->buffer_create = st_softpipe_buffer_create;
- winsys->user_buffer_create = st_softpipe_user_buffer_create;
- winsys->buffer_map = st_softpipe_buffer_map;
- winsys->buffer_unmap = st_softpipe_buffer_unmap;
- winsys->buffer_destroy = st_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
-
- winsys->fence_reference = st_softpipe_fence_reference;
- winsys->fence_signalled = st_softpipe_fence_signalled;
- winsys->fence_finish = st_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
- winsys->get_name = st_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- st_softpipe_destroy(winsys);
-
- return screen;
-}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
deleted file mode 100644
index 6e3920c49b..0000000000
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/* This is the interface that softpipe requires any window system
- * hosting it to implement. This is the only include file in softpipe
- * which is public.
- */
-
-
-#ifndef SP_WINSYS_H
-#define SP_WINSYS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "pipe/p_defines.h"
-
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_texture;
-struct pipe_buffer;
-
-
-
-/**
- * Create a softpipe screen that uses the
- * given winsys for allocating buffers.
- */
-struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
-
-/**
- * Create a softpipe screen that uses
- * regular malloc to create all its buffers.
- */
-struct pipe_screen *softpipe_create_screen_malloc(void);
-
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride );
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SP_WINSYS_H */
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 03302e2a6e..791d30edc0 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -169,6 +169,11 @@ struct svga_sampler_state {
unsigned view_max_lod;
};
+struct svga_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
/* Use to calculate differences between state emitted to hardware and
* current driver-calculated state.
*/
@@ -178,13 +183,13 @@ struct svga_state
const struct svga_depth_stencil_state *depth;
const struct svga_rasterizer_state *rast;
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 svga_fragment_shader *fs;
struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
struct pipe_buffer *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
@@ -204,7 +209,6 @@ struct svga_state
unsigned num_samplers;
unsigned num_textures;
- unsigned num_vertex_elements;
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 acba2b8f9d..1a8ef296ca 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -155,7 +155,7 @@ static void svga_bind_sampler_states(struct pipe_context *pipe,
/* Check for no-op */
if (num == svga->curr.num_samplers &&
!memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
- debug_printf("sampler noop\n");
+ if (0) debug_printf("sampler noop\n");
return;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 836b8441da..1715a47fc6 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -26,6 +26,7 @@
#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
+#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
#include "svga_screen.h"
@@ -64,20 +65,37 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
svga->dirty |= SVGA_NEW_VBUFFER;
}
-static void svga_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+
+static void *
+svga_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct svga_context *svga = svga_context(pipe);
- unsigned i;
+ struct svga_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
- for (i = 0; i < count; i++)
- svga->curr.ve[i] = elements[i];
+static void svga_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct svga_context *svga = svga_context(pipe);
+ struct svga_velems_state *svga_velems = (struct svga_velems_state *) velems;
- svga->curr.num_vertex_elements = count;
+ svga->curr.velems = svga_velems;
svga->dirty |= SVGA_NEW_VELEMENT;
}
+static void svga_delete_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ FREE(velems);
+}
void svga_cleanup_vertex_state( struct svga_context *svga )
{
@@ -91,7 +109,9 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
void svga_init_vertex_functions( struct svga_context *svga )
{
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
- svga->pipe.set_vertex_elements = svga_set_vertex_elements;
+ svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
+ svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
+ svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index e9792e063e..5b581debfc 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -315,7 +315,11 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.cachable = 0;
}
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
+ tex->key.cachable = 0;
+ }
+
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
tex->key.cachable = 0;
}
@@ -355,80 +359,18 @@ error1:
}
-static struct pipe_texture *
-svga_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- struct svga_texture *tex;
- struct svga_buffer *sbuf = svga_buffer(buffer);
- struct svga_winsys_screen *sws = svga_winsys_screen(screen);
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- /**
- * We currently can't do texture blanket on
- * SVGA3D_BUFFER. Need to blit to a temporary surface?
- */
-
- assert(sbuf->handle);
- if (!sbuf->handle)
- return NULL;
-
- if (svga_translate_format(base->format) != sbuf->key.format) {
- unsigned f1 = svga_translate_format(base->format);
- unsigned f2 = sbuf->key.format;
-
- /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
- if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
- (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
- (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
- debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
- return NULL;
- }
- }
-
- tex = CALLOC_STRUCT(svga_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
-
-
- if (sbuf->key.format == 1)
- tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM;
- else if (sbuf->key.format == 2)
- tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
- SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
- /* We don't own this storage, so don't try to cache it.
- */
- assert(sbuf->key.cachable == 0);
- tex->key.cachable = 0;
- sws->surface_reference(sws, &tex->handle, sbuf->handle);
- return &tex->base;
-}
-
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf)
+static struct pipe_texture *
+svga_screen_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *base,
+ struct winsys_handle *whandle)
{
+ struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+ struct svga_winsys_surface *srf;
struct svga_texture *tex;
+ enum SVGA3dSurfaceFormat format = 0;
assert(screen);
/* Only supports one type */
@@ -438,6 +380,8 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
return NULL;
}
+ srf = sws->surface_from_handle(sws, whandle, &format);
+
if (!srf)
return NULL;
@@ -478,6 +422,22 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
}
+static boolean
+svga_screen_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
+ unsigned stride;
+
+ assert(svga_texture(texture)->key.cachable == 0);
+ svga_texture(texture)->key.cachable = 0;
+ stride = util_format_get_nblocksx(texture->format, texture->width0) *
+ util_format_get_blocksize(texture->format);
+ return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
+}
+
+
static void
svga_texture_destroy(struct pipe_texture *pt)
{
@@ -955,10 +915,11 @@ void
svga_screen_init_texture_functions(struct pipe_screen *screen)
{
screen->texture_create = svga_texture_create;
+ screen->texture_from_handle = svga_screen_texture_from_handle;
+ screen->texture_get_handle = svga_screen_texture_get_handle;
screen->texture_destroy = svga_texture_destroy;
screen->get_tex_surface = svga_get_tex_surface;
screen->tex_surface_destroy = svga_tex_surface_destroy;
- screen->texture_blanket = svga_texture_blanket;
screen->get_tex_transfer = svga_get_tex_transfer;
screen->transfer_map = svga_transfer_map;
screen->transfer_unmap = svga_transfer_unmap;
@@ -1120,33 +1081,3 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
pipe_texture_reference(&v->texture, NULL);
FREE(v);
}
-
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride)
-{
- struct svga_texture *stex = svga_texture(texture);
-
- *buffer = svga_screen_buffer_wrap_surface
- (texture->screen,
- svga_translate_format(texture->format),
- stex->handle);
-
- *stride = util_format_get_stride(texture->format, texture->width0);
-
- return *buffer != NULL;
-}
-
-
-struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
- struct svga_winsys_surface *vsurf = NULL;
-
- assert(svga_texture(texture)->key.cachable == 0);
- svga_texture(texture)->key.cachable = 0;
- sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
- return vsurf;
-}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 24c1f78ca5..ca6602b436 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -78,7 +78,7 @@ struct svga_texture
{
struct pipe_texture base;
- boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
+ boolean defined[6][SVGA_MAX_TEXTURE_LEVELS];
struct svga_sampler_view *cached_view;
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
index d774e3e504..dfaab53aef 100644
--- a/src/gallium/drivers/svga/svga_state_need_swtnl.c
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -76,8 +76,13 @@ static int update_need_swvfetch( struct svga_context *svga,
unsigned i;
boolean need_swvfetch = FALSE;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format);
+ if (!svga->curr.velems) {
+ /* No vertex elements bound. */
+ return 0;
+ }
+
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format);
if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
need_swvfetch = TRUE;
break;
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 107cc403b4..b7195d246b 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -191,15 +191,24 @@ static int emit_rss( struct svga_context *svga,
EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
}
- if (dirty & SVGA_NEW_RAST)
+ if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
{
const struct svga_rasterizer_state *curr = svga->curr.rast;
+ unsigned cullmode = curr->cullmode;
/* Shademode: still need to rearrange index list to move
* flat-shading PV first vertex.
*/
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
- EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
+
+ /* Don't do culling while the software pipeline is active. It
+ * does it for us, and additionally introduces potentially
+ * back-facing triangles.
+ */
+ if (svga->state.sw.need_pipeline)
+ cullmode = SVGA3D_FACE_NONE;
+
+ EMIT_RS( svga, cullmode, CULLMODE, fail );
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index ded903170b..f531e22304 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -95,17 +95,17 @@ upload_user_buffers( struct svga_context *svga )
static int emit_hw_vs_vdecl( struct svga_context *svga,
unsigned dirty )
{
- const struct pipe_vertex_element *ve = svga->curr.ve;
+ const struct pipe_vertex_element *ve = svga->curr.velems->velem;
SVGA3dVertexDecl decl;
unsigned i;
- assert(svga->curr.num_vertex_elements >=
+ assert(svga->curr.velems->count >=
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
svga_hwtnl_reset_vdecl( svga->hwtnl,
- svga->curr.num_vertex_elements );
+ svga->curr.velems->count );
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+ for (i = 0; i < svga->curr.velems->count; i++) {
const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
unsigned usage, index;
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index d7999fe53d..781f7bf533 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -186,8 +186,8 @@ static int update_zero_stride( struct svga_context *svga,
svga->curr.zero_stride_vertex_elements = 0;
svga->curr.num_zero_stride_vertex_elements = 0;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- const struct pipe_vertex_element *vel = &svga->curr.ve[i];
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
vel->vertex_buffer_index];
if (vbuffer->stride == 0) {
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 35f36a828f..246d34e649 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -99,8 +99,8 @@ static int update_swtnl_draw( struct svga_context *svga,
if (dirty & SVGA_NEW_VELEMENT)
draw_set_vertex_elements(svga->swtnl.draw,
- svga->curr.num_vertex_elements,
- svga->curr.ve );
+ svga->curr.velems->count,
+ svga->curr.velems->velem );
if (dirty & SVGA_NEW_CLIP)
draw_set_clip_state(svga->swtnl.draw,
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index b4e3af0eaf..d4bb176f9a 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -51,6 +51,7 @@ struct pipe_context;
struct pipe_fence_handle;
struct pipe_texture;
struct svga_region;
+struct winsys_handle;
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
@@ -187,6 +188,25 @@ struct svga_winsys_screen
uint32 numMipLevels);
/**
+ * Creates a surface from a winsys handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ */
+ struct svga_winsys_surface *
+ (*surface_from_handle)(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+
+ /**
+ * Get a winsys_handle from a surface.
+ * Used to implement pipe_screen::texture_get_handle.
+ */
+ boolean
+ (*surface_get_handle)(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
+ /**
* Whether this surface is sitting in a validate list
*/
boolean
@@ -284,19 +304,6 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
struct svga_winsys_surface *srf);
struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
-struct svga_winsys_surface *
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf);
-
#endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index df40fbade6..133521f45e 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -773,6 +773,70 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,
}
+static INLINE void *
+trace_context_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ void * result;
+
+ trace_dump_call_begin("pipe_context", "create_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(uint, num_elements);
+
+ trace_dump_arg_begin("elements");
+ trace_dump_struct_array(vertex_element, elements, num_elements);
+ trace_dump_arg_end();
+
+ result = pipe->create_vertex_elements_state(pipe, num_elements, elements);
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ return result;
+}
+
+
+static INLINE void
+trace_context_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "bind_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->bind_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "delete_verte_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->delete_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
static INLINE void
trace_context_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *state)
@@ -1048,29 +1112,6 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
static INLINE void
-trace_context_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *elements)
-{
- struct trace_context *tr_ctx = trace_context(_pipe);
- struct pipe_context *pipe = tr_ctx->pipe;
-
- trace_dump_call_begin("pipe_context", "set_vertex_elements");
-
- trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_elements);
-
- trace_dump_arg_begin("elements");
- trace_dump_struct_array(vertex_element, elements, num_elements);
- trace_dump_arg_end();
-
- pipe->set_vertex_elements(pipe, num_elements, elements);
-
- trace_dump_call_end();
-}
-
-
-static INLINE void
trace_context_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *dest,
unsigned destx, unsigned desty,
@@ -1303,6 +1344,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.create_vs_state = trace_context_create_vs_state;
tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
+ tr_ctx->base.create_vertex_elements_state = trace_context_create_vertex_elements_state;
+ tr_ctx->base.bind_vertex_elements_state = trace_context_bind_vertex_elements_state;
+ tr_ctx->base.delete_vertex_elements_state = trace_context_delete_vertex_elements_state;
tr_ctx->base.set_blend_color = trace_context_set_blend_color;
tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
tr_ctx->base.set_clip_state = trace_context_set_clip_state;
@@ -1314,7 +1358,6 @@ trace_context_create(struct trace_screen *tr_scr,
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_vertex_buffers = trace_context_set_vertex_buffers;
- tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
if (pipe->surface_copy)
tr_ctx->base.surface_copy = trace_context_surface_copy;
if (pipe->surface_fill)
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 2b4915003e..906b3262e4 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -33,6 +33,7 @@
#include "tr_context.h"
#include "tr_buffer.h"
#include "tr_texture.h"
+#include "tr_public.h"
struct trace_drm_api
{
@@ -62,69 +63,8 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
- return trace_screen_create(screen);
-}
-
-
-static struct pipe_texture *
-trace_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct drm_api *api = tr_api->api;
- struct pipe_texture *result;
-
- /* TODO trace call */
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = trace_texture_create(trace_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-trace_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-static boolean
-trace_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
+ return trace_screen_create(screen);
}
static void
@@ -158,9 +98,6 @@ trace_drm_create(struct drm_api *api)
tr_api->base.name = api->name;
tr_api->base.driver_name = api->driver_name;
tr_api->base.create_screen = trace_drm_create_screen;
- tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
- tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
- tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
tr_api->base.destroy = trace_drm_destroy;
tr_api->api = api;
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index f97d963dba..f82dd01c69 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -479,7 +479,6 @@ void trace_dump_vertex_element(const struct pipe_vertex_element *state)
trace_dump_member(uint, state, src_offset);
trace_dump_member(uint, state, vertex_buffer_index);
- trace_dump_member(uint, state, nr_components);
trace_dump_member(format, state, src_format);
diff --git a/src/gallium/drivers/trace/tr_public.h b/src/gallium/drivers/trace/tr_public.h
new file mode 100644
index 0000000000..62e217097d
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_public.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+ *
+ * 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 SOFTWARE IS PROVIDED "AS 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.
+ *
+ **************************************************************************/
+
+#ifndef TR_PUBLIC_H
+#define TR_PUBLIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_screen;
+struct pipe_context;
+
+struct pipe_screen *
+trace_screen_create(struct pipe_screen *screen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TR_PUBLIC_H */
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 388d83eb5c..86ddb99540 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -35,6 +35,7 @@
#include "tr_texture.h"
#include "tr_context.h"
#include "tr_screen.h"
+#include "tr_public.h"
#include "util/u_inlines.h"
#include "pipe/p_format.h"
@@ -236,39 +237,41 @@ trace_screen_texture_create(struct pipe_screen *_screen,
return result;
}
-
static struct pipe_texture *
-trace_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *ppitch,
- struct pipe_buffer *_buffer)
+trace_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(_buffer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_buffer *buffer = tr_buf->buffer;
- unsigned pitch = *ppitch;
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *result;
- trace_dump_call_begin("pipe_screen", "texture_blanket");
+ /* TODO trace call */
- trace_dump_arg(ptr, screen);
- trace_dump_arg(template, templat);
- trace_dump_arg(uint, pitch);
- trace_dump_arg(ptr, buffer);
+ result = screen->texture_from_handle(screen, templ, handle);
- result = screen->texture_blanket(screen, templat, ppitch, buffer);
+ result = trace_texture_create(trace_screen(_screen), result);
- trace_dump_ret(ptr, result);
+ return result;
+}
- trace_dump_call_end();
+static boolean
+trace_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct trace_texture *tr_texture = trace_texture(_texture);
+ struct pipe_screen *screen = tr_screen->screen;
+ struct pipe_texture *texture = tr_texture->texture;
- result = trace_texture_create(tr_scr, result);
+ /* TODO trace call */
- return result;
+ return screen->texture_get_handle(screen, texture, handle);
}
+
static void
trace_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -484,45 +487,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen,
*/
-static struct pipe_buffer *
-trace_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *pstride)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct pipe_screen *screen = tr_scr->screen;
- unsigned stride;
- struct pipe_buffer *result;
-
- trace_dump_call_begin("pipe_screen", "surface_buffer_create");
-
- trace_dump_arg(ptr, screen);
- trace_dump_arg(uint, width);
- trace_dump_arg(uint, height);
- trace_dump_arg(format, format);
- trace_dump_arg(uint, usage);
- trace_dump_arg(uint, tex_usage);
- result = screen->surface_buffer_create(screen,
- width, height,
- format,
- usage,
- tex_usage,
- pstride);
-
- stride = *pstride;
-
- trace_dump_arg(uint, stride);
-
- trace_dump_ret(ptr, result);
-
- trace_dump_call_end();
-
- return trace_buffer_create(tr_scr, result);
-}
static struct pipe_buffer *
@@ -931,7 +896,8 @@ trace_screen_create(struct pipe_screen *screen)
assert(screen->context_create);
tr_scr->base.context_create = trace_screen_context_create;
tr_scr->base.texture_create = trace_screen_texture_create;
- tr_scr->base.texture_blanket = trace_screen_texture_blanket;
+ tr_scr->base.texture_from_handle = trace_screen_texture_from_handle;
+ tr_scr->base.texture_get_handle = trace_screen_texture_get_handle;
tr_scr->base.texture_destroy = trace_screen_texture_destroy;
tr_scr->base.get_tex_surface = trace_screen_get_tex_surface;
tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy;
@@ -941,7 +907,6 @@ trace_screen_create(struct pipe_screen *screen)
tr_scr->base.transfer_unmap = trace_screen_transfer_unmap;
tr_scr->base.buffer_create = trace_screen_buffer_create;
tr_scr->base.user_buffer_create = trace_screen_user_buffer_create;
- tr_scr->base.surface_buffer_create = trace_screen_surface_buffer_create;
if (screen->buffer_map)
tr_scr->base.buffer_map = trace_screen_buffer_map;
if (screen->buffer_map_range)
diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h
index fe5a0fa190..597e2fc265 100644
--- a/src/gallium/drivers/trace/tr_screen.h
+++ b/src/gallium/drivers/trace/tr_screen.h
@@ -99,9 +99,6 @@ trace_enabled(void);
struct trace_screen *
trace_screen(struct pipe_screen *screen);
-struct pipe_screen *
-trace_screen_create(struct pipe_screen *screen);
-
void
trace_screen_user_buffer_update(struct pipe_screen *screen,
struct pipe_buffer *buffer);
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index b93b38310a..e2766d15cd 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -31,13 +31,8 @@
#include "p_config.h"
-#ifndef XFree86Server
#include <stdlib.h>
#include <string.h>
-#else
-#include "xf86_ansic.h"
-#include "xf86_libc.h"
-#endif
#include <stddef.h>
#include <stdarg.h>
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f82b77903e..376b01aa69 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -177,6 +177,12 @@ struct pipe_context {
void (*bind_gs_state)(struct pipe_context *, void *);
void (*delete_gs_state)(struct pipe_context *, void *);
+ void * (*create_vertex_elements_state)(struct pipe_context *,
+ unsigned num_elements,
+ const struct pipe_vertex_element *);
+ void (*bind_vertex_elements_state)(struct pipe_context *, void *);
+ void (*delete_vertex_elements_state)(struct pipe_context *, void *);
+
/*@}*/
/**
@@ -220,9 +226,6 @@ struct pipe_context {
unsigned num_buffers,
const struct pipe_vertex_buffer * );
- void (*set_vertex_elements)( struct pipe_context *,
- unsigned num_elements,
- const struct pipe_vertex_element * );
/*@}*/
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 5cebd43ace..5c97dc87e8 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -176,11 +176,12 @@ enum pipe_texture_target {
#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1
#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
-#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
-#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
+#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* windows presentable buffer, ie a backbuffer */
+#define PIPE_TEXTURE_USAGE_SCANOUT 0x4 /* ie a frontbuffer */
#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
#define PIPE_TEXTURE_USAGE_DYNAMIC 0x20
+#define PIPE_TEXTURE_USAGE_SHARED 0x40
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16)
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index e4a9222809..b771bfe85e 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -50,6 +50,8 @@ extern "C" {
/** Opaque type */
+struct winsys_handle;
+/** Opaque type */
struct pipe_fence_handle;
struct pipe_winsys;
struct pipe_buffer;
@@ -108,16 +110,23 @@ struct pipe_screen {
const struct pipe_texture *templat);
/**
- * Create a new texture object, using the given template info, but on top of
- * existing memory.
- *
- * It is assumed that the buffer data is layed out according to the expected
- * by the hardware. NULL will be returned if any inconsistency is found.
+ * Create a texture from a winsys_handle. The handle is often created in
+ * another process by first creating a pipe texture and then calling
+ * texture_get_handle.
+ */
+ struct pipe_texture * (*texture_from_handle)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ struct winsys_handle *handle);
+
+ /**
+ * Get a winsys_handle from a texture. Some platforms/winsys requires
+ * that the texture is created with a special usage flag like
+ * DISPLAYTARGET or PRIMARY.
*/
- struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *buffer);
+ boolean (*texture_get_handle)(struct pipe_screen *,
+ struct pipe_texture *tex,
+ struct winsys_handle *handle);
+
void (*texture_destroy)(struct pipe_texture *pt);
@@ -187,23 +196,6 @@ struct pipe_screen {
void *ptr,
unsigned bytes);
- /**
- * Allocate storage for a display target surface.
- *
- * Often surfaces which are meant to be blitted to the front screen (i.e.,
- * display targets) must be allocated with special characteristics, memory
- * pools, or obtained directly from the windowing system.
- *
- * This callback is invoked by the pipe_screenwhen creating a texture marked
- * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
- * buffer storage.
- */
- struct pipe_buffer *(*surface_buffer_create)(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride);
/**
@@ -273,6 +265,7 @@ struct pipe_screen {
/**
* Do any special operations to ensure buffer size is correct
+ * \param context_private the private data of the calling context
*/
void (*update_buffer)( struct pipe_screen *ws,
void *context_private );
@@ -280,10 +273,12 @@ struct pipe_screen {
/**
* Do any special operations to ensure frontbuffer contents are
* displayed, eg copy fake frontbuffer.
+ * \param winsys_drawable_handle an opaque handle that the calling context
+ * gets out-of-band
*/
void (*flush_frontbuffer)( struct pipe_screen *screen,
struct pipe_surface *surf,
- void *context_private );
+ void *winsys_drawable_handle );
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 02558520bf..3a97d888ce 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -249,7 +249,7 @@ struct pipe_framebuffer_state
{
unsigned width, height;
- /** multiple colorbuffers for multiple render targets */
+ /** multiple color buffers for multiple render targets */
unsigned nr_cbufs;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
@@ -285,12 +285,12 @@ struct pipe_sampler_state
struct pipe_surface
{
struct pipe_reference reference;
- enum pipe_format format; /**< PIPE_FORMAT_x */
+ enum pipe_format format;
unsigned width; /**< logical width in pixels */
unsigned height; /**< logical height in pixels */
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
- unsigned usage; /**< PIPE_BUFFER_USAGE_* */
+ unsigned usage; /**< bitmask of PIPE_BUFFER_USAGE_x */
unsigned zslice;
struct pipe_texture *texture; /**< texture into which this is a view */
@@ -336,7 +336,7 @@ struct pipe_texture
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
- unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */
+ unsigned tex_usage; /**< bitmask of PIPE_TEXTURE_USAGE_* */
struct pipe_screen *screen; /**< screen that this texture belongs to */
};
@@ -373,9 +373,8 @@ struct pipe_vertex_element
* this attribute live in?
*/
unsigned vertex_buffer_index:8;
- unsigned nr_components:8;
- enum pipe_format src_format; /**< PIPE_FORMAT_* */
+ enum pipe_format src_format;
};
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index e9fa9b4d2a..fe7ef253ef 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -17,6 +17,32 @@ enum drm_create_screen_mode {
DRM_CREATE_MAX
};
+#define DRM_API_HANDLE_TYPE_SHARED 0
+#define DRM_API_HANDLE_TYPE_KMS 1
+
+/**
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
+ */
+struct winsys_handle
+{
+ /**
+ * Unused for texture_from_handle, always
+ * DRM_API_HANDLE_TYPE_SHARED. Input to texture_get_handle,
+ * use TEXTURE_USAGE to select handle for kms or ipc.
+ */
+ unsigned type;
+ /**
+ * Input to texture_from_handle.
+ * Output for texture_get_handle.
+ */
+ unsigned handle;
+ /**
+ * Input to texture_from_handle.
+ * Output for texture_get_handle.
+ */
+ unsigned stride;
+};
+
/**
* Modes other than DRM_CREATE_NORMAL derive from this struct.
*/
@@ -28,6 +54,8 @@ struct drm_create_screen_arg {
struct drm_api
{
+ void (*destroy)(struct drm_api *api);
+
const char *name;
/**
@@ -36,37 +64,10 @@ struct drm_api
const char *driver_name;
/**
- * Special buffer functions
+ * Create a pipe srcreen.
*/
- /*@{*/
struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd,
struct drm_create_screen_arg *arg);
- /*@}*/
-
- /**
- * Special buffer functions
- */
- /*@{*/
- struct pipe_texture*
- (*texture_from_shared_handle)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle);
- boolean (*shared_handle_from_texture)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle);
- boolean (*local_handle_from_texture)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle);
- /*@}*/
-
- void (*destroy)(struct drm_api *api);
};
extern struct drm_api * drm_api_create(void);
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index ce11fa9304..0de98bbc1c 100644
--- a/src/gallium/drivers/llvmpipe/lp_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -27,12 +27,12 @@
/**
* @file
- * llvmpipe public interface.
+ * Software rasterizer winsys.
*/
-#ifndef LP_WINSYS_H
-#define LP_WINSYS_H
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
#include "pipe/p_compiler.h" /* for boolean */
@@ -51,23 +51,23 @@ struct pipe_context;
/**
* Opaque pointer.
*/
-struct llvmpipe_displaytarget;
+struct sw_displaytarget;
/**
- * This is the interface that llvmpipe expects any window system
+ * This is the interface that sw expects any window system
* hosting it to implement.
*
- * llvmpipe is for the most part a self sufficient driver. The only thing it
+ * sw is for the most part a self sufficient driver. The only thing it
* does not know is how to display a surface.
*/
-struct llvmpipe_winsys
+struct sw_winsys
{
void
- (*destroy)( struct llvmpipe_winsys *ws );
+ (*destroy)( struct sw_winsys *ws );
boolean
- (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
+ (*is_displaytarget_format_supported)( struct sw_winsys *ws,
enum pipe_format format );
/**
@@ -81,21 +81,24 @@ struct llvmpipe_winsys
* with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
* storage.
*/
- struct llvmpipe_displaytarget *
- (*displaytarget_create)( struct llvmpipe_winsys *ws,
+ struct sw_displaytarget *
+ (*displaytarget_create)( struct sw_winsys *ws,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride );
+ /**
+ * \param flags bitmask of PIPE_BUFFER_USAGE_x flags
+ */
void *
- (*displaytarget_map)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+ (*displaytarget_map)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags );
void
- (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
+ (*displaytarget_unmap)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt );
/**
* @sa pipe_screen:flush_frontbuffer.
@@ -103,23 +106,19 @@ struct llvmpipe_winsys
* This call will likely become asynchronous eventually.
*/
void
- (*displaytarget_display)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+ (*displaytarget_display)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
void *context_private );
void
- (*displaytarget_destroy)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
+ (*displaytarget_destroy)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt );
};
-struct pipe_screen *
-llvmpipe_create_screen( struct llvmpipe_winsys * );
-
-
#ifdef __cplusplus
}
#endif
-#endif /* LP_WINSYS_H */
+#endif /* SW_WINSYS_H */
diff --git a/src/gallium/include/state_tracker/xlib_sw_winsys.h b/src/gallium/include/state_tracker/xlib_sw_winsys.h
new file mode 100644
index 0000000000..f22c22bb62
--- /dev/null
+++ b/src/gallium/include/state_tracker/xlib_sw_winsys.h
@@ -0,0 +1,29 @@
+#ifndef XLIB_SW_WINSYS_H
+#define XLIB_SW_WINSYS_H
+
+#include "state_tracker/sw_winsys.h"
+#include <X11/Xlib.h>
+
+
+struct pipe_screen;
+struct pipe_surface;
+
+/* This is what the xlib software winsys expects to find in the
+ * "private" field of flush_frontbuffers().
+ *
+ * Xlib-based state trackers somehow need to know this.
+ */
+struct xlib_drawable {
+ Visual *visual;
+ int depth;
+ Drawable drawable;
+};
+
+
+/* This is the public interface to the ws/xlib module. Why isn't it
+ * being defined in that directory?
+ */
+struct sw_winsys *xlib_create_sw_winsys( Display *display );
+
+
+#endif
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 908cef454e..2f991c39e3 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -128,7 +128,7 @@ dri_unbind_context(__DRIcontext * 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);
+ st_make_current(NULL, NULL, NULL, NULL);
}
}
}
@@ -161,7 +161,13 @@ dri_make_current(__DRIcontext * cPriv,
ctx->r_stamp = driReadPriv->lastStamp - 1;
}
- st_make_current(ctx->st, draw->stfb, read->stfb);
+ /* 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);
@@ -170,7 +176,7 @@ dri_make_current(__DRIcontext * cPriv,
ctx->pipe->priv);
}
} else {
- st_make_current(NULL, NULL, NULL);
+ st_make_current(NULL, NULL, NULL, NULL);
}
return GL_TRUE;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 173f4041c8..458473853c 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -58,6 +58,7 @@ dri_surface_from_handle(struct drm_api *api,
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;
@@ -68,8 +69,11 @@ dri_surface_from_handle(struct drm_api *api,
templat.width0 = width;
templat.height0 = height;
- texture = api->texture_from_shared_handle(api, screen, &templat,
- "dri2 buffer", pitch, handle);
+ 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__);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 50774b03f3..e4972d493d 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -509,20 +509,6 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
/**
- * Flush the front buffer of the context's draw surface.
- */
-static void
-egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
-
- if (gsurf)
- gsurf->native->flush_frontbuffer(gsurf->native);
-}
-
-/**
* Re-validate the context.
*/
static void
@@ -602,7 +588,6 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
gdpy->native->user_data = (void *) dpy;
- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
egl_g3d_init_st(&gdrv->base);
@@ -907,8 +892,13 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
if (gctx) {
ok = egl_g3d_realloc_context(dpy, &gctx->base);
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);
+ 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) {
@@ -920,7 +910,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
}
}
else if (old_gctx) {
- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
+ ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 9c22ff3e43..93c81b26e1 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -140,9 +140,6 @@ struct native_config {
struct native_display {
/**
* The pipe screen of the native display.
- *
- * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be
- * overridden.
*/
struct pipe_screen *screen;
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
index 507a0ec402..562dd68c15 100644
--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h
+++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h
@@ -9,7 +9,7 @@ ST_PUBLIC(st_get_framebuffer_surface, int, struct st_f
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)
+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)
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index 94588bfa74..7322240856 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
templ.format = ksurf->color_format;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
- templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
}
/* create textures */
@@ -100,7 +100,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
for (i = 0; i < num_framebuffers; i++) {
struct kms_framebuffer *fb;
enum native_attachment natt;
- unsigned int handle, stride;
+ struct winsys_handle whandle;
uint block_bits;
if (i == 0) {
@@ -128,13 +128,17 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
/* TODO detect the real value */
fb->is_passive = TRUE;
- if (!kdpy->api->local_handle_from_texture(kdpy->api,
- kdpy->base.screen, fb->texture, &stride, &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!kdpy->base.screen->texture_get_handle(kdpy->base.screen,
+ fb->texture, &whandle))
return FALSE;
block_bits = util_format_get_blocksizebits(ksurf->color_format);
err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
- block_bits, block_bits, stride, handle, &fb->buffer_id);
+ block_bits, block_bits, whandle.stride, whandle.handle,
+ &fb->buffer_id);
if (err) {
fb->buffer_id = 0;
return FALSE;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 8d2a8b1dff..9839979231 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -114,6 +114,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
struct pipe_texture templ;
+ struct winsys_handle whandle;
uint valid_mask;
int i;
@@ -171,9 +172,11 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
continue;
}
- dri2surf->textures[natt] =
- dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
- dri2dpy->base.screen, &templ, desc, xbuf->pitch, xbuf->name);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = xbuf->pitch;
+ whandle.handle = xbuf->name;
+ dri2surf->textures[natt] = dri2dpy->base.screen->texture_from_handle(
+ dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 7b4fe63fa0..c6eb17ab1a 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -142,16 +142,9 @@ native_create_display(EGLNativeDisplayType dpy,
if (!ndpy) {
EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
- boolean use_shm;
-
- /*
- * XXX st/mesa calls pipe_screen::update_buffer in st_validate_state.
- * When SHM is used, there is a good chance that the shared memory
- * segment is detached before the softpipe tile cache is flushed.
- */
- use_shm = FALSE;
- _eglLog(level, "use software%s fallback", (use_shm) ? " (SHM)" : "");
- ndpy = x11_create_ximage_display(dpy, event_handler, use_shm);
+
+ _eglLog(level, "use software fallback");
+ ndpy = x11_create_ximage_display(dpy, event_handler);
}
return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 8c6a7d9349..1566524926 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -30,8 +30,7 @@
struct native_display *
x11_create_ximage_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
- boolean use_xshm);
+ struct native_event_handler *event_handler);
struct native_display *
x11_create_dri2_display(EGLNativeDisplayType dpy,
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 3421c1951a..e0d12acabe 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -28,17 +28,19 @@
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
-#include "softpipe/sp_winsys.h"
+#include "state_tracker/xlib_sw_winsys.h"
+#include "target-helpers/wrap_screen.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "cell/ppu/cell_public.h"
#include "egllog.h"
-#include "sw_winsys.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -53,24 +55,18 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
- struct x11_screen *xscr;
- int xscr_number;
-
struct native_event_handler *event_handler;
- boolean use_xshm;
+ struct x11_screen *xscr;
+ int xscr_number;
- struct pipe_winsys *winsys;
struct ximage_config *configs;
int num_configs;
};
struct ximage_buffer {
- XImage *ximage;
-
struct pipe_texture *texture;
- XShmSegmentInfo *shm_info;
- boolean xshm_attached;
+ struct xlib_drawable xdraw;
};
struct ximage_surface {
@@ -81,8 +77,6 @@ struct ximage_surface {
XVisualInfo visual;
struct ximage_display *xdpy;
- GC gc;
-
unsigned int server_stamp;
unsigned int client_stamp;
int width, height;
@@ -121,18 +115,6 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
struct ximage_buffer *xbuf = &xsurf->buffers[which];
pipe_texture_reference(&xbuf->texture, NULL);
-
- if (xbuf->shm_info) {
- if (xbuf->xshm_attached)
- XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
- if (xbuf->shm_info->shmaddr != (void *) -1)
- shmdt(xbuf->shm_info->shmaddr);
- if (xbuf->shm_info->shmid != -1)
- shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
-
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->shmid = -1;
- }
}
static boolean
@@ -156,40 +138,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- if (xbuf->shm_info) {
- struct pipe_buffer *pbuf;
- unsigned stride, size;
- void *addr = NULL;
-
- stride = util_format_get_stride(xsurf->color_format, xsurf->width);
- /* alignment should depend on visual? */
- stride = align(stride, 4);
- size = stride * xsurf->height;
-
- /* create and attach shm object */
- xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
- if (xbuf->shm_info->shmid != -1) {
- xbuf->shm_info->shmaddr =
- shmat(xbuf->shm_info->shmid, NULL, 0);
- if (xbuf->shm_info->shmaddr != (void *) -1) {
- if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
- addr = xbuf->shm_info->shmaddr;
- xbuf->xshm_attached = TRUE;
- }
- }
- }
-
- if (addr) {
- pbuf = screen->user_buffer_create(screen, addr, size);
- if (pbuf) {
- xbuf->texture =
- screen->texture_blanket(screen, &templ, &stride, pbuf);
- pipe_buffer_reference(&pbuf, NULL);
- }
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+ switch (which) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ break;
+ default:
+ break;
}
}
- else {
- xbuf->texture = screen->texture_create(screen, &templ);
+ xbuf->texture = screen->texture_create(screen, &templ);
+ if (xbuf->texture) {
+ xbuf->xdraw.visual = xsurf->visual.visual;
+ xbuf->xdraw.depth = xsurf->visual.depth;
+ xbuf->xdraw.drawable = xsurf->drawable;
}
/* clean up the buffer if allocation failed */
@@ -269,18 +236,10 @@ ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
new_valid = 0x0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
/* reallocate the texture */
if (!ximage_surface_alloc_buffer(&xsurf->base, att))
break;
- /* update ximage */
- if (xbuf->ximage) {
- xbuf->ximage->width = xsurf->width;
- xbuf->ximage->height = xsurf->height;
- }
-
new_valid |= (1 << att);
if (buffer_mask == new_valid)
break;
@@ -300,43 +259,22 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xbuf = &xsurf->buffers[which];
struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_transfer *transfer;
+ struct pipe_surface *psurf;
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return TRUE;
- assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+ assert(xsurf->drawable && xbuf->texture);
- transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!transfer)
+ /* what's the cost of surface creation? */
+ psurf = screen->get_tex_surface(screen,
+ xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
return FALSE;
- xbuf->ximage->bytes_per_line = transfer->stride;
- xbuf->ximage->data = screen->transfer_map(screen, transfer);
- if (!xbuf->ximage->data) {
- screen->tex_transfer_destroy(transfer);
- return FALSE;
- }
-
+ screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
- if (xbuf->shm_info)
- XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
- else
- XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
-
- xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, transfer);
-
- /*
- * softpipe allows the pipe transfer to be re-used, but we don't want to
- * rely on that behavior.
- */
- screen->tex_transfer_destroy(transfer);
-
- XSync(xsurf->xdpy->dpy, FALSE);
+ pipe_surface_reference(&psurf, NULL);
return TRUE;
}
@@ -364,7 +302,8 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
boolean ret;
/* display the back buffer first */
- ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
+ ret = ximage_surface_draw_buffer(&xsurf->base,
+ NATIVE_ATTACHMENT_BACK_LEFT);
/* force buffers to be updated in next validation call */
xsurf->server_stamp++;
ximage_surface_notify_invalid(&xsurf->base);
@@ -372,13 +311,12 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
- /* skip swapping so that the front buffer is allocated only when needed */
- if (!xfront->texture)
- return ret;
-
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
+ /* skip swapping unless there is a front buffer */
+ if (xfront->texture) {
+ xtmp = *xfront;
+ *xfront = *xback;
+ *xback = xtmp;
+ }
return ret;
}
@@ -433,18 +371,9 @@ ximage_surface_destroy(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
int i;
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
ximage_surface_free_buffer(&xsurf->base, i);
- /* xbuf->shm_info is owned by xbuf->ximage? */
- if (xbuf->ximage) {
- XDestroyImage(xbuf->ximage);
- xbuf->ximage = NULL;
- }
- }
- if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
- XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
free(xsurf);
}
@@ -457,7 +386,6 @@ ximage_display_create_surface(struct native_display *ndpy,
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
- int i;
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
@@ -471,52 +399,8 @@ ximage_display_create_surface(struct native_display *ndpy,
if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
-
- xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
- if (!xsurf->gc) {
- free(xsurf);
- return NULL;
- }
-
/* initialize the geometry */
ximage_surface_update_buffers(&xsurf->base, 0x0);
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
-
- if (xdpy->use_xshm) {
- xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
- if (xbuf->shm_info) {
- /* initialize shm info */
- xbuf->shm_info->shmid = -1;
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->readOnly = TRUE;
-
- xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, NULL,
- xbuf->shm_info,
- 0, 0);
- }
- }
- else {
- xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 8, /* bitmap_pad */
- 0); /* bytes_per_line */
- }
-
- if (!xbuf->ximage) {
- XFreeGC(xdpy->dpy, xsurf->gc);
- free(xsurf);
- return NULL;
- }
- }
}
xsurf->base.destroy = ximage_surface_destroy;
@@ -727,7 +611,6 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
- free(xdpy->winsys);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
@@ -735,10 +618,63 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy);
}
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try.
+ *
+ * Long term, want to avoid having global #defines for things like
+ * GALLIUM_LLVMPIPE, 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.
+ */
+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. Use
+ * llvmpipe if it is available.
+ */
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+
struct native_display *
x11_create_ximage_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
- boolean use_xshm)
+ struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
@@ -756,6 +692,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
xdpy->own_dpy = TRUE;
}
+ xdpy->event_handler = event_handler;
+
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
@@ -763,13 +701,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
return NULL;
}
- xdpy->event_handler = event_handler;
-
- xdpy->use_xshm =
- (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
-
- xdpy->winsys = create_sw_winsys();
- xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+ xdpy->base.screen = swrast_xlib_create_screen(xdpy->dpy);
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
deleted file mode 100644
index 33328aadf2..0000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * Totally software-based winsys layer.
- * Note that the one winsys function that we can't implement here
- * is flush_frontbuffer().
- * Whoever uses this code will have to provide that.
- *
- * Authors: Brian Paul
- */
-
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "sw_winsys.h"
-
-
-
-/** Subclass of pipe_winsys */
-struct sw_pipe_winsys
-{
- struct pipe_winsys Base;
- /* no extra fields for now */
-};
-
-
-/** subclass of pipe_buffer */
-struct sw_pipe_buffer
-{
- struct pipe_buffer Base;
- boolean UserBuffer; /** Is this a user-space buffer? */
- void *Data;
- void *Mapped;
-};
-
-
-/** cast wrapper */
-static INLINE struct sw_pipe_buffer *
-sw_pipe_buffer(struct pipe_buffer *b)
-{
- return (struct sw_pipe_buffer *) b;
-}
-
-
-static const char *
-get_name(struct pipe_winsys *pws)
-{
- return "software";
-}
-
-
-/** Create new pipe_buffer and allocate storage of given size */
-static struct pipe_buffer *
-buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.alignment = alignment;
- buffer->Base.usage = usage;
- buffer->Base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->Data = align_malloc(size, MAX2(alignment, 16));
-
- return &buffer->Base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.size = bytes;
- buffer->UserBuffer = TRUE;
- buffer->Data = ptr;
-
- return &buffer->Base;
-}
-
-
-static void *
-buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = buffer->Data;
- return buffer->Mapped;
-}
-
-
-static void
-buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = NULL;
-}
-
-
-static void
-buffer_destroy(struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
-
- if (buffer->Data && !buffer->UserBuffer) {
- align_free(buffer->Data);
- buffer->Data = NULL;
- }
-
- free(buffer);
-}
-
-
-static struct pipe_buffer *
-surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- /* no-op */
-}
-
-
-static int
-fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-static int
-fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-/**
- * Create/return a new pipe_winsys object.
- */
-struct pipe_winsys *
-create_sw_winsys(void)
-{
- struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
- if (!ws)
- return NULL;
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->Base.buffer_create = buffer_create;
- ws->Base.user_buffer_create = user_buffer_create;
- ws->Base.buffer_map = buffer_map;
- ws->Base.buffer_unmap = buffer_unmap;
- ws->Base.buffer_destroy = buffer_destroy;
-
- ws->Base.surface_buffer_create = surface_buffer_create;
-
- ws->Base.fence_reference = fence_reference;
- ws->Base.fence_signalled = fence_signalled;
- ws->Base.fence_finish = fence_finish;
-
- ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
-
- ws->Base.get_name = get_name;
-
- return &ws->Base;
-}
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index fa96df357d..bb20235150 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -13,8 +13,6 @@ if env['platform'] == 'linux' \
'#/src/mesa/main',
])
- env.Append(CPPDEFINES = ['USE_XSHM'])
-
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
source = [
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 08bf624b5c..2454585850 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -689,7 +689,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
int desiredVisualID = -1;
int numAux = 0;
- xmesa_init();
+ xmesa_init( dpy );
parselist = list;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 217bdeff75..f4d7133d2f 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -35,10 +35,6 @@
* corner of the window. Therefore, most drawing functions in this
* file have to flip Y coordinates.
*
- * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
- * in support for the MIT Shared Memory extension. If enabled, when you
- * use an Ximage for the back buffer in double buffered mode, the "swap"
- * operation will be faster. You must also link with -lXext.
*
* Byte swapping: If the Mesa host and the X display use a different
* byte order then there's some trickiness to be aware of when using
@@ -67,11 +63,7 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#include "trace/tr_texture.h"
-
-#include "xm_winsys.h"
+#include "xm_public.h"
#include <GL/glx.h>
@@ -91,7 +83,6 @@ void xmesa_set_driver( const struct xm_driver *templ )
*/
pipe_mutex _xmesa_lock;
-static struct pipe_screen *_screen = NULL;
static struct pipe_screen *screen = NULL;
@@ -111,41 +102,6 @@ static int host_byte_order( void )
}
-/**
- * Check if the X Shared Memory extension is available.
- * Return: 0 = not available
- * 1 = shared XImage support available
- * 2 = shared Pixmap support available also
- */
-int xmesa_check_for_xshm( Display *display )
-{
-#if defined(USE_XSHM)
- int major, minor, ignore;
- Bool pixmaps;
-
- if (getenv("SP_NO_RAST"))
- return 0;
-
- if (getenv("MESA_NOSHM")) {
- return 0;
- }
-
- if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
- if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
- return (pixmaps==True) ? 2 : 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
- }
-#else
- /* No XSHM support */
- return 0;
-#endif
-}
/**
@@ -242,7 +198,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
pipe_mutex_lock(_xmesa_lock);
XSync(b->xm_visual->display, 0); /* added for Chromium */
- stat = get_drawable_size(dpy, b->drawable, width, height);
+ stat = get_drawable_size(dpy, b->ws.drawable, width, height);
pipe_mutex_unlock(_xmesa_lock);
if (!stat) {
@@ -397,7 +353,9 @@ create_xmesa_buffer(Drawable d, BufferType type,
if (!b)
return NULL;
- b->drawable = d;
+ b->ws.drawable = d;
+ b->ws.visual = vis->visinfo->visual;
+ b->ws.depth = vis->visinfo->depth;
b->xm_visual = vis;
b->type = type;
@@ -422,18 +380,6 @@ create_xmesa_buffer(Drawable d, BufferType type,
(void *) b);
fb = &b->stfb->Base;
- /*
- * Create scratch XImage for xmesa_display_surface()
- */
- b->tempImage = XCreateImage(vis->display,
- vis->visinfo->visual,
- vis->visinfo->depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 32, /* bitmap_pad */
- 0); /* bytes_per_line */
-
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
@@ -490,16 +436,11 @@ xmesa_free_buffer(XMesaBuffer buffer)
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
- b->drawable = 0;
-
- buffer->tempImage->data = NULL;
- XDestroyImage(buffer->tempImage);
+ b->ws.drawable = 0;
/* Unreference. If count = zero we'll really delete the buffer */
_mesa_reference_framebuffer(&fb, NULL);
- XFreeGC(b->xm_visual->display, b->gc);
-
free(buffer);
return;
@@ -576,21 +517,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
}
- if (b && window) {
- /* these should have been set in create_xmesa_buffer */
- ASSERT(b->drawable == window);
-
- /* Setup for single/double buffering */
- if (v->mesa_visual.doubleBufferMode) {
- /* Double buffered */
- b->shm = xmesa_check_for_xshm( v->display );
- }
-
- /* X11 graphics context */
- b->gc = XCreateGC( v->display, window, 0, NULL );
- XSetFunction( v->display, b->gc, GXcopy );
- }
-
return GL_TRUE;
}
@@ -673,7 +599,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
- xmesa_init();
+ xmesa_init( display );
/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
@@ -773,13 +699,12 @@ void XMesaDestroyVisual( XMesaVisual v )
* Do one-time initializations.
*/
void
-xmesa_init(void)
+xmesa_init( Display *display )
{
static GLboolean firstTime = GL_TRUE;
if (firstTime) {
pipe_mutex_init(_xmesa_lock);
- _screen = driver.create_pipe_screen();
- screen = trace_screen_create( _screen );
+ screen = driver.create_pipe_screen( display );
firstTime = GL_FALSE;
}
}
@@ -800,7 +725,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
GLcontext *mesaCtx;
uint pf;
- xmesa_init();
+ xmesa_init( v->display );
/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
@@ -1095,7 +1020,8 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
- st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
+ st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb,
+ &drawBuffer->ws);
xmesa_check_and_update_buffer_size(c, drawBuffer);
if (readBuffer != drawBuffer)
@@ -1106,7 +1032,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
}
else {
/* Detach */
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
}
return GL_TRUE;
@@ -1149,13 +1075,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
if (frontLeftSurf) {
- if (_screen != screen) {
- struct trace_surface *tr_surf = trace_surface( frontLeftSurf );
- struct pipe_surface *surf = tr_surf->surface;
- frontLeftSurf = surf;
- }
-
- driver.display_surface(b, frontLeftSurf);
+ screen->flush_frontbuffer( screen,
+ frontLeftSurf,
+ &b->ws );
}
xmesa_check_and_update_buffer_size(NULL, b);
@@ -1203,7 +1125,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
for (b = XMesaBufferList; b; b = b->Next) {
- if (b->drawable == d && b->xm_visual->display == dpy) {
+ if (b->ws.drawable == d && b->xm_visual->display == dpy) {
return b;
}
}
@@ -1237,10 +1159,10 @@ void XMesaGarbageCollect( void )
next = b->Next;
if (b->xm_visual &&
b->xm_visual->display &&
- b->drawable &&
+ b->ws.drawable &&
b->type == WINDOW) {
XSync(b->xm_visual->display, False);
- if (!window_exists( b->xm_visual->display, b->drawable )) {
+ if (!window_exists( b->xm_visual->display, b->ws.drawable )) {
/* found a dead window, free the ancillary info */
XMesaDestroyBuffer( b );
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 004cb260dc..de47064b41 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -62,15 +62,11 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "state_tracker/st_public.h"
#include "os/os_thread.h"
+#include "state_tracker/xlib_sw_winsys.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
-# ifdef USE_XSHM /* was SHM */
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-# endif
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
@@ -316,6 +312,7 @@ typedef enum {
*/
struct xmesa_buffer {
struct st_framebuffer *stfb;
+ struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
@@ -329,13 +326,6 @@ struct xmesa_buffer {
XImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
- GLuint shm; /* X Shared Memory extension status: */
- /* 0 = not available */
- /* 1 = XImage support available */
- /* 2 = Pixmap support available too */
-#if defined(USE_XSHM)
- XShmSegmentInfo shminfo;
-#endif
GC gc; /* scratch GC for span, line, tri drawing */
@@ -367,7 +357,7 @@ xmesa_buffer(GLframebuffer *fb)
extern void
-xmesa_init(void);
+xmesa_init(Display *dpy);
extern void
xmesa_delete_framebuffer(struct gl_framebuffer *fb);
@@ -397,8 +387,6 @@ xmesa_buffer_height(XMesaBuffer b)
return b->stfb->Base.Height;
}
-extern int
-xmesa_check_for_xshm(Display *display);
#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_public.h
index 4bd5b5c8d3..ac6a8ffb27 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_public.h
@@ -29,22 +29,14 @@
#ifndef XM_WINSYS_H
#define XM_WINSYS_H
-struct pipe_context;
-struct pipe_screen;
-struct pipe_surface;
-struct xmesa_buffer;
-
+struct xm_driver;
+/* This is the driver interface required by the glx/xlib state tracker.
+ */
struct xm_driver {
-
- struct pipe_screen *(*create_pipe_screen)( void );
-
- void (*display_surface)( struct xmesa_buffer *,
- struct pipe_surface * );
-
+ struct pipe_screen *(*create_pipe_screen)( Display *display );
};
-
extern void
xmesa_set_driver( const struct xm_driver *driver );
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 527e065cd9..781f54bf2b 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -24,6 +24,7 @@ if 'python' in env['statetrackers']:
'ws2_32',
])
else:
+ env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY'])
env.Append(LIBS = [
'GL',
'X11',
@@ -33,31 +34,27 @@ if 'python' in env['statetrackers']:
'gallium.i',
'st_device.c',
'st_sample.c',
+ 'st_hardpipe_winsys.c',
+ 'st_softpipe_winsys.c',
]
- drivers = [
- trace
- ]
+ env.Prepend(LIBS = [
+ ws_null,
+ trace,
+ gallium,
+ ])
if 'llvmpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_LLVMPIPE'])
env.Tool('llvm')
- sources += ['st_llvmpipe_winsys.c']
- drivers += [llvmpipe]
- else:
- sources += ['st_softpipe_winsys.c']
- drivers += [softpipe]
-
- pyst = env.ConvenienceLibrary(
- target = 'pyst',
- source = sources,
- )
+ env.Prepend(LIBS = [llvmpipe])
+ if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_SOFTPIPE'])
+ env.Prepend(LIBS = [softpipe])
env['no_import_lib'] = 1
env.SharedLibrary(
target = '_gallium',
- source = [
- 'st_hardpipe_winsys.c',
- ],
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
+ source = sources,
)
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 3f36ccb621..5c44462e80 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -51,7 +51,7 @@ struct st_context {
void set_blend( const struct pipe_blend_state *state ) {
cso_set_blend($self->cso, state);
}
-
+
void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) {
cso_single_sampler($self->cso, index, state);
cso_single_sampler_done($self->cso);
@@ -222,9 +222,9 @@ struct st_context {
void set_vertex_elements(unsigned num)
{
$self->num_vertex_elements = num;
- $self->pipe->set_vertex_elements($self->pipe,
- $self->num_vertex_elements,
- $self->vertex_elements);
+ cso_set_vertex_elements($self->cso,
+ $self->num_vertex_elements,
+ $self->vertex_elements);
}
/*
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 45e7841750..335e8e7f0d 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -34,8 +34,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
+#include "trace/tr_public.h"
#include "st_device.h"
#include "st_winsys.h"
@@ -75,43 +74,34 @@ st_device_destroy(struct st_device *st_dev)
}
-static struct st_device *
-st_device_create_from_st_winsys(const struct st_winsys *st_ws)
+struct st_device *
+st_device_create(boolean hardware)
{
+ struct pipe_screen *screen;
struct st_device *st_dev;
-
- if(!st_ws->screen_create)
- return NULL;
-
+
+ if (hardware)
+ screen = st_hardware_screen_create();
+ else
+ screen = st_software_screen_create();
+
+ screen = trace_screen_create(screen);
+ if (!screen)
+ goto no_screen;
+
st_dev = CALLOC_STRUCT(st_device);
- if(!st_dev)
- return NULL;
+ if (!st_dev)
+ goto no_device;
pipe_reference_init(&st_dev->reference, 1);
- st_dev->st_ws = st_ws;
-
- st_dev->real_screen = st_ws->screen_create();
- if(!st_dev->real_screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
-
- st_dev->screen = trace_screen_create(st_dev->real_screen);
- if(!st_dev->screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
+ st_dev->screen = screen;
return st_dev;
-}
-
-struct st_device *
-st_device_create(boolean hardware) {
- if(hardware)
- return st_device_create_from_st_winsys(&st_hardpipe_winsys);
- else
- return st_device_create_from_st_winsys(&st_softpipe_winsys);
+no_device:
+ screen->destroy(screen);
+no_screen:
+ return NULL;
}
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index de9e0215d8..6ec7409b11 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -47,7 +47,8 @@ struct st_surface
};
-struct st_context {
+struct st_context
+{
struct st_device *st_dev;
struct pipe_context *pipe;
@@ -72,13 +73,11 @@ struct st_context {
};
-struct st_device {
+struct st_device
+{
/* FIXME: we also need to refcount for textures and surfaces... */
struct pipe_reference reference;
- const struct st_winsys *st_ws;
-
- struct pipe_screen *real_screen;
struct pipe_screen *screen;
};
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index a3110a19d5..b141177b79 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -54,11 +54,6 @@ static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
#ifdef PIPE_OS_WINDOWS
static INLINE boolean
@@ -207,16 +202,11 @@ st_hardpipe_load(void)
#endif
-static struct pipe_screen *
-st_hardpipe_screen_create(void)
+struct pipe_screen *
+st_hardware_screen_create(void)
{
if(st_hardpipe_load())
return pfnGetGalliumScreenMESA();
else
- return st_softpipe_winsys.screen_create();
+ return st_software_screen_create();
}
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &st_hardpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
deleted file mode 100644
index 5d83b5a9e1..0000000000
--- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************
- *
- * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Llvmpipe support.
- *
- * @author Jose Fonseca
- */
-
-
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "st_winsys.h"
-
-
-static boolean
-llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
- enum pipe_format format )
-{
- return FALSE;
-}
-
-
-static void *
-llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags )
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
-{
- assert(0);
-}
-
-
-static struct llvmpipe_displaytarget *
-llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride)
-{
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-st_llvmpipe_screen_create(void)
-{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if (!winsys)
- goto no_winsys;
-
- winsys->destroy = llvmpipe_ws_destroy;
- winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported;
- winsys->displaytarget_create = llvmpipe_ws_displaytarget_create;
- winsys->displaytarget_map = llvmpipe_ws_displaytarget_map;
- winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap;
- winsys->displaytarget_display = llvmpipe_ws_displaytarget_display;
- winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy;
-
- screen = llvmpipe_create_screen(winsys);
- if (!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
-}
-
-
-
-const struct st_winsys st_softpipe_winsys = {
- &st_llvmpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 81676bc3a4..985374190c 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -26,18 +26,47 @@
*
**************************************************************************/
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-#include "softpipe/sp_winsys.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "state_tracker/sw_winsys.h"
+#include "null/null_sw_winsys.h"
#include "st_winsys.h"
-const struct st_winsys st_softpipe_winsys = {
- &softpipe_create_screen_malloc
-};
+
+struct pipe_screen *
+st_software_screen_create(void)
+{
+ struct sw_winsys *ws;
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(HAVE_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(HAVE_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ ws = null_sw_create();
+ if(!ws)
+ return NULL;
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#ifdef HAVE_LLVMPIPE
+ if (strcmp(driver, "llvmpipe") == 0) {
+ screen = llvmpipe_create_screen(ws);
+ }
+#endif
+
+#ifdef HAVE_SOFTPIPE
+ if (strcmp(driver, "softpipe") == 0) {
+ screen = softpipe_create_screen(ws);
+ }
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index 0c7b6a200e..e1a99383a4 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -31,19 +31,13 @@
struct pipe_screen;
-struct pipe_context;
-struct st_winsys
-{
- struct pipe_screen *
- (*screen_create)(void);
-};
+struct pipe_screen *
+st_hardware_screen_create(void);
-
-extern const struct st_winsys st_softpipe_winsys;
-
-extern const struct st_winsys st_hardpipe_winsys;
+struct pipe_screen *
+st_software_screen_create(void);
#endif /* ST_WINSYS_H_ */
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 037d8dc911..7f04b2aa83 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -53,7 +53,7 @@ INCLUDE_DIRS = \
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 9c123a4cf9..7eb5ea1f07 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st,
/* draw */
if (buf) {
+ cso_set_vertex_elements(st->cso_context, 2, st->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index c06dbf5206..eef2c1eb87 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx,
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
velement.src_offset = 0;
velement.instance_divisor = 0;
velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
- velement.nr_components = COMPONENTS;
- pipe->set_vertex_elements(pipe, 1, &velement);
+ cso_set_vertex_elements(ctx->cso_context, 1, &velement);
/* draw */
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 05620efa9c..47e8b470a1 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -210,6 +210,7 @@ void renderer_draw_quad(struct renderer *r,
buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -248,6 +249,7 @@ void renderer_draw_texture(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -370,6 +372,7 @@ void renderer_copy_texture(struct renderer *ctx,
0.0f);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -535,6 +538,7 @@ void renderer_copy_surface(struct renderer *ctx,
(float) dstX1, (float) dstY1, z);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -587,6 +591,7 @@ void renderer_texture_quad(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 426bf9bc62..170391ec03 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -72,6 +72,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share)
{
struct vg_context *ctx;
+ unsigned i;
ctx = CALLOC_STRUCT(vg_context);
@@ -103,6 +104,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0;
+ for (i = 0; i < 2; i++) {
+ ctx->velems[i].src_offset = i * 4 * sizeof(float);
+ ctx->velems[i].instance_divisor = 0;
+ ctx->velems[i].vertex_buffer_index = 0;
+ ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index bc88c8d139..804e9e76d7 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -146,6 +146,7 @@ struct vg_context
struct vg_shader *clear_vs;
struct vg_shader *texture_vs;
struct pipe_buffer *vs_const_buffer;
+ struct pipe_vertex_element velems[2];
};
struct vg_object {
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index 57d3baad7f..ea5c2ce41f 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -376,12 +376,12 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb)
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read)
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle)
{
vg_set_current_context(st);
- if (st) {
+ if (st)
st->draw_buffer = draw;
- }
return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index c1196954a7..165a6b7a33 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -101,7 +101,8 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb);
PUBLIC
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read);
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle);
PUBLIC
struct vg_context *st_get_current(void);
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 05ccd5febc..1f11b649c3 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -226,7 +226,7 @@ DrvDeleteContext(
/* Unbind current if deleting current context. */
if (curctx == ctx)
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
st_destroy_context(ctx->st);
FREE(ctx);
@@ -317,7 +317,7 @@ stw_make_current(
}
if (hdc == NULL || dhglrc == 0) {
- return st_make_current( NULL, NULL, NULL );
+ return st_make_current( NULL, NULL, NULL, NULL );
}
pipe_mutex_lock( stw_dev->ctx_mutex );
@@ -352,7 +352,7 @@ stw_make_current(
/* pass to stw_flush_frontbuffer as context_private */
ctx->st->pipe->priv = hdc;
- if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc ))
goto fail;
success:
@@ -367,7 +367,7 @@ success:
fail:
if(fb)
stw_framebuffer_release(fb);
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 472a2a5379..ea300f27cb 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -33,11 +33,6 @@
#include "pipe/p_screen.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_device.h"
#include "stw_winsys.h"
#include "stw_pixelformat.h"
@@ -107,13 +102,10 @@ stw_init(const struct stw_winsys *stw_winsys)
if(stw_winsys->get_adapter_luid)
stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
-#ifdef DEBUG
- stw_dev->screen = trace_screen_create(screen);
- stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
-#else
stw_dev->screen = screen;
-#endif
-
+
+ /* XXX
+ */
stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->ctx_mutex );
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index a83841f6b7..2e9ba197df 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -48,10 +48,6 @@ struct stw_device
struct pipe_screen *screen;
-#ifdef DEBUG
- boolean trace_running;
-#endif
-
LUID AdapterLuid;
struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index 8dd63f124a..5ecbd8048d 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -31,11 +31,6 @@
#include "stw_winsys.h"
#include "stw_ext_gallium.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
struct pipe_screen * APIENTRY
wglGetGalliumScreenMESA(void)
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 02de21ccb2..4f1629de2f 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -34,11 +34,6 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_icd.h"
#include "stw_framebuffer.h"
#include "stw_device.h"
@@ -495,13 +490,6 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
surface = (struct pipe_surface *)data->pPrivateData;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
if(data->hSharedSurface != fb->hSharedSurface) {
if(fb->shared_surface) {
stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
@@ -563,13 +551,6 @@ stw_framebuffer_present_locked(HDC hdc,
else {
struct pipe_screen *screen = stw_dev->screen;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
stw_dev->stw_winsys->present( screen, surface, hdc );
stw_framebuffer_update(fb);
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index a428fa8d94..f60e9abb76 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -198,11 +198,11 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
if (!crtcp->cursor_tex) {
struct pipe_texture templat;
- unsigned pitch;
+ struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
@@ -210,13 +210,14 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
templat.width0 = 64;
templat.height0 = 64;
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
- ms->api->local_handle_from_texture(ms->api,
- ms->screen,
- crtcp->cursor_tex,
- &pitch,
- &crtcp->cursor_handle);
+ ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
+
+ crtcp->cursor_handle = whandle.handle;
}
transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 5fc85c0e98..f23e4c6cc7 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
- unsigned stride, handle;
+ struct winsys_handle whandle;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
@@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
+
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
@@ -128,7 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ PIPE_TEXTURE_USAGE_SHARED;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
@@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
- ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+
+ ms->screen->texture_get_handle(ms->screen, tex, &whandle);
- buffer->name = handle;
- buffer->pitch = stride;
+ buffer->name = whandle.handle;
+ buffer->pitch = whandle.stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index d7c67463d2..8ac5179545 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -994,8 +994,9 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride, fb_id;
struct pipe_texture *tex;
+ struct winsys_handle whandle;
+ unsigned fb_id;
int ret;
ms->noEvict = TRUE;
@@ -1006,10 +1007,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
if (!tex)
return FALSE;
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle))
goto err_destroy;
ret = drmModeAddFB(ms->fd,
@@ -1017,8 +1018,8 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- stride,
- handle,
+ whandle.stride,
+ whandle.handle,
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)\n",
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a242e02ee7..a7ffe3f499 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -789,7 +789,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+ priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT;
return 0;
}
@@ -805,7 +805,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ priv->flags |= PIPE_TEXTURE_USAGE_SHARED;
return 0;
}
@@ -943,7 +943,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
{
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT;
if (!priv)
return FALSE;
@@ -976,8 +976,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED;
return exa->scrn->texture_create(exa->scrn, &template);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 83b0d31e38..1eb926360b 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -68,6 +68,8 @@ renderer_draw(struct xorg_renderer *r)
if (buf) {
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
num_verts, /* verts */
@@ -92,6 +94,7 @@ renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state raster;
+ unsigned i;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
@@ -103,6 +106,14 @@ renderer_init_state(struct xorg_renderer *r)
raster.gl_rasterization_rules = 1;
cso_set_rasterizer(r->cso, &raster);
+ /* vertex elements state */
+ memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
+ for (i = 0; i < 3; i++) {
+ r->velems[i].src_offset = i * 4 * sizeof(float);
+ r->velems[i].instance_divisor = 0;
+ r->velems[i].vertex_buffer_index = 0;
+ r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
}
@@ -600,6 +611,8 @@ void renderer_draw_yuv(struct xorg_renderer *r,
if (buf) {
const int num_attribs = 2; /*pos + tex coord*/
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index af6aa0567d..3d00628719 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -28,6 +28,7 @@ struct xorg_renderer {
float buffer[BUF_SIZE];
int buffer_size;
+ struct pipe_vertex_element velems[3];
/* number of attributes per vertex for the current
* draw operation */
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 87d1dfaace..12d94e0c5c 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -106,7 +106,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
- template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_SHARED;
tex = vpipe->screen->texture_create(vpipe->screen, &template);
if (!tex)
diff --git a/src/gallium/targets/Makefile b/src/gallium/targets/Makefile
new file mode 100644
index 0000000000..a0bc5eb14f
--- /dev/null
+++ b/src/gallium/targets/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/Makefile
+TOP = ../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GALLIUM_TARGET_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/targets/SConscript b/src/gallium/targets/SConscript
new file mode 100644
index 0000000000..df62fc65fb
--- /dev/null
+++ b/src/gallium/targets/SConscript
@@ -0,0 +1,16 @@
+Import('*')
+
+#if env['dri']:
+# SConscript([
+# 'drm/SConscript',
+# ])
+
+if 'xlib' in env['winsys']:
+ SConscript([
+ 'libgl-xlib/SConscript',
+ ])
+
+if 'gdi' in env['winsys']:
+ SConscript([
+ 'libgl-gdi/SConscript',
+ ])
diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript
new file mode 100644
index 0000000000..57704440ce
--- /dev/null
+++ b/src/gallium/targets/libgl-gdi/SConscript
@@ -0,0 +1,51 @@
+#######################################################################
+# SConscript for gdi winsys
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#src/gallium/state_trackers/wgl',
+ ])
+
+ env.Append(LIBS = [
+ 'gdi32',
+ 'user32',
+ 'kernel32',
+ 'ws2_32',
+ ])
+
+ sources = []
+ drivers = []
+
+ if 'softpipe' in env['drivers']:
+ sources = ['gdi_softpipe_winsys.c']
+ drivers = [softpipe]
+
+ if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ sources = ['gdi_llvmpipe_winsys.c']
+ drivers = [llvmpipe]
+
+ if not sources or not drivers:
+ print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled'
+ Return()
+
+ if env['gcc']:
+ sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
+ else:
+ sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
+
+ drivers += [trace]
+
+ env['no_import_lib'] = 1
+
+ env.SharedLibrary(
+ target ='opengl32',
+ source = sources,
+ LIBS = wgl + ws_gdi + glapi + mesa + drivers + gallium + glsl + env['LIBS'],
+ )
diff --git a/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c b/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c
new file mode 100644
index 0000000000..29316a1ce2
--- /dev/null
+++ b/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include <windows.h>
+
+#include "stw_winsys.h"
+#include "gdi/gdi_sw_winsys.h"
+#include "llvmpipe/lp_texture.h"
+#include "llvmpipe/lp_screen.h"
+#include "llvmpipe/lp_public.h"
+
+
+static struct pipe_screen *
+gdi_llvmpipe_screen_create(void)
+{
+ static struct sw_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = gdi_create_sw_winsys();
+ if(!winsys)
+ goto no_winsys;
+
+ screen = llvmpipe_create_screen(winsys);
+ if(!screen)
+ goto no_screen;
+
+ return screen;
+
+no_screen:
+ winsys->destroy(winsys);
+no_winsys:
+ return NULL;
+}
+
+
+
+
+static void
+gdi_llvmpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
+{
+ /* This will fail if any interposing layer (trace, debug, etc) has
+ * been introduced between the state-trackers and llvmpipe.
+ *
+ * Ideally this would get replaced with a call to
+ * pipe_screen::flush_frontbuffer().
+ *
+ * Failing that, it may be necessary for intervening layers to wrap
+ * other structs such as this stw_winsys as well...
+ */
+ gdi_sw_display(llvmpipe_screen(screen)->winsys,
+ llvmpipe_texture(surface->texture)->dt,
+ hDC);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+ &gdi_llvmpipe_screen_create,
+ &gdi_llvmpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ stw_init(&stw_winsys);
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_DETACH:
+ stw_cleanup_thread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ stw_cleanup_thread();
+ stw_cleanup();
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c b/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c
new file mode 100644
index 0000000000..dfe60195d9
--- /dev/null
+++ b/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include <windows.h>
+
+#include "stw_winsys.h"
+#include "gdi/gdi_sw_winsys.h"
+#include "softpipe/sp_texture.h"
+#include "softpipe/sp_screen.h"
+#include "softpipe/sp_public.h"
+
+
+static struct pipe_screen *
+gdi_softpipe_screen_create(void)
+{
+ static struct sw_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = gdi_create_sw_winsys();
+ if(!winsys)
+ goto no_winsys;
+
+ screen = softpipe_create_screen(winsys);
+ if(!screen)
+ goto no_screen;
+
+ return screen;
+
+no_screen:
+ winsys->destroy(winsys);
+no_winsys:
+ return NULL;
+}
+
+
+
+
+static void
+gdi_softpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
+{
+ /* This will fail if any interposing layer (trace, debug, etc) has
+ * been introduced between the state-trackers and softpipe.
+ *
+ * Ideally this would get replaced with a call to
+ * pipe_screen::flush_frontbuffer().
+ *
+ * Failing that, it may be necessary for intervening layers to wrap
+ * other structs such as this stw_winsys as well...
+ */
+ gdi_sw_display(softpipe_screen(screen)->winsys,
+ softpipe_texture(surface->texture)->dt,
+ hDC);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+ &gdi_softpipe_screen_create,
+ &gdi_softpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ stw_init(&stw_winsys);
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_DETACH:
+ stw_cleanup_thread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ stw_cleanup_thread();
+ stw_cleanup();
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/gallium/targets/libgl-xlib/Makefile b/src/gallium/targets/libgl-xlib/Makefile
new file mode 100644
index 0000000000..5a4e035c2e
--- /dev/null
+++ b/src/gallium/targets/libgl-xlib/Makefile
@@ -0,0 +1,100 @@
+# src/gallium/targets/libgl-xlib/Makefile
+
+# This makefile produces a "stand-alone" libGL.so which is based on
+# Xlib (no DRI HW acceleration)
+
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+
+GL_MAJOR = 1
+GL_MINOR = 5
+GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/state_trackers/glx/xlib \
+ -I$(TOP)/src/gallium/auxiliary
+
+DEFINES += \
+ -DGALLIUM_SOFTPIPE
+#-DGALLIUM_CELL will be defined by the config */
+
+XLIB_TARGET_SOURCES = \
+ xlib.c
+
+
+XLIB_TARGET_OBJECTS = $(XLIB_TARGET_SOURCES:.c=.o)
+
+
+# Note: CELL_SPU_LIB is only defined for cell configs
+
+LIBS = \
+ $(GALLIUM_DRIVERS) \
+ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
+ $(TOP)/src/gallium/winsys/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/mesa/libglapi.a \
+ $(TOP)/src/mesa/libmesagallium.a \
+ $(GALLIUM_AUXILIARIES) \
+ $(CELL_SPU_LIB) \
+
+
+.SUFFIXES : .cpp
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
+
+
+
+default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ @ mkdir -p $(TOP)/$(LIB_DIR)/gallium
+
+# Make the libGL.so library
+$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_TARGET_OBJECTS) $(LIBS) Makefile
+ $(TOP)/bin/mklib -o $(GL_LIB) \
+ -linker "$(CC)" \
+ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
+ -install $(TOP)/$(LIB_DIR)/gallium \
+ $(MKLIB_OPTIONS) $(XLIB_TARGET_OBJECTS) \
+ -Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
+
+
+depend: $(XLIB_TARGET_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend # workaround oops on gutsy?!?
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_TARGET_SOURCES) \
+ > /dev/null 2>/dev/null
+
+
+install: default
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
+ @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
+ fi
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+ -rm -f *.o
+
+
+include depend
diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript
new file mode 100644
index 0000000000..efa7e797d1
--- /dev/null
+++ b/src/gallium/targets/libgl-xlib/SConscript
@@ -0,0 +1,69 @@
+#######################################################################
+# SConscript for xlib winsys
+
+Import('*')
+
+if env['platform'] != 'linux':
+ Return()
+
+if 'mesa' not in env['statetrackers']:
+ print 'warning: Mesa state tracker disabled: skipping build of xlib libGL.so'
+ Return()
+
+if env['dri']:
+ print 'warning: DRI enabled: skipping build of xlib libGL.so'
+ 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.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/mesa/main',
+ '#src/gallium/state_trackers/glx/xlib',
+])
+
+env.Append(CPPDEFINES = ['USE_XSHM'])
+
+env.Prepend(LIBS = [
+ st_xlib,
+ ws_xlib,
+ trace,
+ identity,
+ glapi,
+ mesa,
+ glsl,
+ gallium,
+])
+
+sources = [
+ '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])
+
+if 'cell' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_CELL')
+ env.Prepend(LIBS = [cell])
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+libgl = env.SharedLibrary(
+ target ='GL',
+ source = sources,
+)
+
+if not env['dri']:
+ # Only install this libGL.so if DRI not enabled
+ env.InstallSharedLibrary(libgl, version=(1, 5))
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c
index 67617a470d..05dc8db57d 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/targets/libgl-xlib/xlib.c
@@ -30,66 +30,88 @@
* Authors:
* Keith Whitwell
*/
-
-#include "xlib.h"
-#include "xm_winsys.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-/* Todo, replace all this with callback-structs provided by the
- * individual implementations.
- */
-
-enum mode {
- MODE_CELL,
- MODE_LLVMPIPE,
- MODE_SOFTPIPE
-};
+#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 "xm_public.h"
/* advertise OpenGL support */
PUBLIC const int st_api_OpenGL = 1;
-static enum mode get_mode()
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try. Long term, want
+ * to avoid having global #defines for things like GALLIUM_LLVMPIPE,
+ * 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.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
{
-#ifdef GALLIUM_CELL
- if (!getenv("GALLIUM_NOCELL"))
- return MODE_CELL;
+ 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:
+ */
+#if defined(GALLIUM_CELL)
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_CELL", FALSE))
+ screen = cell_create_screen( winsys );
#endif
#if defined(GALLIUM_LLVMPIPE)
- return MODE_LLVMPIPE;
-#else
- return MODE_SOFTPIPE;
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen( winsys );
#endif
+
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
}
-static void _init( void ) __attribute__((constructor));
+struct xm_driver xlib_driver =
+{
+ .create_pipe_screen = swrast_xlib_create_screen,
+};
+
+/* Build the rendering stack.
+ */
+static void _init( void ) __attribute__((constructor));
static void _init( void )
{
- enum mode xlib_mode = get_mode();
-
- switch (xlib_mode) {
- case MODE_CELL:
-#if defined(GALLIUM_CELL)
- xmesa_set_driver( &xlib_cell_driver );
-#endif
- break;
- case MODE_LLVMPIPE:
-#if defined(GALLIUM_LLVMPIPE)
- xmesa_set_driver( &xlib_llvmpipe_driver );
-#endif
- break;
- case MODE_SOFTPIPE:
-#if defined(GALLIUM_SOFTPIPE)
- xmesa_set_driver( &xlib_softpipe_driver );
-#endif
- break;
- default:
- assert(0);
- break;
- }
+ /* Initialize the xlib libgl code, pass in the winsys:
+ */
+ xmesa_set_driver( &xlib_driver );
}
diff --git a/src/gallium/winsys/drm/Makefile.egl b/src/gallium/winsys/drm/Makefile.egl
index 8363de6e97..bc5dd3a53b 100644
--- a/src/gallium/winsys/drm/Makefile.egl
+++ b/src/gallium/winsys/drm/Makefile.egl
@@ -13,7 +13,8 @@ EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
common_LIBS = -ldrm -lm -ldl
-x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a
+x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a \
+ $(TOP)/src/gallium/winsys/xlib/libws_xlib.a
x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
@@ -38,8 +39,10 @@ $(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/%.so: %.so
define mklib-egl
$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) $($(1)_ST) \
- $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS)
+ $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \
+ -Wl,--start-group $($(1)_ST) $(EGL_DRIVER_PIPES) \
+ $(GALLIUM_AUXILIARIES) -Wl,--end-group \
+ $($(1)_LIBS) $(EGL_DRIVER_LIBS)
endef
egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
index a061eef0be..21e82303f7 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
@@ -37,129 +37,6 @@ i965_libdrm_get_device_id(unsigned int *device_id)
fclose(file);
}
-static struct i965_libdrm_buffer *
-i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
- const char* name, unsigned handle)
-{
- struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
- uint32_t swizzle = 0;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!buf)
- return NULL;
- pipe_reference_init(&buf->base.reference, 1);
- buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
- buf->base.size = buf->bo->size;
- buf->base.sws = &idws->base;
- buf->flinked = TRUE;
- buf->flink = handle;
-
-
- if (!buf->bo)
- goto err;
-
- drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
- if (buf->tiling != 0)
- buf->map_gtt = TRUE;
-
- return buf;
-
-err:
- FREE(buf);
- return NULL;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_texture *
-i965_libdrm_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *template,
- const char* name,
- unsigned pitch,
- unsigned handle)
-{
- /* XXX: this is silly -- there should be a way to get directly from
- * the "drm_api" struct to ourselves, without peering into
- * unrelated code:
- */
- struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
- struct i965_libdrm_buffer *buffer;
-
- if (BRW_DUMP)
- debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
- name, pitch, handle);
-
- buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
- if (!buffer)
- return NULL;
-
- return brw_texture_blanket_winsys_buffer(screen, template, pitch,
- buffer->tiling,
- &buffer->base);
-}
-
-
-static boolean
-i965_libdrm_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct i965_libdrm_buffer *buf = NULL;
- struct brw_winsys_buffer *buffer = NULL;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
- return FALSE;
-
- buf = i965_libdrm_buffer(buffer);
- if (!buf->flinked) {
- if (drm_intel_bo_flink(buf->bo, &buf->flink))
- return FALSE;
- buf->flinked = TRUE;
- }
-
- *handle = buf->flink;
-
- if (BRW_DUMP)
- debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
-
- return TRUE;
-}
-
-static boolean
-i965_libdrm_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct brw_winsys_buffer *buffer = NULL;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
- return FALSE;
-
- *handle = i965_libdrm_buffer(buffer)->bo->handle;
-
- if (BRW_DUMP)
- debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
-
- return TRUE;
-}
-
static void
i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
{
@@ -225,9 +102,6 @@ struct drm_api i965_libdrm_api =
{
.name = "i965",
.create_screen = i965_libdrm_create_screen,
- .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
- .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
- .local_handle_from_texture = i965_libdrm_local_handle_from_texture,
.destroy = destroy,
};
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
index 07be1df87f..33a17496b2 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
+++ b/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
@@ -1,4 +1,5 @@
+#include "state_tracker/drm_api.h"
#include "i965_drm_winsys.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
@@ -122,6 +123,78 @@ err:
return PIPE_ERROR_OUT_OF_MEMORY;
}
+static enum pipe_error
+i965_libdrm_bo_from_handle(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tile,
+ struct brw_winsys_buffer **bo_out)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+ struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ uint32_t swizzle = 0;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, "FROM_HANDLE", whandle->handle);
+ buf->base.size = buf->bo->size;
+ buf->base.sws = &idws->base;
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
+ if (buf->tiling != 0)
+ buf->map_gtt = TRUE;
+
+ *tile = buf->tiling;
+ *stride = whandle->stride;
+
+ *bo_out = &buf->base;
+ return PIPE_OK;
+
+err:
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static enum pipe_error
+i965_libdrm_bo_get_handle(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return PIPE_ERROR_BAD_INPUT;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return PIPE_ERROR_BAD_INPUT;
+ }
+
+ whandle->stride = stride;
+ return PIPE_OK;
+}
+
static void
i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
{
@@ -415,6 +488,8 @@ void
i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
{
idws->base.bo_alloc = i965_libdrm_bo_alloc;
+ idws->base.bo_from_handle = i965_libdrm_bo_from_handle;
+ idws->base.bo_get_handle = i965_libdrm_bo_get_handle;
idws->base.bo_destroy = i965_libdrm_bo_destroy;
idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
idws->base.bo_exec = i965_libdrm_bo_exec;
diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
index 74501eeb16..063e9f600b 100644
--- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
+++ b/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
@@ -38,7 +38,7 @@
#include "pipe/p_error.h"
#include "pipe/p_context.h"
-#include "xm_winsys.h"
+#include "xm_public.h"
#include "i965/brw_winsys.h"
#include "i965/brw_screen.h"
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
index 377ed25513..e3b980a832 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -38,99 +38,6 @@ intel_drm_get_device_id(unsigned int *device_id)
fclose(file);
}
-static struct intel_buffer *
-intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
- const char* name, unsigned handle)
-{
- struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
- uint32_t tile = 0, swizzle = 0;
-
- if (!buf)
- return NULL;
-
- buf->magic = 0xDEAD1337;
- buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
- buf->flinked = TRUE;
- buf->flink = handle;
-
- if (!buf->bo)
- goto err;
-
- drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
- if (tile != INTEL_TILE_NONE)
- buf->map_gtt = TRUE;
-
- return (struct intel_buffer *)buf;
-
-err:
- FREE(buf);
- return NULL;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_texture *
-intel_drm_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char* name,
- unsigned pitch,
- unsigned handle)
-{
- struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
- struct intel_buffer *buffer;
-
- buffer = intel_drm_buffer_from_handle(idws, name, handle);
- if (!buffer)
- return NULL;
-
- return i915_texture_blanket_intel(screen, templ, pitch, buffer);
-}
-
-static boolean
-intel_drm_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct intel_drm_buffer *buf = NULL;
- struct intel_buffer *buffer = NULL;
- if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
- return FALSE;
-
- buf = intel_drm_buffer(buffer);
- if (!buf->flinked) {
- if (drm_intel_bo_flink(buf->bo, &buf->flink))
- return FALSE;
- buf->flinked = TRUE;
- }
-
- *handle = buf->flink;
-
- return TRUE;
-}
-
-static boolean
-intel_drm_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct intel_buffer *buffer = NULL;
- if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
- return FALSE;
-
- *handle = intel_drm_buffer(buffer)->bo->handle;
-
- return TRUE;
-}
-
static void
intel_drm_winsys_destroy(struct intel_winsys *iws)
{
@@ -192,9 +99,6 @@ struct drm_api intel_drm_api =
.name = "i915",
.driver_name = "i915",
.create_screen = intel_drm_create_screen,
- .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
- .shared_handle_from_texture = intel_drm_shared_handle_from_texture,
- .local_handle_from_texture = intel_drm_local_handle_from_texture,
.destroy = destroy,
};
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
index ac4dd6e00e..cb4f92a3b1 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
@@ -1,4 +1,5 @@
+#include "state_tracker/drm_api.h"
#include "intel_drm_winsys.h"
#include "util/u_memory.h"
@@ -52,6 +53,66 @@ err:
return NULL;
}
+static struct intel_buffer *
+intel_drm_buffer_from_handle(struct intel_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);
+ uint32_t tile = 0, swizzle = 0;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, "gallium3d_from_handle", whandle->handle);
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
+ if (tile != INTEL_TILE_NONE)
+ buf->map_gtt = TRUE;
+
+ *stride = whandle->stride;
+
+ return (struct intel_buffer *)buf;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+static boolean
+intel_drm_buffer_get_handle(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return FALSE;
+ }
+
+ whandle->stride = stride;
+ return TRUE;
+}
+
static int
intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
struct intel_buffer *buffer,
@@ -146,6 +207,8 @@ void
intel_drm_winsys_init_buffer_functions(struct intel_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;
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 0d05f316c4..21517b4bb5 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -21,9 +21,10 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_surface *ps = NULL;
struct pipe_texture *pt = NULL;
struct pipe_texture tmpl;
+ struct winsys_handle whandle;
memset(&tmpl, 0, sizeof(tmpl));
- tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY;
+ tmpl.tex_usage = PIPE_TEXTURE_USAGE_SCANOUT;
tmpl.target = PIPE_TEXTURE_2D;
tmpl.last_level = 0;
tmpl.depth0 = 1;
@@ -31,8 +32,11 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
tmpl.width0 = width;
tmpl.height0 = height;
- pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
- "front buffer", pitch, handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = pitch;
+ whandle.handle = handle;
+
+ pt = pscreen->texture_from_handle(pscreen, &tmpl, &whandle);
if (!pt)
return NULL;
@@ -142,74 +146,10 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return nvws->pscreen;
}
-static struct pipe_texture *
-nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *templ, const char *name,
- unsigned stride, unsigned handle)
-{
- struct nouveau_device *dev = nouveau_screen(pscreen)->device;
- struct pipe_texture *pt;
- struct pipe_buffer *pb;
- int ret;
-
- pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
- if (!pb)
- return NULL;
-
- ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1));
- if (ret) {
- debug_printf("%s: ref name 0x%08x failed with %d\n",
- __func__, handle, ret);
- FREE(pb);
- return NULL;
- }
-
- pipe_reference_init(&pb->reference, 1);
- pb->screen = pscreen;
- pb->alignment = 0;
- pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ_WRITE;
- pb->size = nouveau_bo(pb)->size;
- pt = pscreen->texture_blanket(pscreen, templ, &stride, pb);
- pipe_buffer_reference(&pb, NULL);
- return pt;
-}
-
-static boolean
-nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *pt, unsigned *stride,
- unsigned *handle)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- if (!mt || !mt->bo)
- return false;
-
- return nouveau_bo_handle_get(mt->bo, handle) == 0;
-}
-
-static boolean
-nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *pt, unsigned *stride,
- unsigned *handle)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- if (!mt || !mt->bo)
- return false;
-
- *handle = mt->bo->handle;
- *stride = util_format_get_stride(mt->base.format, mt->base.width0);
- return true;
-}
-
struct drm_api drm_api_hooks = {
.name = "nouveau",
.driver_name = "nouveau",
.create_screen = nouveau_drm_create_screen,
- .texture_from_shared_handle = nouveau_drm_pt_from_name,
- .shared_handle_from_texture = nouveau_drm_name_from_pt,
- .local_handle_from_texture = nouveau_drm_handle_from_pt,
};
struct drm_api *
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index e5c6919933..daa032af6f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -264,6 +264,75 @@ static int radeon_fence_finish(struct pipe_winsys *ws,
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;
@@ -298,6 +367,8 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
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;
return radeon_ws;
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index e817a26da6..97edb6a47e 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -148,124 +148,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
}
}
-
-boolean radeon_buffer_from_texture(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride)
-{
- /* XXX fix this */
- return r300_get_texture_buffer(screen, texture, buffer, stride);
-}
-
-/* Create a buffer from a handle. */
-/* XXX what's up with name? */
-struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
- struct pipe_screen* screen,
- const char* name,
- unsigned handle)
-{
- struct radeon_bo_manager* bom =
- ((struct radeon_winsys*)screen->winsys)->priv->bom;
- struct radeon_pipe_buffer* radeon_buffer;
- struct radeon_bo* bo = NULL;
-
- bo = radeon_bo_open(bom, 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;
- return &radeon_buffer->base;
-}
-
-static struct pipe_texture*
-radeon_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct pipe_buffer *buffer;
- struct pipe_texture *blanket;
-
- buffer = radeon_buffer_from_handle(api, screen, name, handle);
- if (!buffer) {
- return NULL;
- }
-
- blanket = screen->texture_blanket(screen, templ, &stride, buffer);
-
- pipe_buffer_reference(&buffer, NULL);
-
- return blanket;
-}
-
-static boolean radeon_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
-{
- int retval, fd;
- struct drm_gem_flink flink;
- struct radeon_pipe_buffer* radeon_buffer;
- struct pipe_buffer *buffer = NULL;
-
- if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
- return FALSE;
- }
-
- radeon_buffer = (struct radeon_pipe_buffer*)buffer;
- if (!radeon_buffer->flinked) {
- fd = ((struct radeon_winsys*)screen->winsys)->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;
- }
-
- *handle = radeon_buffer->flink;
- return TRUE;
-}
-
-static boolean radeon_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct pipe_buffer *buffer = NULL;
- if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
- return FALSE;
- }
-
- *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
-
- pipe_buffer_reference(&buffer, NULL);
-
- return TRUE;
-}
-
static void radeon_drm_api_destroy(struct drm_api *api)
{
return;
@@ -275,9 +157,6 @@ struct drm_api drm_api_hooks = {
.name = "radeon",
.driver_name = "radeon",
.create_screen = radeon_create_screen,
- .texture_from_shared_handle = radeon_texture_from_shared_handle,
- .shared_handle_from_texture = radeon_shared_handle_from_texture,
- .local_handle_from_texture = radeon_local_handle_from_texture,
.destroy = radeon_drm_api_destroy,
};
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index f62a9b8048..78451b6f01 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -37,28 +37,6 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
-
-boolean radeon_buffer_from_texture(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride);
-
-struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
- struct pipe_screen* screen,
- const char* name,
- unsigned handle);
-
-boolean radeon_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle);
-
-boolean radeon_global_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle);
-
void radeon_destroy_drm_api(struct drm_api* api);
/* Guess at whether this chipset should use r300g.
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
index 4901080ca7..37eeb45979 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
@@ -56,6 +56,18 @@ struct radeon_winsys {
/* VRAM size. */
uint32_t vram_size;
+ /* Create a buffer from a winsys handle. */
+ struct pipe_buffer *(*buffer_from_handle)(struct radeon_winsys *winsys,
+ struct pipe_screen *screen,
+ struct winsys_handle *whandle,
+ unsigned *stride);
+
+ /* Get the handle from a buffer. */
+ boolean (*buffer_get_handle)(struct radeon_winsys *winsys,
+ struct pipe_buffer *buffer,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
/* Add a pipe_buffer to the list of buffer objects to validate. */
boolean (*add_buffer)(struct radeon_winsys* winsys,
struct pipe_buffer* pbuffer,
diff --git a/src/gallium/winsys/drm/radeon/python/README b/src/gallium/winsys/drm/radeon/python/README
deleted file mode 100644
index 339836a592..0000000000
--- a/src/gallium/winsys/drm/radeon/python/README
+++ /dev/null
@@ -1,15 +0,0 @@
-Python bindings for the radeon gallium driver.
-
-
-See gallium/src/gallium/state_trackers/python/README for more information.
-
-
-Build as:
-
- scons debug=1 statetrackers=python winsys=drm/radeon/python
-
-Run as:
-
- export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/winsys/drm/radeon/python:$PWD/build/linux-x86-debug/gallium/state_trackers/python
-
- python progs/gallium/python/samples/tri.py
diff --git a/src/gallium/winsys/drm/radeon/python/SConscript b/src/gallium/winsys/drm/radeon/python/SConscript
deleted file mode 100644
index 91cae98697..0000000000
--- a/src/gallium/winsys/drm/radeon/python/SConscript
+++ /dev/null
@@ -1,33 +0,0 @@
-import os.path
-
-Import('*')
-
-if env['platform'] == 'linux':
-
- env = env.Clone()
-
- env.Tool('python')
-
- env.ParseConfig('pkg-config --cflags --libs libdrm')
-
- env.Prepend(CPPPATH = [
- '#src/gallium/state_trackers/python',
- '../core',
- ])
-
- drivers = [
- softpipe,
- radeon,
- trace,
- ]
-
- sources = [
- 'radeon_hardpipe_winsys.c',
- 'xf86dri.c',
- ]
-
- env.SharedLibrary(
- target ='_gallium',
- source = sources,
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
- )
diff --git a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c
deleted file mode 100644
index fc63081a4c..0000000000
--- a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c
+++ /dev/null
@@ -1,132 +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.
- *
- **************************************************************************/
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <drm/drm.h>
-
-#include "pipe/p_screen.h"
-#include "pipe/p_context.h"
-
-#include "st_winsys.h"
-
-#include "radeon_winsys.h"
-
-#include "xf86dri.h"
-
-
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
-static struct pipe_screen *
-radeon_hardpipe_screen_create(void)
-{
- Display *dpy;
- Window rootWin;
- XWindowAttributes winAttr;
- int isCapable;
- int screen;
- char *driverName;
- char *curBusID;
- unsigned magic;
- int ddxDriverMajor;
- int ddxDriverMinor;
- int ddxDriverPatch;
- drm_handle_t sAreaOffset;
- int ret;
- int drmFD;
- drm_context_t hHWContext;
- XID id;
-
- dpy = XOpenDisplay(":0");
- if (!dpy) {
- fprintf(stderr, "Open Display Failed\n");
- return NULL;
- }
-
- screen = DefaultScreen(dpy);
- rootWin = RootWindow(dpy, screen);
- XGetWindowAttributes(dpy, rootWin, &winAttr);
-
- ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable);
- if (!ret || !isCapable) {
- fprintf(stderr, "No DRI on this display:sceen\n");
- goto error;
- }
-
- if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset,
- &curBusID)) {
- fprintf(stderr, "Could not open DRI connection.\n");
- goto error;
- }
-
- if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor,
- &ddxDriverMinor, &ddxDriverPatch,
- &driverName)) {
- fprintf(stderr, "Could not get DRI driver name.\n");
- goto error;
- }
-
- if ((drmFD = drmOpen(NULL, curBusID)) < 0) {
- perror("DRM Device could not be opened");
- goto error;
- }
-
- drmGetMagic(drmFD, &magic);
- if (!uniDRIAuthConnection(dpy, screen, magic)) {
- fprintf(stderr, "Could not get X server to authenticate us.\n");
- goto error;
- }
-
- if (!uniDRICreateContext(dpy, screen, winAttr.visual,
- &id, &hHWContext)) {
- fprintf(stderr, "Could not create DRI context.\n");
- goto error;
- }
-
- /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */
-
- return NULL;
-
-error:
- return NULL;
-}
-
-
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &radeon_hardpipe_screen_create,
-};
-
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.c b/src/gallium/winsys/drm/radeon/python/xf86dri.c
deleted file mode 100644
index 1736f1e54f..0000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dri.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NEED_REPLIES
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include "xf86dristr.h"
-
-static XExtensionInfo _xf86dri_info_data;
-static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
-static char xf86dri_extension_name[] = XF86DRINAME;
-
-#define uniDRICheckExtension(dpy,i,val) \
- XextCheckExtension (dpy, i, xf86dri_extension_name, val)
-
-/*****************************************************************************
- * *
- * private utility routines *
- * *
- *****************************************************************************/
-
-static int close_display(Display * dpy, XExtCodes * extCodes);
-static /* const */ XExtensionHooks xf86dri_extension_hooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- close_display, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- NULL, /* error_string */
-};
-
-static
-XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
- xf86dri_extension_name, &xf86dri_extension_hooks,
- 0, NULL)
-
- static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
-
-/*****************************************************************************
- * *
- * public XFree86-DRI Extension routines *
- * *
- *****************************************************************************/
-#if 0
-#include <stdio.h>
-#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg);
-#else
-#define TRACE(msg)
-#endif
- Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
- Display *dpy;
- int *event_basep, *error_basep;
-{
- XExtDisplayInfo *info = find_display(dpy);
-
- TRACE("QueryExtension...");
- if (XextHasExtension(info)) {
- *event_basep = info->codes->first_event;
- *error_basep = info->codes->first_error;
- TRACE("QueryExtension... return True");
- return True;
- } else {
- TRACE("QueryExtension... return False");
- return False;
- }
-}
-
-Bool
-uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
- Display *dpy;
- int *majorVersion;
- int *minorVersion;
- int *patchVersion;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIQueryVersionReply rep;
- xXF86DRIQueryVersionReq *req;
-
- TRACE("QueryVersion...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryVersion, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryVersion;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return False");
- return False;
- }
- *majorVersion = rep.majorVersion;
- *minorVersion = rep.minorVersion;
- *patchVersion = rep.patchVersion;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return True");
- return True;
-}
-
-Bool
-uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
- Display *dpy;
- int screen;
- Bool *isCapable;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIQueryDirectRenderingCapableReply rep;
- xXF86DRIQueryDirectRenderingCapableReq *req;
-
- TRACE("QueryDirectRenderingCapable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryDirectRenderingCapable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return False");
- return False;
- }
- *isCapable = rep.isCapable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return True");
- return True;
-}
-
-Bool
-uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
- Display *dpy;
- int screen;
- drm_handle_t *hSAREA;
- char **busIdString;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIOpenConnectionReply rep;
- xXF86DRIOpenConnectionReq *req;
-
- TRACE("OpenConnection...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIOpenConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIOpenConnection;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
-
- *hSAREA = rep.hSAREALow;
-#ifdef LONG64
- if (sizeof(drm_handle_t) == 8) {
- *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
- }
-#endif
- if (rep.length) {
- if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
- _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
- _XReadPad(dpy, *busIdString, rep.busIdStringLength);
- } else {
- *busIdString = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return True");
- return True;
-}
-
-Bool
-uniDRIAuthConnection(dpy, screen, magic)
- Display *dpy;
- int screen;
- drm_magic_t magic;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIAuthConnectionReq *req;
- xXF86DRIAuthConnectionReply rep;
-
- TRACE("AuthConnection...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIAuthConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIAuthConnection;
- req->screen = screen;
- req->magic = magic;
- rep.authenticated = 0;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return False");
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return True");
- return True;
-}
-
-Bool
-uniDRICloseConnection(dpy, screen)
- Display *dpy;
- int screen;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICloseConnectionReq *req;
-
- TRACE("CloseConnection...");
-
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICloseConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICloseConnection;
- req->screen = screen;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CloseConnection... return True");
- return True;
-}
-
-Bool
-uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
- ddxDriverMinorVersion, ddxDriverPatchVersion,
- clientDriverName)
- Display *dpy;
- int screen;
- int *ddxDriverMajorVersion;
- int *ddxDriverMinorVersion;
- int *ddxDriverPatchVersion;
- char **clientDriverName;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetClientDriverNameReply rep;
- xXF86DRIGetClientDriverNameReq *req;
-
- TRACE("GetClientDriverName...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetClientDriverName, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetClientDriverName;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
-
- *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
- *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
- *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
-
- if (rep.length) {
- if (!(*clientDriverName =
- (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
- _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
- _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
- } else {
- *clientDriverName = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return True");
- return True;
-}
-
-Bool
-uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
- Display *dpy;
- int screen;
- int configID;
- XID *context;
- drm_context_t *hHWContext;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICreateContextReply rep;
- xXF86DRICreateContextReq *req;
-
- TRACE("CreateContext...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateContext;
- req->visual = configID;
- req->screen = screen;
- *context = XAllocID(dpy);
- req->context = *context;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return False");
- return False;
- }
- *hHWContext = rep.hHWContext;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return True");
- return True;
-}
-
-Bool
-uniDRICreateContext(dpy, screen, visual, context, hHWContext)
- Display *dpy;
- int screen;
- Visual *visual;
- XID *context;
- drm_context_t *hHWContext;
-{
- return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
- context, hHWContext);
-}
-
-Bool
-uniDRIDestroyContext(Display * ndpy, int screen, XID context)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIDestroyContextReq *req;
-
- TRACE("DestroyContext...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyContext;
- req->screen = screen;
- req->context = context;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyContext... return True");
- return True;
-}
-
-Bool
-uniDRICreateDrawable(Display * ndpy, int screen,
- Drawable drawable, drm_drawable_t * hHWDrawable)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICreateDrawableReply rep;
- xXF86DRICreateDrawableReq *req;
-
- TRACE("CreateDrawable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateDrawable;
- req->screen = screen;
- req->drawable = drawable;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return False");
- return False;
- }
- *hHWDrawable = rep.hHWDrawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return True");
- return True;
-}
-
-Bool
-uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIDestroyDrawableReq *req;
-
- TRACE("DestroyDrawable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyDrawable;
- req->screen = screen;
- req->drawable = drawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyDrawable... return True");
- return True;
-}
-
-Bool
-uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects,
- drm_clip_rect_t ** pBackClipRects)
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetDrawableInfoReply rep;
- xXF86DRIGetDrawableInfoReq *req;
- int total_rects;
-
- TRACE("GetDrawableInfo...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDrawableInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDrawableInfo;
- req->screen = screen;
- req->drawable = drawable;
-
- if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
- *index = rep.drawableTableIndex;
- *stamp = rep.drawableTableStamp;
- *X = (int)rep.drawableX;
- *Y = (int)rep.drawableY;
- *W = (int)rep.drawableWidth;
- *H = (int)rep.drawableHeight;
- *numClipRects = rep.numClipRects;
- total_rects = *numClipRects;
-
- *backX = rep.backX;
- *backY = rep.backY;
- *numBackClipRects = rep.numBackClipRects;
- total_rects += *numBackClipRects;
-
-#if 0
- /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
- * backwards compatibility (Because of the >> 2 shift) but the fix
- * enables multi-threaded apps to work.
- */
- if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply) +
- total_rects * sizeof(drm_clip_rect_t)) +
- 3) & ~3) >> 2)) {
- _XEatData(dpy, rep.length);
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
-#endif
-
- if (*numClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numClipRects);
-
- *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
- if (*pClipRects)
- _XRead(dpy, (char *)*pClipRects, len);
- } else {
- *pClipRects = NULL;
- }
-
- if (*numBackClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
-
- *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
- if (*pBackClipRects)
- _XRead(dpy, (char *)*pBackClipRects, len);
- } else {
- *pBackClipRects = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return True");
- return True;
-}
-
-Bool
-uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
- fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
- Display *dpy;
- int screen;
- drm_handle_t *hFrameBuffer;
- int *fbOrigin;
- int *fbSize;
- int *fbStride;
- int *devPrivateSize;
- void **pDevPrivate;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetDeviceInfoReply rep;
- xXF86DRIGetDeviceInfoReq *req;
-
- TRACE("GetDeviceInfo...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDeviceInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDeviceInfo;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
-
- *hFrameBuffer = rep.hFrameBufferLow;
-#ifdef LONG64
- if (sizeof(drm_handle_t) == 8) {
- *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
- }
-#endif
-
- *fbOrigin = rep.framebufferOrigin;
- *fbSize = rep.framebufferSize;
- *fbStride = rep.framebufferStride;
- *devPrivateSize = rep.devPrivateSize;
-
- if (rep.length) {
- if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
- _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
- _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
- } else {
- *pDevPrivate = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return True");
- return True;
-}
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.h b/src/gallium/winsys/drm/radeon/python/xf86dri.h
deleted file mode 100644
index bf6de37d9d..0000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dri.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/**
- * \file xf86dri.h
- * Protocol numbers and function prototypes for DRI X protocol.
- *
- * \author Kevin E. Martin <martin@valinux.com>
- * \author Jens Owen <jens@tungstengraphics.com>
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-#ifndef _XF86DRI_H_
-#define _XF86DRI_H_
-
-#include <stdint.h>
-#include <X11/Xfuncproto.h>
-#include <drm/drm.h>
-
-#define X_XF86DRIQueryVersion 0
-#define X_XF86DRIQueryDirectRenderingCapable 1
-#define X_XF86DRIOpenConnection 2
-#define X_XF86DRICloseConnection 3
-#define X_XF86DRIGetClientDriverName 4
-#define X_XF86DRICreateContext 5
-#define X_XF86DRIDestroyContext 6
-#define X_XF86DRICreateDrawable 7
-#define X_XF86DRIDestroyDrawable 8
-#define X_XF86DRIGetDrawableInfo 9
-#define X_XF86DRIGetDeviceInfo 10
-#define X_XF86DRIAuthConnection 11
-#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
-#define X_XF86DRICloseFullScreen 13 /* Deprecated */
-
-#define XF86DRINumberEvents 0
-
-#define XF86DRIClientNotLocal 0
-#define XF86DRIOperationNotSupported 1
-#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
-
-#ifndef _XF86DRI_SERVER_
-
-_XFUNCPROTOBEGIN
- Bool uniDRIQueryExtension(Display * dpy, int *event_base,
- int *error_base);
-
-Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
- int *patchVersion);
-
-Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
- Bool * isCapable);
-
-Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
- char **busIDString);
-
-Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
-
-Bool uniDRICloseConnection(Display * dpy, int screen);
-
-Bool uniDRIGetClientDriverName(Display * dpy, int screen,
- int *ddxDriverMajorVersion,
- int *ddxDriverMinorVersion,
- int *ddxDriverPatchVersion,
- char **clientDriverName);
-
-Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
- XID * ptr_to_returned_context_id,
- drm_context_t * hHWContext);
-
-Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
- XID * ptr_to_returned_context_id,
- drm_context_t * hHWContext);
-
-extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
-
-extern Bool uniDRICreateDrawable(Display * dpy, int screen,
- Drawable drawable,
- drm_drawable_t * hHWDrawable);
-
-extern Bool uniDRIDestroyDrawable(Display * dpy, int screen,
- Drawable drawable);
-
-Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects,
- drm_clip_rect_t ** pBackClipRects);
-
-Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
- drm_handle_t * hFrameBuffer, int *fbOrigin,
- int *fbSize, int *fbStride, int *devPrivateSize,
- void **pDevPrivate);
-
-_XFUNCPROTOEND
-#endif /* _XF86DRI_SERVER_ */
-#endif /* _XF86DRI_H_ */
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dristr.h b/src/gallium/winsys/drm/radeon/python/xf86dristr.h
deleted file mode 100644
index d898996360..0000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dristr.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Fiath <faith@valinux.com>
- *
- */
-
-#ifndef _XF86DRISTR_H_
-#define _XF86DRISTR_H_
-
-#include "xf86dri.h"
-
-#define XF86DRINAME "XFree86-DRI"
-
-/* The DRI version number. This was originally set to be the same of the
- * XFree86 version number. However, this version is really indepedent of
- * the XFree86 version.
- *
- * Version History:
- * 4.0.0: Original
- * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
- * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
- */
-#define XF86DRI_MAJOR_VERSION 4
-#define XF86DRI_MINOR_VERSION 1
-#define XF86DRI_PATCH_VERSION 0
-
-typedef struct _XF86DRIQueryVersion
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIQueryVersion */
- CARD16 length B16;
-} xXF86DRIQueryVersionReq;
-
-#define sz_xXF86DRIQueryVersionReq 4
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD16 majorVersion B16; /* major version of DRI protocol */
- CARD16 minorVersion B16; /* minor version of DRI protocol */
- CARD32 patchVersion B32; /* patch version of DRI protocol */
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIQueryVersionReply;
-
-#define sz_xXF86DRIQueryVersionReply 32
-
-typedef struct _XF86DRIQueryDirectRenderingCapable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIQueryDirectRenderingCapableReq;
-
-#define sz_xXF86DRIQueryDirectRenderingCapableReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- BOOL isCapable;
- BOOL pad2;
- BOOL pad3;
- BOOL pad4;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
- CARD32 pad9 B32;
-} xXF86DRIQueryDirectRenderingCapableReply;
-
-#define sz_xXF86DRIQueryDirectRenderingCapableReply 32
-
-typedef struct _XF86DRIOpenConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIOpenConnectionReq;
-
-#define sz_xXF86DRIOpenConnectionReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hSAREALow B32;
- CARD32 hSAREAHigh B32;
- CARD32 busIdStringLength B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
-} xXF86DRIOpenConnectionReply;
-
-#define sz_xXF86DRIOpenConnectionReply 32
-
-typedef struct _XF86DRIAuthConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 magic B32;
-} xXF86DRIAuthConnectionReq;
-
-#define sz_xXF86DRIAuthConnectionReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 authenticated B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIAuthConnectionReply;
-
-#define zx_xXF86DRIAuthConnectionReply 32
-
-typedef struct _XF86DRICloseConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRICloseConnectionReq;
-
-#define sz_xXF86DRICloseConnectionReq 8
-
-typedef struct _XF86DRIGetClientDriverName
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetClientDriverName */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetClientDriverNameReq;
-
-#define sz_xXF86DRIGetClientDriverNameReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 ddxDriverMajorVersion B32;
- CARD32 ddxDriverMinorVersion B32;
- CARD32 ddxDriverPatchVersion B32;
- CARD32 clientDriverNameLength B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIGetClientDriverNameReply;
-
-#define sz_xXF86DRIGetClientDriverNameReply 32
-
-typedef struct _XF86DRICreateContext
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 visual B32;
- CARD32 context B32;
-} xXF86DRICreateContextReq;
-
-#define sz_xXF86DRICreateContextReq 16
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWContext B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateContextReply;
-
-#define sz_xXF86DRICreateContextReply 32
-
-typedef struct _XF86DRIDestroyContext
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 context B32;
-} xXF86DRIDestroyContextReq;
-
-#define sz_xXF86DRIDestroyContextReq 12
-
-typedef struct _XF86DRICreateDrawable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICreateDrawableReq;
-
-#define sz_xXF86DRICreateDrawableReq 12
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWDrawable B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateDrawableReply;
-
-#define sz_xXF86DRICreateDrawableReply 32
-
-typedef struct _XF86DRIDestroyDrawable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIDestroyDrawableReq;
-
-#define sz_xXF86DRIDestroyDrawableReq 12
-
-typedef struct _XF86DRIGetDrawableInfo
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDrawableInfo */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIGetDrawableInfoReq;
-
-#define sz_xXF86DRIGetDrawableInfoReq 12
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 drawableTableIndex B32;
- CARD32 drawableTableStamp B32;
- INT16 drawableX B16;
- INT16 drawableY B16;
- INT16 drawableWidth B16;
- INT16 drawableHeight B16;
- CARD32 numClipRects B32;
- INT16 backX B16;
- INT16 backY B16;
- CARD32 numBackClipRects B32;
-} xXF86DRIGetDrawableInfoReply;
-
-#define sz_xXF86DRIGetDrawableInfoReply 36
-
-typedef struct _XF86DRIGetDeviceInfo
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDeviceInfo */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetDeviceInfoReq;
-
-#define sz_xXF86DRIGetDeviceInfoReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hFrameBufferLow B32;
- CARD32 hFrameBufferHigh B32;
- CARD32 framebufferOrigin B32;
- CARD32 framebufferSize B32;
- CARD32 framebufferStride B32;
- CARD32 devPrivateSize B32;
-} xXF86DRIGetDeviceInfoReply;
-
-#define sz_xXF86DRIGetDeviceInfoReply 32
-
-typedef struct _XF86DRIOpenFullScreen
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIOpenFullScreenReq;
-
-#define sz_xXF86DRIOpenFullScreenReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 isFullScreen B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIOpenFullScreenReply;
-
-#define sz_xXF86DRIOpenFullScreenReply 32
-
-typedef struct _XF86DRICloseFullScreen
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICloseFullScreenReq;
-
-#define sz_xXF86DRICloseFullScreenReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
-} xXF86DRICloseFullScreenReply;
-
-#define sz_xXF86DRICloseFullScreenReply 32
-
-#endif /* _XF86DRISTR_H_ */
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
index a7c6e88b9e..657544dcb2 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
@@ -44,6 +44,16 @@
#include <stdio.h>
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+static boolean
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
static struct dri1_api dri1_api_hooks;
static struct dri1_api_version ddx_required = { 0, 1, 0 };
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
@@ -129,7 +139,12 @@ vmw_drm_create_screen(struct drm_api *drm_api,
&drm_compat, "use old scanout field (not a error)"))
use_old_scanout_flag = TRUE;
dri1->api = &dri1_api_hooks;
+#if 0
break;
+#else
+ assert(!"No dri 1 support for now\n");
+ return NULL;
+#endif
default:
return NULL;
}
@@ -139,6 +154,10 @@ vmw_drm_create_screen(struct drm_api *drm_api,
if (!vws)
goto out_no_vws;
+ /* XXX do this properly */
+ vws->base.surface_from_handle = vmw_drm_surface_from_handle;
+ vws->base.surface_get_handle = vmw_drm_surface_get_handle;
+
screen = svga_screen_create( &vws->base );
if (!screen)
goto out_no_screen;
@@ -200,6 +219,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
const struct drm_clip_rect *bbox,
struct pipe_fence_handle **p_fence)
{
+#if 0
struct svga_winsys_surface *srf =
svga_screen_texture_get_winsys_surface(surf->texture);
struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
@@ -246,21 +266,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
*p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
vmw_svga_winsys_surface_reference(&vsrf, NULL);
+#else
+ assert(!"No dri 1 support for now\n");
+#endif
}
-static struct pipe_texture *
-vmw_drm_texture_from_handle(struct drm_api *drm_api,
- struct pipe_screen *screen,
- struct pipe_texture *templat,
- const char *name,
- unsigned stride,
- unsigned handle)
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format)
{
struct vmw_svga_winsys_surface *vsrf;
struct svga_winsys_surface *ssrf;
- struct vmw_winsys_screen *vws =
- vmw_winsys_screen(svga_winsys_screen(screen));
- struct pipe_texture *tex;
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
union drm_vmw_surface_reference_arg arg;
struct drm_vmw_surface_arg *req = &arg.req;
struct drm_vmw_surface_create_req *rep = &arg.rep;
@@ -273,7 +291,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
*/
memset(&arg, 0, sizeof(arg));
- req->sid = handle;
+ req->sid = whandle->handle;
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
&arg, sizeof(arg));
@@ -281,14 +299,14 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (ret) {
fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
"Error %d (%s).\n",
- handle, ret, strerror(-ret));
+ whandle->handle, ret, strerror(-ret));
return NULL;
}
if (rep->mip_levels[0] != 1) {
fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
" SID %d, levels %d\n",
- handle, rep->mip_levels[0]);
+ whandle->handle, rep->mip_levels[0]);
goto out_mip;
}
@@ -296,7 +314,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (rep->mip_levels[i] != 0) {
fprintf(stderr, "Incorrect number of faces levels on shared surface."
" SID %d, face %d present.\n",
- handle, i);
+ whandle->handle, i);
goto out_mip;
}
}
@@ -308,38 +326,32 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
pipe_reference_init(&vsrf->refcnt, 1);
p_atomic_set(&vsrf->validated, 0);
vsrf->screen = vws;
- vsrf->sid = handle;
+ vsrf->sid = whandle->handle;
ssrf = svga_winsys_surface(vsrf);
- tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
- if (!tex)
- vmw_svga_winsys_surface_reference(&vsrf, NULL);
+ *format = rep->format;
+
+ return ssrf;
- return tex;
- out_mip:
- vmw_ioctl_surface_destroy(vws, handle);
+out_mip:
+ vmw_ioctl_surface_destroy(vws, whandle->handle);
return NULL;
}
static boolean
-vmw_drm_handle_from_texture(struct drm_api *drm_api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle)
{
- struct svga_winsys_surface *surface =
- svga_screen_texture_get_winsys_surface(texture);
struct vmw_svga_winsys_surface *vsrf;
if (!surface)
return FALSE;
vsrf = vmw_svga_winsys_surface(surface);
- *handle = vsrf->sid;
- *stride = util_format_get_nblocksx(texture->format, texture->width0) *
- util_format_get_blocksize(texture->format);
+ whandle->handle = vsrf->sid;
+ whandle->stride = stride;
- vmw_svga_winsys_surface_reference(&vsrf, NULL);
return TRUE;
}
@@ -353,9 +365,6 @@ static struct drm_api vmw_drm_api_hooks = {
.name = "vmwgfx",
.driver_name = "vmwgfx",
.create_screen = vmw_drm_create_screen,
- .texture_from_shared_handle = vmw_drm_texture_from_handle,
- .shared_handle_from_texture = vmw_drm_handle_from_texture,
- .local_handle_from_texture = vmw_drm_handle_from_texture,
};
struct drm_api* drm_api_create()
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript
index 4cbc86f331..1267fc6eea 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/gdi/SConscript
@@ -1,5 +1,6 @@
#######################################################################
-# SConscript for gdi winsys
+# SConscript for xlib winsys
+
Import('*')
@@ -8,44 +9,15 @@ if env['platform'] == 'windows':
env = env.Clone()
env.Append(CPPPATH = [
- '#src/gallium/state_trackers/wgl',
- ])
-
- env.Append(LIBS = [
- 'gdi32',
- 'user32',
- 'kernel32',
- 'ws2_32',
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
])
- sources = []
- drivers = []
-
- if 'softpipe' in env['drivers']:
- sources = ['gdi_softpipe_winsys.c']
- drivers = [softpipe]
-
- if 'llvmpipe' in env['drivers']:
- env.Tool('llvm')
- if 'LLVM_VERSION' in env:
- sources = ['gdi_llvmpipe_winsys.c']
- drivers = [llvmpipe]
-
- if not sources or not drivers:
- print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled'
- Return()
-
- if env['gcc']:
- sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
- else:
- sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
-
- drivers += [trace]
-
- env['no_import_lib'] = 1
-
- env.SharedLibrary(
- target ='opengl32',
- source = sources,
- LIBS = wgl + glapi + mesa + drivers + gallium + glsl + env['LIBS'],
+ ws_gdi = env.ConvenienceLibrary(
+ target = 'ws_gdi',
+ source = [
+ 'gdi_sw_winsys.c',
+ ]
)
+ Export('ws_gdi')
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
deleted file mode 100644
index 71360e55aa..0000000000
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include <windows.h>
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
-#include "stw_winsys.h"
-
-
-struct gdi_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct gdi_softpipe_buffer *
-gdi_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct gdi_softpipe_buffer *)buf;
-}
-
-
-static void *
-gdi_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
- gdi_softpipe_buf->mapped = gdi_softpipe_buf->data;
- return gdi_softpipe_buf->mapped;
-}
-
-
-static void
-gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
- gdi_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-gdi_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static const char *
-gdi_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct gdi_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surface,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-gdi_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-gdi_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-gdi_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-gdi_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-gdi_softpipe_screen_create(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = gdi_softpipe_destroy;
-
- winsys->buffer_create = gdi_softpipe_buffer_create;
- winsys->user_buffer_create = gdi_softpipe_user_buffer_create;
- winsys->buffer_map = gdi_softpipe_buffer_map;
- winsys->buffer_unmap = gdi_softpipe_buffer_unmap;
- winsys->buffer_destroy = gdi_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create;
-
- winsys->fence_reference = gdi_softpipe_fence_reference;
- winsys->fence_signalled = gdi_softpipe_fence_signalled;
- winsys->fence_finish = gdi_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer;
- winsys->get_name = gdi_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- gdi_softpipe_destroy(winsys);
-
- return screen;
-}
-
-
-static void
-gdi_softpipe_present(struct pipe_screen *screen,
- struct pipe_surface *surface,
- HDC hDC)
-{
- struct softpipe_texture *texture;
- struct gdi_softpipe_buffer *buffer;
- BITMAPINFO bmi;
-
- texture = softpipe_texture(surface->texture);
-
- buffer = gdi_softpipe_buffer(texture->buffer);
-
- memset(&bmi, 0, sizeof(BITMAPINFO));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = texture->stride[surface->level] / util_format_get_blocksize(surface->format);
- bmi.bmiHeader.biHeight= -(long)surface->height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = util_format_get_blocksizebits(surface->format);
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = 0;
- bmi.bmiHeader.biXPelsPerMeter = 0;
- bmi.bmiHeader.biYPelsPerMeter = 0;
- bmi.bmiHeader.biClrUsed = 0;
- bmi.bmiHeader.biClrImportant = 0;
-
- StretchDIBits(hDC,
- 0, 0, surface->width, surface->height,
- 0, 0, surface->width, surface->height,
- buffer->data, &bmi, 0, SRCCOPY);
-}
-
-
-static const struct stw_winsys stw_winsys = {
- &gdi_softpipe_screen_create,
- &gdi_softpipe_present,
- NULL, /* get_adapter_luid */
- NULL, /* shared_surface_open */
- NULL, /* shared_surface_close */
- NULL /* compose */
-};
-
-
-BOOL WINAPI
-DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
-{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- stw_init(&stw_winsys);
- stw_init_thread();
- break;
-
- case DLL_THREAD_ATTACH:
- stw_init_thread();
- break;
-
- case DLL_THREAD_DETACH:
- stw_cleanup_thread();
- break;
-
- case DLL_PROCESS_DETACH:
- stw_cleanup_thread();
- stw_cleanup();
- break;
- }
- return TRUE;
-}
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_sw_winsys.c
index a9fa03b8e5..f5c0b7d56e 100644
--- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_sw_winsys.c
@@ -28,7 +28,7 @@
/**
* @file
- * LLVMpipe support.
+ * GDI software rasterizer support.
*
* @author Jose Fonseca <jfonseca@vmware.com>
*/
@@ -42,12 +42,11 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
-#include "stw_winsys.h"
+#include "state_tracker/sw_winsys.h"
+#include "gdi_sw_winsys.h"
-struct gdi_llvmpipe_displaytarget
+struct gdi_sw_displaytarget
{
enum pipe_format format;
unsigned width;
@@ -63,15 +62,15 @@ struct gdi_llvmpipe_displaytarget
/** Cast wrapper */
-static INLINE struct gdi_llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf )
+static INLINE struct gdi_sw_displaytarget *
+gdi_sw_displaytarget( struct sw_displaytarget *buf )
{
- return (struct gdi_llvmpipe_displaytarget *)buf;
+ return (struct gdi_sw_displaytarget *)buf;
}
static boolean
-gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
enum pipe_format format )
{
switch(format) {
@@ -89,47 +88,47 @@ gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
static void *
-gdi_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+gdi_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags )
{
- struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
return gdt->data;
}
static void
-gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
+gdi_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
{
}
static void
-gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
+gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
{
- struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
align_free(gdt->data);
FREE(gdt);
}
-static struct llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
+static struct sw_displaytarget *
+gdi_sw_displaytarget_create(struct sw_winsys *winsys,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride)
{
- struct gdi_llvmpipe_displaytarget *gdt;
+ struct gdi_sw_displaytarget *gdt;
unsigned cpp;
unsigned bpp;
- gdt = CALLOC_STRUCT(gdi_llvmpipe_displaytarget);
+ gdt = CALLOC_STRUCT(gdi_sw_displaytarget);
if(!gdt)
goto no_gdt;
@@ -160,7 +159,7 @@ gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
gdt->bmi.bmiHeader.biClrImportant = 0;
*stride = gdt->stride;
- return (struct llvmpipe_displaytarget *)gdt;
+ return (struct sw_displaytarget *)gdt;
no_data:
FREE(gdt);
@@ -169,104 +168,55 @@ no_gdt:
}
-static void
-gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
+void
+gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC )
{
- assert(0);
-}
-
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
-static void
-gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys)
-{
- FREE(winsys);
+ StretchDIBits(hDC,
+ 0, 0, gdt->width, gdt->height,
+ 0, 0, gdt->width, gdt->height,
+ gdt->data, &gdt->bmi, 0, SRCCOPY);
}
-
-static struct pipe_screen *
-gdi_llvmpipe_screen_create(void)
+static void
+gdi_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if(!winsys)
- goto no_winsys;
-
- winsys->destroy = gdi_llvmpipe_destroy;
- winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported;
- winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create;
- winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map;
- winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap;
- winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display;
- winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy;
+ /* nasty:
+ */
+ HDC hDC = (HDC)context_private;
- screen = llvmpipe_create_screen(winsys);
- if(!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
+ gdi_sw_display(winsys, dt, hDC);
}
-
-
static void
-gdi_llvmpipe_present(struct pipe_screen *screen,
- struct pipe_surface *surface,
- HDC hDC)
+gdi_sw_destroy(struct sw_winsys *winsys)
{
- struct llvmpipe_texture *texture;
- struct gdi_llvmpipe_displaytarget *gdt;
-
- texture = llvmpipe_texture(surface->texture);
- gdt = gdi_llvmpipe_displaytarget(texture->dt);
-
- StretchDIBits(hDC,
- 0, 0, gdt->width, gdt->height,
- 0, 0, gdt->width, gdt->height,
- gdt->data, &gdt->bmi, 0, SRCCOPY);
+ FREE(winsys);
}
+struct sw_winsys *
+gdi_create_sw_winsys(void)
+{
+ static struct sw_winsys *winsys;
-static const struct stw_winsys stw_winsys = {
- &gdi_llvmpipe_screen_create,
- &gdi_llvmpipe_present,
- NULL, /* get_adapter_luid */
- NULL, /* shared_surface_open */
- NULL, /* shared_surface_close */
- NULL /* compose */
-};
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if(!winsys)
+ return NULL;
+ 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_map = gdi_sw_displaytarget_map;
+ winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
+ winsys->displaytarget_display = gdi_sw_displaytarget_display;
+ winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy;
-BOOL WINAPI
-DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
-{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- stw_init(&stw_winsys);
- stw_init_thread();
- break;
-
- case DLL_THREAD_ATTACH:
- stw_init_thread();
- break;
-
- case DLL_THREAD_DETACH:
- stw_cleanup_thread();
- break;
-
- case DLL_PROCESS_DETACH:
- stw_cleanup_thread();
- stw_cleanup();
- break;
- }
- return TRUE;
+ return winsys;
}
+
diff --git a/src/gallium/winsys/gdi/gdi_sw_winsys.h b/src/gallium/winsys/gdi/gdi_sw_winsys.h
new file mode 100644
index 0000000000..4bbcb47848
--- /dev/null
+++ b/src/gallium/winsys/gdi/gdi_sw_winsys.h
@@ -0,0 +1,16 @@
+#ifndef GDI_SW_WINSYS_H
+#define GDI_SW_WINSYS_H
+
+#include <windows.h>
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/sw_winsys.h"
+
+void gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC );
+
+struct sw_winsys *
+gdi_create_sw_winsys(void);
+
+#endif
diff --git a/src/gallium/winsys/null/Makefile b/src/gallium/winsys/null/Makefile
new file mode 100644
index 0000000000..3a3fb75ab3
--- /dev/null
+++ b/src/gallium/winsys/null/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = ws_null
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary
+
+C_SOURCES = \
+ null_sw_winsys.c
+
+include ../../Makefile.template
+
+
diff --git a/src/gallium/winsys/null/SConscript b/src/gallium/winsys/null/SConscript
new file mode 100644
index 0000000000..21837dc60c
--- /dev/null
+++ b/src/gallium/winsys/null/SConscript
@@ -0,0 +1,21 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+])
+
+ws_null = env.ConvenienceLibrary(
+ target = 'ws_null',
+ source = [
+ 'null_sw_winsys.c',
+ ]
+)
+Export('ws_null')
diff --git a/src/gallium/winsys/null/null_sw_winsys.c b/src/gallium/winsys/null/null_sw_winsys.c
new file mode 100644
index 0000000000..d961d34860
--- /dev/null
+++ b/src/gallium/winsys/null/null_sw_winsys.c
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Null software rasterizer winsys.
+ *
+ * There is no present support. Framebuffer data needs to be obtained via
+ * transfers.
+ *
+ * @author Jose Fonseca
+ */
+
+
+#include "pipe/p_format.h"
+#include "util/u_memory.h"
+#include "state_tracker/sw_winsys.h"
+#include "null_sw_winsys.h"
+
+
+static boolean
+null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
+ enum pipe_format format )
+{
+ return FALSE;
+}
+
+
+static void *
+null_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags )
+{
+ assert(0);
+ return NULL;
+}
+
+
+static void
+null_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
+{
+ assert(0);
+}
+
+
+static void
+null_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
+{
+ assert(0);
+}
+
+
+static struct sw_displaytarget *
+null_sw_displaytarget_create(struct sw_winsys *winsys,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static void
+null_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ assert(0);
+}
+
+
+static void
+null_sw_destroy(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+
+struct sw_winsys *
+null_sw_create(void)
+{
+ static struct sw_winsys *winsys;
+
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if (!winsys)
+ return NULL;
+
+ 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_map = null_sw_displaytarget_map;
+ winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
+ winsys->displaytarget_display = null_sw_displaytarget_display;
+ winsys->displaytarget_destroy = null_sw_displaytarget_destroy;
+
+ return winsys;
+}
diff --git a/src/gallium/winsys/null/null_sw_winsys.h b/src/gallium/winsys/null/null_sw_winsys.h
new file mode 100644
index 0000000000..1986186feb
--- /dev/null
+++ b/src/gallium/winsys/null/null_sw_winsys.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * 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 SOFTWARE IS PROVIDED "AS 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.
+ *
+ **************************************************************************/
+
+
+#ifndef NULL_SW_WINSYS_H_
+#define NULL_SW_WINSYS_H_
+
+
+struct sw_winsys;
+
+
+struct sw_winsys *
+null_sw_create(void);
+
+
+#endif /* NULL_SW_WINSYS_H_ */
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 824c666ae3..68542b488d 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -1,100 +1,16 @@
-# src/gallium/winsys/xlib/Makefile
-
-# This makefile produces a "stand-alone" libGL.so which is based on
-# Xlib (no DRI HW acceleration)
-
-
TOP = ../../../..
include $(TOP)/configs/current
+LIBNAME = ws_xlib
-GL_MAJOR = 1
-GL_MINOR = 5
-GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
-
-
-INCLUDE_DIRS = \
- -I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main \
+LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/state_trackers/glx/xlib \
-I$(TOP)/src/gallium/auxiliary
-DEFINES += \
- -DGALLIUM_SOFTPIPE
-#-DGALLIUM_CELL will be defined by the config */
-
-XLIB_WINSYS_SOURCES = \
- xlib.c \
- xlib_cell.c \
- xlib_llvmpipe.c \
- xlib_softpipe.c
-
-
-XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
-
-
-# Note: CELL_SPU_LIB is only defined for cell configs
-
-LIBS = \
- $(GALLIUM_DRIVERS) \
- $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
- $(TOP)/src/mesa/libglapi.a \
- $(TOP)/src/mesa/libmesagallium.a \
- $(GALLIUM_AUXILIARIES) \
- $(CELL_SPU_LIB) \
-
-
-.SUFFIXES : .cpp
-
-.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
-
-.cpp.o:
- $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
-
-
-
-default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME)
-
-$(TOP)/$(LIB_DIR)/gallium:
- @ mkdir -p $(TOP)/$(LIB_DIR)/gallium
-
-# Make the libGL.so library
-$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile
- $(TOP)/bin/mklib -o $(GL_LIB) \
- -linker "$(CC)" \
- -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
- -install $(TOP)/$(LIB_DIR)/gallium \
- $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
- -Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
-
-
-depend: $(XLIB_WINSYS_SOURCES)
- @ echo "running $(MKDEP)"
- @ rm -f depend # workaround oops on gutsy?!?
- @ touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \
- > /dev/null 2>/dev/null
-
-
-install: default
- $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GL
- $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
- $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(DESTDIR)$(INSTALL_DIR)/include/GL
- @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
- $(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR); \
- fi
-
-
-# Emacs tags
-tags:
- etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+C_SOURCES = \
+ xlib_sw_winsys.c
-clean:
- -rm -f *.o
+include ../../Makefile.template
-include depend
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index 8c9d318af2..2af6153b4c 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -1,64 +1,23 @@
#######################################################################
# SConscript for xlib winsys
-Import('*')
-
-if env['platform'] != 'linux':
- Return()
-
-if 'mesa' not in env['statetrackers']:
- print 'warning: Mesa state tracker disabled: skipping build of xlib libGL.so'
- Return()
-
-if env['dri']:
- print 'warning: DRI enabled: skipping build of xlib libGL.so'
- 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.Append(CPPPATH = [
- '#/src/mesa',
- '#/src/mesa/main',
- '#src/gallium/state_trackers/glx/xlib',
-])
-
-env.Append(CPPDEFINES = ['USE_XSHM'])
-
-sources = [
- 'xlib.c',
-]
+Import('*')
-drivers = [trace]
-
-if 'softpipe' in env['drivers']:
- env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
- sources += ['xlib_softpipe.c']
- drivers += [softpipe]
+if env['platform'] == 'linux':
-if 'llvmpipe' in env['drivers']:
- env.Tool('llvm')
- if 'LLVM_VERSION' in env:
- env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
- env.Tool('udis86')
- sources += ['xlib_llvmpipe.c']
- drivers += [llvmpipe]
-
-if 'cell' in env['drivers']:
- env.Append(CPPDEFINES = 'GALLIUM_CELL')
- sources += ['xlib_cell.c']
- drivers += [cell]
+ env = env.Clone()
-# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
-libgl = env.SharedLibrary(
- target ='GL',
- source = sources,
- LIBS = st_xlib + glapi + mesa + glsl + drivers + gallium + env['LIBS'],
-)
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
-if not env['dri']:
- # Only install this libGL.so if DRI not enabled
- env.InstallSharedLibrary(libgl, version=(1, 5))
+ ws_xlib = env.ConvenienceLibrary(
+ target = 'ws_xlib',
+ source = [
+ 'xlib_sw_winsys.c',
+ ]
+ )
+ Export('ws_xlib')
diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h
deleted file mode 100644
index 8e091d0c08..0000000000
--- a/src/gallium/winsys/xlib/xlib.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef XLIB_H
-#define XLIB_H
-
-#include "pipe/p_compiler.h"
-#include "xm_winsys.h"
-
-extern struct xm_driver xlib_softpipe_driver;
-extern struct xm_driver xlib_llvmpipe_driver;
-extern struct xm_driver xlib_cell_driver;
-
-
-#endif
diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c
deleted file mode 100644
index 22bf41a46f..0000000000
--- a/src/gallium/winsys/xlib/xlib_brw_context.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-
-/* #include "glxheader.h" */
-/* #include "xmesaP.h" */
-
-#include "util/u_simple_screen.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "i965simple/brw_winsys.h"
-#include "xlib_brw_aub.h"
-#include "xlib_brw.h"
-
-
-
-
-#define XBCWS_BATCHBUFFER_SIZE 1024
-
-
-/* The backend to the brw driver (ie struct brw_winsys) is actually a
- * per-context entity.
- */
-struct xlib_brw_context_winsys {
- struct brw_winsys brw_context_winsys; /**< batch buffer funcs */
- struct aub_context *aub;
-
- struct pipe_winsys *pipe_winsys;
-
- unsigned batch_data[XBCWS_BATCHBUFFER_SIZE];
- unsigned batch_nr;
- unsigned batch_size;
- unsigned batch_alloc;
-};
-
-
-/* Turn a brw_winsys into an xlib_brw_context_winsys:
- */
-static inline struct xlib_brw_context_winsys *
-xlib_brw_context_winsys( struct brw_winsys *sws )
-{
- return (struct xlib_brw_context_winsys *)sws;
-}
-
-
-/* Simple batchbuffer interface:
- */
-
-static unsigned *xbcws_batch_start( struct brw_winsys *sws,
- unsigned dwords,
- unsigned relocs )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- if (xbcws->batch_size < xbcws->batch_nr + dwords)
- return NULL;
-
- xbcws->batch_alloc = xbcws->batch_nr + dwords;
- return (void *)1; /* not a valid pointer! */
-}
-
-static void xbcws_batch_dword( struct brw_winsys *sws,
- unsigned dword )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr < xbcws->batch_alloc);
- xbcws->batch_data[xbcws->batch_nr++] = dword;
-}
-
-static void xbcws_batch_reloc( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags,
- unsigned delta )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr < xbcws->batch_alloc);
- xbcws->batch_data[xbcws->batch_nr++] =
- ( xlib_brw_get_buffer_offset( NULL, buf, access_flags ) +
- delta );
-}
-
-static void xbcws_batch_end( struct brw_winsys *sws )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr <= xbcws->batch_alloc);
- xbcws->batch_alloc = 0;
-}
-
-static void xbcws_batch_flush( struct brw_winsys *sws,
- struct pipe_fence_handle **fence )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
- assert(xbcws->batch_nr <= xbcws->batch_size);
-
- if (xbcws->batch_nr) {
- xlib_brw_commands_aub( xbcws->pipe_winsys,
- xbcws->batch_data,
- xbcws->batch_nr );
- }
-
- xbcws->batch_nr = 0;
-}
-
-
-
-/* Really a per-device function, just pass through:
- */
-static unsigned xbcws_get_buffer_offset( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- return xlib_brw_get_buffer_offset( xbcws->pipe_winsys,
- buf,
- access_flags );
-}
-
-
-/* Really a per-device function, just pass through:
- */
-static void xbcws_buffer_subdata_typed( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned long offset,
- unsigned long size,
- const void *data,
- unsigned data_type )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- xlib_brw_buffer_subdata_typed( xbcws->pipe_winsys,
- buf,
- offset,
- size,
- data,
- data_type );
-}
-
-
-/**
- * Create i965 hardware rendering context, but plugged into a
- * dump-to-aubfile backend.
- */
-struct pipe_context *
-xlib_create_brw_context( struct pipe_screen *screen,
- void *unused )
-{
- struct xlib_brw_context_winsys *xbcws = CALLOC_STRUCT( xlib_brw_context_winsys );
-
- /* Fill in this struct with callbacks that i965simple will need to
- * communicate with the window system, buffer manager, etc.
- */
- xbcws->brw_context_winsys.batch_start = xbcws_batch_start;
- xbcws->brw_context_winsys.batch_dword = xbcws_batch_dword;
- xbcws->brw_context_winsys.batch_reloc = xbcws_batch_reloc;
- xbcws->brw_context_winsys.batch_end = xbcws_batch_end;
- xbcws->brw_context_winsys.batch_flush = xbcws_batch_flush;
- xbcws->brw_context_winsys.buffer_subdata_typed = xbcws_buffer_subdata_typed;
- xbcws->brw_context_winsys.get_buffer_offset = xbcws_get_buffer_offset;
-
- xbcws->pipe_winsys = screen->winsys; /* redundant */
-
- xbcws->batch_size = XBCWS_BATCHBUFFER_SIZE;
-
- /* Create the i965simple context:
- */
-#ifdef GALLIUM_CELL
- return NULL;
-#else
- return brw_create( screen,
- &xbcws->brw_context_winsys,
- 0 );
-#endif
-}
diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c
deleted file mode 100644
index 1dc9e8fa11..0000000000
--- a/src/gallium/winsys/xlib/xlib_cell.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-#include "xlib.h"
-
-#ifdef GALLIUM_CELL
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "cell/ppu/cell_context.h"
-#include "cell/ppu/cell_screen.h"
-#include "cell/ppu/cell_winsys.h"
-#include "cell/ppu/cell_texture.h"
-
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-
- XImage *tempImage;
- int shm;
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
- struct pipe_winsys base;
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
- return (struct xm_buffer *)buf;
-}
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = xm_buf->data;
- return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(/*struct pipe_winsys *pws,*/
- struct pipe_buffer *buf)
-{
- struct xm_buffer *oldBuf = xm_buffer(buf);
-
- if (oldBuf) {
- if (oldBuf->data) {
- if (!oldBuf->userBuffer) {
- align_free(oldBuf->data);
- }
-
- oldBuf->data = NULL;
- }
- free(oldBuf);
- }
-}
-
-
-/**
- * For Cell. Basically, rearrange the pixels/quads from this layout:
- * +--+--+--+--+
- * |p0|p1|p2|p3|....
- * +--+--+--+--+
- *
- * to this layout:
- * +--+--+
- * |p0|p1|....
- * +--+--+
- * |p2|p3|
- * +--+--+
- */
-static void
-twiddle_tile(const uint *tileIn, uint *tileOut)
-{
- int y, x;
-
- for (y = 0; y < TILE_SIZE; y+=2) {
- for (x = 0; x < TILE_SIZE; x+=2) {
- int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
- tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
- tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
- tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
- tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
- }
- }
-}
-
-
-
-/**
- * Display a surface that's in a tiled configuration. That is, all the
- * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory.
- */
-static void
-xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf)
-{
- XImage *ximage;
- struct xm_buffer *xm_buf = xm_buffer(
- cell_texture(surf->texture)->buffer);
- const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
- uint x, y;
-
- ximage = b->tempImage;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = TILE_SIZE;
- ximage->height = TILE_SIZE;
- ximage->bytes_per_line = TILE_SIZE * 4;
-
- for (y = 0; y < surf->height; y += TILE_SIZE) {
- for (x = 0; x < surf->width; x += TILE_SIZE) {
- uint tmpTile[TILE_SIZE * TILE_SIZE];
- int tx = x / TILE_SIZE;
- int ty = y / TILE_SIZE;
- int offset = ty * tilesPerRow + tx;
- int w = TILE_SIZE;
- int h = TILE_SIZE;
-
- if (y + h > surf->height)
- h = surf->height - y;
- if (x + w > surf->width)
- w = surf->width - x;
-
- /* offset in pixels */
- offset *= TILE_SIZE * TILE_SIZE;
-
- /* twiddle from ximage buffer to temp tile */
- twiddle_tile((uint *) xm_buf->data + offset, tmpTile);
- /* display temp tile data */
- ximage->data = (char *) tmpTile;
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, x, y, w, h);
- }
- }
-}
-
-
-
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *surf,
- void *context_private)
-{
- /*
- * The front color buffer is actually just another XImage buffer.
- * This function copies that XImage to the actual X Window.
- */
- XMesaContext xmctx = (XMesaContext) context_private;
- if (xmctx)
- xlib_cell_display_surface(xmctx->xm_buffer, surf);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
- return "Xlib/Cell";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
-
- if (buffer->data == NULL) {
- buffer->shm = 0;
-
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
- }
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
- buffer->shm = 0;
-
- return &buffer->base;
-}
-
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- /* XXX a bit of a hack */
- *stride * align(nblocksy, TILE_SIZE));
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_cell_winsys( void )
-{
- static struct xmesa_pipe_winsys *ws = NULL;
-
- if (!ws) {
- ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->base.buffer_create = xm_buffer_create;
- ws->base.user_buffer_create = xm_user_buffer_create;
- ws->base.buffer_map = xm_buffer_map;
- ws->base.buffer_unmap = xm_buffer_unmap;
- ws->base.buffer_destroy = xm_buffer_destroy;
-
- ws->base.surface_buffer_create = xm_surface_buffer_create;
-
- ws->base.fence_reference = xm_fence_reference;
- ws->base.fence_signalled = xm_fence_signalled;
- ws->base.fence_finish = xm_fence_finish;
-
- ws->base.flush_frontbuffer = xm_flush_frontbuffer;
- ws->base.get_name = xm_get_name;
- }
-
- return &ws->base;
-}
-
-
-static struct pipe_screen *
-xlib_create_cell_screen( void )
-{
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_cell_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = cell_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-
-struct xm_driver xlib_cell_driver =
-{
- .create_pipe_screen = xlib_create_cell_screen,
- .display_surface = xlib_cell_display_surface,
-};
-
-#else
-
-struct xm_driver xlib_cell_driver =
-{
- .create_pipe_screen = NULL,
- .display_surface = NULL,
-};
-
-#endif
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
deleted file mode 100644
index 716338aef4..0000000000
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
-
-#include "xlib.h"
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-
- XImage *tempImage;
-#ifdef USE_XSHM
- boolean shm; /** Is this a shared memory buffer? */
- XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
- struct pipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
- return (struct xm_buffer *)buf;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
- (void) dpy;
- (void) event;
- mesaXErrorFlag = 1;
- return 0;
-}
-
-
-static char *alloc_shm(struct xm_buffer *buf, unsigned size)
-{
- XShmSegmentInfo *const shminfo = & buf->shminfo;
-
- shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
- if (shminfo->shmid < 0) {
- return NULL;
- }
-
- shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
- if (shminfo->shmaddr == (char *) -1) {
- shmctl(shminfo->shmid, IPC_RMID, 0);
- return NULL;
- }
-
- shminfo->readOnly = False;
- return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
- unsigned width, unsigned height)
-{
- /*
- * We have to do a _lot_ of error checking here to be sure we can
- * really use the XSHM extension. It seems different servers trigger
- * errors at different points if the extension won't work. Therefore
- * we have to be very careful...
- */
- int (*old_handler)(Display *, XErrorEvent *);
-
- b->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &b->shminfo,
- width, height);
- if (b->tempImage == NULL) {
- b->shm = FALSE;
- return;
- }
-
-
- mesaXErrorFlag = 0;
- old_handler = XSetErrorHandler(mesaHandleXError);
- /* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &b->shminfo);
- XSync(xmb->xm_visual->display, False);
-
- if (mesaXErrorFlag) {
- /* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
- mesaXErrorFlag = 0;
- XDestroyImage(b->tempImage);
- b->tempImage = NULL;
- b->shm = FALSE;
- (void) XSetErrorHandler(old_handler);
- return;
- }
-
- b->shm = TRUE;
-}
-
-#endif /* USE_XSHM */
-
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = xm_buf->data;
- return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(struct pipe_buffer *buf)
-{
- struct xm_buffer *oldBuf = xm_buffer(buf);
-
- /*
- * Note oldBuf->data may point to one of three things:
- * 1. XShm shared memory image data
- * 2. User-provided (wrapped) memory, see xm_user_buffer_create()
- * 3. Regular, malloc'd memory
- * We need to be careful with freeing that data now.
- */
-
- if (oldBuf->data) {
-#ifdef USE_XSHM
- if (oldBuf->shminfo.shmid >= 0) {
- shmdt(oldBuf->shminfo.shmaddr);
- shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
-
- oldBuf->shminfo.shmid = -1;
- oldBuf->shminfo.shmaddr = (char *) -1;
- }
-
- if (oldBuf->shm) {
- oldBuf->data = NULL;
- }
-
- if (oldBuf->tempImage) {
- XDestroyImage(oldBuf->tempImage);
- oldBuf->tempImage = NULL;
- }
-#endif
-
- if (oldBuf->data && !oldBuf->userBuffer) {
- /* this was regular malloc'd memory */
- align_free(oldBuf->data);
- }
-
- oldBuf->data = NULL;
- }
-
- free(oldBuf);
-}
-
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xlib_softpipe_display_surface(struct xmesa_buffer *b,
- struct pipe_surface *surf)
-{
- XImage *ximage;
- struct softpipe_texture *spt = softpipe_texture(surf->texture);
- struct xm_buffer *xm_buf = xm_buffer(spt->buffer);
- static boolean no_swap = 0;
- static boolean firsttime = 1;
-
- if (firsttime) {
- no_swap = getenv("SP_NO_RAST") != NULL;
- firsttime = 0;
- }
-
- if (no_swap)
- return;
-
-#ifdef USE_XSHM
- if (xm_buf->shm)
- {
- if (xm_buf->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(surf->texture->format) == 1);
- assert(util_format_get_blockheight(surf->texture->format) == 1);
- alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
- util_format_get_blocksize(surf->texture->format), surf->height);
- }
-
- ximage = xm_buf->tempImage;
- ximage->data = xm_buf->data;
-
- /* _debug_printf("XSHM\n"); */
- XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height, False);
- }
- else
-#endif
- {
- /* display image in Window */
- ximage = b->tempImage;
- ximage->data = xm_buf->data;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = surf->width;
- ximage->height = surf->height;
- ximage->bytes_per_line = spt->stride[surf->level];
-
- /* _debug_printf("XPUT\n"); */
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height);
- }
-}
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *surf,
- void *context_private)
-{
- /*
- * The front color buffer is actually just another XImage buffer.
- * This function copies that XImage to the actual X Window.
- */
- XMesaContext xmctx = (XMesaContext) context_private;
- xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
- xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
- return "Xlib";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy, size;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
- size = *stride * nblocksy;
-
-#ifdef USE_XSHM
- if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
- {
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
- buffer->userBuffer = FALSE;
- buffer->shminfo.shmid = -1;
- buffer->shminfo.shmaddr = (char *) -1;
- buffer->shm = TRUE;
-
- buffer->data = alloc_shm(buffer, size);
- if (!buffer->data)
- goto out;
-
- return &buffer->base;
-
- out:
- if (buffer)
- FREE(buffer);
- }
-#endif
-
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- size);
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_softpipe_winsys( void )
-{
- static struct xmesa_pipe_winsys *ws = NULL;
-
- if (!ws) {
- ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->base.buffer_create = xm_buffer_create;
- ws->base.user_buffer_create = xm_user_buffer_create;
- ws->base.buffer_map = xm_buffer_map;
- ws->base.buffer_unmap = xm_buffer_unmap;
- ws->base.buffer_destroy = xm_buffer_destroy;
-
- ws->base.surface_buffer_create = xm_surface_buffer_create;
-
- ws->base.fence_reference = xm_fence_reference;
- ws->base.fence_signalled = xm_fence_signalled;
- ws->base.fence_finish = xm_fence_finish;
-
- ws->base.flush_frontbuffer = xm_flush_frontbuffer;
- ws->base.get_name = xm_get_name;
- }
-
- return &ws->base;
-}
-
-
-static struct pipe_screen *
-xlib_create_softpipe_screen( void )
-{
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_softpipe_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = softpipe_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-struct xm_driver xlib_softpipe_driver =
-{
- .create_pipe_screen = xlib_create_softpipe_screen,
- .display_surface = xlib_softpipe_display_surface
-};
-
-
-
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_sw_winsys.c
index 6cebd4c201..cecfa4a53d 100644
--- a/src/gallium/winsys/xlib/xlib_llvmpipe.c
+++ b/src/gallium/winsys/xlib/xlib_sw_winsys.c
@@ -32,25 +32,21 @@
* Brian Paul
*/
-
-#if defined(GALLIUM_LLVMPIPE)
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
-#include "xlib.h"
+#include "state_tracker/xlib_sw_winsys.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
/**
* Subclass of pipe_buffer for Xlib winsys.
@@ -66,28 +62,38 @@ struct xm_displaytarget
void *data;
void *mapped;
+ Display *display;
+ Visual *visual;
XImage *tempImage;
-#ifdef USE_XSHM
- int shm;
+ GC gc;
+
+ /* This is the last drawable that this display target was presented
+ * against. May need to recreate gc, tempImage when this changes??
+ */
+ Drawable drawable;
+
XShmSegmentInfo shminfo;
-#endif
+ int shm;
};
/**
- * Subclass of llvmpipe_winsys for Xlib winsys
+ * Subclass of sw_winsys for Xlib winsys
*/
-struct xmesa_llvmpipe_winsys
+struct xlib_sw_winsys
{
- struct llvmpipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
+ struct sw_winsys base;
+
+
+
+ Display *display;
};
/** Cast wrapper */
static INLINE struct xm_displaytarget *
-xm_displaytarget( struct llvmpipe_displaytarget *dt )
+xm_displaytarget( struct sw_displaytarget *dt )
{
return (struct xm_displaytarget *)dt;
}
@@ -97,8 +103,6 @@ xm_displaytarget( struct llvmpipe_displaytarget *dt )
* X Shared Memory Image extension code
*/
-#ifdef USE_XSHM
-
static volatile int mesaXErrorFlag = 0;
/**
@@ -138,8 +142,8 @@ static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
*/
static void
-alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
- struct xmesa_buffer *xmb,
+alloc_shm_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
unsigned width, unsigned height)
{
/*
@@ -150,15 +154,15 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
*/
int (*old_handler)(Display *, XErrorEvent *);
- xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &xm_buffer->shminfo,
- width, height);
- if (xm_buffer->tempImage == NULL) {
- xm_buffer->shm = 0;
+ xm_dt->tempImage = XShmCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap,
+ NULL,
+ &xm_dt->shminfo,
+ width, height);
+ if (xm_dt->tempImage == NULL) {
+ xm_dt->shm = 0;
return;
}
@@ -166,27 +170,44 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
mesaXErrorFlag = 0;
old_handler = XSetErrorHandler(mesaHandleXError);
/* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
- XSync(xmb->xm_visual->display, False);
+ XShmAttach(xm_dt->display, &xm_dt->shminfo);
+ XSync(xm_dt->display, False);
if (mesaXErrorFlag) {
/* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
+ XFlush(xm_dt->display);
mesaXErrorFlag = 0;
- XDestroyImage(xm_buffer->tempImage);
- xm_buffer->tempImage = NULL;
- xm_buffer->shm = 0;
+ XDestroyImage(xm_dt->tempImage);
+ xm_dt->tempImage = NULL;
+ xm_dt->shm = 0;
(void) XSetErrorHandler(old_handler);
return;
}
- xm_buffer->shm = 1;
+ xm_dt->shm = 1;
}
-#endif /* USE_XSHM */
+
+static void
+alloc_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
+ unsigned width, unsigned height)
+{
+ if (xm_dt->shm) {
+ alloc_shm_ximage(xm_dt, xmb, width, height);
+ return;
+ }
+
+ xm_dt->tempImage = XCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap, 0,
+ NULL, width, height,
+ 8, 0);
+}
static boolean
-xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+xm_is_displaytarget_format_supported( struct sw_winsys *ws,
enum pipe_format format )
{
/* TODO: check visuals or other sensible thing here */
@@ -195,8 +216,8 @@ xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
static void *
-xm_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+xm_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
@@ -205,21 +226,20 @@ xm_displaytarget_map(struct llvmpipe_winsys *ws,
}
static void
-xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
+xm_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
xm_dt->mapped = NULL;
}
static void
-xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
+xm_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
if (xm_dt->data) {
-#ifdef USE_XSHM
if (xm_dt->shminfo.shmid >= 0) {
shmdt(xm_dt->shminfo.shmaddr);
shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
@@ -227,11 +247,17 @@ xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
xm_dt->shminfo.shmid = -1;
xm_dt->shminfo.shmaddr = (char *) -1;
}
- else
-#endif
+ else {
FREE(xm_dt->data);
+ }
}
+ if (xm_dt->tempImage)
+ XDestroyImage(xm_dt->tempImage);
+
+ if (xm_dt->gc)
+ XFreeGC(xm_dt->display, xm_dt->gc);
+
FREE(xm_dt);
}
@@ -241,13 +267,14 @@ xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
* by the XMesaBuffer.
*/
static void
-xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
- struct llvmpipe_displaytarget *dt)
+xlib_sw_display(struct xlib_drawable *xlib_drawable,
+ struct sw_displaytarget *dt)
{
- XImage *ximage;
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
static boolean no_swap = 0;
static boolean firsttime = 1;
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ Display *display = xm_dt->display;
+ XImage *ximage;
if (firsttime) {
no_swap = getenv("SP_NO_RAST") != NULL;
@@ -257,28 +284,45 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
if (no_swap)
return;
-#ifdef USE_XSHM
- if (xm_dt->shm)
- {
- if (xm_dt->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(xm_dt->format) == 1);
- assert(util_format_get_blockheight(xm_dt->format) == 1);
- alloc_shm_ximage(xm_dt, xm_buffer,
- xm_dt->stride / util_format_get_blocksize(xm_dt->format),
- xm_dt->height);
+ if (xm_dt->drawable != xlib_drawable->drawable) {
+ if (xm_dt->gc) {
+ XFreeGC( display, xm_dt->gc );
+ xm_dt->gc = NULL;
+ }
+
+ if (xm_dt->tempImage) {
+ XDestroyImage( xm_dt->tempImage );
+ xm_dt->tempImage = NULL;
}
+ xm_dt->drawable = xlib_drawable->drawable;
+ }
+
+ if (xm_dt->tempImage == NULL) {
+ assert(util_format_get_blockwidth(xm_dt->format) == 1);
+ assert(util_format_get_blockheight(xm_dt->format) == 1);
+ alloc_ximage(xm_dt, xlib_drawable,
+ xm_dt->stride / util_format_get_blocksize(xm_dt->format),
+ xm_dt->height);
+ if (!xm_dt->tempImage)
+ return;
+ }
+
+ if (xm_dt->gc == NULL) {
+ xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL );
+ XSetFunction( display, xm_dt->gc, GXcopy );
+ }
+
+ if (xm_dt->shm)
+ {
ximage = xm_dt->tempImage;
ximage->data = xm_dt->data;
/* _debug_printf("XSHM\n"); */
- XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
}
- else
-#endif
- {
+ else {
/* display image in Window */
ximage = xm_dt->tempImage;
ximage->data = xm_dt->data;
@@ -293,7 +337,7 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
ximage->bytes_per_line = xm_dt->stride;
/* _debug_printf("XPUT\n"); */
- XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
}
}
@@ -303,30 +347,30 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
* by the XMesaBuffer.
*/
static void
-xm_displaytarget_display(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+xm_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
void *context_private)
{
- XMesaContext xmctx = (XMesaContext) context_private;
- struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
- xm_llvmpipe_display(xm_buffer, dt);
+ struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
+ xlib_sw_display(xlib_drawable, dt);
}
-static struct llvmpipe_displaytarget *
-xm_displaytarget_create(struct llvmpipe_winsys *winsys,
+static struct sw_displaytarget *
+xm_displaytarget_create(struct sw_winsys *winsys,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride)
{
- struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ struct xm_displaytarget *xm_dt;
unsigned nblocksy, size;
xm_dt = CALLOC_STRUCT(xm_displaytarget);
if(!xm_dt)
goto no_xm_dt;
+ xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display;
xm_dt->format = format;
xm_dt->width = width;
xm_dt->height = height;
@@ -335,7 +379,6 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
xm_dt->stride = align(util_format_get_stride(format, width), alignment);
size = xm_dt->stride * nblocksy;
-#ifdef USE_XSHM
if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
{
xm_dt->shminfo.shmid = -1;
@@ -346,7 +389,6 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
if(!xm_dt->data)
goto no_data;
}
-#endif
if(!xm_dt->data) {
xm_dt->data = align_malloc(size, alignment);
@@ -355,7 +397,7 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
}
*stride = xm_dt->stride;
- return (struct llvmpipe_displaytarget *)xm_dt;
+ return (struct sw_displaytarget *)xm_dt;
no_data:
FREE(xm_dt);
@@ -365,21 +407,22 @@ no_xm_dt:
static void
-xm_destroy( struct llvmpipe_winsys *ws )
+xm_destroy( struct sw_winsys *ws )
{
FREE(ws);
}
-static struct llvmpipe_winsys *
-xlib_create_llvmpipe_winsys( void )
+struct sw_winsys *
+xlib_create_sw_winsys( Display *display )
{
- struct xmesa_llvmpipe_winsys *ws;
+ struct xlib_sw_winsys *ws;
- ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
+ ws = CALLOC_STRUCT(xlib_sw_winsys);
if (!ws)
return NULL;
+ ws->display = display;
ws->base.destroy = xm_destroy;
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
@@ -394,49 +437,3 @@ xlib_create_llvmpipe_winsys( void )
return &ws->base;
}
-
-static struct pipe_screen *
-xlib_create_llvmpipe_screen( void )
-{
- struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_llvmpipe_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = llvmpipe_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-static void
-xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
- struct pipe_surface *surf)
-{
- struct llvmpipe_texture *texture = llvmpipe_texture(surf->texture);
-
- assert(texture->dt);
- if (texture->dt)
- xm_llvmpipe_display(xm_buffer, texture->dt);
-}
-
-
-struct xm_driver xlib_llvmpipe_driver =
-{
- .create_pipe_screen = xlib_create_llvmpipe_screen,
- .display_surface = xlib_llvmpipe_display_surface
-};
-
-
-
-#endif /* GALLIUM_LLVMPIPE */
diff --git a/src/gallium/winsys/xlib/xmesa.h b/src/gallium/winsys/xlib/xmesa.h
deleted file mode 100644
index 98139af833..0000000000
--- a/src/gallium/winsys/xlib/xmesa.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * Mesa/X11 interface. This header file serves as the documentation for
- * the Mesa/X11 interface functions.
- *
- * Note: this interface isn't intended for user programs. It's primarily
- * just for implementing the pseudo-GLX interface.
- */
-
-
-/* Sample Usage:
-
-In addition to the usual X calls to select a visual, create a colormap
-and create a window, you must do the following to use the X/Mesa interface:
-
-1. Call XMesaCreateVisual() to make an XMesaVisual from an XVisualInfo.
-
-2. Call XMesaCreateContext() to create an X/Mesa rendering context, given
- the XMesaVisual.
-
-3. Call XMesaCreateWindowBuffer() to create an XMesaBuffer from an X window
- and XMesaVisual.
-
-4. Call XMesaMakeCurrent() to bind the XMesaBuffer to an XMesaContext and
- to make the context the current one.
-
-5. Make gl* calls to render your graphics.
-
-6. Use XMesaSwapBuffers() when double buffering to swap front/back buffers.
-
-7. Before the X window is destroyed, call XMesaDestroyBuffer().
-
-8. Before exiting, call XMesaDestroyVisual and XMesaDestroyContext.
-
-*/
-
-
-
-
-#ifndef XMESA_H
-#define XMESA_H
-
-#ifdef __VMS
-#include <GL/vms_x_fix.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef XFree86Server
-#include "xmesa_xf86.h"
-#else
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include "xmesa_x.h"
-#endif
-#include "GL/gl.h"
-
-#ifdef AMIWIN
-#include <pragmas/xlib_pragmas.h>
-extern struct Library *XLibBase;
-#endif
-
-
-#define XMESA_MAJOR_VERSION 6
-#define XMESA_MINOR_VERSION 3
-
-
-
-/*
- * Values passed to XMesaGetString:
- */
-#define XMESA_VERSION 1
-#define XMESA_EXTENSIONS 2
-
-
-/*
- * Values passed to XMesaSetFXmode:
- */
-#define XMESA_FX_WINDOW 1
-#define XMESA_FX_FULLSCREEN 2
-
-
-
-typedef struct xmesa_context *XMesaContext;
-
-typedef struct xmesa_visual *XMesaVisual;
-
-typedef struct xmesa_buffer *XMesaBuffer;
-
-
-
-/*
- * Create a new X/Mesa visual.
- * Input: display - X11 display
- * visinfo - an XVisualInfo pointer
- * rgb_flag - GL_TRUE = RGB mode,
- * GL_FALSE = color index mode
- * alpha_flag - alpha buffer requested?
- * db_flag - GL_TRUE = double-buffered,
- * GL_FALSE = single buffered
- * stereo_flag - stereo visual?
- * ximage_flag - GL_TRUE = use an XImage for back buffer,
- * GL_FALSE = use an off-screen pixmap for back buffer
- * depth_size - requested bits/depth values, or zero
- * stencil_size - requested bits/stencil values, or zero
- * accum_red_size - requested bits/red accum values, or zero
- * accum_green_size - requested bits/green accum values, or zero
- * accum_blue_size - requested bits/blue accum values, or zero
- * accum_alpha_size - requested bits/alpha accum values, or zero
- * num_samples - number of samples/pixel if multisampling, or zero
- * level - visual level, usually 0
- * visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
- * Return; a new XMesaVisual or 0 if error.
- */
-extern XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
- XMesaVisualInfo visinfo,
- GLboolean rgb_flag,
- GLboolean alpha_flag,
- GLboolean db_flag,
- GLboolean stereo_flag,
- GLboolean ximage_flag,
- GLint depth_size,
- GLint stencil_size,
- GLint accum_red_size,
- GLint accum_green_size,
- GLint accum_blue_size,
- GLint accum_alpha_size,
- GLint num_samples,
- GLint level,
- GLint visualCaveat );
-
-/*
- * Destroy an XMesaVisual, but not the associated XVisualInfo.
- */
-extern void XMesaDestroyVisual( XMesaVisual v );
-
-
-
-/*
- * Create a new XMesaContext for rendering into an X11 window.
- *
- * Input: visual - an XMesaVisual
- * share_list - another XMesaContext with which to share display
- * lists or NULL if no sharing is wanted.
- * Return: an XMesaContext or NULL if error.
- */
-extern XMesaContext XMesaCreateContext( XMesaVisual v,
- XMesaContext share_list );
-
-
-/*
- * Destroy a rendering context as returned by XMesaCreateContext()
- */
-extern void XMesaDestroyContext( XMesaContext c );
-
-
-#ifdef XFree86Server
-/*
- * These are the extra routines required for integration with XFree86.
- * None of these routines should be user visible. -KEM
- */
-extern GLboolean XMesaForceCurrent( XMesaContext c );
-
-extern GLboolean XMesaLoseCurrent( XMesaContext c );
-
-extern GLboolean XMesaCopyContext( XMesaContext src,
- XMesaContext dst,
- GLuint mask );
-#endif /* XFree86Server */
-
-
-/*
- * Create an XMesaBuffer from an X window.
- */
-extern XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w );
-
-
-/*
- * Create an XMesaBuffer from an X pixmap.
- */
-extern XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
- XMesaPixmap p,
- XMesaColormap cmap );
-
-
-/*
- * Destroy an XMesaBuffer, but not the corresponding window or pixmap.
- */
-extern void XMesaDestroyBuffer( XMesaBuffer b );
-
-
-/*
- * Return the XMesaBuffer handle which corresponds to an X drawable, if any.
- *
- * New in Mesa 2.3.
- */
-extern XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy,
- XMesaDrawable d );
-
-
-
-/*
- * Bind a buffer to a context and make the context the current one.
- */
-extern GLboolean XMesaMakeCurrent( XMesaContext c,
- XMesaBuffer b );
-
-
-/*
- * Bind two buffers (read and draw) to a context and make the
- * context the current one.
- * New in Mesa 3.3
- */
-extern GLboolean XMesaMakeCurrent2( XMesaContext c,
- XMesaBuffer drawBuffer,
- XMesaBuffer readBuffer );
-
-
-/*
- * Unbind the current context from its buffer.
- */
-extern GLboolean XMesaUnbindContext( XMesaContext c );
-
-
-/*
- * Return a handle to the current context.
- */
-extern XMesaContext XMesaGetCurrentContext( void );
-
-
-/*
- * Return handle to the current (draw) buffer.
- */
-extern XMesaBuffer XMesaGetCurrentBuffer( void );
-
-
-/*
- * Return handle to the current read buffer.
- * New in Mesa 3.3
- */
-extern XMesaBuffer XMesaGetCurrentReadBuffer( void );
-
-
-/*
- * Swap the front and back buffers for the given buffer. No action is
- * taken if the buffer is not double buffered.
- */
-extern void XMesaSwapBuffers( XMesaBuffer b );
-
-
-/*
- * Copy a sub-region of the back buffer to the front buffer.
- *
- * New in Mesa 2.6
- */
-extern void XMesaCopySubBuffer( XMesaBuffer b,
- int x,
- int y,
- int width,
- int height );
-
-
-/*
- * Return a pointer to the the Pixmap or XImage being used as the back
- * color buffer of an XMesaBuffer. This function is a way to get "under
- * the hood" of X/Mesa so one can manipulate the back buffer directly.
- * Input: b - the XMesaBuffer
- * Output: pixmap - pointer to back buffer's Pixmap, or 0
- * ximage - pointer to back buffer's XImage, or NULL
- * Return: GL_TRUE = context is double buffered
- * GL_FALSE = context is single buffered
- */
-extern GLboolean XMesaGetBackBuffer( XMesaBuffer b,
- XMesaPixmap *pixmap,
- XMesaImage **ximage );
-
-
-
-/*
- * Return the depth buffer associated with an XMesaBuffer.
- * Input: b - the XMesa buffer handle
- * Output: width, height - size of buffer in pixels
- * bytesPerValue - bytes per depth value (2 or 4)
- * buffer - pointer to depth buffer values
- * Return: GL_TRUE or GL_FALSE to indicate success or failure.
- *
- * New in Mesa 2.4.
- */
-extern GLboolean XMesaGetDepthBuffer( XMesaBuffer b,
- GLint *width,
- GLint *height,
- GLint *bytesPerValue,
- void **buffer );
-
-
-
-/*
- * Flush/sync a context
- */
-extern void XMesaFlush( XMesaContext c );
-
-
-
-/*
- * Get an X/Mesa-specific string.
- * Input: name - either XMESA_VERSION or XMESA_EXTENSIONS
- */
-extern const char *XMesaGetString( XMesaContext c, int name );
-
-
-
-/*
- * Scan for XMesaBuffers whose window/pixmap has been destroyed, then free
- * any memory used by that buffer.
- *
- * New in Mesa 2.3.
- */
-extern void XMesaGarbageCollect( void );
-
-
-
-/*
- * Return a dithered pixel value.
- * Input: c - XMesaContext
- * x, y - window coordinate
- * red, green, blue, alpha - color components in [0,1]
- * Return: pixel value
- *
- * New in Mesa 2.3.
- */
-extern unsigned long XMesaDitherColor( XMesaContext xmesa,
- GLint x,
- GLint y,
- GLfloat red,
- GLfloat green,
- GLfloat blue,
- GLfloat alpha );
-
-
-
-/*
- * 3Dfx Glide driver only!
- * Set 3Dfx/Glide full-screen or window rendering mode.
- * Input: mode - either XMESA_FX_WINDOW (window rendering mode) or
- * XMESA_FX_FULLSCREEN (full-screen rendering mode)
- * Return: GL_TRUE if success
- * GL_FALSE if invalid mode or if not using 3Dfx driver
- *
- * New in Mesa 2.6.
- */
-extern GLboolean XMesaSetFXmode( GLint mode );
-
-
-
-/*
- * Reallocate the back/depth/stencil/accum/etc/ buffers associated with
- * buffer <b> if its size has changed.
- *
- * New in Mesa 4.0.2
- */
-extern void XMesaResizeBuffers( XMesaBuffer b );
-
-
-
-/*
- * Create a pbuffer.
- * New in Mesa 4.1
- */
-extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
- unsigned int width, unsigned int height);
-
-
-
-/*
- * Texture from Pixmap
- * New in Mesa 7.1
- */
-extern void
-XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
- const int *attrib_list);
-
-extern void
-XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer);
-
-
-extern XMesaBuffer
-XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
- XMesaColormap cmap,
- int format, int target, int mipmap);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/src/gallium/winsys/xlib/xmesa_x.h b/src/gallium/winsys/xlib/xmesa_x.h
deleted file mode 100644
index 865bab4313..0000000000
--- a/src/gallium/winsys/xlib/xmesa_x.h
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <kevin@precisioninsight.com>
- *
- * When we're building the XMesa driver for stand-alone Mesa we
- * include this file when building the xm_*.c files.
- * We need to define some types and macros differently when building
- * in the Xserver vs. stand-alone Mesa.
- */
-
-#ifndef _XMESA_X_H_
-#define _XMESA_X_H_
-
-typedef Display XMesaDisplay;
-typedef Pixmap XMesaPixmap;
-typedef Colormap XMesaColormap;
-typedef Drawable XMesaDrawable;
-typedef Window XMesaWindow;
-typedef GC XMesaGC;
-typedef XVisualInfo *XMesaVisualInfo;
-typedef XImage XMesaImage;
-typedef XPoint XMesaPoint;
-typedef XColor XMesaColor;
-
-#define XMesaDestroyImage XDestroyImage
-
-#define XMesaPutPixel XPutPixel
-#define XMesaGetPixel XGetPixel
-
-#define XMesaSetForeground XSetForeground
-#define XMesaSetBackground XSetBackground
-#define XMesaSetPlaneMask XSetPlaneMask
-#define XMesaSetFunction XSetFunction
-#define XMesaSetFillStyle XSetFillStyle
-#define XMesaSetTile XSetTile
-
-#define XMesaDrawPoint XDrawPoint
-#define XMesaDrawPoints XDrawPoints
-#define XMesaDrawLine XDrawLine
-#define XMesaFillRectangle XFillRectangle
-#define XMesaGetImage XGetImage
-#define XMesaPutImage XPutImage
-#define XMesaCopyArea XCopyArea
-
-#define XMesaCreatePixmap XCreatePixmap
-#define XMesaFreePixmap XFreePixmap
-#define XMesaFreeGC XFreeGC
-
-#define GET_COLORMAP_SIZE(__v) __v->visinfo->colormap_size
-#define GET_REDMASK(__v) __v->mesa_visual.redMask
-#define GET_GREENMASK(__v) __v->mesa_visual.greenMask
-#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask
-#define GET_VISUAL_DEPTH(__v) __v->visinfo->depth
-#define GET_BLACK_PIXEL(__v) BlackPixel(__v->display, __v->mesa_visual.screen)
-#define CHECK_BYTE_ORDER(__v) host_byte_order()==ImageByteOrder(__v->display)
-#define CHECK_FOR_HPCR(__v) XInternAtom(__v->display, "_HP_RGB_SMOOTH_MAP_LIST", True)
-
-#endif