aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/Makefile4
-rw-r--r--src/gallium/auxiliary/SConscript7
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.c141
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.cpp357
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.h10
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp60
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c5
-rw-r--r--src/gallium/auxiliary/os/os_thread.h3
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c11
-rw-r--r--src/gallium/auxiliary/rbug/rbug_context.c4
-rw-r--r--src/gallium/auxiliary/rbug/rbug_context.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c2
-rw-r--r--src/gallium/auxiliary/util/u_blit.c156
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c7
-rw-r--r--src/gallium/auxiliary/util/u_cache.c170
-rw-r--r--src/gallium/auxiliary/util/u_cache.h4
-rw-r--r--src/gallium/auxiliary/util/u_caps.c3
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c4
-rw-r--r--src/gallium/auxiliary/util/u_format.csv6
-rw-r--r--src/gallium/auxiliary/util/u_format_latc.c328
-rw-r--r--src/gallium/auxiliary/util/u_format_latc.h108
-rw-r--r--src/gallium/auxiliary/util/u_format_rgtc.c20
-rw-r--r--src/gallium/auxiliary/util/u_format_rgtc.h6
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py1
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c108
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h9
-rw-r--r--src/gallium/auxiliary/util/u_pstipple.c434
-rw-r--r--src/gallium/auxiliary/util/u_pstipple.h56
-rw-r--r--src/gallium/auxiliary/util/u_resource.c8
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.h3
-rw-r--r--src/gallium/auxiliary/util/u_surface.c2
-rw-r--r--src/gallium/auxiliary/util/u_transfer.c7
-rw-r--r--src/gallium/auxiliary/util/u_transfer.h12
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c4
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c15
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c2
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_context.c10
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c2
-rw-r--r--src/gallium/docs/d3d11ddi.txt4
-rw-r--r--src/gallium/docs/source/context.rst10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c14
-rw-r--r--src/gallium/drivers/cell/ppu/cell_fence.c6
-rw-r--r--src/gallium/drivers/cell/ppu/cell_fence.h9
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.c7
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c3
-rw-r--r--src/gallium/drivers/failover/fo_context.c17
-rw-r--r--src/gallium/drivers/galahad/glhd_context.c20
-rw-r--r--src/gallium/drivers/galahad/glhd_screen.c20
-rw-r--r--src/gallium/drivers/i915/TODO17
-rw-r--r--src/gallium/drivers/i915/i915_batch.h3
-rw-r--r--src/gallium/drivers/i915/i915_batchbuffer.h10
-rw-r--r--src/gallium/drivers/i915/i915_clear.c105
-rw-r--r--src/gallium/drivers/i915/i915_context.c24
-rw-r--r--src/gallium/drivers/i915/i915_context.h46
-rw-r--r--src/gallium/drivers/i915/i915_debug.c3
-rw-r--r--src/gallium/drivers/i915/i915_flush.c23
-rw-r--r--src/gallium/drivers/i915/i915_prim_emit.c1
-rw-r--r--src/gallium/drivers/i915/i915_prim_vbuf.c3
-rw-r--r--src/gallium/drivers/i915/i915_reg.h1
-rw-r--r--src/gallium/drivers/i915/i915_resource.c1
-rw-r--r--src/gallium/drivers/i915/i915_resource_buffer.c1
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c9
-rw-r--r--src/gallium/drivers/i915/i915_screen.c29
-rw-r--r--src/gallium/drivers/i915/i915_screen.h1
-rw-r--r--src/gallium/drivers/i915/i915_state.c70
-rw-r--r--src/gallium/drivers/i915/i915_state.h1
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c1
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c37
-rw-r--r--src/gallium/drivers/i915/i915_state_static.c106
-rw-r--r--src/gallium/drivers/i915/i915_surface.c152
-rw-r--r--src/gallium/drivers/i965/brw_pipe_flush.c1
-rw-r--r--src/gallium/drivers/i965/brw_resource_buffer.c20
-rw-r--r--src/gallium/drivers/i965/brw_resource_texture.c43
-rw-r--r--src/gallium/drivers/i965/brw_screen.c16
-rw-r--r--src/gallium/drivers/identity/id_context.c20
-rw-r--r--src/gallium/drivers/identity/id_screen.c20
-rw-r--r--src/gallium/drivers/llvmpipe/README23
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c47
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_setup.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h10
-rw-r--r--src/gallium/drivers/noop/noop_pipe.c13
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c1
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.c9
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c34
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h4
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c47
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.c17
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c42
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_3d.xml.h9
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c54
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h4
-rw-r--r--src/gallium/drivers/nvc0/nvc0_graph_macros.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_miptree.c1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc.c8
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc.h14
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_emit.c7
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_optimize.c6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_pc_print.c16
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.c11
-rw-r--r--src/gallium/drivers/nvc0/nvc0_push.c89
-rw-r--r--src/gallium/drivers/nvc0/nvc0_resource.c20
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c19
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_shader_state.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c33
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c84
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c4
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.c7
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c6
-rw-r--r--src/gallium/drivers/nvfx/nvfx_resource.c9
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_emit.c2
-rw-r--r--src/gallium/drivers/r300/r300_blit.c6
-rw-r--r--src/gallium/drivers/r300/r300_context.c10
-rw-r--r--src/gallium/drivers/r300/r300_context.h14
-rw-r--r--src/gallium/drivers/r300/r300_emit.c107
-rw-r--r--src/gallium/drivers/r300/r300_emit.h3
-rw-r--r--src/gallium/drivers/r300/r300_flush.c23
-rw-r--r--src/gallium/drivers/r300/r300_fs.c2
-rw-r--r--src/gallium/drivers/r300/r300_render.c259
-rw-r--r--src/gallium/drivers/r300/r300_resource.c8
-rw-r--r--src/gallium/drivers/r300/r300_screen.c53
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c16
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h3
-rw-r--r--src/gallium/drivers/r300/r300_state.c69
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c4
-rw-r--r--src/gallium/drivers/r300/r300_texture.c15
-rw-r--r--src/gallium/drivers/r300/r300_texture_desc.c6
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c23
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h13
-rw-r--r--src/gallium/drivers/r600/eg_asm.c12
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c54
-rw-r--r--src/gallium/drivers/r600/r600_asm.c96
-rw-r--r--src/gallium/drivers/r600/r600_asm.h2
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c9
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c23
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h5
-rw-r--r--src/gallium/drivers/r600/r600_query.c2
-rw-r--r--src/gallium/drivers/r600/r600_resource.c1
-rw-r--r--src/gallium/drivers/r600/r600_shader.c238
-rw-r--r--src/gallium/drivers/r600/r600_state.c187
-rw-r--r--src/gallium/drivers/r600/r600_texture.c25
-rw-r--r--src/gallium/drivers/r600/r700_asm.c9
-rw-r--r--src/gallium/drivers/rbug/rbug_context.c231
-rw-r--r--src/gallium/drivers/rbug/rbug_core.c2
-rw-r--r--src/gallium/drivers/rbug/rbug_screen.c20
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c26
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_fence.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c54
-rw-r--r--src/gallium/drivers/svga/svga_cmd.c5
-rw-r--r--src/gallium/drivers/svga/svga_cmd.h3
-rw-r--r--src/gallium/drivers/svga/svga_context.c3
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c14
-rw-r--r--src/gallium/drivers/svga/svga_pipe_flush.c33
-rw-r--r--src/gallium/drivers/svga/svga_resource.c1
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c287
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h20
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c50
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.h4
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c68
-rw-r--r--src/gallium/drivers/svga/svga_screen.c22
-rw-r--r--src/gallium/drivers/svga/svga_screen.h4
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c9
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h7
-rw-r--r--src/gallium/drivers/trace/tr_context.c30
-rw-r--r--src/gallium/drivers/trace/tr_dump.c16
-rw-r--r--src/gallium/drivers/trace/tr_dump.h5
-rw-r--r--src/gallium/drivers/trace/tr_screen.c28
-rw-r--r--src/gallium/include/pipe/p_context.h24
-rw-r--r--src/gallium/include/pipe/p_defines.h31
-rw-r--r--src/gallium/include/pipe/p_format.h5
-rw-r--r--src/gallium/include/pipe/p_screen.h20
-rw-r--r--src/gallium/include/pipe/p_video_context.h3
-rw-r--r--src/gallium/include/state_tracker/st_api.h5
-rw-r--r--src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp2
-rw-r--r--src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h2
-rw-r--r--src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h20
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c4
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c24
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c2
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c2
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c19
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.c4
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c4
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c2
-rw-r--r--src/gallium/state_trackers/egl/fbdev/native_fbdev.c2
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c2
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c85
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c15
-rw-r--r--src/gallium/state_trackers/python/p_context.i4
-rw-r--r--src/gallium/state_trackers/python/p_device.i6
-rw-r--r--src/gallium/state_trackers/vdpau/decode.c19
-rw-r--r--src/gallium/state_trackers/vdpau/query.c3
-rw-r--r--src/gallium/state_trackers/vega/api_context.c7
-rw-r--r--src/gallium/state_trackers/vega/api_images.c5
-rw-r--r--src/gallium/state_trackers/vega/image.c10
-rw-r--r--src/gallium/state_trackers/vega/mask.c2
-rw-r--r--src/gallium/state_trackers/vega/renderer.c8
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c2
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c4
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c20
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c11
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c8
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c21
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c9
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c16
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c20
-rw-r--r--src/gallium/targets/graw-gdi/graw_gdi.c4
-rw-r--r--src/gallium/tests/graw/SConscript2
-rw-r--r--src/gallium/tests/graw/clear.c2
-rw-r--r--src/gallium/tests/graw/fs-test.c2
-rw-r--r--src/gallium/tests/graw/gs-test.c2
-rw-r--r--src/gallium/tests/graw/quad-sample.c2
-rw-r--r--src/gallium/tests/graw/quad-tex.c2
-rw-r--r--src/gallium/tests/graw/shader-leak.c2
-rw-r--r--src/gallium/tests/graw/tri-gs.c2
-rw-r--r--src/gallium/tests/graw/tri-instanced.c2
-rw-r--r--src/gallium/tests/graw/tri.c2
-rw-r--r--src/gallium/tests/graw/vs-test.c2
-rw-r--r--src/gallium/tests/trivial/quad-tex.c2
-rw-r--r--src/gallium/tests/trivial/tri.c2
-rw-r--r--src/gallium/tests/unit/SConscript33
-rw-r--r--src/gallium/winsys/r600/drm/r600_bo.c2
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c3
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c24
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c11
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_cs.c17
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_cs.h5
-rw-r--r--src/gallium/winsys/sw/dri/SConscript2
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c2
-rw-r--r--src/gallium/winsys/sw/xlib/SConscript2
258 files changed, 4223 insertions, 2453 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index f5fea1f71b8..869b2d486a4 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -110,6 +110,7 @@ C_SOURCES = \
util/u_draw_quad.c \
util/u_format.c \
util/u_format_other.c \
+ util/u_format_latc.c \
util/u_format_s3tc.c \
util/u_format_rgtc.c \
util/u_format_srgb.c \
@@ -130,6 +131,7 @@ C_SOURCES = \
util/u_network.c \
util/u_math.c \
util/u_mm.c \
+ util/u_pstipple.c \
util/u_rect.c \
util/u_ringbuffer.c \
util/u_sampler.c \
@@ -159,7 +161,6 @@ GALLIVM_SOURCES = \
gallivm/lp_bld_bitarit.c \
gallivm/lp_bld_const.c \
gallivm/lp_bld_conv.c \
- gallivm/lp_bld_debug.c \
gallivm/lp_bld_flow.c \
gallivm/lp_bld_format_aos.c \
gallivm/lp_bld_format_soa.c \
@@ -187,6 +188,7 @@ GALLIVM_SOURCES = \
draw/draw_pt_fetch_shade_pipeline_llvm.c
GALLIVM_CPP_SOURCES = \
+ gallivm/lp_bld_debug.cpp \
gallivm/lp_bld_misc.cpp
GENERATED_SOURCES = \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index f4ab8a50da4..84519cfd048 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -157,6 +157,7 @@ source = [
'util/u_draw_quad.c',
'util/u_format.c',
'util/u_format_other.c',
+ 'util/u_format_latc.c',
'util/u_format_s3tc.c',
'util/u_format_rgtc.c',
'util/u_format_srgb.c',
@@ -177,6 +178,7 @@ source = [
'util/u_network.c',
'util/u_math.c',
'util/u_mm.c',
+ 'util/u_pstipple.c',
'util/u_rect.c',
'util/u_resource.c',
'util/u_ringbuffer.c',
@@ -199,16 +201,13 @@ source = [
]
if env['llvm']:
- if env['UDIS86']:
- env.Append(CPPDEFINES = [('HAVE_UDIS86', '1')])
-
source += [
'gallivm/lp_bld_arit.c',
'gallivm/lp_bld_assert.c',
'gallivm/lp_bld_bitarit.c',
'gallivm/lp_bld_const.c',
'gallivm/lp_bld_conv.c',
- 'gallivm/lp_bld_debug.c',
+ 'gallivm/lp_bld_debug.cpp',
'gallivm/lp_bld_flow.c',
'gallivm/lp_bld_format_aos.c',
'gallivm/lp_bld_format_soa.c',
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index ea62c9739fd..fe3627be867 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -388,13 +388,6 @@ pstip_update_texture(struct pstip_stage *pstip)
uint i, j;
ubyte *data;
- /* XXX: want to avoid flushing just because we use stipple:
- *
- * Flush should no longer be necessary if driver is properly
- * interleaving drawing and transfers on a given context:
- */
- pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL );
-
transfer = pipe_get_transfer(pipe, pstip->texture, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
data = pipe->transfer_map(pipe, transfer);
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index bfb72d50efa..e6d187e9774 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -33,6 +33,7 @@
#include "draw_context.h"
#include "draw_private.h"
+#include "draw_vertex.h"
struct draw_context;
@@ -48,7 +49,7 @@ struct draw_variant_input
struct draw_variant_output
{
- enum pipe_format format; /* output format */
+ enum attrib_emit format; /* output format */
unsigned vs_output:8; /* which vertex shader output is this? */
unsigned offset:24; /* offset into output vertex */
};
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index 8f8bbe7cb88..f1dd4487732 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -384,7 +384,7 @@ static void emit_store_R8G8B8A8_UNORM( struct aos_compilation *cp,
static boolean emit_output( struct aos_compilation *cp,
struct x86_reg ptr,
struct x86_reg dataXMM,
- unsigned format )
+ enum attrib_emit format )
{
switch (format) {
case EMIT_1F:
@@ -422,7 +422,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp )
unsigned i;
for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) {
- unsigned format = cp->vaos->base.key.element[i].out.format;
+ enum attrib_emit format = cp->vaos->base.key.element[i].out.format;
unsigned offset = cp->vaos->base.key.element[i].out.offset;
unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.c b/src/gallium/auxiliary/gallivm/lp_bld_debug.c
deleted file mode 100644
index 93e56553d7b..00000000000
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.c
+++ /dev/null
@@ -1,141 +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.
- *
- **************************************************************************/
-
-
-#ifdef HAVE_UDIS86
-#include <udis86.h>
-#endif
-
-#include "util/u_math.h"
-#include "util/u_debug.h"
-#include "lp_bld_debug.h"
-
-
-/**
- * Check alignment.
- *
- * It is important that this check is not implemented as a macro or inlined
- * function, as the compiler assumptions in respect to alignment of global
- * and stack variables would often make the check a no op, defeating the
- * whole purpose of the exercise.
- */
-boolean
-lp_check_alignment(const void *ptr, unsigned alignment)
-{
- assert(util_is_power_of_two(alignment));
- return ((uintptr_t)ptr & (alignment - 1)) == 0;
-}
-
-
-void
-lp_disassemble(const void* func)
-{
-#ifdef HAVE_UDIS86
- ud_t ud_obj;
- uint64_t max_jmp_pc;
- uint inst_no;
- boolean emit_addrs = TRUE, emit_line_nos = FALSE;
-
- ud_init(&ud_obj);
-
- ud_set_input_buffer(&ud_obj, (void*)func, 0xffff);
-
- max_jmp_pc = (uint64_t) (uintptr_t) func;
- ud_set_pc(&ud_obj, max_jmp_pc);
-
-#ifdef PIPE_ARCH_X86
- ud_set_mode(&ud_obj, 32);
-#endif
-#ifdef PIPE_ARCH_X86_64
- ud_set_mode(&ud_obj, 64);
-#endif
-
- ud_set_syntax(&ud_obj, UD_SYN_ATT);
-
- while (ud_disassemble(&ud_obj)) {
-
- if (emit_addrs) {
-#ifdef PIPE_ARCH_X86
- debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj));
-#endif
-#ifdef PIPE_ARCH_X86_64
- debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj));
-#endif
- }
- else if (emit_line_nos) {
- debug_printf("%6d:\t", inst_no);
- inst_no++;
- }
-#if 0
- debug_printf("%-16s ", ud_insn_hex(&ud_obj));
-#endif
-
- debug_printf("%s\n", ud_insn_asm(&ud_obj));
-
- if(ud_obj.mnemonic != UD_Icall) {
- unsigned i;
- for(i = 0; i < 3; ++i) {
- const struct ud_operand *op = &ud_obj.operand[i];
- if (op->type == UD_OP_JIMM){
- uint64_t pc = ud_obj.pc;
-
- switch (op->size) {
- case 8:
- pc += op->lval.sbyte;
- break;
- case 16:
- pc += op->lval.sword;
- break;
- case 32:
- pc += op->lval.sdword;
- break;
- default:
- break;
- }
- if(pc > max_jmp_pc)
- max_jmp_pc = pc;
- }
- }
- }
-
- if (ud_obj.mnemonic == UD_Iinvalid ||
- (ud_insn_off(&ud_obj) >= max_jmp_pc &&
- (ud_obj.mnemonic == UD_Iret ||
- ud_obj.mnemonic == UD_Ijmp)))
- break;
- }
-
-#if 0
- /* Print GDB command, useful to verify udis86 output */
- debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc);
-#endif
-
- debug_printf("\n");
-#else
- (void)func;
-#endif
-}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
new file mode 100644
index 00000000000..bb2c82fe0ed
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
@@ -0,0 +1,357 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2011 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 <llvm-c/Core.h>
+#include <llvm/Target/TargetMachine.h>
+#include <llvm/Target/TargetRegistry.h>
+#include <llvm/Target/TargetSelect.h>
+#include <llvm/Target/TargetInstrInfo.h>
+#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/MemoryObject.h>
+#include <llvm/System/Host.h>
+
+#if HAVE_LLVM >= 0x0207
+#include <llvm/MC/MCDisassembler.h>
+#include <llvm/MC/MCAsmInfo.h>
+#include <llvm/MC/MCInst.h>
+#include <llvm/MC/MCInstPrinter.h>
+#endif /* HAVE_LLVM >= 0x0207 */
+
+#include "util/u_math.h"
+#include "util/u_debug.h"
+
+#include "lp_bld_debug.h"
+
+
+
+/**
+ * Check alignment.
+ *
+ * It is important that this check is not implemented as a macro or inlined
+ * function, as the compiler assumptions in respect to alignment of global
+ * and stack variables would often make the check a no op, defeating the
+ * whole purpose of the exercise.
+ */
+extern "C" boolean
+lp_check_alignment(const void *ptr, unsigned alignment)
+{
+ assert(util_is_power_of_two(alignment));
+ return ((uintptr_t)ptr & (alignment - 1)) == 0;
+}
+
+
+class raw_debug_ostream :
+ public llvm::raw_ostream
+{
+ uint64_t pos;
+
+ void write_impl(const char *Ptr, size_t Size);
+ uint64_t current_pos() { return pos; }
+ uint64_t current_pos() const { return pos; }
+
+#if HAVE_LLVM >= 0x207
+ uint64_t preferred_buffer_size() { return 512; }
+#else
+ size_t preferred_buffer_size() { return 512; }
+#endif
+};
+
+
+void
+raw_debug_ostream::write_impl(const char *Ptr, size_t Size)
+{
+ if (Size > 0) {
+ char *lastPtr = (char *)&Ptr[Size];
+ char last = *lastPtr;
+ *lastPtr = 0;
+ _debug_printf("%*s", Size, Ptr);
+ *lastPtr = last;
+ pos += Size;
+ }
+}
+
+
+/**
+ * Same as LLVMDumpValue, but through our debugging channels.
+ */
+extern "C" void
+lp_debug_dump_value(LLVMValueRef value)
+{
+#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED)
+ raw_debug_ostream os;
+ llvm::unwrap(value)->print(os);
+ os.flush();
+#else
+ LLVMDumpValue(value);
+#endif
+}
+
+
+#if HAVE_LLVM >= 0x0207
+/*
+ * MemoryObject wrapper around a buffer of memory, to be used by MC
+ * disassembler.
+ */
+class BufferMemoryObject:
+ public llvm::MemoryObject
+{
+private:
+ const uint8_t *Bytes;
+ uint64_t Length;
+public:
+ BufferMemoryObject(const uint8_t *bytes, uint64_t length) :
+ Bytes(bytes), Length(length)
+ {
+ }
+
+ uint64_t getBase() const
+ {
+ return 0;
+ }
+
+ uint64_t getExtent() const
+ {
+ return Length;
+ }
+
+ int readByte(uint64_t addr, uint8_t *byte) const
+ {
+ if (addr > getExtent())
+ return -1;
+ *byte = Bytes[addr];
+ return 0;
+ }
+};
+#endif /* HAVE_LLVM >= 0x0207 */
+
+
+/*
+ * Disassemble a function, using the LLVM MC disassembler.
+ *
+ * See also:
+ * - http://blog.llvm.org/2010/01/x86-disassembler.html
+ * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html
+ */
+extern "C" void
+lp_disassemble(const void* func)
+{
+#if HAVE_LLVM >= 0x0207
+ using namespace llvm;
+
+ const uint8_t *bytes = (const uint8_t *)func;
+
+ /*
+ * Limit disassembly to this extent
+ */
+ const uint64_t extent = 0x10000;
+
+ uint64_t max_pc = 0;
+
+ /*
+ * Initialize all used objects.
+ */
+
+ std::string Triple = sys::getHostTriple();
+
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget(Triple, Error);
+
+#if HAVE_LLVM >= 0x0208
+ InitializeNativeTargetAsmPrinter();
+#else
+ InitializeAllAsmPrinters();
+#endif
+
+ InitializeAllDisassemblers();
+
+ OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple));
+
+ if (!AsmInfo) {
+ debug_printf("error: no assembly info for target %s\n", Triple.c_str());
+ return;
+ }
+
+ OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler());
+ if (!DisAsm) {
+ debug_printf("error: no disassembler for target %s\n", Triple.c_str());
+ return;
+ }
+
+ raw_debug_ostream Out;
+
+ int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
+#if HAVE_LLVM >= 0x0208
+ OwningPtr<MCInstPrinter> Printer(
+ T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo));
+#else
+ OwningPtr<MCInstPrinter> Printer(
+ T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out));
+#endif
+ if (!Printer) {
+ debug_printf("error: no instruction printer for target %s\n", Triple.c_str());
+ return;
+ }
+
+ TargetMachine *TM = T->createTargetMachine(Triple, "");
+
+ const TargetInstrInfo *TII = TM->getInstrInfo();
+
+ /*
+ * Wrap the data in a MemoryObject
+ */
+ BufferMemoryObject memoryObject((const uint8_t *)bytes, extent);
+
+ uint64_t pc;
+ pc = 0;
+ while (true) {
+ MCInst Inst;
+ uint64_t Size;
+
+ /*
+ * Print address. We use addresses relative to the start of the function,
+ * so that between runs.
+ */
+
+ debug_printf("%6lu:\t", (unsigned long)pc);
+
+ if (!DisAsm->getInstruction(Inst, Size, memoryObject,
+ pc,
+ nulls())) {
+ debug_printf("invalid\n");
+ pc += 1;
+ }
+
+ /*
+ * Output the bytes in hexidecimal format.
+ */
+
+ if (0) {
+ unsigned i;
+ for (i = 0; i < Size; ++i) {
+ debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]);
+ }
+ for (; i < 16; ++i) {
+ debug_printf(" ");
+ }
+ }
+
+ /*
+ * Print the instruction.
+ */
+
+#if HAVE_LLVM >= 0x208
+ Printer->printInst(&Inst, Out);
+#else
+ Printer->printInst(&Inst);
+#endif
+ Out.flush();
+
+ /*
+ * Advance.
+ */
+
+ pc += Size;
+
+ const TargetInstrDesc &TID = TII->get(Inst.getOpcode());
+
+ /*
+ * Keep track of forward jumps to a nearby address.
+ */
+
+ if (TID.isBranch()) {
+ for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
+ const MCOperand &operand = Inst.getOperand(i);
+ if (operand.isImm()) {
+ uint64_t jump;
+
+ /*
+ * FIXME: Handle both relative and absolute addresses correctly.
+ * EDInstInfo actually has this info, but operandTypes and
+ * operandFlags enums are not exposed in the public interface.
+ */
+
+ if (1) {
+ /*
+ * PC relative addr.
+ */
+
+ jump = pc + operand.getImm();
+ } else {
+ /*
+ * Absolute addr.
+ */
+
+ jump = (uint64_t)operand.getImm();
+ }
+
+ /*
+ * Output the address relative to the function start, given
+ * that MC will print the addresses relative the current pc.
+ */
+ debug_printf("\t\t; %lu", (unsigned long)jump);
+
+ /*
+ * Ignore far jumps given it could be actually a tail return to
+ * a random address.
+ */
+
+ if (jump > max_pc &&
+ jump < extent) {
+ max_pc = jump;
+ }
+ }
+ }
+ }
+
+ debug_printf("\n");
+
+ /*
+ * Stop disassembling on return statements, if there is no record of a
+ * jump to a successive address.
+ */
+
+ if (TID.isReturn()) {
+ if (pc > max_pc) {
+ break;
+ }
+ }
+ }
+
+ /*
+ * Print GDB command, useful to verify output.
+ */
+
+ if (0) {
+ debug_printf("disassemble %p %p\n", bytes, bytes + pc);
+ }
+
+ debug_printf("\n");
+#else /* HAVE_LLVM < 0x0207 */
+ (void)func;
+#endif /* HAVE_LLVM < 0x0207 */
+}
+
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
index 8a58f95b78f..da873f30b2d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
@@ -45,6 +45,11 @@
#define GALLIVM_DEBUG_GC (1 << 6)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#ifdef DEBUG
extern unsigned gallivm_debug;
#else
@@ -81,4 +86,9 @@ void
lp_disassemble(const void* func);
+#ifdef __cplusplus
+}
+#endif
+
+
#endif /* !LP_BLD_DEBUG_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 46dd00d8224..843a14a500c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -46,66 +46,6 @@
#include "util/u_debug.h"
-#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED)
-
-#include "llvm/Support/raw_ostream.h"
-
-class raw_debug_ostream :
- public llvm::raw_ostream
-{
- uint64_t pos;
-
- void write_impl(const char *Ptr, size_t Size);
- uint64_t current_pos() { return pos; }
- uint64_t current_pos() const { return pos; }
-
-#if HAVE_LLVM >= 0x207
- uint64_t preferred_buffer_size() { return 512; }
-#else
- size_t preferred_buffer_size() { return 512; }
-#endif
-};
-
-
-void
-raw_debug_ostream::write_impl(const char *Ptr, size_t Size)
-{
- if (Size > 0) {
- char *lastPtr = (char *)&Ptr[Size];
- char last = *lastPtr;
- *lastPtr = 0;
- _debug_printf("%*s", Size, Ptr);
- *lastPtr = last;
- pos += Size;
- }
-}
-
-
-/**
- * Same as LLVMDumpValue, but through our debugging channels.
- */
-extern "C" void
-lp_debug_dump_value(LLVMValueRef value)
-{
- raw_debug_ostream os;
- llvm::unwrap(value)->print(os);
- os.flush();
-}
-
-
-#else
-
-
-extern "C" void
-lp_debug_dump_value(LLVMValueRef value)
-{
- LLVMDumpValue(value);
-}
-
-
-#endif
-
-
/**
* Register the engine with oprofile.
*
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 1fec3adf5b1..9961ba08f3a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -1108,6 +1108,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
coord, tex);
}
+ /* Clamp p coords to [0,1] */
+ p = lp_build_clamp(&bld->coord_bld, p,
+ bld->coord_bld.zero,
+ bld->coord_bld.one);
+
/* result = (p FUNC texel) ? 1 : 0 */
res = lp_build_cmp(texel_bld, bld->static_state->compare_func,
p, texel[chan]);
diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h
index a084310d4ff..8173d4cc37f 100644
--- a/src/gallium/auxiliary/os/os_thread.h
+++ b/src/gallium/auxiliary/os/os_thread.h
@@ -152,8 +152,9 @@ static INLINE int pipe_thread_destroy( pipe_thread thread )
*/
typedef CRITICAL_SECTION pipe_mutex;
+/* http://locklessinc.com/articles/pthreads_on_windows/ */
#define pipe_static_mutex(mutex) \
- /*static*/ pipe_mutex mutex = {0,0,0,0,0,0}
+ static pipe_mutex mutex = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0}
#define pipe_mutex_init(mutex) \
InitializeCriticalSection(&mutex)
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
index c2322eed19b..5754f476188 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c
@@ -174,11 +174,20 @@ pb_malloc_bufmgr_destroy(struct pb_manager *mgr)
}
+static boolean
+pb_malloc_bufmgr_is_buffer_busy( struct pb_manager *mgr,
+ struct pb_buffer *buf )
+{
+ return FALSE;
+}
+
+
static struct pb_manager
pb_malloc_bufmgr = {
pb_malloc_bufmgr_destroy,
pb_malloc_bufmgr_create_buffer,
- pb_malloc_bufmgr_flush
+ pb_malloc_bufmgr_flush,
+ pb_malloc_bufmgr_is_buffer_busy
};
diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c
index a3fd7e8430e..36824058c7d 100644
--- a/src/gallium/auxiliary/rbug/rbug_context.c
+++ b/src/gallium/auxiliary/rbug/rbug_context.c
@@ -288,7 +288,6 @@ int rbug_send_context_draw_rule(struct rbug_connection *__con,
int rbug_send_context_flush(struct rbug_connection *__con,
rbug_context_t context,
- int32_t flags,
uint32_t *__serial)
{
uint32_t __len = 0;
@@ -298,7 +297,6 @@ int rbug_send_context_flush(struct rbug_connection *__con,
LEN(8); /* header */
LEN(8); /* context */
- LEN(4); /* flags */
/* align */
PAD(__len, 8);
@@ -310,7 +308,6 @@ int rbug_send_context_flush(struct rbug_connection *__con,
WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_FLUSH));
WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
WRITE(8, rbug_context_t, context); /* context */
- WRITE(4, int32_t, flags); /* flags */
/* final pad */
PAD(__pos, 8);
@@ -663,7 +660,6 @@ struct rbug_proto_context_flush * rbug_demarshal_context_flush(struct rbug_proto
ret->header.opcode = header->opcode;
READ(8, rbug_context_t, context); /* context */
- READ(4, int32_t, flags); /* flags */
return ret;
}
diff --git a/src/gallium/auxiliary/rbug/rbug_context.h b/src/gallium/auxiliary/rbug/rbug_context.h
index 03126d6b123..4a865c25fc5 100644
--- a/src/gallium/auxiliary/rbug/rbug_context.h
+++ b/src/gallium/auxiliary/rbug/rbug_context.h
@@ -96,7 +96,6 @@ struct rbug_proto_context_flush
{
struct rbug_header header;
rbug_context_t context;
- int32_t flags;
};
struct rbug_proto_context_list_reply
@@ -162,7 +161,6 @@ int rbug_send_context_draw_rule(struct rbug_connection *__con,
int rbug_send_context_flush(struct rbug_connection *__con,
rbug_context_t context,
- int32_t flags,
uint32_t *__serial);
int rbug_send_context_list_reply(struct rbug_connection *__con,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 1eac762e6e5..57622a0dea6 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -137,7 +137,7 @@ static boolean parse_identifier( const char **pcur, char *ret )
int i = 0;
if (is_alpha_underscore( cur )) {
ret[i++] = *cur++;
- while (is_alpha_underscore( cur ))
+ while (is_alpha_underscore( cur ) || is_digit( cur ))
ret[i++] = *cur++;
ret[i++] = '\0';
*pcur = cur;
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 76bd7ace526..421726b40e0 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -128,21 +128,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
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.
- */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_GENERIC };
- const uint semantic_indexes[] = { 0, 0 };
- ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
- }
-
- /* fragment shader */
- ctx->fs[TGSI_WRITEMASK_XYZW] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@@ -170,7 +155,8 @@ util_destroy_blit(struct blit_state *ctx)
struct pipe_context *pipe = ctx->pipe;
unsigned i;
- pipe->delete_vs_state(pipe, ctx->vs);
+ if (ctx->vs)
+ pipe->delete_vs_state(pipe, ctx->vs);
for (i = 0; i < Elements(ctx->fs); i++)
if (ctx->fs[i])
@@ -186,6 +172,59 @@ util_destroy_blit(struct blit_state *ctx)
/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct blit_state *ctx, uint writemask)
+{
+ if (!ctx->fs[writemask])
+ ctx->fs[writemask] =
+ util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR,
+ writemask);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+}
+
+
+/**
+ * Helper function to set the depthwrite shader.
+ */
+static INLINE void
+set_depth_fragment_shader(struct blit_state *ctx)
+{
+ if (!ctx->fs_depth)
+ ctx->fs_depth =
+ util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct blit_state *ctx)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!ctx->vs) {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
* Get offset of next free slot in vertex buffer for quad vertices.
*/
static unsigned
@@ -304,8 +343,10 @@ util_blit_pixels_writemask(struct blit_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
+ enum pipe_format src_format, dst_format;
struct pipe_sampler_view *sampler_view = NULL;
struct pipe_sampler_view sv_templ;
+ struct pipe_surface *dst_surface;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@@ -326,12 +367,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
regions_overlap(srcX0, srcY0, srcX1, srcY1,
dstX0, dstY0, dstX1, dstY1);
+ src_format = util_format_linear(src_tex->format);
+ dst_format = util_format_linear(dst->format);
+
/*
* Check for simple case: no format conversion, no flipping, no stretching,
* no overlapping.
* Filter mode should not matter since there's no stretching.
*/
- if (dst->format == src_tex->format &&
+ if (dst_format == src_format &&
srcX0 < srcX1 &&
dstX0 < dstX1 &&
srcY0 < srcY1 &&
@@ -354,6 +398,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
return;
}
+ if (dst_format == dst->format) {
+ dst_surface = dst;
+ } else {
+ struct pipe_surface templ = *dst;
+ templ.format = dst_format;
+ dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
+ }
+
/* Create a temporary texture when src and dest alias or when src
* is anything other than a 2d texture.
* XXX should just use appropriate shader to access 1d / 3d slice / cube face,
@@ -361,9 +413,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
*
* This can still be improved upon.
*/
- if ((src_tex == dst->texture &&
- dst->u.tex.level == src_level &&
- dst->u.tex.first_layer == srcZ0) ||
+ if ((src_tex == dst_surface->texture &&
+ dst_surface->u.tex.level == src_level &&
+ dst_surface->u.tex.first_layer == srcZ0) ||
(src_tex->target != PIPE_TEXTURE_2D &&
src_tex->target != PIPE_TEXTURE_2D &&
src_tex->target != PIPE_TEXTURE_RECT))
@@ -392,7 +444,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* create temp texture */
memset(&texTemp, 0, sizeof(texTemp));
texTemp.target = ctx->internal_target;
- texTemp.format = src_tex->format;
+ texTemp.format = src_format;
texTemp.last_level = 0;
texTemp.width0 = srcW;
texTemp.height0 = srcH;
@@ -439,7 +491,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
pipe_resource_reference(&tex, NULL);
}
else {
- u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format);
+ u_sampler_view_default_template(&sv_templ, src_tex, src_format);
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
if (!sampler_view) {
@@ -460,15 +512,15 @@ util_blit_pixels_writemask(struct blit_state *ctx,
}
}
- dst_is_depth = util_format_is_depth_or_stencil(dst->format);
+ dst_is_depth = util_format_is_depth_or_stencil(dst_format);
assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target,
sampler_view->texture->nr_samples,
- PIPE_BIND_SAMPLER_VIEW, 0));
- assert(screen->is_format_supported(screen, dst->format, ctx->internal_target,
- dst->texture->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW));
+ assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
+ dst_surface->texture->nr_samples,
dst_is_depth ? PIPE_BIND_DEPTH_STENCIL :
- PIPE_BIND_RENDER_TARGET, 0));
+ PIPE_BIND_RENDER_TARGET));
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
@@ -502,12 +554,12 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_single_sampler_done(ctx->cso);
/* viewport */
- ctx->viewport.scale[0] = 0.5f * dst->width;
- ctx->viewport.scale[1] = 0.5f * dst->height;
+ ctx->viewport.scale[0] = 0.5f * dst_surface->width;
+ ctx->viewport.scale[1] = 0.5f * dst_surface->height;
ctx->viewport.scale[2] = 0.5f;
ctx->viewport.scale[3] = 1.0f;
- ctx->viewport.translate[0] = 0.5f * dst->width;
- ctx->viewport.translate[1] = 0.5f * dst->height;
+ ctx->viewport.translate[0] = 0.5f * dst_surface->width;
+ ctx->viewport.translate[1] = 0.5f * dst_surface->height;
ctx->viewport.translate[2] = 0.5f;
ctx->viewport.translate[3] = 0.0f;
cso_set_viewport(ctx->cso, &ctx->viewport);
@@ -517,41 +569,30 @@ util_blit_pixels_writemask(struct blit_state *ctx,
/* shaders */
if (dst_is_depth) {
- if (ctx->fs_depth == NULL)
- ctx->fs_depth =
- util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
-
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth);
+ set_depth_fragment_shader(ctx);
} else {
- if (ctx->fs[writemask] == NULL)
- ctx->fs[writemask] =
- util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR,
- writemask);
-
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
+ set_fragment_shader(ctx, writemask);
}
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_vertex_shader(ctx);
/* drawing dest */
memset(&fb, 0, sizeof(fb));
- fb.width = dst->width;
- fb.height = dst->height;
+ fb.width = dst_surface->width;
+ fb.height = dst_surface->height;
if (dst_is_depth) {
- fb.zsbuf = dst;
+ fb.zsbuf = dst_surface;
} else {
fb.nr_cbufs = 1;
- fb.cbufs[0] = dst;
+ fb.cbufs[0] = dst_surface;
}
cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
offset = setup_vertex_data_tex(ctx,
- (float) dstX0 / dst->width * 2.0f - 1.0f,
- (float) dstY0 / dst->height * 2.0f - 1.0f,
- (float) dstX1 / dst->width * 2.0f - 1.0f,
- (float) dstY1 / dst->height * 2.0f - 1.0f,
+ (float) dstX0 / dst_surface->width * 2.0f - 1.0f,
+ (float) dstY0 / dst_surface->height * 2.0f - 1.0f,
+ (float) dstX1 / dst_surface->width * 2.0f - 1.0f,
+ (float) dstY1 / dst_surface->height * 2.0f - 1.0f,
s0, t0,
s1, t1,
z);
@@ -576,6 +617,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_vertex_buffers(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
+ if (dst_surface != dst)
+ pipe_surface_reference(&dst_surface, NULL);
}
@@ -660,8 +703,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
PIPE_TEXTURE_2D,
dst->texture->nr_samples,
- PIPE_BIND_RENDER_TARGET,
- 0));
+ PIPE_BIND_RENDER_TARGET));
/* save state (restored below) */
cso_save_blend(ctx->cso);
@@ -706,8 +748,8 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view);
/* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
- cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+ set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW);
+ set_vertex_shader(ctx);
/* drawing dest */
memset(&fb, 0, sizeof(fb));
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index fd1c2b72d04..a4c399052fd 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -772,9 +772,9 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* (assuming copying a stencil buffer is not possible) */
if ((!ignore_stencil && is_stencil) ||
!screen->is_format_supported(screen, dst->format, dst->target,
- dst->nr_samples, bind, 0) ||
+ dst->nr_samples, bind) ||
!screen->is_format_supported(screen, src->format, src->target,
- src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
+ src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
ctx->base.running = TRUE;
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
@@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* Get surface. */
memset(&surf_templ, 0, sizeof(surf_templ));
u_surface_default_template(&surf_templ, dst, bind);
+ surf_templ.format = util_format_linear(dst->format);
surf_templ.u.tex.level = dstlevel;
surf_templ.u.tex.first_layer = dstz;
surf_templ.u.tex.last_layer = dstz;
@@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
normalized = src->target != PIPE_TEXTURE_RECT;
/* Initialize sampler view. */
- u_sampler_view_default_template(&viewTempl, src, src->format);
+ u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format));
view = pipe->create_sampler_view(pipe, src, &viewTempl);
/* Set rasterizer state, shaders, and textures. */
diff --git a/src/gallium/auxiliary/util/u_cache.c b/src/gallium/auxiliary/util/u_cache.c
index 15f4a8831f2..df08ec302a2 100644
--- a/src/gallium/auxiliary/util/u_cache.c
+++ b/src/gallium/auxiliary/util/u_cache.c
@@ -27,9 +27,10 @@
/**
* @file
- * Simple cache implementation.
+ * Improved cache implementation.
*
- * We simply have fixed size array, and destroy previous values on collision.
+ * Fixed size array with linear probing on collision and LRU eviction
+ * on full.
*
* @author Jose Fonseca <[email protected]>
*/
@@ -41,10 +42,17 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_cache.h"
+#include "util/u_simple_list.h"
struct util_cache_entry
{
+ enum { EMPTY = 0, FILLED, DELETED } state;
+ uint32_t hash;
+
+ struct util_cache_entry *next;
+ struct util_cache_entry *prev;
+
void *key;
void *value;
@@ -69,11 +77,14 @@ struct util_cache
struct util_cache_entry *entries;
-#ifdef DEBUG
unsigned count;
-#endif
+ struct util_cache_entry lru;
};
+static void
+ensure_sanity(const struct util_cache *cache);
+
+#define CACHE_DEFAULT_ALPHA 2
struct util_cache *
util_cache_create(uint32_t (*hash)(const void *key),
@@ -90,6 +101,10 @@ util_cache_create(uint32_t (*hash)(const void *key),
cache->hash = hash;
cache->compare = compare;
cache->destroy = destroy;
+
+ make_empty_list(&cache->lru);
+
+ size *= CACHE_DEFAULT_ALPHA;
cache->size = size;
cache->entries = CALLOC(size, sizeof(struct util_cache_entry));
@@ -98,19 +113,46 @@ util_cache_create(uint32_t (*hash)(const void *key),
return NULL;
}
+ ensure_sanity(cache);
return cache;
}
-static INLINE struct util_cache_entry *
+static struct util_cache_entry *
util_cache_entry_get(struct util_cache *cache,
+ uint32_t hash,
const void *key)
{
- uint32_t hash;
-
- hash = cache->hash(key);
+ struct util_cache_entry *first_unfilled = NULL;
+ uint32_t index = hash % cache->size;
+ uint32_t probe;
+
+ /* Probe until we find either a matching FILLED entry or an EMPTY
+ * slot (which has never been occupied).
+ *
+ * Deleted or non-matching slots are not indicative of completion
+ * as a previous linear probe for the same key could have continued
+ * past this point.
+ */
+ for (probe = 0; probe < cache->size; probe++) {
+ uint32_t i = (index + probe) % cache->size;
+ struct util_cache_entry *current = &cache->entries[i];
+
+ if (current->state == FILLED) {
+ if (current->hash == hash &&
+ cache->compare(key, current->key) == 0)
+ return current;
+ }
+ else {
+ if (!first_unfilled)
+ first_unfilled = current;
+
+ if (current->state == EMPTY)
+ return first_unfilled;
+ }
+ }
- return &cache->entries[hash % cache->size];
+ return NULL;
}
static INLINE void
@@ -123,9 +165,15 @@ util_cache_entry_destroy(struct util_cache *cache,
entry->key = NULL;
entry->value = NULL;
- if(key || value)
+ if (entry->state == FILLED) {
+ remove_from_list(entry);
+ cache->count--;
+
if(cache->destroy)
cache->destroy(key, value);
+
+ entry->state = DELETED;
+ }
}
@@ -135,21 +183,33 @@ util_cache_set(struct util_cache *cache,
void *value)
{
struct util_cache_entry *entry;
+ uint32_t hash = cache->hash(key);
assert(cache);
if (!cache)
return;
- entry = util_cache_entry_get(cache, key);
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
+ entry = cache->lru.prev;
+
+ if (cache->count >= cache->size / CACHE_DEFAULT_ALPHA)
+ util_cache_entry_destroy(cache, cache->lru.prev);
+
util_cache_entry_destroy(cache, entry);
#ifdef DEBUG
++entry->count;
- ++cache->count;
#endif
entry->key = key;
+ entry->hash = hash;
entry->value = value;
+ entry->state = FILLED;
+ insert_at_head(&cache->lru, entry);
+ cache->count++;
+
+ ensure_sanity(cache);
}
@@ -158,17 +218,18 @@ util_cache_get(struct util_cache *cache,
const void *key)
{
struct util_cache_entry *entry;
+ uint32_t hash = cache->hash(key);
assert(cache);
if (!cache)
return NULL;
- entry = util_cache_entry_get(cache, key);
- if(!entry->key && !entry->value)
- return NULL;
-
- if(cache->compare(key, entry->key) != 0)
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
return NULL;
+
+ if (entry->state == FILLED)
+ move_to_head(&cache->lru, entry);
return entry->value;
}
@@ -183,8 +244,14 @@ util_cache_clear(struct util_cache *cache)
if (!cache)
return;
- for(i = 0; i < cache->size; ++i)
+ for(i = 0; i < cache->size; ++i) {
util_cache_entry_destroy(cache, &cache->entries[i]);
+ cache->entries[i].state = EMPTY;
+ }
+
+ assert(cache->count == 0);
+ assert(is_empty_list(&cache->lru));
+ ensure_sanity(cache);
}
@@ -215,3 +282,70 @@ util_cache_destroy(struct util_cache *cache)
FREE(cache->entries);
FREE(cache);
}
+
+
+void
+util_cache_remove(struct util_cache *cache,
+ const void *key)
+{
+ struct util_cache_entry *entry;
+ uint32_t hash;
+
+ assert(cache);
+ if (!cache)
+ return;
+
+ hash = cache->hash(key);
+
+ entry = util_cache_entry_get(cache, hash, key);
+ if (!entry)
+ return;
+
+ if (entry->state == FILLED)
+ util_cache_entry_destroy(cache, entry);
+
+ ensure_sanity(cache);
+}
+
+
+static void
+ensure_sanity(const struct util_cache *cache)
+{
+#ifdef DEBUG
+ unsigned i, cnt = 0;
+
+ assert(cache);
+ for (i = 0; i < cache->size; i++) {
+ struct util_cache_entry *header = &cache->entries[i];
+
+ assert(header);
+ assert(header->state == FILLED ||
+ header->state == EMPTY ||
+ header->state == DELETED);
+ if (header->state == FILLED) {
+ cnt++;
+ assert(header->hash == cache->hash(header->key));
+ }
+ }
+
+ assert(cnt == cache->count);
+ assert(cache->size >= cnt);
+
+ if (cache->count == 0) {
+ assert (is_empty_list(&cache->lru));
+ }
+ else {
+ struct util_cache_entry *header = cache->lru.next;
+
+ assert (header);
+ assert (!is_empty_list(&cache->lru));
+
+ for (i = 0; i < cache->count; i++)
+ header = header->next;
+
+ assert(header == &cache->lru);
+ }
+#endif
+
+ (void)cache;
+}
diff --git a/src/gallium/auxiliary/util/u_cache.h b/src/gallium/auxiliary/util/u_cache.h
index 8a612c6585f..be3631b7254 100644
--- a/src/gallium/auxiliary/util/u_cache.h
+++ b/src/gallium/auxiliary/util/u_cache.h
@@ -79,6 +79,10 @@ util_cache_clear(struct util_cache *cache);
void
util_cache_destroy(struct util_cache *cache);
+void
+util_cache_remove(struct util_cache *cache,
+ const void *key);
+
#ifdef __cplusplus
}
diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c
index e209a98b706..75677b2b133 100644
--- a/src/gallium/auxiliary/util/u_caps.c
+++ b/src/gallium/auxiliary/util/u_caps.c
@@ -69,8 +69,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
list[i++],
PIPE_TEXTURE_2D,
0,
- PIPE_BIND_SAMPLER_VIEW,
- 0)) {
+ PIPE_BIND_SAMPLER_VIEW)) {
*out = i - 2;
return FALSE;
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 0defd919974..8ed3b3c0959 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -82,7 +82,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
uint numAttribs = 2, i, j;
uint vertexBytes = 4 * (4 * numAttribs * sizeof(float));
struct pipe_resource *vbuf = NULL;
- uint *v = NULL;
+ float *v = NULL;
v = MALLOC(vertexBytes);
if (v == NULL)
@@ -121,7 +121,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes,
PIPE_BIND_VERTEX_BUFFER);
- if (!vbuf)
+ if (!vbuf)
goto out;
util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 0ae15c9cc0a..22c63ae162a 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -141,6 +141,7 @@ PIPE_FORMAT_R8G8Bx_SNORM , other, 1, 1, sn8 , sn8 , , , x
# - http://en.wikipedia.org/wiki/S3_Texture_Compression
# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt
+# - http://www.opengl.org/registry/specs/EXT/texture_compression_latc.txt
# - http://msdn.microsoft.com/en-us/library/bb694531.aspx
PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb
PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb
@@ -156,6 +157,11 @@ PIPE_FORMAT_RGTC1_SNORM , rgtc, 4, 4, x64, , , , x001, rg
PIPE_FORMAT_RGTC2_UNORM , rgtc, 4, 4, x128, , , , xy01, rgb
PIPE_FORMAT_RGTC2_SNORM , rgtc, 4, 4, x128, , , , xy01, rgb
+PIPE_FORMAT_LATC1_UNORM , rgtc, 4, 4, x64, , , , xxx1, rgb
+PIPE_FORMAT_LATC1_SNORM , rgtc, 4, 4, x64, , , , xxx1, rgb
+PIPE_FORMAT_LATC2_UNORM , rgtc, 4, 4, x128, , , , xxxy, rgb
+PIPE_FORMAT_LATC2_SNORM , rgtc, 4, 4, x128, , , , xxxy, rgb
+
# Straightforward D3D10-like formats (also used for
# vertex buffer element description)
#
diff --git a/src/gallium/auxiliary/util/u_format_latc.c b/src/gallium/auxiliary/util/u_format_latc.c
new file mode 100644
index 00000000000..e84c493bb1e
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_latc.c
@@ -0,0 +1,328 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+#include "u_math.h"
+#include "u_format.h"
+#include "u_format_rgtc.h"
+#include "u_format_latc.h"
+
+static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4],
+ int numxpixels, int numypixels);
+
+static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
+ unsigned i, unsigned j, uint8_t *value, unsigned comps);
+
+static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4],
+ int numxpixels, int numypixels);
+
+static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
+ unsigned i, unsigned j, int8_t *value, unsigned comps);
+
+void
+util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ /* Fix warnings here: */
+ (void) u_format_unsigned_encode_rgtc_chan;
+ (void) u_format_signed_encode_rgtc_chan;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
+}
+
+void
+util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row,
+ unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 8;
+
+ for(y = 0; y < height; y += 4) {
+ const uint8_t *src = src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ uint8_t tmp_r;
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = 1.0;
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ uint8_t tmp_r;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = 1.0;
+}
+
+void
+util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 8;
+
+ for(y = 0; y < height; y += 4) {
+ const int8_t *src = (int8_t *)src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ int8_t tmp_r;
+ u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = 1.0;
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ int8_t tmp_r;
+
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = 1.0;
+}
+
+
+void
+util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ puts(__func__);
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
+}
+
+void
+util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height);
+}
+
+void
+util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3);
+}
+
+void
+util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 16;
+
+ for(y = 0; y < height; y += 4) {
+ const uint8_t *src = src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ uint8_t tmp_r, tmp_g;
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = ubyte_to_float(tmp_g);
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ uint8_t tmp_r, tmp_g;
+
+ u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = ubyte_to_float(tmp_r);
+ dst[3] = ubyte_to_float(tmp_g);
+}
+
+
+void
+util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ fprintf(stderr,"%s\n", __func__);
+}
+
+void
+util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ unsigned x, y, i, j;
+ int block_size = 16;
+
+ for(y = 0; y < height; y += 4) {
+ const int8_t *src = (int8_t *)src_row;
+ for(x = 0; x < width; x += 4) {
+ for(j = 0; j < 4; ++j) {
+ for(i = 0; i < 4; ++i) {
+ float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
+ int8_t tmp_r, tmp_g;
+ u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
+ u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = byte_to_float_tex(tmp_g);
+ }
+ }
+ src += block_size;
+ }
+ src_row += src_stride;
+ }
+}
+
+void
+util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3);
+}
+
+void
+util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
+{
+ int8_t tmp_r, tmp_g;
+
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
+ u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
+ dst[0] =
+ dst[1] =
+ dst[2] = byte_to_float_tex(tmp_r);
+ dst[3] = byte_to_float_tex(tmp_g);
+}
+
+
+#define TAG(x) u_format_unsigned_##x
+#define TYPE uint8_t
+#define T_MIN 0
+#define T_MAX 255
+
+#include "../../../mesa/main/texcompress_rgtc_tmp.h"
+
+#undef TYPE
+#undef TAG
+#undef T_MIN
+#undef T_MAX
+
+
+#define TAG(x) u_format_signed_##x
+#define TYPE int8_t
+#define T_MIN (int8_t)-128
+#define T_MAX (int8_t)127
+
+#include "../../../mesa/main/texcompress_rgtc_tmp.h"
+
+#undef TYPE
+#undef TAG
+#undef T_MIN
+#undef T_MAX
diff --git a/src/gallium/auxiliary/util/u_format_latc.h b/src/gallium/auxiliary/util/u_format_latc.h
new file mode 100644
index 00000000000..1f08887533d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_latc.h
@@ -0,0 +1,108 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Red Hat 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_LATC_H_
+#define U_FORMAT_LATC_H_
+
+void
+util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+
+void
+util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+void
+util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+void
+util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
+
+void
+util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
+
+void
+util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_format_rgtc.c b/src/gallium/auxiliary/util/u_format_rgtc.c
index 6ffcd7e99ef..c929fd47e99 100644
--- a/src/gallium/auxiliary/util/u_format_rgtc.c
+++ b/src/gallium/auxiliary/util/u_format_rgtc.c
@@ -281,7 +281,7 @@ util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
}
void
-util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
@@ -294,7 +294,7 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
- tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
+ tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4);
@@ -306,6 +306,12 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
}
void
+util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
+}
+
+void
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
@@ -389,7 +395,7 @@ util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c
}
void
-util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
@@ -402,7 +408,7 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
- tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
+ tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
}
}
u_format_signed_encode_rgtc_chan(dst, tmp_r, 4, 4);
@@ -414,6 +420,12 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c
}
void
+util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
+{
+ util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
+}
+
+void
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
int8_t tmp_r, tmp_g;
diff --git a/src/gallium/auxiliary/util/u_format_rgtc.h b/src/gallium/auxiliary/util/u_format_rgtc.h
index 3e8636d110c..67ac4728e56 100644
--- a/src/gallium/auxiliary/util/u_format_rgtc.h
+++ b/src/gallium/auxiliary/util/u_format_rgtc.h
@@ -77,6 +77,9 @@ void
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
+util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off);
+
+void
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
@@ -99,6 +102,9 @@ void
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
+util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off);
+
+void
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 7468bc38b32..55e0f7827ef 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -88,6 +88,7 @@ def write_format_table(formats):
print '#include "u_format.h"'
print '#include "u_format_s3tc.h"'
print '#include "u_format_rgtc.h"'
+ print '#include "u_format_latc.h"'
print
u_format_pack.generate(formats)
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 4f1b0e71934..4a1662462e5 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -67,7 +67,7 @@ struct gen_mipmap_state
struct pipe_vertex_element velem[2];
void *vs;
- void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da;
+ void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */
struct pipe_resource *vbuf; /**< quad vertices */
unsigned vbuf_slot;
@@ -1301,34 +1301,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
}
- /* vertex shader - still needed to specify mapping from fragment
- * shader input semantics to vertex elements
- */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_GENERIC };
- const uint semantic_indexes[] = { 0, 0 };
- ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indexes);
- }
-
- /* fragment shader */
- ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
- TGSI_INTERPOLATE_LINEAR);
- if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) {
- ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY,
- TGSI_INTERPOLATE_LINEAR);
- }
-
-
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
ctx->vertices[i][0][2] = 0.0f; /* z */
@@ -1343,6 +1315,44 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/**
+ * Helper function to set the fragment shaders.
+ */
+static INLINE void
+set_fragment_shader(struct gen_mipmap_state *ctx, uint type)
+{
+ if (!ctx->fs[type])
+ ctx->fs[type] =
+ util_make_fragment_tex_shader(ctx->pipe, type,
+ TGSI_INTERPOLATE_LINEAR);
+
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]);
+}
+
+
+/**
+ * Helper function to set the vertex shader.
+ */
+static INLINE void
+set_vertex_shader(struct gen_mipmap_state *ctx)
+{
+ /* vertex shader - still required to provide the linkage between
+ * fragment shader input semantics and vertex_element/buffers.
+ */
+ if (!ctx->vs)
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC };
+ const uint semantic_indexes[] = { 0, 0 };
+ ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
+ semantic_names,
+ semantic_indexes);
+ }
+
+ cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
+}
+
+
+/**
* Get next "slot" of vertex space in the vertex buffer.
* We're allocating one large vertex buffer and using it piece by piece.
*/
@@ -1450,16 +1460,14 @@ void
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
+ unsigned i;
+
+ for (i = 0; i < Elements(ctx->fs); i++)
+ if (ctx->fs[i])
+ pipe->delete_fs_state(pipe, ctx->fs[i]);
- if (ctx->fs2da)
- pipe->delete_fs_state(pipe, ctx->fs2da);
- if (ctx->fs1da)
- pipe->delete_fs_state(pipe, ctx->fs1da);
- pipe->delete_fs_state(pipe, ctx->fsCube);
- pipe->delete_fs_state(pipe, ctx->fs3d);
- pipe->delete_fs_state(pipe, ctx->fs2d);
- pipe->delete_fs_state(pipe, ctx->fs1d);
- pipe->delete_vs_state(pipe, ctx->vs);
+ if (ctx->vs)
+ pipe->delete_vs_state(pipe, ctx->vs);
pipe_resource_reference(&ctx->vbuf, NULL);
@@ -1498,9 +1506,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
struct pipe_resource *pt = psv->texture;
- void *fs;
uint dstLevel;
uint offset;
+ uint type;
/* The texture object should have room for the levels which we're
* about to generate.
@@ -1515,31 +1523,31 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
switch (pt->target) {
case PIPE_TEXTURE_1D:
- fs = ctx->fs1d;
+ type = TGSI_TEXTURE_1D;
break;
case PIPE_TEXTURE_2D:
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
break;
case PIPE_TEXTURE_3D:
- fs = ctx->fs3d;
+ type = TGSI_TEXTURE_3D;
break;
case PIPE_TEXTURE_CUBE:
- fs = ctx->fsCube;
+ type = TGSI_TEXTURE_CUBE;
break;
case PIPE_TEXTURE_1D_ARRAY:
- fs = ctx->fs1da;
+ type = TGSI_TEXTURE_1D_ARRAY;
break;
case PIPE_TEXTURE_2D_ARRAY:
- fs = ctx->fs2da;
+ type = TGSI_TEXTURE_2D_ARRAY;
break;
default:
assert(0);
- fs = ctx->fs2d;
+ type = TGSI_TEXTURE_2D;
}
/* check if we can render in the texture's format */
if (!screen->is_format_supported(screen, psv->format, pt->target,
- pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) {
+ pt->nr_samples, PIPE_BIND_RENDER_TARGET)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
}
@@ -1564,8 +1572,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
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);
+ set_fragment_shader(ctx, type);
+ set_vertex_shader(ctx);
/* init framebuffer state */
memset(&fb, 0, sizeof(fb));
@@ -1660,8 +1668,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
4, /* verts */
2); /* attribs/vert */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
/* need to signal that the texture has changed _after_ rendering to it */
pipe_surface_reference( &surf, NULL );
}
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 98889fb70ac..ddb81b5b957 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -299,13 +299,20 @@ pipe_buffer_write(struct pipe_context *pipe,
const void *data)
{
struct pipe_box box;
+ unsigned usage = PIPE_TRANSFER_WRITE;
+
+ if (offset == 0 && size == buf->width0) {
+ usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
+ } else {
+ usage |= PIPE_TRANSFER_DISCARD_RANGE;
+ }
u_box_1d(offset, size, &box);
pipe->transfer_inline_write( pipe,
buf,
0,
- PIPE_TRANSFER_WRITE,
+ usage,
&box,
data,
size,
diff --git a/src/gallium/auxiliary/util/u_pstipple.c b/src/gallium/auxiliary/util/u_pstipple.c
new file mode 100644
index 00000000000..f79a6938d1d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_pstipple.c
@@ -0,0 +1,434 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * Polygon stipple helper module. Drivers/GPUs which don't support polygon
+ * stipple natively can use this module to simulate it.
+ *
+ * Basically, modify fragment shader to sample the 32x32 stipple pattern
+ * texture and do a fragment kill for the 'off' bits.
+ *
+ * This was originally a 'draw' module stage, but since we don't need
+ * vertex window coords or anything, it can be a stand-alone utility module.
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "util/u_inlines.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_pstipple.h"
+#include "util/u_sampler.h"
+
+#include "tgsi/tgsi_transform.h"
+#include "tgsi/tgsi_dump.h"
+
+/** Approx number of new tokens for instructions in pstip_transform_inst() */
+#define NUM_NEW_TOKENS 50
+
+
+static void
+util_pstipple_update_stipple_texture(struct pipe_context *pipe,
+ struct pipe_resource *tex,
+ const uint32_t pattern[32])
+{
+ static const uint bit31 = 1 << 31;
+ struct pipe_transfer *transfer;
+ ubyte *data;
+ int i, j;
+
+ /* map texture memory */
+ transfer = pipe_get_transfer(pipe, tex, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
+ data = pipe->transfer_map(pipe, transfer);
+
+ /*
+ * Load alpha texture.
+ * Note: 0 means keep the fragment, 255 means kill it.
+ * We'll negate the texel value and use KILP which kills if value
+ * is negative.
+ */
+ for (i = 0; i < 32; i++) {
+ for (j = 0; j < 32; j++) {
+ if (pattern[i] & (bit31 >> j)) {
+ /* fragment "on" */
+ data[i * transfer->stride + j] = 0;
+ }
+ else {
+ /* fragment "off" */
+ data[i * transfer->stride + j] = 255;
+ }
+ }
+ }
+
+ /* unmap */
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->transfer_destroy(pipe, transfer);
+}
+
+
+/**
+ * Create a 32x32 alpha8 texture that encodes the given stipple pattern.
+ */
+struct pipe_resource *
+util_pstipple_create_stipple_texture(struct pipe_context *pipe,
+ const uint32_t pattern[32])
+{
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_resource templat, *tex;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.target = PIPE_TEXTURE_2D;
+ templat.format = PIPE_FORMAT_A8_UNORM;
+ templat.last_level = 0;
+ templat.width0 = 32;
+ templat.height0 = 32;
+ templat.depth0 = 1;
+ templat.array_size = 1;
+ templat.bind = PIPE_BIND_SAMPLER_VIEW;
+
+ tex = screen->resource_create(screen, &templat);
+
+ if (tex)
+ util_pstipple_update_stipple_texture(pipe, tex, pattern);
+
+ return tex;
+}
+
+
+/**
+ * Create sampler view to sample the stipple texture.
+ */
+struct pipe_sampler_view *
+util_pstipple_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *tex)
+{
+ struct pipe_sampler_view templat, *sv;
+
+ u_sampler_view_default_template(&templat, tex, tex->format);
+ sv = pipe->create_sampler_view(pipe, tex, &templat);
+
+ return sv;
+}
+
+
+/**
+ * Create the sampler CSO that'll be used for stippling.
+ */
+void *
+util_pstipple_create_sampler(struct pipe_context *pipe)
+{
+ struct pipe_sampler_state templat;
+ void *s;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.wrap_s = PIPE_TEX_WRAP_REPEAT;
+ templat.wrap_t = PIPE_TEX_WRAP_REPEAT;
+ templat.wrap_r = PIPE_TEX_WRAP_REPEAT;
+ templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ templat.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+ templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+ templat.normalized_coords = 1;
+ templat.min_lod = 0.0f;
+ templat.max_lod = 0.0f;
+
+ s = pipe->create_sampler_state(pipe, &templat);
+ return s;
+}
+
+
+
+/**
+ * Subclass of tgsi_transform_context, used for transforming the
+ * user's fragment shader to add the extra texture sample and fragment kill
+ * instructions.
+ */
+struct pstip_transform_context {
+ struct tgsi_transform_context base;
+ uint tempsUsed; /**< bitmask */
+ int wincoordInput;
+ int maxInput;
+ uint samplersUsed; /**< bitfield of samplers used */
+ int freeSampler; /** an available sampler for the pstipple */
+ int texTemp; /**< temp registers */
+ int numImmed;
+ boolean firstInstruction;
+};
+
+
+/**
+ * TGSI declaration transform callback.
+ * Look for a free sampler, a free input attrib, and two free temp regs.
+ */
+static void
+pstip_transform_decl(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *decl)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+
+ if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
+ uint i;
+ for (i = decl->Range.First;
+ i <= decl->Range.Last; i++) {
+ pctx->samplersUsed |= 1 << i;
+ }
+ }
+ else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+ pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last);
+ if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION)
+ pctx->wincoordInput = (int) decl->Range.First;
+ }
+ else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+ uint i;
+ for (i = decl->Range.First;
+ i <= decl->Range.Last; i++) {
+ pctx->tempsUsed |= (1 << i);
+ }
+ }
+
+ ctx->emit_declaration(ctx, decl);
+}
+
+
+static void
+pstip_transform_immed(struct tgsi_transform_context *ctx,
+ struct tgsi_full_immediate *immed)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+ pctx->numImmed++;
+}
+
+
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+ return ffs(~bitfield) - 1;
+}
+
+
+/**
+ * TGSI instruction transform callback.
+ * Replace writes to result.color w/ a temp reg.
+ * Upon END instruction, insert texture sampling code for antialiasing.
+ */
+static void
+pstip_transform_inst(struct tgsi_transform_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ struct pstip_transform_context *pctx =
+ (struct pstip_transform_context *) ctx;
+
+ if (pctx->firstInstruction) {
+ /* emit our new declarations before the first instruction */
+
+ struct tgsi_full_declaration decl;
+ struct tgsi_full_instruction newInst;
+ uint i;
+ int wincoordInput;
+
+ /* find free sampler */
+ pctx->freeSampler = free_bit(pctx->samplersUsed);
+ if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+ pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
+ if (pctx->wincoordInput < 0)
+ wincoordInput = pctx->maxInput + 1;
+ else
+ wincoordInput = pctx->wincoordInput;
+
+ /* find one free temp reg */
+ for (i = 0; i < 32; i++) {
+ if ((pctx->tempsUsed & (1 << i)) == 0) {
+ /* found a free temp */
+ if (pctx->texTemp < 0)
+ pctx->texTemp = i;
+ else
+ break;
+ }
+ }
+ assert(pctx->texTemp >= 0);
+
+ if (pctx->wincoordInput < 0) {
+ /* declare new position input reg */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_INPUT;
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR;
+ decl.Declaration.Semantic = 1;
+ decl.Semantic.Name = TGSI_SEMANTIC_POSITION;
+ decl.Semantic.Index = 0;
+ decl.Range.First =
+ decl.Range.Last = wincoordInput;
+ ctx->emit_declaration(ctx, &decl);
+ }
+
+ /* declare new sampler */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_SAMPLER;
+ decl.Range.First =
+ decl.Range.Last = pctx->freeSampler;
+ ctx->emit_declaration(ctx, &decl);
+
+ /* declare new temp regs */
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_TEMPORARY;
+ decl.Range.First =
+ decl.Range.Last = pctx->texTemp;
+ ctx->emit_declaration(ctx, &decl);
+
+ /* emit immediate = {1/32, 1/32, 1, 1}
+ * The index/position of this immediate will be pctx->numImmed
+ */
+ {
+ static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
+ struct tgsi_full_immediate immed;
+ uint size = 4;
+ immed = tgsi_default_full_immediate();
+ immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
+ immed.u[0].Float = value[0];
+ immed.u[1].Float = value[1];
+ immed.u[2].Float = value[2];
+ immed.u[3].Float = value[3];
+ ctx->emit_immediate(ctx, &immed);
+ }
+
+ pctx->firstInstruction = FALSE;
+
+
+ /*
+ * Insert new MUL/TEX/KILP instructions at start of program
+ * Take gl_FragCoord, divide by 32 (stipple size), sample the
+ * texture and kill fragment if needed.
+ *
+ * We'd like to use non-normalized texcoords to index into a RECT
+ * texture, but we can only use REPEAT wrap mode with normalized
+ * texcoords. Darn.
+ */
+
+ /* XXX invert wincoord if origin isn't lower-left... */
+
+ /* MUL texTemp, INPUT[wincoord], 1/32; */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Dst[0].Register.Index = pctx->texTemp;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.Src[0].Register.File = TGSI_FILE_INPUT;
+ newInst.Src[0].Register.Index = wincoordInput;
+ newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE;
+ newInst.Src[1].Register.Index = pctx->numImmed;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* TEX texTemp, texTemp, sampler; */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
+ newInst.Instruction.NumDstRegs = 1;
+ newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Dst[0].Register.Index = pctx->texTemp;
+ newInst.Instruction.NumSrcRegs = 2;
+ newInst.Instruction.Texture = TRUE;
+ newInst.Texture.Texture = TGSI_TEXTURE_2D;
+ newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Src[0].Register.Index = pctx->texTemp;
+ newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
+ newInst.Src[1].Register.Index = pctx->freeSampler;
+ ctx->emit_instruction(ctx, &newInst);
+
+ /* KIL -texTemp; # if -texTemp < 0, KILL fragment */
+ newInst = tgsi_default_full_instruction();
+ newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
+ newInst.Instruction.NumDstRegs = 0;
+ newInst.Instruction.NumSrcRegs = 1;
+ newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ newInst.Src[0].Register.Index = pctx->texTemp;
+ newInst.Src[0].Register.Negate = 1;
+ ctx->emit_instruction(ctx, &newInst);
+ }
+
+ /* emit this instruction */
+ ctx->emit_instruction(ctx, inst);
+}
+
+
+/**
+ * Given a fragment shader, return a new fragment shader which
+ * samples a stipple texture and executes KILL.
+ */
+struct pipe_shader_state *
+util_pstipple_create_fragment_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *fs,
+ unsigned *samplerUnitOut)
+{
+ struct pipe_shader_state *new_fs;
+ struct pstip_transform_context transform;
+ const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS;
+
+ new_fs = MALLOC(sizeof(*new_fs));
+ if (!new_fs)
+ return NULL;
+
+ new_fs->tokens = tgsi_alloc_tokens(newLen);
+ if (!new_fs->tokens) {
+ FREE(new_fs);
+ return NULL;
+ }
+
+ memset(&transform, 0, sizeof(transform));
+ transform.wincoordInput = -1;
+ transform.maxInput = -1;
+ transform.texTemp = -1;
+ transform.firstInstruction = TRUE;
+ transform.base.transform_instruction = pstip_transform_inst;
+ transform.base.transform_declaration = pstip_transform_decl;
+ transform.base.transform_immediate = pstip_transform_immed;
+
+ tgsi_transform_shader(fs->tokens,
+ (struct tgsi_token *) new_fs->tokens,
+ newLen, &transform.base);
+
+#if 0 /* DEBUG */
+ tgsi_dump(fs->tokens, 0);
+ tgsi_dump(pstip_fs.tokens, 0);
+#endif
+
+ assert(transform.freeSampler < PIPE_MAX_SAMPLERS);
+ *samplerUnitOut = transform.freeSampler;
+
+ return new_fs;
+}
+
diff --git a/src/gallium/auxiliary/util/u_pstipple.h b/src/gallium/auxiliary/util/u_pstipple.h
new file mode 100644
index 00000000000..1c2f5f48af4
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_pstipple.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_PSTIPPLE_H
+#define U_PSTIPPLE_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_context;
+struct pipe_resource;
+struct pipe_shader_state;
+
+
+extern struct pipe_resource *
+util_pstipple_create_stipple_texture(struct pipe_context *pipe,
+ const uint32_t pattern[32]);
+
+extern struct pipe_sampler_view *
+util_pstipple_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *tex);
+
+extern void *
+util_pstipple_create_sampler(struct pipe_context *pipe);
+
+extern struct pipe_shader_state *
+util_pstipple_create_fragment_shader(struct pipe_context *pipe,
+ struct pipe_shader_state *fs,
+ unsigned *samplerUnitOut);
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_resource.c b/src/gallium/auxiliary/util/u_resource.c
index ea6896b430f..50a7cd4d55b 100644
--- a/src/gallium/auxiliary/util/u_resource.c
+++ b/src/gallium/auxiliary/util/u_resource.c
@@ -24,14 +24,6 @@ void u_resource_destroy_vtbl(struct pipe_screen *screen,
ur->vtbl->resource_destroy(screen, resource);
}
-unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- struct u_resource *ur = u_resource(resource);
- return ur->vtbl->is_resource_referenced(pipe, resource, level, layer);
-}
-
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_simple_screen.h b/src/gallium/auxiliary/util/u_simple_screen.h
index 7139aaabc56..7caeb75cd27 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.h
+++ b/src/gallium/auxiliary/util/u_simple_screen.h
@@ -159,7 +159,8 @@ struct pipe_winsys
*/
int (*fence_finish)( struct pipe_winsys *ws,
struct pipe_fence_handle *fence,
- unsigned flag );
+ unsigned flags,
+ uint64_t timeout );
};
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 4eddd3f519e..9caf76c802b 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -84,7 +84,7 @@ util_create_rgba_surface(struct pipe_context *pipe,
/* Choose surface format */
for (i = 0; rgbaFormats[i]; i++) {
if (screen->is_format_supported(screen, rgbaFormats[i],
- target, 0, bind, 0)) {
+ target, 0, bind)) {
format = rgbaFormats[i];
break;
}
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index b6c63d9642f..7e72a59ee00 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -73,13 +73,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe,
*/
}
-unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- return 0;
-}
-
struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 8cf9c418b04..5b5ddeb4aba 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -27,10 +27,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe,
struct pipe_transfer *transfer,
const struct pipe_box *box);
-unsigned u_default_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer);
-
struct pipe_transfer * u_default_get_transfer(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
@@ -57,10 +53,6 @@ struct u_resource_vtbl {
void (*resource_destroy)(struct pipe_screen *,
struct pipe_resource *pt);
- unsigned (*is_resource_referenced)(struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer);
-
struct pipe_transfer *(*get_transfer)(struct pipe_context *,
struct pipe_resource *resource,
unsigned level,
@@ -104,10 +96,6 @@ boolean u_resource_get_handle_vtbl(struct pipe_screen *screen,
void u_resource_destroy_vtbl(struct pipe_screen *screen,
struct pipe_resource *resource);
-unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer);
-
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index dcf800a1e8e..9562acb8210 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -85,9 +85,9 @@ void u_upload_flush( struct u_upload_mgr *upload )
{
/* Unmap and unreference the upload buffer. */
if (upload->transfer) {
- if (upload->size) {
+ if (upload->offset) {
pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
- 0, upload->size);
+ 0, upload->offset);
}
pipe_transfer_unmap(upload->pipe, upload->transfer);
pipe_transfer_destroy(upload->pipe, upload->transfer);
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index 7d157c99ccc..521ac07747c 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -87,27 +87,27 @@ static void u_vbuf_mgr_init_format_caps(struct u_vbuf_mgr_priv *mgr)
mgr->caps.format_fixed32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_float16 =
screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_float64 =
screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_norm32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ 0, PIPE_BIND_VERTEX_BUFFER) &&
screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
mgr->caps.format_scaled32 =
screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ 0, PIPE_BIND_VERTEX_BUFFER) &&
screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
- 0, PIPE_BIND_VERTEX_BUFFER, 0);
+ 0, PIPE_BIND_VERTEX_BUFFER);
}
struct u_vbuf_mgr *
@@ -170,6 +170,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
/* Initialize the translate key, i.e. the recipe how vertices should be
* translated. */
+ memset(&key, 0, sizeof key);
for (i = 0; i < mgr->ve->count; i++) {
struct pipe_vertex_buffer *vb =
&mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index];
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index d1ba5faf788..c54e5476f3a 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -618,7 +618,7 @@ void vl_compositor_render(struct vl_compositor *compositor,
draw_layers(compositor, src_surface, src_area, dst_area);
assert(!compositor->dirty_bg && !compositor->dirty_layers);
- compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence);
+ compositor->pipe->flush(compositor->pipe, fence);
}
void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat)
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.c b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
index ce1c158e828..74893ab4e3a 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_context.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.c
@@ -265,13 +265,9 @@ vl_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
assert(vpipe);
- /* XXX: Temporary; not all paths are NPOT-tested */
- if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
- return FALSE;
-
-
- return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format, PIPE_TEXTURE_2D,
- 0, usage, geom);
+ return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format,
+ PIPE_TEXTURE_2D,
+ 0, usage);
}
static void
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index 0e5a21c18b6..d45b0642e3c 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -681,7 +681,7 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
empty_start_instance, empty_num_instances);
- renderer->pipe->flush(renderer->pipe, PIPE_FLUSH_RENDER_CACHE, buffer->fence);
+ renderer->pipe->flush(renderer->pipe, buffer->fence);
/* Next time we get this surface it may have new ref frames */
pipe_surface_reference(&buffer->surface, NULL);
diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt
index 0a9e7e50f1d..b5a06b4b943 100644
--- a/src/gallium/docs/d3d11ddi.txt
+++ b/src/gallium/docs/d3d11ddi.txt
@@ -453,8 +453,8 @@ SetVertexPipelineOutput (D3D10.1+ only)
SetViewports
- Gallium lacks support for multiple geometry-shader-selectable viewports D3D11 has
-ShaderResourceViewReadAfterWriteHazard -> flush(PIPE_FLUSH_RENDER_CACHE)
- - Gallium does not support specifying this per-render-target/view
+ShaderResourceViewReadAfterWriteHazard
+ - Gallium lacks support for this
SoSetTargets -> set_stream_output_buffers
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index c6812cd309e..b0229c70f20 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -408,6 +408,16 @@ The width0 is redefined to ``MAX2(width0, offset+size)``.
+.. _texture_barrier
+
+texture_barrier
+%%%%%%%%%%%%%%%
+
+This function flushes all pending writes to the currently-set surfaces and
+invalidates all read caches of the currently-set samplers.
+
+
+
.. _pipe_transfer:
PIPE_TRANSFER
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index f9b83c8666c..58e647a39fa 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -104,18 +104,6 @@ static const struct debug_named_value cell_debug_flags[] = {
DEBUG_NAMED_VALUE_END
};
-static unsigned int
-cell_is_resource_referenced( struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer)
-{
- /**
- * FIXME: Optimize.
- */
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
struct pipe_context *
cell_create_context(struct pipe_screen *screen,
@@ -140,8 +128,6 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.clear = cell_clear;
cell->pipe.flush = cell_flush;
- cell->pipe.is_resource_referenced = cell_is_resource_referenced;
-
#if 0
cell->pipe.begin_query = cell_begin_query;
cell->pipe.end_query = cell_end_query;
diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c
index e7c9fc46d9f..181fef44f45 100644
--- a/src/gallium/drivers/cell/ppu/cell_fence.c
+++ b/src/gallium/drivers/cell/ppu/cell_fence.c
@@ -59,9 +59,10 @@ cell_fence_signalled(const struct cell_context *cell,
}
-void
+boolean
cell_fence_finish(const struct cell_context *cell,
- const struct cell_fence *fence)
+ const struct cell_fence *fence,
+ uint64_t timeout)
{
while (!cell_fence_signalled(cell, fence)) {
usleep(10);
@@ -75,6 +76,7 @@ cell_fence_finish(const struct cell_context *cell,
}
}
#endif
+ return TRUE;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_fence.h b/src/gallium/drivers/cell/ppu/cell_fence.h
index 536b4ba411a..3568230b1c0 100644
--- a/src/gallium/drivers/cell/ppu/cell_fence.h
+++ b/src/gallium/drivers/cell/ppu/cell_fence.h
@@ -36,12 +36,15 @@ cell_fence_init(struct cell_fence *fence);
extern boolean
cell_fence_signalled(const struct cell_context *cell,
- const struct cell_fence *fence);
+ const struct cell_fence *fence,
+ unsigned flags);
-extern void
+extern boolean
cell_fence_finish(const struct cell_context *cell,
- const struct cell_fence *fence);
+ const struct cell_fence *fence,
+ unsigned flags,
+ uint64_t timeout);
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c
index 8275c9dc9c7..463f4d03eb9 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.c
+++ b/src/gallium/drivers/cell/ppu/cell_flush.c
@@ -38,19 +38,16 @@
* Called via pipe->flush()
*/
void
-cell_flush(struct pipe_context *pipe, unsigned flags,
+cell_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
struct cell_context *cell = cell_context(pipe);
if (fence) {
*fence = NULL;
- /* XXX: Implement real fencing */
- flags |= CELL_FLUSH_WAIT;
}
- if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_RENDER_CACHE))
- flags |= CELL_FLUSH_WAIT;
+ flags |= CELL_FLUSH_WAIT;
draw_flush( cell->draw );
cell_flush_int(cell, flags);
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 8d2b4b96438..0ee124a24fc 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -149,8 +149,7 @@ cell_is_format_supported( struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags )
+ unsigned tex_usage)
{
struct sw_winsys *winsys = cell_screen(screen)->winsys;
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index d60718d9716..0fefec9aaea 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -79,7 +79,7 @@ static void failover_draw_vbo( struct pipe_context *pipe,
if (failover->mode == FO_SW) {
if (failover->dirty) {
- failover->hw->flush( failover->hw, ~0, NULL );
+ failover->hw->flush( failover->hw, NULL );
failover_state_emit( failover );
}
@@ -89,22 +89,10 @@ static void failover_draw_vbo( struct pipe_context *pipe,
* intervening flush. Unlikely to be much performance impact to
* this:
*/
- failover->sw->flush( failover->sw, ~0, NULL );
+ failover->sw->flush( failover->sw, NULL );
}
}
-static unsigned int
-failover_is_resource_referenced( struct pipe_context *_pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- struct failover_context *failover = failover_context( _pipe );
- struct pipe_context *pipe = (failover->mode == FO_HW) ?
- failover->hw : failover->sw;
-
- return pipe->is_resource_referenced(pipe, resource, level, layer);
-}
-
struct pipe_context *failover_create( struct pipe_context *hw,
struct pipe_context *sw )
{
@@ -150,7 +138,6 @@ struct pipe_context *failover_create( struct pipe_context *hw,
#endif
failover->pipe.flush = hw->flush;
- failover->pipe.is_resource_referenced = failover_is_resource_referenced;
failover->dirty = 0;
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index 75e4c253dd9..813a21e2ee3 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -761,34 +761,15 @@ galahad_clear_depth_stencil(struct pipe_context *_pipe,
static void
galahad_flush(struct pipe_context *_pipe,
- unsigned flags,
struct pipe_fence_handle **fence)
{
struct galahad_context *glhd_pipe = galahad_context(_pipe);
struct pipe_context *pipe = glhd_pipe->pipe;
pipe->flush(pipe,
- flags,
fence);
}
-static unsigned int
-galahad_is_resource_referenced(struct pipe_context *_pipe,
- struct pipe_resource *_resource,
- unsigned level,
- int layer)
-{
- struct galahad_context *glhd_pipe = galahad_context(_pipe);
- struct galahad_resource *glhd_resource = galahad_resource(_resource);
- struct pipe_context *pipe = glhd_pipe->pipe;
- struct pipe_resource *resource = glhd_resource->resource;
-
- return pipe->is_resource_referenced(pipe,
- resource,
- level,
- layer);
-}
-
static struct pipe_sampler_view *
galahad_context_create_sampler_view(struct pipe_context *_pipe,
struct pipe_resource *_resource,
@@ -1038,7 +1019,6 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
glhd_pipe->base.clear_render_target = galahad_clear_render_target;
glhd_pipe->base.clear_depth_stencil = galahad_clear_depth_stencil;
glhd_pipe->base.flush = galahad_flush;
- glhd_pipe->base.is_resource_referenced = galahad_is_resource_referenced;
glhd_pipe->base.create_sampler_view = galahad_context_create_sampler_view;
glhd_pipe->base.sampler_view_destroy = galahad_context_sampler_view_destroy;
glhd_pipe->base.create_surface = galahad_context_create_surface;
diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c
index b4825bef66d..b4edebe4920 100644
--- a/src/gallium/drivers/galahad/glhd_screen.c
+++ b/src/gallium/drivers/galahad/glhd_screen.c
@@ -106,8 +106,7 @@ galahad_screen_is_format_supported(struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
struct galahad_screen *glhd_screen = galahad_screen(_screen);
struct pipe_screen *screen = glhd_screen->screen;
@@ -120,8 +119,7 @@ galahad_screen_is_format_supported(struct pipe_screen *_screen,
format,
target,
sample_count,
- tex_usage,
- geom_flags);
+ tex_usage);
}
static struct pipe_context *
@@ -276,30 +274,28 @@ galahad_screen_fence_reference(struct pipe_screen *_screen,
fence);
}
-static int
+static boolean
galahad_screen_fence_signalled(struct pipe_screen *_screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
struct galahad_screen *glhd_screen = galahad_screen(_screen);
struct pipe_screen *screen = glhd_screen->screen;
return screen->fence_signalled(screen,
- fence,
- flags);
+ fence);
}
-static int
+static boolean
galahad_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
struct galahad_screen *glhd_screen = galahad_screen(_screen);
struct pipe_screen *screen = glhd_screen->screen;
return screen->fence_finish(screen,
fence,
- flags);
+ timeout);
}
struct pipe_screen *
diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO
index f4e1423fa59..fba180064c3 100644
--- a/src/gallium/drivers/i915/TODO
+++ b/src/gallium/drivers/i915/TODO
@@ -12,22 +12,19 @@ Random list of problems with i915g:
unusable :( Upgrading xserver helped here, it doesn't crash anymore. Still
broken, it doesn't update the viewport/get new buffers.
-- Tends to hang the chip after a few minutes of openarena. Looks tiling related,
- at the last frame rendered has tiling corruption over the complete frame.
-
- Kills the chip in 3D_PRIMITIVE LINELIST with mesa-demos/fbotexture in
- wireframe mode.
-
-- Tiling is funny: If unlucky, it renders/samples all black. No clue yet what's
- going on. Seems to depend on tiny details like whethever the sampler
- relocation is fenced/unfenced (broken _with_ fenced reloc using tiling bits!).
+ wireframe mode. Changing the cullmode to cw from none mitigates the crash. As
+ does emitting only one line segment (2 indices) per 3D_PRIMITIVE command in
+ the batch.
- Y-tiling is even more fun. i915c doesn't use it, maybe there's a reason?
Texture sampling from Y-tiled buffers seems to work, though (save above
problems).
+ RESOLVED: Y-tiling works with the render engine, but not with the blitter.
+ Use u_blitter and hw clears (PRIM3D_CLEAR_RECT).
-- Need to validate buffers before usage. Currently do_exec on the batchbuffer
- can fail with -ENOSPC.
+- src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various
+ commands defined. Scavenge them and see what's useful.
Other bugs can be found here:
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g
diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h
index 039c8713570..ce2691b2fd7 100644
--- a/src/gallium/drivers/i915/i915_batch.h
+++ b/src/gallium/drivers/i915/i915_batch.h
@@ -37,6 +37,9 @@
#define OUT_BATCH(dword) \
i915_winsys_batchbuffer_dword(i915->batch, dword)
+#define OUT_BATCH_F(f) \
+ i915_winsys_batchbuffer_float(i915->batch, f)
+
#define OUT_RELOC(buf, usage, offset) \
i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, false)
diff --git a/src/gallium/drivers/i915/i915_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h
index 9df82272604..78554034781 100644
--- a/src/gallium/drivers/i915/i915_batchbuffer.h
+++ b/src/gallium/drivers/i915/i915_batchbuffer.h
@@ -55,6 +55,16 @@ i915_winsys_batchbuffer_dword_unchecked(struct i915_winsys_batchbuffer *batch,
}
static INLINE void
+i915_winsys_batchbuffer_float(struct i915_winsys_batchbuffer *batch,
+ float f)
+{
+ union { float f; unsigned int ui; } uif;
+ uif.f = f;
+ assert (i915_winsys_batchbuffer_space(batch) >= 4);
+ i915_winsys_batchbuffer_dword_unchecked(batch, uif.ui);
+}
+
+static INLINE void
i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch,
unsigned dword)
{
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 6d824a507aa..4a97746e981 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -31,17 +31,118 @@
#include "util/u_clear.h"
+#include "util/u_format.h"
+#include "util/u_pack_color.h"
#include "i915_context.h"
+#include "i915_screen.h"
+#include "i915_reg.h"
+#include "i915_batch.h"
+#include "i915_resource.h"
+#include "i915_state.h"
+void
+i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil,
+ unsigned destx, unsigned desty, unsigned width, unsigned height)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ uint32_t clear_params, clear_color, clear_depth, clear_stencil,
+ clear_color8888, packed_z_stencil;
+ union util_color u_color;
+ float f_depth = depth;
+ struct i915_texture *cbuf_tex, *depth_tex;
+
+ cbuf_tex = depth_tex = NULL;
+ clear_params = 0;
+
+ if (buffers & PIPE_CLEAR_COLOR) {
+ struct pipe_surface *cbuf = i915->framebuffer.cbufs[0];
+
+ clear_params |= CLEARPARAM_WRITE_COLOR;
+ cbuf_tex = i915_texture(cbuf->texture);
+ util_pack_color(rgba, cbuf->format, &u_color);
+ if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4)
+ clear_color = u_color.ui;
+ else
+ clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);
+
+ util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
+ clear_color8888 = u_color.ui;
+ } else
+ clear_color = clear_color8888 = 0;
+
+ clear_depth = clear_stencil = 0;
+ if (buffers & PIPE_CLEAR_DEPTH) {
+ struct pipe_surface *zbuf = i915->framebuffer.zsbuf;
+
+ clear_params |= CLEARPARAM_WRITE_DEPTH;
+ depth_tex = i915_texture(zbuf->texture);
+ packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil);
+
+ if (util_format_get_blocksize(depth_tex->b.b.format) == 4) {
+ /* Avoid read-modify-write if there's no stencil. */
+ if (buffers & PIPE_CLEAR_STENCIL
+ || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_USCALED) {
+ clear_params |= CLEARPARAM_WRITE_STENCIL;
+ clear_stencil = packed_z_stencil & 0xff;
+ clear_depth = packed_z_stencil;
+ } else
+ clear_depth = packed_z_stencil & 0xffffff00;
+ } else {
+ clear_depth = (clear_depth & 0xffff) | (clear_depth << 16);
+ }
+ }
+
+ if (i915->hardware_dirty)
+ i915_emit_hardware_state(i915);
+
+ if (!BEGIN_BATCH(7 + 7)) {
+ FLUSH_BATCH(NULL);
+
+ i915_emit_hardware_state(i915);
+ i915->vbo_flushed = 1;
+
+ assert(BEGIN_BATCH(7 + 7));
+ }
+
+ OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS);
+ OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT);
+ OUT_BATCH(clear_color);
+ OUT_BATCH(clear_depth);
+ OUT_BATCH(clear_color8888);
+ OUT_BATCH_F(f_depth);
+ OUT_BATCH(clear_stencil);
+
+ OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5);
+ OUT_BATCH_F(destx + width);
+ OUT_BATCH_F(desty + height);
+ OUT_BATCH_F(destx);
+ OUT_BATCH_F(desty + height);
+ OUT_BATCH_F(destx);
+ OUT_BATCH_F(desty);
+}
/**
* Clear the given buffers to the specified values.
* No masking, no scissor (clear entire buffer).
*/
void
-i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
- double depth, unsigned stencil)
+i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil)
{
util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth,
stencil);
}
+
+void
+i915_clear_render(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil)
+{
+ struct i915_context *i915 = i915_context(pipe);
+
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ i915_clear_emit(pipe, buffers, rgba, depth, stencil,
+ 0, 0, i915->framebuffer.width, i915->framebuffer.height);
+}
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 84c8cb54436..7a98ef73c1f 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -103,6 +103,9 @@ static void i915_destroy(struct pipe_context *pipe)
int i;
draw_destroy(i915->draw);
+
+ if (i915->blitter)
+ util_blitter_destroy(i915->blitter);
if(i915->batch)
i915->iws->batchbuffer_destroy(i915->batch);
@@ -137,7 +140,10 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915->base.destroy = i915_destroy;
- i915->base.clear = i915_clear;
+ if (i915_screen(screen)->debug.use_blitter)
+ i915->base.clear = i915_clear_blitter;
+ else
+ i915->base.clear = i915_clear_render;
i915->base.draw_vbo = i915_draw_vbo;
@@ -145,6 +151,10 @@ i915_create_context(struct pipe_screen *screen, void *priv)
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
16, UTIL_SLAB_SINGLETHREADED);
+ /* Batch stream debugging is a bit hacked up at the moment:
+ */
+ i915->batch = i915->iws->batchbuffer_create(i915->iws);
+
/*
* Create drawing context and plug our rendering stage into it.
*/
@@ -164,15 +174,19 @@ i915_create_context(struct pipe_screen *screen, void *priv)
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
+ /* augmented draw pipeline clobbers state functions */
+ i915_init_fixup_state_functions(i915);
+
+ /* Create blitter last - calls state creation functions. */
+ i915->blitter = util_blitter_create(&i915->base);
+ assert(i915->blitter);
+
i915->dirty = ~0;
i915->hardware_dirty = ~0;
i915->immediate_dirty = ~0;
i915->dynamic_dirty = ~0;
+ i915->static_dirty = ~0;
i915->flush_dirty = 0;
- /* Batch stream debugging is a bit hacked up at the moment:
- */
- i915->batch = i915->iws->batchbuffer_create(i915->iws);
-
return &i915->base;
}
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 1da637d068e..dacf50e870d 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -38,6 +38,7 @@
#include "tgsi/tgsi_scan.h"
#include "util/u_slab.h"
+#include "util/u_blitter.h"
struct i915_winsys;
@@ -185,7 +186,7 @@ struct i915_rasterizer_state {
unsigned LIS7;
unsigned sc[1];
- const struct pipe_rasterizer_state *templ;
+ struct pipe_rasterizer_state templ;
union { float f; unsigned u; } ds[2];
};
@@ -244,14 +245,35 @@ struct i915_context {
struct i915_state current;
unsigned hardware_dirty;
- unsigned immediate_dirty;
- unsigned dynamic_dirty;
- unsigned flush_dirty;
+ unsigned immediate_dirty : I915_MAX_IMMEDIATE;
+ unsigned dynamic_dirty : I915_MAX_DYNAMIC;
+ unsigned static_dirty : 4;
+ unsigned flush_dirty : 2;
struct i915_winsys_buffer *validation_buffers[2 + 1 + I915_TEX_UNITS];
int num_validation_buffers;
struct util_slab_mempool transfer_pool;
+
+ /** blitter/hw-clear */
+ struct blitter_context* blitter;
+
+ /** State tracking needed by u_blitter for save/restore. */
+ void *saved_fs;
+ void (*saved_bind_fs_state)(struct pipe_context *pipe, void *shader);
+ void *saved_vs;
+ struct pipe_clip_state saved_clip;
+ struct i915_velems_state *saved_velems;
+ unsigned saved_nr_vertex_buffers;
+ struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS];
+ unsigned saved_nr_samplers;
+ void *saved_samplers[PIPE_MAX_SAMPLERS];
+ void (*saved_bind_sampler_states)(struct pipe_context *pipe,
+ unsigned num, void **sampler);
+ unsigned saved_nr_sampler_views;
+ struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
+ void (*saved_set_sampler_views)(struct pipe_context *pipe,
+ unsigned num, struct pipe_sampler_view **views);
};
/* A flag for each state_tracker state object:
@@ -296,6 +318,12 @@ struct i915_context {
#define I915_FLUSH_CACHE 1
#define I915_PIPELINE_FLUSH 2
+/* split up static state */
+#define I915_DST_BUF_COLOR 1
+#define I915_DST_BUF_DEPTH 2
+#define I915_DST_VARS 4
+#define I915_DST_RECT 8
+
static INLINE
void i915_set_flush_dirty(struct i915_context *i915, unsigned flush)
{
@@ -326,14 +354,20 @@ void i915_emit_hardware_state(struct i915_context *i915 );
/***********************************************************************
* i915_clear.c:
*/
-void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba,
- double depth, unsigned stencil);
+void i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil);
+void i915_clear_render(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil);
+void i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil,
+ unsigned destx, unsigned desty, unsigned width, unsigned height);
/***********************************************************************
*
*/
void i915_init_state_functions( struct i915_context *i915 );
+void i915_init_fixup_state_functions( struct i915_context *i915 );
void i915_init_flush_functions( struct i915_context *i915 );
void i915_init_string_functions( struct i915_context *i915 );
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index 1713bf131f2..c4eed473e90 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -46,17 +46,18 @@ static const struct debug_named_value debug_options[] = {
};
unsigned i915_debug = 0;
-boolean i915_tiling = TRUE;
DEBUG_GET_ONCE_FLAGS_OPTION(i915_debug, "I915_DEBUG", debug_options, 0)
DEBUG_GET_ONCE_BOOL_OPTION(i915_no_tiling, "I915_NO_TILING", FALSE)
DEBUG_GET_ONCE_BOOL_OPTION(i915_lie, "I915_LIE", FALSE)
+DEBUG_GET_ONCE_BOOL_OPTION(i915_use_blitter, "I915_USE_BLITTER", FALSE)
void i915_debug_init(struct i915_screen *is)
{
i915_debug = debug_get_option_i915_debug();
is->debug.tiling = !debug_get_option_i915_no_tiling();
is->debug.lie = debug_get_option_i915_lie();
+ is->debug.use_blitter = debug_get_option_i915_use_blitter();
}
diff --git a/src/gallium/drivers/i915/i915_flush.c b/src/gallium/drivers/i915/i915_flush.c
index f2044d661e3..b4e81147c4f 100644
--- a/src/gallium/drivers/i915/i915_flush.c
+++ b/src/gallium/drivers/i915/i915_flush.c
@@ -39,34 +39,12 @@
static void i915_flush_pipe( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence )
{
struct i915_context *i915 = i915_context(pipe);
draw_flush(i915->draw);
-#if 0
- /* Do we need to emit an MI_FLUSH command to flush the hardware
- * caches?
- */
- if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) {
- unsigned flush = MI_FLUSH;
-
- if (!(flags & PIPE_FLUSH_RENDER_CACHE))
- flush |= INHIBIT_FLUSH_RENDER_CACHE;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE)
- flush |= FLUSH_MAP_CACHE;
-
- if (!BEGIN_BATCH(1)) {
- FLUSH_BATCH(NULL);
- assert(BEGIN_BATCH(1));
- }
- OUT_BATCH( flush );
- }
-#endif
-
if (i915->batch->map == i915->batch->ptr) {
return;
}
@@ -96,6 +74,7 @@ void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence)
i915->hardware_dirty = ~0;
i915->immediate_dirty = ~0;
i915->dynamic_dirty = ~0;
+ i915->static_dirty = ~0;
/* kernel emits flushes in between batchbuffers */
i915->flush_dirty = 0;
}
diff --git a/src/gallium/drivers/i915/i915_prim_emit.c b/src/gallium/drivers/i915/i915_prim_emit.c
index 276e33d4b9d..85656cd7846 100644
--- a/src/gallium/drivers/i915/i915_prim_emit.c
+++ b/src/gallium/drivers/i915/i915_prim_emit.c
@@ -149,7 +149,6 @@ emit_prim( struct draw_stage *stage,
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived( i915 );
i915_emit_hardware_state( i915 );
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c
index fb4c0516dd8..79db3b650eb 100644
--- a/src/gallium/drivers/i915/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915/i915_prim_vbuf.c
@@ -470,7 +470,6 @@ draw_arrays_fallback(struct vbuf_render *render,
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived(i915);
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
@@ -519,7 +518,6 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived(i915);
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
@@ -640,7 +638,6 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render,
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived(i915);
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h
index 5e4e80ddf6b..6fe032cdb6e 100644
--- a/src/gallium/drivers/i915/i915_reg.h
+++ b/src/gallium/drivers/i915/i915_reg.h
@@ -148,6 +148,7 @@
/* p161 */
#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16))
/* Dword 1 */
+#define CLASSIC_EARLY_DEPTH (1<<31)
#define TEX_DEFAULT_COLOR_OGL (0<<30)
#define TEX_DEFAULT_COLOR_D3D (1<<30)
#define ZR_EARLY_DEPTH (1<<29)
diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c
index 499233ceb9b..7f52ba11d61 100644
--- a/src/gallium/drivers/i915/i915_resource.c
+++ b/src/gallium/drivers/i915/i915_resource.c
@@ -31,7 +31,6 @@ i915_resource_from_handle(struct pipe_screen * screen,
void
i915_init_resource_functions(struct i915_context *i915 )
{
- i915->base.is_resource_referenced = u_default_is_resource_referenced;
i915->base.get_transfer = u_get_transfer_vtbl;
i915->base.transfer_map = u_transfer_map_vtbl;
i915->base.transfer_flush_region = u_transfer_flush_region_vtbl;
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index 51482f54fc4..77c03450b3a 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -123,7 +123,6 @@ struct u_resource_vtbl i915_buffer_vtbl =
{
i915_buffer_get_handle, /* get_handle */
i915_buffer_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
i915_get_transfer, /* get_transfer */
i915_transfer_destroy, /* transfer_destroy */
i915_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index aad5235a6ad..7816925d230 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -184,7 +184,10 @@ i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex)
/* XXX X-tiling might make sense */
return I915_TILE_NONE;
- return I915_TILE_X;
+ if (is->debug.use_blitter)
+ return I915_TILE_X;
+ else
+ return I915_TILE_Y;
}
@@ -756,6 +759,9 @@ i915_texture_transfer_map(struct pipe_context *pipe,
assert(box->z == 0);
offset = i915_texture_offset(tex, transfer->level, box->z);
+ /* TODO this is a sledgehammer */
+ pipe->flush(pipe, NULL);
+
map = iws->buffer_map(iws, tex->buffer,
(transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
if (map == NULL)
@@ -781,7 +787,6 @@ struct u_resource_vtbl i915_texture_vtbl =
{
i915_texture_get_handle, /* get_handle */
i915_texture_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
i915_texture_get_transfer, /* get_transfer */
i915_transfer_destroy, /* transfer_destroy */
i915_texture_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 77febbf5012..e62b609eb5a 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -105,6 +105,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
switch (cap) {
/* Supported features (boolean caps). */
case PIPE_CAP_ANISOTROPIC_FILTER:
+ case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_NPOT_TEXTURES:
case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
@@ -115,17 +116,18 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
/* Features that should be supported (boolean caps). */
/* XXX: Just test the code */
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- return 0;
+ /* XXX: No code but hw supports it */
+ case PIPE_CAP_POINT_SPRITE:
+ /* Also lie about these when asked to (needed for GLSL / GL 2.0) */
+ return is->debug.lie ? 1 : 0;
/* Unsupported features (boolean caps). */
case PIPE_CAP_ARRAY_TEXTURES:
case PIPE_CAP_DEPTH_CLAMP:
- case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: /* disable for now */
- case PIPE_CAP_GLSL:
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_INDEP_BLEND_FUNC:
- case PIPE_CAP_INSTANCED_DRAWING: /* draw module? */
- case PIPE_CAP_POINT_SPRITE:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_TEXTURE_SWIZZLE:
@@ -133,6 +135,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
return 0;
/* Features we can lie about (boolean caps). */
+ case PIPE_CAP_GLSL:
case PIPE_CAP_OCCLUSION_QUERY:
return is->debug.lie ? 1 : 0;
@@ -249,8 +252,7 @@ i915_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
@@ -317,24 +319,23 @@ i915_fence_reference(struct pipe_screen *screen,
is->iws->fence_reference(is->iws, ptr, fence);
}
-static int
+static boolean
i915_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
struct i915_screen *is = i915_screen(screen);
- return is->iws->fence_signalled(is->iws, fence);
+ return is->iws->fence_signalled(is->iws, fence) == 0;
}
-static int
+static boolean
i915_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
struct i915_screen *is = i915_screen(screen);
- return is->iws->fence_finish(is->iws, fence);
+ return is->iws->fence_finish(is->iws, fence) == 0;
}
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index 60f0e2971e0..cfc585b5350 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -49,6 +49,7 @@ struct i915_screen
struct {
boolean tiling;
boolean lie;
+ boolean use_blitter;
} debug;
};
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 58bbbd1de2c..1b57c5776f2 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -287,6 +287,17 @@ i915_create_sampler_state(struct pipe_context *pipe,
return cso;
}
+static void i915_fixup_bind_sampler_states(struct pipe_context *pipe,
+ unsigned num, void **sampler)
+{
+ struct i915_context *i915 = i915_context(pipe);
+
+ i915->saved_nr_samplers = num;
+ memcpy(&i915->saved_samplers, sampler, sizeof(void *) * num);
+
+ i915->saved_bind_sampler_states(pipe, num, sampler);
+}
+
static void i915_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
@@ -466,6 +477,17 @@ i915_create_fs_state(struct pipe_context *pipe,
}
static void
+i915_fixup_bind_fs_state(struct pipe_context *pipe, void *shader)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
+
+ i915->saved_fs = shader;
+
+ i915->saved_bind_fs_state(pipe, shader);
+}
+
+static void
i915_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct i915_context *i915 = i915_context(pipe);
@@ -505,6 +527,8 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader)
{
struct i915_context *i915 = i915_context(pipe);
+ i915->saved_vs = shader;
+
/* just pass-through to draw module */
draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader);
@@ -571,6 +595,27 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
}
+static void
+i915_fixup_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ int i;
+
+ for (i = 0; i < num; i++)
+ pipe_sampler_view_reference(&i915->saved_sampler_views[i],
+ views[i]);
+
+ for (i = num; i < i915->saved_nr_sampler_views; i++)
+ pipe_sampler_view_reference(&i915->saved_sampler_views[i],
+ NULL);
+
+ i915->saved_nr_sampler_views = num;
+
+ i915->saved_set_sampler_views(pipe, num, views);
+}
+
static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@@ -642,7 +687,8 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe,
i915->framebuffer.height = fb->height;
i915->framebuffer.nr_cbufs = fb->nr_cbufs;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]);
+ pipe_surface_reference(&i915->framebuffer.cbufs[i],
+ i < fb->nr_cbufs ? fb->cbufs[i] : NULL);
}
pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
@@ -657,6 +703,8 @@ static void i915_set_clip_state( struct pipe_context *pipe,
struct i915_context *i915 = i915_context(pipe);
draw_flush(i915->draw);
+ i915->saved_clip = *clip;
+
draw_set_clip_state(i915->draw, clip);
i915->dirty |= I915_NEW_CLIP;
@@ -687,7 +735,7 @@ i915_create_rasterizer_state(struct pipe_context *pipe,
{
struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state );
- cso->templ = rasterizer;
+ cso->templ = *rasterizer;
cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
cso->light_twoside = rasterizer->light_twoside;
cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE;
@@ -758,7 +806,7 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe,
/* pass-through to draw module */
draw_set_rasterizer_state(i915->draw,
- (i915->rasterizer ? i915->rasterizer->templ : NULL),
+ (i915->rasterizer ? &(i915->rasterizer->templ) : NULL),
raster);
i915->dirty |= I915_NEW_RASTERIZER;
@@ -778,6 +826,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
struct draw_context *draw = i915->draw;
int i;
+ util_copy_vertex_buffers(i915->saved_vertex_buffers,
+ &i915->saved_nr_vertex_buffers,
+ buffers, count);
#if 0
/* XXX doesn't look like this is needed */
/* unmap old */
@@ -818,6 +869,8 @@ i915_bind_vertex_elements_state(struct pipe_context *pipe,
struct i915_context *i915 = i915_context(pipe);
struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
+ i915->saved_velems = velems;
+
/* pass-through to draw module */
if (i915_velems) {
draw_set_vertex_elements(i915->draw,
@@ -896,3 +949,14 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_index_buffer = i915_set_index_buffer;
i915->base.redefine_user_buffer = u_default_redefine_user_buffer;
}
+
+void
+i915_init_fixup_state_functions( struct i915_context *i915 )
+{
+ i915->saved_bind_fs_state = i915->base.bind_fs_state;
+ i915->base.bind_fs_state = i915_fixup_bind_fs_state;
+ i915->saved_bind_sampler_states = i915->base.bind_fragment_sampler_states;
+ i915->base.bind_fragment_sampler_states = i915_fixup_bind_sampler_states;
+ i915->saved_set_sampler_views = i915->base.set_fragment_sampler_views;
+ i915->base.set_fragment_sampler_views = i915_fixup_set_fragment_sampler_views;
+}
diff --git a/src/gallium/drivers/i915/i915_state.h b/src/gallium/drivers/i915/i915_state.h
index b4074dc35ba..3f4e40294e6 100644
--- a/src/gallium/drivers/i915/i915_state.h
+++ b/src/gallium/drivers/i915/i915_state.h
@@ -48,6 +48,7 @@ extern struct i915_tracked_state i915_hw_immediate;
extern struct i915_tracked_state i915_hw_dynamic;
extern struct i915_tracked_state i915_hw_fs;
extern struct i915_tracked_state i915_hw_framebuffer;
+extern struct i915_tracked_state i915_hw_dst_buf_vars;
extern struct i915_tracked_state i915_hw_constants;
void i915_update_derived(struct i915_context *i915);
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index 1d4026a214e..59ac2f7292a 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -165,6 +165,7 @@ static struct i915_tracked_state *atoms[] = {
&i915_hw_dynamic,
&i915_hw_fs,
&i915_hw_framebuffer,
+ &i915_hw_dst_buf_vars,
&i915_hw_constants,
NULL,
};
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 15350c0a5d7..0155cd83510 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -119,7 +119,7 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space)
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) &
i915->immediate_dirty;
- if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0))
+ if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0) && i915->vbo)
i915->validation_buffers[i915->num_validation_buffers++] = i915->vbo;
*batch_space = 1 + util_bitcount(dirty);
@@ -173,25 +173,31 @@ emit_dynamic(struct i915_context *i915)
static void
validate_static(struct i915_context *i915, unsigned *batch_space)
{
- *batch_space = 2 + 5; /* including DRAW_RECT */
+ *batch_space = 0;
- if (i915->current.cbuf_bo) {
+ if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) {
i915->validation_buffers[i915->num_validation_buffers++]
= i915->current.cbuf_bo;
*batch_space += 3;
}
- if (i915->current.depth_bo) {
+ if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) {
i915->validation_buffers[i915->num_validation_buffers++]
= i915->current.depth_bo;
*batch_space += 3;
}
+
+ if (i915->static_dirty & I915_DST_VARS)
+ *batch_space += 2;
+
+ if (i915->static_dirty & I915_DST_RECT)
+ *batch_space += 5;
}
static void
emit_static(struct i915_context *i915)
{
- if (i915->current.cbuf_bo) {
+ if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.cbuf_flags);
OUT_RELOC(i915->current.cbuf_bo,
@@ -201,7 +207,7 @@ emit_static(struct i915_context *i915)
/* What happens if no zbuf??
*/
- if (i915->current.depth_bo) {
+ if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.depth_flags);
OUT_RELOC(i915->current.depth_bo,
@@ -209,7 +215,7 @@ emit_static(struct i915_context *i915)
0);
}
- {
+ if (i915->static_dirty & I915_DST_VARS) {
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
OUT_BATCH(i915->current.dst_buf_vars);
}
@@ -273,7 +279,7 @@ emit_sampler(struct i915_context *i915)
if (i915->current.sampler_enable_nr) {
int i;
- OUT_BATCH( _3DSTATE_SAMPLER_STATE |
+ OUT_BATCH( _3DSTATE_SAMPLER_STATE |
(3 * i915->current.sampler_enable_nr) );
OUT_BATCH( i915->current.sampler_enable_flags );
@@ -355,11 +361,13 @@ emit_program(struct i915_context *i915)
static void
emit_draw_rect(struct i915_context *i915)
{
- OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
- OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
- OUT_BATCH(i915->current.draw_offset);
- OUT_BATCH(i915->current.draw_size);
- OUT_BATCH(i915->current.draw_offset);
+ if (i915->static_dirty & I915_DST_RECT) {
+ OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
+ OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
+ OUT_BATCH(i915->current.draw_offset);
+ OUT_BATCH(i915->current.draw_size);
+ OUT_BATCH(i915->current.draw_offset);
+ }
}
static boolean
@@ -405,6 +413,8 @@ i915_emit_hardware_state(struct i915_context *i915 )
unsigned batch_space;
uintptr_t save_ptr;
+ assert(i915->dirty == 0);
+
if (I915_DBG_ON(DBG_ATOMS))
i915_dump_hardware_dirty(i915, __FUNCTION__);
@@ -444,5 +454,6 @@ i915_emit_hardware_state(struct i915_context *i915 )
i915->hardware_dirty = 0;
i915->immediate_dirty = 0;
i915->dynamic_dirty = 0;
+ i915->static_dirty = 0;
i915->flush_dirty = 0;
}
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 20cd23f8f73..2865298318c 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -28,6 +28,7 @@
#include "i915_context.h"
#include "i915_state.h"
#include "i915_resource.h"
+#include "i915_screen.h"
@@ -78,38 +79,13 @@ buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling)
return tiling_bits;
}
-/**
- * Examine framebuffer state to determine width, height.
- */
-static boolean
-framebuffer_size(const struct pipe_framebuffer_state *fb,
- uint *width, uint *height)
-{
- if (fb->cbufs[0]) {
- *width = fb->cbufs[0]->width;
- *height = fb->cbufs[0]->height;
- return TRUE;
- }
- else if (fb->zsbuf) {
- *width = fb->zsbuf->width;
- *height = fb->zsbuf->height;
- return TRUE;
- }
- else {
- *width = *height = 0;
- return FALSE;
- }
-}
-
static void update_framebuffer(struct i915_context *i915)
{
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
- unsigned cformat, zformat;
- unsigned x, y, w, h;
+ unsigned x, y;
int layer;
- uint32_t draw_offset;
- boolean ret;
+ uint32_t draw_offset, draw_size;
if (cbuf_surface) {
struct i915_texture *tex = i915_texture(cbuf_surface->texture);
@@ -119,7 +95,6 @@ static void update_framebuffer(struct i915_context *i915)
i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
buf_3d_tiling_bits(tex->tiling);
- cformat = cbuf_surface->format;
layer = cbuf_surface->u.tex.first_layer;
@@ -127,10 +102,9 @@ static void update_framebuffer(struct i915_context *i915)
y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy;
} else {
i915->current.cbuf_bo = NULL;
- cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */
x = y = 0;
}
- cformat = translate_format(cformat);
+ i915->static_dirty |= I915_DST_BUF_COLOR;
/* What happens if no zbuf??
*/
@@ -145,28 +119,23 @@ static void update_framebuffer(struct i915_context *i915)
i915->current.depth_flags = BUF_3D_ID_DEPTH |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
buf_3d_tiling_bits(tex->tiling);
- zformat = translate_depth_format(depth_surface->format);
- } else {
+ } else
i915->current.depth_bo = NULL;
- zformat = 0;
- }
-
- i915->current.dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- LOD_PRECLAMP_OGL |
- TEX_DEFAULT_COLOR_OGL |
- cformat |
- zformat;
+ i915->static_dirty |= I915_DST_BUF_DEPTH;
/* drawing rect calculations */
draw_offset = x | (y << 16);
- ret = framebuffer_size(&i915->framebuffer, &w, &h);
- assert(ret);
+ draw_size = (i915->framebuffer.width - 1 + x) |
+ ((i915->framebuffer.height - 1 + y) << 16);
if (i915->current.draw_offset != draw_offset) {
i915->current.draw_offset = draw_offset;
i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH);
+ i915->static_dirty |= I915_DST_RECT;
+ }
+ if (i915->current.draw_size != draw_size) {
+ i915->current.draw_size = draw_size;
+ i915->static_dirty |= I915_DST_RECT;
}
- i915->current.draw_size = (w - 1 + x) | ((h - 1 + y) << 16);
i915->hardware_dirty |= I915_HW_STATIC;
@@ -179,3 +148,52 @@ struct i915_tracked_state i915_hw_framebuffer = {
update_framebuffer,
I915_NEW_FRAMEBUFFER
};
+
+static void update_dst_buf_vars(struct i915_context *i915)
+{
+ struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+ struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
+ uint32_t dst_buf_vars, cformat, zformat;
+ uint32_t early_z = 0;
+
+ if (cbuf_surface)
+ cformat = cbuf_surface->format;
+ else
+ cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */
+ cformat = translate_format(cformat);
+
+ if (depth_surface) {
+ struct i915_texture *tex = i915_texture(depth_surface->texture);
+ struct i915_screen *is = i915_screen(i915->base.screen);
+
+ zformat = translate_depth_format(depth_surface->format);
+
+ if (is->is_i945 && tex->tiling != I915_TILE_NONE
+ && !i915->fs->info.writes_z)
+ early_z = CLASSIC_EARLY_DEPTH;
+ } else
+ zformat = 0;
+
+ dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */
+ DSTORG_VERT_BIAS(0x8) | /* .5 */
+ LOD_PRECLAMP_OGL |
+ TEX_DEFAULT_COLOR_OGL |
+ cformat |
+ zformat |
+ early_z;
+
+ if (i915->current.dst_buf_vars != dst_buf_vars) {
+ if (early_z != (i915->current.dst_buf_vars & CLASSIC_EARLY_DEPTH))
+ i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH);
+
+ i915->current.dst_buf_vars = dst_buf_vars;
+ i915->static_dirty |= I915_DST_VARS;
+ i915->hardware_dirty |= I915_HW_STATIC;
+ }
+}
+
+struct i915_tracked_state i915_hw_dst_buf_vars = {
+ "dst buf vars",
+ update_dst_buf_vars,
+ I915_NEW_FRAMEBUFFER | I915_NEW_FS
+};
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index becc6e93c2d..d02c420f6c2 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -27,6 +27,7 @@
#include "i915_surface.h"
#include "i915_resource.h"
+#include "i915_state.h"
#include "i915_blit.h"
#include "i915_reg.h"
#include "i915_screen.h"
@@ -37,16 +38,119 @@
#include "util/u_memory.h"
#include "util/u_pack_color.h"
+/*
+ * surface functions using the render engine
+ */
+
+static void
+i915_surface_copy_render(struct pipe_context *pipe,
+ struct pipe_resource *dst, unsigned dst_level,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src, unsigned src_level,
+ const struct pipe_box *src_box)
+{
+ struct i915_context *i915 = i915_context(pipe);
+
+ util_blitter_save_blend(i915->blitter, (void *)i915->blend);
+ util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil);
+ util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref);
+ util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer);
+ util_blitter_save_fragment_shader(i915->blitter, i915->saved_fs);
+ util_blitter_save_vertex_shader(i915->blitter, i915->saved_vs);
+ util_blitter_save_viewport(i915->blitter, &i915->viewport);
+ util_blitter_save_clip(i915->blitter, &i915->saved_clip);
+ util_blitter_save_vertex_elements(i915->blitter, i915->saved_velems);
+ util_blitter_save_vertex_buffers(i915->blitter, i915->saved_nr_vertex_buffers,
+ i915->saved_vertex_buffers);
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ util_blitter_save_fragment_sampler_states(i915->blitter,
+ i915->saved_nr_samplers,
+ i915->saved_samplers);
+ util_blitter_save_fragment_sampler_views(i915->blitter,
+ i915->saved_nr_sampler_views,
+ i915->saved_sampler_views);
+
+ util_blitter_copy_region(i915->blitter, dst, dst_level, dstx, dsty, dstz,
+ src, src_level, src_box, TRUE);
+}
+
+static void
+i915_clear_render_target_render(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ struct pipe_framebuffer_state fb_state;
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 1;
+ fb_state.cbufs[0] = dst;
+ fb_state.zsbuf = NULL;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ i915_clear_emit(pipe, PIPE_CLEAR_COLOR, rgba, 0.0, 0x0,
+ dstx, dsty, width, height);
+
+ pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
+ util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
+ i915->blitter->saved_fb_state.nr_cbufs = ~0;
+}
+
+static void
+i915_clear_depth_stencil_render(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
+{
+ struct i915_context *i915 = i915_context(pipe);
+ struct pipe_framebuffer_state fb_state;
+
+ util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer);
+
+ fb_state.width = dst->width;
+ fb_state.height = dst->height;
+ fb_state.nr_cbufs = 0;
+ fb_state.zsbuf = dst;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ if (i915->dirty)
+ i915_update_derived(i915);
+
+ i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL,
+ NULL, depth, stencil,
+ dstx, dsty, width, height);
+
+ pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state);
+ util_unreference_framebuffer_state(&i915->blitter->saved_fb_state);
+ i915->blitter->saved_fb_state.nr_cbufs = ~0;
+}
+
+/*
+ * surface functions using the blitter
+ */
/* Assumes all values are within bounds -- no checking at this level -
* do it higher up if required.
*/
static void
-i915_surface_copy(struct pipe_context *pipe,
- struct pipe_resource *dst, unsigned dst_level,
- unsigned dstx, unsigned dsty, unsigned dstz,
- struct pipe_resource *src, unsigned src_level,
- const struct pipe_box *src_box)
+i915_surface_copy_blitter(struct pipe_context *pipe,
+ struct pipe_resource *dst, unsigned dst_level,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src, unsigned src_level,
+ const struct pipe_box *src_box)
{
struct i915_texture *dst_tex = i915_texture(dst);
struct i915_texture *src_tex = i915_texture(src);
@@ -66,7 +170,6 @@ i915_surface_copy(struct pipe_context *pipe,
assert(src_box->z == 0);
src_offset = i915_texture_offset(src_tex, src_level, src_box->z);
- assert( dst != src );
assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) );
assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) );
assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) );
@@ -81,13 +184,12 @@ i915_surface_copy(struct pipe_context *pipe,
(short) src_box->width, (short) src_box->height );
}
-
static void
-i915_clear_render_target(struct pipe_context *pipe,
- struct pipe_surface *dst,
- const float *rgba,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height)
+i915_clear_render_target_blitter(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ const float *rgba,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
@@ -109,13 +211,13 @@ i915_clear_render_target(struct pipe_context *pipe,
}
static void
-i915_clear_depth_stencil(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned clear_flags,
- double depth,
- unsigned stencil,
- unsigned dstx, unsigned dsty,
- unsigned width, unsigned height)
+i915_clear_depth_stencil_blitter(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ unsigned clear_flags,
+ double depth,
+ unsigned stencil,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height)
{
struct i915_texture *tex = i915_texture(dst->texture);
struct pipe_resource *pt = &tex->b.b;
@@ -193,9 +295,15 @@ i915_surface_destroy(struct pipe_context *ctx,
void
i915_init_surface_functions(struct i915_context *i915)
{
- i915->base.resource_copy_region = i915_surface_copy;
- i915->base.clear_render_target = i915_clear_render_target;
- i915->base.clear_depth_stencil = i915_clear_depth_stencil;
+ if (i915_screen(i915->base.screen)->debug.use_blitter) {
+ i915->base.resource_copy_region = i915_surface_copy_blitter;
+ i915->base.clear_render_target = i915_clear_render_target_blitter;
+ i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter;
+ } else {
+ i915->base.resource_copy_region = i915_surface_copy_render;
+ i915->base.clear_render_target = i915_clear_render_target_render;
+ i915->base.clear_depth_stencil = i915_clear_depth_stencil_render;
+ }
i915->base.create_surface = i915_create_surface;
i915->base.surface_destroy = i915_surface_destroy;
}
diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c
index 0ae1a6be9e5..3b4a99beed2 100644
--- a/src/gallium/drivers/i965/brw_pipe_flush.c
+++ b/src/gallium/drivers/i965/brw_pipe_flush.c
@@ -38,7 +38,6 @@ void brw_context_flush( struct brw_context *brw )
static void
brw_flush( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence )
{
brw_context_flush( brw_context( pipe ) );
diff --git a/src/gallium/drivers/i965/brw_resource_buffer.c b/src/gallium/drivers/i965/brw_resource_buffer.c
index afb96ee3e7f..32dc54f2b26 100644
--- a/src/gallium/drivers/i965/brw_resource_buffer.c
+++ b/src/gallium/drivers/i965/brw_resource_buffer.c
@@ -91,30 +91,10 @@ brw_buffer_transfer_unmap( struct pipe_context *pipe,
}
-static unsigned brw_buffer_is_referenced( struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- int layer)
-{
- struct brw_context *brw = brw_context(pipe);
- struct brw_winsys_buffer *batch_bo = brw->batch->buf;
- struct brw_buffer *buf = brw_buffer(resource);
-
- if (buf->bo == NULL)
- return PIPE_UNREFERENCED;
-
- if (!brw_screen(pipe->screen)->sws->bo_references( batch_bo, buf->bo ))
- return PIPE_UNREFERENCED;
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
-
struct u_resource_vtbl brw_buffer_vtbl =
{
brw_buffer_get_handle, /* get_handle */
brw_buffer_destroy, /* resource_destroy */
- brw_buffer_is_referenced, /* is_resource_referenced */
u_default_get_transfer, /* get_transfer */
u_default_transfer_destroy, /* transfer_destroy */
brw_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/i965/brw_resource_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c
index 0cb895f35de..71a18290248 100644
--- a/src/gallium/drivers/i965/brw_resource_texture.c
+++ b/src/gallium/drivers/i965/brw_resource_texture.c
@@ -225,48 +225,6 @@ static void brw_texture_destroy(struct pipe_screen *screen,
}
-
-
-static unsigned brw_texture_is_referenced( struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level,
- int layer )
-{
- struct brw_context *brw = brw_context(pipe);
- struct brw_screen *bscreen = brw_screen(pipe->screen);
- struct brw_winsys_buffer *batch_bo = brw->batch->buf;
- struct brw_texture *tex = brw_texture(texture);
- struct brw_surface *surf;
- int i;
-
- /* XXX: this is subject to false positives if the underlying
- * texture BO is referenced, we can't tell whether the sub-region
- * we care about participates in that.
- */
- if (bscreen->sws->bo_references( batch_bo, tex->bo ))
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-
- /* Find any view on this texture for this level/layer and see if it
- * is referenced:
- */
- for (i = 0; i < 2; i++) {
- foreach (surf, &tex->views[i]) {
- if (surf->bo == tex->bo)
- continue;
-
- if (!(layer == -1 || surf->id.bits.layer == layer) ||
- surf->id.bits.level != level)
- continue;
-
- if (bscreen->sws->bo_references( batch_bo, surf->bo))
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
- }
- }
-
- return PIPE_UNREFERENCED;
-}
-
-
/*
* Transfer functions
*/
@@ -347,7 +305,6 @@ struct u_resource_vtbl brw_texture_vtbl =
{
brw_texture_get_handle, /* get_handle */
brw_texture_destroy, /* resource_destroy */
- brw_texture_is_referenced, /* is_resource_referenced */
brw_texture_get_transfer, /* get_transfer */
u_default_transfer_destroy, /* transfer_destroy */
brw_texture_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index bf805fd080c..25204fd088d 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -278,8 +278,7 @@ brw_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_L8_UNORM,
@@ -365,20 +364,19 @@ brw_fence_reference(struct pipe_screen *screen,
{
}
-static int
+static boolean
brw_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
- return 0; /* XXX shouldn't this be a boolean? */
+ return TRUE;
}
-static int
+static boolean
brw_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
- return 0;
+ return TRUE;
}
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index b533abe24c6..2a9d7360155 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -668,34 +668,15 @@ identity_clear_depth_stencil(struct pipe_context *_pipe,
static void
identity_flush(struct pipe_context *_pipe,
- unsigned flags,
struct pipe_fence_handle **fence)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
pipe->flush(pipe,
- flags,
fence);
}
-static unsigned int
-identity_is_resource_referenced(struct pipe_context *_pipe,
- struct pipe_resource *_resource,
- unsigned level,
- int layer)
-{
- struct identity_context *id_pipe = identity_context(_pipe);
- struct identity_resource *id_resource = identity_resource(_resource);
- struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_resource *resource = id_resource->resource;
-
- return pipe->is_resource_referenced(pipe,
- resource,
- level,
- layer);
-}
-
static struct pipe_sampler_view *
identity_context_create_sampler_view(struct pipe_context *_pipe,
struct pipe_resource *_resource,
@@ -931,7 +912,6 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.clear_render_target = identity_clear_render_target;
id_pipe->base.clear_depth_stencil = identity_clear_depth_stencil;
id_pipe->base.flush = identity_flush;
- id_pipe->base.is_resource_referenced = identity_is_resource_referenced;
id_pipe->base.create_surface = identity_context_create_surface;
id_pipe->base.surface_destroy = identity_context_surface_destroy;
id_pipe->base.create_sampler_view = identity_context_create_sampler_view;
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index 644481bb748..9bf7fd4c0ee 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -103,8 +103,7 @@ identity_screen_is_format_supported(struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct pipe_screen *screen = id_screen->screen;
@@ -113,8 +112,7 @@ identity_screen_is_format_supported(struct pipe_screen *_screen,
format,
target,
sample_count,
- tex_usage,
- geom_flags);
+ tex_usage);
}
static struct pipe_context *
@@ -242,30 +240,28 @@ identity_screen_fence_reference(struct pipe_screen *_screen,
fence);
}
-static int
+static boolean
identity_screen_fence_signalled(struct pipe_screen *_screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct pipe_screen *screen = id_screen->screen;
return screen->fence_signalled(screen,
- fence,
- flags);
+ fence);
}
-static int
+static boolean
identity_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct pipe_screen *screen = id_screen->screen;
return screen->fence_finish(screen,
fence,
- flags);
+ timeout);
}
struct pipe_screen *
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index e9374cc6efa..1fc7746a834 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -12,7 +12,7 @@ Requirements
See /proc/cpuinfo to know what your CPU supports.
- - LLVM 2.6 (or later)
+ - LLVM. Version 2.8 recommended. 2.6 or later required.
For Linux, on a recent Debian based distribution do:
@@ -30,21 +30,8 @@ Requirements
debug=no. This is necessary as LLVM builds as static library so the chosen
MS CRT must match.
- The version of LLVM from SVN ("2.7svn") from mid-March 2010 is pretty
- stable and has some features not in version 2.6.
-
- scons (optional)
- - udis86, http://udis86.sourceforge.net/ (optional). My personal repository
- supports more opcodes which haven't been merged upstream yet:
-
- git clone git://anongit.freedesktop.org/~jrfonseca/udis86
- cd udis86
- ./autogen.sh
- ./configure --with-pic
- make
- sudo make install
-
Building
========
@@ -94,13 +81,7 @@ that no tail call optimizations are done by gcc.
To better profile JIT code you'll need to build LLVM with oprofile integration.
- source_dir=$PWD/llvm-2.6
- build_dir=$source_dir/build/profile
- install_dir=$source_dir-profile
-
- mkdir -p "$build_dir"
- cd "$build_dir" && \
- $source_dir/configure \
+ ./configure \
--prefix=$install_dir \
--enable-optimized \
--disable-profiling \
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index 644201ddf7c..8a5655d4996 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -136,10 +136,9 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
static void
do_flush( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence)
{
- llvmpipe_flush(pipe, flags, fence, __FUNCTION__);
+ llvmpipe_flush(pipe, fence, __FUNCTION__);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 849db06acdf..42430550ea6 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -40,12 +40,10 @@
/**
- * \param flags bitmask of PIPE_FLUSH_x flags
* \param fence if non-null, returns pointer to a fence which can be waited on
*/
void
llvmpipe_flush( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence,
const char *reason)
{
@@ -54,7 +52,7 @@ llvmpipe_flush( struct pipe_context *pipe,
draw_flush(llvmpipe->draw);
/* ask the setup module to flush */
- lp_setup_flush(llvmpipe->setup, flags, fence, reason);
+ lp_setup_flush(llvmpipe->setup, fence, reason);
if (llvmpipe_variant_count > 1000) {
@@ -65,23 +63,21 @@ llvmpipe_flush( struct pipe_context *pipe,
/* Enable to dump BMPs of the color/depth buffers each frame */
if (0) {
- if (flags & PIPE_FLUSH_FRAME) {
- static unsigned frame_no = 1;
- char filename[256];
- unsigned i;
-
- for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
- util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no);
- debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]);
- }
-
- if (0) {
- util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no);
- debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf);
- }
-
- ++frame_no;
+ static unsigned frame_no = 1;
+ char filename[256];
+ unsigned i;
+
+ for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
+ util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]);
+ }
+
+ if (0) {
+ util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf);
}
+
+ ++frame_no;
}
}
@@ -90,9 +86,9 @@ llvmpipe_finish( struct pipe_context *pipe,
const char *reason )
{
struct pipe_fence_handle *fence = NULL;
- llvmpipe_flush(pipe, 0, &fence, reason);
+ llvmpipe_flush(pipe, &fence, reason);
if (fence) {
- pipe->screen->fence_finish(pipe->screen, fence, 0);
+ pipe->screen->fence_finish(pipe->screen, fence, PIPE_TIMEOUT_INFINITE);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
}
@@ -110,7 +106,6 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
int layer,
- unsigned flush_flags,
boolean read_only,
boolean cpu_access,
boolean do_not_block,
@@ -118,10 +113,10 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
{
unsigned referenced;
- referenced = pipe->is_resource_referenced(pipe, resource, level, layer);
+ referenced = llvmpipe_is_resource_referenced(pipe, resource, level, layer);
- if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
- ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
+ if ((referenced & LP_REFERENCED_FOR_WRITE) ||
+ ((referenced & LP_REFERENCED_FOR_READ) && !read_only)) {
if (cpu_access) {
/*
@@ -136,7 +131,7 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
* Just flush.
*/
- llvmpipe_flush(pipe, flush_flags, NULL, reason);
+ llvmpipe_flush(pipe, NULL, reason);
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
index 579d24c68ad..efff94c8c0c 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.h
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -36,7 +36,6 @@ struct pipe_resource;
void
llvmpipe_flush(struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence,
const char *reason);
@@ -49,7 +48,6 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
int layer,
- unsigned flush_flags,
boolean read_only,
boolean cpu_access,
boolean do_not_block,
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 84c66dd36e8..1e2401fa84d 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -69,7 +69,7 @@ llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
*/
if (pq->fence) {
if (!lp_fence_issued(pq->fence))
- llvmpipe_flush(pipe, 0, NULL, __FUNCTION__);
+ llvmpipe_flush(pipe, NULL, __FUNCTION__);
if (!lp_fence_signalled(pq->fence))
lp_fence_wait(pq->fence);
@@ -99,7 +99,7 @@ llvmpipe_get_query_result(struct pipe_context *pipe,
if (!lp_fence_signalled(pq->fence)) {
if (!lp_fence_issued(pq->fence))
- llvmpipe_flush(pipe, 0, NULL, __FUNCTION__);
+ llvmpipe_flush(pipe, NULL, __FUNCTION__);
if (!wait)
return FALSE;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 2c32aa93cdf..521a52ad3ae 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -164,7 +164,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
return 1;
case PIPE_CAP_DEPTH_CLAMP:
return 0;
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
default:
return 0;
@@ -224,8 +225,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bind,
- unsigned geom_flags )
+ unsigned bind)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
struct sw_winsys *winsys = screen->winsys;
@@ -348,10 +348,9 @@ llvmpipe_fence_reference(struct pipe_screen *screen,
/**
* Has the fence been executed/finished?
*/
-static int
+static boolean
llvmpipe_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flag)
+ struct pipe_fence_handle *fence)
{
struct lp_fence *f = (struct lp_fence *) fence;
return lp_fence_signalled(f);
@@ -361,15 +360,15 @@ llvmpipe_fence_signalled(struct pipe_screen *screen,
/**
* Wait for the fence to finish.
*/
-static int
+static boolean
llvmpipe_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence_handle,
- unsigned flag)
+ uint64_t timeout)
{
struct lp_fence *f = (struct lp_fence *) fence_handle;
lp_fence_wait(f);
- return 0;
+ return TRUE;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 7b7b2721ba8..3813e0ed972 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -333,12 +333,8 @@ fail:
}
-/**
- * \param flags bitmask of PIPE_FLUSH_x flags
- */
void
lp_setup_flush( struct lp_setup_context *setup,
- unsigned flags,
struct pipe_fence_handle **fence,
const char *reason)
{
@@ -469,7 +465,7 @@ lp_setup_clear( struct lp_setup_context *setup,
unsigned flags )
{
if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) {
- lp_setup_flush(setup, 0, NULL, __FUNCTION__);
+ lp_setup_flush(setup, NULL, __FUNCTION__);
if (!lp_setup_try_clear( setup, color, depth, stencil, flags ))
assert(0);
@@ -753,20 +749,20 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
/* check the render targets */
for (i = 0; i < setup->fb.nr_cbufs; i++) {
if (setup->fb.cbufs[i]->texture == texture)
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+ return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
}
if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) {
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+ return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE;
}
/* check textures referenced by the scene */
for (i = 0; i < Elements(setup->scenes); i++) {
if (lp_scene_is_resource_referenced(setup->scenes[i], texture)) {
- return PIPE_REFERENCED_FOR_READ;
+ return LP_REFERENCED_FOR_READ;
}
}
- return PIPE_UNREFERENCED;
+ return LP_UNREFERENCED;
}
@@ -1114,7 +1110,7 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
if (!lp_scene_bin_everywhere(setup->scene,
LP_RAST_OP_END_QUERY,
dummy)) {
- lp_setup_flush(setup, 0, NULL, __FUNCTION__);
+ lp_setup_flush(setup, NULL, __FUNCTION__);
}
}
else {
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 0d6e161a218..8655259d27c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -64,7 +64,6 @@ lp_setup_clear(struct lp_setup_context *setup,
void
lp_setup_flush( struct lp_setup_context *setup,
- unsigned flags,
struct pipe_fence_handle **fence,
const char *reason);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c
index ad751b9ef42..9f1ec146e9d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c
@@ -651,7 +651,7 @@ generate_setup_variant(struct gallivm_state *gallivm,
LLVMTypeRef arg_types[7];
LLVMBasicBlockRef block;
LLVMBuilderRef builder = gallivm->builder;
- int64_t t0, t1;
+ int64_t t0 = 0, t1;
if (0)
goto fail;
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index e7e46a628a1..f49638acf08 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -69,7 +69,6 @@ lp_resource_copy(struct pipe_context *pipe,
llvmpipe_flush_resource(pipe,
dst, dst_level, dstz,
- 0, /* flush_flags */
FALSE, /* read_only */
TRUE, /* cpu_access */
FALSE, /* do_not_block */
@@ -77,7 +76,6 @@ lp_resource_copy(struct pipe_context *pipe,
llvmpipe_flush_resource(pipe,
src, src_level, src_box->z,
- 0, /* flush_flags */
TRUE, /* read_only */
TRUE, /* cpu_access */
FALSE, /* do_not_block */
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 9753da5e57e..fa4ce5bf2ac 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -575,7 +575,6 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
if (!llvmpipe_flush_resource(pipe, resource,
level,
box->depth > 1 ? -1 : box->z,
- 0, /* flush_flags */
read_only,
TRUE, /* cpu_access */
do_not_block,
@@ -695,7 +694,7 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe,
transfer->box.z);
}
-static unsigned int
+unsigned int
llvmpipe_is_resource_referenced( struct pipe_context *pipe,
struct pipe_resource *presource,
unsigned level, int layer)
@@ -703,7 +702,7 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe,
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
if (presource->target == PIPE_BUFFER)
- return PIPE_UNREFERENCED;
+ return LP_UNREFERENCED;
return lp_setup_is_resource_referenced(llvmpipe->setup, presource);
}
@@ -1401,7 +1400,6 @@ llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
pipe->transfer_destroy = llvmpipe_transfer_destroy;
pipe->transfer_map = llvmpipe_transfer_map;
pipe->transfer_unmap = llvmpipe_transfer_unmap;
- pipe->is_resource_referenced = llvmpipe_is_resource_referenced;
pipe->transfer_flush_region = u_default_transfer_flush_region;
pipe->transfer_inline_write = u_default_transfer_inline_write;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index b789c0f4090..b4a0dfd1c36 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -243,4 +243,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
extern void
llvmpipe_init_context_texture_funcs(struct pipe_context *pipe);
+
+#define LP_UNREFERENCED 0
+#define LP_REFERENCED_FOR_READ (1 << 0)
+#define LP_REFERENCED_FOR_WRITE (1 << 1)
+
+unsigned int
+llvmpipe_is_resource_referenced( struct pipe_context *pipe,
+ struct pipe_resource *presource,
+ unsigned level, int layer);
+
#endif /* LP_TEXTURE_H */
diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c
index 3680f4622da..496b7f5ec6d 100644
--- a/src/gallium/drivers/noop/noop_pipe.c
+++ b/src/gallium/drivers/noop/noop_pipe.c
@@ -87,13 +87,6 @@ struct noop_resource {
struct sw_displaytarget *dt;
};
-static unsigned noop_is_resource_referenced(struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level, int layer)
-{
- return PIPE_UNREFERENCED;
-}
-
static struct pipe_resource *noop_resource_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
@@ -267,7 +260,7 @@ static void noop_resource_copy_region(struct pipe_context *ctx,
/*
* context
*/
-static void noop_flush(struct pipe_context *ctx, unsigned flags,
+static void noop_flush(struct pipe_context *ctx,
struct pipe_fence_handle **fence)
{
}
@@ -303,7 +296,6 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void
ctx->transfer_unmap = noop_transfer_unmap;
ctx->transfer_destroy = noop_transfer_destroy;
ctx->transfer_inline_write = noop_transfer_inline_write;
- ctx->is_resource_referenced = noop_is_resource_referenced;
noop_init_state_functions(ctx);
return ctx;
@@ -453,8 +445,7 @@ static boolean noop_is_format_supported(struct pipe_screen* screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned usage,
- unsigned geom_flags)
+ unsigned usage)
{
return true;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index d0cc29104b8..01d3aa46d0e 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -314,7 +314,6 @@ const struct u_resource_vtbl nouveau_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
nouveau_buffer_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
nouveau_buffer_transfer_get, /* get_transfer */
nouveau_buffer_transfer_destroy, /* transfer_destroy */
nouveau_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index 18bdb18ad41..d8f59dce9ed 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -90,6 +90,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
+ /* set this now, so that if fence.emit triggers a flush we don't recurse */
+ fence->state = NOUVEAU_FENCE_STATE_EMITTED;
+
screen->fence.emit(&screen->base, fence->sequence);
++fence->ref;
@@ -100,8 +103,6 @@ nouveau_fence_emit(struct nouveau_fence *fence)
screen->fence.head = fence;
screen->fence.tail = fence;
-
- fence->state = NOUVEAU_FENCE_STATE_EMITTED;
}
void
@@ -215,6 +216,8 @@ nouveau_fence_wait(struct nouveau_fence *fence)
void
nouveau_fence_next(struct nouveau_screen *screen)
{
- nouveau_fence_emit(screen->fence.current);
+ if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTED)
+ nouveau_fence_emit(screen->fence.current);
+
nouveau_fence_new(screen, &screen->fence.current, FALSE);
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index e6cd3064c9a..401155bba6e 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include "nouveau/nouveau_bo.h"
+#include "nouveau/nouveau_mm.h"
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
#include "nouveau_fence.h"
@@ -154,20 +155,19 @@ nouveau_screen_fence_ref(struct pipe_screen *pscreen,
nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr);
}
-static int
+static boolean
nouveau_screen_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *pfence,
- unsigned flags)
+ struct pipe_fence_handle *pfence)
{
- return !nouveau_fence_signalled(nouveau_fence(pfence));
+ return nouveau_fence_signalled(nouveau_fence(pfence));
}
-static int
+static boolean
nouveau_screen_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *pfence,
- unsigned flags)
+ uint64_t timeout)
{
- return !nouveau_fence_wait(nouveau_fence(pfence));
+ return nouveau_fence_wait(nouveau_fence(pfence));
}
@@ -210,26 +210,6 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
}
}
-
-unsigned int
-nouveau_reference_flags(struct nouveau_bo *bo)
-{
- uint32_t bo_flags;
- int flags = 0;
-
- bo_flags = nouveau_bo_pending(bo);
- if (bo_flags & NOUVEAU_BO_RD)
- flags |= PIPE_REFERENCED_FOR_READ;
- if (bo_flags & NOUVEAU_BO_WR)
- flags |= PIPE_REFERENCED_FOR_WRITE;
-
- return flags;
-}
-
-
-
-
-
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index c091abf2786..186ada39677 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -74,10 +74,6 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
struct winsys_handle *whandle,
unsigned *out_stride);
-unsigned int
-nouveau_reference_flags(struct nouveau_bo *bo);
-
-
int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
void nouveau_screen_fini(struct nouveau_screen *);
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 912367b8391..930cee7c1e7 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -30,25 +30,20 @@
#include "nouveau/nouveau_reloc.h"
static void
-nv50_flush(struct pipe_context *pipe, unsigned flags,
+nv50_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
- OUT_RING (chan, 0x20);
- }
+ struct nouveau_screen *screen = &nv50_context(pipe)->screen->base;
if (fence)
- nouveau_fence_ref(nv50->screen->base.fence.current,
- (struct nouveau_fence **)fence);
+ nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+
+ /* Try to emit before firing to avoid having to flush again right after
+ * in case we have to wait on this fence.
+ */
+ nouveau_fence_emit(screen->fence.current);
- if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME))
- FIRE_RING(chan);
+ FIRE_RING(screen->channel);
}
void
@@ -64,10 +59,34 @@ nv50_default_flush_notify(struct nouveau_channel *chan)
}
static void
+nv50_context_unreference_resources(struct nv50_context *nv50)
+{
+ unsigned s, i;
+
+ for (i = 0; i < NV50_BUFCTX_COUNT; ++i)
+ nv50_bufctx_reset(nv50, i);
+
+ for (i = 0; i < nv50->num_vtxbufs; ++i)
+ pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
+
+ pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
+
+ for (s = 0; s < 3; ++s) {
+ for (i = 0; i < nv50->num_textures[s]; ++i)
+ pipe_sampler_view_reference(&nv50->textures[s][i], NULL);
+
+ for (i = 0; i < 16; ++i)
+ pipe_resource_reference(&nv50->constbuf[s][i], NULL);
+ }
+}
+
+static void
nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ nv50_context_unreference_resources(nv50);
+
draw_destroy(nv50->draw);
if (nv50->screen->cur_ctx == nv50) {
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index ae6b26af1eb..9eeca05ada3 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -106,7 +106,6 @@ const struct u_resource_vtbl nv50_miptree_vtbl =
{
nv50_miptree_get_handle, /* get_handle */
nv50_miptree_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
nv50_miptree_transfer_new, /* get_transfer */
nv50_miptree_transfer_del, /* transfer_destroy */
nv50_miptree_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c
index 2a2fb0e32bc..1ae4d70a845 100644
--- a/src/gallium/drivers/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nv50/nv50_resource.c
@@ -3,22 +3,6 @@
#include "nv50_resource.h"
#include "nouveau/nouveau_screen.h"
-static unsigned
-nv50_resource_is_referenced(struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned face, int layer)
-{
- struct nv04_resource *res = nv04_resource(resource);
- unsigned flags = 0;
- unsigned bo_flags = nouveau_bo_pending(res->bo);
-
- if (bo_flags & NOUVEAU_BO_RD)
- flags = PIPE_REFERENCED_FOR_READ;
- if (bo_flags & NOUVEAU_BO_WR)
- flags |= PIPE_REFERENCED_FOR_WRITE;
-
- return flags;
-}
static struct pipe_resource *
nv50_resource_create(struct pipe_screen *screen,
@@ -52,7 +36,6 @@ nv50_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
- pcontext->is_resource_referenced = nv50_resource_is_referenced;
pcontext->create_surface = nv50_miptree_surface_new;
pcontext->surface_destroy = nv50_miptree_surface_del;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ae0365eb5c5..7690c80eef0 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -40,7 +40,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bindings, unsigned geom_flags)
+ unsigned bindings)
{
if (sample_count > 1)
return FALSE;
@@ -127,7 +127,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
return 0;
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
default:
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 980bc369293..db257159698 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -796,10 +796,13 @@ nv50_set_index_buffer(struct pipe_context *pipe,
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (ib)
+ if (ib) {
+ pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+
memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
- else
- nv50->idxbuf.buffer = NULL;
+ } else {
+ pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
+ }
}
static void
@@ -866,5 +869,7 @@ nv50_init_state_functions(struct nv50_context *nv50)
pipe->set_vertex_buffers = nv50_set_vertex_buffers;
pipe->set_index_buffer = nv50_set_index_buffer;
+
+ pipe->redefine_user_buffer = u_default_redefine_user_buffer;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index bf46296e7ef..f3d45eb95e0 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -43,8 +43,9 @@ nv50_validate_fb(struct nv50_context *nv50)
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
+ /* only register for writing, otherwise we'd always serialize here */
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
}
if (fb->zsbuf) {
@@ -74,7 +75,7 @@ nv50_validate_fb(struct nv50_context *nv50)
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
} else {
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
OUT_RING (chan, 0);
@@ -253,6 +254,35 @@ nv50_validate_rasterizer(struct nv50_context *nv50)
OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
}
+static void
+nv50_switch_pipe_context(struct nv50_context *ctx_to)
+{
+ struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
+
+ if (ctx_from)
+ ctx_to->state = ctx_from->state;
+
+ ctx_to->dirty = ~0;
+
+ if (!ctx_to->vertex)
+ ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS);
+
+ if (!ctx_to->vertprog)
+ ctx_to->dirty &= ~NV50_NEW_VERTPROG;
+ if (!ctx_to->fragprog)
+ ctx_to->dirty &= ~NV50_NEW_FRAGPROG;
+
+ if (!ctx_to->blend)
+ ctx_to->dirty &= ~NV50_NEW_BLEND;
+ if (!ctx_to->rast)
+ ctx_to->dirty &= ~NV50_NEW_RASTERIZER;
+ if (!ctx_to->zsa)
+ ctx_to->dirty &= ~NV50_NEW_ZSA;
+
+ ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
+ ctx_to;
+}
+
static struct state_validate {
void (*func)(struct nv50_context *);
uint32_t states;
@@ -292,11 +322,9 @@ boolean
nv50_state_validate(struct nv50_context *nv50)
{
unsigned i;
-#if 0
- if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */
- nv50->dirty = 0xffffffff;
-#endif
- nv50->screen->cur_ctx = nv50;
+
+ if (nv50->screen->cur_ctx != nv50)
+ nv50_switch_pipe_context(nv50);
if (nv50->dirty) {
for (i = 0; i < validate_list_len; ++i) {
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
index cf5b92ef1a8..515e3e78d42 100644
--- a/src/gallium/drivers/nv50/nv50_stateobj.h
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -49,7 +49,7 @@ struct nv50_vertex_stateobj {
boolean need_conversion;
unsigned vertex_size;
unsigned packet_vertex_limit;
- struct nv50_vertex_element element[1];
+ struct nv50_vertex_element element[0];
};
#endif
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 4f0a5018459..abdb9ce2f93 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -51,10 +51,8 @@ nv50_vertex_state_create(struct pipe_context *pipe,
struct translate_key transkey;
unsigned i;
- assert(num_elements);
-
so = MALLOC(sizeof(*so) +
- (num_elements - 1) * sizeof(struct nv50_vertex_element));
+ num_elements * sizeof(struct nv50_vertex_element));
if (!so)
return NULL;
so->num_elements = num_elements;
diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
index 5857f7cee9e..94fa081ad7e 100644
--- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
@@ -927,6 +927,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_ZETA_BASE_LAYER 0x0000179c
+#define NVC0_3D_VERTEX_QUARANTINE_ADDRESS_HIGH 0x000017bc
+
+#define NVC0_3D_VERTEX_QUARANTINE_ADDRESS_LOW 0x000017c0
+
+#define NVC0_3D_VERTEX_QUARANTINE_SIZE 0x000017c4
+#define NVC0_3D_VERTEX_QUARANTINE_SIZE_16K 0x00000001
+#define NVC0_3D_VERTEX_QUARANTINE_SIZE_32K 0x00000002
+#define NVC0_3D_VERTEX_QUARANTINE_SIZE_64K 0x00000003
+
#define NVC0_3D_STRMOUT_UNK1780(i0) (0x00001780 + 0x4*(i0))
#define NVC0_3D_STRMOUT_UNK1780__ESIZE 0x00000004
#define NVC0_3D_STRMOUT_UNK1780__LEN 0x00000004
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index d6de979b132..5d2168e600b 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -30,29 +30,45 @@
#include "nouveau/nouveau_reloc.h"
static void
-nvc0_flush(struct pipe_context *pipe, unsigned flags,
+nvc0_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
- struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
- OUT_RING (chan, 0x00);
- } else
- if ((flags & PIPE_FLUSH_RENDER_CACHE) && !(flags & PIPE_FLUSH_FRAME)) {
- BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
- OUT_RING (chan, 0);
- }
+ struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base;
if (fence)
- nouveau_fence_ref(nvc0->screen->base.fence.current,
- (struct nouveau_fence **)fence);
+ nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+
+ /* Try to emit before firing to avoid having to flush again right after
+ * in case we have to wait on this fence.
+ */
+ nouveau_fence_emit(screen->fence.current);
+
+ FIRE_RING(screen->channel);
+}
+
+static void
+nvc0_context_unreference_resources(struct nvc0_context *nvc0)
+{
+ unsigned s, i;
+
+ for (i = 0; i < NVC0_BUFCTX_COUNT; ++i)
+ nvc0_bufctx_reset(nvc0, i);
+
+ for (i = 0; i < nvc0->num_vtxbufs; ++i)
+ pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
+
+ pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
- if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME))
- FIRE_RING(chan);
+ for (s = 0; s < 5; ++s) {
+ for (i = 0; i < nvc0->num_textures[s]; ++i)
+ pipe_sampler_view_reference(&nvc0->textures[s][i], NULL);
+
+ for (i = 0; i < 16; ++i)
+ pipe_resource_reference(&nvc0->constbuf[s][i], NULL);
+ }
+
+ for (i = 0; i < nvc0->num_tfbbufs; ++i)
+ pipe_resource_reference(&nvc0->tfbbuf[i], NULL);
}
static void
@@ -60,6 +76,8 @@ nvc0_destroy(struct pipe_context *pipe)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ nvc0_context_unreference_resources(nvc0);
+
draw_destroy(nvc0->draw);
if (nvc0->screen->cur_ctx == nvc0) {
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index 67c5a1287b1..102997e4fcb 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -79,6 +79,7 @@ struct nvc0_context {
uint32_t instance_base;
int32_t index_bias;
boolean prim_restart;
+ boolean early_z;
uint8_t num_vtxbufs;
uint8_t num_vtxelts;
uint8_t num_textures[5];
@@ -135,6 +136,9 @@ struct nvc0_context {
struct draw_context *draw;
};
+#define NVC0_USING_EDGEFLAG(ctx) \
+ ((ctx)->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS)
+
static INLINE struct nvc0_context *
nvc0_context(struct pipe_context *pipe)
{
diff --git a/src/gallium/drivers/nvc0/nvc0_graph_macros.h b/src/gallium/drivers/nvc0/nvc0_graph_macros.h
index 8da963a4c5b..b7d0d3eafa4 100644
--- a/src/gallium/drivers/nvc0/nvc0_graph_macros.h
+++ b/src/gallium/drivers/nvc0/nvc0_graph_macros.h
@@ -144,7 +144,7 @@ static const uint32_t nvc0_9097_poly_mode_back[] =
0x00180611, /* 0x05: mov $r6 0x60 */
0x0014bf10, /* 0x06: mov $r7 and $r7 $r2 */
0x0000f807, /* 0x07: braz $r7 0xa */
- 0x00dac021, /* 0x08: maddr 0x36b */
+ 0x00db0021, /* 0x08: maddr 0x36c */
0x00800611, /* 0x09: mov $r6 0x200 */
0x00131f10, /* 0x0a: mov $r7 or $r3 $r4 */
0x0014bf10, /* 0x0b: mov $r7 and $r7 $r2 */
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c
index db9117c3ff1..bced3245524 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -114,7 +114,6 @@ const struct u_resource_vtbl nvc0_miptree_vtbl =
{
nvc0_miptree_get_handle, /* get_handle */
nvc0_miptree_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
nvc0_miptree_transfer_new, /* get_transfer */
nvc0_miptree_transfer_del, /* transfer_destroy */
nvc0_miptree_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/nvc0/nvc0_pc.c b/src/gallium/drivers/nvc0/nvc0_pc.c
index f51d289e8cd..bd85a7f1ffd 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc.c
@@ -25,6 +25,14 @@
#include "nvc0_pc.h"
#include "nvc0_program.h"
+uint8_t
+nvc0_ir_reverse_cc(uint8_t cc)
+{
+ static const uint8_t cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+ return cc_swapped[cc & 7] | (cc & ~7);
+}
+
boolean
nvc0_insn_can_load(struct nv_instruction *nvi, int s,
struct nv_instruction *ld)
diff --git a/src/gallium/drivers/nvc0/nvc0_pc.h b/src/gallium/drivers/nvc0/nvc0_pc.h
index efa073a9201..3a5612a5fac 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc.h
+++ b/src/gallium/drivers/nvc0/nvc0_pc.h
@@ -210,6 +210,8 @@
#define NV_CC_P 0
#define NV_CC_NOT_P 1
+uint8_t nvc0_ir_reverse_cc(uint8_t cc);
+
#define NV_PC_MAX_INSTRUCTIONS 2048
#define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4)
@@ -219,7 +221,7 @@ struct nv_op_info {
uint base; /* e.g. ADD_S32 -> ADD */
char name[12];
uint8_t type;
- uint8_t mods;
+ uint16_t mods;
unsigned flow : 1;
unsigned commutative : 1;
unsigned vector : 1;
@@ -234,12 +236,6 @@ extern struct nv_op_info nvc0_op_info_table[];
#define NV_BASEOP(op) (nvc0_op_info_table[op].base)
#define NV_OPTYPE(op) (nvc0_op_info_table[op].type)
-static INLINE uint
-nv_op_base(uint opcode)
-{
- return nvc0_op_info_table[opcode].base;
-}
-
static INLINE boolean
nv_is_texture_op(uint opcode)
{
@@ -259,9 +255,9 @@ nv_op_commutative(uint opcode)
}
static INLINE uint8_t
-nv_op_supported_src_mods(uint opcode)
+nv_op_supported_src_mods(uint opcode, int s)
{
- return nvc0_op_info_table[opcode].mods;
+ return (nvc0_op_info_table[opcode].mods >> (s * 4)) & 0xf;
}
static INLINE uint
diff --git a/src/gallium/drivers/nvc0/nvc0_pc_emit.c b/src/gallium/drivers/nvc0/nvc0_pc_emit.c
index c10f920e6f1..76ad40dbcf8 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc_emit.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc_emit.c
@@ -610,6 +610,8 @@ emit_selp(struct nv_pc *pc, struct nv_instruction *i)
static void
emit_slct(struct nv_pc *pc, struct nv_instruction *i)
{
+ uint8_t cc = i->set_cond;
+
pc->emit[0] = 0x00000000;
switch (i->opcode) {
@@ -627,7 +629,10 @@ emit_slct(struct nv_pc *pc, struct nv_instruction *i)
emit_form_0(pc, i);
- pc->emit[1] |= i->set_cond << 23;
+ if (i->src[2]->mod & NV_MOD_NEG)
+ cc = nvc0_ir_reverse_cc(cc);
+
+ pc->emit[1] |= cc << 23;
}
static void
diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
index c5a7367a5fd..f7bf1680d09 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c
@@ -240,8 +240,6 @@ is_immd32_load(struct nv_instruction *nvi)
static INLINE void
check_swap_src_0_1(struct nv_instruction *nvi)
{
- static const uint8_t cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-
struct nv_ref *src0 = nvi->src[0];
struct nv_ref *src1 = nvi->src[1];
@@ -270,7 +268,7 @@ check_swap_src_0_1(struct nv_instruction *nvi)
if (nvi->src[0] != src0) {
if (NV_BASEOP(nvi->opcode) == NV_OP_SET)
- nvi->set_cond = (nvi->set_cond & ~7) | cc_swapped[nvi->set_cond & 7];
+ nvi->set_cond = nvc0_ir_reverse_cc(nvi->set_cond);
else
if (NV_BASEOP(nvi->opcode) == NV_OP_SLCT)
nvi->set_cond = NV_CC_INVERSE(nvi->set_cond);
@@ -363,7 +361,7 @@ nv_pass_lower_mods(struct nv_pass *ctx, struct nv_basic_block *b)
mod = 0;
}
- if ((nv_op_supported_src_mods(nvi->opcode) & mod) != mod)
+ if ((nv_op_supported_src_mods(nvi->opcode, j) & mod) != mod)
continue;
nv_reference(ctx->pc, nvi, j, mi->src[0]->value);
diff --git a/src/gallium/drivers/nvc0/nvc0_pc_print.c b/src/gallium/drivers/nvc0/nvc0_pc_print.c
index 90c669cc4b8..1f37cb802d7 100644
--- a/src/gallium/drivers/nvc0/nvc0_pc_print.c
+++ b/src/gallium/drivers/nvc0/nvc0_pc_print.c
@@ -269,7 +269,11 @@ nvc0_print_instruction(struct nv_instruction *i)
PRINT(" %s\n", norm);
}
-#define NV_MOD_SGN NV_MOD_ABS | NV_MOD_NEG
+#define NV_MOD_SGN_12 ((NV_MOD_ABS | NV_MOD_NEG) | ((NV_MOD_ABS | NV_MOD_NEG) << 4))
+#define NV_MOD_NEG_123 (NV_MOD_NEG | (NV_MOD_NEG << 4) | (NV_MOD_NEG << 8))
+#define NV_MOD_NEG_3 (NV_MOD_NEG << 8)
+
+#define NV_MOD_SGN NV_MOD_SGN_12
struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] =
{
@@ -292,8 +296,8 @@ struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] =
{ NV_OP_SET, "set", NV_TYPE_ANY, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 },
{ NV_OP_ADD, "add", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 },
{ NV_OP_SUB, "sub", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 2, 2 },
- { NV_OP_MUL, "mul", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 },
- { NV_OP_MAD, "mad", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 },
+ { NV_OP_MUL, "mul", NV_TYPE_F32, NV_MOD_NEG_123, 0, 1, 0, 1, 0, 2, 2 },
+ { NV_OP_MAD, "mad", NV_TYPE_F32, NV_MOD_NEG_123, 0, 1, 0, 1, 0, 2, 2 },
{ NV_OP_ABS, "abs", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 },
{ NV_OP_NEG, "neg", NV_TYPE_F32, NV_MOD_ABS, 0, 0, 0, 1, 0, 0, 0 },
{ NV_OP_MAX, "max", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 },
@@ -363,9 +367,9 @@ struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] =
{ NV_OP_SELP, "selp", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 },
- { NV_OP_SLCT, "slct", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 2, 2 },
- { NV_OP_SLCT, "slct", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 2, 2 },
- { NV_OP_SLCT, "slct", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 2, 2 },
+ { NV_OP_SLCT, "slct", NV_TYPE_F32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 },
+ { NV_OP_SLCT, "slct", NV_TYPE_S32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 },
+ { NV_OP_SLCT, "slct", NV_TYPE_U32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 },
{ NV_OP_ADD, "sub", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 1, 0 },
diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index 899fe147c6a..3c59213176e 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -202,6 +202,8 @@ nvc0_varying_location(unsigned sn, unsigned si)
return 0x40;
case TGSI_SEMANTIC_FACE:
return 0x3fc;
+ case TGSI_SEMANTIC_EDGEFLAG: /* doesn't exist, set value like for an sreg */
+ return 0xf00;
/*
case TGSI_SEMANTIC_CLIP_DISTANCE:
return 0x2c0 + (si * 4);
@@ -290,6 +292,8 @@ prog_decl(struct nvc0_translation_info *ti,
ti->output_loc[i][c] = si * 4 + c;
}
} else {
+ if (sn == TGSI_SEMANTIC_EDGEFLAG)
+ ti->edgeflag_out = i;
for (c = 0; c < 4; ++c)
ti->output_loc[i][c] = nvc0_varying_location(sn, si) + c * 4;
/* for TFB_VARYING_LOCS: */
@@ -298,6 +302,7 @@ prog_decl(struct nvc0_translation_info *ti,
}
break;
case TGSI_FILE_SYSTEM_VALUE:
+ i = first;
ti->sysval_loc[i] = nvc0_system_value_location(sn, si, &ti->sysval_in[i]);
assert(first == last);
break;
@@ -426,6 +431,8 @@ nvc0_vp_gp_gen_header(struct nvc0_program *vp, struct nvc0_translation_info *ti)
for (i = 0; i <= ti->scan.file_max[TGSI_FILE_OUTPUT]; ++i) {
a = (ti->output_loc[i][0] - 0x40) / 4;
+ if (ti->output_loc[i][0] >= 0xf00)
+ continue;
for (c = 0; c < 4; ++c, ++a) {
if (!ti->output_access[i][c])
continue;
@@ -528,7 +535,7 @@ nvc0_fp_gen_header(struct nvc0_program *fp, struct nvc0_translation_info *ti)
}
for (i = 0; i <= ti->scan.file_max[TGSI_FILE_INPUT]; ++i) {
- m = ti->interp_mode[i];
+ m = ti->interp_mode[i] & 3;
for (c = 0; c < 4; ++c) {
if (!ti->input_access[i][c])
continue;
@@ -669,6 +676,8 @@ nvc0_program_translate(struct nvc0_program *prog)
ti->edgeflag_out = PIPE_MAX_SHADER_OUTPUTS;
+ prog->vp.edgeflag = PIPE_MAX_ATTRIBS;
+
if (prog->type == PIPE_SHADER_VERTEX && prog->vp.num_ucps)
ti->append_ucp = TRUE;
diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c
index 68544c90d29..2e9f4c10928 100644
--- a/src/gallium/drivers/nvc0/nvc0_push.c
+++ b/src/gallium/drivers/nvc0/nvc0_push.c
@@ -15,9 +15,6 @@ struct push_context {
void *idxbuf;
- float edgeflag;
- int edgeflag_attr;
-
uint32_t vertex_words;
uint32_t packet_vertex_limit;
@@ -27,8 +24,56 @@ struct push_context {
uint32_t prim;
uint32_t restart_index;
uint32_t instance_id;
+
+ struct {
+ int buffer;
+ float value;
+ uint8_t *data;
+ unsigned offset;
+ unsigned stride;
+ } edgeflag;
};
+static void
+init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
+{
+ struct pipe_vertex_element *ve;
+
+ ctx->chan = nvc0->screen->base.channel;
+ ctx->translate = nvc0->vertex->translate;
+
+ ctx->edgeflag.value = 0.5f;
+
+ if (NVC0_USING_EDGEFLAG(nvc0)) {
+ ve = &nvc0->vertex->element[nvc0->vertprog->vp.edgeflag].pipe;
+
+ ctx->edgeflag.buffer = ve->vertex_buffer_index;
+ ctx->edgeflag.offset = ve->src_offset;
+
+ ctx->packet_vertex_limit = 1;
+ } else {
+ ctx->edgeflag.buffer = -1;
+ ctx->edgeflag.offset = 0;
+ ctx->edgeflag.stride = 0;
+ ctx->edgeflag.data = NULL;
+
+ ctx->packet_vertex_limit = nvc0->vertex->vtx_per_packet_max;
+ }
+
+ ctx->vertex_words = nvc0->vertex->vtx_size;
+}
+
+static INLINE void
+set_edgeflag(struct push_context *ctx, unsigned vtx_id)
+{
+ float f = *(float *)(ctx->edgeflag.data + vtx_id * ctx->edgeflag.stride);
+
+ if (ctx->edgeflag.value != f) {
+ ctx->edgeflag.value = f;
+ IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0);
+ }
+}
+
static INLINE unsigned
prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index)
{
@@ -62,7 +107,7 @@ prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index)
static void
emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
{
- uint8_t *elts = (uint8_t *)ctx->idxbuf + start;
+ uint8_t *restrict elts = (uint8_t *)ctx->idxbuf + start;
while (count) {
unsigned push = MIN2(count, ctx->packet_vertex_limit);
@@ -72,6 +117,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i08(elts, push, ctx->restart_index);
+ if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
+ set_edgeflag(ctx, elts[0]);
+
size = ctx->vertex_words * nr;
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
@@ -97,7 +145,7 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
static void
emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
{
- uint16_t *elts = (uint16_t *)ctx->idxbuf + start;
+ uint16_t *restrict elts = (uint16_t *)ctx->idxbuf + start;
while (count) {
unsigned push = MIN2(count, ctx->packet_vertex_limit);
@@ -107,6 +155,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i16(elts, push, ctx->restart_index);
+ if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
+ set_edgeflag(ctx, elts[0]);
+
size = ctx->vertex_words * nr;
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
@@ -132,7 +183,7 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
static void
emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
{
- uint32_t *elts = (uint32_t *)ctx->idxbuf + start;
+ uint32_t *restrict elts = (uint32_t *)ctx->idxbuf + start;
while (count) {
unsigned push = MIN2(count, ctx->packet_vertex_limit);
@@ -142,6 +193,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
if (ctx->primitive_restart)
nr = prim_restart_search_i32(elts, push, ctx->restart_index);
+ if (unlikely(ctx->edgeflag.buffer >= 0) && nr)
+ set_edgeflag(ctx, elts[0]);
+
size = ctx->vertex_words * nr;
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
@@ -171,6 +225,9 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
unsigned push = MIN2(count, ctx->packet_vertex_limit);
unsigned size = ctx->vertex_words * push;
+ if (unlikely(ctx->edgeflag.buffer >= 0))
+ set_edgeflag(ctx, start);
+
BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
@@ -219,10 +276,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
unsigned inst = info->instance_count;
boolean apply_bias = info->indexed && info->index_bias;
- ctx.chan = nvc0->screen->base.channel;
- ctx.translate = nvc0->vertex->translate;
- ctx.packet_vertex_limit = nvc0->vertex->vtx_per_packet_max;
- ctx.vertex_words = nvc0->vertex->vtx_size;
+ init_push_context(nvc0, &ctx);
for (i = 0; i < nvc0->num_vtxbufs; ++i) {
uint8_t *data;
@@ -236,12 +290,18 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
data += info->index_bias * vb->stride;
ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
+
+ if (unlikely(i == ctx.edgeflag.buffer)) {
+ ctx.edgeflag.data = data + ctx.edgeflag.offset;
+ ctx.edgeflag.stride = vb->stride;
+ }
}
if (info->indexed) {
- ctx.idxbuf = nouveau_resource_map_offset(&nvc0->base,
- nv04_resource(nvc0->idxbuf.buffer),
- nvc0->idxbuf.offset, NOUVEAU_BO_RD);
+ ctx.idxbuf =
+ nouveau_resource_map_offset(&nvc0->base,
+ nv04_resource(nvc0->idxbuf.buffer),
+ nvc0->idxbuf.offset, NOUVEAU_BO_RD);
if (!ctx.idxbuf)
return;
index_size = nvc0->idxbuf.index_size;
@@ -283,6 +343,9 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
+ if (unlikely(ctx.edgeflag.value == 0.0f))
+ IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1);
+
if (info->indexed)
nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer));
diff --git a/src/gallium/drivers/nvc0/nvc0_resource.c b/src/gallium/drivers/nvc0/nvc0_resource.c
index fb5a496b84b..44e66314e7e 100644
--- a/src/gallium/drivers/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nvc0/nvc0_resource.c
@@ -3,25 +3,6 @@
#include "nvc0_resource.h"
#include "nouveau/nouveau_screen.h"
-static unsigned
-nvc0_resource_is_referenced(struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned face, int layer)
-{
- struct nv04_resource *res = nv04_resource(resource);
- unsigned flags = 0;
-
-#ifdef NOUVEAU_USERSPACE_MM
- flags = res->status;
-#else
- unsigned bo_flags = nouveau_bo_pending(res->bo);
- if (bo_flags & NOUVEAU_BO_RD)
- flags = PIPE_REFERENCED_FOR_READ;
- if (bo_flags & NOUVEAU_BO_WR)
- flags |= PIPE_REFERENCED_FOR_WRITE;
-#endif
- return flags;
-}
static struct pipe_resource *
nvc0_resource_create(struct pipe_screen *screen,
@@ -55,7 +36,6 @@ nvc0_init_resource_functions(struct pipe_context *pcontext)
pcontext->transfer_unmap = u_transfer_unmap_vtbl;
pcontext->transfer_destroy = u_transfer_destroy_vtbl;
pcontext->transfer_inline_write = u_transfer_inline_write_vtbl;
- pcontext->is_resource_referenced = nvc0_resource_is_referenced;
pcontext->create_surface = nvc0_miptree_surface_new;
pcontext->surface_destroy = nvc0_miptree_surface_del;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index d430be92c51..1047ba3c337 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -34,7 +34,7 @@ nvc0_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bindings, unsigned geom_flags)
+ unsigned bindings)
{
if (sample_count > 1)
return FALSE;
@@ -111,7 +111,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
return 0;
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
default:
NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
@@ -206,7 +207,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->tls);
nouveau_bo_ref(NULL, &screen->txc);
nouveau_bo_ref(NULL, &screen->fence.bo);
- nouveau_bo_ref(NULL, &screen->mp_stack_bo);
+ nouveau_bo_ref(NULL, &screen->vfetch_cache);
nouveau_resource_destroy(&screen->text_heap);
@@ -495,14 +496,14 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
OUT_RING (chan, 0);
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20,
- &screen->mp_stack_bo);
+ &screen->vfetch_cache);
if (ret)
goto fail;
- BEGIN_RING(chan, RING_3D_(0x17bc), 3);
- OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, 1);
+ BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
+ OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ OUT_RING (chan, 3);
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc);
if (ret)
@@ -634,7 +635,7 @@ nvc0_screen_make_buffers_resident(struct nvc0_screen *screen)
nouveau_bo_validate(chan, screen->text, flags);
nouveau_bo_validate(chan, screen->uniforms, flags);
nouveau_bo_validate(chan, screen->txc, flags);
- nouveau_bo_validate(chan, screen->mp_stack_bo, flags);
+ nouveau_bo_validate(chan, screen->vfetch_cache, flags);
if (screen->cur_ctx && screen->cur_ctx->state.tls_required)
nouveau_bo_validate(chan, screen->tls, flags);
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 81f404ada83..94bf0cf3481 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -26,7 +26,7 @@ struct nvc0_screen {
struct nouveau_bo *uniforms;
struct nouveau_bo *tls;
struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */
- struct nouveau_bo *mp_stack_bo;
+ struct nouveau_bo *vfetch_cache;
uint64_t tls_size;
diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c
index 79b5f3d81cc..7294eaa222e 100644
--- a/src/gallium/drivers/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c
@@ -111,8 +111,6 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0)
return;
nvc0_program_update_context_state(nvc0, fp, 4);
- BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1);
- OUT_RING (chan, fp->fp.early_z);
BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2);
OUT_RING (chan, 0x51);
OUT_RING (chan, fp->code_base);
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index f230292316f..ab68abcfb5a 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -166,6 +166,7 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nvc0_rasterizer_stateobj *so;
+ uint32_t reg;
so = CALLOC_STRUCT(nvc0_rasterizer_stateobj);
if (!so)
@@ -202,6 +203,13 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe,
SB_BEGIN_3D(so, POINT_SIZE, 1);
SB_DATA (so, fui(cso->point_size));
}
+
+ reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ?
+ NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT :
+ NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT;
+
+ SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1);
+ SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg);
SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization);
SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth);
@@ -268,14 +276,11 @@ nvc0_zsa_state_create(struct pipe_context *pipe,
so->pipe = *cso;
- SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
- SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
+ SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled);
if (cso->depth.enabled) {
- SB_DATA (so, 1);
+ SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
SB_DATA (so, nvgl_comparison_op(cso->depth.func));
- } else {
- SB_DATA (so, 0);
}
if (cso->stencil[0].enabled) {
@@ -307,15 +312,12 @@ nvc0_zsa_state_create(struct pipe_context *pipe,
if (cso->stencil[0].enabled) {
SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0);
}
-
- SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
+
+ SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled);
if (cso->alpha.enabled) {
- SB_DATA (so, 1);
SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
SB_DATA (so, fui(cso->alpha.ref_value));
SB_DATA (so, nvgl_comparison_op(cso->alpha.func));
- } else {
- SB_DATA (so, 0);
}
assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
@@ -706,10 +708,13 @@ nvc0_set_index_buffer(struct pipe_context *pipe,
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- if (ib)
- memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
- else
- nvc0->idxbuf.buffer = NULL;
+ if (ib) {
+ pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
+
+ memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
+ } else {
+ pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
+ }
}
static void
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 6fd880829e4..bb81480bab9 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -93,8 +93,9 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
+ /* only register for writing, otherwise we'd always serialize here */
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
}
if (fb->zsbuf) {
@@ -127,7 +128,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
} else {
BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
OUT_RING (chan, 0);
@@ -294,32 +295,6 @@ nvc0_validate_rasterizer(struct nvc0_context *nvc0)
}
static void
-nvc0_validate_sprite_coords(struct nvc0_context *nvc0)
-{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
- uint32_t reg;
-
- if (nvc0->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT)
- reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT;
- else
- reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT;
-
- if (nvc0->rast->pipe.point_quad_rasterization) {
- uint32_t en = nvc0->rast->pipe.sprite_coord_enable;
-
- while (en) {
- int i = ffs(en) - 1;
- en &= ~(1 << i);
- if (i >= 0 && i < 8)
- reg |= 8 << i;
- }
- }
-
- BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1);
- OUT_RING (chan, reg);
-}
-
-static void
nvc0_constbufs_validate(struct nvc0_context *nvc0)
{
struct nouveau_channel *chan = nvc0->screen->base.channel;
@@ -413,6 +388,49 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
}
}
+static void
+nvc0_validate_derived_1(struct nvc0_context *nvc0)
+{
+ struct nouveau_channel *chan = nvc0->screen->base.channel;
+ boolean early_z;
+
+ early_z = nvc0->fragprog->fp.early_z && !nvc0->zsa->pipe.alpha.enabled;
+
+ if (early_z != nvc0->state.early_z) {
+ nvc0->state.early_z = early_z;
+ IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z);
+ }
+}
+
+static void
+nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
+{
+ struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx;
+
+ if (ctx_from)
+ ctx_to->state = ctx_from->state;
+
+ ctx_to->dirty = ~0;
+
+ if (!ctx_to->vertex)
+ ctx_to->dirty &= ~(NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS);
+
+ if (!ctx_to->vertprog)
+ ctx_to->dirty &= ~NVC0_NEW_VERTPROG;
+ if (!ctx_to->fragprog)
+ ctx_to->dirty &= ~NVC0_NEW_FRAGPROG;
+
+ if (!ctx_to->blend)
+ ctx_to->dirty &= ~NVC0_NEW_BLEND;
+ if (!ctx_to->rast)
+ ctx_to->dirty &= ~NVC0_NEW_RASTERIZER;
+ if (!ctx_to->zsa)
+ ctx_to->dirty &= ~NVC0_NEW_ZSA;
+
+ ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx =
+ ctx_to;
+}
+
static struct state_validate {
void (*func)(struct nvc0_context *);
uint32_t states;
@@ -432,7 +450,7 @@ static struct state_validate {
{ nvc0_tevlprog_validate, NVC0_NEW_TEVLPROG },
{ nvc0_gmtyprog_validate, NVC0_NEW_GMTYPROG },
{ nvc0_fragprog_validate, NVC0_NEW_FRAGPROG },
- { nvc0_validate_sprite_coords, NVC0_NEW_RASTERIZER | NVC0_NEW_FRAGPROG },
+ { nvc0_validate_derived_1, NVC0_NEW_FRAGPROG | NVC0_NEW_ZSA },
{ nvc0_constbufs_validate, NVC0_NEW_CONSTBUF },
{ nvc0_validate_textures, NVC0_NEW_TEXTURES },
{ nvc0_validate_samplers, NVC0_NEW_SAMPLERS },
@@ -445,11 +463,9 @@ boolean
nvc0_state_validate(struct nvc0_context *nvc0)
{
unsigned i;
-#if 0
- if (nvc0->screen->cur_ctx != nvc0) /* FIXME: not everything is valid */
- nvc0->dirty = 0xffffffff;
-#endif
- nvc0->screen->cur_ctx = nvc0;
+
+ if (nvc0->screen->cur_ctx != nvc0)
+ nvc0_switch_pipe_context(nvc0);
if (nvc0->dirty) {
for (i = 0; i < validate_list_len; ++i) {
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index 17fc51b8aac..fc5f45ea25d 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -240,7 +240,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
struct nvc0_m2mf_rect drect, srect;
unsigned i;
unsigned nx = util_format_get_nblocksx(src->format, src_box->width);
- unsigned ny = util_format_get_nblocksx(src->format, src_box->height);
+ unsigned ny = util_format_get_nblocksy(src->format, src_box->height);
nvc0_setup_m2mf_rect(&drect, dst, dst_level, dstx, dsty, dstz);
nvc0_setup_m2mf_rect(&srect, src, src_level,
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index e7e7ce7dc22..6bbcf2447ec 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -51,8 +51,6 @@ nvc0_vertex_state_create(struct pipe_context *pipe,
struct translate_key transkey;
unsigned i;
- assert(num_elements);
-
so = MALLOC(sizeof(*so) +
num_elements * sizeof(struct nvc0_vertex_element));
if (!so)
@@ -265,7 +263,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
struct nvc0_vertex_element *ve;
unsigned i;
- if (unlikely(vertex->need_conversion)) {
+ if (unlikely(vertex->need_conversion || NVC0_USING_EDGEFLAG(nvc0))) {
nvc0->vbo_fifo = ~0;
nvc0->vbo_user = 0;
} else {
diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
index 6c8934d3a4a..2bcb93d93e3 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -7,7 +7,7 @@
#include "nvfx_resource.h"
static void
-nvfx_flush(struct pipe_context *pipe, unsigned flags,
+nvfx_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
@@ -16,12 +16,13 @@ nvfx_flush(struct pipe_context *pipe, unsigned flags,
struct nouveau_grobj *eng3d = screen->eng3d;
/* XXX: we need to actually be intelligent here */
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+ /* XXX This flag wasn't set by the state tracker anyway. */
+ /*if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
BEGIN_RING(chan, eng3d, 0x1fd8, 1);
OUT_RING(chan, 2);
BEGIN_RING(chan, eng3d, 0x1fd8, 1);
OUT_RING(chan, 1);
- }
+ }*/
FIRE_RING(chan);
if (fence)
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 8c043b867ba..1be84b90a90 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -138,11 +138,11 @@ nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_reso
// on our current driver (and the driver too), format support does not depend on geometry, so don't bother computing it
// TODO: may want to revisit this
- if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_RENDER_TARGET, 0))
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_RENDER_TARGET))
mt->base.base.bind &=~ PIPE_BIND_RENDER_TARGET;
- if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_SAMPLER_VIEW))
mt->base.base.bind &=~ PIPE_BIND_SAMPLER_VIEW;
- if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+ if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_DEPTH_STENCIL))
mt->base.base.bind &=~ PIPE_BIND_DEPTH_STENCIL;
return mt;
diff --git a/src/gallium/drivers/nvfx/nvfx_resource.c b/src/gallium/drivers/nvfx/nvfx_resource.c
index c60a7bb8b93..42e77c53621 100644
--- a/src/gallium/drivers/nvfx/nvfx_resource.c
+++ b/src/gallium/drivers/nvfx/nvfx_resource.c
@@ -4,13 +4,6 @@
#include "nvfx_resource.h"
#include "nouveau/nouveau_screen.h"
-static unsigned int
-nvfx_resource_is_referenced(struct pipe_context *pipe,
- struct pipe_resource *pr,
- unsigned level, int layer)
-{
- return !!nouveau_reference_flags(nvfx_resource(pr)->bo);
-}
static struct pipe_resource *
nvfx_resource_create(struct pipe_screen *screen,
@@ -58,8 +51,6 @@ nvfx_resource_get_handle(struct pipe_screen *pscreen,
void
nvfx_init_resource_functions(struct pipe_context *pipe)
{
- pipe->is_resource_referenced = nvfx_resource_is_referenced;
-
pipe->create_surface = nvfx_miptree_surface_new;
pipe->surface_destroy = nvfx_miptree_surface_del;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 15db574a1d0..8742f60c163 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -203,7 +203,7 @@ nvfx_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bind, unsigned geom_flags)
+ unsigned bind)
{
struct nvfx_screen *screen = nvfx_screen(pscreen);
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 40ae4f5bd21..ae9c31418c3 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -426,7 +426,7 @@ nvfx_state_validate_swtnl(struct nvfx_context *nvfx)
NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx->fallback_swtnl);
warned = TRUE;
}
- nvfx->pipe.flush(&nvfx->pipe, 0, NULL);
+ nvfx->pipe.flush(&nvfx->pipe, NULL);
nvfx->dirty |= (NVFX_NEW_VIEWPORT |
NVFX_NEW_VERTPROG |
NVFX_NEW_ARRAYS);
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 6391ea7f3be..37b635fd120 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -263,7 +263,7 @@ static void r300_clear(struct pipe_context* pipe,
/* Reserve CS space. */
if (dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
- r300->context.flush(&r300->context, 0, NULL);
+ r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL);
}
/* Emit clear packets. */
@@ -447,11 +447,11 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
!pipe->screen->is_format_supported(pipe->screen,
src->format, src->target,
src->nr_samples,
- PIPE_BIND_SAMPLER_VIEW, 0) ||
+ PIPE_BIND_SAMPLER_VIEW) ||
!pipe->screen->is_format_supported(pipe->screen,
dst->format, dst->target,
dst->nr_samples,
- PIPE_BIND_RENDER_TARGET, 0))) {
+ PIPE_BIND_RENDER_TARGET))) {
switch (util_format_get_blocksize(old_dst.format)) {
case 1:
new_dst.format = PIPE_FORMAT_I8_UNORM;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index b8db6fb6c12..720d666d98c 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -78,10 +78,8 @@ static void r300_release_referenced_objects(struct r300_context *r300)
NULL);
}
- /* The dummy VBO. */
+ /* Manually-created vertex buffers. */
pipe_resource_reference(&r300->dummy_vb, NULL);
-
- /* The SWTCL VBO. */
pipe_resource_reference(&r300->vbo, NULL);
/* If there are any queries pending or not destroyed, remove them now. */
@@ -141,11 +139,11 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300);
}
-void r300_flush_cb(void *data)
+static void r300_flush_callback(void *data, unsigned flags)
{
struct r300_context* const cs_context_copy = data;
- cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL);
+ r300_flush(&cs_context_copy->context, flags, NULL);
}
#define R300_INIT_ATOM(atomname, atomsize) \
@@ -455,7 +453,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300_init_render_functions(r300);
r300_init_states(&r300->context);
- rws->cs_set_flush(r300->cs, r300_flush_cb, r300);
+ rws->cs_set_flush(r300->cs, r300_flush_callback, r300);
/* The KIL opcode needs the first texture unit to be enabled
* on r3xx-r4xx. In order to calm down the CS checker, we bind this
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 58e1094e339..e395f41290e 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -65,7 +65,10 @@ struct r300_aa_state {
};
struct r300_blend_state {
- uint32_t cb[8];
+ struct pipe_blend_state state;
+
+ uint32_t cb_clamp[8];
+ uint32_t cb_noclamp[8];
uint32_t cb_no_readwrite[8];
};
@@ -610,6 +613,8 @@ struct r300_context {
boolean vertex_arrays_dirty;
boolean vertex_arrays_indexed;
int vertex_arrays_offset;
+ int vertex_arrays_instance_id;
+ boolean instancing_enabled;
};
#define foreach_atom(r300, atom) \
@@ -663,8 +668,6 @@ static INLINE void r300_mark_atom_dirty(struct r300_context *r300,
struct pipe_context* r300_create_context(struct pipe_screen* screen,
void *priv);
-void r300_flush_cb(void *data);
-
/* Context initialization. */
struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_blit_functions(struct r300_context *r300);
@@ -679,6 +682,11 @@ void r300_decompress_zmask(struct r300_context *r300);
void r300_decompress_zmask_locked_unsafe(struct r300_context *r300);
void r300_decompress_zmask_locked(struct r300_context *r300);
+/* r300_flush.c */
+void r300_flush(struct pipe_context *pipe,
+ unsigned flags,
+ struct pipe_fence_handle **fence);
+
/* r300_hyperz.c */
void r300_update_hyperz_state(struct r300_context* r300);
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index e3945b72d7a..e17a907e77e 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -45,7 +45,10 @@ void r300_emit_blend_state(struct r300_context* r300,
CS_LOCALS(r300);
if (fb->nr_cbufs) {
- WRITE_CS_TABLE(blend->cb, size);
+ if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT)
+ WRITE_CS_TABLE(blend->cb_noclamp, size);
+ else
+ WRITE_CS_TABLE(blend->cb_clamp, size);
} else {
WRITE_CS_TABLE(blend->cb_no_readwrite, size);
}
@@ -794,7 +797,8 @@ void r300_emit_textures_state(struct r300_context *r300,
END_CS;
}
-void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed)
+void r300_emit_vertex_arrays(struct r300_context* r300, int offset,
+ boolean indexed, int instance_id)
{
struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer;
struct pipe_resource **valid_vbuf = r300->vbuf_mgr->real_vertex_buffer;
@@ -804,39 +808,92 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde
unsigned vertex_array_count = r300->velems->count;
unsigned packet_size = (vertex_array_count * 3 + 1) / 2;
struct pipe_vertex_buffer *vb1, *vb2;
- unsigned *hw_format_size;
- unsigned size1, size2;
+ unsigned *hw_format_size = r300->velems->format_size;
+ unsigned size1, size2, offset1, offset2, stride1, stride2;
CS_LOCALS(r300);
BEGIN_CS(2 + packet_size + vertex_array_count * 2);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
- hw_format_size = r300->velems->format_size;
+ if (instance_id == -1) {
+ /* Non-instanced arrays. This ignores instance_divisor and instance_id. */
+ for (i = 0; i < vertex_array_count - 1; i += 2) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+ size1 = hw_format_size[i];
+ size2 = hw_format_size[i+1];
+
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
+ R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+ OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
+ }
- for (i = 0; i < vertex_array_count - 1; i += 2) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- vb2 = &vbuf[velem[i+1].vertex_buffer_index];
- size1 = hw_format_size[i];
- size2 = hw_format_size[i+1];
+ if (vertex_array_count & 1) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ size1 = hw_format_size[i];
- OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |
- R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride));
- OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
- OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride);
- }
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
+ OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
+ }
- if (vertex_array_count & 1) {
- vb1 = &vbuf[velem[i].vertex_buffer_index];
- size1 = hw_format_size[i];
+ for (i = 0; i < vertex_array_count; i++) {
+ buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
+ OUT_CS_RELOC(buf);
+ }
+ } else {
+ /* Instanced arrays. */
+ for (i = 0; i < vertex_array_count - 1; i += 2) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ vb2 = &vbuf[velem[i+1].vertex_buffer_index];
+ size1 = hw_format_size[i];
+ size2 = hw_format_size[i+1];
+
+ if (velem[i].instance_divisor) {
+ stride1 = 0;
+ offset1 = vb1->buffer_offset + velem[i].src_offset +
+ (instance_id / velem[i].instance_divisor) * vb1->stride;
+ } else {
+ stride1 = vb1->stride;
+ offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride;
+ }
+ if (velem[i+1].instance_divisor) {
+ stride2 = 0;
+ offset2 = vb2->buffer_offset + velem[i+1].src_offset +
+ (instance_id / velem[i+1].instance_divisor) * vb2->stride;
+ } else {
+ stride2 = vb2->stride;
+ offset2 = vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride;
+ }
- OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));
- OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride);
- }
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1) |
+ R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(stride2));
+ OUT_CS(offset1);
+ OUT_CS(offset2);
+ }
+
+ if (vertex_array_count & 1) {
+ vb1 = &vbuf[velem[i].vertex_buffer_index];
+ size1 = hw_format_size[i];
+
+ if (velem[i].instance_divisor) {
+ stride1 = 0;
+ offset1 = vb1->buffer_offset + velem[i].src_offset +
+ (instance_id / velem[i].instance_divisor) * vb1->stride;
+ } else {
+ stride1 = vb1->stride;
+ offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride;
+ }
- for (i = 0; i < vertex_array_count; i++) {
- buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
- OUT_CS_RELOC(buf);
+ OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1));
+ OUT_CS(offset1);
+ }
+
+ for (i = 0; i < vertex_array_count; i++) {
+ buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
+ OUT_CS_RELOC(buf);
+ }
}
END_CS;
}
@@ -1164,7 +1221,7 @@ validate:
if (flushed)
return FALSE;
- r300->context.flush(&r300->context, 0, NULL);
+ r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL);
flushed = TRUE;
goto validate;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index acea51d942f..6c1c9d2fb13 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -31,7 +31,8 @@ struct r300_vertex_program_code;
uint32_t pack_float24(float f);
-void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed);
+void r300_emit_vertex_arrays(struct r300_context* r300, int offset,
+ boolean indexed, int instance_id);
void r300_emit_blend_state(struct r300_context* r300,
unsigned size, void* state);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 9c41a1383ce..b3d0d344ec4 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -31,9 +31,10 @@
#include "r300_cs.h"
#include "r300_emit.h"
-static void r300_flush(struct pipe_context* pipe,
- unsigned flags,
- struct pipe_fence_handle** fence)
+
+void r300_flush(struct pipe_context *pipe,
+ unsigned flags,
+ struct pipe_fence_handle **fence)
{
struct r300_context *r300 = r300_context(pipe);
struct r300_atom *atom;
@@ -61,7 +62,7 @@ static void r300_flush(struct pipe_context* pipe,
r500_emit_index_bias(r300, 0);
r300->flush_counter++;
- r300->rws->cs_flush(r300->cs);
+ r300->rws->cs_flush(r300->cs, flags);
r300->dirty_hw = 0;
/* New kitchen sink, baby. */
@@ -83,20 +84,22 @@ static void r300_flush(struct pipe_context* pipe,
* and we cannot emit an empty CS. We must write some regs then. */
CS_LOCALS(r300);
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0);
- r300->rws->cs_flush(r300->cs);
+ r300->rws->cs_flush(r300->cs, flags);
} else {
/* Even if hw is not dirty, we should at least reset the CS in case
* the space checking failed for the first draw operation. */
- r300->rws->cs_flush(r300->cs);
+ r300->rws->cs_flush(r300->cs, flags);
}
}
+}
- if (flags & PIPE_FLUSH_FRAME) {
- r300->rws->cs_sync_flush(r300->cs);
- }
+static void r300_flush_wrapped(struct pipe_context *pipe,
+ struct pipe_fence_handle **fence)
+{
+ r300_flush(pipe, 0, fence);
}
void r300_init_flush_functions(struct r300_context* r300)
{
- r300->context.flush = r300_flush;
+ r300->context.flush = r300_flush_wrapped;
}
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index cec7473009a..4c502fefb3f 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -149,6 +149,8 @@ static void get_external_state(
unsigned i;
unsigned char *swizzle;
+ state->frag_clamp = 0;
+
for (i = 0; i < texstate->sampler_state_count; i++) {
struct r300_sampler_state *s = texstate->sampler_states[i];
struct r300_sampler_view *v = texstate->sampler_views[i];
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 0ec4a225865..26594dabe42 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -177,7 +177,7 @@ static void r300_split_index_bias(struct r300_context *r300, int index_bias,
}
enum r300_prepare_flags {
- PREP_FIRST_DRAW = (1 << 0), /* call emit_dirty_state and friends? */
+ PREP_EMIT_STATES = (1 << 0), /* call emit_dirty_state and friends? */
PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */
PREP_EMIT_AOS = (1 << 2), /* call emit_vertex_arrays? */
PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
@@ -193,11 +193,11 @@ enum r300_prepare_flags {
* \return TRUE if the CS was flushed
*/
static boolean r300_reserve_cs_dwords(struct r300_context *r300,
- enum r300_prepare_flags flags,
- unsigned cs_dwords)
+ enum r300_prepare_flags flags,
+ unsigned cs_dwords)
{
boolean flushed = FALSE;
- boolean first_draw = flags & PREP_FIRST_DRAW;
+ boolean first_draw = flags & PREP_EMIT_STATES;
boolean emit_vertex_arrays = flags & PREP_EMIT_AOS;
boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
@@ -219,7 +219,7 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
/* Reserve requested CS space. */
if (cs_dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) {
- r300->context.flush(&r300->context, 0, NULL);
+ r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL);
flushed = TRUE;
}
@@ -233,15 +233,16 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
* \param index_buffer The index buffer to validate. The parameter may be NULL.
* \param buffer_offset The offset passed to emit_vertex_arrays.
* \param index_bias The index bias to emit.
+ * \param instance_id Index of instance to render
* \return TRUE if rendering should be skipped
*/
static boolean r300_emit_states(struct r300_context *r300,
enum r300_prepare_flags flags,
struct pipe_resource *index_buffer,
int buffer_offset,
- int index_bias)
+ int index_bias, int instance_id)
{
- boolean first_draw = flags & PREP_FIRST_DRAW;
+ boolean first_draw = flags & PREP_EMIT_STATES;
boolean emit_vertex_arrays = flags & PREP_EMIT_AOS;
boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
boolean indexed = flags & PREP_INDEXED;
@@ -267,12 +268,14 @@ static boolean r300_emit_states(struct r300_context *r300,
if (emit_vertex_arrays &&
(r300->vertex_arrays_dirty ||
r300->vertex_arrays_indexed != indexed ||
- r300->vertex_arrays_offset != buffer_offset)) {
- r300_emit_vertex_arrays(r300, buffer_offset, indexed);
+ r300->vertex_arrays_offset != buffer_offset ||
+ r300->vertex_arrays_instance_id != instance_id)) {
+ r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
r300->vertex_arrays_dirty = FALSE;
r300->vertex_arrays_indexed = indexed;
r300->vertex_arrays_offset = buffer_offset;
+ r300->vertex_arrays_instance_id = instance_id;
}
if (emit_vertex_arrays_swtcl)
@@ -291,6 +294,7 @@ static boolean r300_emit_states(struct r300_context *r300,
* \param cs_dwords The number of dwords to reserve in CS.
* \param buffer_offset The offset passed to emit_vertex_arrays.
* \param index_bias The index bias to emit.
+ * \param instance_id The instance to render.
* \return TRUE if rendering should be skipped
*/
static boolean r300_prepare_for_rendering(struct r300_context *r300,
@@ -298,13 +302,15 @@ static boolean r300_prepare_for_rendering(struct r300_context *r300,
struct pipe_resource *index_buffer,
unsigned cs_dwords,
int buffer_offset,
- int index_bias)
+ int index_bias,
+ int instance_id)
{
+ /* Make sure there is enough space in the command stream and emit states. */
if (r300_reserve_cs_dwords(r300, flags, cs_dwords))
- flags |= PREP_FIRST_DRAW;
+ flags |= PREP_EMIT_STATES;
return r300_emit_states(r300, flags, index_buffer, buffer_offset,
- index_bias);
+ index_bias, instance_id);
}
static boolean immd_is_good_idea(struct r300_context *r300,
@@ -352,8 +358,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
****************************************************************************/
static void r300_draw_arrays_immediate(struct r300_context *r300,
- unsigned mode, unsigned start,
- unsigned count)
+ const struct pipe_draw_info *info)
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
@@ -364,7 +369,7 @@ static void r300_draw_arrays_immediate(struct r300_context *r300,
unsigned vertex_size = r300->velems->vertex_size_dwords;
/* The number of dwords for this draw operation. */
- unsigned dwords = 4 + count * vertex_size;
+ unsigned dwords = 4 + info->count * vertex_size;
/* Size of the vertex element, in dwords. */
unsigned size[PIPE_MAX_ATTRIBS];
@@ -379,7 +384,7 @@ static void r300_draw_arrays_immediate(struct r300_context *r300,
CS_LOCALS(r300);
- if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0))
+ if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
return;
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
@@ -395,21 +400,21 @@ static void r300_draw_arrays_immediate(struct r300_context *r300,
map[vbi] = (uint32_t*)r300->rws->buffer_map(
r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf,
r300->cs, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED);
- map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start;
+ map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * info->start;
}
mapelem[i] = map[vbi] + (velem->src_offset / 4);
}
- r300_emit_draw_init(r300, mode, 0, count-1);
+ r300_emit_draw_init(r300, info->mode, 0, info->count-1);
BEGIN_CS(dwords);
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
- 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));
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) |
+ r300_translate_primitive(info->mode));
/* Emit vertices. */
- for (v = 0; v < count; v++) {
+ for (v = 0; v < info->count; v++) {
for (i = 0; i < vertex_element_count; i++) {
OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
}
@@ -456,8 +461,8 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
static void r300_emit_draw_elements(struct r300_context *r300,
struct pipe_resource* indexBuffer,
unsigned indexSize,
- unsigned minIndex,
- unsigned maxIndex,
+ unsigned min_index,
+ unsigned max_index,
unsigned mode,
unsigned start,
unsigned count,
@@ -467,16 +472,16 @@ static void r300_emit_draw_elements(struct r300_context *r300,
boolean alt_num_verts = count > 65535;
CS_LOCALS(r300);
- if (count >= (1 << 24) || maxIndex >= (1 << 24)) {
+ if (count >= (1 << 24) || max_index >= (1 << 24)) {
fprintf(stderr, "r300: Got a huge number of vertices: %i, "
- "refusing to render (maxIndex: %i).\n", count, maxIndex);
+ "refusing to render (max_index: %i).\n", count, max_index);
return;
}
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
- count, minIndex, maxIndex);
+ count, min_index, max_index);
- r300_emit_draw_init(r300, mode, minIndex, maxIndex);
+ r300_emit_draw_init(r300, mode, min_index, max_index);
/* If start is odd, render the first triangle with indices embedded
* in the command stream. This will increase start by 3 and make it
@@ -527,24 +532,23 @@ static void r300_emit_draw_elements(struct r300_context *r300,
}
static void r300_draw_elements_immediate(struct r300_context *r300,
- int indexBias, unsigned minIndex,
- unsigned maxIndex, unsigned mode,
- unsigned start, unsigned count)
+ const struct pipe_draw_info *info)
{
uint8_t *ptr1;
uint16_t *ptr2;
uint32_t *ptr4;
unsigned index_size = r300->index_buffer.index_size;
- unsigned i, count_dwords = index_size == 4 ? count : (count + 1) / 2;
+ unsigned i, count_dwords = index_size == 4 ? info->count :
+ (info->count + 1) / 2;
CS_LOCALS(r300);
/* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
- PREP_INDEXED, NULL, 2+count_dwords, 0, indexBias))
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+ PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
return;
- r300_emit_draw_init(r300, mode, minIndex, maxIndex);
+ r300_emit_draw_init(r300, info->mode, info->min_index, info->max_index);
BEGIN_CS(2 + count_dwords);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords);
@@ -552,42 +556,42 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
switch (index_size) {
case 1:
ptr1 = r300_resource(r300->index_buffer.buffer)->b.user_ptr;
- ptr1 += start;
+ ptr1 += info->start;
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
- r300_translate_primitive(mode));
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
+ r300_translate_primitive(info->mode));
- if (indexBias && !r300->screen->caps.is_r500) {
- for (i = 0; i < count-1; i += 2)
- OUT_CS(((ptr1[i+1] + indexBias) << 16) |
- (ptr1[i] + indexBias));
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count-1; i += 2)
+ OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
+ (ptr1[i] + info->index_bias));
- if (count & 1)
- OUT_CS(ptr1[i] + indexBias);
+ if (info->count & 1)
+ OUT_CS(ptr1[i] + info->index_bias);
} else {
- for (i = 0; i < count-1; i += 2)
+ for (i = 0; i < info->count-1; i += 2)
OUT_CS(((ptr1[i+1]) << 16) |
(ptr1[i] ));
- if (count & 1)
+ if (info->count & 1)
OUT_CS(ptr1[i]);
}
break;
case 2:
ptr2 = (uint16_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
- ptr2 += start;
+ ptr2 += info->start;
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
- r300_translate_primitive(mode));
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
+ r300_translate_primitive(info->mode));
- if (indexBias && !r300->screen->caps.is_r500) {
- for (i = 0; i < count-1; i += 2)
- OUT_CS(((ptr2[i+1] + indexBias) << 16) |
- (ptr2[i] + indexBias));
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count-1; i += 2)
+ OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
+ (ptr2[i] + info->index_bias));
- if (count & 1)
- OUT_CS(ptr2[i] + indexBias);
+ if (info->count & 1)
+ OUT_CS(ptr2[i] + info->index_bias);
} else {
OUT_CS_TABLE(ptr2, count_dwords);
}
@@ -595,15 +599,15 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
case 4:
ptr4 = (uint32_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr;
- ptr4 += start;
+ ptr4 += info->start;
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) |
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
- r300_translate_primitive(mode));
+ r300_translate_primitive(info->mode));
- if (indexBias && !r300->screen->caps.is_r500) {
- for (i = 0; i < count; i++)
- OUT_CS(ptr4[i] + indexBias);
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ for (i = 0; i < info->count; i++)
+ OUT_CS(ptr4[i] + info->index_bias);
} else {
OUT_CS_TABLE(ptr4, count_dwords);
}
@@ -612,21 +616,23 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
END_CS;
}
-static void r300_draw_elements(struct r300_context *r300, int indexBias,
- unsigned minIndex, unsigned maxIndex,
- unsigned mode, unsigned start, unsigned count)
+static void r300_draw_elements(struct r300_context *r300,
+ const struct pipe_draw_info *info,
+ int instance_id)
{
struct pipe_resource *indexBuffer = r300->index_buffer.buffer;
unsigned indexSize = r300->index_buffer.index_size;
struct pipe_resource* orgIndexBuffer = indexBuffer;
+ unsigned start = info->start;
+ unsigned count = info->count;
boolean alt_num_verts = r300->screen->caps.is_r500 &&
count > 65536;
unsigned short_count;
int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
uint16_t indices3[3];
- if (indexBias && !r300->screen->caps.is_r500) {
- r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
+ if (info->index_bias && !r300->screen->caps.is_r500) {
+ r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset);
}
r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset,
@@ -641,7 +647,7 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias,
PIPE_TRANSFER_READ |
PIPE_TRANSFER_UNSYNCHRONIZED);
- if (mode == PIPE_PRIM_TRIANGLES) {
+ if (info->mode == PIPE_PRIM_TRIANGLES) {
memcpy(indices3, ptr + start, 6);
} else {
/* Copy the mapped index buffer directly to the upload buffer.
@@ -660,13 +666,15 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias,
/* 19 dwords for emit_draw_elements. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
- PREP_INDEXED, indexBuffer, 19, buffer_offset, indexBias))
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+ PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
+ instance_id))
goto done;
if (alt_num_verts || count <= 65535) {
- r300_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count, indices3);
+ r300_emit_draw_elements(r300, indexBuffer, indexSize, info->min_index,
+ info->max_index, info->mode, start, count,
+ indices3);
} else {
do {
if (indexSize == 2 && (start & 1))
@@ -675,8 +683,8 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias,
short_count = MIN2(count, 65534);
r300_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex,
- mode, start, short_count, indices3);
+ info->min_index, info->max_index,
+ info->mode, start, short_count, indices3);
start += short_count;
count -= short_count;
@@ -685,7 +693,8 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias,
if (count) {
if (!r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
- indexBuffer, 19, buffer_offset, indexBias))
+ indexBuffer, 19, buffer_offset, info->index_bias,
+ instance_id))
goto done;
}
} while (count);
@@ -697,25 +706,28 @@ done:
}
}
-static void r300_draw_arrays(struct r300_context *r300, unsigned mode,
- unsigned start, unsigned count)
+static void r300_draw_arrays(struct r300_context *r300,
+ const struct pipe_draw_info *info,
+ int instance_id)
{
boolean alt_num_verts = r300->screen->caps.is_r500 &&
- count > 65536;
+ info->count > 65536;
+ unsigned start = info->start;
+ unsigned count = info->count;
unsigned short_count;
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
- NULL, 9, start, 0))
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
+ NULL, 9, start, 0, instance_id))
return;
if (alt_num_verts || count <= 65535) {
- r300_emit_draw_arrays(r300, mode, count);
+ r300_emit_draw_arrays(r300, info->mode, count);
} else {
do {
short_count = MIN2(count, 65535);
- r300_emit_draw_arrays(r300, mode, short_count);
+ r300_emit_draw_arrays(r300, info->mode, short_count);
start += short_count;
count -= short_count;
@@ -724,53 +736,78 @@ static void r300_draw_arrays(struct r300_context *r300, unsigned mode,
if (count) {
if (!r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
- start, 0))
+ start, 0, instance_id))
return;
}
} while (count);
}
}
+static void r300_draw_arrays_instanced(struct r300_context *r300,
+ const struct pipe_draw_info *info)
+{
+ int i;
+
+ for (i = 0; i < info->instance_count; i++)
+ r300_draw_arrays(r300, info, i);
+}
+
+static void r300_draw_elements_instanced(struct r300_context *r300,
+ const struct pipe_draw_info *info)
+{
+ int i;
+
+ for (i = 0; i < info->instance_count; i++)
+ r300_draw_elements(r300, info, i);
+}
+
static void r300_draw_vbo(struct pipe_context* pipe,
- const struct pipe_draw_info *info)
+ const struct pipe_draw_info *dinfo)
{
struct r300_context* r300 = r300_context(pipe);
- unsigned count = info->count;
+ struct pipe_draw_info info = *dinfo;
boolean buffers_updated, uploader_flushed;
- boolean indexed = info->indexed && r300->index_buffer.buffer;
- unsigned start_indexed = info->start + r300->index_buffer.offset;
- int max_index = MIN2(r300->vbuf_mgr->max_index, info->max_index);
+
+ info.indexed = info.indexed && r300->index_buffer.buffer;
if (r300->skip_rendering ||
- !u_trim_pipe_prim(info->mode, &count)) {
+ !u_trim_pipe_prim(info.mode, &info.count)) {
return;
}
r300_update_derived_state(r300);
/* Start the vbuf manager and update buffers if needed. */
- u_vbuf_mgr_draw_begin(r300->vbuf_mgr, info,
+ u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info,
&buffers_updated, &uploader_flushed);
if (buffers_updated) {
r300->vertex_arrays_dirty = TRUE;
}
/* Draw. */
- if (indexed) {
- if (count <= 8 &&
- r300_resource(r300->index_buffer.buffer)->b.user_ptr) {
- r300_draw_elements_immediate(r300, info->index_bias,
- info->min_index, max_index,
- info->mode, start_indexed, count);
+ if (info.indexed) {
+ info.start += r300->index_buffer.offset;
+ info.max_index = MIN2(r300->vbuf_mgr->max_index, info.max_index);
+
+ if (info.instance_count <= 1) {
+ if (info.count <= 8 &&
+ r300_resource(r300->index_buffer.buffer)->b.user_ptr) {
+ r300_draw_elements_immediate(r300, &info);
+ } else {
+ r300_draw_elements(r300, &info, -1);
+ }
} else {
- r300_draw_elements(r300, info->index_bias, info->min_index,
- max_index, info->mode, start_indexed, count);
+ r300_draw_elements_instanced(r300, &info);
}
} else {
- if (immd_is_good_idea(r300, count)) {
- r300_draw_arrays_immediate(r300, info->mode, info->start, count);
+ if (info.instance_count <= 1) {
+ if (immd_is_good_idea(r300, info.count)) {
+ r300_draw_arrays_immediate(r300, &info);
+ } else {
+ r300_draw_arrays(r300, &info, -1);
+ }
} else {
- r300_draw_arrays(r300, info->mode, info->start, count);
+ r300_draw_arrays_instanced(r300, &info);
}
}
@@ -805,7 +842,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
r300_update_derived_state(r300);
r300_reserve_cs_dwords(r300,
- PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL |
+ PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL |
(indexed ? PREP_INDEXED : 0),
indexed ? 256 : 6);
@@ -987,13 +1024,13 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
if (r300->draw_first_emitted) {
if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
- NULL, dwords, 0, 0))
+ PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+ NULL, dwords, 0, 0, -1))
return;
} else {
if (!r300_emit_states(r300,
- PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
- NULL, 0, 0))
+ PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+ NULL, 0, 0, -1))
return;
}
@@ -1027,13 +1064,13 @@ static void r300_render_draw_elements(struct vbuf_render* render,
if (r300->draw_first_emitted) {
if (!r300_prepare_for_rendering(r300,
- PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
- NULL, 256, 0, 0))
+ PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ NULL, 256, 0, 0, -1))
return;
} else {
if (!r300_emit_states(r300,
- PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
- NULL, 0, 0))
+ PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ NULL, 0, 0, -1))
return;
}
@@ -1070,7 +1107,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
if (count) {
if (!r300_prepare_for_rendering(r300,
PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
- NULL, 256, 0, 0))
+ NULL, 256, 0, 0, -1))
return;
end_cs_dwords = r300_get_num_cs_end_dwords(r300);
@@ -1174,7 +1211,7 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
r300->clip_state.dirty = FALSE;
r300->viewport_state.dirty = FALSE;
- if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0))
+ if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
goto done;
DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c
index f3d8c5b889f..6593474b1f0 100644
--- a/src/gallium/drivers/r300/r300_resource.c
+++ b/src/gallium/drivers/r300/r300_resource.c
@@ -38,13 +38,6 @@ r300_resource_create(struct pipe_screen *screen,
}
-static unsigned r300_resource_is_referenced_by_cs(struct pipe_context *context,
- struct pipe_resource *buf,
- unsigned level, int layer)
-{
- return r300_buffer_is_referenced(context, buf);
-}
-
void r300_init_resource_functions(struct r300_context *r300)
{
r300->context.get_transfer = u_get_transfer_vtbl;
@@ -53,7 +46,6 @@ void r300_init_resource_functions(struct r300_context *r300)
r300->context.transfer_unmap = u_transfer_unmap_vtbl;
r300->context.transfer_destroy = u_transfer_destroy_vtbl;
r300->context.transfer_inline_write = u_transfer_inline_write_vtbl;
- r300->context.is_resource_referenced = r300_resource_is_referenced_by_cs;
r300->context.create_surface = r300_create_surface;
r300->context.surface_destroy = r300_surface_destroy;
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 52d0247fbfd..8a69628c53e 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -24,6 +24,7 @@
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
#include "util/u_memory.h"
+#include "os/os_time.h"
#include "r300_context.h"
#include "r300_texture.h"
@@ -112,6 +113,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
case PIPE_CAP_TEXTURE_SWIZZLE:
return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1;
@@ -124,12 +126,15 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_DEPTH_CLAMP:
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
- case PIPE_CAP_STREAM_OUTPUT:
- case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_INSTANCED_DRAWING:
case PIPE_CAP_ARRAY_TEXTURES:
return 0;
+ /* SWTCL-only features. */
+ case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_PRIMITIVE_RESTART:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ return !r300screen->caps.has_tcl;
+
/* Texturing. */
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
@@ -301,8 +306,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned usage,
- unsigned geom_flags)
+ unsigned usage)
{
struct r300_winsys_screen *rws = r300_screen(screen)->rws;
uint32_t retval = 0;
@@ -314,9 +318,13 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
format == PIPE_FORMAT_B10G10R10A2_UNORM ||
format == PIPE_FORMAT_R10SG10SB10SA2U_NORM;
boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM ||
- format == PIPE_FORMAT_RGTC1_SNORM;
+ format == PIPE_FORMAT_RGTC1_SNORM ||
+ format == PIPE_FORMAT_LATC1_UNORM ||
+ format == PIPE_FORMAT_LATC1_SNORM;
boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
- format == PIPE_FORMAT_RGTC2_SNORM;
+ format == PIPE_FORMAT_RGTC2_SNORM ||
+ format == PIPE_FORMAT_LATC2_UNORM ||
+ format == PIPE_FORMAT_LATC2_SNORM;
boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
format == PIPE_FORMAT_R16G16_FLOAT ||
format == PIPE_FORMAT_R16G16B16_FLOAT ||
@@ -414,25 +422,40 @@ static void r300_fence_reference(struct pipe_screen *screen,
(struct r300_winsys_bo*)fence);
}
-static int r300_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+static boolean r300_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence)
{
struct r300_winsys_screen *rws = r300_screen(screen)->rws;
struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence;
- return !rws->buffer_is_busy(rfence) ? 0 : 1; /* 0 == success */
+ return !rws->buffer_is_busy(rfence);
}
-static int r300_fence_finish(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+static boolean r300_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ uint64_t timeout)
{
struct r300_winsys_screen *rws = r300_screen(screen)->rws;
struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence;
+ if (timeout != PIPE_TIMEOUT_INFINITE) {
+ int64_t start_time = os_time_get();
+
+ /* Convert to microseconds. */
+ timeout /= 1000;
+
+ /* Wait in a loop. */
+ while (rws->buffer_is_busy(rfence)) {
+ if (os_time_get() - start_time >= timeout) {
+ return FALSE;
+ }
+ os_time_sleep(10);
+ }
+ return TRUE;
+ }
+
rws->buffer_wait(rfence);
- return 0; /* 0 == success */
+ return TRUE;
}
struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 1045911f3ae..986ae384fbf 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -33,21 +33,6 @@
#include "r300_screen_buffer.h"
#include "r300_winsys.h"
-unsigned r300_buffer_is_referenced(struct pipe_context *context,
- struct pipe_resource *buf)
-{
- struct r300_context *r300 = r300_context(context);
- struct r300_resource *rbuf = r300_resource(buf);
-
- if (rbuf->b.user_ptr || rbuf->constant_buffer)
- return PIPE_UNREFERENCED;
-
- if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf))
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-
- return PIPE_UNREFERENCED;
-}
-
void r300_upload_index_buffer(struct r300_context *r300,
struct pipe_resource **index_buffer,
unsigned index_size, unsigned *start,
@@ -181,7 +166,6 @@ static const struct u_resource_vtbl r300_buffer_vtbl =
{
NULL, /* get_handle */
r300_buffer_destroy, /* resource_destroy */
- NULL, /* is_buffer_referenced */
r300_buffer_get_transfer, /* get_transfer */
r300_buffer_transfer_destroy, /* transfer_destroy */
r300_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index 14bee460d5b..cdbc4425fcb 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -49,9 +49,6 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
void *ptr, unsigned size,
unsigned bind);
-unsigned r300_buffer_is_referenced(struct pipe_context *context,
- struct pipe_resource *buf);
-
/* Inline functions. */
static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 2b0c8750554..ecb4fc691cc 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -188,13 +188,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */
+ uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */
uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */
+ uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */
uint32_t color_channel_mask = 0; /* R300_RB3D_COLOR_CHANNEL_MASK: 0x4e0c */
uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */
uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */
- boolean clamp = TRUE;
CB_LOCALS;
+ blend->state = *state;
+
if (state->rt[0].blend_enable)
{
unsigned eqRGB = state->rt[0].rgb_func;
@@ -207,10 +210,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
/* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,
* this is just the crappy D3D naming */
- blend_control = R300_ALPHA_BLEND_ENABLE |
- r300_translate_blend_function(eqRGB, clamp) |
+ blend_control = blend_control_noclamp =
+ R300_ALPHA_BLEND_ENABLE |
( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) |
( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT);
+ blend_control |=
+ r300_translate_blend_function(eqRGB, TRUE);
+ blend_control_noclamp |=
+ r300_translate_blend_function(eqRGB, FALSE);
/* Optimization: some operations do not require the destination color.
*
@@ -232,6 +239,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) {
/* Enable reading from the colorbuffer. */
blend_control |= R300_READ_ENABLE;
+ blend_control_noclamp |= R300_READ_ENABLE;
if (r300screen->caps.is_r500) {
/* Optimization: Depending on incoming pixels, we can
@@ -269,8 +277,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
*
* Equations other than ADD are rarely used and therefore won't be
* optimized. */
- if (clamp &&
- (eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) &&
+ if ((eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) &&
(eqA == PIPE_BLEND_ADD || eqA == PIPE_BLEND_REVERSE_SUBTRACT)) {
/* ADD: X+Y
* REVERSE_SUBTRACT: Y-X
@@ -308,10 +315,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
/* separate alpha */
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
blend_control |= R300_SEPARATE_ALPHA_ENABLE;
- alpha_blend_control =
- r300_translate_blend_function(eqA, clamp) |
+ blend_control_noclamp |= R300_SEPARATE_ALPHA_ENABLE;
+ alpha_blend_control = alpha_blend_control_noclamp =
(r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) |
(r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT);
+ alpha_blend_control |=
+ r300_translate_blend_function(eqA, TRUE);
+ alpha_blend_control_noclamp |=
+ r300_translate_blend_function(eqA, FALSE);
}
}
@@ -348,7 +359,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
*/
/* Build a command buffer. */
- BEGIN_CB(blend->cb, 8);
+ BEGIN_CB(blend->cb_clamp, 8);
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
OUT_CB(blend_control);
@@ -357,6 +368,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
END_CB;
+ /* Build a command buffer. */
+ BEGIN_CB(blend->cb_noclamp, 8);
+ OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
+ OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3);
+ OUT_CB(blend_control_noclamp);
+ OUT_CB(alpha_blend_control_noclamp);
+ OUT_CB(color_channel_mask);
+ OUT_CB_REG(R300_RB3D_DITHER_CTL, dither);
+ END_CB;
+
/* The same as above, but with no colorbuffer reads and writes. */
BEGIN_CB(blend->cb_no_readwrite, 8);
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
@@ -377,6 +398,10 @@ static void r300_bind_blend_state(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
UPDATE_STATE(state, r300->blend_state);
+
+ if (r300->fs.state && r300_pick_fragment_shader(r300)) {
+ r300_mark_fs_code_dirty(r300);
+ }
}
/* Free blend state. */
@@ -836,10 +861,9 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
}
}
- /* If nr_cbufs is changed from zero to non-zero or vice versa... */
- if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
- r300_mark_atom_dirty(r300, &r300->blend_state);
- }
+ /* Need to reset clamping or colormask. */
+ r300_mark_atom_dirty(r300, &r300->blend_state);
+
/* If zsbuf is set from NULL to non-NULL or vice versa.. */
if (!!old_state->zsbuf != !!state->zsbuf) {
r300_mark_atom_dirty(r300, &r300->dsa_state);
@@ -1593,12 +1617,6 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
enum pipe_format format;
unsigned i;
- if (velems->count > 16) {
- fprintf(stderr, "r300: More than 16 vertex elements are not supported,"
- " requested %i, using 16.\n", velems->count);
- 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. */
@@ -1649,9 +1667,12 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
attribs = &dummy_attrib;
count = 1;
+ } else if (count > 16) {
+ fprintf(stderr, "r300: More than 16 vertex elements are not supported,"
+ " requested %i, using 16.\n", count);
+ count = 16;
}
- assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
if (!velems)
return NULL;
@@ -1849,6 +1870,14 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
}
}
+static void r300_texture_barrier(struct pipe_context *pipe)
+{
+ struct r300_context *r300 = r300_context(pipe);
+
+ r300_mark_atom_dirty(r300, &r300->gpu_flush);
+ r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
+}
+
void r300_init_state_functions(struct r300_context* r300)
{
r300->context.create_blend_state = r300_create_blend_state;
@@ -1904,4 +1933,6 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state;
r300->context.delete_vs_state = r300_delete_vs_state;
+
+ r300->context.texture_barrier = r300_texture_barrier;
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index a1e116f4b61..ec00e2552ca 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -644,16 +644,20 @@ static uint32_t r300_get_border_color(enum pipe_format format,
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_RGTC1_UNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
+ case PIPE_FORMAT_LATC1_UNORM:
/* Add 1/32 to round the border color instead of truncating. */
/* The Y component is used for the border color. */
border_swizzled[1] = border_swizzled[2] + 1.0f/32;
util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
return uc.ui;
case PIPE_FORMAT_RGTC2_SNORM:
+ case PIPE_FORMAT_LATC2_SNORM:
border_swizzled[0] = border_swizzled[2];
util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc);
return uc.ui;
case PIPE_FORMAT_RGTC2_UNORM:
+ case PIPE_FORMAT_LATC2_UNORM:
util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
return uc.ui;
default:
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 86ad0b8b8e0..c650fb7ed37 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -174,9 +174,11 @@ uint32_t r300_translate_texformat(enum pipe_format format,
if (util_format_is_compressed(format) &&
dxtc_swizzle &&
format != PIPE_FORMAT_RGTC2_UNORM &&
- format != PIPE_FORMAT_RGTC2_SNORM) {
+ format != PIPE_FORMAT_RGTC2_SNORM &&
+ format != PIPE_FORMAT_LATC2_UNORM &&
+ format != PIPE_FORMAT_LATC2_SNORM) {
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
- dxtc_swizzle);
+ TRUE);
} else {
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
FALSE);
@@ -209,13 +211,19 @@ uint32_t r300_translate_texformat(enum pipe_format format,
if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
result |= sign_bit[1];
+ case PIPE_FORMAT_LATC1_UNORM:
case PIPE_FORMAT_RGTC1_UNORM:
return R500_TX_FORMAT_ATI1N | result;
+
case PIPE_FORMAT_RGTC2_SNORM:
+ case PIPE_FORMAT_LATC2_SNORM:
result |= sign_bit[2] | sign_bit[3];
case PIPE_FORMAT_RGTC2_UNORM:
+ case PIPE_FORMAT_LATC2_UNORM:
return R400_TX_FORMAT_ATI2N | result;
+
default:
return ~0; /* Unsupported/unknown. */
}
@@ -363,6 +371,8 @@ uint32_t r500_tx_format_msb_bit(enum pipe_format format)
switch (format) {
case PIPE_FORMAT_RGTC1_UNORM:
case PIPE_FORMAT_RGTC1_SNORM:
+ case PIPE_FORMAT_LATC1_UNORM:
+ case PIPE_FORMAT_LATC1_SNORM:
case PIPE_FORMAT_X8Z24_UNORM:
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
return R500_TXFORMAT_MSB;
@@ -742,7 +752,6 @@ static const struct u_resource_vtbl r300_texture_vtbl =
{
NULL, /* get_handle */
r300_texture_destroy, /* resource_destroy */
- NULL, /* is_resource_referenced */
r300_texture_get_transfer, /* get_transfer */
r300_texture_transfer_destroy, /* transfer_destroy */
r300_texture_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c
index 3846fb8b6b3..2910666dd51 100644
--- a/src/gallium/drivers/r300/r300_texture_desc.c
+++ b/src/gallium/drivers/r300/r300_texture_desc.c
@@ -315,7 +315,7 @@ static unsigned r300_pixels_to_dwords(unsigned stride,
unsigned height,
unsigned xblock, unsigned yblock)
{
- return (align(stride, xblock) * align(height, yblock)) / (xblock * yblock);
+ return (util_align_npot(stride, xblock) * align(height, yblock)) / (xblock * yblock);
}
static void r300_setup_hyperz_properties(struct r300_screen *screen,
@@ -390,7 +390,7 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen,
tex->tex.zcomp8x8[i] = zcompsize == 8;
tex->tex.zmask_stride_in_pixels[i] =
- align(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
+ util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
} else {
tex->tex.zmask_dwords[i] = 0;
tex->tex.zcomp8x8[i] = FALSE;
@@ -398,7 +398,7 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen,
}
/* Now setup HIZ. */
- stride = align(stride, hiz_align_x[pipes-1]);
+ stride = util_align_npot(stride, hiz_align_x[pipes-1]);
height = align(height, hiz_align_y[pipes-1]);
/* Get the HIZ buffer size in dwords. */
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index 30de9ec1e32..65c5095be6a 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -72,7 +72,8 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
transfer->box.x, transfer->box.y, transfer->box.z,
&r300transfer->linear_texture->b.b.b, 0, &src_box);
- ctx->flush(ctx, 0, NULL);
+ /* XXX remove this. */
+ r300_flush(ctx, 0, NULL);
}
struct pipe_transfer*
@@ -100,7 +101,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
}
blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ||
- desc->layout == UTIL_FORMAT_LAYOUT_S3TC;
+ desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
+ desc->layout == UTIL_FORMAT_LAYOUT_RGTC;
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
@@ -151,7 +153,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
if (!trans->linear_texture) {
/* Oh crap, the thing can't create the texture.
* Let's flush and try again. */
- ctx->flush(ctx, 0, NULL);
+ r300_flush(ctx, 0, NULL);
trans->linear_texture = r300_resource(
ctx->screen->resource_create(ctx->screen,
@@ -175,13 +177,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
assert(!trans->linear_texture->tex.microtile &&
!trans->linear_texture->tex.macrotile[0]);
- /* Set the stride.
- *
- * Even though we are using an internal texture for this,
- * the transfer level, box and usage parameters still reflect
- * the arguments received to get_transfer. We just do the
- * right thing internally.
- */
+ /* Set the stride. */
trans->transfer.stride =
trans->linear_texture->tex.stride_in_bytes[0];
@@ -191,7 +187,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
r300_copy_from_tiled_texture(ctx, trans);
/* Always referenced in the blit. */
- ctx->flush(ctx, 0, NULL);
+ r300_flush(ctx, 0, NULL);
}
return &trans->transfer;
}
@@ -201,8 +197,9 @@ r300_texture_get_transfer(struct pipe_context *ctx,
trans->transfer.stride = tex->tex.stride_in_bytes[level];
trans->offset = r300_texture_get_offset(tex, level, box->z);
- if (referenced_cs)
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ if (referenced_cs &&
+ !(usage & PIPE_TRANSFER_UNSYNCHRONIZED))
+ r300_flush(ctx, 0, NULL);
return &trans->transfer;
}
return NULL;
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index c0b66899f8b..3a6798a5423 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -35,6 +35,7 @@
#include "pipe/p_state.h"
#define R300_MAX_CMDBUF_DWORDS (16 * 1024)
+#define R300_FLUSH_ASYNC (1 << 0)
struct winsys_handle;
struct r300_winsys_screen;
@@ -265,15 +266,9 @@ struct r300_winsys_screen {
* Flush a command stream.
*
* \param cs A command stream to flush.
+ * \param flags, R300_FLUSH_ASYNC or 0.
*/
- void (*cs_flush)(struct r300_winsys_cs *cs);
-
- /**
- * Wait until the last flush is completed.
- *
- * \param cs A command stream.
- */
- void (*cs_sync_flush)(struct r300_winsys_cs *cs);
+ void (*cs_flush)(struct r300_winsys_cs *cs, unsigned flags);
/**
* Set a flush callback which is called from winsys when flush is
@@ -284,7 +279,7 @@ struct r300_winsys_screen {
* \param user A user pointer that will be passed to the flush callback.
*/
void (*cs_set_flush)(struct r300_winsys_cs *cs,
- void (*flush)(void *),
+ void (*flush)(void *ctx, unsigned flags),
void *user);
/**
diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c
index 8cb417f9731..20a319a255d 100644
--- a/src/gallium/drivers/r600/eg_asm.c
+++ b/src/gallium/drivers/r600/eg_asm.c
@@ -97,15 +97,3 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
}
return 0;
}
-
-void eg_cf_vtx(struct r600_vertex_element *ve)
-{
- struct r600_pipe_state *rstate = &ve->rstate;
- rstate->id = R600_PIPE_STATE_FETCH_SHADER;
- rstate->nregs = 0;
- r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS,
- 0x00000000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS,
- (r600_bo_offset(ve->fetch_shader)) >> 8,
- 0xFFFFFFFF, ve->fetch_shader);
-}
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 4206b4a201d..77432661b64 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -150,10 +150,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
rstate->id = R600_PIPE_STATE_DSA;
/* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */
- /* db_shader_control is 0xFFFFFFBE as Z_EXPORT_ENABLE (bit 0) will be
- * set by fragment shader if it export Z and KILL_ENABLE (bit 6) will
- * be set if shader use texkill instruction
- */
db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
stencil_ref_mask = 0;
stencil_ref_mask_bf = 0;
@@ -210,7 +206,10 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBE, NULL);
+ /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE,
+ * STENCIL_EXPORT_ENABLE and KILL_ENABLE are controlled by
+ * evergreen_pipe_shader_ps().*/
+ r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBC, NULL);
r600_pipe_state_add_reg(rstate, R_028000_DB_RENDER_CONTROL, db_render_control, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_02800C_DB_RENDER_OVERRIDE, db_render_override, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0, 0xFFFFFFFF, NULL);
@@ -1329,7 +1328,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
{
struct r600_pipe_state *rstate = &shader->rstate;
struct r600_shader *rshader = &shader->shader;
- unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
+ unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control;
int pos_index = -1, face_index = -1;
int ninterp = 0;
boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
@@ -1337,6 +1336,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
rstate->nregs = 0;
+ db_shader_control = 0;
for (i = 0; i < rshader->ninput; i++) {
/* evergreen NUM_INTERP only contains values interpolated into the LDS,
POSITION goes via GPRs from the SC so isn't counted */
@@ -1358,16 +1358,12 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
}
for (i = 0; i < rshader->noutput; i++) {
if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_Z_EXPORT_ENABLE(1),
- S_02880C_Z_EXPORT_ENABLE(1), NULL);
+ db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_STENCIL_EXPORT_ENABLE(1),
- S_02880C_STENCIL_EXPORT_ENABLE(1), NULL);
+ db_shader_control |= S_02880C_STENCIL_EXPORT_ENABLE(1);
}
+ if (rshader->uses_kill)
+ db_shader_control |= S_02880C_KILL_ENABLE(1);
exports_ps = 0;
num_cout = 0;
@@ -1442,15 +1438,15 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
r600_pipe_state_add_reg(rstate,
R_02884C_SQ_PGM_EXPORTS_PS,
exports_ps, 0xFFFFFFFF, NULL);
-
- if (rshader->uses_kill) {
- /* only set some bits here, the other bits are set in the dsa state */
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_KILL_ENABLE(1),
- S_02880C_KILL_ENABLE(1), NULL);
- }
-
+ /* FIXME: Evergreen doesn't seem to support MULTIWRITE_ENABLE. */
+ /* only set some bits here, the other bits are set in the dsa state */
+ r600_pipe_state_add_reg(rstate,
+ R_02880C_DB_SHADER_CONTROL,
+ db_shader_control,
+ S_02880C_Z_EXPORT_ENABLE(1) |
+ S_02880C_STENCIL_EXPORT_ENABLE(1) |
+ S_02880C_KILL_ENABLE(1),
+ NULL);
r600_pipe_state_add_reg(rstate,
R_03A200_SQ_LOOP_CONST_0, 0x01000FFF,
0xFFFFFFFF, NULL);
@@ -1501,6 +1497,18 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
0xFFFFFFFF, NULL);
}
+void evergreen_fetch_shader(struct r600_vertex_element *ve)
+{
+ struct r600_pipe_state *rstate = &ve->rstate;
+ rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+ rstate->nregs = 0;
+ r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS,
+ 0x00000000, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS,
+ (r600_bo_offset(ve->fetch_shader)) >> 8,
+ 0xFFFFFFFF, ve->fetch_shader);
+}
+
void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx)
{
struct pipe_depth_stencil_alpha_state dsa;
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 996d9f74a60..45e614977e2 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -483,7 +483,9 @@ static int is_alu_mova_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
static int is_alu_vec_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
{
return is_alu_reduction_inst(bc, alu) ||
- is_alu_mova_inst(bc, alu);
+ is_alu_mova_inst(bc, alu) ||
+ (bc->chiprev == CHIPREV_EVERGREEN &&
+ alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR);
}
/* alu instructions that can only execute on the trans unit */
@@ -525,8 +527,9 @@ static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
case CHIPREV_EVERGREEN:
default:
if (!alu->is_op3)
- /* Note that FLT_TO_INT* instructions are vector instructions
- * on Evergreen, despite what the documentation says. */
+ /* Note that FLT_TO_INT_* instructions are vector-only instructions
+ * on Evergreen, despite what the documentation says. FLT_TO_INT
+ * can do both vector and scalar. */
return alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT ||
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT ||
alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT ||
@@ -1314,6 +1317,24 @@ static void r600_bc_remove_alu(struct r600_bc_cf *cf, struct r600_bc_alu *alu)
cf->ndw -= 2;
}
+static unsigned r600_bc_num_tex_and_vtx_instructions(const struct r600_bc *bc)
+{
+ switch (bc->chiprev) {
+ case CHIPREV_R600:
+ return 8;
+
+ case CHIPREV_R700:
+ return 16;
+
+ case CHIPREV_EVERGREEN:
+ return 64;
+
+ default:
+ R600_ERR("Unknown chiprev %d.\n", bc->chiprev);
+ return 8;
+ }
+}
+
int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
{
struct r600_bc_vtx *nvtx = r600_bc_vtx();
@@ -1339,7 +1360,7 @@ int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
/* each fetch use 4 dwords */
bc->cf_last->ndw += 4;
bc->ndw += 4;
- if ((bc->cf_last->ndw / 4) > 7)
+ if ((bc->cf_last->ndw / 4) >= r600_bc_num_tex_and_vtx_instructions(bc))
bc->force_add_cf = 1;
return 0;
}
@@ -1386,7 +1407,7 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
/* each texture fetch use 4 dwords */
bc->cf_last->ndw += 4;
bc->ndw += 4;
- if ((bc->cf_last->ndw / 4) > 7)
+ if ((bc->cf_last->ndw / 4) >= r600_bc_num_tex_and_vtx_instructions(bc))
bc->force_add_cf = 1;
return 0;
}
@@ -1406,31 +1427,7 @@ int r600_bc_add_cfinst(struct r600_bc *bc, int inst)
/* common to all 3 families */
static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
{
- unsigned fetch_resource_start = 0;
-
- /* check if we are fetch shader */
- /* fetch shader can also access vertex resource,
- * first fetch shader resource is at 160
- */
- if (bc->type == -1) {
- switch (bc->chiprev) {
- /* r600 */
- case CHIPREV_R600:
- /* r700 */
- case CHIPREV_R700:
- fetch_resource_start = 160;
- break;
- /* evergreen */
- case CHIPREV_EVERGREEN:
- fetch_resource_start = 0;
- break;
- default:
- fprintf(stderr, "%s:%s:%d unknown chiprev %d\n",
- __FILE__, __func__, __LINE__, bc->chiprev);
- break;
- }
- }
- bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id + fetch_resource_start) |
+ bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
S_SQ_VTX_WORD0_FETCH_TYPE(vtx->fetch_type) |
S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) |
@@ -1523,6 +1520,14 @@ static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsign
return 0;
}
+static void r600_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf)
+{
+ *bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
+ *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) |
+ S_SQ_CF_WORD1_BARRIER(1) |
+ S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
+}
+
enum cf_class
{
CF_CLASS_ALU,
@@ -1596,11 +1601,10 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
break;
case CF_CLASS_TEXTURE:
case CF_CLASS_VERTEX:
- bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
- bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
- S_SQ_CF_WORD1_BARRIER(cf->barrier) |
- S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1) |
- S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program);
+ if (bc->chiprev == CHIPREV_R700)
+ r700_bc_cf_vtx_build(&bc->bytecode[id], cf);
+ else
+ r600_bc_cf_vtx_build(&bc->bytecode[id], cf);
break;
case CF_CLASS_EXPORT:
bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
@@ -2801,22 +2805,6 @@ void r600_bc_dump(struct r600_bc *bc)
fprintf(stderr, "--------------------------------------\n");
}
-static void r600_cf_vtx(struct r600_vertex_element *ve)
-{
- struct r600_pipe_state *rstate;
-
- rstate = &ve->rstate;
- rstate->id = R600_PIPE_STATE_FETCH_SHADER;
- rstate->nregs = 0;
- r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS,
- 0x00000000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS,
- 0x00000000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS,
- r600_bo_offset(ve->fetch_shader) >> 8,
- 0xFFFFFFFF, ve->fetch_shader);
-}
-
static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
unsigned *num_format, unsigned *format_comp)
{
@@ -2987,7 +2975,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
alu.src[0].chan = 3;
alu.src[1].sel = V_SQ_ALU_SRC_LITERAL;
- alu.src[1].value = (1l << 32) / elements[i].instance_divisor + 1;
+ alu.src[1].value = (1ll << 32) / elements[i].instance_divisor + 1;
alu.dst.sel = i + 1;
alu.dst.chan = 3;
@@ -3075,9 +3063,9 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
r600_bc_clear(&bc);
if (rctx->family >= CHIP_CEDAR)
- eg_cf_vtx(ve);
+ evergreen_fetch_shader(ve);
else
- r600_cf_vtx(ve);
+ r600_fetch_shader(ve);
return 0;
}
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index dbd1e204b49..db8d0a4ed10 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -188,7 +188,6 @@ struct r600_bc {
/* eg_asm.c */
int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf);
-void eg_cf_vtx(struct r600_vertex_element *ve);
/* r600_asm.c */
int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
@@ -206,6 +205,7 @@ void r600_bc_dump(struct r600_bc *bc);
int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve);
/* r700_asm.c */
+void r700_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf);
int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id);
#endif
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index 2363cd1ebc5..6ced719c8f0 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -52,14 +52,6 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
util_slab_free(&rscreen->pool_buffers, rbuffer);
}
-static unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
- struct pipe_resource *buf,
- unsigned level, int layer)
-{
- /* FIXME */
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
static struct pipe_transfer *r600_get_transfer(struct pipe_context *ctx,
struct pipe_resource *resource,
unsigned level,
@@ -160,7 +152,6 @@ static const struct u_resource_vtbl r600_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
r600_buffer_destroy, /* resource_destroy */
- r600_buffer_is_referenced_by_cs, /* is_buffer_referenced */
r600_get_transfer, /* get_transfer */
r600_transfer_destroy, /* transfer_destroy */
r600_buffer_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 651f994a502..4a30eddb621 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -49,7 +49,7 @@
/*
* pipe_context
*/
-static void r600_flush(struct pipe_context *ctx, unsigned flags,
+static void r600_flush(struct pipe_context *ctx,
struct pipe_fence_handle **fence)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
@@ -281,18 +281,28 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_SM3:
case PIPE_CAP_TEXTURE_SWIZZLE:
- case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_DEPTH_CLAMP:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ /* R600 doesn't support per-MRT blends */
+ if (family == CHIP_R600)
+ return 0;
+ else
+ return 1;
/* Unsupported features (boolean caps). */
case PIPE_CAP_STREAM_OUTPUT:
case PIPE_CAP_PRIMITIVE_RESTART:
case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */
- return 0;
+ /* R600 doesn't support per-MRT blends */
+ if (family == CHIP_R600)
+ return 0;
+ else
+ return 0;
case PIPE_CAP_ARRAY_TEXTURES:
/* fix once the CS checker upstream is fixed */
@@ -394,7 +404,7 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
case PIPE_SHADER_CAP_MAX_ADDRS:
return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */
case PIPE_SHADER_CAP_MAX_CONSTS:
- return 256; //max native parameters
+ return R600_MAX_CONST_BUFFER_SIZE;
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
return R600_MAX_CONST_BUFFERS;
case PIPE_SHADER_CAP_MAX_PREDS:
@@ -417,8 +427,7 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned usage,
- unsigned geom_flags)
+ unsigned usage)
{
unsigned retval = 0;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 5f701d87e8f..396801e4a41 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -38,6 +38,7 @@
#include "r600_resource.h"
#define R600_MAX_CONST_BUFFERS 1
+#define R600_MAX_CONST_BUFFER_SIZE 4096
enum r600_pipe_state_id {
R600_PIPE_STATE_BLEND = 0,
@@ -175,6 +176,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx);
void evergreen_init_config(struct r600_pipe_context *rctx);
void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+void evergreen_fetch_shader(struct r600_vertex_element *ve);
void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx);
void evergreen_polygon_offset_update(struct r600_pipe_context *rctx);
void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
@@ -214,6 +216,9 @@ int r600_find_vs_semantic_index(struct r600_shader *vs,
void r600_init_state_functions(struct r600_pipe_context *rctx);
void r600_spi_update(struct r600_pipe_context *rctx);
void r600_init_config(struct r600_pipe_context *rctx);
+void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader);
+void r600_fetch_shader(struct r600_vertex_element *ve);
void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx);
void r600_polygon_offset_update(struct r600_pipe_context *rctx);
void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
index 343403f92f3..181ea3f9e49 100644
--- a/src/gallium/drivers/r600/r600_query.c
+++ b/src/gallium/drivers/r600/r600_query.c
@@ -62,7 +62,7 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
struct r600_query *rquery = (struct r600_query *)query;
if (rquery->num_results) {
- ctx->flush(ctx, 0, NULL);
+ ctx->flush(ctx, NULL);
}
return r600_context_query_result(&rctx->ctx, (struct r600_query *)query, wait, vresult);
}
diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c
index 207642ccfa9..f3ab3613c84 100644
--- a/src/gallium/drivers/r600/r600_resource.c
+++ b/src/gallium/drivers/r600/r600_resource.c
@@ -61,5 +61,4 @@ void r600_init_context_resource_functions(struct r600_pipe_context *r600)
r600->context.transfer_unmap = u_transfer_unmap_vtbl;
r600->context.transfer_destroy = u_transfer_destroy_vtbl;
r600->context.transfer_inline_write = u_transfer_inline_write_vtbl;
- r600->context.is_resource_referenced = u_is_resource_referenced_vtbl;
}
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 0b4dc75e584..12786daa464 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -34,55 +34,6 @@
#include <stdio.h>
#include <errno.h>
-static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader)
-{
- struct r600_pipe_state *rstate = &shader->rstate;
- struct r600_shader *rshader = &shader->shader;
- unsigned spi_vs_out_id[10];
- unsigned i, tmp;
-
- /* clear previous register */
- rstate->nregs = 0;
-
- /* so far never got proper semantic id from tgsi */
- /* FIXME better to move this in config things so they get emited
- * only one time per cs
- */
- for (i = 0; i < 10; i++) {
- spi_vs_out_id[i] = 0;
- }
- for (i = 0; i < 32; i++) {
- tmp = i << ((i & 3) * 8);
- spi_vs_out_id[i / 4] |= tmp;
- }
- for (i = 0; i < 10; i++) {
- r600_pipe_state_add_reg(rstate,
- R_028614_SPI_VS_OUT_ID_0 + i * 4,
- spi_vs_out_id[i], 0xFFFFFFFF, NULL);
- }
-
- r600_pipe_state_add_reg(rstate,
- R_0286C4_SPI_VS_OUT_CONFIG,
- S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2),
- 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_028868_SQ_PGM_RESOURCES_VS,
- S_028868_NUM_GPRS(rshader->bc.ngpr) |
- S_028868_STACK_SIZE(rshader->bc.nstack),
- 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_0288D0_SQ_PGM_CF_OFFSET_VS,
- 0x00000000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_028858_SQ_PGM_START_VS,
- r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo);
-
- r600_pipe_state_add_reg(rstate,
- R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
- 0xFFFFFFFF, NULL);
-
-}
-
int r600_find_vs_semantic_index(struct r600_shader *vs,
struct r600_shader *ps, int id)
{
@@ -97,104 +48,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs,
return 0;
}
-static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader)
-{
- struct r600_pipe_state *rstate = &shader->rstate;
- struct r600_shader *rshader = &shader->shader;
- unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1;
- int pos_index = -1, face_index = -1;
-
- rstate->nregs = 0;
-
- for (i = 0; i < rshader->ninput; i++) {
- if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
- pos_index = i;
- if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
- face_index = i;
- }
-
- for (i = 0; i < rshader->noutput; i++) {
- if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_Z_EXPORT_ENABLE(1),
- S_02880C_Z_EXPORT_ENABLE(1), NULL);
- if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_STENCIL_REF_EXPORT_ENABLE(1),
- S_02880C_STENCIL_REF_EXPORT_ENABLE(1), NULL);
- }
-
- exports_ps = 0;
- num_cout = 0;
- for (i = 0; i < rshader->noutput; i++) {
- if (rshader->output[i].name == TGSI_SEMANTIC_POSITION || rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
- exports_ps |= 1;
- else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) {
- num_cout++;
- }
- }
- exports_ps |= S_028854_EXPORT_COLORS(num_cout);
- if (!exports_ps) {
- /* always at least export 1 component per pixel */
- exports_ps = 2;
- }
-
- spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) |
- S_0286CC_PERSP_GRADIENT_ENA(1);
- spi_input_z = 0;
- if (pos_index != -1) {
- spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) |
- S_0286CC_POSITION_CENTROID(rshader->input[pos_index].centroid) |
- S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) |
- S_0286CC_BARYC_SAMPLE_CNTL(1));
- spi_input_z |= 1;
- }
-
- spi_ps_in_control_1 = 0;
- if (face_index != -1) {
- spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) |
- S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr);
- }
-
- r600_pipe_state_add_reg(rstate, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_0286D0_SPI_PS_IN_CONTROL_1, spi_ps_in_control_1, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_0286D8_SPI_INPUT_Z, spi_input_z, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_028840_SQ_PGM_START_PS,
- r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo);
- r600_pipe_state_add_reg(rstate,
- R_028850_SQ_PGM_RESOURCES_PS,
- S_028868_NUM_GPRS(rshader->bc.ngpr) |
- S_028868_STACK_SIZE(rshader->bc.nstack),
- 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_028854_SQ_PGM_EXPORTS_PS,
- exports_ps, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate,
- R_0288CC_SQ_PGM_CF_OFFSET_PS,
- 0x00000000, 0xFFFFFFFF, NULL);
-
- if (rshader->fs_write_all) {
- r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
- S_028808_MULTIWRITE_ENABLE(1),
- S_028808_MULTIWRITE_ENABLE(1),
- NULL);
- }
-
- if (rshader->uses_kill) {
- /* only set some bits here, the other bits are set in the dsa state */
- r600_pipe_state_add_reg(rstate,
- R_02880C_DB_SHADER_CONTROL,
- S_02880C_KILL_ENABLE(1),
- S_02880C_KILL_ENABLE(1), NULL);
- }
- r600_pipe_state_add_reg(rstate,
- R_03E200_SQ_LOOP_CONST_0, 0x01000FFF,
- 0xFFFFFFFF, NULL);
-}
-
static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
@@ -1706,37 +1559,15 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
}
if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) {
- int src_chan, src2_chan;
+ static const unsigned src0_swizzle[] = {2, 2, 0, 1};
+ static const unsigned src1_swizzle[] = {1, 0, 2, 2};
/* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */
for (i = 0; i < 4; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE);
- switch (i) {
- case 0:
- src_chan = 2;
- src2_chan = 1;
- break;
- case 1:
- src_chan = 2;
- src2_chan = 0;
- break;
- case 2:
- src_chan = 0;
- src2_chan = 2;
- break;
- case 3:
- src_chan = 1;
- src2_chan = 2;
- break;
- default:
- assert(0);
- src_chan = 0;
- src2_chan = 0;
- break;
- }
- r600_bc_src(&alu.src[0], &ctx->src[0], src_chan);
- r600_bc_src(&alu.src[1], &ctx->src[0], src2_chan);
+ r600_bc_src(&alu.src[0], &ctx->src[0], src0_swizzle[i]);
+ r600_bc_src(&alu.src[1], &ctx->src[0], src1_swizzle[i]);
alu.dst.sel = ctx->temp_reg;
alu.dst.chan = i;
if (i == 3)
@@ -2011,6 +1842,8 @@ static int tgsi_cmp(struct r600_shader_ctx *ctx)
static int tgsi_xpd(struct r600_shader_ctx *ctx)
{
struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+ static const unsigned int src0_swizzle[] = {2, 0, 1};
+ static const unsigned int src1_swizzle[] = {1, 2, 0};
struct r600_bc_alu alu;
uint32_t use_temp = 0;
int i, r;
@@ -2021,33 +1854,12 @@ static int tgsi_xpd(struct r600_shader_ctx *ctx)
for (i = 0; i < 4; i++) {
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL);
-
- switch (i) {
- case 0:
- r600_bc_src(&alu.src[0], &ctx->src[0], 2);
- break;
- case 1:
- r600_bc_src(&alu.src[0], &ctx->src[0], 0);
- break;
- case 2:
- r600_bc_src(&alu.src[0], &ctx->src[0], 1);
- break;
- case 3:
+ if (i < 3) {
+ r600_bc_src(&alu.src[0], &ctx->src[0], src0_swizzle[i]);
+ r600_bc_src(&alu.src[1], &ctx->src[1], src1_swizzle[i]);
+ } else {
alu.src[0].sel = V_SQ_ALU_SRC_0;
alu.src[0].chan = i;
- }
-
- switch (i) {
- case 0:
- r600_bc_src(&alu.src[1], &ctx->src[1], 1);
- break;
- case 1:
- r600_bc_src(&alu.src[1], &ctx->src[1], 2);
- break;
- case 2:
- r600_bc_src(&alu.src[1], &ctx->src[1], 0);
- break;
- case 3:
alu.src[1].sel = V_SQ_ALU_SRC_0;
alu.src[1].chan = i;
}
@@ -2067,32 +1879,12 @@ static int tgsi_xpd(struct r600_shader_ctx *ctx)
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD);
- switch (i) {
- case 0:
- r600_bc_src(&alu.src[0], &ctx->src[0], 1);
- break;
- case 1:
- r600_bc_src(&alu.src[0], &ctx->src[0], 2);
- break;
- case 2:
- r600_bc_src(&alu.src[0], &ctx->src[0], 0);
- break;
- case 3:
+ if (i < 3) {
+ r600_bc_src(&alu.src[0], &ctx->src[0], src1_swizzle[i]);
+ r600_bc_src(&alu.src[1], &ctx->src[1], src0_swizzle[i]);
+ } else {
alu.src[0].sel = V_SQ_ALU_SRC_0;
alu.src[0].chan = i;
- }
-
- switch (i) {
- case 0:
- r600_bc_src(&alu.src[1], &ctx->src[1], 2);
- break;
- case 1:
- r600_bc_src(&alu.src[1], &ctx->src[1], 0);
- break;
- case 2:
- r600_bc_src(&alu.src[1], &ctx->src[1], 1);
- break;
- case 3:
alu.src[1].sel = V_SQ_ALU_SRC_0;
alu.src[1].chan = i;
}
@@ -2960,7 +2752,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
{TGSI_OPCODE_RCP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate},
{TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate},
{TGSI_OPCODE_EXP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_exp},
- {TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+ {TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_log},
{TGSI_OPCODE_MUL, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
{TGSI_OPCODE_ADD, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
{TGSI_OPCODE_DP3, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 1be641798f7..efb68cbd139 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -117,9 +117,10 @@ static void r600_set_blend_color(struct pipe_context *ctx,
static void *r600_create_blend_state(struct pipe_context *ctx,
const struct pipe_blend_state *state)
{
+ struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_pipe_blend *blend = CALLOC_STRUCT(r600_pipe_blend);
struct r600_pipe_state *rstate;
- u32 color_control, target_mask;
+ u32 color_control = 0, target_mask;
if (blend == NULL) {
return NULL;
@@ -129,7 +130,10 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
rstate->id = R600_PIPE_STATE_BLEND;
target_mask = 0;
- color_control = S_028808_PER_MRT_BLEND(1);
+
+ /* R600 does not support per-MRT blends */
+ if (rctx->family > CHIP_R600)
+ color_control |= S_028808_PER_MRT_BLEND(1);
if (state->logicop_enable) {
color_control |= (state->logicop_func << 16) | (state->logicop_func << 20);
} else {
@@ -152,8 +156,9 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
}
}
blend->cb_target_mask = target_mask;
+ /* MULTIWRITE_ENABLE is controlled by r600_pipe_shader_ps(). */
r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
- color_control, 0xFFFFFFFF, NULL);
+ color_control, 0xFFFFFFFD, NULL);
for (int i = 0; i < 8; i++) {
unsigned eqRGB = state->rt[i].rgb_func;
@@ -179,10 +184,11 @@ static void *r600_create_blend_state(struct pipe_context *ctx,
bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA));
}
- r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, bc, 0xFFFFFFFF, NULL);
- if (i == 0) {
+ /* R600 does not support per-MRT blends */
+ if (rctx->family > CHIP_R600)
+ r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, bc, 0xFFFFFFFF, NULL);
+ if (i == 0)
r600_pipe_state_add_reg(rstate, R_028804_CB_BLEND_CONTROL, bc, 0xFFFFFFFF, NULL);
- }
}
return rstate;
}
@@ -200,10 +206,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
rstate->id = R600_PIPE_STATE_DSA;
/* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */
- /* db_shader_control is 0xFFFFFFBE as Z_EXPORT_ENABLE (bit 0) will be
- * set by fragment shader if it export Z and KILL_ENABLE (bit 6) will
- * be set if shader use texkill instruction
- */
db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
stencil_ref_mask = 0;
stencil_ref_mask_bf = 0;
@@ -262,7 +264,10 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBE, NULL);
+ /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE,
+ * STENCIL_EXPORT_ENABLE and KILL_ENABLE are controlled by
+ * r600_pipe_shader_ps().*/
+ r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBC, NULL);
r600_pipe_state_add_reg(rstate, R_028D0C_DB_RENDER_CONTROL, db_render_control, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028D10_DB_RENDER_OVERRIDE, db_render_override, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0x00000000, 0xFFFFFFFF, NULL);
@@ -501,7 +506,8 @@ static void r600_set_vs_sampler_view(struct pipe_context *ctx, unsigned count,
for (int i = 0; i < count; i++) {
if (resource[i]) {
- r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i);
+ r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state,
+ i + R600_MAX_CONST_BUFFERS);
}
}
}
@@ -1232,6 +1238,163 @@ void r600_init_config(struct r600_pipe_context *rctx)
r600_context_pipe_state_set(&rctx->ctx, rstate);
}
+void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_pipe_state *rstate = &shader->rstate;
+ struct r600_shader *rshader = &shader->shader;
+ unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control;
+ int pos_index = -1, face_index = -1;
+
+ rstate->nregs = 0;
+
+ for (i = 0; i < rshader->ninput; i++) {
+ if (rshader->input[i].name == TGSI_SEMANTIC_POSITION)
+ pos_index = i;
+ if (rshader->input[i].name == TGSI_SEMANTIC_FACE)
+ face_index = i;
+ }
+
+ db_shader_control = 0;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].name == TGSI_SEMANTIC_POSITION)
+ db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
+ if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
+ db_shader_control |= S_02880C_STENCIL_REF_EXPORT_ENABLE(1);
+ }
+ if (rshader->uses_kill)
+ db_shader_control |= S_02880C_KILL_ENABLE(1);
+
+ exports_ps = 0;
+ num_cout = 0;
+ for (i = 0; i < rshader->noutput; i++) {
+ if (rshader->output[i].name == TGSI_SEMANTIC_POSITION ||
+ rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
+ exports_ps |= 1;
+ else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) {
+ num_cout++;
+ }
+ }
+ exports_ps |= S_028854_EXPORT_COLORS(num_cout);
+ if (!exports_ps) {
+ /* always at least export 1 component per pixel */
+ exports_ps = 2;
+ }
+
+ spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) |
+ S_0286CC_PERSP_GRADIENT_ENA(1);
+ spi_input_z = 0;
+ if (pos_index != -1) {
+ spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) |
+ S_0286CC_POSITION_CENTROID(rshader->input[pos_index].centroid) |
+ S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) |
+ S_0286CC_BARYC_SAMPLE_CNTL(1));
+ spi_input_z |= 1;
+ }
+
+ spi_ps_in_control_1 = 0;
+ if (face_index != -1) {
+ spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) |
+ S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr);
+ }
+
+ r600_pipe_state_add_reg(rstate, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_0286D0_SPI_PS_IN_CONTROL_1, spi_ps_in_control_1, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_0286D8_SPI_INPUT_Z, spi_input_z, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_028840_SQ_PGM_START_PS,
+ r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo);
+ r600_pipe_state_add_reg(rstate,
+ R_028850_SQ_PGM_RESOURCES_PS,
+ S_028868_NUM_GPRS(rshader->bc.ngpr) |
+ S_028868_STACK_SIZE(rshader->bc.nstack),
+ 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_028854_SQ_PGM_EXPORTS_PS,
+ exports_ps, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_0288CC_SQ_PGM_CF_OFFSET_PS,
+ 0x00000000, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL,
+ S_028808_MULTIWRITE_ENABLE(!!rshader->fs_write_all),
+ S_028808_MULTIWRITE_ENABLE(1),
+ NULL);
+ /* only set some bits here, the other bits are set in the dsa state */
+ r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL,
+ db_shader_control,
+ S_02880C_Z_EXPORT_ENABLE(1) |
+ S_02880C_STENCIL_REF_EXPORT_ENABLE(1) |
+ S_02880C_KILL_ENABLE(1),
+ NULL);
+
+ r600_pipe_state_add_reg(rstate,
+ R_03E200_SQ_LOOP_CONST_0, 0x01000FFF,
+ 0xFFFFFFFF, NULL);
+}
+
+void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader)
+{
+ struct r600_pipe_state *rstate = &shader->rstate;
+ struct r600_shader *rshader = &shader->shader;
+ unsigned spi_vs_out_id[10];
+ unsigned i, tmp;
+
+ /* clear previous register */
+ rstate->nregs = 0;
+
+ /* so far never got proper semantic id from tgsi */
+ /* FIXME better to move this in config things so they get emited
+ * only one time per cs
+ */
+ for (i = 0; i < 10; i++) {
+ spi_vs_out_id[i] = 0;
+ }
+ for (i = 0; i < 32; i++) {
+ tmp = i << ((i & 3) * 8);
+ spi_vs_out_id[i / 4] |= tmp;
+ }
+ for (i = 0; i < 10; i++) {
+ r600_pipe_state_add_reg(rstate,
+ R_028614_SPI_VS_OUT_ID_0 + i * 4,
+ spi_vs_out_id[i], 0xFFFFFFFF, NULL);
+ }
+
+ r600_pipe_state_add_reg(rstate,
+ R_0286C4_SPI_VS_OUT_CONFIG,
+ S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2),
+ 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_028868_SQ_PGM_RESOURCES_VS,
+ S_028868_NUM_GPRS(rshader->bc.ngpr) |
+ S_028868_STACK_SIZE(rshader->bc.nstack),
+ 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_0288D0_SQ_PGM_CF_OFFSET_VS,
+ 0x00000000, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate,
+ R_028858_SQ_PGM_START_VS,
+ r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo);
+
+ r600_pipe_state_add_reg(rstate,
+ R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF,
+ 0xFFFFFFFF, NULL);
+}
+
+void r600_fetch_shader(struct r600_vertex_element *ve)
+{
+ struct r600_pipe_state *rstate;
+
+ rstate = &ve->rstate;
+ rstate->id = R600_PIPE_STATE_FETCH_SHADER;
+ rstate->nregs = 0;
+ r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS,
+ 0x00000000, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS,
+ 0x00000000, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS,
+ r600_bo_offset(ve->fetch_shader) >> 8,
+ 0xFFFFFFFF, ve->fetch_shader);
+}
+
void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx)
{
struct pipe_depth_stencil_alpha_state dsa;
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 16b53a0b2a5..d079b571156 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -68,7 +68,7 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
rtransfer->staging_texture,
0, &sbox);
- ctx->flush(ctx, 0, NULL);
+ ctx->flush(ctx, NULL);
}
unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
@@ -299,14 +299,14 @@ static boolean permit_hardware_blit(struct pipe_screen *screen,
res->format,
res->target,
res->nr_samples,
- bind, 0))
+ bind))
return FALSE;
if (!screen->is_format_supported(screen,
res->format,
res->target,
res->nr_samples,
- PIPE_BIND_SAMPLER_VIEW, 0))
+ PIPE_BIND_SAMPLER_VIEW))
return FALSE;
switch (res->usage) {
@@ -349,19 +349,10 @@ static void r600_texture_destroy(struct pipe_screen *screen,
FREE(rtex);
}
-static unsigned int r600_texture_is_referenced(struct pipe_context *context,
- struct pipe_resource *texture,
- unsigned level, int layer)
-{
- /* FIXME */
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
static const struct u_resource_vtbl r600_texture_vtbl =
{
r600_texture_get_handle, /* get_handle */
r600_texture_destroy, /* resource_destroy */
- r600_texture_is_referenced, /* is_resource_referenced */
r600_texture_get_transfer, /* get_transfer */
r600_texture_transfer_destroy, /* transfer_destroy */
r600_texture_transfer_map, /* transfer_map */
@@ -423,10 +414,12 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
/* Would like some magic "get_bool_option_once" routine.
*/
if (force_tiling == -1) {
- struct r600_screen *rscreen = (struct r600_screen *)screen;
+#if 0
/* reenable when 2D tiling is fixed better */
- /*if (r600_get_minor_version(rscreen->radeon) >= 9)
- force_tiling = debug_get_bool_option("R600_TILING", TRUE);*/
+ struct r600_screen *rscreen = (struct r600_screen *)screen;
+ if (r600_get_minor_version(rscreen->radeon) >= 9)
+ force_tiling = debug_get_bool_option("R600_TILING", TRUE);
+#endif
force_tiling = debug_get_bool_option("R600_TILING", FALSE);
}
@@ -653,7 +646,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
if (usage & PIPE_TRANSFER_READ) {
r600_copy_to_staging_texture(ctx, trans);
/* Always referenced in the blit. */
- ctx->flush(ctx, 0, NULL);
+ ctx->flush(ctx, NULL);
}
return &trans->transfer;
}
diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c
index a7f2f54736e..b3c7d1494fc 100644
--- a/src/gallium/drivers/r600/r700_asm.c
+++ b/src/gallium/drivers/r600/r700_asm.c
@@ -26,6 +26,15 @@
#include "r600_asm.h"
#include "r700_sq.h"
+void r700_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf)
+{
+ unsigned count = (cf->ndw / 4) - 1;
+ *bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
+ *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) |
+ S_SQ_CF_WORD1_BARRIER(1) |
+ S_SQ_CF_WORD1_COUNT(count) |
+ S_SQ_CF_WORD1_COUNT_3(count >> 3);
+}
int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
{
diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
index 4a5d5413d8c..6e2d6ba1efa 100644
--- a/src/gallium/drivers/rbug/rbug_context.c
+++ b/src/gallium/drivers/rbug/rbug_context.c
@@ -44,7 +44,10 @@ rbug_destroy(struct pipe_context *_pipe)
struct pipe_context *pipe = rb_pipe->pipe;
remove_from_list(&rb_pipe->list);
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->destroy(pipe);
+ rb_pipe->pipe = NULL;
+ pipe_mutex_unlock(rb_pipe->call_mutex);
FREE(rb_pipe);
}
@@ -112,7 +115,12 @@ rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
pipe_mutex_lock(rb_pipe->draw_mutex);
rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE);
- pipe->draw_vbo(pipe, info);
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ if (!(rb_pipe->curr.fs && rb_pipe->curr.fs->disabled) &&
+ !(rb_pipe->curr.gs && rb_pipe->curr.gs->disabled) &&
+ !(rb_pipe->curr.vs && rb_pipe->curr.vs->disabled))
+ pipe->draw_vbo(pipe, info);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
pipe_mutex_unlock(rb_pipe->draw_mutex);
@@ -125,8 +133,10 @@ rbug_create_query(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
return pipe->create_query(pipe,
query_type);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -136,8 +146,10 @@ rbug_destroy_query(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->destroy_query(pipe,
query);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -147,8 +159,10 @@ rbug_begin_query(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->begin_query(pipe,
query);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -158,8 +172,10 @@ rbug_end_query(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->end_query(pipe,
query);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static boolean
@@ -170,11 +186,16 @@ rbug_get_query_result(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ boolean ret;
- return pipe->get_query_result(pipe,
- query,
- wait,
- result);
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->get_query_result(pipe,
+ query,
+ wait,
+ result);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
+ return ret;
}
static void *
@@ -183,9 +204,14 @@ rbug_create_blend_state(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ void *ret;
+
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->create_blend_state(pipe,
+ blend);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
- return pipe->create_blend_state(pipe,
- blend);
+ return ret;
}
static void
@@ -195,8 +221,10 @@ rbug_bind_blend_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_blend_state(pipe,
- blend);
+ blend);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -206,8 +234,10 @@ rbug_delete_blend_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->delete_blend_state(pipe,
blend);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -216,9 +246,14 @@ rbug_create_sampler_state(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ void *ret;
+
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->create_sampler_state(pipe,
+ sampler);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
- return pipe->create_sampler_state(pipe,
- sampler);
+ return ret;
}
static void
@@ -229,9 +264,11 @@ rbug_bind_fragment_sampler_states(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_fragment_sampler_states(pipe,
num_samplers,
samplers);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -242,9 +279,11 @@ rbug_bind_vertex_sampler_states(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_vertex_sampler_states(pipe,
num_samplers,
samplers);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -254,8 +293,10 @@ rbug_delete_sampler_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->delete_sampler_state(pipe,
sampler);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -264,9 +305,14 @@ rbug_create_rasterizer_state(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ void *ret;
- return pipe->create_rasterizer_state(pipe,
- rasterizer);
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->create_rasterizer_state(pipe,
+ rasterizer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
+ return ret;
}
static void
@@ -276,8 +322,10 @@ rbug_bind_rasterizer_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_rasterizer_state(pipe,
rasterizer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -287,8 +335,10 @@ rbug_delete_rasterizer_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->delete_rasterizer_state(pipe,
rasterizer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -297,9 +347,14 @@ rbug_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ void *ret;
+
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->create_depth_stencil_alpha_state(pipe,
+ depth_stencil_alpha);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
- return pipe->create_depth_stencil_alpha_state(pipe,
- depth_stencil_alpha);
+ return ret;
}
static void
@@ -309,8 +364,10 @@ rbug_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_depth_stencil_alpha_state(pipe,
depth_stencil_alpha);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -320,8 +377,10 @@ rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->delete_depth_stencil_alpha_state(pipe,
depth_stencil_alpha);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -332,7 +391,10 @@ rbug_create_fs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = pipe->create_fs_state(pipe, state);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
if (!result)
return NULL;
@@ -347,10 +409,14 @@ rbug_bind_fs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *fs;
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
fs = rbug_shader_unwrap(_fs);
rb_pipe->curr.fs = rbug_shader(_fs);
pipe->bind_fs_state(pipe,
fs);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -360,7 +426,9 @@ rbug_delete_fs_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_shader *rb_shader = rbug_shader(_fs);
+ pipe_mutex_lock(rb_pipe->call_mutex);
rbug_shader_destroy(rb_pipe, rb_shader);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -371,7 +439,10 @@ rbug_create_vs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = pipe->create_vs_state(pipe, state);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
if (!result)
return NULL;
@@ -386,10 +457,14 @@ rbug_bind_vs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *vs;
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
vs = rbug_shader_unwrap(_vs);
rb_pipe->curr.vs = rbug_shader(_vs);
pipe->bind_vs_state(pipe,
vs);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -399,7 +474,9 @@ rbug_delete_vs_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_shader *rb_shader = rbug_shader(_vs);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
rbug_shader_destroy(rb_pipe, rb_shader);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -410,7 +487,10 @@ rbug_create_gs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = pipe->create_gs_state(pipe, state);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
if (!result)
return NULL;
@@ -425,10 +505,14 @@ rbug_bind_gs_state(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
void *gs;
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
gs = rbug_shader_unwrap(_gs);
rb_pipe->curr.gs = rbug_shader(_gs);
pipe->bind_gs_state(pipe,
gs);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -438,7 +522,9 @@ rbug_delete_gs_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct rbug_shader *rb_shader = rbug_shader(_gs);
+ pipe_mutex_lock(rb_pipe->call_mutex);
rbug_shader_destroy(rb_pipe, rb_shader);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -448,10 +534,15 @@ rbug_create_vertex_elements_state(struct pipe_context *_pipe,
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ void *ret;
- return pipe->create_vertex_elements_state(pipe,
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = pipe->create_vertex_elements_state(pipe,
num_elements,
vertex_elements);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
+ return ret;
}
static void
@@ -461,8 +552,10 @@ rbug_bind_vertex_elements_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->bind_vertex_elements_state(pipe,
velems);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -472,8 +565,10 @@ rbug_delete_vertex_elements_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->delete_vertex_elements_state(pipe,
velems);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -483,8 +578,10 @@ rbug_set_blend_color(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_blend_color(pipe,
blend_color);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -494,8 +591,10 @@ rbug_set_stencil_ref(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_stencil_ref(pipe,
stencil_ref);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -505,8 +604,10 @@ rbug_set_clip_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_clip_state(pipe,
clip);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -526,10 +627,12 @@ rbug_set_constant_buffer(struct pipe_context *_pipe,
resource = unwrapped_resource;
}
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_constant_buffer(pipe,
shader,
index,
resource);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -542,6 +645,9 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe,
struct pipe_framebuffer_state *state = NULL;
unsigned i;
+ /* must protect curr status */
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
rb_pipe->curr.nr_cbufs = 0;
memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs));
rb_pipe->curr.zsbuf = NULL;
@@ -564,6 +670,8 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe,
pipe->set_framebuffer_state(pipe,
state);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -573,8 +681,10 @@ rbug_set_polygon_stipple(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_polygon_stipple(pipe,
poly_stipple);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -584,8 +694,10 @@ rbug_set_scissor_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_scissor_state(pipe,
scissor);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -595,8 +707,10 @@ rbug_set_viewport_state(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_viewport_state(pipe,
viewport);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -610,6 +724,9 @@ rbug_set_fragment_sampler_views(struct pipe_context *_pipe,
struct pipe_sampler_view **views = NULL;
unsigned i;
+ /* must protect curr status */
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
rb_pipe->curr.num_fs_views = 0;
memset(rb_pipe->curr.fs_views, 0, sizeof(rb_pipe->curr.fs_views));
memset(rb_pipe->curr.fs_texs, 0, sizeof(rb_pipe->curr.fs_texs));
@@ -626,6 +743,8 @@ rbug_set_fragment_sampler_views(struct pipe_context *_pipe,
}
pipe->set_fragment_sampler_views(pipe, num, views);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -639,6 +758,9 @@ rbug_set_vertex_sampler_views(struct pipe_context *_pipe,
struct pipe_sampler_view **views = NULL;
unsigned i;
+ /* must protect curr status */
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
rb_pipe->curr.num_vs_views = 0;
memset(rb_pipe->curr.vs_views, 0, sizeof(rb_pipe->curr.vs_views));
memset(rb_pipe->curr.vs_texs, 0, sizeof(rb_pipe->curr.vs_texs));
@@ -655,6 +777,8 @@ rbug_set_vertex_sampler_views(struct pipe_context *_pipe,
}
pipe->set_vertex_sampler_views(pipe, num, views);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -668,6 +792,8 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe,
struct pipe_vertex_buffer *buffers = NULL;
unsigned i;
+ pipe_mutex_lock(rb_pipe->call_mutex);
+
if (num_buffers) {
memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
for (i = 0; i < num_buffers; i++)
@@ -678,6 +804,8 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe,
pipe->set_vertex_buffers(pipe,
num_buffers,
buffers);
+
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -694,7 +822,9 @@ rbug_set_index_buffer(struct pipe_context *_pipe,
ib = &unwrapped_ib;
}
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_index_buffer(pipe, ib);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -704,7 +834,9 @@ rbug_set_sample_mask(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->set_sample_mask(pipe, sample_mask);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -725,6 +857,7 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
struct pipe_resource *dst = rb_resource_dst->resource;
struct pipe_resource *src = rb_resource_src->resource;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->resource_copy_region(pipe,
dst,
dst_level,
@@ -734,6 +867,7 @@ rbug_resource_copy_region(struct pipe_context *_pipe,
src,
src_level,
src_box);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -746,11 +880,13 @@ rbug_clear(struct pipe_context *_pipe,
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->clear(pipe,
buffers,
rgba,
depth,
stencil);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -765,6 +901,7 @@ rbug_clear_render_target(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
struct pipe_surface *dst = rb_surface_dst->surface;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->clear_render_target(pipe,
dst,
rgba,
@@ -772,6 +909,7 @@ rbug_clear_render_target(struct pipe_context *_pipe,
dsty,
width,
height);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
@@ -788,6 +926,7 @@ rbug_clear_depth_stencil(struct pipe_context *_pipe,
struct pipe_context *pipe = rb_pipe->pipe;
struct pipe_surface *dst = rb_surface_dst->surface;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->clear_depth_stencil(pipe,
dst,
clear_flags,
@@ -797,36 +936,20 @@ rbug_clear_depth_stencil(struct pipe_context *_pipe,
dsty,
width,
height);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void
rbug_flush(struct pipe_context *_pipe,
- unsigned flags,
struct pipe_fence_handle **fence)
{
struct rbug_context *rb_pipe = rbug_context(_pipe);
struct pipe_context *pipe = rb_pipe->pipe;
+ pipe_mutex_lock(rb_pipe->call_mutex);
pipe->flush(pipe,
- flags,
fence);
-}
-
-static unsigned int
-rbug_is_resource_referenced(struct pipe_context *_pipe,
- struct pipe_resource *_resource,
- unsigned level,
- int layer)
-{
- struct rbug_context *rb_pipe = rbug_context(_pipe);
- struct rbug_resource *rb_resource = rbug_resource(_resource);
- struct pipe_context *pipe = rb_pipe->pipe;
- struct pipe_resource *resource = rb_resource->resource;
-
- return pipe->is_resource_referenced(pipe,
- resource,
- level,
- layer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static struct pipe_sampler_view *
@@ -840,9 +963,11 @@ rbug_context_create_sampler_view(struct pipe_context *_pipe,
struct pipe_resource *resource = rb_resource->resource;
struct pipe_sampler_view *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = pipe->create_sampler_view(pipe,
resource,
templ);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
if (result)
return rbug_sampler_view_create(rb_pipe, rb_resource, result);
@@ -868,9 +993,11 @@ rbug_context_create_surface(struct pipe_context *_pipe,
struct pipe_resource *resource = rb_resource->resource;
struct pipe_surface *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = pipe->create_surface(pipe,
resource,
surf_tmpl);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
if (result)
return rbug_surface_create(rb_pipe, rb_resource, result);
@@ -881,8 +1008,13 @@ static void
rbug_context_surface_destroy(struct pipe_context *_pipe,
struct pipe_surface *_surface)
{
- rbug_surface_destroy(rbug_context(_pipe),
- rbug_surface(_surface));
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct rbug_surface *rb_surface = rbug_surface(_surface);
+
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ rbug_surface_destroy(rb_pipe,
+ rb_surface);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -900,11 +1032,13 @@ rbug_context_get_transfer(struct pipe_context *_context,
struct pipe_resource *resource = rb_resource->resource;
struct pipe_transfer *result;
+ pipe_mutex_lock(rb_pipe->call_mutex);
result = context->get_transfer(context,
resource,
level,
usage,
box);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
if (result)
return rbug_transfer_create(rb_pipe, rb_resource, result);
@@ -915,8 +1049,13 @@ static void
rbug_context_transfer_destroy(struct pipe_context *_pipe,
struct pipe_transfer *_transfer)
{
- rbug_transfer_destroy(rbug_context(_pipe),
- rbug_transfer(_transfer));
+ struct rbug_context *rb_pipe = rbug_context(_pipe);
+ struct rbug_transfer *rb_transfer =rbug_transfer(_transfer);
+
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ rbug_transfer_destroy(rb_pipe,
+ rb_transfer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
static void *
@@ -927,9 +1066,14 @@ rbug_context_transfer_map(struct pipe_context *_context,
struct rbug_transfer *rb_transfer = rbug_transfer(_transfer);
struct pipe_context *context = rb_pipe->pipe;
struct pipe_transfer *transfer = rb_transfer->transfer;
+ void *ret;
- return context->transfer_map(context,
+ pipe_mutex_lock(rb_pipe->call_mutex);
+ ret = context->transfer_map(context,
transfer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
+
+ return ret;
}
@@ -944,9 +1088,11 @@ rbug_context_transfer_flush_region(struct pipe_context *_context,
struct pipe_context *context = rb_pipe->pipe;
struct pipe_transfer *transfer = rb_transfer->transfer;
+ pipe_mutex_lock(rb_pipe->call_mutex);
context->transfer_flush_region(context,
transfer,
box);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -959,8 +1105,10 @@ rbug_context_transfer_unmap(struct pipe_context *_context,
struct pipe_context *context = rb_pipe->pipe;
struct pipe_transfer *transfer = rb_transfer->transfer;
+ pipe_mutex_lock(rb_pipe->call_mutex);
context->transfer_unmap(context,
transfer);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -979,6 +1127,7 @@ rbug_context_transfer_inline_write(struct pipe_context *_context,
struct pipe_context *context = rb_pipe->pipe;
struct pipe_resource *resource = rb_resource->resource;
+ pipe_mutex_lock(rb_pipe->call_mutex);
context->transfer_inline_write(context,
resource,
level,
@@ -987,6 +1136,7 @@ rbug_context_transfer_inline_write(struct pipe_context *_context,
data,
stride,
layer_stride);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -999,7 +1149,9 @@ static void rbug_redefine_user_buffer(struct pipe_context *_context,
struct pipe_context *context = rb_pipe->pipe;
struct pipe_resource *resource = rb_resource->resource;
+ pipe_mutex_lock(rb_pipe->call_mutex);
context->redefine_user_buffer(context, resource, offset, size);
+ pipe_mutex_unlock(rb_pipe->call_mutex);
}
@@ -1077,7 +1229,6 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
rb_pipe->base.clear_render_target = rbug_clear_render_target;
rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil;
rb_pipe->base.flush = rbug_flush;
- rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced;
rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view;
rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy;
rb_pipe->base.create_surface = rbug_context_create_surface;
diff --git a/src/gallium/drivers/rbug/rbug_core.c b/src/gallium/drivers/rbug/rbug_core.c
index eb772d19d05..b80bcd4228f 100644
--- a/src/gallium/drivers/rbug/rbug_core.c
+++ b/src/gallium/drivers/rbug/rbug_core.c
@@ -498,7 +498,7 @@ rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32
/* protect the pipe context */
pipe_mutex_lock(rb_context->call_mutex);
- rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL);
+ rb_context->pipe->flush(rb_context->pipe, NULL);
pipe_mutex_unlock(rb_context->call_mutex);
pipe_mutex_unlock(rb_screen->list_mutex);
diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c
index d635ce575c0..7c8dfdcc12a 100644
--- a/src/gallium/drivers/rbug/rbug_screen.c
+++ b/src/gallium/drivers/rbug/rbug_screen.c
@@ -106,8 +106,7 @@ rbug_screen_is_format_supported(struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
struct rbug_screen *rb_screen = rbug_screen(_screen);
struct pipe_screen *screen = rb_screen->screen;
@@ -116,8 +115,7 @@ rbug_screen_is_format_supported(struct pipe_screen *_screen,
format,
target,
sample_count,
- tex_usage,
- geom_flags);
+ tex_usage);
}
static struct pipe_context *
@@ -240,30 +238,28 @@ rbug_screen_fence_reference(struct pipe_screen *_screen,
fence);
}
-static int
+static boolean
rbug_screen_fence_signalled(struct pipe_screen *_screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
struct rbug_screen *rb_screen = rbug_screen(_screen);
struct pipe_screen *screen = rb_screen->screen;
return screen->fence_signalled(screen,
- fence,
- flags);
+ fence);
}
-static int
+static boolean
rbug_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
struct rbug_screen *rb_screen = rbug_screen(_screen);
struct pipe_screen *screen = rb_screen->screen;
return screen->fence_finish(screen,
fence,
- flags);
+ timeout);
}
boolean
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 70fdfb7ddf3..ce22f646228 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -148,13 +148,13 @@ softpipe_destroy( struct pipe_context *pipe )
/**
* if (the texture is being used as a framebuffer surface)
- * return PIPE_REFERENCED_FOR_WRITE
+ * return SP_REFERENCED_FOR_WRITE
* else if (the texture is a bound texture source)
- * return PIPE_REFERENCED_FOR_READ
+ * return SP_REFERENCED_FOR_READ
* else
- * return PIPE_UNREFERENCED
+ * return SP_UNREFERENCED
*/
-static unsigned int
+unsigned int
softpipe_is_resource_referenced( struct pipe_context *pipe,
struct pipe_resource *texture,
unsigned level, int layer)
@@ -163,19 +163,19 @@ softpipe_is_resource_referenced( struct pipe_context *pipe,
unsigned i;
if (texture->target == PIPE_BUFFER)
- return PIPE_UNREFERENCED;
+ return SP_UNREFERENCED;
/* check if any of the bound drawing surfaces are this texture */
if (softpipe->dirty_render_cache) {
for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
if (softpipe->framebuffer.cbufs[i] &&
softpipe->framebuffer.cbufs[i]->texture == texture) {
- return PIPE_REFERENCED_FOR_WRITE;
+ return SP_REFERENCED_FOR_WRITE;
}
}
if (softpipe->framebuffer.zsbuf &&
softpipe->framebuffer.zsbuf->texture == texture) {
- return PIPE_REFERENCED_FOR_WRITE;
+ return SP_REFERENCED_FOR_WRITE;
}
}
@@ -183,20 +183,20 @@ softpipe_is_resource_referenced( struct pipe_context *pipe,
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
if (softpipe->fragment_tex_cache[i] &&
softpipe->fragment_tex_cache[i]->texture == texture)
- return PIPE_REFERENCED_FOR_READ;
+ return SP_REFERENCED_FOR_READ;
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
if (softpipe->vertex_tex_cache[i] &&
softpipe->vertex_tex_cache[i]->texture == texture)
- return PIPE_REFERENCED_FOR_READ;
+ return SP_REFERENCED_FOR_READ;
}
for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
if (softpipe->geometry_tex_cache[i] &&
softpipe->geometry_tex_cache[i]->texture == texture)
- return PIPE_REFERENCED_FOR_READ;
+ return SP_REFERENCED_FOR_READ;
}
- return PIPE_UNREFERENCED;
+ return SP_UNREFERENCED;
}
@@ -255,9 +255,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.draw_stream_output = softpipe_draw_stream_output;
softpipe->pipe.clear = softpipe_clear;
- softpipe->pipe.flush = softpipe_flush;
-
- softpipe->pipe.is_resource_referenced = softpipe_is_resource_referenced;
+ softpipe->pipe.flush = softpipe_flush_wrapped;
softpipe->pipe.render_condition = softpipe_render_condition;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index c91709aef06..a572ee8cf00 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -198,4 +198,13 @@ struct pipe_context *
softpipe_create_context( struct pipe_screen *, void *priv );
+#define SP_UNREFERENCED 0
+#define SP_REFERENCED_FOR_READ (1 << 0)
+#define SP_REFERENCED_FOR_WRITE (1 << 1)
+
+unsigned int
+softpipe_is_resource_referenced( struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ unsigned level, int layer);
+
#endif /* SP_CONTEXT_H */
diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c
index 66c52141132..7b79a0df4ea 100644
--- a/src/gallium/drivers/softpipe/sp_fence.c
+++ b/src/gallium/drivers/softpipe/sp_fence.c
@@ -41,23 +41,22 @@ softpipe_fence_reference(struct pipe_screen *screen,
}
-static int
+static boolean
softpipe_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
assert(!fence);
- return 0;
+ return TRUE;
}
-static int
+static boolean
softpipe_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
assert(!fence);
- return 0;
+ return TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 6f7addd441a..720fea83cb2 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -42,7 +42,7 @@
void
softpipe_flush( struct pipe_context *pipe,
- unsigned flags,
+ unsigned flags,
struct pipe_fence_handle **fence )
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@@ -50,7 +50,7 @@ softpipe_flush( struct pipe_context *pipe,
draw_flush(softpipe->draw);
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+ if (flags & SP_FLUSH_TEXTURE_CACHE) {
for (i = 0; i < softpipe->num_fragment_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->fragment_tex_cache[i]);
}
@@ -62,34 +62,27 @@ softpipe_flush( struct pipe_context *pipe,
}
}
- if (flags & PIPE_FLUSH_SWAPBUFFERS) {
- /* If this is a swapbuffers, just flush color buffers.
- *
- * The zbuffer changes are not discarded, but held in the cache
- * in the hope that a later clear will wipe them out.
- */
- for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
- if (softpipe->cbuf_cache[i])
- sp_flush_tile_cache(softpipe->cbuf_cache[i]);
-
- /* Need this call for hardware buffers before swapbuffers.
- *
- * there should probably be another/different flush-type function
- * that's called before swapbuffers because we don't always want
- * to unmap surfaces when flushing.
- */
- softpipe_unmap_transfers(softpipe);
- }
- else if (flags & PIPE_FLUSH_RENDER_CACHE) {
- for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
- if (softpipe->cbuf_cache[i])
- sp_flush_tile_cache(softpipe->cbuf_cache[i]);
-
- if (softpipe->zsbuf_cache)
- sp_flush_tile_cache(softpipe->zsbuf_cache);
-
- softpipe->dirty_render_cache = FALSE;
- }
+ /* If this is a swapbuffers, just flush color buffers.
+ *
+ * The zbuffer changes are not discarded, but held in the cache
+ * in the hope that a later clear will wipe them out.
+ */
+ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
+ if (softpipe->cbuf_cache[i])
+ sp_flush_tile_cache(softpipe->cbuf_cache[i]);
+
+ if (softpipe->zsbuf_cache)
+ sp_flush_tile_cache(softpipe->zsbuf_cache);
+
+ softpipe->dirty_render_cache = FALSE;
+
+ /* Need this call for hardware buffers before swapbuffers.
+ *
+ * there should probably be another/different flush-type function
+ * that's called before swapbuffers because we don't always want
+ * to unmap surfaces when flushing.
+ */
+ softpipe_unmap_transfers(softpipe);
/* Enable to dump BMPs of the color/depth buffers each frame */
#if 0
@@ -108,6 +101,13 @@ softpipe_flush( struct pipe_context *pipe,
*fence = NULL;
}
+void
+softpipe_flush_wrapped( struct pipe_context *pipe,
+ struct pipe_fence_handle **fence )
+{
+ softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence);
+}
+
/**
* Flush context if necessary.
@@ -129,21 +129,18 @@ softpipe_flush_resource(struct pipe_context *pipe,
{
unsigned referenced;
- referenced = pipe->is_resource_referenced(pipe, texture, level, layer);
+ referenced = softpipe_is_resource_referenced(pipe, texture, level, layer);
- if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
- ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
+ if ((referenced & SP_REFERENCED_FOR_WRITE) ||
+ ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) {
/*
* TODO: The semantics of these flush flags are too obtuse. They should
* disappear and the pipe driver should just ensure that all visible
* side-effects happen when they need to happen.
*/
- if (referenced & PIPE_REFERENCED_FOR_WRITE)
- flush_flags |= PIPE_FLUSH_RENDER_CACHE;
-
- if (referenced & PIPE_REFERENCED_FOR_READ)
- flush_flags |= PIPE_FLUSH_TEXTURE_CACHE;
+ if (referenced & SP_REFERENCED_FOR_READ)
+ flush_flags |= SP_FLUSH_TEXTURE_CACHE;
if (cpu_access) {
/*
@@ -155,14 +152,15 @@ softpipe_flush_resource(struct pipe_context *pipe,
if (do_not_block)
return FALSE;
- pipe->flush(pipe, flush_flags, &fence);
+ softpipe_flush(pipe, flush_flags, &fence);
if (fence) {
/*
* This is for illustrative purposes only, as softpipe does not
* have fences.
*/
- pipe->screen->fence_finish(pipe->screen, fence, 0);
+ pipe->screen->fence_finish(pipe->screen, fence,
+ PIPE_TIMEOUT_INFINITE);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
} else {
@@ -170,7 +168,7 @@ softpipe_flush_resource(struct pipe_context *pipe,
* Just flush.
*/
- pipe->flush(pipe, flush_flags, NULL);
+ softpipe_flush(pipe, flush_flags, NULL);
}
}
diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h
index 22a5ceeb9ec..ab01c249abe 100644
--- a/src/gallium/drivers/softpipe/sp_flush.h
+++ b/src/gallium/drivers/softpipe/sp_flush.h
@@ -33,10 +33,17 @@
struct pipe_context;
struct pipe_fence_handle;
+#define SP_FLUSH_TEXTURE_CACHE 0x2
+
void
-softpipe_flush(struct pipe_context *pipe, unsigned flags,
+softpipe_flush(struct pipe_context *pipe,
+ unsigned flags,
struct pipe_fence_handle **fence);
+void
+softpipe_flush_wrapped( struct pipe_context *pipe,
+ struct pipe_fence_handle **fence );
+
boolean
softpipe_flush_resource(struct pipe_context *pipe,
struct pipe_resource *texture,
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 401e3177b48..26f5e1b5740 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -125,7 +125,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
return 0;
case PIPE_CAP_SHADER_STENCIL_EXPORT:
return 1;
- case PIPE_CAP_INSTANCED_DRAWING:
+ case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
case PIPE_CAP_ARRAY_TEXTURES:
return 1;
@@ -181,8 +182,7 @@ softpipe_is_format_supported( struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bind,
- unsigned geom_flags )
+ unsigned bind)
{
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
const struct util_format_description *format_desc;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 8a4ef934348..c09ce19559c 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -1795,6 +1795,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
const struct pipe_sampler_state *sampler = samp->sampler;
int j, k0, k1, k2, k3;
float val;
+ float pc0, pc1, pc2, pc3;
samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba);
@@ -1804,43 +1805,48 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
* RGBA channels. We look at the red channel here.
*/
+ pc0 = CLAMP(p[0], 0.0F, 1.0F);
+ pc1 = CLAMP(p[1], 0.0F, 1.0F);
+ pc2 = CLAMP(p[2], 0.0F, 1.0F);
+ pc3 = CLAMP(p[3], 0.0F, 1.0F);
+
/* compare four texcoords vs. four texture samples */
switch (sampler->compare_func) {
case PIPE_FUNC_LESS:
- k0 = p[0] < rgba[0][0];
- k1 = p[1] < rgba[0][1];
- k2 = p[2] < rgba[0][2];
- k3 = p[3] < rgba[0][3];
+ k0 = pc0 < rgba[0][0];
+ k1 = pc1 < rgba[0][1];
+ k2 = pc2 < rgba[0][2];
+ k3 = pc3 < rgba[0][3];
break;
case PIPE_FUNC_LEQUAL:
- k0 = p[0] <= rgba[0][0];
- k1 = p[1] <= rgba[0][1];
- k2 = p[2] <= rgba[0][2];
- k3 = p[3] <= rgba[0][3];
+ k0 = pc0 <= rgba[0][0];
+ k1 = pc1 <= rgba[0][1];
+ k2 = pc2 <= rgba[0][2];
+ k3 = pc3 <= rgba[0][3];
break;
case PIPE_FUNC_GREATER:
- k0 = p[0] > rgba[0][0];
- k1 = p[1] > rgba[0][1];
- k2 = p[2] > rgba[0][2];
- k3 = p[3] > rgba[0][3];
+ k0 = pc0 > rgba[0][0];
+ k1 = pc1 > rgba[0][1];
+ k2 = pc2 > rgba[0][2];
+ k3 = pc3 > rgba[0][3];
break;
case PIPE_FUNC_GEQUAL:
- k0 = p[0] >= rgba[0][0];
- k1 = p[1] >= rgba[0][1];
- k2 = p[2] >= rgba[0][2];
- k3 = p[3] >= rgba[0][3];
+ k0 = pc0 >= rgba[0][0];
+ k1 = pc1 >= rgba[0][1];
+ k2 = pc2 >= rgba[0][2];
+ k3 = pc3 >= rgba[0][3];
break;
case PIPE_FUNC_EQUAL:
- k0 = p[0] == rgba[0][0];
- k1 = p[1] == rgba[0][1];
- k2 = p[2] == rgba[0][2];
- k3 = p[3] == rgba[0][3];
+ k0 = pc0 == rgba[0][0];
+ k1 = pc1 == rgba[0][1];
+ k2 = pc2 == rgba[0][2];
+ k3 = pc3 == rgba[0][3];
break;
case PIPE_FUNC_NOTEQUAL:
- k0 = p[0] != rgba[0][0];
- k1 = p[1] != rgba[0][1];
- k2 = p[2] != rgba[0][2];
- k3 = p[3] != rgba[0][3];
+ k0 = pc0 != rgba[0][0];
+ k1 = pc1 != rgba[0][1];
+ k2 = pc2 != rgba[0][2];
+ k3 = pc3 != rgba[0][3];
break;
case PIPE_FUNC_ALWAYS:
k0 = k1 = k2 = k3 = 1;
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
index 05eab8a517d..1ed1d5d25bb 100644
--- a/src/gallium/drivers/svga/svga_cmd.c
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -422,7 +422,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
struct svga_transfer *st, // IN
SVGA3dTransferType transfer, // IN
const SVGA3dCopyBox *boxes, // IN
- uint32 numBoxes) // IN
+ uint32 numBoxes, // IN
+ SVGA3dSurfaceDMAFlags flags) // IN
{
struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCmdSurfaceDMA *cmd;
@@ -465,7 +466,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
pSuffix->suffixSize = sizeof *pSuffix;
pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
- memset(&pSuffix->flags, 0, sizeof pSuffix->flags);
+ pSuffix->flags = flags;
swc->commit(swc);
diff --git a/src/gallium/drivers/svga/svga_cmd.h b/src/gallium/drivers/svga/svga_cmd.h
index 0e568d78e65..223ab17df81 100644
--- a/src/gallium/drivers/svga/svga_cmd.h
+++ b/src/gallium/drivers/svga/svga_cmd.h
@@ -102,7 +102,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
struct svga_transfer *st,
SVGA3dTransferType transfer,
const SVGA3dCopyBox *boxes,
- uint32 numBoxes);
+ uint32 numBoxes,
+ SVGA3dSurfaceDMAFlags flags);
enum pipe_error
SVGA3D_BufferDMA(struct svga_winsys_context *swc,
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index f0f875b2b23..4782b4bf70e 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -241,7 +241,8 @@ void svga_context_flush( struct svga_context *svga,
if (SVGA_DEBUG & DEBUG_SYNC) {
if (fence)
- svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 0);
+ svga->pipe.screen->fence_finish( svga->pipe.screen, fence,
+ PIPE_TIMEOUT_INFINITE);
}
if(pfence)
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index d98b9b0e000..2093bcae101 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -73,12 +73,6 @@ retry_draw_range_elements( struct svga_context *svga,
if (ret)
goto retry;
- if (svga->curr.any_user_vertex_buffers) {
- ret = svga_hwtnl_flush( svga->hwtnl );
- if (ret)
- goto retry;
- }
-
return PIPE_OK;
retry:
@@ -122,12 +116,6 @@ retry_draw_arrays( struct svga_context *svga,
if (ret)
goto retry;
- if (svga->curr.any_user_vertex_buffers) {
- ret = svga_hwtnl_flush( svga->hwtnl );
- if (ret)
- goto retry;
- }
-
return 0;
retry:
@@ -161,7 +149,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
/* We're switching between SW and HW drawing. Do a flush to avoid
* mixing HW and SW rendering with the same vertex buffer.
*/
- pipe->flush(pipe, ~0, NULL);
+ pipe->flush(pipe, NULL);
svga->prev_draw_swtnl = svga->state.sw.need_swtnl;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c
index 9357d827f28..4578c136cb8 100644
--- a/src/gallium/drivers/svga/svga_pipe_flush.c
+++ b/src/gallium/drivers/svga/svga_pipe_flush.c
@@ -32,7 +32,6 @@
static void svga_flush( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence )
{
struct svga_context *svga = svga_context(pipe);
@@ -45,29 +44,27 @@ static void svga_flush( struct pipe_context *pipe,
*/
svga_context_flush(svga, fence);
- SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s flags %x fence_ptr %p\n",
- __FUNCTION__, flags, fence ? *fence : 0x0);
+ SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
+ __FUNCTION__, fence ? *fence : 0x0);
/* Enable to dump BMPs of the color/depth buffers each frame */
if (0) {
- if (flags & PIPE_FLUSH_FRAME) {
- struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
- static unsigned frame_no = 1;
- char filename[256];
- unsigned i;
+ struct pipe_framebuffer_state *fb = &svga->curr.framebuffer;
+ static unsigned frame_no = 1;
+ char filename[256];
+ unsigned i;
- for (i = 0; i < fb->nr_cbufs; i++) {
- util_snprintf(filename, sizeof(filename), "cbuf%u_%04u", i, frame_no);
- debug_dump_surface_bmp(&svga->pipe, filename, fb->cbufs[i]);
- }
-
- if (0 && fb->zsbuf) {
- util_snprintf(filename, sizeof(filename), "zsbuf_%04u", frame_no);
- debug_dump_surface_bmp(&svga->pipe, filename, fb->zsbuf);
- }
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ util_snprintf(filename, sizeof(filename), "cbuf%u_%04u", i, frame_no);
+ debug_dump_surface_bmp(&svga->pipe, filename, fb->cbufs[i]);
+ }
- ++frame_no;
+ if (0 && fb->zsbuf) {
+ util_snprintf(filename, sizeof(filename), "zsbuf_%04u", frame_no);
+ debug_dump_surface_bmp(&svga->pipe, filename, fb->zsbuf);
}
+
+ ++frame_no;
}
}
diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c
index bed15ec02e5..6e0622a312b 100644
--- a/src/gallium/drivers/svga/svga_resource.c
+++ b/src/gallium/drivers/svga/svga_resource.c
@@ -33,7 +33,6 @@ svga_resource_from_handle(struct pipe_screen * screen,
void
svga_init_resource_functions(struct svga_context *svga)
{
- svga->pipe.is_resource_referenced = u_is_resource_referenced_vtbl;
svga->pipe.get_transfer = u_get_transfer_vtbl;
svga->pipe.transfer_map = u_transfer_map_vtbl;
svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl;
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index e1f07d655b9..34ab9e143e6 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -51,53 +51,114 @@ svga_buffer_needs_hw_storage(unsigned usage)
}
-static unsigned int
-svga_buffer_is_referenced( struct pipe_context *pipe,
- struct pipe_resource *buf,
- unsigned level, int layer)
+/**
+ * Create a buffer transfer.
+ *
+ * Unlike texture DMAs (which are written immediately to the command buffer and
+ * therefore inherently serialized with other context operations), for buffers
+ * we try to coalesce multiple range mappings (i.e, multiple calls to this
+ * function) into a single DMA command, for better efficiency in command
+ * processing. This means we need to exercise extra care here to ensure that
+ * the end result is exactly the same as if one DMA was used for every mapped
+ * range.
+ */
+static struct pipe_transfer *
+svga_buffer_get_transfer(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box)
{
+ struct svga_context *svga = svga_context(pipe);
struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_buffer *sbuf = svga_buffer(buf);
+ struct svga_buffer *sbuf = svga_buffer(resource);
+ struct pipe_transfer *transfer;
- /**
- * XXX: Check this.
- * The screen may cache buffer writes, but when we map, we map out
- * of those cached writes, so we don't need to set a
- * PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
- */
+ transfer = CALLOC_STRUCT(pipe_transfer);
+ if (transfer == NULL) {
+ return NULL;
+ }
- if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
- return PIPE_UNREFERENCED;
+ transfer->resource = resource;
+ transfer->level = level;
+ transfer->usage = usage;
+ transfer->box = *box;
- /**
- * sws->surface_is_flushed() does not distinguish between read references
- * and write references. So assume a reference is both,
- * however, we make an exception for index- and vertex buffers, to avoid
- * a flush in st_bufferobj_get_subdata, during display list replay.
- */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ /*
+ * Finish writing any pending DMA commands, and tell the host to discard
+ * the buffer contents on the next DMA operation.
+ */
- if (sbuf->b.b.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
- return PIPE_REFERENCED_FOR_READ;
+ if (sbuf->dma.pending) {
+ svga_buffer_upload_flush(svga, sbuf);
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
+ /*
+ * Instead of flushing the context command buffer, simply discard
+ * the current hwbuf, and start a new one.
+ */
+ svga_buffer_destroy_hw_storage(ss, sbuf);
+ }
+ sbuf->map.num_ranges = 0;
+ sbuf->dma.flags.discard = TRUE;
+ }
+ if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
+ if (!sbuf->map.num_ranges) {
+ /*
+ * No pending ranges to upload so far, so we can tell the host to
+ * not synchronize on the next DMA command.
+ */
+ sbuf->dma.flags.unsynchronized = TRUE;
+ }
+ } else {
+ /*
+ * Synchronizing, so finish writing any pending DMA command, and
+ * ensure the next DMA will be done in order.
+ */
+ if (sbuf->dma.pending) {
+ svga_buffer_upload_flush(svga, sbuf);
+
+ if (sbuf->hwbuf) {
+ /*
+ * We have a pending DMA upload from a hardware buffer, therefore
+ * we need to ensure that the host finishes processing that DMA
+ * command before the state tracker can start overwriting the
+ * hardware buffer.
+ *
+ * XXX: This could be avoided by tying the hardware buffer to
+ * the transfer (just as done with textures), which would allow
+ * overlapping DMAs commands to be queued on the same context
+ * buffer. However, due to the likelihood of software vertex
+ * processing, it is more convenient to hold on to the hardware
+ * buffer, allowing to quickly access the contents from the CPU
+ * without having to do a DMA download from the host.
+ */
+
+ if (usage & PIPE_TRANSFER_DONTBLOCK) {
+ /*
+ * Flushing the command buffer here will most likely cause
+ * the map of the hwbuf below to block, so preemptively
+ * return NULL here if DONTBLOCK is set to prevent unnecessary
+ * command buffer flushes.
+ */
+
+ FREE(transfer);
+ return NULL;
+ }
+
+ svga_context_flush(svga, NULL);
+ }
+ }
-static void *
-svga_buffer_map_range( struct pipe_screen *screen,
- struct pipe_resource *buf,
- unsigned offset,
- unsigned length,
- unsigned usage )
-{
- struct svga_screen *ss = svga_screen(screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_buffer *sbuf = svga_buffer( buf );
- void *map;
+ sbuf->dma.flags.unsynchronized = FALSE;
+ }
+ }
if (!sbuf->swbuf && !sbuf->hwbuf) {
if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
@@ -113,86 +174,120 @@ svga_buffer_map_range( struct pipe_screen *screen,
}
sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16);
+ if (!sbuf->swbuf) {
+ FREE(transfer);
+ return NULL;
+ }
}
}
+ return transfer;
+}
+
+
+/**
+ * Map a range of a buffer.
+ */
+static void *
+svga_buffer_transfer_map( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct svga_buffer *sbuf = svga_buffer(transfer->resource);
+
+ uint8_t *map;
+
if (sbuf->swbuf) {
/* User/malloc buffer */
map = sbuf->swbuf;
}
else if (sbuf->hwbuf) {
- map = sws->buffer_map(sws, sbuf->hwbuf, usage);
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_screen *sws = ss->sws;
+
+ map = sws->buffer_map(sws, sbuf->hwbuf, transfer->usage);
}
else {
map = NULL;
}
- if(map) {
+ if (map) {
++sbuf->map.count;
-
- if (usage & PIPE_TRANSFER_WRITE) {
- assert(sbuf->map.count <= 1);
- sbuf->map.writing = TRUE;
- if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT)
- sbuf->map.flush_explicit = TRUE;
- }
+ map += transfer->box.x;
}
return map;
}
-
-static void
-svga_buffer_flush_mapped_range( struct pipe_screen *screen,
- struct pipe_resource *buf,
- unsigned offset, unsigned length)
+static void
+svga_buffer_transfer_flush_region( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
{
- struct svga_buffer *sbuf = svga_buffer( buf );
- struct svga_screen *ss = svga_screen(screen);
-
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_buffer *sbuf = svga_buffer(transfer->resource);
+
+ unsigned offset = transfer->box.x + box->x;
+ unsigned length = box->width;
+
+ assert(transfer->usage & PIPE_TRANSFER_WRITE);
+ assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
+
pipe_mutex_lock(ss->swc_mutex);
- assert(sbuf->map.writing);
- if(sbuf->map.writing) {
- assert(sbuf->map.flush_explicit);
- svga_buffer_add_range(sbuf, offset, offset + length);
- }
+ svga_buffer_add_range(sbuf, offset, offset + length);
pipe_mutex_unlock(ss->swc_mutex);
}
-static void
-svga_buffer_unmap( struct pipe_screen *screen,
- struct pipe_resource *buf)
+
+static void
+svga_buffer_transfer_unmap( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
{
- struct svga_screen *ss = svga_screen(screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
- struct svga_buffer *sbuf = svga_buffer( buf );
+ struct svga_buffer *sbuf = svga_buffer(transfer->resource);
pipe_mutex_lock(ss->swc_mutex);
assert(sbuf->map.count);
- if(sbuf->map.count)
+ if (sbuf->map.count) {
--sbuf->map.count;
+ }
- if(sbuf->hwbuf)
+ if (sbuf->hwbuf) {
sws->buffer_unmap(sws, sbuf->hwbuf);
+ }
+
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
+ /*
+ * Mapped range not flushed explicitly, so flush the whole buffer,
+ * and tell the host to discard the contents when processing the DMA
+ * command.
+ */
- if(sbuf->map.writing) {
- if(!sbuf->map.flush_explicit) {
- /* No mapped range was flushed -- flush the whole buffer */
SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
+ sbuf->dma.flags.discard = TRUE;
+
svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
}
-
- sbuf->map.writing = FALSE;
- sbuf->map.flush_explicit = FALSE;
}
pipe_mutex_unlock(ss->swc_mutex);
}
+/**
+ * Destroy transfer
+ */
+static void
+svga_buffer_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ FREE(transfer);
+}
+
static void
svga_buffer_destroy( struct pipe_screen *screen,
@@ -221,62 +316,12 @@ svga_buffer_destroy( struct pipe_screen *screen,
}
-/* Keep the original code more or less intact, implement transfers in
- * terms of the old functions.
- */
-static void *
-svga_buffer_transfer_map( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
-{
- uint8_t *map = svga_buffer_map_range( pipe->screen,
- transfer->resource,
- transfer->box.x,
- transfer->box.width,
- transfer->usage );
- if (map == NULL)
- return NULL;
-
- /* map_buffer() returned a pointer to the beginning of the buffer,
- * but transfers are expected to return a pointer to just the
- * region specified in the box.
- */
- return map + transfer->box.x;
-}
-
-
-
-static void svga_buffer_transfer_flush_region( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box)
-{
- assert(box->x + box->width <= transfer->box.width);
-
- svga_buffer_flush_mapped_range(pipe->screen,
- transfer->resource,
- transfer->box.x + box->x,
- box->width);
-}
-
-static void svga_buffer_transfer_unmap( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
-{
- svga_buffer_unmap(pipe->screen,
- transfer->resource);
-}
-
-
-
-
-
-
-
struct u_resource_vtbl svga_buffer_vtbl =
{
u_default_resource_get_handle, /* get_handle */
svga_buffer_destroy, /* resource_destroy */
- svga_buffer_is_referenced, /* is_resource_referenced */
- u_default_get_transfer, /* get_transfer */
- u_default_transfer_destroy, /* transfer_destroy */
+ svga_buffer_get_transfer, /* get_transfer */
+ svga_buffer_transfer_destroy, /* transfer_destroy */
svga_buffer_transfer_map, /* transfer_map */
svga_buffer_transfer_flush_region, /* transfer_flush_region */
svga_buffer_transfer_unmap, /* transfer_unmap */
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index c559f70ec12..95032213fa5 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -90,7 +90,9 @@ struct svga_buffer
* Host surface handle.
*
* This is a platform independent abstraction for host SID. We create when
- * trying to bind
+ * trying to bind.
+ *
+ * Only set for non-user buffers.
*/
struct svga_winsys_surface *handle;
@@ -100,24 +102,10 @@ struct svga_buffer
struct {
/**
* Number of concurrent mappings.
- *
- * XXX: It is impossible to guarantee concurrent maps work in all
- * circumstances -- pipe_buffers really need transfer objects too.
*/
unsigned count;
/**
- * Whether this buffer is currently mapped for writing.
- */
- boolean writing;
-
- /**
- * Whether the application will tell us explicity which ranges it touched
- * or not.
- */
- boolean flush_explicit;
-
- /**
* Dirty ranges.
*
* Ranges that were touched by the application and need to be uploaded to
@@ -149,6 +137,8 @@ struct svga_buffer
* A piece of GMR memory, with the same size of the buffer. It is created
* when mapping the buffer, and will be used to upload vertex data to the
* host.
+ *
+ * Only set for non-user buffers.
*/
struct svga_winsys_buffer *hwbuf;
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index b7d54605e66..e5fcec08d6e 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -131,6 +131,8 @@ enum pipe_error
svga_buffer_create_host_surface(struct svga_screen *ss,
struct svga_buffer *sbuf)
{
+ assert(!sbuf->user);
+
if(!sbuf->handle) {
sbuf->key.flags = 0;
@@ -252,7 +254,7 @@ svga_buffer_upload_command(struct svga_context *svga,
* Patch up the upload DMA command reserved by svga_buffer_upload_command
* with the final ranges.
*/
-static void
+void
svga_buffer_upload_flush(struct svga_context *svga,
struct svga_buffer *sbuf)
{
@@ -260,6 +262,10 @@ svga_buffer_upload_flush(struct svga_context *svga,
unsigned i;
struct pipe_resource *dummy;
+ if (!sbuf->dma.pending) {
+ return;
+ }
+
assert(sbuf->handle);
assert(sbuf->hwbuf);
assert(sbuf->map.num_ranges);
@@ -296,6 +302,8 @@ svga_buffer_upload_flush(struct svga_context *svga,
sbuf->head.next = sbuf->head.prev = NULL;
#endif
sbuf->dma.pending = FALSE;
+ sbuf->dma.flags.discard = FALSE;
+ sbuf->dma.flags.unsynchronized = FALSE;
sbuf->dma.svga = NULL;
sbuf->dma.boxes = NULL;
@@ -306,7 +314,6 @@ svga_buffer_upload_flush(struct svga_context *svga,
}
-
/**
* Note a dirty range.
*
@@ -337,12 +344,6 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
/*
* Try to grow one of the ranges.
- *
- * Note that it is not this function task to care about overlapping ranges,
- * as the GMR was already given so it is too late to do anything. Situations
- * where overlapping ranges may pose a problem should be detected via
- * pipe_context::is_resource_referenced and the context that refers to the
- * buffer should be flushed.
*/
for(i = 0; i < sbuf->map.num_ranges; ++i) {
@@ -357,6 +358,11 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
if (dist <= 0) {
/*
* Ranges are contiguous or overlapping -- extend this one and return.
+ *
+ * Note that it is not this function's task to prevent overlapping
+ * ranges, as the GMR was already given so it is too late to do
+ * anything. If the ranges overlap here it must surely be because
+ * PIPE_TRANSFER_UNSYNCHRONIZED was set.
*/
sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
@@ -380,8 +386,7 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
* pending DMA upload and start clean.
*/
- if(sbuf->dma.pending)
- svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
+ svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
assert(!sbuf->dma.pending);
assert(!sbuf->dma.svga);
@@ -662,6 +667,9 @@ svga_redefine_user_buffer(struct pipe_context *pipe,
struct svga_buffer *sbuf = svga_buffer(resource);
assert(sbuf->user);
+ assert(!sbuf->dma.pending);
+ assert(!sbuf->handle);
+ assert(!sbuf->hwbuf);
/*
* Release any uploaded user buffer.
@@ -674,29 +682,9 @@ svga_redefine_user_buffer(struct pipe_context *pipe,
pipe_mutex_lock(ss->swc_mutex);
- if (offset + size > resource->width0) {
- /*
- * User buffers shouldn't have DMA directly, unless
- * SVGA_COMBINE_USERBUFFERS is not set.
- */
-
- if (sbuf->dma.pending) {
- svga_buffer_upload_flush(svga, sbuf);
- }
-
- if (sbuf->handle) {
- svga_buffer_destroy_host_surface(ss, sbuf);
- }
-
- if (sbuf->hwbuf) {
- svga_buffer_destroy_hw_storage(ss, sbuf);
- }
-
- sbuf->key.size.width = sbuf->b.b.width0 = offset + size;
- }
+ sbuf->key.size.width = sbuf->b.b.width0 = offset + size;
pipe_mutex_unlock(ss->swc_mutex);
- svga->curr.any_user_vertex_buffers = TRUE;
svga->dirty |= SVGA_NEW_VBUFFER | SVGA_NEW_VELEMENT;
}
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.h b/src/gallium/drivers/svga/svga_resource_buffer_upload.h
index 11df3065263..13d8f3e299b 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.h
@@ -28,6 +28,10 @@
void
+svga_buffer_upload_flush(struct svga_context *svga,
+ struct svga_buffer *sbuf);
+
+void
svga_buffer_add_range(struct svga_buffer *sbuf,
unsigned start,
unsigned end);
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 994f30719ae..b61f85955a2 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -48,31 +48,6 @@
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
-static unsigned int
-svga_texture_is_referenced( struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer)
-{
- struct svga_texture *tex = svga_texture(texture);
- struct svga_screen *ss = svga_screen(pipe->screen);
-
- /**
- * The screen does not cache texture writes.
- */
-
- if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
- return PIPE_UNREFERENCED;
-
- /**
- * sws->surface_is_flushed() does not distinguish between read references
- * and write references. So assume a reference is both.
- */
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
-
-
/*
* Helper function and arrays
*/
@@ -156,7 +131,8 @@ static INLINE void
svga_transfer_dma_band(struct svga_context *svga,
struct svga_transfer *st,
SVGA3dTransferType transfer,
- unsigned y, unsigned h, unsigned srcy)
+ unsigned y, unsigned h, unsigned srcy,
+ SVGA3dSurfaceDMAFlags flags)
{
struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCopyBox box;
@@ -192,10 +168,10 @@ svga_transfer_dma_band(struct svga_context *svga,
util_format_get_blocksize(texture->b.b.format) * 8 /
(util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
if(ret != PIPE_OK) {
svga_context_flush(svga, NULL);
- ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1);
+ ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
assert(ret == PIPE_OK);
}
}
@@ -204,7 +180,8 @@ svga_transfer_dma_band(struct svga_context *svga,
static INLINE void
svga_transfer_dma(struct svga_context *svga,
struct svga_transfer *st,
- SVGA3dTransferType transfer)
+ SVGA3dTransferType transfer,
+ SVGA3dSurfaceDMAFlags flags)
{
struct svga_texture *texture = svga_texture(st->base.resource);
struct svga_screen *screen = svga_screen(texture->b.b.screen);
@@ -223,7 +200,9 @@ svga_transfer_dma(struct svga_context *svga,
if(!st->swbuf) {
/* Do the DMA transfer in a single go */
- svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0);
+ svga_transfer_dma_band(svga, st, transfer,
+ st->base.box.y, st->base.box.height, 0,
+ flags);
if(transfer == SVGA3D_READ_HOST_VRAM) {
svga_context_flush(svga, &fence);
@@ -269,7 +248,14 @@ svga_transfer_dma(struct svga_context *svga,
}
}
- svga_transfer_dma_band(svga, st, transfer, y, h, srcy);
+ svga_transfer_dma_band(svga, st, transfer, y, h, srcy, flags);
+
+ /*
+ * Prevent the texture contents to be discarded on the next band
+ * upload.
+ */
+
+ flags.discard = FALSE;
if(transfer == SVGA3D_READ_HOST_VRAM) {
svga_context_flush(svga, &fence);
@@ -398,8 +384,11 @@ svga_texture_get_transfer(struct pipe_context *pipe,
goto no_swbuf;
}
- if (usage & PIPE_TRANSFER_READ)
- svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM);
+ if (usage & PIPE_TRANSFER_READ) {
+ SVGA3dSurfaceDMAFlags flags;
+ memset(&flags, 0, sizeof flags);
+ svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM, flags);
+ }
return &st->base;
@@ -458,7 +447,17 @@ svga_texture_transfer_destroy(struct pipe_context *pipe,
struct svga_transfer *st = svga_transfer(transfer);
if (st->base.usage & PIPE_TRANSFER_WRITE) {
- svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
+ SVGA3dSurfaceDMAFlags flags;
+
+ memset(&flags, 0, sizeof flags);
+ if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+ flags.discard = TRUE;
+ }
+ if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
+ flags.unsynchronized = TRUE;
+ }
+
+ svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
ss->texture_timestamp++;
tex->view_age[transfer->level] = ++(tex->age);
if (transfer->resource->target == PIPE_TEXTURE_CUBE)
@@ -481,7 +480,6 @@ struct u_resource_vtbl svga_texture_vtbl =
{
svga_texture_get_handle, /* get_handle */
svga_texture_destroy, /* resource_destroy */
- svga_texture_is_referenced, /* is_resource_referenced */
svga_texture_get_transfer, /* get_transfer */
svga_texture_transfer_destroy, /* transfer_destroy */
svga_texture_transfer_map, /* transfer_map */
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index ef1d3098d51..6c987abe056 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -342,8 +342,7 @@ svga_is_format_supported( struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags )
+ unsigned tex_usage)
{
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
SVGA3dDevCapIndex index;
@@ -412,27 +411,26 @@ svga_fence_reference(struct pipe_screen *screen,
}
-static int
+static boolean
svga_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flag)
+ struct pipe_fence_handle *fence)
{
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
- return sws->fence_signalled(sws, fence, flag);
+ return sws->fence_signalled(sws, fence, 0) == 0;
}
-static int
+static boolean
svga_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flag)
+ uint64_t timeout)
{
struct svga_winsys_screen *sws = svga_screen(screen)->sws;
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n",
__FUNCTION__, fence);
- return sws->fence_finish(sws, fence, flag);
+ return sws->fence_finish(sws, fence, 0) == 0;
}
@@ -498,6 +496,12 @@ svga_screen_create(struct svga_winsys_screen *sws)
svga_init_screen_resource_functions(svgascreen);
+ if (sws->get_hw_version) {
+ svgascreen->hw_version = sws->get_hw_version(sws);
+ } else {
+ svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1;
+ }
+
svgascreen->use_ps30 =
sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE;
diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h
index 86ec89d88c1..6d8d287ce95 100644
--- a/src/gallium/drivers/svga/svga_screen.h
+++ b/src/gallium/drivers/svga/svga_screen.h
@@ -39,8 +39,6 @@ struct svga_winsys_screen;
struct svga_winsys_context;
struct SVGACmdMemory;
-#define SVGA_COMBINE_USERBUFFERS 1
-
/**
* Subclass of pipe_screen
*/
@@ -49,6 +47,8 @@ struct svga_screen
struct pipe_screen screen;
struct svga_winsys_screen *sws;
+ SVGA3dHardwareVersion hw_version;
+
unsigned use_ps30;
unsigned use_vs30;
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index 958d00393f2..7c393a1da8d 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -78,7 +78,6 @@ upload_user_buffers( struct svga_context *svga )
buffer->b.b.width0);
}
- pipe_resource_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
}
}
@@ -110,6 +109,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
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;
+ struct svga_buffer *buffer = svga_buffer(vb->buffer);
svga_generate_vdecl_semantics( i, &usage, &index );
@@ -127,6 +127,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
svga_hwtnl_vdecl( svga->hwtnl,
i,
&decl,
+ buffer->uploaded.buffer ? buffer->uploaded.buffer :
vb->buffer );
}
@@ -148,14 +149,10 @@ static int emit_hw_vdecl( struct svga_context *svga,
* userbuffers now and try to combine multiple userbuffers from
* multiple draw calls into a single host buffer for performance.
*/
- if (svga->curr.any_user_vertex_buffers &&
- SVGA_COMBINE_USERBUFFERS)
- {
+ if (svga->curr.any_user_vertex_buffers) {
ret = upload_user_buffers( svga );
if (ret)
return ret;
-
- svga->curr.any_user_vertex_buffers = FALSE;
}
return emit_hw_vs_vdecl( svga, dirty );
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 5e4bdeff2ee..ae61cea083f 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -136,6 +136,9 @@ struct svga_winsys_screen
void
(*destroy)(struct svga_winsys_screen *sws);
+ SVGA3dHardwareVersion
+ (*get_hw_version)(struct svga_winsys_screen *sws);
+
boolean
(*get_cap)(struct svga_winsys_screen *sws,
SVGA3dDevCapIndex index,
@@ -243,12 +246,12 @@ struct svga_winsys_screen
/**
* Map the entire data store of a buffer object into the client's address.
- * flags is a bitmaks of PIPE_TRANSFER_*
+ * usage is a bitmask of PIPE_TRANSFER_*
*/
void *
(*buffer_map)( struct svga_winsys_screen *sws,
struct svga_winsys_buffer *buf,
- unsigned flags );
+ unsigned usage );
void
(*buffer_unmap)( struct svga_winsys_screen *sws,
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index d24cc623c2e..4db7619c424 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1184,7 +1184,6 @@ trace_context_clear_depth_stencil(struct pipe_context *_pipe,
static INLINE void
trace_context_flush(struct pipe_context *_pipe,
- unsigned flags,
struct pipe_fence_handle **fence)
{
struct trace_context *tr_ctx = trace_context(_pipe);
@@ -1193,9 +1192,8 @@ trace_context_flush(struct pipe_context *_pipe,
trace_dump_call_begin("pipe_context", "flush");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, flags);
- pipe->flush(pipe, flags, fence);
+ pipe->flush(pipe, fence);
if(fence)
trace_dump_ret(ptr, *fence);
@@ -1219,31 +1217,6 @@ trace_context_destroy(struct pipe_context *_pipe)
FREE(tr_ctx);
}
-static unsigned int
-trace_is_resource_referenced( struct pipe_context *_pipe,
- struct pipe_resource *_resource,
- unsigned level, int layer)
-{
- struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_resource *tr_tex = trace_resource(_resource);
- struct pipe_context *pipe = tr_ctx->pipe;
- struct pipe_resource *texture = tr_tex->resource;
- unsigned int referenced;
-
- trace_dump_call_begin("pipe_context", "is_resource_referenced");
- trace_dump_arg(ptr, pipe);
- trace_dump_arg(ptr, texture);
- trace_dump_arg(uint, level);
- trace_dump_arg(int, layer);
-
- referenced = pipe->is_resource_referenced(pipe, texture, level, layer);
-
- trace_dump_ret(uint, referenced);
- trace_dump_call_end();
-
- return referenced;
-}
-
/********************************************************************
* transfer
@@ -1520,7 +1493,6 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.clear_render_target = trace_context_clear_render_target;
tr_ctx->base.clear_depth_stencil = trace_context_clear_depth_stencil;
tr_ctx->base.flush = trace_context_flush;
- tr_ctx->base.is_resource_referenced = trace_is_resource_referenced;
tr_ctx->base.get_transfer = trace_context_get_transfer;
tr_ctx->base.transfer_destroy = trace_context_transfer_destroy;
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 51a4ea96335..8a4ec20fb84 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -60,10 +60,9 @@
static struct os_stream *stream = NULL;
static unsigned refcount = 0;
-static pipe_mutex call_mutex;
+pipe_static_mutex(call_mutex);
static long unsigned call_no = 0;
static boolean dumping = FALSE;
-static boolean initialized = FALSE;
static INLINE void
@@ -225,26 +224,13 @@ trace_dump_trace_close(void)
stream = NULL;
refcount = 0;
call_no = 0;
- pipe_mutex_destroy(call_mutex);
}
}
-void trace_dump_init()
-{
- if (initialized)
- return;
-
- pipe_mutex_init(call_mutex);
- dumping = FALSE;
- initialized = TRUE;
-}
-
boolean trace_dump_trace_begin()
{
const char *filename;
- assert(initialized);
-
filename = debug_get_option("GALLIUM_TRACE", NULL);
if(!filename)
return FALSE;
diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h
index 74c5e83e9e1..62b4fe429b1 100644
--- a/src/gallium/drivers/trace/tr_dump.h
+++ b/src/gallium/drivers/trace/tr_dump.h
@@ -43,11 +43,6 @@ struct pipe_transfer;
struct pipe_box;
/*
- * Call before use.
- */
-void trace_dump_init(void);
-
-/*
* Low level dumping controls.
*
* Opening the trace file and checking if that is opened.
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index c2de2daa883..42180c4f19e 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -158,8 +158,7 @@ trace_screen_is_format_supported(struct pipe_screen *_screen,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned tex_usage,
- unsigned geom_flags)
+ unsigned tex_usage)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -172,10 +171,9 @@ trace_screen_is_format_supported(struct pipe_screen *_screen,
trace_dump_arg(int, target);
trace_dump_arg(uint, sample_count);
trace_dump_arg(uint, tex_usage);
- trace_dump_arg(uint, geom_flags);
result = screen->is_format_supported(screen, format, target, sample_count,
- tex_usage, geom_flags);
+ tex_usage);
trace_dump_ret(bool, result);
@@ -393,10 +391,9 @@ trace_screen_fence_reference(struct pipe_screen *_screen,
}
-static int
+static boolean
trace_screen_fence_signalled(struct pipe_screen *_screen,
- struct pipe_fence_handle *fence,
- unsigned flags)
+ struct pipe_fence_handle *fence)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -406,11 +403,10 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flags);
- result = screen->fence_signalled(screen, fence, flags);
+ result = screen->fence_signalled(screen, fence);
- trace_dump_ret(int, result);
+ trace_dump_ret(bool, result);
trace_dump_call_end();
@@ -418,10 +414,10 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
}
-static int
+static boolean
trace_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flags)
+ uint64_t timeout)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -431,11 +427,11 @@ trace_screen_fence_finish(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flags);
+ trace_dump_arg(uint, timeout);
- result = screen->fence_finish(screen, fence, flags);
+ result = screen->fence_finish(screen, fence, timeout);
- trace_dump_ret(int, result);
+ trace_dump_ret(bool, result);
trace_dump_call_end();
@@ -472,8 +468,6 @@ trace_enabled(void)
return trace;
firstrun = FALSE;
- trace_dump_init();
-
if(trace_dump_trace_begin()) {
trace_dumping_start();
trace = TRUE;
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 24ee3fe1175..d8de3bac0ec 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -312,29 +312,12 @@ struct pipe_context {
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
- /** Flush rendering
- * \param flags bitmask of PIPE_FLUSH_x tokens)
+ /** Flush draw commands
*/
void (*flush)( struct pipe_context *pipe,
- unsigned flags,
struct pipe_fence_handle **fence );
/**
- * Check whether a texture is referenced by an unflushed hw command.
- * The state-tracker uses this function to avoid unnecessary flushes.
- * It is safe (but wasteful) to always return
- * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
- * \param pipe context whose unflushed hw commands will be checked.
- * \param texture texture to check.
- * \param level mipmap level.
- * \param layer cubemap face, 2d array or 3d slice, 0 otherwise. Use -1 for any layer.
- * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
- */
- unsigned int (*is_resource_referenced)(struct pipe_context *pipe,
- struct pipe_resource *texture,
- unsigned level, int layer);
-
- /**
* Create a view on a texture to be used by a shader stage.
*/
struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx,
@@ -407,6 +390,11 @@ struct pipe_context {
struct pipe_resource *,
unsigned offset,
unsigned size);
+
+ /**
+ * Flush any pending framebuffer writes and invalidate texture caches.
+ */
+ void (*texture_barrier)(struct pipe_context *);
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 8cf738fa2c0..e9d47983e1b 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -337,25 +337,6 @@ enum pipe_transfer_usage {
#define PIPE_USAGE_STAGING 5 /* supports data transfers from the GPU to the CPU */
-/* These are intended to be used in calls to is_format_supported, but
- * no driver actually uses these flags, and only the glx/xlib state
- * tracker issues them.
- *
- * Deprecate?
- */
-#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1
-#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2
-
-
-/**
- * Flush types:
- */
-#define PIPE_FLUSH_RENDER_CACHE 0x1
-#define PIPE_FLUSH_TEXTURE_CACHE 0x2
-#define PIPE_FLUSH_SWAPBUFFERS 0x4
-#define PIPE_FLUSH_FRAME 0x8 /**< Mark the end of a frame */
-
-
/**
* Shaders
*/
@@ -426,6 +407,8 @@ enum pipe_transfer_usage {
#define PIPE_SWIZZLE_ONE 5
+#define PIPE_TIMEOUT_INFINITE 0xffffffffffffffffull
+
/**
* Implementation capabilities/limits which are queried through
* pipe_screen::get_param() and pipe_screen::get_paramf().
@@ -478,7 +461,8 @@ enum pipe_cap {
PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER,
PIPE_CAP_DEPTH_CLAMP,
PIPE_CAP_SHADER_STENCIL_EXPORT,
- PIPE_CAP_INSTANCED_DRAWING,
+ PIPE_CAP_TGSI_INSTANCEID,
+ PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR,
};
/* Shader caps not specific to any single stage */
@@ -504,13 +488,6 @@ enum pipe_shader_cap
PIPE_SHADER_CAP_SUBROUTINES, /* BGNSUB, ENDSUB, CAL, RET */
};
-/**
- * Referenced query flags.
- */
-
-#define PIPE_UNREFERENCED 0
-#define PIPE_REFERENCED_FOR_READ (1 << 0)
-#define PIPE_REFERENCED_FOR_WRITE (1 << 1)
enum pipe_video_codec
{
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index e2cc32222de..f3b1e5561cf 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -218,6 +218,11 @@ enum pipe_format {
PIPE_FORMAT_A16_UNORM = 148,
PIPE_FORMAT_I16_UNORM = 149,
+ PIPE_FORMAT_LATC1_UNORM = 143,
+ PIPE_FORMAT_LATC1_SNORM = 144,
+ PIPE_FORMAT_LATC2_UNORM = 145,
+ PIPE_FORMAT_LATC2_SNORM = 146,
+
PIPE_FORMAT_COUNT
};
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 2a6acecb726..0d1b1094550 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -104,14 +104,12 @@ struct pipe_screen {
* Check if the given pipe_format is supported as a texture or
* drawing surface.
* \param bindings bitmask of PIPE_BIND_*
- * \param geom_flags bitmask of PIPE_TEXTURE_GEOM_*
*/
boolean (*is_format_supported)( struct pipe_screen *,
enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bindings,
- unsigned geom_flags );
+ unsigned bindings );
/**
* Create a new texture object, using the given template info.
@@ -188,21 +186,17 @@ struct pipe_screen {
/**
* Checks whether the fence has been signalled.
- * \param flags driver-specific meaning
- * \return zero on success.
*/
- int (*fence_signalled)( struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags );
+ boolean (*fence_signalled)( struct pipe_screen *screen,
+ struct pipe_fence_handle *fence );
/**
* Wait for the fence to finish.
- * \param flags driver-specific meaning
- * \return zero on success.
+ * \param timeout in nanoseconds
*/
- int (*fence_finish)( struct pipe_screen *screen,
- struct pipe_fence_handle *fence,
- unsigned flags );
+ boolean (*fence_finish)( struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ uint64_t timeout );
};
diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h
index 73f03d58ea6..2d59741ec18 100644
--- a/src/gallium/include/pipe/p_video_context.h
+++ b/src/gallium/include/pipe/p_video_context.h
@@ -69,8 +69,7 @@ struct pipe_video_context
*/
boolean (*is_format_supported)(struct pipe_video_context *vpipe,
enum pipe_format format,
- unsigned usage,
- unsigned geom);
+ unsigned usage);
void (*destroy)(struct pipe_video_context *vpipe);
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index 1c2148b78f2..d4973a10cc7 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -121,6 +121,11 @@ enum st_context_resource_type {
};
/**
+ * Flush flags.
+ */
+#define ST_FLUSH_FRONT (1 << 0)
+
+/**
* Value to st_manager->get_param function.
*/
enum st_manager_param {
diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
index 2e45f3f43e9..741a97f897d 100644
--- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
+++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
@@ -1234,7 +1234,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX
if(dst_surface)
pipe->surface_destroy(pipe, dst_surface);
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0);
+ pipe->flush(pipe, 0);
att = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT;
if(!surface->present(surface, att, FALSE, 0))
diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
index 542d6591293..12f2aaddc91 100644
--- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
+++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h
@@ -1823,7 +1823,7 @@ changed:
virtual void STDMETHODCALLTYPE Flush(void)
{
SYNCHRONIZED;
- pipe->flush(pipe, PIPE_FLUSH_FRAME, 0);
+ pipe->flush(pipe, 0);
}
/* In Direct3D 10, if the reference count of an object drops to 0, it is automatically
diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
index 9cfdc837d8e..f678ac7f733 100644
--- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
+++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h
@@ -299,25 +299,25 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen
sampler_view |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON;
/* TODO: do this properly when Gallium drivers actually support index/vertex format queries */
- if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER, 0)
- || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER, 0)
+ if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER)
+ || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER)
|| format == PIPE_FORMAT_R8_UNORM))
support |= buffer;
- if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT, 0))
+ if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT))
support |= buffer | D3D11_FORMAT_SUPPORT_SO_BUFFER;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW))
support |= D3D11_FORMAT_SUPPORT_TEXTURE1D | sampler_view;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW))
support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW))
support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW))
support |= D3D11_FORMAT_SUPPORT_TEXTURE3D | sampler_view;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL))
support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL;
- if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET, 0))
+ if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET))
support |= D3D11_FORMAT_SUPPORT_DISPLAY;
format_support[format] = support;
}
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index fc68ee13eaa..e23c1bcafaf 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -149,7 +149,7 @@ dri_unbind_context(__DRIcontext * cPriv)
if (--ctx->bind_count == 0) {
if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
- ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
stapi->make_current(stapi, NULL, NULL, NULL);
draw->context = NULL;
read->context = NULL;
@@ -171,7 +171,7 @@ dri_make_current(__DRIcontext * cPriv,
struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
if (old_st && old_st != ctx->st)
- old_st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ old_st->flush(old_st, ST_FLUSH_FRONT, NULL);
++ctx->bind_count;
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 69c2e7e9ec8..5931df993b0 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -81,34 +81,34 @@ dri_fill_in_modes(struct dri_screen *screen,
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
if (dri_with_format(screen->sPriv)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
} else {
pf_z16 = FALSE;
pf_z32 = FALSE;
@@ -142,7 +142,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
@@ -161,7 +161,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
@@ -183,7 +183,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index a5c94b4166b..30326a23d6c 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -270,7 +270,7 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
struct pipe_resource templ;
enum st_attachment_type statt;
enum pipe_format pf;
- unsigned bind;
+ unsigned bind = 0;
struct winsys_handle whandle;
switch (attachment) {
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index 30088b09685..ac11f7c47f6 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -139,7 +139,7 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
- ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
drisw_copy_to_front(dPriv, ptex);
}
@@ -233,6 +233,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
*/
static const __DRIextension *drisw_screen_extensions[] = {
+ &driTexBufferExtension.base,
NULL
};
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index e60a56074dd..2c7f3bde4f0 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -368,7 +368,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
/* pick the first supported format */
for (i = 0; i < n; i++) {
if (screen->is_format_supported(screen, fmt[i],
- PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) {
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
formats[count++] = fmt[i];
break;
}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 2068256dff2..f1568329ecf 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -528,8 +528,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
old_gctx = egl_g3d_context(old_ctx);
if (old_gctx) {
/* flush old context */
- old_gctx->stctxi->flush(old_gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ old_gctx->stctxi->flush(old_gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
if (gctx) {
@@ -606,8 +605,7 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
/* flush if the surface is current */
if (gctx) {
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
return gsurf->native->present(gsurf->native,
@@ -652,8 +650,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
/* flush if the surface is current */
if (ctx && ctx->DrawSurface == &gsurf->base) {
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
pipe = ndpy_get_copy_context(gdpy->native);
@@ -667,7 +664,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0,
gsurf->render_texture, 0, &src_box);
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ pipe->flush(pipe, NULL);
nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
pipe_resource_reference(&ptex, NULL);
@@ -686,10 +683,9 @@ egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_fence_handle *fence = NULL;
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, &fence);
if (fence) {
- screen->fence_finish(screen, fence, 0);
+ screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
}
@@ -758,8 +754,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
- gctx->stctxi->flush(gctx->stctxi,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
gctx = egl_g3d_context(es1);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
index 4e6d944c151..dd07af140a7 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
@@ -109,7 +109,7 @@ egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
_eglUnlockMutex(&dpy->Mutex);
/* no timed finish? */
- screen->fence_finish(screen, fence, 0x0);
+ screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
ret = EGL_CONDITION_SATISFIED_KHR;
_eglLockMutex(&dpy->Mutex);
@@ -234,7 +234,7 @@ egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
if (gctx)
- gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL);
+ gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
if (timeout) {
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index be6713d03a8..ee18cb2025b 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -333,7 +333,7 @@ resource_surface_throttle(struct resource_surface *rsurf)
struct pipe_fence_handle *fence = swap_fences_pop_front(rsurf);
if (fence) {
- (void) screen->fence_finish(screen, fence, 0);
+ (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
screen->fence_reference(screen, &fence, NULL);
return TRUE;
}
@@ -352,7 +352,7 @@ resource_surface_flush(struct resource_surface *rsurf,
if (!pipe)
return FALSE;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &fence);
+ pipe->flush(pipe, &fence);
if (fence == NULL)
return FALSE;
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index cdbb304c5ee..9863329ff40 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -43,7 +43,7 @@ drm_display_is_format_supported(struct native_display *ndpy,
return ndpy->screen->is_format_supported(ndpy->screen,
fmt, PIPE_TEXTURE_2D, 0,
(is_color) ? PIPE_BIND_RENDER_TARGET :
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
}
static const struct native_config **
diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
index 4a96039ac39..e2fde00e975 100644
--- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
+++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
@@ -422,7 +422,7 @@ fbdev_display_init(struct native_display *ndpy)
if (fbdpy->base.screen) {
if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
fbdpy->base.screen->destroy(fbdpy->base.screen);
fbdpy->base.screen = NULL;
}
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
index 3c2475f84d8..5d0045f92ee 100644
--- a/src/gallium/state_trackers/egl/gdi/native_gdi.c
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -285,7 +285,7 @@ fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8])
for (i = 0; i < Elements(candidates); i++) {
if (screen->is_format_supported(screen, candidates[i],
- PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET))
formats[count++] = candidates[i];
}
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index b18c3132c57..5afca67a4d4 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -541,7 +541,7 @@ is_format_supported(struct pipe_screen *screen,
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count,
(is_color) ? PIPE_BIND_RENDER_TARGET :
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
}
static boolean
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 205a7e3c19a..351267bae4d 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -1367,8 +1367,8 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable )
/*** GLX_MESA_copy_sub_buffer ***/
PUBLIC void
-glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
- int x, int y, int width, int height )
+glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
+ int x, int y, int width, int height)
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
if (buffer) {
@@ -1718,8 +1718,8 @@ glXGetClientString( Display *dpy, int name )
PUBLIC int
-glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
- int attribute, int *value )
+glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
+ int attribute, int *value)
{
XMesaVisual v = (XMesaVisual) config;
(void) dpy;
@@ -1763,8 +1763,8 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
PUBLIC GLXFBConfig *
-glXChooseFBConfig( Display *dpy, int screen,
- const int *attribList, int *nitems )
+glXChooseFBConfig(Display *dpy, int screen,
+ const int *attribList, int *nitems)
{
XMesaVisual xmvis;
@@ -1814,8 +1814,8 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
PUBLIC GLXWindow
-glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
- const int *attribList )
+glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
+ const int *attribList)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf;
@@ -1845,8 +1845,8 @@ glXDestroyWindow( Display *dpy, GLXWindow window )
/* XXX untested */
PUBLIC GLXPixmap
-glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
- const int *attribList )
+glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
+ const int *attribList)
{
XMesaVisual v = (XMesaVisual) config;
XMesaBuffer b;
@@ -1965,8 +1965,7 @@ glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
PUBLIC GLXPbuffer
-glXCreatePbuffer( Display *dpy, GLXFBConfig config,
- const int *attribList )
+glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf;
@@ -2038,8 +2037,8 @@ glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
PUBLIC void
-glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
- unsigned int *value )
+glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
+ unsigned int *value)
{
GLuint width, height;
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
@@ -2085,7 +2084,7 @@ glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
PUBLIC GLXContext
glXCreateNewContext( Display *dpy, GLXFBConfig config,
- int renderType, GLXContext shareList, Bool direct )
+ int renderType, GLXContext shareList, Bool direct )
{
GLXContext glxCtx;
GLXContext shareCtx = shareList;
@@ -2156,8 +2155,7 @@ glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
PUBLIC void
-glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
- unsigned long *mask )
+glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf)
@@ -2209,7 +2207,8 @@ glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
/*** GLX_SGI_make_current_read ***/
PUBLIC Bool
-glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
+ GLXContext ctx)
{
return glXMakeContextCurrent( dpy, draw, read, ctx );
}
@@ -2227,7 +2226,8 @@ glXGetCurrentReadDrawableSGI(void)
#if defined(_VL_H)
PUBLIC GLXVideoSourceSGIX
-glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
+glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
+ VLPath path, int nodeClass, VLNode drainNode)
{
(void) dpy;
(void) screen;
@@ -2273,7 +2273,8 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
}
PUBLIC int
-glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
+glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
+ int *value)
{
(void) dpy;
(void) context;
@@ -2287,20 +2288,24 @@ glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *val
/*** GLX_SGIX_fbconfig ***/
PUBLIC int
-glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
+glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
+ int attribute, int *value)
{
return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
PUBLIC GLXFBConfigSGIX *
-glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
+glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
+ int *nelements)
{
- return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
+ return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
+ attrib_list, nelements);
}
PUBLIC GLXPixmap
-glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
+glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+ Pixmap pixmap)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
@@ -2309,7 +2314,9 @@ glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pi
PUBLIC GLXContext
-glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
+glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+ int render_type, GLXContext share_list,
+ Bool direct)
{
XMesaVisual xmvis = (XMesaVisual) config;
GLXContext glxCtx;
@@ -2362,8 +2369,8 @@ glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
PUBLIC GLXPbufferSGIX
glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
- unsigned int width, unsigned int height,
- int *attribList)
+ unsigned int width, unsigned int height,
+ int *attribList)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf;
@@ -2410,7 +2417,8 @@ glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
PUBLIC int
-glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
+glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
+ unsigned int *value)
{
const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2454,7 +2462,8 @@ glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
PUBLIC void
-glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
+ unsigned long *mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf) {
@@ -2482,7 +2491,8 @@ glXCushionSGI(Display *dpy, Window win, float cushion)
/*** GLX_SGIX_video_resize ***/
PUBLIC int
-glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
+glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
+ Window window)
{
(void) dpy;
(void) screen;
@@ -2492,7 +2502,8 @@ glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window
}
PUBLIC int
-glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
+glXChannelRectSGIX(Display *dpy, int screen, int channel,
+ int x, int y, int w, int h)
{
(void) dpy;
(void) screen;
@@ -2505,7 +2516,8 @@ glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, i
}
PUBLIC int
-glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
+glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
+ int *x, int *y, int *w, int *h)
{
(void) dpy;
(void) screen;
@@ -2518,7 +2530,8 @@ glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, i
}
PUBLIC int
-glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
+glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
+ int *dx, int *dy, int *dw, int *dh)
{
(void) dpy;
(void) screen;
@@ -2546,7 +2559,8 @@ glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
#if defined(_DM_BUFFER_H_)
PUBLIC Bool
-glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
+glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
+ DMparams *params, DMbuffer dmbuffer)
{
(void) dpy;
(void) pbuffer;
@@ -2593,7 +2607,8 @@ glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
/*** GLX_SUN_get_transparent_index ***/
PUBLIC Status
-glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
+glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
+ long *pTransparent)
{
(void) dpy;
(void) overlay;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 7c47a25ceba..3b35cbc890c 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -376,8 +376,6 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_BIND_DEPTH_STENCIL;
- const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
- PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
const unsigned sample_count = 0;
enum pipe_format formats[8], fmt;
int count, i;
@@ -403,7 +401,7 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
for (i = 0; i < count; i++) {
if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
target, sample_count,
- tex_usage, geom_flags)) {
+ tex_usage)) {
fmt = formats[i];
break;
}
@@ -1195,11 +1193,7 @@ void XMesaSwapBuffers( XMesaBuffer b )
XMesaContext xmctx = XMesaGetCurrentContext();
if (xmctx && xmctx->xm_buffer == b) {
- xmctx->st->flush( xmctx->st,
- PIPE_FLUSH_RENDER_CACHE |
- PIPE_FLUSH_SWAPBUFFERS |
- PIPE_FLUSH_FRAME,
- NULL);
+ xmctx->st->flush( xmctx->st, ST_FLUSH_FRONT, NULL);
}
xmesa_swap_st_framebuffer(b->stfb);
@@ -1225,9 +1219,10 @@ void XMesaFlush( XMesaContext c )
XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
struct pipe_fence_handle *fence = NULL;
- c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ c->st->flush(c->st, ST_FLUSH_FRONT, &fence);
if (fence) {
- xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
+ xmdpy->screen->fence_finish(xmdpy->screen, fence,
+ PIPE_TIMEOUT_INFINITE);
xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
}
XFlush( c->xm_visual->display );
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index b30050bf6d4..17d25ad0aa6 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -400,10 +400,10 @@ error1:
void
flush(unsigned flags = 0) {
struct pipe_fence_handle *fence = NULL;
- $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence);
+ $self->pipe->flush($self->pipe, &fence);
if(fence) {
/* TODO: allow asynchronous operation */
- $self->pipe->screen->fence_finish( $self->pipe->screen, fence, 0 );
+ $self->pipe->screen->fence_finish( $self->pipe->screen, fence, PIPE_TIMEOUT_INFINITE );
$self->pipe->screen->fence_reference( $self->pipe->screen, &fence, NULL );
}
}
diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i
index cc67da937cd..61f6b3bb739 100644
--- a/src/gallium/state_trackers/python/p_device.i
+++ b/src/gallium/state_trackers/python/p_device.i
@@ -86,8 +86,7 @@ struct st_device {
int is_format_supported( enum pipe_format format,
enum pipe_texture_target target,
unsigned sample_count,
- unsigned bind,
- unsigned geom_flags ) {
+ unsigned bind ) {
/* We can't really display surfaces with the python statetracker so mask
* out that usage */
bind &= ~PIPE_BIND_DISPLAY_TARGET;
@@ -96,8 +95,7 @@ struct st_device {
format,
target,
sample_count,
- bind,
- geom_flags );
+ bind );
}
struct st_context *
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
index 8bc54d7fc7d..048cfe819f0 100644
--- a/src/gallium/state_trackers/vdpau/decode.c
+++ b/src/gallium/state_trackers/vdpau/decode.c
@@ -134,24 +134,15 @@ vlVdpCreateSurfaceTarget(vlVdpDecoder *vldecoder, vlVdpSurface *vlsurf)
vctx = vldecoder->vctx->vpipe;
+ if (!vctx->is_format_supported(vctx, tmplt.format, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
+ return VDP_STATUS_RESOURCES;
+
memset(&tmplt, 0, sizeof(struct pipe_resource));
tmplt.target = PIPE_TEXTURE_2D;
tmplt.format = vctx->get_param(vctx,PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
tmplt.last_level = 0;
-
- if (vctx->is_format_supported(vctx, tmplt.format,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
- PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
- tmplt.width0 = vlsurf->width;
- tmplt.height0 = vlsurf->height;
- } else {
- assert(vctx->is_format_supported(vctx, tmplt.format,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
- PIPE_TEXTURE_GEOM_NON_SQUARE));
- tmplt.width0 = util_next_power_of_two(vlsurf->width);
- tmplt.height0 = util_next_power_of_two(vlsurf->height);
- }
-
+ tmplt.width0 = vlsurf->width;
+ tmplt.height0 = vlsurf->height;
tmplt.depth0 = 1;
tmplt.usage = PIPE_USAGE_DEFAULT;
tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c
index 74a3bd925cf..e971b6dc02e 100644
--- a/src/gallium/state_trackers/vdpau/query.c
+++ b/src/gallium/state_trackers/vdpau/query.c
@@ -123,8 +123,7 @@ vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaTyp
FormatToPipe(bits_ycbcr_format),
PIPE_TEXTURE_2D,
1,
- PIPE_BIND_RENDER_TARGET,
- PIPE_TEXTURE_GEOM_NON_SQUARE);
+ PIPE_BIND_RENDER_TARGET);
vl_screen_destroy(vlscreen);
diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c
index d6bbda5e075..19e42dd1562 100644
--- a/src/gallium/state_trackers/vega/api_context.c
+++ b/src/gallium/state_trackers/vega/api_context.c
@@ -56,7 +56,7 @@ void vegaFlush(void)
return;
pipe = ctx->pipe;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ pipe->flush(pipe, NULL);
vg_manager_flush_frontbuffer(ctx);
}
@@ -72,9 +72,10 @@ void vegaFinish(void)
pipe = ctx->pipe;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ pipe->flush(pipe, &fence);
if (fence) {
- pipe->screen->fence_finish(pipe->screen, fence, 0);
+ pipe->screen->fence_finish(pipe->screen, fence,
+ PIPE_TIMEOUT_INFINITE);
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
}
}
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c
index b993ba62c26..2cb5622f817 100644
--- a/src/gallium/state_trackers/vega/api_images.c
+++ b/src/gallium/state_trackers/vega/api_images.c
@@ -356,7 +356,6 @@ void vegaWritePixels(const void * data, VGint dataStride,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_context *pipe = ctx->pipe;
if (!supported_image_format(dataFormat)) {
vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR);
@@ -387,8 +386,6 @@ void vegaWritePixels(const void * data, VGint dataStride,
#endif
image_destroy(img);
}
- /* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
}
void vegaReadPixels(void * data, VGint dataStride,
@@ -421,8 +418,6 @@ void vegaReadPixels(void * data, VGint dataStride,
return;
}
- /* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
if (sx < 0) {
xoffset = -sx;
xoffset *= _vega_size_for_format(dataFormat);
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 73351b671f9..44480876b6e 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -257,7 +257,7 @@ struct vg_image * image_create(VGImageFormat format,
image->sampler.normalized_coords = 1;
assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_SAMPLER_VIEW, 0));
+ 0, PIPE_BIND_SAMPLER_VIEW));
memset(&pt, 0, sizeof(pt));
pt.target = PIPE_TEXTURE_2D;
@@ -518,8 +518,6 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR);
return;
}
- /* make sure rendering has completed */
- ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
src->sampler_view, src->x + sx, src->y + sy, width, height);
}
@@ -569,9 +567,6 @@ void image_set_pixels(VGint dx, VGint dy,
struct pipe_surface *surf, surf_tmpl;
struct st_renderbuffer *strb = ctx->draw_buffer->strb;
- /* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
u_surface_default_template(&surf_tmpl, image_texture(src),
0 /* no bind flag - not a surface*/);
@@ -595,9 +590,6 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
/* flip the y coordinates */
/*dy = dst->height - dy - height;*/
- /* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
u_surface_default_template(&surf_tmpl, image_texture(dst),
PIPE_BIND_RENDER_TARGET);
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index dfd0600e444..10590e29cd2 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -111,8 +111,6 @@ static void read_alpha_mask(void * data, VGint dataStride,
VGubyte *dst = (VGubyte *)data;
VGint xoffset = 0, yoffset = 0;
- /* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
if (sx < 0) {
xoffset = -sx;
xoffset *= _vega_size_for_format(dataFormat);
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 9de2cb1014d..5715073e2d9 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -140,7 +140,7 @@ static VGboolean renderer_can_support(struct renderer *renderer,
struct pipe_screen *screen = renderer->pipe->screen;
return screen->is_format_supported(screen,
- res->format, res->target, 0, bindings, 0);
+ res->format, res->target, 0, bindings);
}
/**
@@ -1463,11 +1463,11 @@ void renderer_copy_surface(struct renderer *ctx,
}
assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_SAMPLER_VIEW, 0));
+ 0, PIPE_BIND_SAMPLER_VIEW));
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_SAMPLER_VIEW, 0));
+ 0, PIPE_BIND_SAMPLER_VIEW));
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_RENDER_TARGET, 0));
+ 0, PIPE_BIND_RENDER_TARGET));
/*
* XXX for now we're always creating a temporary texture.
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 83b42609e03..c2ab56455b1 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -69,7 +69,7 @@ choose_depth_stencil_format(struct vg_context *ctx)
for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) {
if (screen->is_format_supported(screen, *fmt,
- PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL))
break;
}
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index 44d2996bb45..eeea68677de 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -142,8 +142,8 @@ vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
struct pipe_fence_handle **fence)
{
struct vg_context *ctx = (struct vg_context *) stctxi;
- ctx->pipe->flush(ctx->pipe, flags, fence);
- if (flags & PIPE_FLUSH_RENDER_CACHE)
+ ctx->pipe->flush(ctx->pipe, fence);
+ if (flags & ST_FLUSH_FRONT)
vg_manager_flush_frontbuffer(ctx);
}
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index cd4f3c8b3e2..5608d4f4ce7 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -277,7 +277,7 @@ stw_make_current(
return TRUE;
}
} else {
- curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL);
}
}
@@ -351,11 +351,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb )
struct stw_context *ctx = stw_current_context();
if (ctx && ctx->current_framebuffer == fb) {
- ctx->st->flush(ctx->st,
- PIPE_FLUSH_RENDER_CACHE |
- PIPE_FLUSH_SWAPBUFFERS |
- PIPE_FLUSH_FRAME,
- NULL);
+ ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
}
}
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 4ece4e4979a..e65e71dc15f 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -41,8 +41,6 @@
#include "stw_framebuffer.h"
#include "stw_st.h"
-extern _glthread_Mutex OneTimeLock;
-
struct stw_device *stw_dev = NULL;
@@ -50,7 +48,19 @@ static int
stw_get_param(struct st_manager *smapi,
enum st_manager_param param)
{
- return 0;
+ switch (param) {
+ case ST_MANAGER_BROKEN_INVALIDATE:
+ /*
+ * Force framebuffer validation on glViewport.
+ *
+ * Certain applications, like Rhinoceros 4, uses glReadPixels
+ * exclusively (never uses SwapBuffers), so framebuffers never get
+ * resized unless we check on glViewport.
+ */
+ return 1;
+ default:
+ return 0;
+ }
}
boolean
@@ -74,8 +84,6 @@ stw_init(const struct stw_winsys *stw_winsys)
stw_dev->stw_winsys = stw_winsys;
- _glthread_INIT_MUTEX(OneTimeLock);
-
stw_dev->stapi = stw_st_create_api();
stw_dev->smapi = CALLOC_STRUCT(st_manager);
if (!stw_dev->stapi || !stw_dev->smapi)
@@ -168,8 +176,6 @@ stw_cleanup(void)
stw_dev->screen->destroy(stw_dev->screen);
- _glthread_DESTROY_MUTEX(OneTimeLock);
-
/* glapi is statically linked: we can call the local destroy function. */
#ifdef _GLAPI_NO_EXPORTS
_glapi_destroy_multithread();
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 5ede1d43220..333f50c25f6 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -225,7 +225,7 @@ stw_pixelformat_init( void )
if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D,
0, PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET, 0))
+ PIPE_BIND_DISPLAY_TARGET))
continue;
for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) {
@@ -235,7 +235,7 @@ stw_pixelformat_init( void )
const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l];
if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D,
- 0, PIPE_BIND_DEPTH_STENCIL, 0))
+ 0, PIPE_BIND_DEPTH_STENCIL))
continue;
stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples );
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 17c34b7eac8..6f2c52eabb6 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -336,7 +336,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
/* pixmap glXWaitX */
if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL);
+ ms->ctx->flush(ms->ctx, NULL);
return;
}
/* pixmap glXWaitGL */
@@ -362,7 +362,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
if (extents->x1 == 0 && extents->y1 == 0 &&
extents->x2 == pDraw->width && extents->y2 == pDraw->height) {
- ms->screen->fence_finish(ms->screen, dst_priv->fence, 0);
+ ms->screen->fence_finish(ms->screen, dst_priv->fence,
+ PIPE_TIMEOUT_INFINITE);
ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL);
}
}
@@ -388,7 +389,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
FreeScratchGC(gc);
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
+ ms->ctx->flush(ms->ctx,
(pDestBuffer->attachment == DRI2BufferFrontLeft
&& ms->swapThrottling) ?
&dst_priv->fence : NULL);
@@ -451,12 +452,12 @@ xorg_dri2_init(ScreenPtr pScreen)
ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM,
PIPE_TEXTURE_2D,
0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
ms->ds_depth_bits_last =
ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_TEXTURE_2D,
0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
return DRI2ScreenInit(pScreen, &dri2info);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 33bcacdcc2e..19e9bf84656 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -334,7 +334,8 @@ drv_cleanup_fences(ScrnInfoPtr pScrn)
for (i = 0; i < XORG_NR_FENCES; i++) {
if (ms->fence[i]) {
- ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
+ ms->screen->fence_finish(ms->screen, ms->fence[i],
+ PIPE_TIMEOUT_INFINITE);
ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
}
}
@@ -547,7 +548,7 @@ void xorg_flush(ScreenPtr pScreen)
if (ms->ctx) {
int j;
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+ ms->ctx->flush(ms->ctx,
ms->dirtyThrottling ?
&ms->fence[XORG_NR_FENCES-1] :
NULL);
@@ -555,7 +556,8 @@ void xorg_flush(ScreenPtr pScreen)
if (ms->dirtyThrottling) {
if (ms->fence[0])
ms->ctx->screen->fence_finish(ms->ctx->screen,
- ms->fence[0], 0);
+ ms->fence[0],
+ PIPE_TIMEOUT_INFINITE);
/* The amount of rendering generated by a block handler can be
* quite small. Let us get a fair way ahead of hardware before
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 718a3453939..e7d6a93e5ca 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -349,7 +349,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
priv->tex->target, 0,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
XORG_FALLBACK("format %s", util_format_name(priv->tex->format));
}
@@ -430,12 +430,12 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
priv->tex->target, 0,
- PIPE_BIND_RENDER_TARGET, 0))
+ PIPE_BIND_RENDER_TARGET))
XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format));
if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format,
src_priv->tex->target, 0,
- PIPE_BIND_SAMPLER_VIEW, 0))
+ PIPE_BIND_SAMPLER_VIEW))
XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format));
exa->copy.src = src_priv;
@@ -630,7 +630,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
priv->tex->target, 0,
- PIPE_BIND_RENDER_TARGET, 0))
+ PIPE_BIND_RENDER_TARGET))
XORG_FALLBACK("pDst format: %s", util_format_name(priv->tex->format));
if (priv->picture_format != pDstPicture->format)
@@ -645,7 +645,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
priv->tex->target, 0,
- PIPE_BIND_SAMPLER_VIEW, 0))
+ PIPE_BIND_SAMPLER_VIEW))
XORG_FALLBACK("pSrc format: %s", util_format_name(priv->tex->format));
if (!picture_check_formats(priv, pSrcPicture))
@@ -662,7 +662,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
priv->tex->target, 0,
- PIPE_BIND_SAMPLER_VIEW, 0))
+ PIPE_BIND_SAMPLER_VIEW))
XORG_FALLBACK("pMask format: %s", util_format_name(priv->tex->format));
if (!picture_check_formats(priv, pMaskPicture))
@@ -1072,19 +1072,20 @@ xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv)
}
-void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
+void xorg_exa_flush(struct exa_context *exa,
struct pipe_fence_handle **fence)
{
- exa->pipe->flush(exa->pipe, pipeFlushFlags, fence);
+ exa->pipe->flush(exa->pipe, fence);
}
void xorg_exa_finish(struct exa_context *exa)
{
struct pipe_fence_handle *fence = NULL;
- xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence);
+ xorg_exa_flush(exa, &fence);
- exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0);
+ exa->pipe->screen->fence_finish(exa->pipe->screen, fence,
+ PIPE_TIMEOUT_INFINITE);
exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 1f78f60be74..30b6f0ce460 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -74,7 +74,7 @@ do { \
struct pipe_surface *
xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv);
-void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
+void xorg_exa_flush(struct exa_context *exa,
struct pipe_fence_handle **fence);
void xorg_exa_finish(struct exa_context *exa);
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 3b3ae455c0b..6b799af90c8 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -450,8 +450,7 @@ void renderer_copy_prepare(struct xorg_renderer *r,
assert(screen->is_format_supported(screen, dst_surface->format,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET,
- 0));
+ PIPE_BIND_RENDER_TARGET));
(void) screen;
@@ -519,14 +518,10 @@ renderer_clone_texture(struct xorg_renderer *r,
struct pipe_resource *pt;
struct pipe_resource templ;
- if (pipe->is_resource_referenced(pipe, src, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
/* the coming in texture should already have that invariance */
debug_assert(screen->is_format_supported(screen, src->format,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_SAMPLER_VIEW, 0));
+ PIPE_BIND_SAMPLER_VIEW));
format = src->format;
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index c72ba9ef8db..234574b968e 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -461,20 +461,6 @@ bind_shaders(struct xorg_xv_port_priv *port)
cso_set_fragment_shader_handle(port->r->cso, shader.fs);
}
-static INLINE void
-conditional_flush(struct pipe_context *pipe, struct pipe_resource **tex,
- int num)
-{
- int i;
- for (i = 0; i < num; ++i) {
- if (tex[i] && pipe->is_resource_referenced(pipe, tex[i], 0, 0) &
- PIPE_REFERENCED_FOR_WRITE) {
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- return;
- }
- }
-}
-
static void
bind_samplers(struct xorg_xv_port_priv *port)
{
@@ -485,8 +471,6 @@ bind_samplers(struct xorg_xv_port_priv *port)
memset(&sampler, 0, sizeof(struct pipe_sampler_state));
- conditional_flush(port->r->pipe, dst, 3);
-
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index c90ad409c10..799dac2efc8 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -226,20 +226,14 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
memset(&template, 0, sizeof(struct pipe_resource));
template.target = PIPE_TEXTURE_2D;
template.format = (enum pipe_format)vpipe->get_param(vpipe, PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
- template.last_level = 0;
- if (vpipe->is_format_supported(vpipe, template.format,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
- PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
- template.width0 = context->width;
- template.height0 = context->height;
- }
- else {
- assert(vpipe->is_format_supported(vpipe, template.format,
- PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
- PIPE_TEXTURE_GEOM_NON_SQUARE));
- template.width0 = util_next_power_of_two(context->width);
- template.height0 = util_next_power_of_two(context->height);
+ if (!vpipe->is_format_supported(vpipe, template.format,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) {
+ FREE(surface_priv);
+ return BadAlloc;
}
+ template.last_level = 0;
+ template.width0 = util_next_power_of_two(context->width);
+ template.height0 = util_next_power_of_two(context->height);
template.depth0 = 1;
template.array_size = 1;
template.usage = PIPE_USAGE_DEFAULT;
diff --git a/src/gallium/targets/graw-gdi/graw_gdi.c b/src/gallium/targets/graw-gdi/graw_gdi.c
index 17ca2a761ca..99d8641d6b1 100644
--- a/src/gallium/targets/graw-gdi/graw_gdi.c
+++ b/src/gallium/targets/graw-gdi/graw_gdi.c
@@ -66,7 +66,7 @@ graw_create_window_and_screen(int x,
{
struct sw_winsys *winsys = NULL;
struct pipe_screen *screen = NULL;
- WNDCLASSEX wc = {sizeof(wc)};
+ WNDCLASSEX wc;
UINT style = WS_VISIBLE | WS_TILEDWINDOW;
RECT rect;
HWND hWnd = NULL;
@@ -83,6 +83,8 @@ graw_create_window_and_screen(int x,
if (screen == NULL)
goto fail;
+ memset(&wc, 0, sizeof wc);
+ wc.cbSize = sizeof wc;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = window_proc;
wc.lpszClassName = "graw-gdi";
diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript
index 565fa5279cd..ad44d54c855 100644
--- a/src/gallium/tests/graw/SConscript
+++ b/src/gallium/tests/graw/SConscript
@@ -8,7 +8,7 @@ env.Prepend(LIBPATH = [graw.dir])
env.Prepend(LIBS = ['graw'])
-if env['platform'] in ('freebsd8', 'sunos5'):
+if env['platform'] in ('freebsd8', 'sunos'):
env.Append(LIBS = ['m'])
if env['platform'] == 'freebsd8':
diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c
index 55cc0087a09..392d1503f19 100644
--- a/src/gallium/tests/graw/clear.c
+++ b/src/gallium/tests/graw/clear.c
@@ -29,7 +29,7 @@ static void draw( void )
float clear_color[4] = {1,0,1,1};
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c
index ff82b607110..fda23bd7c9f 100644
--- a/src/gallium/tests/graw/fs-test.c
+++ b/src/gallium/tests/graw/fs-test.c
@@ -276,7 +276,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c
index cc05889dd05..ebb26d2f3f4 100644
--- a/src/gallium/tests/graw/gs-test.c
+++ b/src/gallium/tests/graw/gs-test.c
@@ -339,7 +339,7 @@ static void draw( void )
else
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c
index 3c6458b434e..6903046cf0e 100644
--- a/src/gallium/tests/graw/quad-sample.c
+++ b/src/gallium/tests/graw/quad-sample.c
@@ -150,7 +150,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c
index 4e66813b301..fd01cb3f84f 100644
--- a/src/gallium/tests/graw/quad-tex.c
+++ b/src/gallium/tests/graw/quad-tex.c
@@ -147,7 +147,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c
index a23ca73ac1d..004b1691b6b 100644
--- a/src/gallium/tests/graw/shader-leak.c
+++ b/src/gallium/tests/graw/shader-leak.c
@@ -149,7 +149,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
ctx->bind_fs_state(ctx, NULL);
ctx->delete_fs_state(ctx, fs);
diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c
index 47b76530c6b..ab0116bed73 100644
--- a/src/gallium/tests/graw/tri-gs.c
+++ b/src/gallium/tests/graw/tri-gs.c
@@ -163,7 +163,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
screen->flush_frontbuffer(screen, tex, 0, 0, window);
}
diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c
index 259b3d9527c..bed34374666 100644
--- a/src/gallium/tests/graw/tri-instanced.c
+++ b/src/gallium/tests/graw/tri-instanced.c
@@ -211,7 +211,7 @@ static void draw( void )
ctx->draw_vbo(ctx, &info);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c
index 4266c0394d8..30ead999a47 100644
--- a/src/gallium/tests/graw/tri.c
+++ b/src/gallium/tests/graw/tri.c
@@ -140,7 +140,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3);
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c
index dd64d8b9301..18e056dcb35 100644
--- a/src/gallium/tests/graw/vs-test.c
+++ b/src/gallium/tests/graw/vs-test.c
@@ -227,7 +227,7 @@ static void draw( void )
ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices));
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->flush(ctx, NULL);
graw_save_surface_to_file(ctx, surf, NULL);
diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c
index af93e09d8d4..3a64b1c8d96 100644
--- a/src/gallium/tests/trivial/quad-tex.c
+++ b/src/gallium/tests/trivial/quad-tex.c
@@ -335,7 +335,7 @@ static void draw(struct program *p)
4, /* verts */
2); /* attribs/vert */
- p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ p->pipe->flush(p->pipe, NULL);
debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
}
diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c
index b89cfe0d989..bfd2f3ca9a3 100644
--- a/src/gallium/tests/trivial/tri.c
+++ b/src/gallium/tests/trivial/tri.c
@@ -264,7 +264,7 @@ static void draw(struct program *p)
3, /* verts */
2); /* attribs/vert */
- p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ p->pipe->flush(p->pipe, NULL);
debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]);
}
diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript
new file mode 100644
index 00000000000..49f28c03691
--- /dev/null
+++ b/src/gallium/tests/unit/SConscript
@@ -0,0 +1,33 @@
+Import('*')
+
+env = env.Clone()
+
+env.Prepend(LIBS = [gallium])
+
+if env['platform'] in ('freebsd8', 'sunos'):
+ env.Append(LIBS = ['m'])
+
+if env['platform'] == 'freebsd8':
+ env.Append(LIBS = ['pthread'])
+
+progs = [
+ 'pipe_barrier_test',
+ 'u_cache_test',
+ 'u_format_test',
+ 'u_format_compatible_test',
+ 'u_half_test',
+ 'translate_test'
+]
+
+for prog in progs:
+ prog = env.Program(
+ target = prog,
+ source = prog + '.c',
+ )
+
+ env.InstallProgram(prog)
+
+ # http://www.scons.org/wiki/UnitTests
+ test_alias = env.Alias('unit', [prog], prog[0].abspath)
+ AlwaysBuild(test_alias)
+
diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 06e8f6910f3..40d6ec4c625 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -133,7 +133,7 @@ void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, voi
return NULL;
}
if (ctx) {
- pctx->flush(pctx, 0, NULL);
+ pctx->flush(pctx, NULL);
}
}
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index cd0aa318be5..c081abb4dcd 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -363,9 +363,6 @@ struct radeon *radeon_decref(struct radeon *radeon)
if (radeon->bomgr)
r600_bomgr_destroy(radeon->bomgr);
- if (radeon->fd >= 0)
- drmClose(radeon->fd);
-
free(radeon);
return NULL;
}
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 6b3baa2c909..a7c21784e51 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -760,6 +760,17 @@ out_err:
return r;
}
+static void rv6xx_context_surface_base_update(struct r600_context *ctx,
+ unsigned base_update_flags)
+{
+ /* need to emit surface base update on rv6xx */
+ if ((ctx->radeon->family > CHIP_R600) &&
+ (ctx->radeon->family < CHIP_RV770)) {
+ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0);
+ ctx->pm4[ctx->pm4_cdwords++] = base_update_flags;
+ }
+}
+
void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
unsigned flush_mask, struct r600_bo *rbo)
{
@@ -991,6 +1002,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
unsigned ndwords = 9;
struct r600_block *dirty_block = NULL;
struct r600_block *next_block;
+ unsigned rv6xx_surface_base_update = 0;
if (draw->indices) {
ndwords = 13;
@@ -1013,10 +1025,14 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
for (int i = 0; i < 8; i++) {
if (cb[i]) {
ndwords += 7;
+ rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_COLOR(i);
}
}
- if (db)
+ if (db) {
ndwords += 7;
+ rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_DEPTH;
+ }
+ /* XXX also need to update SURFACE_BASE_UPDATE_STRMOUT when we support it */
/* queries need some special values */
if (ctx->num_query_running) {
@@ -1043,10 +1059,14 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw)
}
/* enough room to copy packet */
- LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty,list) {
+ LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty, list) {
r600_context_block_emit_dirty(ctx, dirty_block);
}
+ /* rv6xx surface base udpate */
+ if (rv6xx_surface_base_update)
+ rv6xx_context_surface_base_update(ctx, rv6xx_surface_base_update);
+
/* draw packet */
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type;
diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h
index cb12865ff01..80424818044 100644
--- a/src/gallium/winsys/r600/drm/r600d.h
+++ b/src/gallium/winsys/r600/drm/r600d.h
@@ -90,6 +90,9 @@
#define PKT3_SET_SAMPLER 0x6E
#define PKT3_SET_CTL_CONST 0x6F
#define PKT3_SURFACE_BASE_UPDATE 0x73
+#define SURFACE_BASE_UPDATE_DEPTH (1 << 0)
+#define SURFACE_BASE_UPDATE_COLOR(x) (2 << (x))
+#define SURFACE_BASE_UPDATE_STRMOUT(x) (0x200 << (x))
#define EVENT_TYPE_PS_PARTIAL_FLUSH 0x10
#define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index 3094337a3cd..9eb833454df 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -172,7 +172,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
/* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */
if (flags & PB_USAGE_DONTBLOCK) {
if (radeon_bo_is_referenced_by_cs(cs, bo)) {
- cs->flush_cs(cs->flush_data);
+ cs->flush_cs(cs->flush_data, R300_FLUSH_ASYNC);
return NULL;
}
@@ -181,7 +181,11 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf,
}
} else {
if (radeon_bo_is_referenced_by_cs(cs, bo)) {
- cs->flush_cs(cs->flush_data);
+ cs->flush_cs(cs->flush_data, 0);
+ } else {
+ /* Try to avoid busy-waiting in radeon_bo_wait. */
+ if (p_atomic_read(&bo->num_active_ioctls))
+ radeon_drm_cs_sync_flush(cs);
}
radeon_bo_wait((struct r300_winsys_bo*)bo);
@@ -406,8 +410,7 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf,
/* Tiling determines how DRM treats the buffer data.
* We must flush CS when changing it if the buffer is referenced. */
if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) {
- radeon_drm_cs_flush(rcs);
- radeon_drm_cs_sync_flush(rcs);
+ cs->flush_cs(cs->flush_data, 0);
}
while (p_atomic_read(&bo->num_active_ioctls)) {
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 9ee800f5950..951791a1727 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -355,10 +355,8 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
return NULL;
}
-void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs)
+void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs)
{
- struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
-
/* Wait for any pending ioctl to complete. */
if (cs->thread) {
pipe_thread_wait(cs->thread);
@@ -368,12 +366,12 @@ void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs)
DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE)
-void radeon_drm_cs_flush(struct r300_winsys_cs *rcs)
+static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags)
{
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
struct radeon_cs_context *tmp;
- radeon_drm_cs_sync_flush(rcs);
+ radeon_drm_cs_sync_flush(cs);
/* If the CS is not empty, emit it in a newly-spawned thread. */
if (cs->base.cdw) {
@@ -384,7 +382,8 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs)
for (i = 0; i < crelocs; i++)
p_atomic_inc(&cs->csc->relocs_bo[i]->num_active_ioctls);
- if (cs->ws->num_cpus > 1 && debug_get_option_thread()) {
+ if (cs->ws->num_cpus > 1 && debug_get_option_thread() &&
+ (flags & R300_FLUSH_ASYNC)) {
cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, cs->csc);
assert(cs->thread);
} else {
@@ -407,7 +406,7 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs)
static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs)
{
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
- radeon_drm_cs_sync_flush(rcs);
+ radeon_drm_cs_sync_flush(cs);
radeon_cs_context_cleanup(&cs->csc1);
radeon_cs_context_cleanup(&cs->csc2);
p_atomic_dec(&cs->ws->num_cs);
@@ -417,7 +416,8 @@ static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs)
}
static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs,
- void (*flush)(void *), void *user)
+ void (*flush)(void *ctx, unsigned flags),
+ void *user)
{
struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
cs->flush_cs = flush;
@@ -441,7 +441,6 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws)
ws->base.cs_validate = radeon_drm_cs_validate;
ws->base.cs_write_reloc = radeon_drm_cs_write_reloc;
ws->base.cs_flush = radeon_drm_cs_flush;
- ws->base.cs_sync_flush = radeon_drm_cs_sync_flush;
ws->base.cs_set_flush = radeon_drm_cs_set_flush;
ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced;
}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index 4cc97f37e09..dfaa161c318 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -70,7 +70,7 @@ struct radeon_drm_cs {
struct radeon_drm_winsys *ws;
/* Flush CS. */
- void (*flush_cs)(void *);
+ void (*flush_cs)(void *ctx, unsigned flags);
void *flush_data;
pipe_thread thread;
@@ -96,8 +96,7 @@ static INLINE boolean radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo)
return bo->num_cs_references;
}
-void radeon_drm_cs_flush(struct r300_winsys_cs *rcs);
-void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs);
+void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs);
void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws);
#endif
diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript
index b255d725f95..f8e1fa6cfd8 100644
--- a/src/gallium/winsys/sw/dri/SConscript
+++ b/src/gallium/winsys/sw/dri/SConscript
@@ -4,7 +4,7 @@
Import('*')
-if env['platform'] == 'linux':
+if env['platform'] in ('linux', 'sunos'):
env = env.Clone()
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
index 4ecfdbf3915..51245766d1c 100644
--- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -246,7 +246,7 @@ wsw_dt_unmap(struct sw_winsys *ws,
pipe->transfer_unmap(pipe, wdt->transfer);
pipe->transfer_destroy(pipe, wdt->transfer);
- pipe->flush(pipe, 0, NULL);
+ pipe->flush(pipe, NULL);
wdt->transfer = NULL;
}
diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript
index df01a9ec2bf..e9c274059bd 100644
--- a/src/gallium/winsys/sw/xlib/SConscript
+++ b/src/gallium/winsys/sw/xlib/SConscript
@@ -4,7 +4,7 @@
Import('*')
-if env['platform'] in ('cygwin', 'linux'):
+if env['platform'] in ('cygwin', 'linux', 'sunos'):
env = env.Clone()