summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/Makefile.template7
-rw-r--r--src/gallium/SConscript7
-rw-r--r--src/gallium/auxiliary/Makefile16
-rw-r--r--src/gallium/auxiliary/SConscript17
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.c21
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h16
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c335
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h52
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c66
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c72
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_decompose.h40
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c39
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c29
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h38
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.c37
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex.h35
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld.h47
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_alpha.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c275
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.h6
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_blend.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.c28
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.h10
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_conv.c34
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_conv.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_depth.c608
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_depth.h19
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.c28
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.h6
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format_soa.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_interp.c6
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_interp.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_intr.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.c163
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_logic.h7
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.c19
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_pack.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_printf.c113
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_printf.h (renamed from src/gallium/drivers/cell/ppu/cell_winsys.h)34
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c53
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h11
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c1337
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_struct.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_swizzle.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi.h2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c191
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.c13
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h54
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c9
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c2
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.h6
-rw-r--r--src/gallium/auxiliary/target-helpers/wrap_screen.c65
-rw-r--r--src/gallium/auxiliary/target-helpers/wrap_screen.h16
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c4
-rw-r--r--src/gallium/auxiliary/translate/translate_generic.c8
-rw-r--r--src/gallium/auxiliary/translate/translate_sse.c4
-rw-r--r--src/gallium/auxiliary/util/u_blit.c76
-rw-r--r--src/gallium/auxiliary/util/u_blit.h4
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c67
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h32
-rw-r--r--src/gallium/auxiliary/util/u_debug.c51
-rw-r--r--src/gallium/auxiliary/util/u_debug.h17
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c12
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c1
-rw-r--r--src/gallium/auxiliary/util/u_format.csv27
-rw-r--r--src/gallium/auxiliary/util/u_format.h45
-rw-r--r--src/gallium/auxiliary/util/u_format_pack.py209
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py10
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py4
-rw-r--r--src/gallium/auxiliary/util/u_format_tests.c551
-rw-r--r--src/gallium/auxiliary/util/u_format_tests.h69
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c77
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.h2
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h28
-rw-r--r--src/gallium/auxiliary/util/u_pack_color.h19
-rw-r--r--src/gallium/auxiliary/util/u_rect.c26
-rw-r--r--src/gallium/auxiliary/util/u_sampler.c100
-rw-r--r--src/gallium/auxiliary/util/u_sampler.h (renamed from src/gallium/drivers/softpipe/sp_winsys.h)62
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c16
-rw-r--r--src/gallium/auxiliary/util/u_tile.c160
-rw-r--r--src/gallium/auxiliary/util/u_tile.h32
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c31
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h2
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c136
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h4
-rw-r--r--src/gallium/docs/d3d11ddi.txt492
-rw-r--r--src/gallium/docs/source/context.rst41
-rw-r--r--src/gallium/docs/source/cso/rasterizer.rst76
-rw-r--r--src/gallium/docs/source/cso/velems.rst24
-rw-r--r--src/gallium/drivers/cell/ppu/Makefile1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.c118
-rw-r--r--src/gallium/drivers/cell/ppu/cell_buffer.h55
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h11
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c66
-rw-r--r--src/gallium/drivers/cell/ppu/cell_fence.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c69
-rw-r--r--src/gallium/drivers/cell/ppu/cell_public.h10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.h22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c5
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c18
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c42
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c148
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.h19
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vertex_shader.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.c1
-rw-r--r--src/gallium/drivers/failover/fo_context.h21
-rw-r--r--src/gallium/drivers/failover/fo_state.c171
-rw-r--r--src/gallium/drivers/failover/fo_state_emit.c34
-rw-r--r--src/gallium/drivers/i915/i915_batch.h10
-rw-r--r--src/gallium/drivers/i915/i915_batchbuffer.h (renamed from src/gallium/drivers/i915/intel_batchbuffer.h)50
-rw-r--r--src/gallium/drivers/i915/i915_blit.c12
-rw-r--r--src/gallium/drivers/i915/i915_blit.h6
-rw-r--r--src/gallium/drivers/i915/i915_buffer.c4
-rw-r--r--src/gallium/drivers/i915/i915_context.c1
-rw-r--r--src/gallium/drivers/i915/i915_context.h41
-rw-r--r--src/gallium/drivers/i915/i915_debug.c2
-rw-r--r--src/gallium/drivers/i915/i915_debug.h4
-rw-r--r--src/gallium/drivers/i915/i915_debug_fp.c1
-rw-r--r--src/gallium/drivers/i915/i915_prim_emit.c7
-rw-r--r--src/gallium/drivers/i915/i915_prim_vbuf.c16
-rw-r--r--src/gallium/drivers/i915/i915_screen.c16
-rw-r--r--src/gallium/drivers/i915/i915_screen.h4
-rw-r--r--src/gallium/drivers/i915/i915_state.c93
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c8
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c11
-rw-r--r--src/gallium/drivers/i915/i915_state_immediate.c6
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c26
-rw-r--r--src/gallium/drivers/i915/i915_texture.c161
-rw-r--r--src/gallium/drivers/i915/i915_winsys.h (renamed from src/gallium/drivers/i915/intel_winsys.h)136
-rw-r--r--src/gallium/drivers/i965/brw_context.c1
-rw-r--r--src/gallium/drivers/i965/brw_context.h9
-rw-r--r--src/gallium/drivers/i965/brw_draw_upload.c208
-rw-r--r--src/gallium/drivers/i965/brw_pipe_sampler.c54
-rw-r--r--src/gallium/drivers/i965/brw_pipe_vertex.c247
-rw-r--r--src/gallium/drivers/i965/brw_screen.c6
-rw-r--r--src/gallium/drivers/i965/brw_screen.h13
-rw-r--r--src/gallium/drivers/i965/brw_screen_texture.c260
-rw-r--r--src/gallium/drivers/i965/brw_structs.h4
-rw-r--r--src/gallium/drivers/i965/brw_winsys.h32
-rw-r--r--src/gallium/drivers/i965/brw_wm.c4
-rw-r--r--src/gallium/drivers/i965/brw_wm_sampler_state.c8
-rw-r--r--src/gallium/drivers/i965/brw_wm_surface_state.c6
-rw-r--r--src/gallium/drivers/identity/id_context.c221
-rw-r--r--src/gallium/drivers/identity/id_drm.c60
-rw-r--r--src/gallium/drivers/identity/id_objects.c18
-rw-r--r--src/gallium/drivers/identity/id_objects.h34
-rw-r--r--src/gallium/drivers/identity/id_screen.c137
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile15
-rw-r--r--src/gallium/drivers/llvmpipe/README19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c68
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h12
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c60
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h58
-rw-r--r--src/gallium/drivers/llvmpipe/lp_public.h10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c69
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c70
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c37
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c134
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h42
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h24
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_line.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_point.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c75
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c153
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h42
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c167
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c65
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c35
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_format.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_printf.c162
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c281
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h37
-rw-r--r--src/gallium/drivers/nouveau/Makefile3
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c75
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h12
-rw-r--r--src/gallium/drivers/nouveau/nouveau_util.h102
-rw-r--r--src/gallium/drivers/nouveau/nouveau_winsys.h5
-rw-r--r--src/gallium/drivers/nv30/Makefile29
-rw-r--r--src/gallium/drivers/nv30/nv30_clear.c14
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c87
-rw-r--r--src/gallium/drivers/nv30/nv30_context.h218
-rw-r--r--src/gallium/drivers/nv30/nv30_draw.c61
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c905
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c239
-rw-r--r--src/gallium/drivers/nv30/nv30_query.c127
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c362
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h41
-rw-r--r--src/gallium/drivers/nv30/nv30_shader.h490
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c728
-rw-r--r--src/gallium/drivers/nv30/nv30_state.h86
-rw-r--r--src/gallium/drivers/nv30/nv30_state_blend.c41
-rw-r--r--src/gallium/drivers/nv30/nv30_state_emit.c122
-rw-r--r--src/gallium/drivers/nv30/nv30_state_fb.c173
-rw-r--r--src/gallium/drivers/nv30/nv30_state_rasterizer.c17
-rw-r--r--src/gallium/drivers/nv30/nv30_state_scissor.c36
-rw-r--r--src/gallium/drivers/nv30/nv30_state_stipple.c40
-rw-r--r--src/gallium/drivers/nv30/nv30_state_viewport.c42
-rw-r--r--src/gallium/drivers/nv30/nv30_state_zsa.c41
-rw-r--r--src/gallium/drivers/nv30/nv30_transfer.c178
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c842
-rw-r--r--src/gallium/drivers/nv40/Makefile29
-rw-r--r--src/gallium/drivers/nv40/nv40_context.c87
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h239
-rw-r--r--src/gallium/drivers/nv40/nv40_draw.c360
-rw-r--r--src/gallium/drivers/nv40/nv40_query.c127
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c320
-rw-r--r--src/gallium/drivers/nv40/nv40_shader.h556
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c743
-rw-r--r--src/gallium/drivers/nv40/nv40_state_blend.c41
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c189
-rw-r--r--src/gallium/drivers/nv40/nv40_state_fb.c175
-rw-r--r--src/gallium/drivers/nv40/nv40_state_rasterizer.c17
-rw-r--r--src/gallium/drivers/nv40/nv40_state_scissor.c36
-rw-r--r--src/gallium/drivers/nv40/nv40_state_stipple.c39
-rw-r--r--src/gallium/drivers/nv40/nv40_state_viewport.c38
-rw-r--r--src/gallium/drivers/nv40/nv40_state_zsa.c41
-rw-r--r--src/gallium/drivers/nv40/nv40_surface.c64
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c565
-rw-r--r--src/gallium/drivers/nv50/Makefile3
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c44
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h122
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c5
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c42
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c326
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c305
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h4
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c110
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c436
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c225
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h32
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c21
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c1112
-rw-r--r--src/gallium/drivers/nvfx/Makefile32
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.c (renamed from src/gallium/drivers/nouveau/nv04_surface_2d.c)2
-rw-r--r--src/gallium/drivers/nvfx/nv04_surface_2d.h (renamed from src/gallium/drivers/nouveau/nv04_surface_2d.h)0
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c (renamed from src/gallium/drivers/nv30/nv30_fragtex.c)86
-rw-r--r--src/gallium/drivers/nvfx/nv30_vertprog.h169
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c (renamed from src/gallium/drivers/nv40/nv40_fragtex.c)129
-rw-r--r--src/gallium/drivers/nvfx/nv40_vertprog.h177
-rw-r--r--src/gallium/drivers/nvfx/nvfx_clear.c (renamed from src/gallium/drivers/nv40/nv40_clear.c)6
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.c90
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h264
-rw-r--r--src/gallium/drivers/nvfx/nvfx_draw.c356
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c (renamed from src/gallium/drivers/nv40/nv40_fragprog.c)451
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragtex.c49
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c (renamed from src/gallium/drivers/nv40/nv40_miptree.c)71
-rw-r--r--src/gallium/drivers/nvfx/nvfx_query.c127
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c462
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h (renamed from src/gallium/drivers/nv40/nv40_screen.h)26
-rw-r--r--src/gallium/drivers/nvfx/nvfx_shader.h429
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c650
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.h (renamed from src/gallium/drivers/nv40/nv40_state.h)34
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_blend.c41
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_emit.c179
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_fb.c234
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_rasterizer.c17
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_scissor.c36
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_stipple.c40
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_viewport.c52
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_zsa.c41
-rw-r--r--src/gallium/drivers/nvfx/nvfx_surface.c (renamed from src/gallium/drivers/nv30/nv30_surface.c)30
-rw-r--r--src/gallium/drivers/nvfx/nvfx_tex.h133
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c (renamed from src/gallium/drivers/nv40/nv40_transfer.c)64
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c (renamed from src/gallium/drivers/nv30/nv30_vbo.c)222
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vertprog.c (renamed from src/gallium/drivers/nv40/nv40_vertprog.c)641
-rw-r--r--src/gallium/drivers/r300/Makefile4
-rw-r--r--src/gallium/drivers/r300/SConscript2
-rw-r--r--src/gallium/drivers/r300/r300_blit.c8
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c7
-rw-r--r--src/gallium/drivers/r300/r300_context.c63
-rw-r--r--src/gallium/drivers/r300/r300_context.h62
-rw-r--r--src/gallium/drivers/r300/r300_cs.h25
-rw-r--r--src/gallium/drivers/r300/r300_debug.c13
-rw-r--r--src/gallium/drivers/r300/r300_defines.h47
-rw-r--r--src/gallium/drivers/r300/r300_emit.c168
-rw-r--r--src/gallium/drivers/r300/r300_emit.h3
-rw-r--r--src/gallium/drivers/r300/r300_flush.c6
-rw-r--r--src/gallium/drivers/r300/r300_fs.c6
-rw-r--r--src/gallium/drivers/r300/r300_query.c8
-rw-r--r--src/gallium/drivers/r300/r300_reg.h4
-rw-r--r--src/gallium/drivers/r300/r300_render.c148
-rw-r--r--src/gallium/drivers/r300/r300_screen.c115
-rw-r--r--src/gallium/drivers/r300/r300_screen.h22
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c314
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h99
-rw-r--r--src/gallium/drivers/r300/r300_state.c403
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c121
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h79
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c2
-rw-r--r--src/gallium/drivers/r300/r300_texture.c202
-rw-r--r--src/gallium/drivers/r300/r300_texture.h10
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c19
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c280
-rw-r--r--src/gallium/drivers/r300/r300_transfer.h33
-rw-r--r--src/gallium/drivers/r300/r300_vs.c167
-rw-r--r--src/gallium/drivers/r300/r300_vs.h13
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h146
-rw-r--r--src/gallium/drivers/softpipe/Makefile5
-rw-r--r--src/gallium/drivers/softpipe/SConscript5
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.c118
-rw-r--r--src/gallium/drivers/softpipe/sp_buffer.h55
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c27
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h14
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c97
-rw-r--r--src/gallium/drivers/softpipe/sp_fence.c70
-rw-r--r--src/gallium/drivers/softpipe/sp_fence.h40
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c7
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c80
-rw-r--r--src/gallium/drivers/softpipe/sp_public.h10
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c56
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h38
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c89
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c36
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c94
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c62
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h14
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c180
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h22
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c41
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.c245
-rw-r--r--src/gallium/drivers/svga/svga_context.c2
-rw-r--r--src/gallium/drivers/svga/svga_context.h12
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c61
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c38
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c189
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.h5
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c2
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_need_swtnl.c9
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c13
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c22
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c8
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c4
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c4
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h33
-rw-r--r--src/gallium/drivers/svga/svgadump/svga_shader_dump.c4
-rw-r--r--src/gallium/drivers/sw/Makefile10
-rw-r--r--src/gallium/drivers/sw/SConscript42
-rw-r--r--src/gallium/drivers/sw/sw.c59
-rw-r--r--src/gallium/drivers/sw/sw_public.h13
-rw-r--r--src/gallium/drivers/trace/tr_context.c363
-rw-r--r--src/gallium/drivers/trace/tr_context.h10
-rw-r--r--src/gallium/drivers/trace/tr_drm.c70
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c1
-rw-r--r--src/gallium/drivers/trace/tr_public.h45
-rw-r--r--src/gallium/drivers/trace/tr_rbug.c24
-rw-r--r--src/gallium/drivers/trace/tr_screen.c221
-rw-r--r--src/gallium/drivers/trace/tr_screen.h4
-rw-r--r--src/gallium/drivers/trace/tr_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_texture.h27
-rw-r--r--src/gallium/include/pipe/p_compiler.h5
-rw-r--r--src/gallium/include/pipe/p_context.h57
-rw-r--r--src/gallium/include/pipe/p_defines.h16
-rw-r--r--src/gallium/include/pipe/p_format.h1
-rw-r--r--src/gallium/include/pipe/p_screen.h66
-rw-r--r--src/gallium/include/pipe/p_state.h29
-rw-r--r--src/gallium/include/state_tracker/dri1_api.h8
-rw-r--r--src/gallium/include/state_tracker/drisw_api.h35
-rw-r--r--src/gallium/include/state_tracker/drm_api.h58
-rw-r--r--src/gallium/include/state_tracker/graw.h36
-rw-r--r--src/gallium/include/state_tracker/st_api.h407
-rw-r--r--src/gallium/include/state_tracker/sw_winsys.h (renamed from src/gallium/drivers/llvmpipe/lp_winsys.h)68
-rw-r--r--src/gallium/include/state_tracker/xlib_sw_winsys.h29
-rw-r--r--src/gallium/state_trackers/dri/Makefile32
-rw-r--r--src/gallium/state_trackers/dri/SConscript25
-rw-r--r--src/gallium/state_trackers/dri/common/dri1_helper.c129
-rw-r--r--src/gallium/state_trackers/dri/common/dri1_helper.h61
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c (renamed from src/gallium/state_trackers/dri/dri_context.c)123
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.h (renamed from src/gallium/state_trackers/dri/dri_context.h)41
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c94
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h (renamed from src/gallium/state_trackers/dri/dri_drawable.h)45
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c (renamed from src/gallium/state_trackers/dri/dri_screen.c)302
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.h (renamed from src/gallium/state_trackers/dri/dri_screen.h)49
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.c263
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.h55
-rw-r--r--src/gallium/state_trackers/dri/common/dri_wrapper.h10
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c761
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c142
-rw-r--r--src/gallium/state_trackers/dri/drm/Makefile32
-rw-r--r--src/gallium/state_trackers/dri/drm/SConscript27
-rw-r--r--src/gallium/state_trackers/dri/drm/dri1.c522
-rw-r--r--src/gallium/state_trackers/dri/drm/dri1.h59
l---------src/gallium/state_trackers/dri/drm/dri1_helper.c1
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c416
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.h46
l---------src/gallium/state_trackers/dri/drm/dri_context.c1
l---------src/gallium/state_trackers/dri/drm/dri_drawable.c1
l---------src/gallium/state_trackers/dri/drm/dri_screen.c1
l---------src/gallium/state_trackers/dri/drm/dri_st_api.c1
-rw-r--r--src/gallium/state_trackers/dri/sw/Makefile26
-rw-r--r--src/gallium/state_trackers/dri/sw/SConscript28
l---------src/gallium/state_trackers/dri/sw/dri1_helper.c1
l---------src/gallium/state_trackers/dri/sw/dri_context.c1
l---------src/gallium/state_trackers/dri/sw/dri_drawable.c1
l---------src/gallium/state_trackers/dri/sw/dri_screen.c1
l---------src/gallium/state_trackers/dri/sw/dri_st_api.c1
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c298
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.h54
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c596
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h25
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c227
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.h (renamed from src/gallium/state_trackers/egl/common/egl_st.h)86
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c131
-rw-r--r--src/gallium/state_trackers/egl/common/native.h3
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h20
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c14
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c9
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c13
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h3
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c278
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/es/Makefile2
-rw-r--r--src/gallium/state_trackers/es/st_es1.c7
-rw-r--r--src/gallium/state_trackers/es/st_es2.c7
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile6
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript3
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c11
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c419
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h73
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_public.h (renamed from src/gallium/state_trackers/glx/xlib/xm_winsys.h)24
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c332
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.h51
-rw-r--r--src/gallium/state_trackers/python/SConscript31
-rw-r--r--src/gallium/state_trackers/python/gallium.i1
-rw-r--r--src/gallium/state_trackers/python/p_context.i328
-rw-r--r--src/gallium/state_trackers/python/p_texture.i228
-rw-r--r--src/gallium/state_trackers/python/st_device.c106
-rw-r--r--src/gallium/state_trackers/python/st_device.h13
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c16
-rw-r--r--src/gallium/state_trackers/python/st_llvmpipe_winsys.c141
-rw-r--r--src/gallium/state_trackers/python/st_sample.c29
-rw-r--r--src/gallium/state_trackers/python/st_sample.h7
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c55
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h14
-rw-r--r--src/gallium/state_trackers/vega/Makefile3
-rw-r--r--src/gallium/state_trackers/vega/api_context.c3
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c87
-rw-r--r--src/gallium/state_trackers/vega/api_images.c7
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c6
-rw-r--r--src/gallium/state_trackers/vega/image.c54
-rw-r--r--src/gallium/state_trackers/vega/image.h4
-rw-r--r--src/gallium/state_trackers/vega/mask.c66
-rw-r--r--src/gallium/state_trackers/vega/mask.h2
-rw-r--r--src/gallium/state_trackers/vega/paint.c68
-rw-r--r--src/gallium/state_trackers/vega/paint.h2
-rw-r--r--src/gallium/state_trackers/vega/polygon.c4
-rw-r--r--src/gallium/state_trackers/vega/renderer.c42
-rw-r--r--src/gallium/state_trackers/vega/renderer.h3
-rw-r--r--src/gallium/state_trackers/vega/shader.c34
-rw-r--r--src/gallium/state_trackers/vega/st_inlines.h9
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c27
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h13
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c373
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.h40
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c64
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h3
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c14
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c19
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c37
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c29
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c50
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c34
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c88
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c2
-rw-r--r--src/gallium/targets/Makefile (renamed from src/gallium/winsys/drm/Makefile)4
-rw-r--r--src/gallium/targets/Makefile.dri (renamed from src/gallium/winsys/drm/Makefile.template)7
-rw-r--r--src/gallium/targets/Makefile.egl (renamed from src/gallium/winsys/drm/Makefile.egl)15
-rw-r--r--src/gallium/targets/SConscript27
-rw-r--r--src/gallium/targets/SConscript.dri96
-rw-r--r--src/gallium/targets/dri-i915/Makefile (renamed from src/gallium/winsys/drm/intel/dri/Makefile)14
-rw-r--r--src/gallium/targets/dri-i915/SConscript26
-rw-r--r--src/gallium/targets/dri-i915/dummy.c0
-rw-r--r--src/gallium/targets/dri-i965/Makefile (renamed from src/gallium/winsys/drm/i965/dri/Makefile)16
-rw-r--r--src/gallium/targets/dri-i965/SConscript26
-rw-r--r--src/gallium/targets/dri-i965/dummy.c0
-rw-r--r--src/gallium/targets/dri-nouveau/Makefile (renamed from src/gallium/winsys/drm/nouveau/dri/Makefile)13
-rw-r--r--src/gallium/targets/dri-radeong/Makefile (renamed from src/gallium/winsys/drm/radeon/dri/Makefile)11
-rw-r--r--src/gallium/targets/dri-radeong/SConscript26
-rw-r--r--src/gallium/targets/dri-radeong/dummy.c0
-rw-r--r--src/gallium/targets/dri-swrast/Makefile30
-rw-r--r--src/gallium/targets/dri-swrast/SConscript42
-rw-r--r--src/gallium/targets/dri-swrast/swrast_drm_api.c147
-rw-r--r--src/gallium/targets/dri-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/dri/Makefile)9
-rw-r--r--src/gallium/targets/dri-vmwgfx/SConscript24
-rw-r--r--src/gallium/targets/dri-vmwgfx/dummy.c0
-rw-r--r--src/gallium/targets/egl-i915/Makefile (renamed from src/gallium/winsys/drm/intel/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-i915/dummy.c (renamed from src/gallium/winsys/drm/i965/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-i965/Makefile16
-rw-r--r--src/gallium/targets/egl-i965/dummy.c (renamed from src/gallium/winsys/drm/intel/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-nouveau/Makefile14
-rw-r--r--src/gallium/targets/egl-nouveau/dummy.c (renamed from src/gallium/winsys/drm/nouveau/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-radeon/Makefile (renamed from src/gallium/winsys/drm/radeon/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-radeon/dummy.c (renamed from src/gallium/winsys/drm/radeon/egl/dummy.c)0
-rw-r--r--src/gallium/targets/egl-swrast/Makefile12
-rw-r--r--src/gallium/targets/egl-swrast/swrast_glue.c (renamed from src/gallium/winsys/drm/swrast/core/swrast_drm_api.c)4
-rw-r--r--src/gallium/targets/egl-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/egl/Makefile)7
-rw-r--r--src/gallium/targets/egl-vmwgfx/dummy.c (renamed from src/gallium/winsys/drm/swrast/egl/dummy.c)0
-rw-r--r--src/gallium/targets/graw-xlib/SConscript57
-rw-r--r--src/gallium/targets/graw-xlib/graw.h36
-rw-r--r--src/gallium/targets/graw-xlib/graw_xlib.c181
-rw-r--r--src/gallium/targets/libgl-gdi/SConscript (renamed from src/gallium/winsys/gdi/SConscript)3
-rw-r--r--src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c124
-rw-r--r--src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c124
-rw-r--r--src/gallium/targets/libgl-xlib/Makefile (renamed from src/gallium/winsys/xlib/Makefile)22
-rw-r--r--src/gallium/targets/libgl-xlib/SConscript (renamed from src/gallium/winsys/xlib/SConscript)23
-rw-r--r--src/gallium/targets/libgl-xlib/xlib.c211
-rw-r--r--src/gallium/targets/xorg-i915/Makefile (renamed from src/gallium/winsys/drm/intel/xorg/Makefile)10
-rw-r--r--src/gallium/targets/xorg-i915/intel_xorg.c (renamed from src/gallium/winsys/drm/intel/xorg/intel_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-i965/Makefile (renamed from src/gallium/winsys/drm/i965/xorg/Makefile)22
-rw-r--r--src/gallium/targets/xorg-i965/intel_xorg.c (renamed from src/gallium/winsys/drm/i965/xorg/intel_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-nouveau/Makefile (renamed from src/gallium/winsys/drm/nouveau/xorg/Makefile)12
-rw-r--r--src/gallium/targets/xorg-nouveau/nouveau_xorg.c (renamed from src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-radeon/Makefile (renamed from src/gallium/winsys/drm/radeon/xorg/Makefile)22
-rw-r--r--src/gallium/targets/xorg-radeon/radeon_xorg.c (renamed from src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/Makefile (renamed from src/gallium/winsys/drm/vmware/xorg/Makefile)5
-rw-r--r--src/gallium/targets/xorg-vmwgfx/SConscript (renamed from src/gallium/winsys/drm/vmware/xorg/SConscript)4
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_driver.h (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_driver.h)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_hook.h (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_hook.h)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_screen.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_screen.c)0
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_video.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_video.c)2
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_xorg.c (renamed from src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c)0
-rw-r--r--src/gallium/winsys/SConscript34
-rw-r--r--src/gallium/winsys/drm/SConscript69
-rw-r--r--src/gallium/winsys/drm/i965/Makefile12
-rw-r--r--src/gallium/winsys/drm/i965/SConscript7
-rw-r--r--src/gallium/winsys/drm/i965/dri/SConscript19
-rw-r--r--src/gallium/winsys/drm/i965/egl/Makefile14
-rw-r--r--src/gallium/winsys/drm/i965/gem/i965_drm_api.c238
-rw-r--r--src/gallium/winsys/drm/intel/SConscript7
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript21
-rw-r--r--src/gallium/winsys/drm/intel/gem/SConscript17
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c205
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c154
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h77
-rw-r--r--src/gallium/winsys/drm/nouveau/Makefile12
-rw-r--r--src/gallium/winsys/drm/nouveau/egl/Makefile16
-rw-r--r--src/gallium/winsys/drm/radeon/Makefile12
-rw-r--r--src/gallium/winsys/drm/radeon/SConscript7
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c303
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c162
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_winsys.h111
-rw-r--r--src/gallium/winsys/drm/radeon/dri/SConscript17
-rw-r--r--src/gallium/winsys/drm/radeon/python/README15
-rw-r--r--src/gallium/winsys/drm/radeon/python/SConscript33
-rw-r--r--src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c132
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dri.c605
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dri.h123
-rw-r--r--src/gallium/winsys/drm/radeon/python/xf86dristr.h389
-rw-r--r--src/gallium/winsys/drm/swrast/Makefile12
-rw-r--r--src/gallium/winsys/drm/swrast/core/Makefile10
-rw-r--r--src/gallium/winsys/drm/swrast/egl/Makefile12
-rw-r--r--src/gallium/winsys/drm/vmware/Makefile12
-rw-r--r--src/gallium/winsys/drm/vmware/SConscript11
-rw-r--r--src/gallium/winsys/drm/vmware/dri/SConscript63
-rw-r--r--src/gallium/winsys/drm/vmware/egl/dummy.c3
-rw-r--r--src/gallium/winsys/gdi/gdi_softpipe_winsys.c318
-rw-r--r--src/gallium/winsys/i915/drm/Makefile (renamed from src/gallium/winsys/drm/intel/gem/Makefile)14
-rw-r--r--src/gallium/winsys/i915/drm/SConscript17
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_api.c109
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c)78
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_buffer.c217
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_fence.c (renamed from src/gallium/winsys/drm/intel/gem/intel_drm_fence.c)30
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.h77
-rw-r--r--src/gallium/winsys/i965/drm/Makefile (renamed from src/gallium/winsys/drm/i965/gem/Makefile)4
-rw-r--r--src/gallium/winsys/i965/drm/SConscript (renamed from src/gallium/winsys/drm/i965/gem/SConscript)2
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_api.c122
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_buffer.c (renamed from src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c)75
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_winsys.h (renamed from src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h)0
-rw-r--r--src/gallium/winsys/i965/xlib/Makefile (renamed from src/gallium/winsys/drm/i965/xlib/Makefile)4
-rw-r--r--src/gallium/winsys/i965/xlib/xlib_i965.c (renamed from src/gallium/winsys/drm/i965/xlib/xlib_i965.c)2
-rw-r--r--src/gallium/winsys/nouveau/drm/Makefile (renamed from src/gallium/winsys/drm/nouveau/drm/Makefile)4
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h)0
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.c (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c)78
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.h (renamed from src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h)0
-rw-r--r--src/gallium/winsys/radeon/drm/Makefile (renamed from src/gallium/winsys/drm/radeon/core/Makefile)6
-rw-r--r--src/gallium/winsys/radeon/drm/SConscript (renamed from src/gallium/winsys/drm/radeon/core/SConscript)4
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h86
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.c (renamed from src/gallium/winsys/drm/radeon/core/radeon_drm.c)167
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_drm.h)6
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c385
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c348
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_r300.h)2
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h (renamed from src/gallium/winsys/drm/radeon/core/radeon_buffer.h)67
-rw-r--r--src/gallium/winsys/svga/drm/Makefile (renamed from src/gallium/winsys/drm/vmware/core/Makefile)12
-rw-r--r--src/gallium/winsys/svga/drm/SConscript (renamed from src/gallium/winsys/drm/vmware/core/SConscript)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_buffer.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_buffer.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_context.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_context.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_fence.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_fence.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_dri.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c)81
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_pools.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_svga.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.c (renamed from src/gallium/winsys/drm/vmware/core/vmw_surface.c)0
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.h (renamed from src/gallium/winsys/drm/vmware/core/vmw_surface.h)0
-rw-r--r--src/gallium/winsys/svga/drm/vmwgfx_drm.h (renamed from src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h)0
-rw-r--r--src/gallium/winsys/sw/Makefile (renamed from src/gallium/winsys/drm/intel/Makefile)6
-rw-r--r--src/gallium/winsys/sw/dri/Makefile13
-rw-r--r--src/gallium/winsys/sw/dri/SConscript23
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c225
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.h (renamed from src/gallium/state_trackers/egl/x11/sw_winsys.h)30
-rw-r--r--src/gallium/winsys/sw/drm/Makefile12
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.c97
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.h34
-rw-r--r--src/gallium/winsys/sw/gdi/SConscript23
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.c (renamed from src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c)177
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.h16
-rw-r--r--src/gallium/winsys/sw/null/Makefile16
-rw-r--r--src/gallium/winsys/sw/null/SConscript21
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.c148
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.h40
-rw-r--r--src/gallium/winsys/sw/wrapper/Makefile12
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c282
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h35
-rw-r--r--src/gallium/winsys/sw/xlib/Makefile17
-rw-r--r--src/gallium/winsys/sw/xlib/SConscript23
-rw-r--r--src/gallium/winsys/sw/xlib/xlib_sw_winsys.c (renamed from src/gallium/winsys/xlib/xlib_llvmpipe.c)288
-rw-r--r--src/gallium/winsys/xlib/xlib.c138
-rw-r--r--src/gallium/winsys/xlib/xlib.h13
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_context.c209
-rw-r--r--src/gallium/winsys/xlib/xlib_cell.c401
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c508
-rw-r--r--src/gallium/winsys/xlib/xmesa.h424
-rw-r--r--src/gallium/winsys/xlib/xmesa_x.h86
667 files changed, 27399 insertions, 25431 deletions
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template
index 91a9b54b362..b5a9938c740 100644
--- a/src/gallium/Makefile.template
+++ b/src/gallium/Makefile.template
@@ -26,7 +26,7 @@ INCLUDES = \
##### TARGETS #####
-default: depend lib$(LIBNAME).a
+default: depend lib$(LIBNAME).a $(PROGS)
lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
$(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS)
@@ -36,13 +36,16 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURC
touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(GENERATED_SOURCES) 2> /dev/null
+$(PROGS): % : %.o
+ $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
+
# Emacs tags
tags:
etags `find . -name \*.[ch]` `find $(TOP)/src/gallium/include -name \*.h`
# Remove .o and backup files
clean:
- rm -f $(OBJECTS) $(GENERATED_SOURCES) lib$(LIBNAME).a depend depend.bak
+ rm -f $(OBJECTS) $(GENERATED_SOURCES) $(PROGS) lib$(LIBNAME).a depend depend.bak
# Dummy target
install:
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index d56c5c84617..b8c04f72379 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -7,6 +7,9 @@ SConscript('auxiliary/SConscript')
for driver in env['drivers']:
SConscript(os.path.join('drivers', driver, 'SConscript'))
+# Needed by some state trackers
+SConscript('winsys/sw/null/SConscript')
+
SConscript('state_trackers/python/SConscript')
if platform != 'embedded':
SConscript('state_trackers/glx/xlib/SConscript')
@@ -15,3 +18,7 @@ if platform != 'embedded':
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
+
+SConscript('winsys/SConscript')
+
+SConscript('targets/SConscript')
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 1d0930e024b..452eceb7f4f 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -107,6 +107,7 @@ C_SOURCES = \
util/u_draw_quad.c \
util/u_format_access.c \
util/u_format_table.c \
+ util/u_format_tests.c \
util/u_gen_mipmap.c \
util/u_handle_table.c \
util/u_hash_table.c \
@@ -118,6 +119,7 @@ C_SOURCES = \
util/u_mm.c \
util/u_rect.c \
util/u_ringbuffer.c \
+ util/u_sampler.c \
util/u_simple_shaders.c \
util/u_snprintf.c \
util/u_surface.c \
@@ -126,11 +128,14 @@ C_SOURCES = \
util/u_timed_winsys.c \
util/u_upload_mgr.c \
util/u_simple_screen.c \
- vl/vl_bitstream_parser.c \
- vl/vl_mpeg12_mc_renderer.c \
- vl/vl_compositor.c \
- vl/vl_csc.c \
- vl/vl_shader_build.c
+ target-helpers/wrap_screen.c
+
+ # Disabling until pipe-video branch gets merged in
+ #vl/vl_bitstream_parser.c \
+ #vl/vl_mpeg12_mc_renderer.c \
+ #vl/vl_compositor.c \
+ #vl/vl_csc.c \
+ #vl/vl_shader_build.c \
GALLIVM_SOURCES = \
gallivm/lp_bld_alpha.c \
@@ -150,6 +155,7 @@ GALLIVM_SOURCES = \
gallivm/lp_bld_intr.c \
gallivm/lp_bld_logic.c \
gallivm/lp_bld_pack.c \
+ gallivm/lp_bld_printf.c \
gallivm/lp_bld_sample.c \
gallivm/lp_bld_sample_soa.c \
gallivm/lp_bld_struct.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index f365c4bbdd6..0a23da47b2a 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -7,6 +7,8 @@ env.Append(CPPPATH = [
'util',
])
+env.Tool('udis86')
+
env.CodeGenerate(
target = 'indices/u_indices_gen.c',
script = 'indices/u_indices_gen.py',
@@ -149,6 +151,7 @@ source = [
'util/u_draw_quad.c',
'util/u_format_access.c',
'util/u_format_table.c',
+ 'util/u_format_tests.c',
'util/u_gen_mipmap.c',
'util/u_handle_table.c',
'util/u_hash.c',
@@ -159,6 +162,7 @@ source = [
'util/u_mm.c',
'util/u_rect.c',
'util/u_ringbuffer.c',
+ 'util/u_sampler.c',
'util/u_simple_shaders.c',
'util/u_snprintf.c',
'util/u_surface.c',
@@ -167,11 +171,13 @@ source = [
'util/u_timed_winsys.c',
'util/u_upload_mgr.c',
'util/u_simple_screen.c',
- 'vl/vl_bitstream_parser.c',
- 'vl/vl_mpeg12_mc_renderer.c',
- 'vl/vl_compositor.c',
- 'vl/vl_csc.c',
- 'vl/vl_shader_build.c',
+ # Disabling until pipe-video branch gets merged in
+ #'vl/vl_bitstream_parser.c',
+ #'vl/vl_mpeg12_mc_renderer.c',
+ #'vl/vl_compositor.c',
+ #'vl/vl_csc.c',
+ #'vl/vl_shader_build.c',
+ 'target-helpers/wrap_screen.c',
]
if drawllvm:
@@ -194,6 +200,7 @@ if drawllvm:
'gallivm/lp_bld_logic.c',
'gallivm/lp_bld_init.cpp',
'gallivm/lp_bld_pack.c',
+ 'gallivm/lp_bld_printf.c',
'gallivm/lp_bld_sample.c',
'gallivm/lp_bld_sample_soa.c',
'gallivm/lp_bld_struct.c',
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index a6a07e72c2f..900c64df4b9 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -43,6 +43,7 @@ struct cso_cache {
struct cso_hash *vs_hash;
struct cso_hash *rasterizer_hash;
struct cso_hash *sampler_hash;
+ struct cso_hash *velements_hash;
int max_size;
cso_sanitize_callback sanitize_cb;
@@ -108,6 +109,9 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
+ case CSO_VELEMENTS:
+ hash = sc->velements_hash;
+ break;
}
return hash;
@@ -161,6 +165,13 @@ static void delete_vs_state(void *state, void *data)
FREE(state);
}
+static void delete_velements(void *state, void *data)
+{
+ struct cso_velements *cso = (struct cso_velements *)state;
+ if (cso->delete_state)
+ cso->delete_state(cso->context, cso->data);
+ FREE(state);
+}
static INLINE void delete_cso(void *state, enum cso_cache_type type)
{
@@ -183,6 +194,9 @@ static INLINE void delete_cso(void *state, enum cso_cache_type type)
case CSO_VERTEX_SHADER:
delete_vs_state(state, 0);
break;
+ case CSO_VELEMENTS:
+ delete_velements(state, 0);
+ break;
default:
assert(0);
FREE(state);
@@ -294,6 +308,7 @@ struct cso_cache *cso_cache_create(void)
sc->rasterizer_hash = cso_hash_create();
sc->fs_hash = cso_hash_create();
sc->vs_hash = cso_hash_create();
+ sc->velements_hash = cso_hash_create();
sc->sanitize_cb = sanitize_cb;
sc->sanitize_data = 0;
@@ -325,6 +340,9 @@ void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
case CSO_VERTEX_SHADER:
hash = sc->vs_hash;
break;
+ case CSO_VELEMENTS:
+ hash = sc->velements_hash;
+ break;
}
iter = cso_hash_first_node(hash);
@@ -351,6 +369,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_for_each_state(sc, CSO_VERTEX_SHADER, delete_vs_state, 0);
cso_for_each_state(sc, CSO_RASTERIZER, delete_rasterizer_state, 0);
cso_for_each_state(sc, CSO_SAMPLER, delete_sampler_state, 0);
+ cso_for_each_state(sc, CSO_VELEMENTS, delete_velements, 0);
cso_hash_delete(sc->blend_hash);
cso_hash_delete(sc->sampler_hash);
@@ -358,6 +377,7 @@ void cso_cache_delete(struct cso_cache *sc)
cso_hash_delete(sc->rasterizer_hash);
cso_hash_delete(sc->fs_hash);
cso_hash_delete(sc->vs_hash);
+ cso_hash_delete(sc->velements_hash);
FREE(sc);
}
@@ -372,6 +392,7 @@ void cso_set_maximum_cache_size(struct cso_cache *sc, int number)
sanitize_hash(sc, sc->vs_hash, CSO_VERTEX_SHADER, sc->max_size);
sanitize_hash(sc, sc->rasterizer_hash, CSO_RASTERIZER, sc->max_size);
sanitize_hash(sc, sc->sampler_hash, CSO_SAMPLER, sc->max_size);
+ sanitize_hash(sc, sc->velements_hash, CSO_VELEMENTS, sc->max_size);
}
int cso_maximum_cache_size(const struct cso_cache *sc)
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h
index eea60b940bb..fb09b83c623 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.h
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.h
@@ -53,6 +53,7 @@
* - rasterizer (old setup)
* - sampler
* - vertex shader
+ * - vertex elements
*
* Things that are not constant state objects include:
* - blend_color
@@ -90,7 +91,8 @@ enum cso_cache_type {
CSO_DEPTH_STENCIL_ALPHA,
CSO_RASTERIZER,
CSO_FRAGMENT_SHADER,
- CSO_VERTEX_SHADER
+ CSO_VERTEX_SHADER,
+ CSO_VELEMENTS
};
typedef void (*cso_state_callback)(void *ctx, void *obj);
@@ -144,6 +146,18 @@ struct cso_sampler {
struct pipe_context *context;
};
+struct cso_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS];
+};
+
+struct cso_velements {
+ struct cso_velems_state state;
+ void *data;
+ cso_state_callback delete_state;
+ struct pipe_context *context;
+};
+
unsigned cso_construct_key(void *item, int item_size);
struct cso_cache *cso_cache_create(void);
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index a7335c340ca..6fd4bd36428 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -37,6 +37,7 @@
#include "pipe/p_state.h"
#include "util/u_inlines.h"
+#include "util/u_math.h"
#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
@@ -69,17 +70,17 @@ struct cso_context {
unsigned nr_vertex_samplers_saved;
void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
- uint nr_textures;
+ uint nr_fragment_sampler_views;
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
- uint nr_vertex_textures;
+ uint nr_vertex_sampler_views;
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
- uint nr_textures_saved;
- struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
+ uint nr_fragment_sampler_views_saved;
+ struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS];
- uint nr_vertex_textures_saved;
- struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS];
+ uint nr_vertex_sampler_views_saved;
+ struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS];
/** Current and saved state.
* The saved state is used as a 1-deep stack.
@@ -89,6 +90,7 @@ struct cso_context {
void *rasterizer, *rasterizer_saved;
void *fragment_shader, *fragment_shader_saved, *geometry_shader;
void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
+ void *velements, *velements_saved;
struct pipe_clip_state clip;
struct pipe_clip_state clip_saved;
@@ -174,6 +176,20 @@ static boolean delete_vs_state(struct cso_context *ctx, void *state)
return FALSE;
}
+static boolean delete_vertex_elements(struct cso_context *ctx,
+ void *state)
+{
+ struct cso_velements *cso = (struct cso_velements *)state;
+
+ if (ctx->velements == cso->data)
+ return FALSE;
+
+ if (cso->delete_state)
+ cso->delete_state(cso->context, cso->data);
+ FREE(state);
+ return TRUE;
+}
+
static INLINE boolean delete_cso(struct cso_context *ctx,
void *state, enum cso_cache_type type)
@@ -197,6 +213,9 @@ static INLINE boolean delete_cso(struct cso_context *ctx,
case CSO_VERTEX_SHADER:
return delete_vs_state(ctx, state);
break;
+ case CSO_VELEMENTS:
+ return delete_vertex_elements(ctx, state);
+ break;
default:
assert(0);
FREE(state);
@@ -271,16 +290,17 @@ void cso_release_all( struct cso_context *ctx )
ctx->pipe->bind_depth_stencil_alpha_state( ctx->pipe, NULL );
ctx->pipe->bind_fs_state( ctx->pipe, NULL );
ctx->pipe->bind_vs_state( ctx->pipe, NULL );
+ ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
}
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->textures[i], NULL);
- pipe_texture_reference(&ctx->textures_saved[i], NULL);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
+ pipe_sampler_view_reference(&ctx->fragment_sampler_views_saved[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL);
+ pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL);
+ pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL);
}
free_framebuffer_state(&ctx->fb);
@@ -597,114 +617,6 @@ cso_restore_vertex_samplers(struct cso_context *ctx)
}
-enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
- uint count,
- struct pipe_texture **textures )
-{
- uint i;
-
- ctx->nr_textures = count;
-
- for (i = 0; i < count; i++)
- pipe_texture_reference(&ctx->textures[i], textures[i]);
- for ( ; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&ctx->textures[i], NULL);
-
- ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures);
-
- return PIPE_OK;
-}
-
-void cso_save_sampler_textures( struct cso_context *ctx )
-{
- uint i;
-
- ctx->nr_textures_saved = ctx->nr_textures;
- for (i = 0; i < ctx->nr_textures; i++) {
- assert(!ctx->textures_saved[i]);
- pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]);
- }
-}
-
-void cso_restore_sampler_textures( struct cso_context *ctx )
-{
- uint i;
-
- ctx->nr_textures = ctx->nr_textures_saved;
-
- for (i = 0; i < ctx->nr_textures; i++) {
- pipe_texture_reference(&ctx->textures[i], NULL);
- ctx->textures[i] = ctx->textures_saved[i];
- ctx->textures_saved[i] = NULL;
- }
- for ( ; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&ctx->textures[i], NULL);
-
- ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures);
-
- ctx->nr_textures_saved = 0;
-}
-
-
-
-enum pipe_error
-cso_set_vertex_sampler_textures(struct cso_context *ctx,
- uint count,
- struct pipe_texture **textures)
-{
- uint i;
-
- ctx->nr_vertex_textures = count;
-
- for (i = 0; i < count; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], textures[i]);
- }
- for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- }
-
- ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures);
-
- return PIPE_OK;
-}
-
-void
-cso_save_vertex_sampler_textures(struct cso_context *ctx)
-{
- uint i;
-
- ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures;
- for (i = 0; i < ctx->nr_vertex_textures; i++) {
- assert(!ctx->vertex_textures_saved[i]);
- pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]);
- }
-}
-
-void
-cso_restore_vertex_sampler_textures(struct cso_context *ctx)
-{
- uint i;
-
- ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved;
-
- for (i = 0; i < ctx->nr_vertex_textures; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- ctx->vertex_textures[i] = ctx->vertex_textures_saved[i];
- ctx->vertex_textures_saved[i] = NULL;
- }
- for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&ctx->vertex_textures[i], NULL);
- }
-
- ctx->pipe->set_vertex_sampler_textures(ctx->pipe,
- ctx->nr_vertex_textures,
- ctx->vertex_textures);
-
- ctx->nr_vertex_textures_saved = 0;
-}
-
-
-
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
@@ -1130,7 +1042,6 @@ void cso_restore_geometry_shader(struct cso_context *ctx)
ctx->geometry_shader_saved = NULL;
}
-
/* clip state */
static INLINE void
@@ -1180,3 +1091,185 @@ cso_restore_clip(struct cso_context *ctx)
ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip_saved);
}
}
+
+enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *states)
+{
+ unsigned key_size, hash_key;
+ struct cso_hash_iter iter;
+ void *handle;
+ struct cso_velems_state velems_state;
+
+ /* need to include the count into the stored state data too.
+ Otherwise first few count pipe_vertex_elements could be identical even if count
+ is different, and there's no guarantee the hash would be different in that
+ case neither */
+ key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned);
+ velems_state.count = count;
+ memcpy(velems_state.velems, states, sizeof(struct pipe_vertex_element) * count);
+ hash_key = cso_construct_key((void*)&velems_state, key_size);
+ iter = cso_find_state_template(ctx->cache, hash_key, CSO_VELEMENTS, (void*)&velems_state, key_size);
+
+ if (cso_hash_iter_is_null(iter)) {
+ struct cso_velements *cso = MALLOC(sizeof(struct cso_velements));
+ if (!cso)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ memcpy(&cso->state, &velems_state, key_size);
+ cso->data = ctx->pipe->create_vertex_elements_state(ctx->pipe, count, &cso->state.velems[0]);
+ cso->delete_state = (cso_state_callback)ctx->pipe->delete_vertex_elements_state;
+ cso->context = ctx->pipe;
+
+ iter = cso_insert_state(ctx->cache, hash_key, CSO_VELEMENTS, cso);
+ if (cso_hash_iter_is_null(iter)) {
+ FREE(cso);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+ }
+
+ handle = cso->data;
+ }
+ else {
+ handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data;
+ }
+
+ if (ctx->velements != handle) {
+ ctx->velements = handle;
+ ctx->pipe->bind_vertex_elements_state(ctx->pipe, handle);
+ }
+ return PIPE_OK;
+}
+
+void cso_save_vertex_elements(struct cso_context *ctx)
+{
+ assert(!ctx->velements_saved);
+ ctx->velements_saved = ctx->velements;
+}
+
+void cso_restore_vertex_elements(struct cso_context *ctx)
+{
+ if (ctx->velements != ctx->velements_saved) {
+ ctx->velements = ctx->velements_saved;
+ ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved);
+ }
+ ctx->velements_saved = NULL;
+}
+
+/* fragment sampler view state */
+
+void
+cso_set_fragment_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views)
+{
+ uint i;
+
+ for (i = 0; i < count; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]);
+ }
+ for (; i < cso->nr_fragment_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_fragment_sampler_views(cso->pipe,
+ MAX2(count, cso->nr_fragment_sampler_views),
+ cso->fragment_sampler_views);
+
+ cso->nr_fragment_sampler_views = count;
+}
+
+void
+cso_save_fragment_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views;
+
+ for (i = 0; i < cso->nr_fragment_sampler_views; i++) {
+ assert(!cso->fragment_sampler_views_saved[i]);
+
+ pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i],
+ cso->fragment_sampler_views[i]);
+ }
+}
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]);
+ pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL);
+ }
+ for (; i < cso->nr_fragment_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_fragment_sampler_views(cso->pipe,
+ MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved),
+ cso->fragment_sampler_views);
+
+ cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved;
+ cso->nr_fragment_sampler_views_saved = 0;
+}
+
+
+/* vertex sampler view state */
+
+void
+cso_set_vertex_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views)
+{
+ uint i;
+
+ for (i = 0; i < count; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]);
+ }
+ for (; i < cso->nr_vertex_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_vertex_sampler_views(cso->pipe,
+ MAX2(count, cso->nr_vertex_sampler_views),
+ cso->vertex_sampler_views);
+
+ cso->nr_vertex_sampler_views = count;
+}
+
+void
+cso_save_vertex_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views;
+
+ for (i = 0; i < cso->nr_vertex_sampler_views; i++) {
+ assert(!cso->vertex_sampler_views_saved[i]);
+
+ pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i],
+ cso->vertex_sampler_views[i]);
+ }
+}
+
+void
+cso_restore_vertex_sampler_views(struct cso_context *cso)
+{
+ uint i;
+
+ for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]);
+ pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL);
+ }
+ for (; i < cso->nr_vertex_sampler_views; i++) {
+ pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+ }
+
+ cso->pipe->set_vertex_sampler_views(cso->pipe,
+ MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved),
+ cso->vertex_sampler_views);
+
+ cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved;
+ cso->nr_vertex_sampler_views_saved = 0;
+}
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 251a9a644f8..d6bcb1fe8f7 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -103,24 +103,11 @@ void
cso_single_vertex_sampler_done(struct cso_context *cso);
-
-enum pipe_error cso_set_sampler_textures( struct cso_context *cso,
- uint count,
- struct pipe_texture **textures );
-void cso_save_sampler_textures( struct cso_context *cso );
-void cso_restore_sampler_textures( struct cso_context *cso );
-
-
-
-enum pipe_error
-cso_set_vertex_sampler_textures(struct cso_context *cso,
- uint count,
- struct pipe_texture **textures);
-void
-cso_save_vertex_sampler_textures(struct cso_context *cso);
-void
-cso_restore_vertex_sampler_textures(struct cso_context *cso);
-
+enum pipe_error cso_set_vertex_elements(struct cso_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *states);
+void cso_save_vertex_elements(struct cso_context *ctx);
+void cso_restore_vertex_elements(struct cso_context *ctx);
/* These aren't really sensible -- most of the time the api provides
@@ -157,7 +144,6 @@ void cso_save_geometry_shader(struct cso_context *cso);
void cso_restore_geometry_shader(struct cso_context *cso);
-
enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb);
void cso_save_framebuffer(struct cso_context *cso);
@@ -193,6 +179,34 @@ void
cso_restore_clip(struct cso_context *cso);
+/* fragment sampler view state */
+
+void
+cso_set_fragment_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views);
+
+void
+cso_save_fragment_sampler_views(struct cso_context *cso);
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *cso);
+
+
+/* vertex sampler view state */
+
+void
+cso_set_vertex_sampler_views(struct cso_context *cso,
+ uint count,
+ struct pipe_sampler_view **views);
+
+void
+cso_save_vertex_sampler_views(struct cso_context *cso);
+
+void
+cso_restore_vertex_sampler_views(struct cso_context *cso);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 8f6ca15dfa2..f4615064e65 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "tgsi/tgsi_transform.h"
#include "tgsi/tgsi_dump.h"
@@ -88,8 +89,9 @@ struct aaline_stage
void *sampler_cso;
struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
uint num_samplers;
- uint num_textures;
+ uint num_sampler_views;
/*
@@ -98,7 +100,7 @@ struct aaline_stage
struct aaline_fragment_shader *fs;
struct {
void *sampler[PIPE_MAX_SAMPLERS];
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
} state;
/*
@@ -111,8 +113,9 @@ struct aaline_stage
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
void **);
- void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
- struct pipe_texture **);
+ void (*driver_set_sampler_views)(struct pipe_context *,
+ unsigned,
+ struct pipe_sampler_view **);
struct pipe_context *pipe;
};
@@ -394,6 +397,7 @@ aaline_create_texture(struct aaline_stage *aaline)
struct pipe_context *pipe = aaline->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture texTemp;
+ struct pipe_sampler_view viewTempl;
uint level;
memset(&texTemp, 0, sizeof(texTemp));
@@ -408,6 +412,16 @@ aaline_create_texture(struct aaline_stage *aaline)
if (!aaline->texture)
return FALSE;
+ u_sampler_view_default_template(&viewTempl,
+ aaline->texture,
+ aaline->texture->format);
+ aaline->sampler_view = pipe->create_sampler_view(pipe,
+ aaline->texture,
+ &viewTempl);
+ if (!aaline->sampler_view) {
+ return FALSE;
+ }
+
/* Fill in mipmap images.
* Basically each level is solid opaque, except for the outermost
* texels which are zero. Special case the 1x1 and 2x2 levels.
@@ -422,9 +436,9 @@ aaline_create_texture(struct aaline_stage *aaline)
/* This texture is new, no need to flush.
*/
- transfer = screen->get_tex_transfer(screen, aaline->texture, 0, level, 0,
+ transfer = pipe->get_tex_transfer(pipe, aaline->texture, 0, level, 0,
PIPE_TRANSFER_WRITE, 0, 0, size, size);
- data = screen->transfer_map(screen, transfer);
+ data = pipe->transfer_map(pipe, transfer);
if (data == NULL)
return FALSE;
@@ -448,8 +462,8 @@ aaline_create_texture(struct aaline_stage *aaline)
}
/* unmap */
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
return TRUE;
}
@@ -669,16 +683,16 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
- num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
+ num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);
num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
- pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
- aaline->texture);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
+ aaline->sampler_view);
draw->suspend_flushing = TRUE;
aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
- aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
+ aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);
draw->suspend_flushing = FALSE;
/* now really draw first line */
@@ -702,8 +716,9 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
aaline->state.sampler);
- aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
- aaline->state.texture);
+ aaline->driver_set_sampler_views(pipe,
+ aaline->num_sampler_views,
+ aaline->state.sampler_views);
draw->suspend_flushing = FALSE;
draw->extra_shader_outputs.slot = 0;
@@ -724,7 +739,7 @@ aaline_destroy(struct draw_stage *stage)
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&aaline->state.texture[i], NULL);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
}
if (aaline->sampler_cso)
@@ -733,6 +748,10 @@ aaline_destroy(struct draw_stage *stage)
if (aaline->texture)
pipe_texture_reference(&aaline->texture, NULL);
+ if (aaline->sampler_view) {
+ pipe_sampler_view_reference(&aaline->sampler_view, NULL);
+ }
+
draw_free_temp_verts( stage );
FREE( stage );
@@ -844,23 +863,24 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
static void
-aaline_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+aaline_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
uint i;
/* save current */
for (i = 0; i < num; i++) {
- pipe_texture_reference(&aaline->state.texture[i], texture[i]);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]);
}
for ( ; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&aaline->state.texture[i], NULL);
+ pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
}
- aaline->num_textures = num;
+ aaline->num_sampler_views = num;
/* pass-through */
- aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
+ aaline->driver_set_sampler_views(aaline->pipe, num, views);
}
@@ -898,7 +918,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
aaline->driver_delete_fs_state = pipe->delete_fs_state;
aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
- aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
+ aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views;
/* override the driver's functions */
pipe->create_fs_state = aaline_create_fs_state;
@@ -906,7 +926,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
pipe->delete_fs_state = aaline_delete_fs_state;
pipe->bind_fragment_sampler_states = aaline_bind_sampler_states;
- pipe->set_fragment_sampler_textures = aaline_set_sampler_textures;
+ pipe->set_fragment_sampler_views = aaline_set_sampler_views;
/* Install once everything is known to be OK:
*/
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index d0d99aa331a..794fd81d70f 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -42,6 +42,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "tgsi/tgsi_transform.h"
#include "tgsi/tgsi_dump.h"
@@ -75,8 +76,9 @@ struct pstip_stage
void *sampler_cso;
struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
uint num_samplers;
- uint num_textures;
+ uint num_sampler_views;
/*
* Currently bound state
@@ -84,7 +86,7 @@ struct pstip_stage
struct pstip_fragment_shader *fs;
struct {
void *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
const struct pipe_poly_stipple *stipple;
} state;
@@ -98,8 +100,9 @@ struct pstip_stage
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **);
- void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
- struct pipe_texture **);
+ void (*driver_set_sampler_views)(struct pipe_context *,
+ unsigned,
+ struct pipe_sampler_view **);
void (*driver_set_polygon_stipple)(struct pipe_context *,
const struct pipe_poly_stipple *);
@@ -374,19 +377,21 @@ pstip_update_texture(struct pstip_stage *pstip)
{
static const uint bit31 = 1 << 31;
struct pipe_context *pipe = pstip->pipe;
- struct pipe_screen *screen = pipe->screen;
struct pipe_transfer *transfer;
const uint *stipple = pstip->state.stipple->stipple;
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 = screen->get_tex_transfer(screen, pstip->texture, 0, 0, 0,
- PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
- data = screen->transfer_map(screen, transfer);
+ transfer = pipe->get_tex_transfer(pipe, pstip->texture, 0, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
+ data = pipe->transfer_map(pipe, transfer);
/*
* Load alpha texture.
@@ -408,8 +413,8 @@ pstip_update_texture(struct pstip_stage *pstip)
}
/* unmap */
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
@@ -422,6 +427,7 @@ pstip_create_texture(struct pstip_stage *pstip)
struct pipe_context *pipe = pstip->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_texture texTemp;
+ struct pipe_sampler_view viewTempl;
memset(&texTemp, 0, sizeof(texTemp));
texTemp.target = PIPE_TEXTURE_2D;
@@ -435,6 +441,16 @@ pstip_create_texture(struct pstip_stage *pstip)
if (pstip->texture == NULL)
return FALSE;
+ u_sampler_view_default_template(&viewTempl,
+ pstip->texture,
+ pstip->texture->format);
+ pstip->sampler_view = pipe->create_sampler_view(pipe,
+ pstip->texture,
+ &viewTempl);
+ if (!pstip->sampler_view) {
+ return FALSE;
+ }
+
return TRUE;
}
@@ -513,19 +529,19 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
- num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
+ num_samplers = MAX2(pstip->num_sampler_views, pstip->num_samplers);
num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);
/* plug in our sampler, texture */
pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso;
- pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit],
- pstip->texture);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[pstip->fs->sampler_unit],
+ pstip->sampler_view);
assert(num_samplers <= PIPE_MAX_SAMPLERS);
draw->suspend_flushing = TRUE;
pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
- pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
+ pstip->driver_set_sampler_views(pipe, num_samplers, pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
/* now really draw first triangle */
@@ -549,8 +565,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
pstip->state.samplers);
- pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
- pstip->state.textures);
+ pstip->driver_set_sampler_views(pipe,
+ pstip->num_sampler_views,
+ pstip->state.sampler_views);
draw->suspend_flushing = FALSE;
}
@@ -569,13 +586,17 @@ pstip_destroy(struct draw_stage *stage)
uint i;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&pstip->state.textures[i], NULL);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);
}
pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);
pipe_texture_reference(&pstip->texture, NULL);
+ if (pstip->sampler_view) {
+ pipe_sampler_view_reference(&pstip->sampler_view, NULL);
+ }
+
draw_free_temp_verts( stage );
FREE( stage );
}
@@ -680,24 +701,25 @@ pstip_bind_sampler_states(struct pipe_context *pipe,
static void
-pstip_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+pstip_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
uint i;
/* save current */
for (i = 0; i < num; i++) {
- pipe_texture_reference(&pstip->state.textures[i], texture[i]);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], views[i]);
}
for (; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&pstip->state.textures[i], NULL);
+ pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);
}
- pstip->num_textures = num;
+ pstip->num_sampler_views = num;
/* pass-through */
- pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
+ pstip->driver_set_sampler_views(pstip->pipe, num, views);
}
@@ -754,7 +776,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
pstip->driver_delete_fs_state = pipe->delete_fs_state;
pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
- pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures;
+ pstip->driver_set_sampler_views = pipe->set_fragment_sampler_views;
pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
/* override the driver's functions */
@@ -763,7 +785,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
pipe->delete_fs_state = pstip_delete_fs_state;
pipe->bind_fragment_sampler_states = pstip_bind_sampler_states;
- pipe->set_fragment_sampler_textures = pstip_set_sampler_textures;
+ pipe->set_fragment_sampler_views = pstip_set_sampler_views;
pipe->set_polygon_stipple = pstip_set_polygon_stipple;
return TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 27099579618..1c7db0005a9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -238,38 +238,15 @@ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
unsigned output_format;
unsigned src_offset = (vbuf->vinfo->attrib[i].src_index * 4 * sizeof(float) );
- switch (vbuf->vinfo->attrib[i].emit) {
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
+ output_format = draw_translate_vinfo_format(vbuf->vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vbuf->vinfo->attrib[i].emit);
+
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
+
+ if (vbuf->vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
src_buffer = 1;
src_offset = 0;
- break;
- case EMIT_4UB:
- output_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- break;
}
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 6d90a6c42fd..a8cdc57ad96 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -307,9 +307,8 @@ draw_arrays_instanced(struct draw_context *draw,
tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
debug_printf("Elements:\n");
for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
- debug_printf(" format=%s comps=%u\n",
- util_format_name(draw->pt.vertex_element[i].src_format),
- draw->pt.vertex_element[i].nr_components);
+ debug_printf(" format=%s\n",
+ util_format_name(draw->pt.vertex_element[i].src_format));
}
debug_printf("Buffers:\n");
for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h
index 4ca5b520204..3c44f7c11ee 100644
--- a/src/gallium/auxiliary/draw/draw_pt_decompose.h
+++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h
@@ -105,40 +105,20 @@ static void FUNC( ARGS,
case PIPE_PRIM_QUADS:
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 4) {
- QUAD( (i + 1),
- (i + 2),
- (i + 3),
- (i + 0) );
- }
- }
- else {
- for (i = 0; i+3 < count; i += 4) {
- QUAD( (i + 0),
- (i + 1),
- (i + 2),
- (i + 3));
- }
+ for (i = 0; i+3 < count; i += 4) {
+ QUAD( (i + 0),
+ (i + 1),
+ (i + 2),
+ (i + 3));
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (flatfirst) {
- for (i = 0; i+3 < count; i += 2) {
- QUAD( (i + 1),
- (i + 3),
- (i + 2),
- (i + 0) );
- }
- }
- else {
- for (i = 0; i+3 < count; i += 2) {
- QUAD( (i + 2),
- (i + 0),
- (i + 1),
- (i + 3));
- }
+ for (i = 0; i+3 < count; i += 2) {
+ QUAD( (i + 2),
+ (i + 0),
+ (i + 1),
+ (i + 3));
}
break;
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index ae357b51226..a7917f54b04 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -86,40 +86,15 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
unsigned output_format;
unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
+ output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
-
- switch (vinfo->attrib[i].emit) {
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
+
+ if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
src_buffer = 1;
src_offset = 0;
- break;
- case EMIT_4UB:
- output_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- break;
}
hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 2a604470e9a..1994ddf2bcc 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -129,41 +129,16 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
unsigned input_offset = src->src_offset;
unsigned output_format;
- switch (vinfo->attrib[i].emit) {
- case EMIT_4UB:
- output_format = PIPE_FORMAT_R8G8B8A8_UNORM;
- emit_sz = 4 * sizeof(unsigned char);
- break;
- case EMIT_4F:
- output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- output_format = PIPE_FORMAT_R32G32B32_FLOAT;
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- output_format = PIPE_FORMAT_R32G32_FLOAT;
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
+ output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+ emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ if (vinfo->attrib[i].emit == EMIT_OMIT)
+ continue;
+
+ if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
input_format = PIPE_FORMAT_R32_FLOAT;
input_buffer = draw->pt.nr_vertex_buffers;
input_offset = 0;
- output_format = PIPE_FORMAT_R32_FLOAT;
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_OMIT:
- continue;
- default:
- assert(0);
- output_format = PIPE_FORMAT_NONE;
- emit_sz = 0;
- continue;
}
key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index 1aecb510777..389e2b105e5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -130,31 +130,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
unsigned dst_offset = 0;
for (i = 0; i < vinfo->num_attribs; i++) {
- unsigned emit_sz = 0;
-
- switch (vinfo->attrib[i].emit) {
- case EMIT_4F:
- emit_sz = 4 * sizeof(float);
- break;
- case EMIT_3F:
- emit_sz = 3 * sizeof(float);
- break;
- case EMIT_2F:
- emit_sz = 2 * sizeof(float);
- break;
- case EMIT_1F:
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_1F_PSIZE:
- emit_sz = 1 * sizeof(float);
- break;
- case EMIT_4UB:
- emit_sz = 4 * sizeof(ubyte);
- break;
- default:
- assert(0);
- break;
- }
+ unsigned emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ /* doesn't handle EMIT_OMIT */
+ assert(emit_sz != 0);
/* The elements in the key correspond to vertex shader output
* numbers, not to positions in the hw vertex description --
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
index 62822a3d562..7cba8547f15 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h
@@ -118,39 +118,21 @@ static void FUNC( struct draw_pt_front_end *frontend,
case PIPE_PRIM_QUADS:
for (i = 0; i+3 < count; i += 4) {
- if (flatfirst) {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3) );
- }
- else {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3) );
- }
+ QUAD( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 3) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i+3 < count; i += 2) {
- if (flatfirst) {
- QUAD( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3),
- get_elt(elts, i + 2) );
- }
- else {
- QUAD( vcache,
- get_elt(elts, i + 2),
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3) );
- }
+ QUAD( vcache,
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 3) );
}
break;
diff --git a/src/gallium/auxiliary/draw/draw_vertex.c b/src/gallium/auxiliary/draw/draw_vertex.c
index 3214213e445..a4f5e882c0a 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.c
+++ b/src/gallium/auxiliary/draw/draw_vertex.c
@@ -48,30 +48,12 @@ draw_compute_vertex_size(struct vertex_info *vinfo)
uint i;
vinfo->size = 0;
- for (i = 0; i < vinfo->num_attribs; i++) {
- switch (vinfo->attrib[i].emit) {
- case EMIT_OMIT:
- break;
- case EMIT_4UB:
- /* fall-through */
- case EMIT_1F_PSIZE:
- /* fall-through */
- case EMIT_1F:
- vinfo->size += 1;
- break;
- case EMIT_2F:
- vinfo->size += 2;
- break;
- case EMIT_3F:
- vinfo->size += 3;
- break;
- case EMIT_4F:
- vinfo->size += 4;
- break;
- default:
- assert(0);
- }
- }
+ for (i = 0; i < vinfo->num_attribs; i++)
+ vinfo->size += draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+ assert(vinfo->size % 4 == 0);
+ /* in dwords */
+ vinfo->size /= 4;
}
@@ -120,6 +102,13 @@ draw_dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data)
debug_printf("%u ", *data++);
debug_printf("%u ", *data++);
break;
+ case EMIT_4UB_BGRA:
+ debug_printf("EMIT_4UB_BGRA:\t");
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ debug_printf("%u ", *data++);
+ break;
default:
assert(0);
}
diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h
index 8c3c7befbc7..ca272371267 100644
--- a/src/gallium/auxiliary/draw/draw_vertex.h
+++ b/src/gallium/auxiliary/draw/draw_vertex.h
@@ -54,7 +54,8 @@ enum attrib_emit {
EMIT_2F,
EMIT_3F,
EMIT_4F,
- EMIT_4UB /**< XXX may need variations for RGBA vs BGRA, etc */
+ EMIT_4UB, /**< is RGBA like the rest */
+ EMIT_4UB_BGRA
};
@@ -141,9 +142,11 @@ void draw_dump_emitted_vertex(const struct vertex_info *vinfo,
const uint8_t *data);
-static INLINE unsigned draw_translate_vinfo_format(unsigned format )
+static INLINE unsigned draw_translate_vinfo_format(enum attrib_emit emit)
{
- switch (format) {
+ switch (emit) {
+ case EMIT_OMIT:
+ return PIPE_FORMAT_NONE;
case EMIT_1F:
case EMIT_1F_PSIZE:
return PIPE_FORMAT_R32_FLOAT;
@@ -155,10 +158,36 @@ static INLINE unsigned draw_translate_vinfo_format(unsigned format )
return PIPE_FORMAT_R32G32B32A32_FLOAT;
case EMIT_4UB:
return PIPE_FORMAT_R8G8B8A8_UNORM;
+ case EMIT_4UB_BGRA:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
default:
+ assert(!"unexpected format");
return PIPE_FORMAT_NONE;
}
}
+static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit)
+{
+ switch (emit) {
+ case EMIT_OMIT:
+ return 0;
+ case EMIT_1F:
+ case EMIT_1F_PSIZE:
+ return 1 * sizeof(float);
+ case EMIT_2F:
+ return 2 * sizeof(float);
+ case EMIT_3F:
+ return 3 * sizeof(float);
+ case EMIT_4F:
+ return 4 * sizeof(float);
+ case EMIT_4UB:
+ return 4 * sizeof(unsigned char);
+ case EMIT_4UB_BGRA:
+ return 4 * sizeof(unsigned char);
+ default:
+ assert(!"unexpected format");
+ return 0;
+ }
+}
#endif /* DRAW_VERTEX_H */
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index ece1ddde0cb..8f8bbe7cb88 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -401,13 +401,11 @@ static boolean emit_output( struct aos_compilation *cp,
emit_store_R32G32B32A32(cp, ptr, dataXMM);
break;
case EMIT_4UB:
- if (1) {
- emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
- emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
- }
- else {
- emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
- }
+ emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
+ break;
+ case EMIT_4UB_BGRA:
+ emit_swizzle(cp, dataXMM, dataXMM, SHUF(Z,Y,X,W));
+ emit_store_R8G8B8A8_UNORM(cp, ptr, dataXMM);
break;
default:
AOS_ERROR(cp, "unhandled output format");
diff --git a/src/gallium/auxiliary/gallivm/lp_bld.h b/src/gallium/auxiliary/gallivm/lp_bld.h
new file mode 100644
index 00000000000..70a4960f913
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld.h
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Wrapper for LLVM header file #includes.
+ */
+
+
+#ifndef LP_BLD_H
+#define LP_BLD_H
+
+
+#include <llvm-c/Core.h>
+
+
+/** Set version to 0 if missing to avoid #ifdef HAVE_LLVM everywhere */
+#ifndef HAVE_LLVM
+#define HAVE_LLVM 0x0207
+#endif
+
+
+#endif /* LP_BLD_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
index 634575670db..0f99fec65ed 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_alpha.h
@@ -35,7 +35,7 @@
#define LP_BLD_ALPHA_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct pipe_alpha_state;
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 32f9e5201c5..8e8fcccf564 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -232,6 +232,37 @@ lp_build_add(struct lp_build_context *bld,
}
+/** Return the sum of the elements of a */
+LLVMValueRef
+lp_build_sum_vector(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMValueRef index, res;
+ int i;
+
+ if (a == bld->zero)
+ return bld->zero;
+ if (a == bld->undef)
+ return bld->undef;
+ assert(type.length > 1);
+
+ assert(!bld->type.norm);
+
+ index = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ res = LLVMBuildExtractElement(bld->builder, a, index, "");
+
+ for (i = 1; i < type.length; i++) {
+ index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ res = LLVMBuildAdd(bld->builder, res,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ "");
+ }
+
+ return res;
+}
+
+
/**
* Generate a - b
*/
@@ -330,12 +361,12 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
LLVMValueRef c8;
LLVMValueRef ab;
- c8 = lp_build_int_const_scalar(i16_type, 8);
+ c8 = lp_build_const_int_vec(i16_type, 8);
#if 0
/* a*b/255 ~= (a*(b + 1)) >> 256 */
- b = LLVMBuildAdd(builder, b, lp_build_int_const_scalar(i16_type, 1), "");
+ b = LLVMBuildAdd(builder, b, lp_build_const_int_vec(i16_type, 1), "");
ab = LLVMBuildMul(builder, a, b, "");
#else
@@ -343,7 +374,7 @@ lp_build_mul_u8n(LLVMBuilderRef builder,
/* ab/255 ~= (ab + (ab >> 8) + 0x80) >> 8 */
ab = LLVMBuildMul(builder, a, b, "");
ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c8, ""), "");
- ab = LLVMBuildAdd(builder, ab, lp_build_int_const_scalar(i16_type, 0x80), "");
+ ab = LLVMBuildAdd(builder, ab, lp_build_const_int_vec(i16_type, 0x80), "");
#endif
@@ -398,7 +429,7 @@ lp_build_mul(struct lp_build_context *bld,
}
if(type.fixed)
- shift = lp_build_int_const_scalar(type, type.width/2);
+ shift = lp_build_const_int_vec(type, type.width/2);
else
shift = NULL;
@@ -460,7 +491,7 @@ lp_build_mul_imm(struct lp_build_context *bld,
* for Inf and NaN.
*/
unsigned mantissa = lp_mantissa(bld->type);
- factor = lp_build_int_const_scalar(bld->type, (unsigned long long)shift << mantissa);
+ factor = lp_build_const_int_vec(bld->type, (unsigned long long)shift << mantissa);
a = LLVMBuildBitCast(bld->builder, a, lp_build_int_vec_type(bld->type), "");
a = LLVMBuildAdd(bld->builder, a, factor, "");
a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(bld->type), "");
@@ -468,12 +499,12 @@ lp_build_mul_imm(struct lp_build_context *bld,
#endif
}
else {
- factor = lp_build_const_scalar(bld->type, shift);
+ factor = lp_build_const_vec(bld->type, shift);
return LLVMBuildShl(bld->builder, a, factor, "");
}
}
- factor = lp_build_const_scalar(bld->type, (double)b);
+ factor = lp_build_const_vec(bld->type, (double)b);
return lp_build_mul(bld, a, factor);
}
@@ -536,7 +567,7 @@ lp_build_lerp(struct lp_build_context *bld,
* but it will be wrong for other uses. Basically we need a more
* powerful lp_type, capable of further distinguishing the values
* interpretation from the value storage. */
- res = LLVMBuildAnd(bld->builder, res, lp_build_int_const_scalar(bld->type, (1 << bld->type.width/2) - 1), "");
+ res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(bld->type, (1 << bld->type.width/2) - 1), "");
return res;
}
@@ -644,13 +675,26 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) {
/* Mask out the sign bit */
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- unsigned long long absMask = ~(1ULL << (type.width - 1));
- LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
- a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
- a = LLVMBuildAnd(bld->builder, a, mask, "");
- a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
- return a;
+ if (type.length == 1) {
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ LLVMTypeRef float_type = LLVMFloatType();
+ unsigned long long absMask = ~(1ULL << (type.width - 1));
+ LLVMValueRef mask = LLVMConstInt(int_type, absMask, 0);
+ a = LLVMBuildBitCast(bld->builder, a, int_type, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildBitCast(bld->builder, a, float_type, "");
+ return a;
+ }
+ else {
+ /* vector of floats */
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ unsigned long long absMask = ~(1ULL << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(type, ((unsigned long long) absMask));
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+ return a;
+ }
}
if(type.width*type.length == 128 && util_cpu_caps.has_ssse3) {
@@ -676,12 +720,12 @@ lp_build_negate(struct lp_build_context *bld,
}
+/** Return -1, 0 or +1 depending on the sign of a */
LLVMValueRef
lp_build_sgn(struct lp_build_context *bld,
LLVMValueRef a)
{
const struct lp_type type = bld->type;
- LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMValueRef cond;
LLVMValueRef res;
@@ -691,27 +735,42 @@ lp_build_sgn(struct lp_build_context *bld,
res = bld->one;
}
else if(type.floating) {
- /* Take the sign bit and add it to 1 constant */
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMTypeRef vec_type;
+ LLVMTypeRef int_type;
+ LLVMValueRef mask;
LLVMValueRef sign;
LLVMValueRef one;
- sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ unsigned long long maskBit = (unsigned long long)1 << (type.width - 1);
+
+ if (type.length == 1) {
+ int_type = lp_build_int_elem_type(type);
+ vec_type = lp_build_elem_type(type);
+ mask = LLVMConstInt(int_type, maskBit, 0);
+ }
+ else {
+ /* vector */
+ int_type = lp_build_int_vec_type(type);
+ vec_type = lp_build_vec_type(type);
+ mask = lp_build_const_int_vec(type, maskBit);
+ }
+
+ /* Take the sign bit and add it to 1 constant */
+ sign = LLVMBuildBitCast(bld->builder, a, int_type, "");
sign = LLVMBuildAnd(bld->builder, sign, mask, "");
- one = LLVMConstBitCast(bld->one, int_vec_type);
+ one = LLVMConstBitCast(bld->one, int_type);
res = LLVMBuildOr(bld->builder, sign, one, "");
res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
}
else
{
- LLVMValueRef minus_one = lp_build_const_scalar(type, -1.0);
+ LLVMValueRef minus_one = lp_build_const_vec(type, -1.0);
cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero);
res = lp_build_select(bld, cond, bld->one, minus_one);
}
/* Handle zero */
cond = lp_build_cmp(bld, PIPE_FUNC_EQUAL, a, bld->zero);
- res = lp_build_select(bld, cond, bld->zero, bld->one);
+ res = lp_build_select(bld, cond, bld->zero, res);
return res;
}
@@ -730,8 +789,8 @@ lp_build_set_sign(struct lp_build_context *bld,
const struct lp_type type = bld->type;
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMTypeRef vec_type = lp_build_vec_type(type);
- LLVMValueRef shift = lp_build_int_const_scalar(type, type.width - 1);
- LLVMValueRef mask = lp_build_int_const_scalar(type,
+ LLVMValueRef shift = lp_build_const_int_vec(type, type.width - 1);
+ LLVMValueRef mask = lp_build_const_int_vec(type,
~((unsigned long long) 1 << (type.width - 1)));
LLVMValueRef val, res;
@@ -753,7 +812,7 @@ lp_build_set_sign(struct lp_build_context *bld,
/**
- * Convert vector of int to vector of float.
+ * Convert vector of (or scalar) int to vector of (or scalar) float.
*/
LLVMValueRef
lp_build_int_to_float(struct lp_build_context *bld,
@@ -764,7 +823,11 @@ lp_build_int_to_float(struct lp_build_context *bld,
assert(type.floating);
/*assert(lp_check_value(type, a));*/
- {
+ if (type.length == 1) {
+ LLVMTypeRef float_type = LLVMFloatType();
+ return LLVMBuildSIToFP(bld->builder, a, float_type, "");
+ }
+ else {
LLVMTypeRef vec_type = lp_build_vec_type(type);
/*LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);*/
LLVMValueRef res;
@@ -866,6 +929,13 @@ lp_build_floor(struct lp_build_context *bld,
assert(type.floating);
+ if (type.length == 1) {
+ LLVMValueRef res;
+ res = lp_build_ifloor(bld, a);
+ res = LLVMBuildSIToFP(bld->builder, res, LLVMFloatType(), "");
+ return res;
+ }
+
if(util_cpu_caps.has_sse4_1)
return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_FLOOR);
else {
@@ -921,15 +991,24 @@ lp_build_itrunc(struct lp_build_context *bld,
LLVMValueRef a)
{
const struct lp_type type = bld->type;
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(type.floating);
- assert(lp_check_value(type, a));
- return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+ if (type.length == 1) {
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ return LLVMBuildFPToSI(bld->builder, a, int_type, "");
+ }
+ else {
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ assert(lp_check_value(type, a));
+ return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+ }
}
+/**
+ * Convert float[] to int[] with round().
+ */
LLVMValueRef
lp_build_iround(struct lp_build_context *bld,
LLVMValueRef a)
@@ -939,6 +1018,15 @@ lp_build_iround(struct lp_build_context *bld,
LLVMValueRef res;
assert(type.floating);
+
+ if (type.length == 1) {
+ /* scalar float to int */
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ /* XXX we want rounding here! */
+ res = LLVMBuildFPToSI(bld->builder, a, int_type, "");
+ return res;
+ }
+
assert(lp_check_value(type, a));
if(util_cpu_caps.has_sse4_1) {
@@ -946,7 +1034,7 @@ lp_build_iround(struct lp_build_context *bld,
}
else {
LLVMTypeRef vec_type = lp_build_vec_type(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef sign;
LLVMValueRef half;
@@ -955,7 +1043,7 @@ lp_build_iround(struct lp_build_context *bld,
sign = LLVMBuildAnd(bld->builder, sign, mask, "");
/* sign * 0.5 */
- half = lp_build_const_scalar(type, 0.5);
+ half = lp_build_const_vec(type, 0.5);
half = LLVMBuildBitCast(bld->builder, half, int_vec_type, "");
half = LLVMBuildOr(bld->builder, sign, half, "");
half = LLVMBuildBitCast(bld->builder, half, vec_type, "");
@@ -981,6 +1069,14 @@ lp_build_ifloor(struct lp_build_context *bld,
LLVMValueRef res;
assert(type.floating);
+
+ if (type.length == 1) {
+ /* scalar float to int */
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+ res = LLVMBuildFPToSI(bld->builder, a, int_type, "");
+ return res;
+ }
+
assert(lp_check_value(type, a));
if(util_cpu_caps.has_sse4_1) {
@@ -990,18 +1086,18 @@ lp_build_ifloor(struct lp_build_context *bld,
/* Take the sign bit and add it to 1 constant */
LLVMTypeRef vec_type = lp_build_vec_type(type);
unsigned mantissa = lp_mantissa(type);
- LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
LLVMValueRef sign;
LLVMValueRef offset;
/* sign = a < 0 ? ~0 : 0 */
sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
sign = LLVMBuildAnd(bld->builder, sign, mask, "");
- sign = LLVMBuildAShr(bld->builder, sign, lp_build_int_const_scalar(type, type.width - 1), "");
+ sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "");
lp_build_name(sign, "floor.sign");
/* offset = -0.99999(9)f */
- offset = lp_build_const_scalar(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
+ offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
offset = LLVMConstBitCast(offset, int_vec_type);
/* offset = a < 0 ? -0.99999(9)f : 0.0f */
@@ -1172,7 +1268,7 @@ lp_build_exp(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log2(e) = 1/log(2) */
- LLVMValueRef log2e = lp_build_const_scalar(bld->type, 1.4426950408889634);
+ LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634);
return lp_build_mul(bld, log2e, lp_build_exp2(bld, x));
}
@@ -1186,7 +1282,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
- LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
+ LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529);
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@@ -1207,6 +1303,7 @@ lp_build_polynomial(struct lp_build_context *bld,
unsigned num_coeffs)
{
const struct lp_type type = bld->type;
+ LLVMTypeRef float_type = LLVMFloatType();
LLVMValueRef res = NULL;
unsigned i;
@@ -1216,7 +1313,13 @@ lp_build_polynomial(struct lp_build_context *bld,
__FUNCTION__);
for (i = num_coeffs; i--; ) {
- LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]);
+ LLVMValueRef coeff;
+
+ if (type.length == 1)
+ coeff = LLVMConstReal(float_type, coeffs[i]);
+ else
+ coeff = lp_build_const_vec(type, coeffs[i]);
+
if(res)
res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
else
@@ -1272,11 +1375,11 @@ lp_build_exp2_approx(struct lp_build_context *bld,
assert(type.floating && type.width == 32);
- x = lp_build_min(bld, x, lp_build_const_scalar(type, 129.0));
- x = lp_build_max(bld, x, lp_build_const_scalar(type, -126.99999));
+ x = lp_build_min(bld, x, lp_build_const_vec(type, 129.0));
+ x = lp_build_max(bld, x, lp_build_const_vec(type, -126.99999));
/* ipart = int(x - 0.5) */
- ipart = LLVMBuildSub(bld->builder, x, lp_build_const_scalar(type, 0.5f), "");
+ ipart = LLVMBuildSub(bld->builder, x, lp_build_const_vec(type, 0.5f), "");
ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, "");
/* fpart = x - ipart */
@@ -1286,8 +1389,8 @@ lp_build_exp2_approx(struct lp_build_context *bld,
if(p_exp2_int_part || p_exp2) {
/* expipart = (float) (1 << ipart) */
- expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_int_const_scalar(type, 127), "");
- expipart = LLVMBuildShl(bld->builder, expipart, lp_build_int_const_scalar(type, 23), "");
+ expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_const_int_vec(type, 127), "");
+ expipart = LLVMBuildShl(bld->builder, expipart, lp_build_const_int_vec(type, 23), "");
expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, "");
}
@@ -1353,8 +1456,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- LLVMValueRef expmask = lp_build_int_const_scalar(type, 0x7f800000);
- LLVMValueRef mantmask = lp_build_int_const_scalar(type, 0x007fffff);
+ LLVMValueRef expmask = lp_build_const_int_vec(type, 0x7f800000);
+ LLVMValueRef mantmask = lp_build_const_int_vec(type, 0x007fffff);
LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type);
LLVMValueRef i = NULL;
@@ -1379,8 +1482,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
}
if(p_floor_log2 || p_log2) {
- logexp = LLVMBuildLShr(bld->builder, exp, lp_build_int_const_scalar(type, 23), "");
- logexp = LLVMBuildSub(bld->builder, logexp, lp_build_int_const_scalar(type, 127), "");
+ logexp = LLVMBuildLShr(bld->builder, exp, lp_build_const_int_vec(type, 23), "");
+ logexp = LLVMBuildSub(bld->builder, logexp, lp_build_const_int_vec(type, 127), "");
logexp = LLVMBuildSIToFP(bld->builder, logexp, vec_type, "");
}
@@ -1410,11 +1513,87 @@ lp_build_log2_approx(struct lp_build_context *bld,
}
+/** scalar version of above function */
+static void
+lp_build_float_log2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp,
+ LLVMValueRef *p_floor_log2,
+ LLVMValueRef *p_log2)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef float_type = LLVMFloatType();
+ LLVMTypeRef int_type = LLVMIntType(type.width);
+
+ LLVMValueRef expmask = LLVMConstInt(int_type, 0x7f800000, 0);
+ LLVMValueRef mantmask = LLVMConstInt(int_type, 0x007fffff, 0);
+ LLVMValueRef one = LLVMConstBitCast(bld->one, int_type);
+
+ LLVMValueRef i = NULL;
+ LLVMValueRef exp = NULL;
+ LLVMValueRef mant = NULL;
+ LLVMValueRef logexp = NULL;
+ LLVMValueRef logmant = NULL;
+ LLVMValueRef res = NULL;
+
+ if(p_exp || p_floor_log2 || p_log2) {
+ /* TODO: optimize the constant case */
+ if(LLVMIsConstant(x))
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
+
+ assert(type.floating && type.width == 32);
+
+ i = LLVMBuildBitCast(bld->builder, x, int_type, "");
+
+ /* exp = (float) exponent(x) */
+ exp = LLVMBuildAnd(bld->builder, i, expmask, "");
+ }
+
+ if(p_floor_log2 || p_log2) {
+ LLVMValueRef c23 = LLVMConstInt(int_type, 23, 0);
+ LLVMValueRef c127 = LLVMConstInt(int_type, 127, 0);
+ logexp = LLVMBuildLShr(bld->builder, exp, c23, "");
+ logexp = LLVMBuildSub(bld->builder, logexp, c127, "");
+ logexp = LLVMBuildSIToFP(bld->builder, logexp, float_type, "");
+ }
+
+ if(p_log2) {
+ /* mant = (float) mantissa(x) */
+ mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
+ mant = LLVMBuildOr(bld->builder, mant, one, "");
+ mant = LLVMBuildBitCast(bld->builder, mant, float_type, "");
+
+ logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
+ Elements(lp_build_log2_polynomial));
+
+ /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
+ logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
+
+ res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
+ }
+
+ if(p_exp)
+ *p_exp = exp;
+
+ if(p_floor_log2)
+ *p_floor_log2 = logexp;
+
+ if(p_log2)
+ *p_log2 = res;
+}
+
+
LLVMValueRef
lp_build_log2(struct lp_build_context *bld,
LLVMValueRef x)
{
LLVMValueRef res;
- lp_build_log2_approx(bld, x, NULL, NULL, &res);
+ if (bld->type.length == 1) {
+ lp_build_float_log2_approx(bld, x, NULL, NULL, &res);
+ }
+ else {
+ lp_build_log2_approx(bld, x, NULL, NULL, &res);
+ }
return res;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.h b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
index 55385e3a66a..31efa9921ce 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.h
@@ -37,7 +37,7 @@
#define LP_BLD_ARIT_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_type;
@@ -57,6 +57,10 @@ lp_build_add(struct lp_build_context *bld,
LLVMValueRef b);
LLVMValueRef
+lp_build_sum_vector(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
lp_build_sub(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_blend.h b/src/gallium/auxiliary/gallivm/lp_bld_blend.h
index da272e549f3..ebbdb1a604c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_blend.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_blend.h
@@ -40,7 +40,7 @@
* for a standalone example.
*/
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "pipe/p_format.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index c8eaa8c3940..57843e9a60c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -221,8 +221,16 @@ lp_build_undef(struct lp_type type)
LLVMValueRef
lp_build_zero(struct lp_type type)
{
- LLVMTypeRef vec_type = lp_build_vec_type(type);
- return LLVMConstNull(vec_type);
+ if (type.length == 1) {
+ if (type.floating)
+ return LLVMConstReal(LLVMFloatType(), 0.0);
+ else
+ return LLVMConstInt(LLVMIntType(type.width), 0, 0);
+ }
+ else {
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ return LLVMConstNull(vec_type);
+ }
}
@@ -255,7 +263,7 @@ lp_build_one(struct lp_type type)
if(type.sign)
/* TODO: Unfortunately this caused "Tried to create a shift operation
* on a non-integer type!" */
- vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1));
+ vec = LLVMConstLShr(vec, lp_build_const_int_vec(type, 1));
#endif
return vec;
@@ -264,13 +272,19 @@ lp_build_one(struct lp_type type)
for(i = 1; i < type.length; ++i)
elems[i] = elems[0];
- return LLVMConstVector(elems, type.length);
+ if (type.length == 1)
+ return elems[0];
+ else
+ return LLVMConstVector(elems, type.length);
}
+/**
+ * Build constant-valued vector from a scalar value.
+ */
LLVMValueRef
-lp_build_const_scalar(struct lp_type type,
- double val)
+lp_build_const_vec(struct lp_type type,
+ double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
@@ -295,7 +309,7 @@ lp_build_const_scalar(struct lp_type type,
LLVMValueRef
-lp_build_int_const_scalar(struct lp_type type,
+lp_build_const_int_vec(struct lp_type type,
long long val)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h
index cb8e1c7b006..9ca2f0664eb 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h
@@ -37,9 +37,9 @@
#define LP_BLD_CONST_H
-#include <llvm-c/Core.h>
+#include "pipe/p_compiler.h"
+#include "gallivm/lp_bld.h"
-#include <pipe/p_compiler.h>
struct lp_type;
@@ -85,13 +85,11 @@ lp_build_one(struct lp_type type);
LLVMValueRef
-lp_build_const_scalar(struct lp_type type,
- double val);
+lp_build_const_vec(struct lp_type type, double val);
LLVMValueRef
-lp_build_int_const_scalar(struct lp_type type,
- long long val);
+lp_build_const_int_vec(struct lp_type type, long long val);
LLVMValueRef
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
index f77cf787213..3f7f2ebde9c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
@@ -114,13 +114,13 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
scale = (double)mask/ubound;
bias = (double)((unsigned long long)1 << (mantissa - n));
- res = LLVMBuildMul(builder, src, lp_build_const_scalar(src_type, scale), "");
- res = LLVMBuildAdd(builder, res, lp_build_const_scalar(src_type, bias), "");
+ res = LLVMBuildMul(builder, src, lp_build_const_vec(src_type, scale), "");
+ res = LLVMBuildAdd(builder, res, lp_build_const_vec(src_type, bias), "");
res = LLVMBuildBitCast(builder, res, int_vec_type, "");
if(dst_width > n) {
int shift = dst_width - n;
- res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
+ res = LLVMBuildShl(builder, res, lp_build_const_int_vec(src_type, shift), "");
/* TODO: Fill in the empty lower bits for additional precision? */
/* YES: this fixes progs/trivial/tri-z-eq.c.
@@ -130,21 +130,21 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
#if 0
{
LLVMValueRef msb;
- msb = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, dst_width - 1), "");
- msb = LLVMBuildShl(builder, msb, lp_build_int_const_scalar(src_type, shift), "");
- msb = LLVMBuildSub(builder, msb, lp_build_int_const_scalar(src_type, 1), "");
+ msb = LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, dst_width - 1), "");
+ msb = LLVMBuildShl(builder, msb, lp_build_const_int_vec(src_type, shift), "");
+ msb = LLVMBuildSub(builder, msb, lp_build_const_int_vec(src_type, 1), "");
res = LLVMBuildOr(builder, res, msb, "");
}
#elif 0
while(shift > 0) {
- res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, n), ""), "");
+ res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_const_int_vec(src_type, n), ""), "");
shift -= n;
n *= 2;
}
#endif
}
else
- res = LLVMBuildAnd(builder, res, lp_build_int_const_scalar(src_type, mask), "");
+ res = LLVMBuildAnd(builder, res, lp_build_const_int_vec(src_type, mask), "");
return res;
}
@@ -183,10 +183,10 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
if(src_width > mantissa) {
int shift = src_width - mantissa;
- res = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(dst_type, shift), "");
+ res = LLVMBuildLShr(builder, res, lp_build_const_int_vec(dst_type, shift), "");
}
- bias_ = lp_build_const_scalar(dst_type, bias);
+ bias_ = lp_build_const_vec(dst_type, bias);
res = LLVMBuildOr(builder,
res,
@@ -195,7 +195,7 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
res = LLVMBuildBitCast(builder, res, vec_type, "");
res = LLVMBuildSub(builder, res, bias_, "");
- res = LLVMBuildMul(builder, res, lp_build_const_scalar(dst_type, scale), "");
+ res = LLVMBuildMul(builder, res, lp_build_const_vec(dst_type, scale), "");
return res;
}
@@ -251,7 +251,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_min == 0.0)
thres = bld.zero;
else
- thres = lp_build_const_scalar(src_type, dst_min);
+ thres = lp_build_const_vec(src_type, dst_min);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_max(&bld, tmp[i], thres);
}
@@ -260,7 +260,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(dst_max == 1.0)
thres = bld.one;
else
- thres = lp_build_const_scalar(src_type, dst_max);
+ thres = lp_build_const_vec(src_type, dst_max);
for(i = 0; i < num_tmps; ++i)
tmp[i] = lp_build_min(&bld, tmp[i], thres);
}
@@ -288,7 +288,7 @@ lp_build_conv(LLVMBuilderRef builder,
LLVMTypeRef tmp_vec_type;
if (dst_scale != 1.0) {
- LLVMValueRef scale = lp_build_const_scalar(tmp_type, dst_scale);
+ LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -315,7 +315,7 @@ lp_build_conv(LLVMBuilderRef builder,
/* FIXME: compensate different offsets too */
if(src_shift > dst_shift) {
- LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, src_shift - dst_shift);
+ LLVMValueRef shift = lp_build_const_int_vec(tmp_type, src_shift - dst_shift);
for(i = 0; i < num_tmps; ++i)
if(src_type.sign)
tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, "");
@@ -388,7 +388,7 @@ lp_build_conv(LLVMBuilderRef builder,
}
if (src_scale != 1.0) {
- LLVMValueRef scale = lp_build_const_scalar(tmp_type, 1.0/src_scale);
+ LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
}
@@ -400,7 +400,7 @@ lp_build_conv(LLVMBuilderRef builder,
/* FIXME: compensate different offsets too */
if(src_shift < dst_shift) {
- LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, dst_shift - src_shift);
+ LLVMValueRef shift = lp_build_const_int_vec(tmp_type, dst_shift - src_shift);
for(i = 0; i < num_tmps; ++i)
tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
index 948e68fae4f..628831c3ada 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
@@ -37,7 +37,7 @@
#define LP_BLD_CONV_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
index 583e6132b4b..7b010cbdb09 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
@@ -30,7 +30,7 @@
#define LP_BLD_DEBUG_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "pipe/p_compiler.h"
#include "util/u_string.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.c b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
index f08f8eb6d8b..4ce1a27a061 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.c
@@ -52,7 +52,14 @@
* Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ...
* ... ... ... ... ... ... ... ... ...
*
- * FIXME: Code generate stencil test
+ *
+ * Stencil test:
+ * Two-sided stencil test is supported but probably not as efficient as
+ * it could be. Currently, we use if/then/else constructs to do the
+ * operations for front vs. back-facing polygons. We could probably do
+ * both the front and back arithmetic then use a Select() instruction to
+ * choose the result depending on polyon orientation. We'd have to
+ * measure performance both ways and see which is better.
*
* @author Jose Fonseca <[email protected]>
*/
@@ -61,11 +68,264 @@
#include "util/u_format.h"
#include "lp_bld_type.h"
+#include "lp_bld_arit.h"
#include "lp_bld_const.h"
#include "lp_bld_logic.h"
#include "lp_bld_flow.h"
#include "lp_bld_debug.h"
#include "lp_bld_depth.h"
+#include "lp_bld_swizzle.h"
+
+
+/** Used to select fields from pipe_stencil_state */
+enum stencil_op {
+ S_FAIL_OP,
+ Z_FAIL_OP,
+ Z_PASS_OP
+};
+
+
+
+/**
+ * Do the stencil test comparison (compare FB stencil values against ref value).
+ * This will be used twice when generating two-sided stencil code.
+ * \param stencil the front/back stencil state
+ * \param stencilRef the stencil reference value, replicated as a vector
+ * \param stencilVals vector of stencil values from framebuffer
+ * \return vector mask of pass/fail values (~0 or 0)
+ */
+static LLVMValueRef
+lp_build_stencil_test_single(struct lp_build_context *bld,
+ const struct pipe_stencil_state *stencil,
+ LLVMValueRef stencilRef,
+ LLVMValueRef stencilVals)
+{
+ const unsigned stencilMax = 255; /* XXX fix */
+ struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ assert(type.sign);
+
+ assert(stencil->enabled);
+
+ if (stencil->valuemask != stencilMax) {
+ /* compute stencilRef = stencilRef & valuemask */
+ LLVMValueRef valuemask = lp_build_const_int_vec(type, stencil->valuemask);
+ stencilRef = LLVMBuildAnd(bld->builder, stencilRef, valuemask, "");
+ /* compute stencilVals = stencilVals & valuemask */
+ stencilVals = LLVMBuildAnd(bld->builder, stencilVals, valuemask, "");
+ }
+
+ res = lp_build_cmp(bld, stencil->func, stencilVals, stencilRef);
+
+ return res;
+}
+
+
+/**
+ * Do the one or two-sided stencil test comparison.
+ * \sa lp_build_stencil_test_single
+ * \param face an integer indicating front (+) or back (-) facing polygon.
+ * If NULL, assume front-facing.
+ */
+static LLVMValueRef
+lp_build_stencil_test(struct lp_build_context *bld,
+ const struct pipe_stencil_state stencil[2],
+ LLVMValueRef stencilRefs[2],
+ LLVMValueRef stencilVals,
+ LLVMValueRef face)
+{
+ LLVMValueRef res;
+
+ assert(stencil[0].enabled);
+
+ if (stencil[1].enabled && face) {
+ /* do two-sided test */
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+ LLVMValueRef front_facing;
+ LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
+ LLVMValueRef result = bld->undef;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ lp_build_flow_scope_declare(flow_ctx, &result);
+
+ /* front_facing = face > 0.0 */
+ front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
+ {
+ result = lp_build_stencil_test_single(bld, &stencil[0],
+ stencilRefs[0], stencilVals);
+ }
+ lp_build_else(&if_ctx);
+ {
+ result = lp_build_stencil_test_single(bld, &stencil[1],
+ stencilRefs[1], stencilVals);
+ }
+ lp_build_endif(&if_ctx);
+
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+
+ res = result;
+ }
+ else {
+ /* do single-side test */
+ res = lp_build_stencil_test_single(bld, &stencil[0],
+ stencilRefs[0], stencilVals);
+ }
+
+ return res;
+}
+
+
+/**
+ * Apply the stencil operator (add/sub/keep/etc) to the given vector
+ * of stencil values.
+ * \return new stencil values vector
+ */
+static LLVMValueRef
+lp_build_stencil_op_single(struct lp_build_context *bld,
+ const struct pipe_stencil_state *stencil,
+ enum stencil_op op,
+ LLVMValueRef stencilRef,
+ LLVMValueRef stencilVals,
+ LLVMValueRef mask)
+
+{
+ const unsigned stencilMax = 255; /* XXX fix */
+ struct lp_type type = bld->type;
+ LLVMValueRef res;
+ LLVMValueRef max = lp_build_const_int_vec(type, stencilMax);
+ unsigned stencil_op;
+
+ assert(type.sign);
+
+ switch (op) {
+ case S_FAIL_OP:
+ stencil_op = stencil->fail_op;
+ break;
+ case Z_FAIL_OP:
+ stencil_op = stencil->zfail_op;
+ break;
+ case Z_PASS_OP:
+ stencil_op = stencil->zpass_op;
+ break;
+ default:
+ assert(0 && "Invalid stencil_op mode");
+ stencil_op = PIPE_STENCIL_OP_KEEP;
+ }
+
+ switch (stencil_op) {
+ case PIPE_STENCIL_OP_KEEP:
+ res = stencilVals;
+ /* we can return early for this case */
+ return res;
+ case PIPE_STENCIL_OP_ZERO:
+ res = bld->zero;
+ break;
+ case PIPE_STENCIL_OP_REPLACE:
+ res = stencilRef;
+ break;
+ case PIPE_STENCIL_OP_INCR:
+ res = lp_build_add(bld, stencilVals, bld->one);
+ res = lp_build_min(bld, res, max);
+ break;
+ case PIPE_STENCIL_OP_DECR:
+ res = lp_build_sub(bld, stencilVals, bld->one);
+ res = lp_build_max(bld, res, bld->zero);
+ break;
+ case PIPE_STENCIL_OP_INCR_WRAP:
+ res = lp_build_add(bld, stencilVals, bld->one);
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ case PIPE_STENCIL_OP_DECR_WRAP:
+ res = lp_build_sub(bld, stencilVals, bld->one);
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ case PIPE_STENCIL_OP_INVERT:
+ res = LLVMBuildNot(bld->builder, stencilVals, "");
+ res = LLVMBuildAnd(bld->builder, res, max, "");
+ break;
+ default:
+ assert(0 && "bad stencil op mode");
+ res = NULL;
+ }
+
+ if (stencil->writemask != stencilMax) {
+ /* compute res = (res & mask) | (stencilVals & ~mask) */
+ LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask);
+ LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask");
+ LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1");
+ LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2");
+ res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2");
+ }
+
+ /* only the update the vector elements enabled by 'mask' */
+ res = lp_build_select(bld, mask, res, stencilVals);
+
+ return res;
+}
+
+
+/**
+ * Do the one or two-sided stencil test op/update.
+ */
+static LLVMValueRef
+lp_build_stencil_op(struct lp_build_context *bld,
+ const struct pipe_stencil_state stencil[2],
+ enum stencil_op op,
+ LLVMValueRef stencilRefs[2],
+ LLVMValueRef stencilVals,
+ LLVMValueRef mask,
+ LLVMValueRef face)
+
+{
+ assert(stencil[0].enabled);
+
+ if (stencil[1].enabled && face) {
+ /* do two-sided op */
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+ LLVMValueRef front_facing;
+ LLVMValueRef zero = LLVMConstReal(LLVMFloatType(), 0.0);
+ LLVMValueRef result = bld->undef;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ lp_build_flow_scope_declare(flow_ctx, &result);
+
+ /* front_facing = face > 0.0 */
+ front_facing = LLVMBuildFCmp(bld->builder, LLVMRealUGT, face, zero, "");
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, front_facing);
+ {
+ result = lp_build_stencil_op_single(bld, &stencil[0], op,
+ stencilRefs[0], stencilVals, mask);
+ }
+ lp_build_else(&if_ctx);
+ {
+ result = lp_build_stencil_op_single(bld, &stencil[1], op,
+ stencilRefs[1], stencilVals, mask);
+ }
+ lp_build_endif(&if_ctx);
+
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+
+ return result;
+ }
+ else {
+ /* do single-sided op */
+ return lp_build_stencil_op_single(bld, &stencil[0], op,
+ stencilRefs[0], stencilVals, mask);
+ }
+}
+
/**
@@ -109,105 +369,303 @@ lp_depth_type(const struct util_format_description *format_desc,
/**
- * Depth test.
+ * Compute bitmask and bit shift to apply to the incoming fragment Z values
+ * and the Z buffer values needed before doing the Z comparison.
+ *
+ * Note that we leave the Z bits in the position that we find them
+ * in the Z buffer (typically 0xffffff00 or 0x00ffffff). That lets us
+ * get by with fewer bit twiddling steps.
*/
-void
-lp_build_depth_test(LLVMBuilderRef builder,
- const struct pipe_depth_state *state,
- struct lp_type type,
- const struct util_format_description *format_desc,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr)
+static boolean
+get_z_shift_and_mask(const struct util_format_description *format_desc,
+ unsigned *shift, unsigned *mask)
{
- struct lp_build_context bld;
+ const unsigned total_bits = format_desc->block.bits;
unsigned z_swizzle;
- LLVMValueRef dst;
- LLVMValueRef z_bitmask = NULL;
- LLVMValueRef test;
-
- if(!state->enabled)
- return;
-
+ int chan;
+ unsigned padding_left, padding_right;
+
assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
assert(format_desc->block.width == 1);
assert(format_desc->block.height == 1);
z_swizzle = format_desc->swizzle[0];
- if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
- return;
- /* Sanity checking */
- assert(z_swizzle < 4);
- assert(format_desc->block.bits == type.width);
- if(type.floating) {
- assert(z_swizzle == 0);
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT);
- assert(format_desc->channel[z_swizzle].size == format_desc->block.bits);
+ if (z_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
+ return FALSE;
+
+ padding_right = 0;
+ for (chan = 0; chan < z_swizzle; ++chan)
+ padding_right += format_desc->channel[chan].size;
+
+ padding_left =
+ total_bits - (padding_right + format_desc->channel[z_swizzle].size);
+
+ if (padding_left || padding_right) {
+ unsigned long long mask_left = (1ULL << (total_bits - padding_left)) - 1;
+ unsigned long long mask_right = (1ULL << (padding_right)) - 1;
+ *mask = mask_left ^ mask_right;
}
else {
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
- assert(format_desc->channel[z_swizzle].normalized);
- assert(!type.fixed);
- assert(!type.sign);
- assert(type.norm);
+ *mask = 0xffffffff;
+ }
+
+ *shift = padding_left;
+
+ return TRUE;
+}
+
+
+/**
+ * Compute bitmask and bit shift to apply to the framebuffer pixel values
+ * to put the stencil bits in the least significant position.
+ * (i.e. 0x000000ff)
+ */
+static boolean
+get_s_shift_and_mask(const struct util_format_description *format_desc,
+ unsigned *shift, unsigned *mask)
+{
+ unsigned s_swizzle;
+ int chan, sz;
+
+ s_swizzle = format_desc->swizzle[1];
+
+ if (s_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
+ return FALSE;
+
+ *shift = 0;
+ for (chan = 0; chan < s_swizzle; chan++)
+ *shift += format_desc->channel[chan].size;
+
+ sz = format_desc->channel[s_swizzle].size;
+ *mask = (1U << sz) - 1U;
+
+ return TRUE;
+}
+
+
+
+/**
+ * Generate code for performing depth and/or stencil tests.
+ * We operate on a vector of values (typically a 2x2 quad).
+ *
+ * \param depth the depth test state
+ * \param stencil the front/back stencil state
+ * \param type the data type of the fragment depth/stencil values
+ * \param format_desc description of the depth/stencil surface
+ * \param mask the alive/dead pixel mask for the quad (vector)
+ * \param stencil_refs the front/back stencil ref values (scalar)
+ * \param z_src the incoming depth/stencil values (a 2x2 quad)
+ * \param zs_dst_ptr pointer to depth/stencil values in framebuffer
+ * \param facing contains float value indicating front/back facing polygon
+ */
+void
+lp_build_depth_stencil_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *depth,
+ const struct pipe_stencil_state stencil[2],
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef z_src,
+ LLVMValueRef zs_dst_ptr,
+ LLVMValueRef face)
+{
+ struct lp_build_context bld;
+ struct lp_build_context sbld;
+ struct lp_type s_type;
+ LLVMValueRef zs_dst, z_dst = NULL;
+ LLVMValueRef stencil_vals = NULL;
+ LLVMValueRef z_bitmask = NULL, stencil_shift = NULL;
+ LLVMValueRef z_pass = NULL, s_pass_mask = NULL;
+ LLVMValueRef orig_mask = mask->value;
+
+ /* Sanity checking */
+ {
+ const unsigned z_swizzle = format_desc->swizzle[0];
+ const unsigned s_swizzle = format_desc->swizzle[1];
+
+ assert(z_swizzle != UTIL_FORMAT_SWIZZLE_NONE ||
+ s_swizzle != UTIL_FORMAT_SWIZZLE_NONE);
+
+ assert(depth->enabled || stencil[0].enabled);
+
+ assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+
+ if (stencil[0].enabled) {
+ assert(format_desc->format == PIPE_FORMAT_Z24S8_UNORM ||
+ format_desc->format == PIPE_FORMAT_S8Z24_UNORM);
+ }
+
+ assert(z_swizzle < 4);
+ assert(format_desc->block.bits == type.width);
+ if (type.floating) {
+ assert(z_swizzle == 0);
+ assert(format_desc->channel[z_swizzle].type ==
+ UTIL_FORMAT_TYPE_FLOAT);
+ assert(format_desc->channel[z_swizzle].size ==
+ format_desc->block.bits);
+ }
+ else {
+ assert(format_desc->channel[z_swizzle].type ==
+ UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(format_desc->channel[z_swizzle].normalized);
+ assert(!type.fixed);
+ assert(!type.sign);
+ assert(type.norm);
+ }
}
- /* Setup build context */
+
+ /* Setup build context for Z vals */
lp_build_context_init(&bld, builder, type);
- dst = LLVMBuildLoad(builder, dst_ptr, "");
+ /* Setup build context for stencil vals */
+ s_type = lp_type_int_vec(type.width);
+ lp_build_context_init(&sbld, builder, s_type);
+
+ /* Load current z/stencil value from z/stencil buffer */
+ zs_dst = LLVMBuildLoad(builder, zs_dst_ptr, "");
+
+ lp_build_name(zs_dst, "zsbufval");
- lp_build_name(dst, "zsbuf");
- /* Align the source depth bits with the destination's, and mask out any
- * stencil or padding bits from both */
- if(format_desc->channel[z_swizzle].size == format_desc->block.bits) {
- assert(z_swizzle == 0);
- /* nothing to do */
+ /* Compute and apply the Z/stencil bitmasks and shifts.
+ */
+ {
+ unsigned z_shift, z_mask;
+ unsigned s_shift, s_mask;
+
+ if (get_z_shift_and_mask(format_desc, &z_shift, &z_mask)) {
+ if (z_shift) {
+ LLVMValueRef shift = lp_build_const_int_vec(type, z_shift);
+ z_src = LLVMBuildLShr(builder, z_src, shift, "");
+ }
+
+ if (z_mask != 0xffffffff) {
+ LLVMValueRef mask = lp_build_const_int_vec(type, z_mask);
+ z_src = LLVMBuildAnd(builder, z_src, mask, "");
+ z_dst = LLVMBuildAnd(builder, zs_dst, mask, "");
+ z_bitmask = mask; /* used below */
+ }
+ else {
+ z_dst = zs_dst;
+ }
+
+ lp_build_name(z_dst, "zsbuf.z");
+ }
+
+ if (get_s_shift_and_mask(format_desc, &s_shift, &s_mask)) {
+ if (s_shift) {
+ LLVMValueRef shift = lp_build_const_int_vec(type, s_shift);
+ stencil_vals = LLVMBuildLShr(builder, zs_dst, shift, "");
+ stencil_shift = shift; /* used below */
+ }
+ else {
+ stencil_vals = zs_dst;
+ }
+
+ if (s_mask != 0xffffffff) {
+ LLVMValueRef mask = lp_build_const_int_vec(type, s_mask);
+ stencil_vals = LLVMBuildAnd(builder, stencil_vals, mask, "");
+ }
+
+ lp_build_name(stencil_vals, "stencil");
+ }
}
- else {
- unsigned padding_left;
- unsigned padding_right;
- unsigned chan;
-
- assert(format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN);
- assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
- assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits);
- assert(format_desc->channel[z_swizzle].normalized);
-
- padding_right = 0;
- for(chan = 0; chan < z_swizzle; ++chan)
- padding_right += format_desc->channel[chan].size;
- padding_left = format_desc->block.bits -
- (padding_right + format_desc->channel[z_swizzle].size);
-
- if(padding_left || padding_right) {
- const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1;
- const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1;
- z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right);
+
+
+ if (stencil[0].enabled) {
+ /* convert scalar stencil refs into vectors */
+ stencil_refs[0] = lp_build_broadcast_scalar(&bld, stencil_refs[0]);
+ stencil_refs[1] = lp_build_broadcast_scalar(&bld, stencil_refs[1]);
+
+ s_pass_mask = lp_build_stencil_test(&sbld, stencil,
+ stencil_refs, stencil_vals, face);
+
+ /* apply stencil-fail operator */
+ {
+ LLVMValueRef s_fail_mask = lp_build_andc(&bld, orig_mask, s_pass_mask);
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, S_FAIL_OP,
+ stencil_refs, stencil_vals,
+ s_fail_mask, face);
+ }
+ }
+
+ if (depth->enabled) {
+ /* compare src Z to dst Z, returning 'pass' mask */
+ z_pass = lp_build_cmp(&bld, depth->func, z_src, z_dst);
+
+ if (!stencil[0].enabled) {
+ /* We can potentially skip all remaining operations here, but only
+ * if stencil is disabled because we still need to update the stencil
+ * buffer values. Don't need to update Z buffer values.
+ */
+ lp_build_mask_update(mask, z_pass);
+ }
+
+ if (depth->writemask) {
+ if(z_bitmask)
+ z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, "");
+ else
+ z_bitmask = mask->value;
+
+ z_dst = lp_build_select(&bld, z_bitmask, z_src, z_dst);
}
- if(padding_left)
- src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), "");
- if(padding_right)
- src = LLVMBuildAnd(builder, src, z_bitmask, "");
- if(padding_left || padding_right)
- dst = LLVMBuildAnd(builder, dst, z_bitmask, "");
+ if (stencil[0].enabled) {
+ /* update stencil buffer values according to z pass/fail result */
+ LLVMValueRef z_fail_mask, z_pass_mask;
+
+ /* apply Z-fail operator */
+ z_fail_mask = lp_build_andc(&bld, orig_mask, z_pass);
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_FAIL_OP,
+ stencil_refs, stencil_vals,
+ z_fail_mask, face);
+
+ /* apply Z-pass operator */
+ z_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, z_pass, "");
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP,
+ stencil_refs, stencil_vals,
+ z_pass_mask, face);
+ }
+ }
+ else {
+ /* No depth test: apply Z-pass operator to stencil buffer values which
+ * passed the stencil test.
+ */
+ s_pass_mask = LLVMBuildAnd(bld.builder, orig_mask, s_pass_mask, "");
+ stencil_vals = lp_build_stencil_op(&sbld, stencil, Z_PASS_OP,
+ stencil_refs, stencil_vals,
+ s_pass_mask, face);
}
- lp_build_name(dst, "zsbuf.z");
+ /* The Z bits are already in the right place but we may need to shift the
+ * stencil bits before ORing Z with Stencil to make the final pixel value.
+ */
+ if (stencil_vals && stencil_shift)
+ stencil_vals = LLVMBuildShl(bld.builder, stencil_vals,
+ stencil_shift, "");
- test = lp_build_cmp(&bld, state->func, src, dst);
- lp_build_mask_update(mask, test);
+ /* Finally, merge/store the z/stencil values */
+ if ((depth->enabled && depth->writemask) ||
+ (stencil[0].enabled && stencil[0].writemask)) {
- if(state->writemask) {
- if(z_bitmask)
- z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, "");
+ if (z_dst && stencil_vals)
+ zs_dst = LLVMBuildOr(bld.builder, z_dst, stencil_vals, "");
+ else if (z_dst)
+ zs_dst = z_dst;
else
- z_bitmask = mask->value;
+ zs_dst = stencil_vals;
- dst = lp_build_select(&bld, z_bitmask, src, dst);
- LLVMBuildStore(builder, dst, dst_ptr);
+ LLVMBuildStore(builder, zs_dst, zs_dst_ptr);
}
+
+ if (s_pass_mask)
+ lp_build_mask_update(mask, s_pass_mask);
+
+ if (depth->enabled && stencil[0].enabled)
+ lp_build_mask_update(mask, z_pass);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_depth.h b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
index 79d6981bb51..27dd46b625d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_depth.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_depth.h
@@ -36,7 +36,7 @@
#define LP_BLD_DEPTH_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct pipe_depth_state;
@@ -51,13 +51,16 @@ lp_depth_type(const struct util_format_description *format_desc,
void
-lp_build_depth_test(LLVMBuilderRef builder,
- const struct pipe_depth_state *state,
- struct lp_type type,
- const struct util_format_description *format_desc,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr);
+lp_build_depth_stencil_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *depth,
+ const struct pipe_stencil_state stencil[2],
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef zs_src,
+ LLVMValueRef zs_dst_ptr,
+ LLVMValueRef facing);
#endif /* !LP_BLD_DEPTH_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
index bc831389085..106fc03e46f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
@@ -308,7 +308,7 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow)
* Note: this function has no dependencies on the flow code and could
* be used elsewhere.
*/
-static LLVMBasicBlockRef
+LLVMBasicBlockRef
lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)
{
LLVMBasicBlockRef current_block;
@@ -648,7 +648,9 @@ lp_build_if(struct lp_build_if_state *ctx,
ifthen->phi[i] = LLVMBuildPhi(builder, LLVMTypeOf(*flow->variables[i]), "");
/* add add the initial value of the var from the entry block */
- LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->entry_block, 1);
+ if (!LLVMIsUndef(*flow->variables[i]))
+ LLVMAddIncoming(ifthen->phi[i], flow->variables[i],
+ &ifthen->entry_block, 1);
}
/* create/insert true_block before merge_block */
@@ -695,18 +697,21 @@ lp_build_endif(struct lp_build_if_state *ctx)
{
struct lp_build_flow_context *flow = ctx->flow;
struct lp_build_flow_if *ifthen;
+ LLVMBasicBlockRef curBlock = LLVMGetInsertBlock(ctx->builder);
unsigned i;
ifthen = &lp_build_flow_pop(flow, LP_BUILD_FLOW_IF)->ifthen;
assert(ifthen);
+ /* Insert branch to the merge block from current block */
+ LLVMBuildBr(ctx->builder, ifthen->merge_block);
+
if (ifthen->false_block) {
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block);
/* for each variable, update the Phi node with a (variable, block) pair */
for (i = 0; i < flow->num_variables; i++) {
assert(*flow->variables[i]);
- LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &ifthen->false_block, 1);
-
+ LLVMAddIncoming(ifthen->phi[i], flow->variables[i], &curBlock, 1);
/* replace the variable ref with the phi function */
*flow->variables[i] = ifthen->phi[i];
}
@@ -742,15 +747,18 @@ lp_build_endif(struct lp_build_if_state *ctx)
ifthen->true_block, ifthen->merge_block);
}
- /* Append an unconditional Br(anch) instruction on the true_block */
- LLVMPositionBuilderAtEnd(ctx->builder, ifthen->true_block);
- LLVMBuildBr(ctx->builder, ifthen->merge_block);
+ /* Insert branch from end of true_block to merge_block */
if (ifthen->false_block) {
- /* Append an unconditional Br(anch) instruction on the false_block */
- LLVMPositionBuilderAtEnd(ctx->builder, ifthen->false_block);
+ /* Append an unconditional Br(anch) instruction on the true_block */
+ LLVMPositionBuilderAtEnd(ctx->builder, ifthen->true_block);
LLVMBuildBr(ctx->builder, ifthen->merge_block);
}
-
+ else {
+ /* No else clause.
+ * Note that we've already inserted the branch at the end of
+ * true_block. See the very first LLVMBuildBr() call in this function.
+ */
+ }
/* Resume building code at end of the ifthen->merge_block */
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
index 4c225a0d4f9..c2b50e1b602 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h
@@ -35,7 +35,7 @@
#define LP_BLD_FLOW_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_type;
@@ -145,7 +145,9 @@ lp_build_else(struct lp_build_if_state *ctx);
void
lp_build_endif(struct lp_build_if_state *ctx);
-
+
+LLVMBasicBlockRef
+lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
#endif /* !LP_BLD_FLOW_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h
index 970bee379f5..73ab6de3f21 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h
@@ -34,7 +34,7 @@
* Pixel format helpers.
*/
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "pipe/p_format.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
index abb27e4c328..45ee4b12ced 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
@@ -114,10 +114,10 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
case UTIL_FORMAT_TYPE_UNSIGNED:
if(type.floating) {
if(start)
- input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
+ input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(type, start), "");
if(stop < format_desc->block.bits) {
unsigned mask = ((unsigned long long)1 << width) - 1;
- input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
+ input = LLVMBuildAnd(builder, input, lp_build_const_int_vec(type, mask), "");
}
if(format_desc->channel[chan].normalized)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.c b/src/gallium/auxiliary/gallivm/lp_bld_interp.c
index 2fc894017d8..09efb161217 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_interp.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.c
@@ -289,17 +289,17 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
/* top-right or bottom-right quad in block */
/* build x += xstep */
x = lp_build_add(&bld->base, x,
- lp_build_const_scalar(bld->base.type, xstep));
+ lp_build_const_vec(bld->base.type, xstep));
}
if (quad_index == 2) {
/* bottom-left quad in block */
/* build y += ystep */
y = lp_build_add(&bld->base, y,
- lp_build_const_scalar(bld->base.type, ystep));
+ lp_build_const_vec(bld->base.type, ystep));
/* build x -= xstep */
x = lp_build_sub(&bld->base, x,
- lp_build_const_scalar(bld->base.type, xstep));
+ lp_build_const_vec(bld->base.type, xstep));
}
lp_build_name(x, "pos.x");
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_interp.h b/src/gallium/auxiliary/gallivm/lp_bld_interp.h
index ca958cdf343..a4937bbb048 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_interp.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_interp.h
@@ -41,7 +41,7 @@
#define LP_BLD_INTERP_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "tgsi/tgsi_exec.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_intr.h b/src/gallium/auxiliary/gallivm/lp_bld_intr.h
index f813f27074b..977f7673228 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_intr.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_intr.h
@@ -37,7 +37,7 @@
#define LP_BLD_INTR_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
/**
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index 2726747eaea..a3b69701162 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -42,6 +42,26 @@
#include "lp_bld_logic.h"
+/*
+ * XXX
+ *
+ * Selection with vector conditional like
+ *
+ * select <4 x i1> %C, %A, %B
+ *
+ * is valid IR (e.g. llvm/test/Assembler/vector-select.ll), but it is not
+ * supported on any backend.
+ *
+ * Expanding the boolean vector to full SIMD register width, as in
+ *
+ * sext <4 x i1> %C to <4 x i32>
+ *
+ * is valid and supported (e.g., llvm/test/CodeGen/X86/vec_compare.ll), but
+ * it causes assertion failures in LLVM 2.6. It appears to work correctly on
+ * LLVM 2.7.
+ */
+
+
/**
* Build code to compare two values 'a' and 'b' of 'type' using the given func.
* \param func one of PIPE_FUNC_x
@@ -54,13 +74,11 @@ lp_build_compare(LLVMBuilderRef builder,
LLVMValueRef a,
LLVMValueRef b)
{
- LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
LLVMValueRef cond;
LLVMValueRef res;
- unsigned i;
assert(func >= PIPE_FUNC_NEVER);
assert(func <= PIPE_FUNC_ALWAYS);
@@ -74,10 +92,12 @@ lp_build_compare(LLVMBuilderRef builder,
/* XXX: It is not clear if we should use the ordered or unordered operators */
+#if HAVE_LLVM < 0x0207
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
if(type.width * type.length == 128) {
if(type.floating && util_cpu_caps.has_sse) {
/* float[4] comparison */
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMValueRef args[3];
unsigned cc;
boolean swap;
@@ -147,6 +167,7 @@ lp_build_compare(LLVMBuilderRef builder,
const char *pcmpgt;
LLVMValueRef args[2];
LLVMValueRef res;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
switch (type.width) {
case 8:
@@ -172,7 +193,7 @@ lp_build_compare(LLVMBuilderRef builder,
if(table[func].gt &&
((type.width == 8 && type.sign) ||
(type.width != 8 && !type.sign))) {
- LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
a = LLVMBuildXor(builder, a, msb, "");
b = LLVMBuildXor(builder, b, msb, "");
}
@@ -198,8 +219,9 @@ lp_build_compare(LLVMBuilderRef builder,
return res;
}
- }
+ } /* if (type.width * type.length == 128) */
#endif
+#endif /* HAVE_LLVM < 0x0207 */
if(type.floating) {
LLVMRealPredicate op;
@@ -233,25 +255,33 @@ lp_build_compare(LLVMBuilderRef builder,
return lp_build_undef(type);
}
-#if 0
- /* XXX: Although valid IR, no LLVM target currently support this */
+#if HAVE_LLVM >= 0x0207
cond = LLVMBuildFCmp(builder, op, a, b, "");
- res = LLVMBuildSelect(builder, cond, ones, zeros, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
#else
- debug_printf("%s: warning: using slow element-wise vector comparison\n",
- __FUNCTION__);
- res = LLVMGetUndef(int_vec_type);
- for(i = 0; i < type.length; ++i) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- cond = LLVMBuildFCmp(builder, op,
- LLVMBuildExtractElement(builder, a, index, ""),
- LLVMBuildExtractElement(builder, b, index, ""),
- "");
- cond = LLVMBuildSelect(builder, cond,
- LLVMConstExtractElement(ones, index),
- LLVMConstExtractElement(zeros, index),
- "");
- res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ if (type.length == 1) {
+ cond = LLVMBuildFCmp(builder, op, a, b, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
+ }
+ else {
+ unsigned i;
+
+ res = LLVMGetUndef(int_vec_type);
+
+ debug_printf("%s: warning: using slow element-wise float"
+ " vector comparison\n", __FUNCTION__);
+ for (i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildFCmp(builder, op,
+ LLVMBuildExtractElement(builder, a, index, ""),
+ LLVMBuildExtractElement(builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ }
}
#endif
}
@@ -281,25 +311,34 @@ lp_build_compare(LLVMBuilderRef builder,
return lp_build_undef(type);
}
-#if 0
- /* XXX: Although valid IR, no LLVM target currently support this */
+#if HAVE_LLVM >= 0x0207
cond = LLVMBuildICmp(builder, op, a, b, "");
- res = LLVMBuildSelect(builder, cond, ones, zeros, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
#else
- debug_printf("%s: warning: using slow element-wise int vector comparison\n",
- __FUNCTION__);
- res = LLVMGetUndef(int_vec_type);
- for(i = 0; i < type.length; ++i) {
- LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
- cond = LLVMBuildICmp(builder, op,
- LLVMBuildExtractElement(builder, a, index, ""),
- LLVMBuildExtractElement(builder, b, index, ""),
- "");
- cond = LLVMBuildSelect(builder, cond,
- LLVMConstExtractElement(ones, index),
- LLVMConstExtractElement(zeros, index),
- "");
- res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ if (type.length == 1) {
+ cond = LLVMBuildICmp(builder, op, a, b, "");
+ res = LLVMBuildSExt(builder, cond, int_vec_type, "");
+ }
+ else {
+ unsigned i;
+
+ res = LLVMGetUndef(int_vec_type);
+
+ debug_printf("%s: warning: using slow element-wise int"
+ " vector comparison\n", __FUNCTION__);
+
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildICmp(builder, op,
+ LLVMBuildExtractElement(builder, a, index, ""),
+ LLVMBuildExtractElement(builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(builder, res, cond, index, "");
+ }
}
#endif
}
@@ -326,6 +365,8 @@ lp_build_cmp(struct lp_build_context *bld,
/**
* Return mask ? a : b;
+ *
+ * mask is a bitwise mask, composed of 0 or ~0 for each element.
*/
LLVMValueRef
lp_build_select(struct lp_build_context *bld,
@@ -339,26 +380,32 @@ lp_build_select(struct lp_build_context *bld,
if(a == b)
return a;
- if(type.floating) {
- LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
- a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
- b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+ if (type.length == 1) {
+ mask = LLVMBuildTrunc(bld->builder, mask, LLVMInt1Type(), "");
+ res = LLVMBuildSelect(bld->builder, mask, a, b, "");
}
+ else {
+ if(type.floating) {
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+ }
- a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
- /* This often gets translated to PANDN, but sometimes the NOT is
- * pre-computed and stored in another constant. The best strategy depends
- * on available registers, so it is not a big deal -- hopefully LLVM does
- * the right decision attending the rest of the program.
- */
- b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
+ /* This often gets translated to PANDN, but sometimes the NOT is
+ * pre-computed and stored in another constant. The best strategy depends
+ * on available registers, so it is not a big deal -- hopefully LLVM does
+ * the right decision attending the rest of the program.
+ */
+ b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
- res = LLVMBuildOr(bld->builder, a, b, "");
+ res = LLVMBuildOr(bld->builder, a, b, "");
- if(type.floating) {
- LLVMTypeRef vec_type = lp_build_vec_type(type);
- res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ if(type.floating) {
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ }
}
return res;
@@ -436,3 +483,13 @@ lp_build_alloca(struct lp_build_context *bld)
return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), "");
}
}
+
+
+/** Return (a & ~b) */
+LLVMValueRef
+lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
+{
+ b = LLVMBuildNot(bld->builder, b, "");
+ b = LLVMBuildAnd(bld->builder, a, b, "");
+ return b;
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
index a399ebf39ef..00a8c750196 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
@@ -37,7 +37,7 @@
#define LP_BLD_LOGIC_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
@@ -79,4 +79,9 @@ lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef
lp_build_alloca(struct lp_build_context *bld);
+
+LLVMValueRef
+lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b);
+
+
#endif /* !LP_BLD_LOGIC_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
index bc360ad77ad..2daa8a3b582 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c
@@ -164,7 +164,7 @@ lp_build_unpack2(LLVMBuilderRef builder,
if(dst_type.sign && src_type.sign) {
/* Replicate the sign bit in the most significant bits */
- msb = LLVMBuildAShr(builder, src, lp_build_int_const_scalar(src_type, src_type.width - 1), "");
+ msb = LLVMBuildAShr(builder, src, lp_build_const_int_vec(src_type, src_type.width - 1), "");
}
else
/* Most significant bits always zero */
@@ -256,7 +256,9 @@ lp_build_pack2(LLVMBuilderRef builder,
LLVMValueRef lo,
LLVMValueRef hi)
{
+#if HAVE_LLVM < 0x0207
LLVMTypeRef src_vec_type = lp_build_vec_type(src_type);
+#endif
LLVMTypeRef dst_vec_type = lp_build_vec_type(dst_type);
LLVMValueRef shuffle;
LLVMValueRef res;
@@ -272,11 +274,14 @@ lp_build_pack2(LLVMBuilderRef builder,
switch(src_type.width) {
case 32:
if(dst_type.sign) {
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", src_vec_type, lo, hi);
+#endif
}
else {
if (util_cpu_caps.has_sse4_1) {
- /* PACKUSDW is the only instrinsic with a consistent signature */
return lp_build_intrinsic_binary(builder, "llvm.x86.sse41.packusdw", dst_vec_type, lo, hi);
}
else {
@@ -288,9 +293,17 @@ lp_build_pack2(LLVMBuilderRef builder,
case 16:
if(dst_type.sign)
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packsswb.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packsswb.128", src_vec_type, lo, hi);
+#endif
else
+#if HAVE_LLVM >= 0x0207
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packuswb.128", dst_vec_type, lo, hi);
+#else
res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packuswb.128", src_vec_type, lo, hi);
+#endif
break;
default:
@@ -348,7 +361,7 @@ lp_build_packs2(LLVMBuilderRef builder,
if(clamp) {
struct lp_build_context bld;
unsigned dst_bits = dst_type.sign ? dst_type.width - 1 : dst_type.width;
- LLVMValueRef dst_max = lp_build_int_const_scalar(src_type, ((unsigned long long)1 << dst_bits) - 1);
+ LLVMValueRef dst_max = lp_build_const_int_vec(src_type, ((unsigned long long)1 << dst_bits) - 1);
lp_build_context_init(&bld, builder, src_type);
lo = lp_build_min(&bld, lo, dst_max);
hi = lp_build_min(&bld, hi, dst_max);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.h b/src/gallium/auxiliary/gallivm/lp_bld_pack.h
index fb2a34984a4..41adeed220c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_pack.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.h
@@ -37,7 +37,7 @@
#define LP_BLD_PACK_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c
new file mode 100644
index 00000000000..78c9ec778b6
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c
@@ -0,0 +1,113 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include <stdio.h>
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "lp_bld_printf.h"
+
+
+static int
+lp_get_printf_arg_count(const char *fmt)
+{
+ int count =0;
+ const char *p = fmt;
+ int c;
+
+ while ((c = *p++)) {
+ if (c != '%')
+ continue;
+ switch (*p) {
+ case '\0':
+ continue;
+ case '%':
+ p++;
+ continue;
+ case '.':
+ if (p[1] == '*' && p[2] == 's') {
+ count += 2;
+ p += 3;
+ continue;
+ }
+ default:
+ count ++;
+ }
+ }
+ return count;
+}
+
+LLVMValueRef
+lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len)
+{
+ LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len + 1), "");
+ LLVMSetGlobalConstant(string, TRUE);
+ LLVMSetLinkage(string, LLVMInternalLinkage);
+ LLVMSetInitializer(string, LLVMConstString(str, len + 1, TRUE));
+ return string;
+}
+
+
+/**
+ * lp_build_printf.
+ *
+ * Build printf call in LLVM IR. The output goes to stdout.
+ * The additional variable arguments need to have type
+ * LLVMValueRef.
+ */
+LLVMValueRef
+lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...)
+{
+ va_list arglist;
+ int i = 0;
+ int argcount = lp_get_printf_arg_count(fmt);
+ LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+ LLVMValueRef params[50];
+ LLVMValueRef fmtarg = lp_build_const_string_variable(module, fmt, strlen(fmt) + 1);
+ LLVMValueRef int0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMValueRef index[2];
+ LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf");
+
+ assert(Elements(params) >= argcount + 1);
+
+ index[0] = index[1] = int0;
+
+ if (!func_printf) {
+ LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntType(32), NULL, 0, 1);
+ func_printf = LLVMAddFunction(module, "printf", printf_type);
+ }
+
+ params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, "");
+
+ va_start(arglist, fmt);
+ for (i = 1; i <= argcount; i++)
+ params[i] = va_arg(arglist, LLVMValueRef);
+ va_end(arglist);
+
+ return LLVMBuildCall(builder, func_printf, params, argcount + 1, "");
+}
+
diff --git a/src/gallium/drivers/cell/ppu/cell_winsys.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h
index e227e065ff3..83bd8f1d557 100644
--- a/src/gallium/drivers/cell/ppu/cell_winsys.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2010 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,38 +10,30 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
+#ifndef LP_BLD_PRINTF_H
+#define LP_BLD_PRINTF_H
-#ifndef CELL_WINSYS_H
-#define CELL_WINSYS_H
#include "pipe/p_compiler.h"
+#include "lp_bld.h"
-
-/**
- * Very simple winsys at this time.
- * Will probably eventually add SPU control info.
- */
-struct cell_winsys
-{
- uint dummy;
-};
-
-
-
+LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, const char *str, int len);
+LLVMValueRef lp_build_printf(LLVMBuilderRef builder, const char *fmt, ...);
#endif
+
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 6a026e468e1..bb76ad4c6bf 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -62,6 +62,18 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
if(!sampler)
return;
+ /*
+ * We don't copy sampler state over unless it is actually enabled, to avoid
+ * spurious recompiles, as the sampler static state is part of the shader
+ * key.
+ *
+ * Ideally the state tracker or cso_cache module would make all state
+ * canonical, but until that happens it's better to be safe than sorry here.
+ *
+ * XXX: Actually there's much more than can be done here, especially
+ * regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
+ */
+
state->format = texture->format;
state->target = texture->target;
state->pot_width = util_is_pot(texture->width0);
@@ -72,10 +84,18 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->wrap_t = sampler->wrap_t;
state->wrap_r = sampler->wrap_r;
state->min_img_filter = sampler->min_img_filter;
- state->min_mip_filter = sampler->min_mip_filter;
state->mag_img_filter = sampler->mag_img_filter;
+ if (texture->last_level) {
+ state->min_mip_filter = sampler->min_mip_filter;
+ } else {
+ state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ }
+
state->compare_mode = sampler->compare_mode;
- state->compare_func = sampler->compare_func;
+ if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE) {
+ state->compare_func = sampler->compare_func;
+ }
+
state->normalized_coords = sampler->normalized_coords;
state->lod_bias = sampler->lod_bias;
state->min_lod = sampler->min_lod;
@@ -139,20 +159,21 @@ lp_build_gather(LLVMBuilderRef builder,
/**
* Compute the offset of a pixel.
*
- * x, y, y_stride are vectors
+ * x, y, z, y_stride, z_stride are vectors
*/
LLVMValueRef
lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef z_stride)
{
LLVMValueRef x_stride;
LLVMValueRef offset;
- x_stride = lp_build_const_scalar(bld->type, format_desc->block.bits/8);
+ x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);
if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
LLVMValueRef x_lo, x_hi;
@@ -163,6 +184,10 @@ lp_build_sample_offset(struct lp_build_context *bld,
LLVMValueRef y_offset_lo, y_offset_hi;
LLVMValueRef offset_lo, offset_hi;
+ /* XXX 1D & 3D addressing not done yet */
+ assert(!z);
+ assert(!z_stride);
+
x_lo = LLVMBuildAnd(bld->builder, x, bld->one, "");
y_lo = LLVMBuildAnd(bld->builder, y, bld->one, "");
@@ -170,9 +195,9 @@ lp_build_sample_offset(struct lp_build_context *bld,
y_hi = LLVMBuildLShr(bld->builder, y, bld->one, "");
x_stride_lo = x_stride;
- y_stride_lo = lp_build_const_scalar(bld->type, 2*format_desc->block.bits/8);
+ y_stride_lo = lp_build_const_vec(bld->type, 2*format_desc->block.bits/8);
- x_stride_hi = lp_build_const_scalar(bld->type, 4*format_desc->block.bits/8);
+ x_stride_hi = lp_build_const_vec(bld->type, 4*format_desc->block.bits/8);
y_stride_hi = LLVMBuildShl(bld->builder, y_stride, bld->one, "");
x_offset_lo = lp_build_mul(bld, x_lo, x_stride_lo);
@@ -186,13 +211,17 @@ lp_build_sample_offset(struct lp_build_context *bld,
offset = lp_build_add(bld, offset_hi, offset_lo);
}
else {
- LLVMValueRef x_offset;
- LLVMValueRef y_offset;
+ offset = lp_build_mul(bld, x, x_stride);
- x_offset = lp_build_mul(bld, x, x_stride);
- y_offset = lp_build_mul(bld, y, y_stride);
+ if (y && y_stride) {
+ LLVMValueRef y_offset = lp_build_mul(bld, y, y_stride);
+ offset = lp_build_add(bld, offset, y_offset);
+ }
- offset = lp_build_add(bld, x_offset, y_offset);
+ if (z && z_stride) {
+ LLVMValueRef z_offset = lp_build_mul(bld, z, z_stride);
+ offset = lp_build_add(bld, offset, z_offset);
+ }
}
return offset;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 5ba0925bb69..92f3c57435a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -36,7 +36,7 @@
#define LP_BLD_SAMPLE_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct pipe_texture;
struct pipe_sampler_state;
@@ -113,9 +113,9 @@ struct lp_sampler_dynamic_state
unsigned unit);
LLVMValueRef
- (*stride)( struct lp_sampler_dynamic_state *state,
- LLVMBuilderRef builder,
- unsigned unit);
+ (*row_stride)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
LLVMValueRef
(*data_ptr)( struct lp_sampler_dynamic_state *state,
@@ -148,8 +148,9 @@ lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr);
+ LLVMValueRef z_stride);
void
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9058f76c1df..995c016b9dd 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -48,6 +48,7 @@
#include "lp_bld_logic.h"
#include "lp_bld_swizzle.h"
#include "lp_bld_pack.h"
+#include "lp_bld_flow.h"
#include "lp_bld_format.h"
#include "lp_bld_sample.h"
@@ -65,6 +66,14 @@ struct lp_build_sample_context
const struct util_format_description *format_desc;
+ /** regular scalar float type */
+ struct lp_type float_type;
+ struct lp_build_context float_bld;
+
+ /** regular scalar float type */
+ struct lp_type int_type;
+ struct lp_build_context int_bld;
+
/** Incoming coordinates type and build context */
struct lp_type coord_type;
struct lp_build_context coord_bld;
@@ -108,9 +117,78 @@ wrap_mode_uses_border_color(unsigned mode)
}
+static LLVMValueRef
+lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
+ LLVMValueRef data_array, LLVMValueRef level)
+{
+ LLVMValueRef indexes[2], data_ptr;
+ indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indexes[1] = level;
+ data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+ data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+ return data_ptr;
+}
+
+
+static LLVMValueRef
+lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
+ LLVMValueRef data_array, int level)
+{
+ LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
+ return lp_build_get_mipmap_level(bld, data_array, lvl);
+}
+
+
+/**
+ * Dereference stride_array[mipmap_level] array to get a stride.
+ * Return stride as a vector.
+ */
+static LLVMValueRef
+lp_build_get_level_stride_vec(struct lp_build_sample_context *bld,
+ LLVMValueRef stride_array, LLVMValueRef level)
+{
+ LLVMValueRef indexes[2], stride;
+ indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indexes[1] = level;
+ stride = LLVMBuildGEP(bld->builder, stride_array, indexes, 2, "");
+ stride = LLVMBuildLoad(bld->builder, stride, "");
+ stride = lp_build_broadcast_scalar(&bld->int_coord_bld, stride);
+ return stride;
+}
+
+
+/** Dereference stride_array[0] array to get a stride (as vector). */
+static LLVMValueRef
+lp_build_get_const_level_stride_vec(struct lp_build_sample_context *bld,
+ LLVMValueRef stride_array, int level)
+{
+ LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
+ return lp_build_get_level_stride_vec(bld, stride_array, lvl);
+}
+
+
+static int
+texture_dims(enum pipe_texture_target tex)
+{
+ switch (tex) {
+ case PIPE_TEXTURE_1D:
+ return 1;
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_CUBE:
+ return 2;
+ case PIPE_TEXTURE_3D:
+ return 3;
+ default:
+ assert(0 && "bad texture target in texture_dims()");
+ return 2;
+ }
+}
+
+
/**
- * Gen code to fetch a texel from a texture at int coords (x, y).
+ * Generate code to fetch a texel from a texture at int coords (x, y, z).
+ * The computation depends on whether the texture is 1D, 2D or 3D.
* The result, texel, will be:
* texel[0] = red values
* texel[1] = green values
@@ -121,12 +199,16 @@ static void
lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
+ LLVMValueRef depth,
LLVMValueRef x,
LLVMValueRef y,
+ LLVMValueRef z,
LLVMValueRef y_stride,
+ LLVMValueRef z_stride,
LLVMValueRef data_ptr,
LLVMValueRef *texel)
{
+ const int dims = texture_dims(bld->static_state->target);
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef offset;
LLVMValueRef packed;
@@ -140,7 +222,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
}
- if (wrap_mode_uses_border_color(bld->static_state->wrap_t)) {
+ if (dims >= 2 && wrap_mode_uses_border_color(bld->static_state->wrap_t)) {
LLVMValueRef b1, b2;
b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, y, int_coord_bld->zero);
b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, y, height);
@@ -153,6 +235,19 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
}
}
+ if (dims == 3 && wrap_mode_uses_border_color(bld->static_state->wrap_r)) {
+ LLVMValueRef b1, b2;
+ b1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, z, int_coord_bld->zero);
+ b2 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, z, depth);
+ if (use_border) {
+ use_border = LLVMBuildOr(bld->builder, use_border, b1, "ub_or_b1");
+ use_border = LLVMBuildOr(bld->builder, use_border, b2, "ub_or_b2");
+ }
+ else {
+ use_border = LLVMBuildOr(bld->builder, b1, b2, "b1_or_b2");
+ }
+ }
+
/*
* Note: if we find an app which frequently samples the texture border
* we might want to implement a true conditional here to avoid sampling
@@ -168,11 +263,10 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
* the texel color results with the border color.
*/
- /* convert x,y coords to linear offset from start of texture, in bytes */
+ /* convert x,y,z coords to linear offset from start of texture, in bytes */
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, z, y_stride, z_stride);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
@@ -185,6 +279,8 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
bld->texel_type.width,
data_ptr, offset);
+ texel[0] = texel[1] = texel[2] = texel[3] = NULL;
+
/* convert texels to float rgba */
lp_build_unpack_rgba_soa(bld->builder,
bld->format_desc,
@@ -196,7 +292,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
int chan;
for (chan = 0; chan < 4; chan++) {
LLVMValueRef border_chan =
- lp_build_const_scalar(bld->texel_type,
+ lp_build_const_vec(bld->texel_type,
bld->static_state->border_color[chan]);
texel[chan] = lp_build_select(&bld->texel_bld, use_border,
border_chan, texel[chan]);
@@ -210,19 +306,22 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef data_array)
{
LLVMValueRef offset;
+ LLVMValueRef data_ptr;
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, NULL, y_stride, NULL);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
assert(bld->format_desc->block.bits <= bld->texel_type.width);
+ /* get pointer to mipmap level 0 data */
+ data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
+
return lp_build_gather(bld->builder,
bld->texel_type.length,
bld->format_desc->block.bits,
@@ -358,8 +457,8 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
- LLVMValueRef half = lp_build_const_scalar(coord_bld->type, 0.5);
+ LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
+ LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -413,7 +512,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
else {
LLVMValueRef min, max;
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_scalar(coord_bld->type, 0.5F);
+ min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
}
@@ -434,7 +533,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -446,7 +545,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_scalar(coord_bld->type, -0.5F);
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
coord = lp_build_sub(coord_bld, coord, half);
@@ -521,7 +620,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
LLVMValueRef min, max;
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = 1.0 - min */
max = lp_build_sub(coord_bld, coord_bld->one, min);
@@ -566,7 +665,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_scalar(coord_bld->type, 2.0);
+ LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
@@ -609,7 +708,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_scalar(coord_bld->type, 0.5F);
+ min = lp_build_const_vec(coord_bld->type, 0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -625,7 +724,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
if (bld->static_state->normalized_coords) {
/* min = -1.0 / (2 * length) = -0.5 / length */
min = lp_build_mul(coord_bld,
- lp_build_const_scalar(coord_bld->type, -0.5F),
+ lp_build_const_vec(coord_bld->type, -0.5F),
lp_build_rcp(coord_bld, length_f));
/* max = length - min */
max = lp_build_sub(coord_bld, length_f, min);
@@ -634,7 +733,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
}
else {
/* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_scalar(coord_bld->type, -0.5F);
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
max = lp_build_sub(coord_bld, length_f, min);
}
/* coord = clamp(coord, min, max) */
@@ -711,83 +810,905 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
/**
- * Sample 2D texture with nearest filtering.
+ * Codegen equivalent for u_minify().
+ * Return max(1, base_size >> level);
+ */
+static LLVMValueRef
+lp_build_minify(struct lp_build_sample_context *bld,
+ LLVMValueRef base_size,
+ LLVMValueRef level)
+{
+ LLVMValueRef size = LLVMBuildAShr(bld->builder, base_size, level, "minify");
+ size = lp_build_max(&bld->int_coord_bld, size, bld->int_coord_bld.one);
+ return size;
+}
+
+
+/**
+ * Generate code to compute texture level of detail (lambda).
+ * \param s vector of texcoord s values
+ * \param t vector of texcoord t values
+ * \param r vector of texcoord r values
+ * \param width scalar int texture width
+ * \param height scalar int texture height
+ * \param depth scalar int texture depth
+ */
+static LLVMValueRef
+lp_build_lod_selector(struct lp_build_sample_context *bld,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef depth)
+
+{
+ if (bld->static_state->min_lod == bld->static_state->max_lod) {
+ /* User is forcing sampling from a particular mipmap level.
+ * This is hit during mipmap generation.
+ */
+ return LLVMConstReal(LLVMFloatType(), bld->static_state->min_lod);
+ }
+ else {
+ const int dims = texture_dims(bld->static_state->target);
+ struct lp_build_context *float_bld = &bld->float_bld;
+ LLVMValueRef lod_bias = LLVMConstReal(LLVMFloatType(),
+ bld->static_state->lod_bias);
+ LLVMValueRef min_lod = LLVMConstReal(LLVMFloatType(),
+ bld->static_state->min_lod);
+ LLVMValueRef max_lod = LLVMConstReal(LLVMFloatType(),
+ bld->static_state->max_lod);
+
+ LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
+ LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
+
+ LLVMValueRef s0, s1, s2;
+ LLVMValueRef t0, t1, t2;
+ LLVMValueRef r0, r1, r2;
+ LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
+ LLVMValueRef rho, lod;
+
+ /*
+ * dsdx = abs(s[1] - s[0]);
+ * dsdy = abs(s[2] - s[0]);
+ * dtdx = abs(t[1] - t[0]);
+ * dtdy = abs(t[2] - t[0]);
+ * drdx = abs(r[1] - r[0]);
+ * drdy = abs(r[2] - r[0]);
+ * XXX we're assuming a four-element quad in 2x2 layout here.
+ */
+ s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
+ s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
+ s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
+ dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
+ dsdx = lp_build_abs(float_bld, dsdx);
+ dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
+ dsdy = lp_build_abs(float_bld, dsdy);
+ if (dims > 1) {
+ t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
+ t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
+ t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
+ dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
+ dtdx = lp_build_abs(float_bld, dtdx);
+ dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
+ dtdy = lp_build_abs(float_bld, dtdy);
+ if (dims > 2) {
+ r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
+ r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
+ r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
+ drdx = LLVMBuildSub(bld->builder, r1, r0, "");
+ drdx = lp_build_abs(float_bld, drdx);
+ drdy = LLVMBuildSub(bld->builder, r2, r0, "");
+ drdy = lp_build_abs(float_bld, drdy);
+ }
+ }
+
+ /* Compute rho = max of all partial derivatives scaled by texture size.
+ * XXX this could be vectorized somewhat
+ */
+ rho = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, dsdx, dsdy),
+ lp_build_int_to_float(float_bld, width), "");
+ if (dims > 1) {
+ LLVMValueRef max;
+ max = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, dtdx, dtdy),
+ lp_build_int_to_float(float_bld, height), "");
+ rho = lp_build_max(float_bld, rho, max);
+ if (dims > 2) {
+ max = LLVMBuildMul(bld->builder,
+ lp_build_max(float_bld, drdx, drdy),
+ lp_build_int_to_float(float_bld, depth), "");
+ rho = lp_build_max(float_bld, rho, max);
+ }
+ }
+
+ /* compute lod = log2(rho) */
+ lod = lp_build_log2(float_bld, rho);
+
+ /* add lod bias */
+ lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "LOD bias");
+
+ /* clamp lod */
+ lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
+
+ return lod;
+ }
+}
+
+
+/**
+ * For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
+ * mipmap level index.
+ * Note: this is all scalar code.
+ * \param lod scalar float texture level of detail
+ * \param level_out returns integer
*/
static void
-lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
- LLVMValueRef s,
- LLVMValueRef t,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef stride,
- LLVMValueRef data_ptr,
- LLVMValueRef *texel)
+lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef lod,
+ LLVMValueRef *level_out)
{
- LLVMValueRef x, y;
+ struct lp_build_context *float_bld = &bld->float_bld;
+ struct lp_build_context *int_bld = &bld->int_bld;
+ LLVMValueRef last_level, level;
- x = lp_build_sample_wrap_nearest(bld, s, width,
- bld->static_state->pot_width,
- bld->static_state->wrap_s);
- y = lp_build_sample_wrap_nearest(bld, t, height,
- bld->static_state->pot_height,
- bld->static_state->wrap_t);
+ LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, 0);
- lp_build_name(x, "tex.x.wrapped");
- lp_build_name(y, "tex.y.wrapped");
+ last_level = bld->dynamic_state->last_level(bld->dynamic_state,
+ bld->builder, unit);
+
+ /* convert float lod to integer */
+ level = lp_build_iround(float_bld, lod);
- lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_ptr, texel);
+ /* clamp level to legal range of levels */
+ *level_out = lp_build_clamp(int_bld, level, zero, last_level);
}
/**
- * Sample 2D texture with bilinear filtering.
+ * For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
+ * two (adjacent) mipmap level indexes. Later, we'll sample from those
+ * two mipmap levels and interpolate between them.
*/
static void
-lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
+lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef lod,
+ LLVMValueRef *level0_out,
+ LLVMValueRef *level1_out,
+ LLVMValueRef *weight_out)
+{
+ struct lp_build_context *float_bld = &bld->float_bld;
+ struct lp_build_context *int_bld = &bld->int_bld;
+ LLVMValueRef last_level, level;
+
+ last_level = bld->dynamic_state->last_level(bld->dynamic_state,
+ bld->builder, unit);
+
+ /* convert float lod to integer */
+ level = lp_build_ifloor(float_bld, lod);
+
+ /* compute level 0 and clamp to legal range of levels */
+ *level0_out = lp_build_clamp(int_bld, level,
+ int_bld->zero,
+ last_level);
+ /* compute level 1 and clamp to legal range of levels */
+ *level1_out = lp_build_add(int_bld, *level0_out, int_bld->one);
+ *level1_out = lp_build_min(int_bld, *level1_out, last_level);
+
+ *weight_out = lp_build_fract(float_bld, lod);
+}
+
+
+/**
+ * Generate code to sample a mipmap level with nearest filtering.
+ * If sampling a cube texture, r = cube face in [0,5].
+ */
+static void
+lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_vec,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_ptr,
LLVMValueRef s,
LLVMValueRef t,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef stride,
- LLVMValueRef data_ptr,
- LLVMValueRef *texel)
+ LLVMValueRef r,
+ LLVMValueRef colors_out[4])
{
- LLVMValueRef s_fpart;
- LLVMValueRef t_fpart;
- LLVMValueRef x0, x1;
- LLVMValueRef y0, y1;
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef x, y, z;
+
+ /*
+ * Compute integer texcoords.
+ */
+ x = lp_build_sample_wrap_nearest(bld, s, width_vec,
+ bld->static_state->pot_width,
+ bld->static_state->wrap_s);
+ lp_build_name(x, "tex.x.wrapped");
+
+ if (dims >= 2) {
+ y = lp_build_sample_wrap_nearest(bld, t, height_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_t);
+ lp_build_name(y, "tex.y.wrapped");
+
+ if (dims == 3) {
+ z = lp_build_sample_wrap_nearest(bld, r, depth_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_r);
+ lp_build_name(z, "tex.z.wrapped");
+ }
+ else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+ z = r;
+ }
+ else {
+ z = NULL;
+ }
+ }
+ else {
+ y = z = NULL;
+ }
+
+ /*
+ * Get texture colors.
+ */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x, y, z,
+ row_stride_vec, img_stride_vec,
+ data_ptr, colors_out);
+}
+
+
+/**
+ * Generate code to sample a mipmap level with linear filtering.
+ * If sampling a cube texture, r = cube face in [0,5].
+ */
+static void
+lp_build_sample_image_linear(struct lp_build_sample_context *bld,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_vec,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_ptr,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef colors_out[4])
+{
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef x0, y0, z0, x1, y1, z1;
+ LLVMValueRef s_fpart, t_fpart, r_fpart;
LLVMValueRef neighbors[2][2][4];
- unsigned chan;
+ int chan;
- lp_build_sample_wrap_linear(bld, s, width, bld->static_state->pot_width,
- bld->static_state->wrap_s, &x0, &x1, &s_fpart);
- lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height,
- bld->static_state->wrap_t, &y0, &y1, &t_fpart);
+ /*
+ * Compute integer texcoords.
+ */
+ lp_build_sample_wrap_linear(bld, s, width_vec,
+ bld->static_state->pot_width,
+ bld->static_state->wrap_s,
+ &x0, &x1, &s_fpart);
+ lp_build_name(x0, "tex.x0.wrapped");
+ lp_build_name(x1, "tex.x1.wrapped");
+
+ if (dims >= 2) {
+ lp_build_sample_wrap_linear(bld, t, height_vec,
+ bld->static_state->pot_height,
+ bld->static_state->wrap_t,
+ &y0, &y1, &t_fpart);
+ lp_build_name(y0, "tex.y0.wrapped");
+ lp_build_name(y1, "tex.y1.wrapped");
+
+ if (dims == 3) {
+ lp_build_sample_wrap_linear(bld, r, depth_vec,
+ bld->static_state->pot_depth,
+ bld->static_state->wrap_r,
+ &z0, &z1, &r_fpart);
+ lp_build_name(z0, "tex.z0.wrapped");
+ lp_build_name(z1, "tex.z1.wrapped");
+ }
+ else if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+ z0 = z1 = r; /* cube face */
+ r_fpart = NULL;
+ }
+ else {
+ z0 = z1 = NULL;
+ r_fpart = NULL;
+ }
+ }
+ else {
+ y0 = y1 = t_fpart = NULL;
+ z0 = z1 = r_fpart = NULL;
+ }
- lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_ptr, neighbors[0][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_ptr, neighbors[0][1]);
- lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_ptr, neighbors[1][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_ptr, neighbors[1][1]);
+ /*
+ * Get texture colors.
+ */
+ /* get x0/x1 texels */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y0, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[0][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y0, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[0][1]);
+
+ if (dims == 1) {
+ /* Interpolate two samples from 1D image to produce one color */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld, s_fpart,
+ neighbors[0][0][chan],
+ neighbors[0][1][chan]);
+ }
+ }
+ else {
+ /* 2D/3D texture */
+ LLVMValueRef colors0[4];
+
+ /* get x0/x1 texels at y1 */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y1, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[1][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y1, z0,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors[1][1]);
+
+ /* Bilinear interpolate the four samples from the 2D image / 3D slice */
+ for (chan = 0; chan < 4; chan++) {
+ colors0[chan] = lp_build_lerp_2d(&bld->texel_bld,
+ s_fpart, t_fpart,
+ neighbors[0][0][chan],
+ neighbors[0][1][chan],
+ neighbors[1][0][chan],
+ neighbors[1][1][chan]);
+ }
- /* TODO: Don't interpolate missing channels */
- for(chan = 0; chan < 4; ++chan) {
- texel[chan] = lp_build_lerp_2d(&bld->texel_bld,
- s_fpart, t_fpart,
- neighbors[0][0][chan],
- neighbors[0][1][chan],
- neighbors[1][0][chan],
- neighbors[1][1][chan]);
+ if (dims == 3) {
+ LLVMValueRef neighbors1[2][2][4];
+ LLVMValueRef colors1[4];
+
+ /* get x0/x1/y0/y1 texels at z1 */
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y0, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[0][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y0, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[0][1]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x0, y1, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[1][0]);
+ lp_build_sample_texel_soa(bld, width_vec, height_vec, depth_vec,
+ x1, y1, z1,
+ row_stride_vec, img_stride_vec,
+ data_ptr, neighbors1[1][1]);
+
+ /* Bilinear interpolate the four samples from the second Z slice */
+ for (chan = 0; chan < 4; chan++) {
+ colors1[chan] = lp_build_lerp_2d(&bld->texel_bld,
+ s_fpart, t_fpart,
+ neighbors1[0][0][chan],
+ neighbors1[0][1][chan],
+ neighbors1[1][0][chan],
+ neighbors1[1][1][chan]);
+ }
+
+ /* Linearly interpolate the two samples from the two 3D slices */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld,
+ r_fpart,
+ colors0[chan], colors1[chan]);
+ }
+ }
+ else {
+ /* 2D tex */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = colors0[chan];
+ }
+ }
+ }
+}
+
+
+/** Helper used by lp_build_cube_lookup() */
+static LLVMValueRef
+lp_build_cube_ima(struct lp_build_context *coord_bld, LLVMValueRef coord)
+{
+ /* ima = -0.5 / abs(coord); */
+ LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5);
+ LLVMValueRef absCoord = lp_build_abs(coord_bld, coord);
+ LLVMValueRef ima = lp_build_mul(coord_bld, negHalf,
+ lp_build_rcp(coord_bld, absCoord));
+ return ima;
+}
+
+
+/**
+ * Helper used by lp_build_cube_lookup()
+ * \param sign scalar +1 or -1
+ * \param coord float vector
+ * \param ima float vector
+ */
+static LLVMValueRef
+lp_build_cube_coord(struct lp_build_context *coord_bld,
+ LLVMValueRef sign, int negate_coord,
+ LLVMValueRef coord, LLVMValueRef ima)
+{
+ /* return negate(coord) * ima * sign + 0.5; */
+ LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
+ LLVMValueRef res;
+
+ assert(negate_coord == +1 || negate_coord == -1);
+
+ if (negate_coord == -1) {
+ coord = lp_build_negate(coord_bld, coord);
+ }
+
+ res = lp_build_mul(coord_bld, coord, ima);
+ if (sign) {
+ sign = lp_build_broadcast_scalar(coord_bld, sign);
+ res = lp_build_mul(coord_bld, res, sign);
+ }
+ res = lp_build_add(coord_bld, res, half);
+
+ return res;
+}
+
+
+/** Helper used by lp_build_cube_lookup()
+ * Return (major_coord >= 0) ? pos_face : neg_face;
+ */
+static LLVMValueRef
+lp_build_cube_face(struct lp_build_sample_context *bld,
+ LLVMValueRef major_coord,
+ unsigned pos_face, unsigned neg_face)
+{
+ LLVMValueRef cmp = LLVMBuildFCmp(bld->builder, LLVMRealUGE,
+ major_coord,
+ bld->float_bld.zero, "");
+ LLVMValueRef pos = LLVMConstInt(LLVMInt32Type(), pos_face, 0);
+ LLVMValueRef neg = LLVMConstInt(LLVMInt32Type(), neg_face, 0);
+ LLVMValueRef res = LLVMBuildSelect(bld->builder, cmp, pos, neg, "");
+ return res;
+}
+
+
+
+/**
+ * Generate code to do cube face selection and per-face texcoords.
+ */
+static void
+lp_build_cube_lookup(struct lp_build_sample_context *bld,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef *face,
+ LLVMValueRef *face_s,
+ LLVMValueRef *face_t)
+{
+ struct lp_build_context *float_bld = &bld->float_bld;
+ struct lp_build_context *coord_bld = &bld->coord_bld;
+ LLVMValueRef rx, ry, rz;
+ LLVMValueRef arx, ary, arz;
+ LLVMValueRef c25 = LLVMConstReal(LLVMFloatType(), 0.25);
+ LLVMValueRef arx_ge_ary, arx_ge_arz;
+ LLVMValueRef ary_ge_arx, ary_ge_arz;
+ LLVMValueRef arx_ge_ary_arz, ary_ge_arx_arz;
+ LLVMValueRef rx_pos, ry_pos, rz_pos;
+
+ assert(bld->coord_bld.type.length == 4);
+
+ /*
+ * Use the average of the four pixel's texcoords to choose the face.
+ */
+ rx = lp_build_mul(float_bld, c25,
+ lp_build_sum_vector(&bld->coord_bld, s));
+ ry = lp_build_mul(float_bld, c25,
+ lp_build_sum_vector(&bld->coord_bld, t));
+ rz = lp_build_mul(float_bld, c25,
+ lp_build_sum_vector(&bld->coord_bld, r));
+
+ arx = lp_build_abs(float_bld, rx);
+ ary = lp_build_abs(float_bld, ry);
+ arz = lp_build_abs(float_bld, rz);
+
+ /*
+ * Compare sign/magnitude of rx,ry,rz to determine face
+ */
+ arx_ge_ary = LLVMBuildFCmp(bld->builder, LLVMRealUGE, arx, ary, "");
+ arx_ge_arz = LLVMBuildFCmp(bld->builder, LLVMRealUGE, arx, arz, "");
+ ary_ge_arx = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ary, arx, "");
+ ary_ge_arz = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ary, arz, "");
+
+ arx_ge_ary_arz = LLVMBuildAnd(bld->builder, arx_ge_ary, arx_ge_arz, "");
+ ary_ge_arx_arz = LLVMBuildAnd(bld->builder, ary_ge_arx, ary_ge_arz, "");
+
+ rx_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, rx, float_bld->zero, "");
+ ry_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, ry, float_bld->zero, "");
+ rz_pos = LLVMBuildFCmp(bld->builder, LLVMRealUGE, rz, float_bld->zero, "");
+
+ {
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ *face_s = bld->coord_bld.undef;
+ *face_t = bld->coord_bld.undef;
+ *face = bld->int_bld.undef;
+
+ lp_build_name(*face_s, "face_s");
+ lp_build_name(*face_t, "face_t");
+ lp_build_name(*face, "face");
+
+ lp_build_flow_scope_declare(flow_ctx, face_s);
+ lp_build_flow_scope_declare(flow_ctx, face_t);
+ lp_build_flow_scope_declare(flow_ctx, face);
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, arx_ge_ary_arz);
+ {
+ /* +/- X face */
+ LLVMValueRef sign = lp_build_sgn(float_bld, rx);
+ LLVMValueRef ima = lp_build_cube_ima(coord_bld, s);
+ *face_s = lp_build_cube_coord(coord_bld, sign, +1, r, ima);
+ *face_t = lp_build_cube_coord(coord_bld, NULL, +1, t, ima);
+ *face = lp_build_cube_face(bld, rx,
+ PIPE_TEX_FACE_POS_X,
+ PIPE_TEX_FACE_NEG_X);
+ }
+ lp_build_else(&if_ctx);
+ {
+ struct lp_build_flow_context *flow_ctx2;
+ struct lp_build_if_state if_ctx2;
+
+ LLVMValueRef face_s2 = bld->coord_bld.undef;
+ LLVMValueRef face_t2 = bld->coord_bld.undef;
+ LLVMValueRef face2 = bld->int_bld.undef;
+
+ flow_ctx2 = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx2);
+ lp_build_flow_scope_declare(flow_ctx2, &face_s2);
+ lp_build_flow_scope_declare(flow_ctx2, &face_t2);
+ lp_build_flow_scope_declare(flow_ctx2, &face2);
+
+ ary_ge_arx_arz = LLVMBuildAnd(bld->builder, ary_ge_arx, ary_ge_arz, "");
+
+ lp_build_if(&if_ctx2, flow_ctx2, bld->builder, ary_ge_arx_arz);
+ {
+ /* +/- Y face */
+ LLVMValueRef sign = lp_build_sgn(float_bld, ry);
+ LLVMValueRef ima = lp_build_cube_ima(coord_bld, t);
+ face_s2 = lp_build_cube_coord(coord_bld, NULL, -1, s, ima);
+ face_t2 = lp_build_cube_coord(coord_bld, sign, -1, r, ima);
+ face2 = lp_build_cube_face(bld, ry,
+ PIPE_TEX_FACE_POS_Y,
+ PIPE_TEX_FACE_NEG_Y);
+ }
+ lp_build_else(&if_ctx2);
+ {
+ /* +/- Z face */
+ LLVMValueRef sign = lp_build_sgn(float_bld, rz);
+ LLVMValueRef ima = lp_build_cube_ima(coord_bld, r);
+ face_s2 = lp_build_cube_coord(coord_bld, sign, -1, s, ima);
+ face_t2 = lp_build_cube_coord(coord_bld, NULL, +1, t, ima);
+ face2 = lp_build_cube_face(bld, rz,
+ PIPE_TEX_FACE_POS_Z,
+ PIPE_TEX_FACE_NEG_Z);
+ }
+ lp_build_endif(&if_ctx2);
+ lp_build_flow_scope_end(flow_ctx2);
+ lp_build_flow_destroy(flow_ctx2);
+
+ *face_s = face_s2;
+ *face_t = face_t2;
+ *face = face2;
+ }
+
+ lp_build_endif(&if_ctx);
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+ }
+}
+
+
+
+/**
+ * Sample the texture/mipmap using given image filter and mip filter.
+ * data0_ptr and data1_ptr point to the two mipmap levels to sample
+ * from. width0/1_vec, height0/1_vec, depth0/1_vec indicate their sizes.
+ * If we're using nearest miplevel sampling the '1' values will be null/unused.
+ */
+static void
+lp_build_sample_mipmap(struct lp_build_sample_context *bld,
+ unsigned img_filter,
+ unsigned mip_filter,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef lod_fpart,
+ LLVMValueRef width0_vec,
+ LLVMValueRef width1_vec,
+ LLVMValueRef height0_vec,
+ LLVMValueRef height1_vec,
+ LLVMValueRef depth0_vec,
+ LLVMValueRef depth1_vec,
+ LLVMValueRef row_stride0_vec,
+ LLVMValueRef row_stride1_vec,
+ LLVMValueRef img_stride0_vec,
+ LLVMValueRef img_stride1_vec,
+ LLVMValueRef data_ptr0,
+ LLVMValueRef data_ptr1,
+ LLVMValueRef *colors_out)
+{
+ LLVMValueRef colors0[4], colors1[4];
+ int chan;
+
+ if (img_filter == PIPE_TEX_FILTER_NEAREST) {
+ lp_build_sample_image_nearest(bld,
+ width0_vec, height0_vec, depth0_vec,
+ row_stride0_vec, img_stride0_vec,
+ data_ptr0, s, t, r, colors0);
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* sample the second mipmap level, and interp */
+ lp_build_sample_image_nearest(bld,
+ width1_vec, height1_vec, depth1_vec,
+ row_stride1_vec, img_stride1_vec,
+ data_ptr1, s, t, r, colors1);
+ }
+ }
+ else {
+ assert(img_filter == PIPE_TEX_FILTER_LINEAR);
+
+ lp_build_sample_image_linear(bld,
+ width0_vec, height0_vec, depth0_vec,
+ row_stride0_vec, img_stride0_vec,
+ data_ptr0, s, t, r, colors0);
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* sample the second mipmap level, and interp */
+ lp_build_sample_image_linear(bld,
+ width1_vec, height1_vec, depth1_vec,
+ row_stride1_vec, img_stride1_vec,
+ data_ptr1, s, t, r, colors1);
+ }
+ }
+
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* interpolate samples from the two mipmap levels */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = lp_build_lerp(&bld->texel_bld, lod_fpart,
+ colors0[chan], colors1[chan]);
+ }
+ }
+ else {
+ /* use first/only level's colors */
+ for (chan = 0; chan < 4; chan++) {
+ colors_out[chan] = colors0[chan];
+ }
}
}
+
+/**
+ * General texture sampling codegen.
+ * This function handles texture sampling for all texture targets (1D,
+ * 2D, 3D, cube) and all filtering modes.
+ */
+static void
+lp_build_sample_general(struct lp_build_sample_context *bld,
+ unsigned unit,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef r,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef depth,
+ LLVMValueRef width_vec,
+ LLVMValueRef height_vec,
+ LLVMValueRef depth_vec,
+ LLVMValueRef row_stride_array,
+ LLVMValueRef img_stride_vec,
+ LLVMValueRef data_array,
+ LLVMValueRef *colors_out)
+{
+ struct lp_build_context *float_bld = &bld->float_bld;
+ const unsigned mip_filter = bld->static_state->min_mip_filter;
+ const unsigned min_filter = bld->static_state->min_img_filter;
+ const unsigned mag_filter = bld->static_state->mag_img_filter;
+ const int dims = texture_dims(bld->static_state->target);
+ LLVMValueRef lod, lod_fpart;
+ LLVMValueRef ilevel0, ilevel1, ilevel0_vec, ilevel1_vec;
+ LLVMValueRef width0_vec = NULL, height0_vec = NULL, depth0_vec = NULL;
+ LLVMValueRef width1_vec = NULL, height1_vec = NULL, depth1_vec = NULL;
+ LLVMValueRef row_stride0_vec = NULL, row_stride1_vec = NULL;
+ LLVMValueRef img_stride0_vec = NULL, img_stride1_vec = NULL;
+ LLVMValueRef data_ptr0, data_ptr1;
+
+ /*
+ printf("%s mip %d min %d mag %d\n", __FUNCTION__,
+ mip_filter, min_filter, mag_filter);
+ */
+
+ /*
+ * Compute the level of detail (float).
+ */
+ if (min_filter != mag_filter ||
+ mip_filter != PIPE_TEX_MIPFILTER_NONE) {
+ /* Need to compute lod either to choose mipmap levels or to
+ * distinguish between minification/magnification with one mipmap level.
+ */
+ lod = lp_build_lod_selector(bld, s, t, r, width, height, depth);
+ }
+
+ /*
+ * Compute integer mipmap level(s) to fetch texels from.
+ */
+ if (mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+ /* always use mip level 0 */
+ ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ }
+ else {
+ if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
+ lp_build_nearest_mip_level(bld, unit, lod, &ilevel0);
+ }
+ else {
+ assert(mip_filter == PIPE_TEX_MIPFILTER_LINEAR);
+ lp_build_linear_mip_levels(bld, unit, lod, &ilevel0, &ilevel1,
+ &lod_fpart);
+ lod_fpart = lp_build_broadcast_scalar(&bld->coord_bld, lod_fpart);
+ }
+ }
+
+ /*
+ * Convert scalar integer mipmap levels into vectors.
+ */
+ ilevel0_vec = lp_build_broadcast_scalar(&bld->int_coord_bld, ilevel0);
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR)
+ ilevel1_vec = lp_build_broadcast_scalar(&bld->int_coord_bld, ilevel1);
+
+ /*
+ * Compute width, height at mipmap level 'ilevel0'
+ */
+ width0_vec = lp_build_minify(bld, width_vec, ilevel0_vec);
+ if (dims >= 2) {
+ height0_vec = lp_build_minify(bld, height_vec, ilevel0_vec);
+ row_stride0_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
+ ilevel0);
+ if (dims == 3 || bld->static_state->target == PIPE_TEXTURE_CUBE) {
+ img_stride0_vec = lp_build_mul(&bld->int_coord_bld,
+ row_stride0_vec, height0_vec);
+ if (dims == 3) {
+ depth0_vec = lp_build_minify(bld, depth_vec, ilevel0_vec);
+ }
+ }
+ }
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ /* compute width, height, depth for second mipmap level at 'ilevel1' */
+ width1_vec = lp_build_minify(bld, width_vec, ilevel1_vec);
+ if (dims >= 2) {
+ height1_vec = lp_build_minify(bld, height_vec, ilevel1_vec);
+ row_stride1_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
+ ilevel1);
+ if (dims == 3 || bld->static_state->target == PIPE_TEXTURE_CUBE) {
+ img_stride1_vec = lp_build_mul(&bld->int_coord_bld,
+ row_stride1_vec, height1_vec);
+ if (dims ==3) {
+ depth1_vec = lp_build_minify(bld, depth_vec, ilevel1_vec);
+ }
+ }
+ }
+ }
+
+ /*
+ * Choose cube face, recompute per-face texcoords.
+ */
+ if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+ LLVMValueRef face, face_s, face_t;
+ lp_build_cube_lookup(bld, s, t, r, &face, &face_s, &face_t);
+ s = face_s; /* vec */
+ t = face_t; /* vec */
+ /* use 'r' to indicate cube face */
+ r = lp_build_broadcast_scalar(&bld->int_coord_bld, face); /* vec */
+ }
+
+ /*
+ * Get pointer(s) to image data for mipmap level(s).
+ */
+ data_ptr0 = lp_build_get_mipmap_level(bld, data_array, ilevel0);
+ if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ data_ptr1 = lp_build_get_mipmap_level(bld, data_array, ilevel1);
+ }
+
+ /*
+ * Get/interpolate texture colors.
+ */
+ if (min_filter == mag_filter) {
+ /* no need to distinquish between minification and magnification */
+ lp_build_sample_mipmap(bld, min_filter, mip_filter, s, t, r, lod_fpart,
+ width0_vec, width1_vec,
+ height0_vec, height1_vec,
+ depth0_vec, depth1_vec,
+ row_stride0_vec, row_stride1_vec,
+ img_stride0_vec, img_stride1_vec,
+ data_ptr0, data_ptr1,
+ colors_out);
+ }
+ else {
+ /* Emit conditional to choose min image filter or mag image filter
+ * depending on the lod being >0 or <= 0, respectively.
+ */
+ struct lp_build_flow_context *flow_ctx;
+ struct lp_build_if_state if_ctx;
+ LLVMValueRef minify;
+
+ flow_ctx = lp_build_flow_create(bld->builder);
+ lp_build_flow_scope_begin(flow_ctx);
+
+ lp_build_flow_scope_declare(flow_ctx, &colors_out[0]);
+ lp_build_flow_scope_declare(flow_ctx, &colors_out[1]);
+ lp_build_flow_scope_declare(flow_ctx, &colors_out[2]);
+ lp_build_flow_scope_declare(flow_ctx, &colors_out[3]);
+
+ /* minify = lod > 0.0 */
+ minify = LLVMBuildFCmp(bld->builder, LLVMRealUGE,
+ lod, float_bld->zero, "");
+
+ lp_build_if(&if_ctx, flow_ctx, bld->builder, minify);
+ {
+ /* Use the minification filter */
+ lp_build_sample_mipmap(bld, min_filter, mip_filter,
+ s, t, r, lod_fpart,
+ width0_vec, width1_vec,
+ height0_vec, height1_vec,
+ depth0_vec, depth1_vec,
+ row_stride0_vec, row_stride1_vec,
+ img_stride0_vec, img_stride1_vec,
+ data_ptr0, data_ptr1,
+ colors_out);
+ }
+ lp_build_else(&if_ctx);
+ {
+ /* Use the magnification filter */
+ lp_build_sample_mipmap(bld, mag_filter, mip_filter,
+ s, t, r, lod_fpart,
+ width0_vec, width1_vec,
+ height0_vec, height1_vec,
+ depth0_vec, depth1_vec,
+ row_stride0_vec, row_stride1_vec,
+ img_stride0_vec, img_stride1_vec,
+ data_ptr0, data_ptr1,
+ colors_out);
+ }
+ lp_build_endif(&if_ctx);
+
+ lp_build_flow_scope_end(flow_ctx);
+ lp_build_flow_destroy(flow_ctx);
+ }
+}
+
+
+
static void
lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
struct lp_type dst_type,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
- LLVMValueRef mask = lp_build_int_const_scalar(dst_type, 0xff);
+ LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
unsigned chan;
/* Decode the input vector components */
@@ -799,7 +1720,7 @@ lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
input = packed;
if(start)
- input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(dst_type, start), "");
+ input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(dst_type, start), "");
if(stop < 32)
input = LLVMBuildAnd(builder, input, mask, "");
@@ -817,8 +1738,8 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef t,
LLVMValueRef width,
LLVMValueRef height,
- LLVMValueRef stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef stride_array,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMBuilderRef builder = bld->builder;
@@ -834,8 +1755,9 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef neighbors_hi[2][2];
LLVMValueRef packed, packed_lo, packed_hi;
LLVMValueRef unswizzled[4];
+ LLVMValueRef stride;
- lp_build_context_init(&i32, builder, lp_type_int(32));
+ lp_build_context_init(&i32, builder, lp_type_int_vec(32));
lp_build_context_init(&h16, builder, lp_type_ufixed(16));
lp_build_context_init(&u8n, builder, lp_type_unorm(8));
@@ -860,17 +1782,17 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
t = LLVMBuildFPToSI(builder, t, i32_vec_type, "");
/* subtract 0.5 (add -128) */
- i32_c128 = lp_build_int_const_scalar(i32.type, -128);
+ i32_c128 = lp_build_const_int_vec(i32.type, -128);
s = LLVMBuildAdd(builder, s, i32_c128, "");
t = LLVMBuildAdd(builder, t, i32_c128, "");
/* compute floor (shift right 8) */
- i32_c8 = lp_build_int_const_scalar(i32.type, 8);
+ i32_c8 = lp_build_const_int_vec(i32.type, 8);
s_ipart = LLVMBuildAShr(builder, s, i32_c8, "");
t_ipart = LLVMBuildAShr(builder, t, i32_c8, "");
/* compute fractional part (AND with 0xff) */
- i32_c255 = lp_build_int_const_scalar(i32.type, 255);
+ i32_c255 = lp_build_const_int_vec(i32.type, 255);
s_fpart = LLVMBuildAnd(builder, s, i32_c255, "");
t_fpart = LLVMBuildAnd(builder, t, i32_c255, "");
@@ -941,6 +1863,8 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
t_fpart_hi = LLVMBuildShuffleVector(builder, t_fpart, h16.undef, shuffle_hi, "");
}
+ stride = lp_build_get_const_level_stride_vec(bld, stride_array, 0);
+
/*
* Fetch the pixels as 4 x 32bit (rgba order might differ):
*
@@ -958,10 +1882,10 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
* The higher 8 bits of the resulting elements will be zero.
*/
- neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_ptr);
- neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_ptr);
- neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_ptr);
- neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_ptr);
+ neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_array);
+ neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_array);
+ neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_array);
+ neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_array);
neighbors[0][0] = LLVMBuildBitCast(builder, neighbors[0][0], u8n_vec_type, "");
neighbors[0][1] = LLVMBuildBitCast(builder, neighbors[0][1], u8n_vec_type, "");
@@ -1035,7 +1959,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
}
assert(res);
- res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25));
+ res = lp_build_mul(texel_bld, res, lp_build_const_vec(texel_bld->type, 0.25));
/* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
for(chan = 0; chan < 3; ++chan)
@@ -1044,194 +1968,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
}
-static int
-texture_dims(enum pipe_texture_target tex)
-{
- switch (tex) {
- case PIPE_TEXTURE_1D:
- return 1;
- case PIPE_TEXTURE_2D:
- case PIPE_TEXTURE_CUBE:
- return 2;
- case PIPE_TEXTURE_3D:
- return 3;
- default:
- assert(0 && "bad texture target in texture_dims()");
- return 2;
- }
-}
-
-
-/**
- * Generate code to compute texture level of detail (lambda).
- * \param s vector of texcoord s values
- * \param t vector of texcoord t values
- * \param r vector of texcoord r values
- * \param width scalar int texture width
- * \param height scalar int texture height
- * \param depth scalar int texture depth
- */
-static LLVMValueRef
-lp_build_lod_selector(struct lp_build_sample_context *bld,
- LLVMValueRef s,
- LLVMValueRef t,
- LLVMValueRef r,
- LLVMValueRef width,
- LLVMValueRef height,
- LLVMValueRef depth)
-
-{
- const int dims = texture_dims(bld->static_state->target);
- struct lp_build_context *coord_bld = &bld->coord_bld;
-
- LLVMValueRef lod_bias = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->lod_bias);
- LLVMValueRef min_lod = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->min_lod);
- LLVMValueRef max_lod = lp_build_const_scalar(bld->coord_bld.type,
- bld->static_state->max_lod);
-
- LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
- LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
- LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-
- LLVMValueRef s0, s1, s2;
- LLVMValueRef t0, t1, t2;
- LLVMValueRef r0, r1, r2;
- LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
- LLVMValueRef rho, lod;
-
- /*
- * dsdx = abs(s[1] - s[0]);
- * dsdy = abs(s[2] - s[0]);
- * dtdx = abs(t[1] - t[0]);
- * dtdy = abs(t[2] - t[0]);
- * drdx = abs(r[1] - r[0]);
- * drdy = abs(r[2] - r[0]);
- * XXX we're assuming a four-element quad in 2x2 layout here.
- */
- s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
- s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
- s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
- dsdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s1, s0));
- dsdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, s2, s0));
- if (dims > 1) {
- t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
- t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
- t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
- dtdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t1, t0));
- dtdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, t2, t0));
- if (dims > 2) {
- r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
- r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
- r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
- drdx = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r1, r0));
- drdy = lp_build_abs(coord_bld, lp_build_sub(coord_bld, r2, r0));
- }
- }
-
- /* Compute rho = max of all partial derivatives scaled by texture size.
- * XXX this can be vectorized somewhat
- */
- rho = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, dsdx, dsdy),
- lp_build_int_to_float(coord_bld, width));
- if (dims > 1) {
- LLVMValueRef max;
- max = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, dtdx, dtdy),
- lp_build_int_to_float(coord_bld, height));
- rho = lp_build_max(coord_bld, rho, max);
- if (dims > 2) {
- max = lp_build_mul(coord_bld,
- lp_build_max(coord_bld, drdx, drdy),
- lp_build_int_to_float(coord_bld, depth));
- rho = lp_build_max(coord_bld, rho, max);
- }
- }
-
- /* compute lod = log2(rho) */
- lod = lp_build_log2(coord_bld, rho);
-
- /* add lod bias */
- lod = lp_build_add(coord_bld, lod, lod_bias);
-
- /* clamp lod */
- lod = lp_build_clamp(coord_bld, lod, min_lod, max_lod);
-
- return lod;
-}
-
-
-/**
- * For PIPE_TEX_MIPFILTER_NEAREST, convert float LOD to integer
- * mipmap level index.
- * \param lod scalar float texture level of detail
- * \param level_out returns integer
- */
-static void
-lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
- unsigned unit,
- LLVMValueRef lod,
- LLVMValueRef *level_out)
-{
- struct lp_build_context *coord_bld = &bld->coord_bld;
- struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
- LLVMValueRef last_level, level;
-
- last_level = bld->dynamic_state->last_level(bld->dynamic_state,
- bld->builder, unit);
-
- /* convert float lod to integer */
- level = lp_build_iround(coord_bld, lod);
-
- /* clamp level to legal range of levels */
- *level_out = lp_build_clamp(int_coord_bld, level,
- int_coord_bld->zero,
- last_level);
-}
-
-
-/**
- * For PIPE_TEX_MIPFILTER_LINEAR, convert float LOD to integer to
- * two (adjacent) mipmap level indexes. Later, we'll sample from those
- * two mipmap levels and interpolate between them.
- */
-static void
-lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
- unsigned unit,
- LLVMValueRef lod,
- LLVMValueRef *level0_out,
- LLVMValueRef *level1_out,
- LLVMValueRef *weight_out)
-{
- struct lp_build_context *coord_bld = &bld->coord_bld;
- struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
- LLVMValueRef last_level, level;
-
- last_level = bld->dynamic_state->last_level(bld->dynamic_state,
- bld->builder, unit);
-
- /* convert float lod to integer */
- level = lp_build_ifloor(coord_bld, lod);
-
- /* compute level 0 and clamp to legal range of levels */
- *level0_out = lp_build_clamp(int_coord_bld, level,
- int_coord_bld->zero,
- last_level);
- /* compute level 1 and clamp to legal range of levels */
- *level1_out = lp_build_add(int_coord_bld, *level0_out, int_coord_bld->one);
- *level1_out = lp_build_min(int_coord_bld, *level1_out, int_coord_bld->zero);
-
- *weight_out = lp_build_fract(coord_bld, lod);
-}
-
-
-
/**
* Build texture sampling code.
* 'texel' will return a vector of four LLVMValueRefs corresponding to
* R, G, B, A.
+ * \param type vector float type to use for coords, etc.
*/
void
lp_build_sample_soa(LLVMBuilderRef builder,
@@ -1245,10 +1986,11 @@ lp_build_sample_soa(LLVMBuilderRef builder,
LLVMValueRef *texel)
{
struct lp_build_sample_context bld;
- LLVMValueRef width;
- LLVMValueRef height;
- LLVMValueRef stride;
- LLVMValueRef data_ptr;
+ LLVMValueRef width, width_vec;
+ LLVMValueRef height, height_vec;
+ LLVMValueRef depth, depth_vec;
+ LLVMValueRef stride_array;
+ LLVMValueRef data_array;
LLVMValueRef s;
LLVMValueRef t;
LLVMValueRef r;
@@ -1256,6 +1998,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
(void) lp_build_lod_selector; /* temporary to silence warning */
(void) lp_build_nearest_mip_level;
(void) lp_build_linear_mip_levels;
+ (void) lp_build_minify;
/* Setup our build context */
memset(&bld, 0, sizeof bld);
@@ -1263,10 +2006,16 @@ lp_build_sample_soa(LLVMBuilderRef builder,
bld.static_state = static_state;
bld.dynamic_state = dynamic_state;
bld.format_desc = util_format_description(static_state->format);
+
+ bld.float_type = lp_type_float(32);
+ bld.int_type = lp_type_int(32);
bld.coord_type = type;
bld.uint_coord_type = lp_uint_type(type);
bld.int_coord_type = lp_int_type(type);
bld.texel_type = type;
+
+ lp_build_context_init(&bld.float_bld, builder, bld.float_type);
+ lp_build_context_init(&bld.int_bld, builder, bld.int_type);
lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
lp_build_context_init(&bld.uint_coord_bld, builder, bld.uint_coord_type);
lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
@@ -1275,41 +2024,37 @@ lp_build_sample_soa(LLVMBuilderRef builder,
/* Get the dynamic state */
width = dynamic_state->width(dynamic_state, builder, unit);
height = dynamic_state->height(dynamic_state, builder, unit);
- stride = dynamic_state->stride(dynamic_state, builder, unit);
- data_ptr = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ depth = dynamic_state->depth(dynamic_state, builder, unit);
+ stride_array = dynamic_state->row_stride(dynamic_state, builder, unit);
+ data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ /* Note that data_array is an array[level] of pointers to texture images */
s = coords[0];
t = coords[1];
r = coords[2];
- width = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
- height = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
- stride = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride);
-
- if(static_state->target == PIPE_TEXTURE_1D)
- t = bld.coord_bld.zero;
-
- switch (static_state->min_img_filter) {
- case PIPE_TEX_FILTER_NEAREST:
- lp_build_sample_2d_nearest_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
- break;
- case PIPE_TEX_FILTER_LINEAR:
- if(lp_format_is_rgba8(bld.format_desc) &&
- is_simple_wrap_mode(static_state->wrap_s) &&
- is_simple_wrap_mode(static_state->wrap_t))
- lp_build_sample_2d_linear_aos(&bld, s, t, width, height,
- stride, data_ptr, texel);
- else
- lp_build_sample_2d_linear_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
- break;
- default:
- assert(0);
+ width_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
+ height_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
+ depth_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, depth);
+
+ if (lp_format_is_rgba8(bld.format_desc) &&
+ static_state->target == PIPE_TEXTURE_2D &&
+ static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
+ static_state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE &&
+ is_simple_wrap_mode(static_state->wrap_s) &&
+ is_simple_wrap_mode(static_state->wrap_t)) {
+ /* special case */
+ lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
+ stride_array, data_array, texel);
+ }
+ else {
+ lp_build_sample_general(&bld, unit, s, t, r,
+ width, height, depth,
+ width_vec, height_vec, depth_vec,
+ stride_array, NULL, data_array,
+ texel);
}
-
- /* FIXME: respect static_state->min_mip_filter */;
- /* FIXME: respect static_state->mag_img_filter */;
lp_build_sample_compare(&bld, r, texel);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
index 740392f5611..147336edb4b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_struct.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h
@@ -37,7 +37,7 @@
#define LP_BLD_STRUCT_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include <llvm-c/Target.h>
#include "util/u_debug.h"
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
index 64e81f7b1fe..278c838eaca 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
@@ -144,9 +144,9 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
#endif
if(shift > 0)
- tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_scalar(type4, shift*type.width), "");
+ tmp = LLVMBuildLShr(bld->builder, a, lp_build_const_int_vec(type4, shift*type.width), "");
if(shift < 0)
- tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_scalar(type4, -shift*type.width), "");
+ tmp = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type4, -shift*type.width), "");
assert(tmp);
if(tmp)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
index b9472127a63..138ca620e63 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
@@ -37,7 +37,7 @@
#define LP_BLD_SWIZZLE_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_type;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
index eddb7a83fa2..63b938bfa98 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
@@ -35,7 +35,7 @@
#ifndef LP_BLD_TGSI_H
#define LP_BLD_TGSI_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct tgsi_token;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 5f2c2a54ee9..95cd6a0ecf3 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -41,6 +41,7 @@
#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
@@ -95,6 +96,19 @@ struct lp_exec_mask {
int cond_stack_size;
LLVMValueRef cond_mask;
+ LLVMValueRef break_stack[LP_TGSI_MAX_NESTING];
+ int break_stack_size;
+ LLVMValueRef break_mask;
+
+ LLVMValueRef cont_stack[LP_TGSI_MAX_NESTING];
+ int cont_stack_size;
+ LLVMValueRef cont_mask;
+
+ LLVMBasicBlockRef loop_stack[LP_TGSI_MAX_NESTING];
+ int loop_stack_size;
+ LLVMBasicBlockRef loop_block;
+
+
LLVMValueRef exec_mask;
};
@@ -145,15 +159,33 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
mask->bld = bld;
mask->has_mask = FALSE;
mask->cond_stack_size = 0;
+ mask->loop_stack_size = 0;
+ mask->break_stack_size = 0;
+ mask->cont_stack_size = 0;
mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
}
static void lp_exec_mask_update(struct lp_exec_mask *mask)
{
- mask->exec_mask = mask->cond_mask;
- if (mask->cond_stack_size > 0)
- mask->has_mask = TRUE;
+ if (mask->loop_stack_size) {
+ /*for loops we need to update the entire mask at
+ * runtime */
+ LLVMValueRef tmp;
+ tmp = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask,
+ mask->break_mask,
+ "maskcb");
+ mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cond_mask,
+ tmp,
+ "maskfull");
+ } else
+ mask->exec_mask = mask->cond_mask;
+
+
+ mask->has_mask = (mask->cond_stack_size > 0 ||
+ mask->loop_stack_size > 0);
}
static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
@@ -190,6 +222,89 @@ static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
lp_exec_mask_update(mask);
}
+static void lp_exec_bgnloop(struct lp_exec_mask *mask)
+{
+
+ if (mask->cont_stack_size == 0)
+ mask->cont_mask = LLVMConstAllOnes(mask->int_vec_type);
+ if (mask->cont_stack_size == 0)
+ mask->break_mask = LLVMConstAllOnes(mask->int_vec_type);
+ if (mask->cond_stack_size == 0)
+ mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type);
+ mask->loop_stack[mask->loop_stack_size++] = mask->loop_block;
+ mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
+ LLVMBuildBr(mask->bld->builder, mask->loop_block);
+ LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
+
+ lp_exec_mask_update(mask);
+}
+
+static void lp_exec_break(struct lp_exec_mask *mask)
+{
+ LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ mask->exec_mask,
+ "break");
+
+ mask->break_stack[mask->break_stack_size++] = mask->break_mask;
+ if (mask->break_stack_size > 1) {
+ mask->break_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->break_mask,
+ exec_mask, "break_full");
+ } else
+ mask->break_mask = exec_mask;
+
+ lp_exec_mask_update(mask);
+}
+
+static void lp_exec_continue(struct lp_exec_mask *mask)
+{
+ LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
+ mask->exec_mask,
+ "");
+
+ mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask;
+ if (mask->cont_stack_size > 1) {
+ mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
+ mask->cont_mask,
+ exec_mask, "");
+ } else
+ mask->cont_mask = exec_mask;
+
+ lp_exec_mask_update(mask);
+}
+
+
+static void lp_exec_endloop(struct lp_exec_mask *mask)
+{
+ LLVMBasicBlockRef endloop;
+ LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
+ mask->bld->type.length);
+ /* i1cond = (mask == 0) */
+ LLVMValueRef i1cond = LLVMBuildICmp(
+ mask->bld->builder,
+ LLVMIntNE,
+ LLVMBuildBitCast(mask->bld->builder, mask->break_mask, reg_type, ""),
+ LLVMConstNull(reg_type), "");
+
+ endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
+
+ LLVMBuildCondBr(mask->bld->builder,
+ i1cond, mask->loop_block, endloop);
+
+ LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
+
+ mask->loop_block = mask->loop_stack[--mask->loop_stack_size];
+ /* pop the break mask */
+ if (mask->cont_stack_size) {
+ mask->cont_mask = mask->cont_stack[--mask->cont_stack_size];
+ }
+ if (mask->break_stack_size) {
+ mask->break_mask = mask->cont_stack[--mask->break_stack_size];
+ }
+
+ lp_exec_mask_update(mask);
+}
+
static void lp_exec_mask_store(struct lp_exec_mask *mask,
LLVMValueRef val,
LLVMValueRef dst)
@@ -360,7 +475,7 @@ emit_store(
break;
case TGSI_SAT_MINUS_PLUS_ONE:
- value = lp_build_max(&bld->base, value, lp_build_const_scalar(bld->base.type, -1.0));
+ value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
value = lp_build_min(&bld->base, value, bld->base.one);
break;
@@ -384,6 +499,11 @@ emit_store(
assert(0);
break;
+ case TGSI_FILE_PREDICATE:
+ /* FIXME */
+ assert(0);
+ break;
+
default:
assert( 0 );
}
@@ -531,6 +651,19 @@ emit_declaration(
unsigned first = decl->Range.First;
unsigned last = decl->Range.Last;
unsigned idx, i;
+ LLVMBasicBlockRef current_block =
+ LLVMGetInsertBlock(bld->base.builder);
+ LLVMBasicBlockRef first_block =
+ LLVMGetEntryBasicBlock(
+ LLVMGetBasicBlockParent(current_block));
+ LLVMValueRef first_inst =
+ LLVMGetFirstInstruction(first_block);
+
+ /* we want alloca's to be the first instruction
+ * in the function so we need to rewind the builder
+ * to the very beginning */
+ LLVMPositionBuilderBefore(bld->base.builder,
+ first_inst);
for (idx = first; idx <= last; ++idx) {
boolean ok;
@@ -553,10 +686,15 @@ emit_declaration(
ok = TRUE;
}
- if (!ok)
+ if (!ok) {
+ LLVMPositionBuilderAtEnd(bld->base.builder,
+ current_block);
return FALSE;
+ }
}
+ LLVMPositionBuilderAtEnd(bld->base.builder,
+ current_block);
return TRUE;
}
@@ -581,6 +719,17 @@ emit_instruction(
if (indirect_temp_reference(inst))
return FALSE;
+ /*
+ * Stores and write masks are handled in a general fashion after the long
+ * instruction opcode switch statement.
+ *
+ * Although not stricitly necessary, we avoid generating instructions for
+ * channels which won't be stored, in cases where's that easy. For some
+ * complex instructions, like texture sampling, it is more convenient to
+ * assume a full writemask and then let LLVM optimization passes eliminate
+ * redundant code.
+ */
+
assert(info->num_dst <= 1);
if(info->num_dst) {
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
@@ -865,7 +1014,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
src2 = emit_fetch( bld, inst, 2, chan_index );
- tmp1 = lp_build_const_scalar(bld->base.type, 0.5);
+ tmp1 = lp_build_const_vec(bld->base.type, 0.5);
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
}
@@ -1126,7 +1275,6 @@ emit_instruction(
break;
case TGSI_OPCODE_TEX:
- /* XXX what about dst0 writemask? */
emit_tex( bld, inst, FALSE, FALSE, dst0 );
break;
@@ -1349,14 +1497,15 @@ emit_instruction(
case TGSI_OPCODE_TXP:
emit_tex( bld, inst, FALSE, TRUE, dst0 );
break;
-
+
case TGSI_OPCODE_BRK:
- /* FIXME */
- return 0;
+ lp_exec_break(&bld->exec_mask);
break;
case TGSI_OPCODE_IF:
tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
+ tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
+ tmp0, bld->base.zero);
lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
break;
@@ -1366,6 +1515,10 @@ emit_instruction(
return 0;
break;
+ case TGSI_OPCODE_BGNLOOP:
+ lp_exec_bgnloop(&bld->exec_mask);
+ break;
+
case TGSI_OPCODE_REP:
/* deprecated */
assert(0);
@@ -1386,6 +1539,10 @@ emit_instruction(
return 0;
break;
+ case TGSI_OPCODE_ENDLOOP:
+ lp_exec_endloop(&bld->exec_mask);
+ break;
+
case TGSI_OPCODE_ENDREP:
/* deprecated */
assert(0);
@@ -1485,8 +1642,7 @@ emit_instruction(
break;
case TGSI_OPCODE_CONT:
- /* FIXME */
- return 0;
+ lp_exec_continue(&bld->exec_mask);
break;
case TGSI_OPCODE_EMIT:
@@ -1575,7 +1731,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
assert(num_immediates < LP_MAX_IMMEDIATES);
for( i = 0; i < size; ++i )
bld.immediates[num_immediates][i] =
- lp_build_const_scalar(type, parse.FullToken.FullImmediate.u[i].Float);
+ lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
for( i = size; i < 4; ++i )
bld.immediates[num_immediates][i] = bld.base.undef;
num_immediates++;
@@ -1589,7 +1745,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
assert( 0 );
}
}
-
+ if (0) {
+ LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+ LLVMValueRef function = LLVMGetBasicBlockParent(block);
+ debug_printf("11111111111111111111111111111 \n");
+ tgsi_dump(tokens, 0);
+ LLVMDumpValue(function);
+ debug_printf("2222222222222222222222222222 \n");
+ }
tgsi_parse_free( &parse );
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c
index c327ba045a6..796af88caad 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c
@@ -58,7 +58,10 @@ LLVMTypeRef
lp_build_vec_type(struct lp_type type)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
- return LLVMVectorType(elem_type, type.length);
+ if (type.length == 1)
+ return elem_type;
+ else
+ return LLVMVectorType(elem_type, type.length);
}
@@ -115,6 +118,9 @@ lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type)
if(!vec_type)
return FALSE;
+ if (type.length == 1)
+ return lp_check_elem_type(type, vec_type);
+
if(LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind)
return FALSE;
@@ -153,7 +159,10 @@ LLVMTypeRef
lp_build_int_vec_type(struct lp_type type)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
- return LLVMVectorType(elem_type, type.length);
+ if (type.length == 1)
+ return elem_type;
+ else
+ return LLVMVectorType(elem_type, type.length);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index 16946cc28a2..cd59d2faa66 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -37,9 +37,9 @@
#define LP_BLD_TYPE_H
-#include <llvm-c/Core.h>
+#include "pipe/p_compiler.h"
+#include "gallivm/lp_bld.h"
-#include <pipe/p_compiler.h>
/**
@@ -103,7 +103,7 @@ struct lp_type {
unsigned width:14;
/**
- * Vector length.
+ * Vector length. If length==1, this is a scalar (float/int) type.
*
* width*length should be a power of two greater or equal to eight.
*
@@ -139,6 +139,7 @@ struct lp_build_context
};
+/** Create scalar float type */
static INLINE struct lp_type
lp_type_float(unsigned width)
{
@@ -148,12 +149,29 @@ lp_type_float(unsigned width)
res_type.floating = TRUE;
res_type.sign = TRUE;
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector of float type */
+static INLINE struct lp_type
+lp_type_float_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.floating = TRUE;
+ res_type.sign = TRUE;
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
}
+/** Create scalar int type */
static INLINE struct lp_type
lp_type_int(unsigned width)
{
@@ -162,12 +180,28 @@ lp_type_int(unsigned width)
memset(&res_type, 0, sizeof res_type);
res_type.sign = TRUE;
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector int type */
+static INLINE struct lp_type
+lp_type_int_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.sign = TRUE;
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
}
+/** Create scalar uint type */
static INLINE struct lp_type
lp_type_uint(unsigned width)
{
@@ -175,6 +209,20 @@ lp_type_uint(unsigned width)
memset(&res_type, 0, sizeof res_type);
res_type.width = width;
+ res_type.length = 1;
+
+ return res_type;
+}
+
+
+/** Create vector uint type */
+static INLINE struct lp_type
+lp_type_uint_vec(unsigned width)
+{
+ struct lp_type res_type;
+
+ memset(&res_type, 0, sizeof res_type);
+ res_type.width = width;
res_type.length = LP_NATIVE_VECTOR_WIDTH / width;
return res_type;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
index 86f9266c95f..0f2ae05daed 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c
@@ -227,6 +227,8 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
pb_size size,
const struct pb_desc *desc)
{
+ void *map;
+
if(buf->base.base.size < size)
return FALSE;
@@ -239,6 +241,13 @@ pb_cache_is_buffer_compat(struct pb_cache_buffer *buf,
if(!pb_check_usage(desc->usage, buf->base.base.usage))
return FALSE;
+
+ map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_DONTBLOCK);
+ if (!map) {
+ return FALSE;
+ }
+
+ pb_unmap(buf->buffer);
return TRUE;
}
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index f675427d987..7595214bdf2 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -87,7 +87,7 @@ void x86_print_reg( struct x86_reg reg )
foo++; \
if (*foo) \
foo++; \
- debug_printf( "\n% 4x% 15s ", p->csr - p->store, foo ); \
+ debug_printf( "\n%4x %14s ", p->csr - p->store, foo ); \
} while (0)
#define DUMP_I( I ) do { \
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
index f7612d416a0..319b836ffb1 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
@@ -102,7 +102,7 @@ enum sse_cc {
#define cc_Z cc_E
#define cc_NZ cc_NE
-/* Begin/end/retreive function creation:
+/* Begin/end/retrieve function creation:
*/
@@ -311,8 +311,8 @@ void x87_fucom( struct x86_function *p, struct x86_reg arg );
-/* Retreive a reference to one of the function arguments, taking into
- * account any push/pop activity. Note - doesn't track explict
+/* Retrieve a reference to one of the function arguments, taking into
+ * account any push/pop activity. Note - doesn't track explicit
* manipulation of ESP by other instructions.
*/
struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );
diff --git a/src/gallium/auxiliary/target-helpers/wrap_screen.c b/src/gallium/auxiliary/target-helpers/wrap_screen.c
new file mode 100644
index 00000000000..5fe30139386
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/wrap_screen.c
@@ -0,0 +1,65 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ */
+
+#include "target-helpers/wrap_screen.h"
+#include "trace/tr_public.h"
+#include "identity/id_public.h"
+#include "util/u_debug.h"
+
+
+/* Centralized code to inject common wrapping layers:
+ */
+struct pipe_screen *
+gallium_wrap_screen( struct pipe_screen *screen )
+{
+ /* Screen wrapping functions are required not to fail. If it is
+ * impossible to wrap a screen, the unwrapped screen should be
+ * returned instead. Any failure condition should be returned in
+ * an OUT argument.
+ *
+ * Otherwise it is really messy trying to clean up in this code.
+ */
+ if (debug_get_bool_option("GALLIUM_WRAP", FALSE)) {
+ screen = identity_screen_create(screen);
+ }
+
+ if (debug_get_bool_option("GALLIUM_TRACE", FALSE)) {
+ screen = trace_screen_create( screen );
+ }
+
+ return screen;
+}
+
+
+
+
diff --git a/src/gallium/auxiliary/target-helpers/wrap_screen.h b/src/gallium/auxiliary/target-helpers/wrap_screen.h
new file mode 100644
index 00000000000..7e76beb7c5a
--- /dev/null
+++ b/src/gallium/auxiliary/target-helpers/wrap_screen.h
@@ -0,0 +1,16 @@
+#ifndef WRAP_SCREEN_HELPER_H
+#define WRAP_SCREEN_HELPER_H
+
+#include "pipe/p_compiler.h"
+
+struct pipe_screen;
+
+/* Centralized code to inject common wrapping layers. Other layers
+ * can be introduced by specific targets, but these are the generally
+ * helpful ones we probably want everywhere.
+ */
+struct pipe_screen *
+gallium_wrap_screen( struct pipe_screen *screen );
+
+
+#endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index f918151daaa..0b468a9184e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -55,7 +55,7 @@ static boolean is_digit_alpha_underscore( const char *cur )
return is_digit( cur ) || is_alpha_underscore( cur );
}
-static boolean uprcase( char c )
+static char uprcase( char c )
{
if (c >= 'a' && c <= 'z')
return c += 'A' - 'a';
@@ -76,7 +76,7 @@ streq_nocase_uprcase(const char *str1,
str1++;
str2++;
}
- return TRUE;
+ return *str1 == 0 && *str2 == 0;
}
static boolean str_match_no_case( const char **pcur, const char *str )
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index c9ec2b32bfe..c3ec9ae3f4b 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -393,10 +393,10 @@ static fetch_func get_fetch_func( enum pipe_format format )
return &fetch_R8G8B8A8_SSCALED;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- return &fetch_A8R8G8B8_UNORM;
+ return &fetch_B8G8R8A8_UNORM;
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return &fetch_B8G8R8A8_UNORM;
+ return &fetch_A8R8G8B8_UNORM;
case PIPE_FORMAT_R32_FIXED:
return &fetch_R32_FIXED;
@@ -552,10 +552,10 @@ static emit_func get_emit_func( enum pipe_format format )
return &emit_R8G8B8A8_SSCALED;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- return &emit_A8R8G8B8_UNORM;
+ return &emit_B8G8R8A8_UNORM;
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return &emit_B8G8R8A8_UNORM;
+ return &emit_A8R8G8B8_UNORM;
default:
assert(0);
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index 03e093c11ea..c13e7427387 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -336,7 +336,7 @@ static boolean translate_attr( struct translate_sse *p,
case PIPE_FORMAT_R32G32B32A32_FLOAT:
emit_load_R32G32B32A32(p, dataXMM, srcECX);
break;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
emit_load_R8G8B8A8_UNORM(p, dataXMM, srcECX);
emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W));
break;
@@ -360,7 +360,7 @@ static boolean translate_attr( struct translate_sse *p,
case PIPE_FORMAT_R32G32B32A32_FLOAT:
emit_store_R32G32B32A32(p, dstEAX, dataXMM);
break;
- case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
emit_swizzle(p, dataXMM, dataXMM, SHUF(Z,Y,X,W));
emit_store_R8G8B8A8_UNORM(p, dstEAX, dataXMM);
break;
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 0b263a9db5c..cd95f85b63b 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,6 +45,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "util/u_surface.h"
#include "util/u_rect.h"
@@ -63,6 +64,7 @@ struct blit_state
struct pipe_sampler_state sampler;
struct pipe_viewport_state viewport;
struct pipe_clip_state clip;
+ struct pipe_vertex_element velem[2];
void *vs;
void *fs[TGSI_WRITEMASK_XYZW + 1];
@@ -114,6 +116,15 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
ctx->sampler.mag_img_filter = 0; /* set later */
ctx->sampler.normalized_coords = 1;
+ /* vertex elements state */
+ memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ ctx->velem[i].src_offset = i * 4 * sizeof(float);
+ ctx->velem[i].instance_divisor = 0;
+ ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
/* vertex shader - still required to provide the linkage between
* fragment shader input semantics and vertex_element/buffers.
*/
@@ -270,6 +281,7 @@ regions_overlap(int srcX0, int srcY0,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -280,7 +292,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_texture *tex = NULL;
+ struct pipe_sampler_view *sampler_view = NULL;
struct pipe_framebuffer_state fb;
const int srcW = abs(srcX1 - srcX0);
const int srcH = abs(srcY1 - srcY0);
@@ -335,6 +347,8 @@ util_blit_pixels_writemask(struct blit_state *ctx,
src->texture->last_level != 0)
{
struct pipe_texture texTemp;
+ struct pipe_texture *tex;
+ struct pipe_sampler_view sv_templ;
struct pipe_surface *texSurf;
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
@@ -366,6 +380,14 @@ util_blit_pixels_writemask(struct blit_state *ctx,
if (!tex)
return;
+ u_sampler_view_default_template(&sv_templ, tex, tex->format);
+
+ sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ);
+ if (!sampler_view) {
+ pipe_texture_reference(&tex, NULL);
+ return;
+ }
+
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -389,33 +411,38 @@ util_blit_pixels_writemask(struct blit_state *ctx,
s1 = 1.0f;
t0 = 0.0f;
t1 = 1.0f;
+
+ pipe_texture_reference(&tex, NULL);
}
else {
- pipe_texture_reference(&tex, src->texture);
- s0 = srcX0 / (float)tex->width0;
- s1 = srcX1 / (float)tex->width0;
- t0 = srcY0 / (float)tex->height0;
- t1 = srcY1 / (float)tex->height0;
+ pipe_sampler_view_reference(&sampler_view, src_sampler_view);
+ s0 = srcX0 / (float)src->texture->width0;
+ s1 = srcX1 / (float)src->texture->width0;
+ t0 = srcY0 / (float)src->texture->height0;
+ t1 = srcY1 / (float)src->texture->height0;
}
+
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */
ctx->sampler.min_img_filter = filter;
@@ -435,7 +462,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_viewport(ctx->cso, &ctx->viewport);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view);
if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] =
@@ -474,20 +501,22 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_viewport(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
- pipe_texture_reference(&tex, NULL);
+ pipe_sampler_view_reference(&sampler_view, NULL);
}
void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -495,7 +524,7 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter )
{
- util_blit_pixels_writemask( ctx, src,
+ util_blit_pixels_writemask( ctx, src, src_sampler_view,
srcX0, srcY0,
srcX1, srcY1,
dst,
@@ -526,21 +555,23 @@ void util_blit_flush( struct blit_state *ctx )
*/
void
util_blit_pixels_tex(struct blit_state *ctx,
- struct pipe_texture *tex,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter)
+ struct pipe_sampler_view *src_sampler_view,
+ int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ struct pipe_surface *dst,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1,
+ float z, uint filter)
{
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
unsigned offset;
+ struct pipe_texture *tex = src_sampler_view->texture;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
+ assert(tex);
assert(tex->width0 != 0);
assert(tex->height0 != 0);
@@ -559,17 +590,19 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
/* sampler */
ctx->sampler.min_img_filter = filter;
@@ -589,7 +622,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_viewport(ctx->cso, &ctx->viewport);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
@@ -623,9 +656,10 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index a102021529e..1ebe65b4558 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -53,6 +53,7 @@ util_destroy_blit(struct blit_state *ctx);
extern void
util_blit_pixels(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -63,6 +64,7 @@ util_blit_pixels(struct blit_state *ctx,
void
util_blit_pixels_writemask(struct blit_state *ctx,
struct pipe_surface *src,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
@@ -73,7 +75,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
extern void
util_blit_pixels_tex(struct blit_state *ctx,
- struct pipe_texture *tex,
+ struct pipe_sampler_view *src_sampler_view,
int srcX0, int srcY0,
int srcX1, int srcY1,
struct pipe_surface *dst,
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 0ba09d33bfc..1692987e8e3 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -45,6 +45,7 @@
#include "util/u_draw_quad.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
#include "util/u_texture.h"
@@ -88,12 +89,16 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
+ void *velem_state;
+
/* Sampler state for clamping to a miplevel. */
void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
/* Rasterizer state. */
void *rs_state;
+ struct pipe_sampler_view *sampler_view;
+
/* Viewport state. */
struct pipe_viewport_state viewport;
@@ -104,10 +109,11 @@ struct blitter_context_priv
struct blitter_context *util_blitter_create(struct pipe_context *pipe)
{
struct blitter_context_priv *ctx;
- struct pipe_blend_state blend = { 0 };
- struct pipe_depth_stencil_alpha_state dsa = { { 0 } };
- struct pipe_rasterizer_state rs_state = { 0 };
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_rasterizer_state rs_state;
struct pipe_sampler_state *sampler_state;
+ struct pipe_vertex_element velem[2];
unsigned i;
ctx = CALLOC_STRUCT(blitter_context_priv);
@@ -122,17 +128,20 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR;
ctx->blitter.saved_vs = INVALID_PTR;
+ ctx->blitter.saved_velem_state = INVALID_PTR;
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
- ctx->blitter.saved_num_textures = ~0;
+ ctx->blitter.saved_num_sampler_views = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
/* blend state objects */
+ memset(&blend, 0, sizeof(blend));
ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
blend.rt[0].colormask = PIPE_MASK_RGBA;
ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
/* depth stencil alpha state objects */
+ memset(&dsa, 0, sizeof(dsa));
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
@@ -170,6 +179,16 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
+ /* vertex elements state */
+ memset(&velem[0], 0, sizeof(velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ velem[i].src_offset = i * 4 * sizeof(float);
+ velem[i].instance_divisor = 0;
+ velem[i].vertex_buffer_index = 0;
+ velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+ ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
+
/* fragment shaders are created on-demand */
/* vertex shaders */
@@ -219,6 +238,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col);
pipe->delete_vs_state(pipe, ctx->vs_tex);
+ pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
if (ctx->fs_texfetch_col[i])
@@ -235,6 +255,10 @@ void util_blitter_destroy(struct blitter_context *blitter)
if (ctx->sampler_state[i])
pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+
pipe_buffer_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
@@ -246,7 +270,8 @@ static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_dsa_state != INVALID_PTR &&
ctx->blitter.saved_rs_state != INVALID_PTR &&
ctx->blitter.saved_fs != INVALID_PTR &&
- ctx->blitter.saved_vs != INVALID_PTR);
+ ctx->blitter.saved_vs != INVALID_PTR &&
+ ctx->blitter.saved_velem_state != INVALID_PTR);
}
static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
@@ -259,12 +284,14 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
+ pipe->bind_vertex_elements_state(pipe, ctx->blitter.saved_velem_state);
ctx->blitter.saved_blend_state = INVALID_PTR;
ctx->blitter.saved_dsa_state = INVALID_PTR;
ctx->blitter.saved_rs_state = INVALID_PTR;
ctx->blitter.saved_fs = INVALID_PTR;
ctx->blitter.saved_vs = INVALID_PTR;
+ ctx->blitter.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
@@ -285,11 +312,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
ctx->blitter.saved_num_sampler_states = ~0;
}
- if (ctx->blitter.saved_num_textures != ~0) {
- pipe->set_fragment_sampler_textures(pipe,
- ctx->blitter.saved_num_textures,
- ctx->blitter.saved_textures);
- ctx->blitter.saved_num_textures = ~0;
+ if (ctx->blitter.saved_num_sampler_views != ~0) {
+ pipe->set_fragment_sampler_views(pipe,
+ ctx->blitter.saved_num_sampler_views,
+ ctx->blitter.saved_sampler_views);
+ ctx->blitter.saved_num_sampler_views = ~0;
}
}
@@ -569,6 +596,7 @@ void util_blitter_clear(struct blitter_context *blitter,
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
pipe->bind_vs_state(pipe, ctx->vs_col);
@@ -600,9 +628,10 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb_state;
+ struct pipe_sampler_view viewTempl, *view;
assert(blitter->saved_fb_state.nr_cbufs != ~0);
- assert(blitter->saved_num_textures != ~0);
+ assert(blitter->saved_num_sampler_views != ~0);
assert(blitter->saved_num_sampler_states != ~0);
assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
@@ -630,11 +659,24 @@ static void util_blitter_do_copy(struct blitter_context *blitter,
fb_state.zsbuf = 0;
}
+ u_sampler_view_default_template(&viewTempl,
+ src->texture,
+ src->texture->format);
+ view = pipe->create_sampler_view(pipe,
+ src->texture,
+ &viewTempl);
+
+ if (ctx->sampler_view) {
+ pipe_sampler_view_reference(&ctx->sampler_view, NULL);
+ }
+ ctx->sampler_view = view;
+
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs_tex);
pipe->bind_fragment_sampler_states(pipe, 1,
blitter_get_sampler_state(ctx, src->level));
- pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
+ pipe->set_fragment_sampler_views(pipe, 1, &view);
pipe->set_framebuffer_state(pipe, &fb_state);
/* set texture coordinates */
@@ -807,6 +849,7 @@ void util_blitter_fill(struct blitter_context *blitter,
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
fb_state.width = dst->width;
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 92008fce992..2ad7201a29d 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -43,6 +43,7 @@ struct blitter_context
/* Private members, really. */
void *saved_blend_state; /**< blend state */
void *saved_dsa_state; /**< depth stencil alpha state */
+ void *saved_velem_state; /**< vertex elements state */
void *saved_rs_state; /**< rasterizer state */
void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
@@ -52,10 +53,10 @@ struct blitter_context
struct pipe_clip_state saved_clip;
int saved_num_sampler_states;
- void *saved_sampler_states[32];
+ void *saved_sampler_states[PIPE_MAX_SAMPLERS];
- int saved_num_textures;
- struct pipe_texture *saved_textures[32]; /* is 32 enough? */
+ int saved_num_sampler_views;
+ struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];
};
/**
@@ -173,6 +174,13 @@ void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
}
static INLINE
+void util_blitter_save_vertex_elements(struct blitter_context *blitter,
+ void *state)
+{
+ blitter->saved_velem_state = state;
+}
+
+static INLINE
void util_blitter_save_stencil_ref(struct blitter_context *blitter,
const struct pipe_stencil_ref *state)
{
@@ -234,17 +242,17 @@ void util_blitter_save_fragment_sampler_states(
num_sampler_states * sizeof(void *));
}
-static INLINE
-void util_blitter_save_fragment_sampler_textures(
- struct blitter_context *blitter,
- int num_textures,
- struct pipe_texture **textures)
+static INLINE void
+util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
+ int num_views,
+ struct pipe_sampler_view **views)
{
- assert(num_textures <= Elements(blitter->saved_textures));
+ assert(num_views <= Elements(blitter->saved_sampler_views));
- blitter->saved_num_textures = num_textures;
- memcpy(blitter->saved_textures, textures,
- num_textures * sizeof(struct pipe_texture *));
+ blitter->saved_num_sampler_views = num_views;
+ memcpy(blitter->saved_sampler_views,
+ views,
+ num_views * sizeof(struct pipe_sampler_view *));
}
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 94be682c4b1..e997cfa8a38 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -421,26 +421,31 @@ void debug_dump_image(const char *prefix,
#endif
}
-void debug_dump_surface(const char *prefix,
+void debug_dump_surface(struct pipe_context *pipe,
+ const char *prefix,
struct pipe_surface *surface)
{
struct pipe_texture *texture;
- struct pipe_screen *screen;
struct pipe_transfer *transfer;
void *data;
if (!surface)
return;
+ /* XXX: this doesn't necessarily work, as the driver may be using
+ * temporary storage for the surface which hasn't been propagated
+ * back into the texture. Need to nail down the semantics of views
+ * and transfers a bit better before we can say if extra work needs
+ * to be done here:
+ */
texture = surface->texture;
- screen = texture->screen;
- transfer = screen->get_tex_transfer(screen, texture, surface->face,
- surface->level, surface->zslice,
- PIPE_TRANSFER_READ, 0, 0, surface->width,
- surface->height);
+ transfer = pipe->get_tex_transfer(pipe, texture, surface->face,
+ surface->level, surface->zslice,
+ PIPE_TRANSFER_READ, 0, 0, surface->width,
+ surface->height);
- data = screen->transfer_map(screen, transfer);
+ data = pipe->transfer_map(pipe, transfer);
if(!data)
goto error;
@@ -452,13 +457,14 @@ void debug_dump_surface(const char *prefix,
transfer->stride,
data);
- screen->transfer_unmap(screen, transfer);
+ pipe->transfer_unmap(pipe, transfer);
error:
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
-void debug_dump_texture(const char *prefix,
+void debug_dump_texture(struct pipe_context *pipe,
+ const char *prefix,
struct pipe_texture *texture)
{
struct pipe_surface *surface;
@@ -473,7 +479,7 @@ void debug_dump_texture(const char *prefix,
surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
PIPE_TEXTURE_USAGE_SAMPLER);
if (surface) {
- debug_dump_surface(prefix, surface);
+ debug_dump_surface(pipe, prefix, surface);
screen->tex_surface_destroy(surface);
}
}
@@ -511,27 +517,28 @@ struct bmp_rgb_quad {
};
void
-debug_dump_surface_bmp(const char *filename,
+debug_dump_surface_bmp(struct pipe_context *pipe,
+ const char *filename,
struct pipe_surface *surface)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
struct pipe_transfer *transfer;
struct pipe_texture *texture = surface->texture;
- struct pipe_screen *screen = texture->screen;
- transfer = screen->get_tex_transfer(screen, texture, surface->face,
- surface->level, surface->zslice,
- PIPE_TRANSFER_READ, 0, 0, surface->width,
- surface->height);
+ transfer = pipe->get_tex_transfer(pipe, texture, surface->face,
+ surface->level, surface->zslice,
+ PIPE_TRANSFER_READ, 0, 0, surface->width,
+ surface->height);
- debug_dump_transfer_bmp(filename, transfer);
+ debug_dump_transfer_bmp(pipe, filename, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
#endif
}
void
-debug_dump_transfer_bmp(const char *filename,
+debug_dump_transfer_bmp(struct pipe_context *pipe,
+ const char *filename,
struct pipe_transfer *transfer)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
@@ -544,7 +551,7 @@ debug_dump_transfer_bmp(const char *filename,
if(!rgba)
goto error1;
- pipe_get_tile_rgba(transfer, 0, 0,
+ pipe_get_tile_rgba(pipe, transfer, 0, 0,
transfer->width, transfer->height,
rgba);
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index 0f4768f3444..98addeb372e 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -312,6 +312,7 @@ debug_memory_end(unsigned long beginning);
#ifdef DEBUG
+struct pipe_context;
struct pipe_surface;
struct pipe_transfer;
struct pipe_texture;
@@ -321,21 +322,25 @@ void debug_dump_image(const char *prefix,
unsigned width, unsigned height,
unsigned stride,
const void *data);
-void debug_dump_surface(const char *prefix,
+void debug_dump_surface(struct pipe_context *pipe,
+ const char *prefix,
struct pipe_surface *surface);
-void debug_dump_texture(const char *prefix,
+void debug_dump_texture(struct pipe_context *pipe,
+ const char *prefix,
struct pipe_texture *texture);
-void debug_dump_surface_bmp(const char *filename,
+void debug_dump_surface_bmp(struct pipe_context *pipe,
+ const char *filename,
struct pipe_surface *surface);
-void debug_dump_transfer_bmp(const char *filename,
+void debug_dump_transfer_bmp(struct pipe_context *pipe,
+ const char *filename,
struct pipe_transfer *transfer);
void debug_dump_float_rgba_bmp(const char *filename,
unsigned width, unsigned height,
float *rgba, unsigned stride);
#else
#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0)
-#define debug_dump_surface(prefix, surface) ((void)0)
-#define debug_dump_surface_bmp(filename, surface) ((void)0)
+#define debug_dump_surface(pipe, prefix, surface) ((void)0)
+#define debug_dump_surface_bmp(pipe, filename, surface) ((void)0)
#define debug_dump_transfer_bmp(filename, transfer) ((void)0)
#define debug_dump_float_rgba_bmp(filename, width, height, rgba, stride) ((void)0)
#endif
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 14506e84519..8c194102bfc 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -45,8 +45,6 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
uint num_attribs)
{
struct pipe_vertex_buffer vbuffer;
- struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
- uint i;
assert(num_attribs <= PIPE_MAX_ATTRIBS);
@@ -58,15 +56,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
vbuffer.max_index = num_verts - 1;
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
- /* tell pipe about the vertex attributes */
- for (i = 0; i < num_attribs; i++) {
- velements[i].src_offset = i * 4 * sizeof(float);
- velements[i].instance_divisor = 0;
- velements[i].vertex_buffer_index = 0;
- velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- velements[i].nr_components = 4;
- }
- pipe->set_vertex_elements(pipe, num_attribs, velements);
+ /* note: vertex elements already set by caller */
/* draw */
pipe->draw_arrays(pipe, prim_type, 0, num_verts);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index ae7afd7311e..52cf3ef4ce0 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -700,7 +700,6 @@ util_dump_vertex_element(struct os_stream *stream, const struct pipe_vertex_elem
util_dump_member(stream, uint, state, src_offset);
util_dump_member(stream, uint, state, vertex_buffer_index);
- util_dump_member(stream, uint, state, nr_components);
util_dump_member(stream, format, state, src_format);
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 96a0fa65507..d819bbbde1c 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -47,9 +47,9 @@
# - color space: rgb, yub, sz
#
# See also:
-# - http://msdn.microsoft.com/en-us/library/ee416489.aspx (D3D9)
-# - http://msdn.microsoft.com/en-us/library/ee415668.aspx (D3D9 -> D3D10)
-# - http://msdn.microsoft.com/en-us/library/ee418116.aspx (D3D10)
+# - http://msdn.microsoft.com/en-us/library/bb172558.aspx (D3D9)
+# - http://msdn.microsoft.com/en-us/library/bb205073.aspx#mapping_texture_formats (D3D9 -> D3D10)
+# - http://msdn.microsoft.com/en-us/library/bb173059.aspx (D3D10)
#
# Note that GL doesn't really specify the layout of internal formats. See
# OpenGL 2.1 specification, Table 3.16, on the "Correspondence of sized
@@ -63,6 +63,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, r
PIPE_FORMAT_X8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb
PIPE_FORMAT_A8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb
PIPE_FORMAT_X8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzy1, rgb
+PIPE_FORMAT_B5G5R5X1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyx1, rgb
PIPE_FORMAT_B5G5R5A1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
PIPE_FORMAT_B4G4R4A4_UNORM , plain, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb
PIPE_FORMAT_B5G6R5_UNORM , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb
@@ -109,14 +110,18 @@ PIPE_FORMAT_UYVY , subsampled, 2, 1, x32 , , , , xyz
PIPE_FORMAT_YUYV , subsampled, 2, 1, x32 , , , , xyz1, yuv
# Compressed formats
-PIPE_FORMAT_DXT1_RGB , compressed, 4, 4, x64 , , , , xyz1, rgb
-PIPE_FORMAT_DXT1_RGBA , compressed, 4, 4, x64 , , , , xyzw, rgb
-PIPE_FORMAT_DXT3_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT5_RGBA , compressed, 4, 4, x128, , , , xyzw, rgb
-PIPE_FORMAT_DXT1_SRGB , compressed, 4, 4, x64 , , , , xyz1, srgb
-PIPE_FORMAT_DXT1_SRGBA , compressed, 4, 4, x64 , , , , xyzw, srgb
-PIPE_FORMAT_DXT3_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
-PIPE_FORMAT_DXT5_SRGBA , compressed, 4, 4, x128, , , , xyzw, srgb
+# - http://en.wikipedia.org/wiki/S3_Texture_Compression
+# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt
+# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt
+# - http://msdn.microsoft.com/en-us/library/bb694531.aspx
+PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb
+PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb
+PIPE_FORMAT_DXT3_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT5_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb
+PIPE_FORMAT_DXT1_SRGB , s3tc, 4, 4, x64 , , , , xyz1, srgb
+PIPE_FORMAT_DXT1_SRGBA , s3tc, 4, 4, x64 , , , , xyzw, srgb
+PIPE_FORMAT_DXT3_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb
+PIPE_FORMAT_DXT5_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb
# Straightforward D3D10-like formats (also used for
# vertex buffer element description)
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index e8fa0022b5b..98d4b98ebb5 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -56,15 +56,23 @@ enum util_format_layout {
*
* This is for formats like YV12 where there is less than one sample per
* pixel.
- *
- * XXX: This could actually b
*/
UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
/**
- * An unspecified compression algorithm.
+ * S3 Texture Compression formats.
+ */
+ UTIL_FORMAT_LAYOUT_S3TC = 4,
+
+ /**
+ * Red-Green Texture Compression formats.
*/
- UTIL_FORMAT_LAYOUT_COMPRESSED = 4
+ UTIL_FORMAT_LAYOUT_RGTC = 5,
+
+ /**
+ * Everything else that doesn't fit in any of the above layouts.
+ */
+ UTIL_FORMAT_LAYOUT_OTHER = 6
};
@@ -120,9 +128,15 @@ struct util_format_channel_description
struct util_format_description
{
enum pipe_format format;
+
const char *name;
/**
+ * Short name, striped of the prefix, lower case.
+ */
+ const char *short_name;
+
+ /**
* Pixel block dimensions.
*/
struct util_format_block block;
@@ -140,6 +154,15 @@ struct util_format_description
unsigned is_array:1;
/**
+ * Whether the pixel format can be described as a bitfield structure.
+ *
+ * In particular:
+ * - pixel depth must be 8, 16, or 32 bits;
+ * - all channels must be unsigned, signed, or void
+ */
+ unsigned is_bitmask:1;
+
+ /**
* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
*/
unsigned is_mixed:1;
@@ -195,7 +218,7 @@ util_format_name(enum pipe_format format)
}
static INLINE boolean
-util_format_is_compressed(enum pipe_format format)
+util_format_is_s3tc(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
@@ -204,7 +227,7 @@ util_format_is_compressed(enum pipe_format format)
return FALSE;
}
- return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE;
+ return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
}
static INLINE boolean
@@ -400,6 +423,16 @@ util_format_has_alpha(enum pipe_format format)
}
}
+/**
+ * Return the number of components stored.
+ * Formats with block size != 1x1 will always have 1 component (the block).
+ */
+static INLINE unsigned
+util_format_get_nr_components(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ return desc->nr_channels;
+}
/*
* Format access functions.
diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py
index 3f33f7cc021..409d024c637 100644
--- a/src/gallium/auxiliary/util/u_format_pack.py
+++ b/src/gallium/auxiliary/util/u_format_pack.py
@@ -252,9 +252,6 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
if src_channel.type == FLOAT and dst_channel.type == FLOAT:
return '(%s)%s' % (dst_native_type, value)
- if not src_channel.norm and not dst_channel.norm:
- return '(%s)%s' % (dst_native_type, value)
-
if clamp:
value = clamp_expr(src_channel, dst_channel, dst_native_type, value)
@@ -280,15 +277,15 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
value = '(%s * %s)' % (value, scale)
return '(%s)%s' % (dst_native_type, value)
- if not src_channel.norm and not dst_channel.norm:
- # neither is normalized -- just cast
- return '(%s)%s' % (dst_native_type, value)
-
if src_channel.type in (SIGNED, UNSIGNED) and dst_channel.type in (SIGNED, UNSIGNED):
+ if not src_channel.norm and not dst_channel.norm:
+ # neither is normalized -- just cast
+ return '(%s)%s' % (dst_native_type, value)
+
src_one = get_one(src_channel)
dst_one = get_one(dst_channel)
- if src_one > dst_one and src_channel.norm:
+ if src_one > dst_one and src_channel.norm and dst_channel.norm:
# We can just bitshift
src_shift = get_one_shift(src_channel)
dst_shift = get_one_shift(dst_channel)
@@ -296,7 +293,7 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
else:
# We need to rescale using an intermediate type big enough to hold the multiplication of both
tmp_native_type = intermediate_native_type(src_channel.size + dst_channel.size, src_channel.sign and dst_channel.sign)
- value = '(%s)%s' % (tmp_native_type, value)
+ value = '((%s)%s)' % (tmp_native_type, value)
value = '(%s * 0x%x / 0x%x)' % (value, dst_one, src_one)
value = '(%s)%s' % (dst_native_type, value)
return value
@@ -307,6 +304,8 @@ def conversion_expr(src_channel, dst_channel, dst_native_type, value, clamp=True
def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix):
'''Generate the function to unpack pixels from a particular format'''
+ assert format.layout == PLAIN
+
name = format.short_name()
src_native_type = native_type(format)
@@ -314,32 +313,99 @@ def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix):
print 'static INLINE void'
print 'util_format_%s_unpack_%s(%s *dst, const void *src)' % (name, dst_suffix, dst_native_type)
print '{'
- print ' union util_format_%s pixel;' % format.short_name()
- print ' memcpy(&pixel, src, sizeof pixel);'
- bswap_format(format)
+
+ if format.is_bitmask():
+ depth = format.block_size()
+ print ' uint%u_t value = *(uint%u_t *)src;' % (depth, depth)
- assert format.layout == PLAIN
+ # Declare the intermediate variables
+ for i in range(format.nr_channels()):
+ src_channel = format.channels[i]
+ if src_channel.type == UNSIGNED:
+ print ' uint%u_t %s;' % (depth, src_channel.name)
+ elif src_channel.type == SIGNED:
+ print ' int%u_t %s;' % (depth, src_channel.name)
- for i in range(4):
- swizzle = format.swizzles[i]
- if swizzle < 4:
- src_channel = format.channels[swizzle]
- value = 'pixel.chan.%s' % src_channel.name
- value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
- elif swizzle == SWIZZLE_0:
- value = '0'
- elif swizzle == SWIZZLE_1:
- value = get_one(dst_channel)
- elif swizzle == SWIZZLE_NONE:
- value = '0'
- else:
- assert False
- if format.colorspace == ZS:
- if i == 3:
+ print '#ifdef PIPE_ARCH_BIG_ENDIAN'
+ print ' value = util_bswap%u(value);' % depth
+ print '#endif'
+
+ # Compute the intermediate unshifted values
+ shift = 0
+ for i in range(format.nr_channels()):
+ src_channel = format.channels[i]
+ value = 'value'
+ if src_channel.type == UNSIGNED:
+ if shift:
+ value = '%s >> %u' % (value, shift)
+ if shift + src_channel.size < depth:
+ value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1)
+ elif src_channel.type == SIGNED:
+ if shift + src_channel.size < depth:
+ # Align the sign bit
+ lshift = depth - (shift + src_channel.size)
+ value = '%s << %u' % (value, lshift)
+ # Cast to signed
+ value = '(int%u_t)(%s) ' % (depth, value)
+ if src_channel.size < depth:
+ # Align the LSB bit
+ rshift = depth - src_channel.size
+ value = '(%s) >> %u' % (value, rshift)
+ else:
+ value = None
+
+ if value is not None:
+ print ' %s = %s;' % (src_channel.name, value)
+
+ shift += src_channel.size
+
+ # Convert, swizzle, and store final values
+ for i in range(4):
+ swizzle = format.swizzles[i]
+ if swizzle < 4:
+ src_channel = format.channels[swizzle]
+ value = src_channel.name
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
+ value = get_one(dst_channel)
+ elif swizzle == SWIZZLE_NONE:
+ value = '0'
+ else:
+ assert False
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = 'dst[0]'
+ print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
+
+ else:
+ print ' union util_format_%s pixel;' % format.short_name()
+ print ' memcpy(&pixel, src, sizeof pixel);'
+ bswap_format(format)
+
+ for i in range(4):
+ swizzle = format.swizzles[i]
+ if swizzle < 4:
+ src_channel = format.channels[swizzle]
+ value = 'pixel.chan.%s' % src_channel.name
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
value = get_one(dst_channel)
- elif i >= 1:
- value = 'dst[0]'
- print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
+ elif swizzle == SWIZZLE_NONE:
+ value = '0'
+ else:
+ assert False
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = 'dst[0]'
+ print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i])
print '}'
print
@@ -352,31 +418,70 @@ def generate_format_pack(format, src_channel, src_native_type, src_suffix):
dst_native_type = native_type(format)
- print 'static INLINE void'
- print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
- print '{'
- print ' union util_format_%s pixel;' % format.short_name()
-
assert format.layout == PLAIN
inv_swizzle = format.inv_swizzles()
+
+ print 'static INLINE void'
+ print 'util_format_%s_pack_%s(void *dst, %s r, %s g, %s b, %s a)' % (name, src_suffix, src_native_type, src_native_type, src_native_type, src_native_type)
+ print '{'
+
+ if format.is_bitmask():
+ depth = format.block_size()
+ print ' uint%u_t value = 0;' % depth
+
+ shift = 0
+ for i in range(4):
+ dst_channel = format.channels[i]
+ if inv_swizzle[i] is not None:
+ value = 'rgba'[inv_swizzle[i]]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = '0'
+ if dst_channel.type in (UNSIGNED, SIGNED):
+ if shift + dst_channel.size < depth:
+ value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1)
+ if shift:
+ value = '(%s) << %u' % (value, shift)
+ if dst_channel.type == SIGNED:
+ # Cast to unsigned
+ value = '(uint%u_t)(%s) ' % (depth, value)
+ else:
+ value = None
+ if value is not None:
+ print ' value |= %s;' % (value)
+
+ shift += dst_channel.size
- for i in range(4):
- dst_channel = format.channels[i]
- width = dst_channel.size
- if inv_swizzle[i] is None:
- continue
- value = 'rgba'[inv_swizzle[i]]
- value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
- if format.colorspace == ZS:
- if i == 3:
- value = get_one(dst_channel)
- elif i >= 1:
- value = '0'
- print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
+ print '#ifdef PIPE_ARCH_BIG_ENDIAN'
+ print ' value = util_bswap%u(value);' % depth
+ print '#endif'
+
+ print ' *(uint%u_t *)dst = value;' % depth
- bswap_format(format)
- print ' memcpy(dst, &pixel, sizeof pixel);'
+ else:
+ print ' union util_format_%s pixel;' % format.short_name()
+
+ for i in range(4):
+ dst_channel = format.channels[i]
+ width = dst_channel.size
+ if inv_swizzle[i] is None:
+ continue
+ value = 'rgba'[inv_swizzle[i]]
+ value = conversion_expr(src_channel, dst_channel, dst_native_type, value)
+ if format.colorspace == ZS:
+ if i == 3:
+ value = get_one(dst_channel)
+ elif i >= 1:
+ value = '0'
+ print ' pixel.chan.%s = %s;' % (dst_channel.name, value)
+
+ bswap_format(format)
+ print ' memcpy(dst, &pixel, sizeof pixel);'
+
print '}'
print
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
index 250926418ec..f74dc5e88a4 100755
--- a/src/gallium/auxiliary/util/u_format_parse.py
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -78,7 +78,7 @@ class Channel:
if self.type == UNSIGNED:
return (1 << self.size) - 1
if self.type == SIGNED:
- return self.size - 1
+ return (1 << (self.size - 1)) - 1
assert False
def min(self):
@@ -166,17 +166,11 @@ class Format:
return True
def is_bitmask(self):
- if self.block_size() > 32:
- return False
- if not self.is_pot():
+ if self.block_size() not in (8, 16, 32):
return False
for channel in self.channels:
- if not is_pot(channel.size):
- return True
if channel.type not in (VOID, UNSIGNED, SIGNED):
return False
- if channel.size >= 32:
- return False
return True
def inv_swizzles(self):
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
index 4e29d15f3bb..fb68852a530 100755
--- a/src/gallium/auxiliary/util/u_format_table.py
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -90,11 +90,13 @@ def write_format_table(formats):
print 'util_format_none_description = {'
print " PIPE_FORMAT_NONE,"
print " \"PIPE_FORMAT_NONE\","
+ print " \"none\","
print " {0, 0, 0},"
print " 0,"
print " 0,"
print " 0,"
print " 0,"
+ print " 0,"
print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
print " {0, 0, 0, 0},"
print " 0"
@@ -105,10 +107,12 @@ def write_format_table(formats):
print 'util_format_%s_description = {' % (format.short_name(),)
print " %s," % (format.name,)
print " \"%s\"," % (format.name,)
+ print " \"%s\"," % (format.short_name(),)
print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
print " %s," % (layout_map(format.layout),)
print " %u,\t/* nr_channels */" % (format.nr_channels(),)
print " %s,\t/* is_array */" % (bool_map(format.is_array()),)
+ print " %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),)
print " %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),)
print " {"
for i in range(4):
diff --git a/src/gallium/auxiliary/util/u_format_tests.c b/src/gallium/auxiliary/util/u_format_tests.c
new file mode 100644
index 00000000000..9d6debcd8c7
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_tests.c
@@ -0,0 +1,551 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "u_memory.h"
+#include "u_format_tests.h"
+
+
+/*
+ * Helper macros to create the packed bytes for longer words.
+ */
+
+#define PACKED_1x8(x) {x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x8(x, y) {x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x8(x, y, z) {x, y, z, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_4x8(x, y, z, w) {x, y, z, w, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+#define PACKED_1x16(x) {(x) & 0xff, (x) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x16(x, y) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x16(x, y, z) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_4x16(x, y, z, w) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, (w) & 0xff, (w) >> 8, 0, 0, 0, 0, 0, 0, 0, 0}
+
+#define PACKED_1x32(x) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_2x32(x, y) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, 0, 0, 0, 0, 0, 0, 0, 0}
+#define PACKED_3x32(x, y, z) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, 0, 0, 0, 0}
+#define PACKED_4x32(x, y, z, w) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, (w) & 0xff, ((w) >> 8) & 0xff, ((w) >> 16) & 0xff, (w) >> 24}
+
+
+/**
+ * Test cases.
+ *
+ * These were manually entered. We could generate these
+ *
+ * To keep this to a we cover only the corner cases, which should produce
+ * good enough coverage since that pixel format transformations are afine for
+ * non SRGB formats.
+ */
+const struct util_format_test_case
+util_format_test_cases[] =
+{
+
+ /*
+ * 32-bit rendertarget formats
+ */
+
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000003ff), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000ffc00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x3ff00000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * 16-bit rendertarget formats
+ */
+
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x03e0), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7c00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00f0), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0f00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x07e0), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf800), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * Luminance/intensity/alpha formats
+ */
+
+ {PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {0.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00ff), {1.0, 1.0, 1.0, 0.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xff00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ /*
+ * TODO: SRGB formats
+ */
+
+ /*
+ * Mixed-signed formats
+ */
+
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x81, 0x00, 0x00, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x81, 0x00, 0x00), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0xff, 0x00), { 0.0, 0.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0011), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x01e0), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0220), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0xfc00), { 0.0, 0.0, 1.0, 1.0}},
+
+ /*
+ * TODO: Depth-stencil formats
+ */
+
+ /*
+ * TODO: YUV formats
+ */
+
+ /*
+ * TODO: Compressed formats
+ */
+
+ /*
+ * Standard 8-bit integer formats
+ */
+
+ {PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0xff), {255.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), {255.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), { 0.0, 255.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), {255.0, 255.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), {255.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), { 0.0, 255.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), { 0.0, 0.0, 255.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), {255.0, 255.0, 255.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), {255.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), { 0.0, 255.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), { 0.0, 0.0, 255.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), { 0.0, 0.0, 0.0, 255.0}},
+ {PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), {255.0, 255.0, 255.0, 255.0}},
+
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x7f), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x81), {-1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x81, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x81), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x81, 0x00, 0x00), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x81, 0x00), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x81), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x81, 0x00, 0x00, 0x00), {-1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x81, 0x00, 0x00), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x81, 0x00), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x81), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x7f), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x80), {-128.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x80, 0x00), {-128.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), { 0.0, 127.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x80), { 0.0, -128.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), { 127.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x80, 0x00, 0x00), {-128.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), { 0.0, 127.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x80, 0x00), { 0.0, -128.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), { 0.0, 0.0, 127.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x80), { 0.0, 0.0, -128.0, 1.0}},
+
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), { 127.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0x00, 0x00, 0x00), {-128.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), { 0.0, 127.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x80, 0x00, 0x00), { 0.0, -128.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), { 0.0, 0.0, 127.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x80, 0x00), { 0.0, 0.0, -128.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), { 0.0, 0.0, 0.0, 127.0}},
+ {PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x80), { 0.0, 0.0, 0.0, -128.0}},
+
+ /*
+ * Standard 16-bit integer formats
+ */
+
+ {PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0xffff), {65535.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), {65535.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), { 0.0, 65535.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), {65535.0, 65535.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), {65535.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), { 0.0, 65535.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), { 0.0, 0.0, 65535.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), {65535.0, 65535.0, 65535.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), {65535.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), { 0.0, 65535.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), { 0.0, 0.0, 65535.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), { 0.0, 0.0, 0.0, 65535.0}},
+ {PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), {65535.0, 65535.0, 65535.0, 65535.0}},
+
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8001), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8001, 0x0000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8001), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8001, 0x0000, 0x0000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8001, 0x0000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8001), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8001, 0x0000, 0x0000, 0x0000), { -1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8001, 0x0000, 0x0000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8001, 0x0000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8001), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x8000), {-32768.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8000, 0x0000), {-32768.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), { 0.0, 32767.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8000), { 0.0, -32768.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), { 32767.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8000, 0x0000, 0x0000), {-32768.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), { 0.0, 32767.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8000, 0x0000), { 0.0, -32768.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 32767.0, 1.0}},
+ {PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8000), { 0.0, 0.0, -32768.0, 1.0}},
+
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), { 32767.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8000, 0x0000, 0x0000, 0x0000), {-32768.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), { 0.0, 32767.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8000, 0x0000, 0x0000), { 0.0, -32768.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), { 0.0, 0.0, 32767.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8000, 0x0000), { 0.0, 0.0, -32768.0, 0.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), { 0.0, 0.0, 0.0, 32767.0}},
+ {PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8000), { 0.0, 0.0, 0.0, -32768.0}},
+
+ /*
+ * Standard 32-bit integer formats
+ *
+ * NOTE: We can't accurately represent integers larger than +/-0x1000000
+ * with single precision floats, so that's as far as we test.
+ */
+
+ {PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), {1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0x00000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xffffffff), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0xffffffff), {1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0x00000000, 0x00000000), {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xffffffff, 0x00000000), {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xffffffff), {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0x00000000, 0x00000000, 0x00000000), {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xffffffff, 0x00000000, 0x00000000), {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xffffffff, 0x00000000), {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xffffffff), {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), {16777216.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), {16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x01000000), {16777216.0, 16777216.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), {16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 16777216.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x01000000, 0x01000000), {16777216.0, 16777216.0, 16777216.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), {16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), { 0.0, 16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), { 0.0, 0.0, 16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 0.0, 16777216.0}},
+ {PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x01000000, 0x01000000, 0x01000000), {16777216.0, 16777216.0, 16777216.0, 16777216.0}},
+
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x7fffffff), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x80000001), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x7fffffff, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x80000001, 0x00000000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x7fffffff), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x80000001), { 0.0, -1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x7fffffff, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x80000001, 0x00000000, 0x00000000), { -1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x7fffffff, 0x00000000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x80000001, 0x00000000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x7fffffff), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x80000001), { 0.0, 0.0, -1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x7fffffff, 0x00000000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x80000001, 0x00000000, 0x00000000, 0x00000000), { -1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x7fffffff, 0x00000000, 0x00000000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x80000001, 0x00000000, 0x00000000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x7fffffff, 0x00000000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x80000001, 0x00000000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x7fffffff), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x80000001), { 0.0, 0.0, 0.0, -1.0}},
+
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), {-16777216.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xff000000, 0x00000000), {-16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xff000000), { 0.0, -16777216.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), { 16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xff000000, 0x00000000, 0x00000000), {-16777216.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), { 0.0, 16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xff000000, 0x00000000), { 0.0, -16777216.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 16777216.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xff000000), { 0.0, 0.0, -16777216.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), { 16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xff000000, 0x00000000, 0x00000000, 0x00000000), {-16777216.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), { 0.0, 16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xff000000, 0x00000000, 0x00000000), { 0.0, -16777216.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), { 0.0, 0.0, 16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xff000000, 0x00000000), { 0.0, 0.0, -16777216.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), { 0.0, 0.0, 0.0, 16777216.0}},
+ {PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xff000000), { 0.0, 0.0, 0.0, -16777216.0}},
+
+ /*
+ * Standard 32-bit float formats
+ */
+
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x3f800000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0xbf800000), { -1.0, 0.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xbf800000, 0x00000000), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x3f800000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xbf800000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x3f800000), { 1.0, 1.0, 0.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xbf800000, 0x00000000, 0x00000000), {-1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x3f800000, 0x00000000), { 0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xbf800000, 0x00000000), { 0.0, -1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x3f800000), { 0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xbf800000), { 0.0, 0.0, -1.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x3f800000, 0x3f800000), { 1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), { 0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x00000000, 0x00000000, 0x00000000), { 1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xbf800000, 0x00000000, 0x00000000, 0x00000000), {-1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x3f800000, 0x00000000, 0x00000000), { 0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xbf800000, 0x00000000, 0x00000000), { 0.0, -1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x3f800000, 0x00000000), { 0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xbf800000, 0x00000000), { 0.0, 0.0, -1.0, 0.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x3f800000), { 0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xbf800000), { 0.0, 0.0, 0.0, -1.0}},
+ {PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000), { 1.0, 1.0, 1.0, 1.0}},
+};
+
+
+const unsigned util_format_nr_test_cases = Elements(util_format_test_cases);
diff --git a/src/gallium/auxiliary/util/u_format_tests.h b/src/gallium/auxiliary/util/u_format_tests.h
new file mode 100644
index 00000000000..2d4d9d5fa9d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_tests.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef U_FORMAT_TESTS_H_
+#define U_FORMAT_TESTS_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+
+#define UTIL_FORMAT_MAX_PACKED_BYTES 16
+
+
+/**
+ * A (packed, unpacked) color pair.
+ */
+struct util_format_test_case
+{
+ enum pipe_format format;
+
+ /**
+ * Mask of the bits that actually meaningful data. Used to mask out the
+ * "X" channels.
+ */
+ uint8_t mask[UTIL_FORMAT_MAX_PACKED_BYTES];
+
+ uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
+
+ /**
+ * RGBA.
+ */
+ double unpacked[4];
+};
+
+
+extern const struct util_format_test_case
+util_format_test_cases[];
+
+
+extern const unsigned util_format_nr_test_cases;
+
+
+#endif /* U_FORMAT_TESTS_H_ */
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index fc027e48e4e..509d38754f5 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -62,6 +62,7 @@ struct gen_mipmap_state
struct pipe_rasterizer_state rasterizer;
struct pipe_sampler_state sampler;
struct pipe_clip_state clip;
+ struct pipe_vertex_element velem[2];
void *vs;
void *fs2d, *fsCube;
@@ -937,6 +938,7 @@ format_to_type_comps(enum pipe_format pformat,
*datatype = DTYPE_UBYTE;
*comps = 4;
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
*datatype = DTYPE_USHORT_1_5_5_5_REV;
*comps = 4;
@@ -1118,7 +1120,6 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
uint face, uint baseLevel, uint lastLevel)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
const uint zslice = 0;
uint dstLevel;
@@ -1127,27 +1128,27 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_transfer *srcTrans, *dstTrans;
void *srcMap, *dstMap;
- srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ srcTrans = pipe->get_tex_transfer(pipe, pt, face, srcLevel, zslice,
PIPE_TRANSFER_READ, 0, 0,
u_minify(pt->width0, srcLevel),
u_minify(pt->height0, srcLevel));
- dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ dstTrans = pipe->get_tex_transfer(pipe, pt, face, dstLevel, zslice,
PIPE_TRANSFER_WRITE, 0, 0,
u_minify(pt->width0, dstLevel),
u_minify(pt->height0, dstLevel));
- srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
- dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
+ srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
+ dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
reduce_1d(pt->format,
srcTrans->width, srcMap,
dstTrans->width, dstMap);
- screen->transfer_unmap(screen, srcTrans);
- screen->transfer_unmap(screen, dstTrans);
+ pipe->transfer_unmap(pipe, srcTrans);
+ pipe->transfer_unmap(pipe, dstTrans);
- screen->tex_transfer_destroy(srcTrans);
- screen->tex_transfer_destroy(dstTrans);
+ pipe->tex_transfer_destroy(pipe, srcTrans);
+ pipe->tex_transfer_destroy(pipe, dstTrans);
}
}
@@ -1158,7 +1159,6 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
uint face, uint baseLevel, uint lastLevel)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
const uint zslice = 0;
uint dstLevel;
@@ -1170,17 +1170,17 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_transfer *srcTrans, *dstTrans;
ubyte *srcMap, *dstMap;
- srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ srcTrans = pipe->get_tex_transfer(pipe, pt, face, srcLevel, zslice,
PIPE_TRANSFER_READ, 0, 0,
u_minify(pt->width0, srcLevel),
u_minify(pt->height0, srcLevel));
- dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ dstTrans = pipe->get_tex_transfer(pipe, pt, face, dstLevel, zslice,
PIPE_TRANSFER_WRITE, 0, 0,
u_minify(pt->width0, dstLevel),
u_minify(pt->height0, dstLevel));
- srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
- dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
+ srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
+ dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
reduce_2d(pt->format,
srcTrans->width, srcTrans->height,
@@ -1188,11 +1188,11 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
dstTrans->width, dstTrans->height,
dstTrans->stride, dstMap);
- screen->transfer_unmap(screen, srcTrans);
- screen->transfer_unmap(screen, dstTrans);
+ pipe->transfer_unmap(pipe, srcTrans);
+ pipe->transfer_unmap(pipe, dstTrans);
- screen->tex_transfer_destroy(srcTrans);
- screen->tex_transfer_destroy(dstTrans);
+ pipe->tex_transfer_destroy(pipe, srcTrans);
+ pipe->tex_transfer_destroy(pipe, dstTrans);
}
}
@@ -1215,17 +1215,17 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_transfer *srcTrans, *dstTrans;
ubyte *srcMap, *dstMap;
- srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ srcTrans = pipe->get_tex_transfer(pipe, pt, face, srcLevel, zslice,
PIPE_TRANSFER_READ, 0, 0,
u_minify(pt->width0, srcLevel),
u_minify(pt->height0, srcLevel));
- dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ dstTrans = pipe->get_tex_transfer(pipe, pt, face, dstLevel, zslice,
PIPE_TRANSFER_WRITE, 0, 0,
u_minify(pt->width0, dstLevel),
u_minify(pt->height0, dstLevel));
- srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
- dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
+ srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
+ dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
reduce_3d(pt->format,
srcTrans->width, srcTrans->height,
@@ -1233,11 +1233,11 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
dstTrans->width, dstTrans->height,
dstTrans->stride, dstMap);
- screen->transfer_unmap(screen, srcTrans);
- screen->transfer_unmap(screen, dstTrans);
+ pipe->transfer_unmap(pipe, srcTrans);
+ pipe->transfer_unmap(pipe, dstTrans);
- screen->tex_transfer_destroy(srcTrans);
- screen->tex_transfer_destroy(dstTrans);
+ pipe->tex_transfer_destroy(pipe, srcTrans);
+ pipe->tex_transfer_destroy(pipe, dstTrans);
}
#else
(void) reduce_3d;
@@ -1307,6 +1307,15 @@ util_create_gen_mipmap(struct pipe_context *pipe,
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
ctx->sampler.normalized_coords = 1;
+ /* vertex elements state */
+ memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
+ for (i = 0; i < 2; i++) {
+ ctx->velem[i].src_offset = i * 4 * sizeof(float);
+ ctx->velem[i].instance_divisor = 0;
+ ctx->velem[i].vertex_buffer_index = 0;
+ ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
/* vertex shader - still needed to specify mapping from fragment
* shader input semantics to vertex elements
*/
@@ -1452,7 +1461,7 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
* Generate mipmap images. It's assumed all needed texture memory is
* already allocated.
*
- * \param pt the texture to generate mipmap levels for
+ * \param psv the sampler view to the texture to generate mipmap levels for
* \param face which cube face to generate mipmaps for (0 for non-cube maps)
* \param baseLevel the first mipmap level to use as a src
* \param lastLevel the last mipmap level to generate
@@ -1461,12 +1470,13 @@ void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
*/
void
util_gen_mipmap(struct gen_mipmap_state *ctx,
- struct pipe_texture *pt,
+ struct pipe_sampler_view *psv,
uint face, uint baseLevel, uint lastLevel, uint filter)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
+ struct pipe_texture *pt = psv->texture;
void *fs = (pt->target == PIPE_TEXTURE_CUBE) ? ctx->fsCube : ctx->fs2d;
uint dstLevel;
uint zslice = 0;
@@ -1484,7 +1494,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
filter == PIPE_TEX_FILTER_NEAREST);
/* check if we can render in the texture's format */
- if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
+ if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
return;
@@ -1495,18 +1505,20 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_save_depth_stencil_alpha(ctx->cso);
cso_save_rasterizer(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
cso_save_viewport(ctx->cso);
cso_save_clip(ctx->cso);
+ cso_save_vertex_elements(ctx->cso);
/* bind our state */
cso_set_blend(ctx->cso, &ctx->blend);
cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
cso_set_clip(ctx->cso, &ctx->clip);
+ cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
cso_set_fragment_shader_handle(ctx->cso, fs);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
@@ -1562,7 +1574,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_single_sampler(ctx->cso, 0, &ctx->sampler);
cso_single_sampler_done(ctx->cso);
- cso_set_sampler_textures(ctx->cso, 1, &pt);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &psv);
/* quad coords in clip coords */
offset = set_vertex_data(ctx,
@@ -1587,10 +1599,11 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_restore_depth_stencil_alpha(ctx->cso);
cso_restore_rasterizer(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
cso_restore_clip(ctx->cso);
+ cso_restore_vertex_elements(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h
index 54608f9466d..35ac9daeaa2 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.h
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.h
@@ -59,7 +59,7 @@ util_gen_mipmap_flush( struct gen_mipmap_state *ctx );
extern void
util_gen_mipmap(struct gen_mipmap_state *ctx,
- struct pipe_texture *pt,
+ struct pipe_sampler_view *psv,
uint face, uint baseLevel, uint lastLevel, uint filter);
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 0cb3432c6e4..e22ab188e11 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -120,6 +120,16 @@ pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex)
*ptr = tex;
}
+static INLINE void
+pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
+{
+ struct pipe_sampler_view *old_view = *ptr;
+
+ if (pipe_reference(&(*ptr)->reference, &view->reference))
+ old_view->context->sampler_view_destroy(old_view->context, old_view);
+ *ptr = view;
+}
+
/*
* Convenience wrappers for screen buffer functions.
@@ -264,24 +274,24 @@ pipe_buffer_read(struct pipe_screen *screen,
}
static INLINE void *
-pipe_transfer_map( struct pipe_transfer *transf )
+pipe_transfer_map( struct pipe_context *context,
+ struct pipe_transfer *transf )
{
- struct pipe_screen *screen = transf->texture->screen;
- return screen->transfer_map(screen, transf);
+ return context->transfer_map(context, transf);
}
static INLINE void
-pipe_transfer_unmap( struct pipe_transfer *transf )
+pipe_transfer_unmap( struct pipe_context *context,
+ struct pipe_transfer *transf )
{
- struct pipe_screen *screen = transf->texture->screen;
- screen->transfer_unmap(screen, transf);
+ context->transfer_unmap(context, transf);
}
static INLINE void
-pipe_transfer_destroy( struct pipe_transfer *transf )
+pipe_transfer_destroy( struct pipe_context *context,
+ struct pipe_transfer *transfer )
{
- struct pipe_screen *screen = transf->texture->screen;
- screen->tex_transfer_destroy(transf);
+ context->tex_transfer_destroy(context, transfer);
}
static INLINE unsigned
diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h
index 50f1b1670b6..c5fd7a6783e 100644
--- a/src/gallium/auxiliary/util/u_pack_color.h
+++ b/src/gallium/auxiliary/util/u_pack_color.h
@@ -92,6 +92,11 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
@@ -216,6 +221,15 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc,
*a = (ubyte) 0xff;
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ ushort p = uc->us;
+ *r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7));
+ *g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7));
+ *b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
+ *a = (ubyte) 0xff;
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
ushort p = uc->us;
@@ -361,6 +375,11 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color *
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ {
+ uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
+ }
+ return;
case PIPE_FORMAT_B5G5R5A1_UNORM:
{
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 8479161c744..e73797f1b7e 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -169,7 +169,6 @@ util_surface_copy(struct pipe_context *pipe,
unsigned src_x, unsigned src_y,
unsigned w, unsigned h)
{
- struct pipe_screen *screen = pipe->screen;
struct pipe_transfer *src_trans, *dst_trans;
void *dst_map;
const void *src_map;
@@ -182,7 +181,7 @@ util_surface_copy(struct pipe_context *pipe,
src_format = src->texture->format;
dst_format = dst->texture->format;
- src_trans = screen->get_tex_transfer(screen,
+ src_trans = pipe->get_tex_transfer(pipe,
src->texture,
src->face,
src->level,
@@ -190,7 +189,7 @@ util_surface_copy(struct pipe_context *pipe,
PIPE_TRANSFER_READ,
src_x, src_y, w, h);
- dst_trans = screen->get_tex_transfer(screen,
+ dst_trans = pipe->get_tex_transfer(pipe,
dst->texture,
dst->face,
dst->level,
@@ -202,8 +201,8 @@ util_surface_copy(struct pipe_context *pipe,
assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format));
assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format));
- src_map = pipe->screen->transfer_map(screen, src_trans);
- dst_map = pipe->screen->transfer_map(screen, dst_trans);
+ src_map = pipe->transfer_map(pipe, src_trans);
+ dst_map = pipe->transfer_map(pipe, dst_trans);
assert(src_map);
assert(dst_map);
@@ -221,11 +220,11 @@ util_surface_copy(struct pipe_context *pipe,
do_flip ? h - 1 : 0);
}
- pipe->screen->transfer_unmap(pipe->screen, src_trans);
- pipe->screen->transfer_unmap(pipe->screen, dst_trans);
+ pipe->transfer_unmap(pipe, src_trans);
+ pipe->transfer_unmap(pipe, dst_trans);
- screen->tex_transfer_destroy(src_trans);
- screen->tex_transfer_destroy(dst_trans);
+ pipe->tex_transfer_destroy(pipe, src_trans);
+ pipe->tex_transfer_destroy(pipe, dst_trans);
}
@@ -243,14 +242,13 @@ util_surface_fill(struct pipe_context *pipe,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height, unsigned value)
{
- struct pipe_screen *screen = pipe->screen;
struct pipe_transfer *dst_trans;
void *dst_map;
assert(dst->texture);
if (!dst->texture)
return;
- dst_trans = screen->get_tex_transfer(screen,
+ dst_trans = pipe->get_tex_transfer(pipe,
dst->texture,
dst->face,
dst->level,
@@ -258,7 +256,7 @@ util_surface_fill(struct pipe_context *pipe,
PIPE_TRANSFER_WRITE,
dstx, dsty, width, height);
- dst_map = pipe->screen->transfer_map(screen, dst_trans);
+ dst_map = pipe->transfer_map(pipe, dst_trans);
assert(dst_map);
@@ -302,6 +300,6 @@ util_surface_fill(struct pipe_context *pipe,
}
}
- pipe->screen->transfer_unmap(pipe->screen, dst_trans);
- screen->tex_transfer_destroy(dst_trans);
+ pipe->transfer_unmap(pipe, dst_trans);
+ pipe->tex_transfer_destroy(pipe, dst_trans);
}
diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c
new file mode 100644
index 00000000000..4d8f861ce49
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_sampler.c
@@ -0,0 +1,100 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "u_format.h"
+#include "u_sampler.h"
+
+
+static void
+default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format,
+ unsigned expand_green_blue)
+{
+ /* XXX: Check if format is compatible with texture->format.
+ */
+
+ view->format = format;
+ view->first_level = 0;
+ view->last_level = texture->last_level;
+ view->swizzle_r = PIPE_SWIZZLE_RED;
+ view->swizzle_g = PIPE_SWIZZLE_GREEN;
+ view->swizzle_b = PIPE_SWIZZLE_BLUE;
+ view->swizzle_a = PIPE_SWIZZLE_ALPHA;
+
+ /* Override default green and blue component expansion to the requested
+ * one.
+ *
+ * Gallium expands nonexistent components to (0,0,0,1), DX9 expands
+ * to (1,1,1,1). Since alpha is always expanded to 1, and red is
+ * always present, we only really care about green and blue
+ * components.
+ *
+ * To make it look less hackish, one would have to add
+ * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion
+ * and then override without exceptions or favoring one component
+ * over another.
+ */
+ if (format != PIPE_FORMAT_A8_UNORM) {
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(desc);
+ if (desc) {
+ if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) {
+ view->swizzle_g = expand_green_blue;
+ }
+ if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) {
+ view->swizzle_b = expand_green_blue;
+ }
+ }
+ }
+}
+
+void
+u_sampler_view_default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format)
+{
+ /* Expand to (0, 0, 0, 1) */
+ default_template(view,
+ texture,
+ format,
+ PIPE_SWIZZLE_ZERO);
+}
+
+void
+u_sampler_view_default_dx9_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format)
+{
+ /* Expand to (1, 1, 1, 1) */
+ default_template(view,
+ texture,
+ format,
+ PIPE_SWIZZLE_ONE);
+}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/auxiliary/util/u_sampler.h
index 6e3920c49b2..bdd061c851c 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/auxiliary/util/u_sampler.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2010 VMware, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,64 +10,48 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
-/* This is the interface that softpipe requires any window system
- * hosting it to implement. This is the only include file in softpipe
- * which is public.
- */
+#ifndef U_SAMPLER_H
+#define U_SAMPLER_H
-#ifndef SP_WINSYS_H
-#define SP_WINSYS_H
+
+#include "pipe/p_defines.h"
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
#ifdef __cplusplus
extern "C" {
#endif
-#include "pipe/p_defines.h"
-
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_texture;
-struct pipe_buffer;
-
-
-
-/**
- * Create a softpipe screen that uses the
- * given winsys for allocating buffers.
- */
-struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
-/**
- * Create a softpipe screen that uses
- * regular malloc to create all its buffers.
- */
-struct pipe_screen *softpipe_create_screen_malloc(void);
+void
+u_sampler_view_default_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format);
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride );
+void
+u_sampler_view_default_dx9_template(struct pipe_sampler_view *view,
+ const struct pipe_texture *texture,
+ enum pipe_format format);
#ifdef __cplusplus
-}
+} /* extern "C" { */
#endif
-#endif /* SP_WINSYS_H */
+#endif /* U_SAMPLER_H */
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 53f3c16dbcc..9203cb6580c 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -59,22 +59,7 @@ pass_user_buffer_create(struct pipe_screen *screen,
return buffer;
}
-static struct pipe_buffer *
-pass_surface_buffer_create(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- struct pipe_buffer *buffer =
- screen->winsys->surface_buffer_create(screen->winsys, width, height,
- format, usage, tex_usage, stride);
- buffer->screen = screen;
-
- return buffer;
-}
static void *
pass_buffer_map(struct pipe_screen *screen,
@@ -135,7 +120,6 @@ u_simple_screen_init(struct pipe_screen *screen)
{
screen->buffer_create = pass_buffer_create;
screen->user_buffer_create = pass_user_buffer_create;
- screen->surface_buffer_create = pass_surface_buffer_create;
screen->buffer_map = pass_buffer_map;
screen->buffer_unmap = pass_buffer_unmap;
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 79481b710bf..09b2382733d 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -45,11 +45,11 @@
* Move raw block of pixels from transfer object to user memory.
*/
void
-pipe_get_tile_raw(struct pipe_transfer *pt,
+pipe_get_tile_raw(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
void *dst, int dst_stride)
{
- struct pipe_screen *screen = pt->texture->screen;
const void *src;
if (dst_stride == 0)
@@ -58,14 +58,14 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- src = screen->transfer_map(screen, pt);
+ src = pipe->transfer_map(pipe, pt);
assert(src);
if(!src)
return;
util_copy_rect(dst, pt->texture->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
- screen->transfer_unmap(screen, pt);
+ pipe->transfer_unmap(pipe, pt);
}
@@ -73,11 +73,11 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
* Move raw block of pixels from user memory to transfer object.
*/
void
-pipe_put_tile_raw(struct pipe_transfer *pt,
+pipe_put_tile_raw(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const void *src, int src_stride)
{
- struct pipe_screen *screen = pt->texture->screen;
void *dst;
enum pipe_format format = pt->texture->format;
@@ -87,14 +87,14 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- dst = screen->transfer_map(screen, pt);
+ dst = pipe->transfer_map(pipe, pt);
assert(dst);
if(!dst)
return;
util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
- screen->transfer_unmap(screen, pt);
+ pipe->transfer_unmap(pipe, pt);
}
@@ -295,6 +295,55 @@ r8g8b8a8_put_tile_rgba(unsigned *dst,
}
+/*** PIPE_FORMAT_B5G5R5X1_UNORM ***/
+
+static void
+x1r5g5b5_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ const ushort pixel = *src++;
+ pRow[0] = ((pixel >> 10) & 0x1f) * (1.0f / 31.0f);
+ pRow[1] = ((pixel >> 5) & 0x1f) * (1.0f / 31.0f);
+ pRow[2] = ((pixel ) & 0x1f) * (1.0f / 31.0f);
+ pRow[3] = 1.0f;
+ }
+ p += dst_stride;
+ }
+}
+
+
+static void
+x1r5g5b5_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ unsigned r, g, b;
+ r = float_to_ubyte(pRow[0]);
+ g = float_to_ubyte(pRow[1]);
+ b = float_to_ubyte(pRow[2]);
+ r = r >> 3; /* 5 bits */
+ g = g >> 3; /* 5 bits */
+ b = b >> 3; /* 5 bits */
+ *dst++ = (1 << 15) | (r << 10) | (g << 5) | b;
+ }
+ p += src_stride;
+ }
+}
+
+
/*** PIPE_FORMAT_B5G5R5A1_UNORM ***/
static void
@@ -1174,6 +1223,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_A8B8G8R8_UNORM:
r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ x1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
+ break;
case PIPE_FORMAT_B5G5R5A1_UNORM:
a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
@@ -1246,7 +1298,8 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
void
-pipe_get_tile_rgba(struct pipe_transfer *pt,
+pipe_get_tile_rgba(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
float *p)
{
@@ -1265,16 +1318,80 @@ pipe_get_tile_rgba(struct pipe_transfer *pt,
if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV)
assert((x & 1) == 0);
- pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
+ pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
+
+ pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
+
+ FREE(packed);
+}
+
+
+void
+pipe_get_tile_swizzle(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x,
+ uint y,
+ uint w,
+ uint h,
+ uint swizzle_r,
+ uint swizzle_g,
+ uint swizzle_b,
+ uint swizzle_a,
+ enum pipe_format format,
+ float *p)
+{
+ unsigned dst_stride = w * 4;
+ void *packed;
+ uint i;
+ float rgba01[6];
+
+ if (pipe_clip_tile(x, y, &w, &h, pt)) {
+ return;
+ }
+
+ packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
+ if (!packed) {
+ return;
+ }
+
+ if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
+ assert((x & 1) == 0);
+ }
+
+ pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
FREE(packed);
+
+ if (swizzle_r == PIPE_SWIZZLE_RED &&
+ swizzle_g == PIPE_SWIZZLE_GREEN &&
+ swizzle_b == PIPE_SWIZZLE_BLUE &&
+ swizzle_a == PIPE_SWIZZLE_ALPHA) {
+ /* no-op, skip */
+ return;
+ }
+
+ rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
+ rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
+
+ for (i = 0; i < w * h; i++) {
+ rgba01[PIPE_SWIZZLE_RED] = p[0];
+ rgba01[PIPE_SWIZZLE_GREEN] = p[1];
+ rgba01[PIPE_SWIZZLE_BLUE] = p[2];
+ rgba01[PIPE_SWIZZLE_ALPHA] = p[3];
+
+ *p++ = rgba01[swizzle_r];
+ *p++ = rgba01[swizzle_g];
+ *p++ = rgba01[swizzle_b];
+ *p++ = rgba01[swizzle_a];
+ }
}
void
-pipe_put_tile_rgba(struct pipe_transfer *pt,
+pipe_put_tile_rgba(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const float *p)
{
@@ -1303,6 +1420,9 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_A8B8G8R8_UNORM:
r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
+ x1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
+ break;
case PIPE_FORMAT_B5G5R5A1_UNORM:
a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
@@ -1363,7 +1483,7 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
0, 0, w, h);
}
- pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
+ pipe_put_tile_raw(pipe, pt, x, y, w, h, packed, 0);
FREE(packed);
}
@@ -1373,11 +1493,11 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
* Get a block of Z values, converted to 32-bit range.
*/
void
-pipe_get_tile_z(struct pipe_transfer *pt,
+pipe_get_tile_z(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
uint *z)
{
- struct pipe_screen *screen = pt->texture->screen;
const uint dstStride = w;
ubyte *map;
uint *pDest = z;
@@ -1387,7 +1507,7 @@ pipe_get_tile_z(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- map = (ubyte *)screen->transfer_map(screen, pt);
+ map = (ubyte *)pipe->transfer_map(pipe, pt);
if (!map) {
assert(0);
return;
@@ -1453,16 +1573,16 @@ pipe_get_tile_z(struct pipe_transfer *pt,
assert(0);
}
- screen->transfer_unmap(screen, pt);
+ pipe->transfer_unmap(pipe, pt);
}
void
-pipe_put_tile_z(struct pipe_transfer *pt,
+pipe_put_tile_z(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const uint *zSrc)
{
- struct pipe_screen *screen = pt->texture->screen;
const uint srcStride = w;
const uint *ptrc = zSrc;
ubyte *map;
@@ -1472,7 +1592,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- map = (ubyte *)screen->transfer_map(screen, pt);
+ map = (ubyte *)pipe->transfer_map(pipe, pt);
if (!map) {
assert(0);
return;
@@ -1560,7 +1680,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
assert(0);
}
- screen->transfer_unmap(screen, pt);
+ pipe->transfer_unmap(pipe, pt);
}
diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h
index 1453af38b8a..1d8ce7d8cbc 100644
--- a/src/gallium/auxiliary/util/u_tile.h
+++ b/src/gallium/auxiliary/util/u_tile.h
@@ -56,34 +56,54 @@ extern "C" {
#endif
void
-pipe_get_tile_raw(struct pipe_transfer *pt,
+pipe_get_tile_raw(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
void *p, int dst_stride);
void
-pipe_put_tile_raw(struct pipe_transfer *pt,
+pipe_put_tile_raw(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const void *p, int src_stride);
void
-pipe_get_tile_rgba(struct pipe_transfer *pt,
+pipe_get_tile_rgba(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
float *p);
void
-pipe_put_tile_rgba(struct pipe_transfer *pt,
+pipe_get_tile_swizzle(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x,
+ uint y,
+ uint w,
+ uint h,
+ uint swizzle_r,
+ uint swizzle_g,
+ uint swizzle_b,
+ uint swizzle_a,
+ enum pipe_format format,
+ float *p);
+
+void
+pipe_put_tile_rgba(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const float *p);
void
-pipe_get_tile_z(struct pipe_transfer *pt,
+pipe_get_tile_z(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
uint *z);
void
-pipe_put_tile_z(struct pipe_transfer *pt,
+pipe_put_tile_z(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const uint *z);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index ba23435f698..6d461cb8800 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -230,6 +230,7 @@ static bool
init_pipe_state(struct vl_compositor *c)
{
struct pipe_sampler_state sampler;
+ struct pipe_vertex_element vertex_elems[2];
assert(c);
@@ -251,15 +252,27 @@ init_pipe_state(struct vl_compositor *c)
/*sampler.border_color[i] = ;*/
/*sampler.max_anisotropy = ;*/
c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
-
+
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ vertex_elems[1].src_offset = 0;
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 1;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ c->vertex_elems = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
+
+
return true;
}
static void cleanup_pipe_state(struct vl_compositor *c)
{
assert(c);
-
+
c->pipe->delete_sampler_state(c->pipe, c->sampler);
+ c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems);
}
static bool
@@ -314,12 +327,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[0].buffer);
- c->vertex_elems[0].src_offset = 0;
- c->vertex_elems[0].instance_divisor = 0;
- c->vertex_elems[0].vertex_buffer_index = 0;
- c->vertex_elems[0].nr_components = 2;
- c->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
/*
* Create our texcoord buffer and texcoord buffer element
* Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices
@@ -344,12 +351,6 @@ init_buffers(struct vl_compositor *c)
pipe_buffer_unmap(c->pipe->screen, c->vertex_bufs[1].buffer);
- c->vertex_elems[1].src_offset = 0;
- c->vertex_elems[1].instance_divisor = 0;
- c->vertex_elems[1].vertex_buffer_index = 1;
- c->vertex_elems[1].nr_components = 2;
- c->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
/*
* Create our vertex shader's constant buffer
* Const buffer contains scaling and translation vectors
@@ -483,7 +484,7 @@ void vl_compositor_render(struct vl_compositor *compositor,
compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
compositor->pipe->bind_fs_state(compositor->pipe, compositor->fragment_shader);
compositor->pipe->set_vertex_buffers(compositor->pipe, 2, compositor->vertex_bufs);
- compositor->pipe->set_vertex_elements(compositor->pipe, 2, compositor->vertex_elems);
+ compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_VERTEX, 0, compositor->vs_const_buf);
compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index 6a9a3fd7af1..51755554da1 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -43,10 +43,10 @@ struct vl_compositor
void *sampler;
void *vertex_shader;
void *fragment_shader;
+ void *vertex_elems;
struct pipe_viewport_state viewport;
struct pipe_scissor_state scissor;
struct pipe_vertex_buffer vertex_bufs[2];
- struct pipe_vertex_element vertex_elems[2];
struct pipe_buffer *vs_const_buf, *fs_const_buf;
};
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
index f323de0ea55..beb4722901e 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -680,14 +680,14 @@ xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
assert(r);
for (i = 0; i < 3; ++i) {
- r->tex_transfer[i] = r->pipe->screen->get_tex_transfer
+ r->tex_transfer[i] = r->pipe->get_tex_transfer
(
- r->pipe->screen, r->textures.all[i],
+ r->pipe, r->textures.all[i],
0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
r->textures.all[i]->width0, r->textures.all[i]->height0
);
- r->texels[i] = r->pipe->screen->transfer_map(r->pipe->screen, r->tex_transfer[i]);
+ r->texels[i] = r->pipe->transfer_map(r->pipe, r->tex_transfer[i]);
}
}
@@ -699,8 +699,8 @@ xfer_buffers_unmap(struct vl_mpeg12_mc_renderer *r)
assert(r);
for (i = 0; i < 3; ++i) {
- r->pipe->screen->transfer_unmap(r->pipe->screen, r->tex_transfer[i]);
- r->pipe->screen->tex_transfer_destroy(r->tex_transfer[i]);
+ r->pipe->transfer_unmap(r->pipe, r->tex_transfer[i]);
+ r->pipe->tex_transfer_destroy(r->pipe, r->tex_transfer[i]);
}
}
@@ -708,6 +708,7 @@ static bool
init_pipe_state(struct vl_mpeg12_mc_renderer *r)
{
struct pipe_sampler_state sampler;
+ struct pipe_vertex_element vertex_elems[8];
unsigned filters[5];
unsigned i;
@@ -771,6 +772,59 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
}
+ /* Position element */
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Luma, texcoord element */
+ vertex_elems[1].src_offset = sizeof(struct vertex2f);
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 0;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cr texcoord element */
+ vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
+ vertex_elems[2].instance_divisor = 0;
+ vertex_elems[2].vertex_buffer_index = 0;
+ vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cb texcoord element */
+ vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
+ vertex_elems[3].instance_divisor = 0;
+ vertex_elems[3].vertex_buffer_index = 0;
+ vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface top field texcoord element */
+ vertex_elems[4].src_offset = 0;
+ vertex_elems[4].instance_divisor = 0;
+ vertex_elems[4].vertex_buffer_index = 1;
+ vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface bottom field texcoord element */
+ vertex_elems[5].src_offset = sizeof(struct vertex2f);
+ vertex_elems[5].instance_divisor = 0;
+ vertex_elems[5].vertex_buffer_index = 1;
+ vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface top field texcoord element */
+ vertex_elems[6].src_offset = 0;
+ vertex_elems[6].instance_divisor = 0;
+ vertex_elems[6].vertex_buffer_index = 2;
+ vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface bottom field texcoord element */
+ vertex_elems[7].src_offset = sizeof(struct vertex2f);
+ vertex_elems[7].instance_divisor = 0;
+ vertex_elems[7].vertex_buffer_index = 2;
+ vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* need versions with 4,6 and 8 vertex elems */
+ r->vertex_elems[0] = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
+ r->vertex_elems[1] = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
+ r->vertex_elems[2] = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
+
return true;
}
@@ -783,6 +837,8 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
for (i = 0; i < 5; ++i)
r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
+ for (i = 0; i < 3; i++)
+ r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems[i]);
}
static bool
@@ -888,62 +944,6 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
);
}
- /* Position element */
- r->vertex_elems[0].src_offset = 0;
- r->vertex_elems[0].instance_divisor = 0;
- r->vertex_elems[0].vertex_buffer_index = 0;
- r->vertex_elems[0].nr_components = 2;
- r->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Luma, texcoord element */
- r->vertex_elems[1].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[1].instance_divisor = 0;
- r->vertex_elems[1].vertex_buffer_index = 0;
- r->vertex_elems[1].nr_components = 2;
- r->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cr texcoord element */
- r->vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
- r->vertex_elems[2].instance_divisor = 0;
- r->vertex_elems[2].vertex_buffer_index = 0;
- r->vertex_elems[2].nr_components = 2;
- r->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Chroma Cb texcoord element */
- r->vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
- r->vertex_elems[3].instance_divisor = 0;
- r->vertex_elems[3].vertex_buffer_index = 0;
- r->vertex_elems[3].nr_components = 2;
- r->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface top field texcoord element */
- r->vertex_elems[4].src_offset = 0;
- r->vertex_elems[4].instance_divisor = 0;
- r->vertex_elems[4].vertex_buffer_index = 1;
- r->vertex_elems[4].nr_components = 2;
- r->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* First ref surface bottom field texcoord element */
- r->vertex_elems[5].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[5].instance_divisor = 0;
- r->vertex_elems[5].vertex_buffer_index = 1;
- r->vertex_elems[5].nr_components = 2;
- r->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface top field texcoord element */
- r->vertex_elems[6].src_offset = 0;
- r->vertex_elems[6].instance_divisor = 0;
- r->vertex_elems[6].vertex_buffer_index = 2;
- r->vertex_elems[6].nr_components = 2;
- r->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
- /* Second ref surface bottom field texcoord element */
- r->vertex_elems[7].src_offset = sizeof(struct vertex2f);
- r->vertex_elems[7].instance_divisor = 0;
- r->vertex_elems[7].vertex_buffer_index = 2;
- r->vertex_elems[7].nr_components = 2;
- r->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
-
r->vs_const_buf = pipe_buffer_create
(
r->pipe->screen,
@@ -1307,7 +1307,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 4, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[0]);
r->pipe->set_fragment_sampler_textures(r->pipe, 3, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
r->pipe->bind_vs_state(r->pipe, r->i_vs);
@@ -1320,7 +1320,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1334,7 +1334,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->past;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1348,7 +1348,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1362,7 +1362,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 6, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[1]);
r->textures.individual.ref[0] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 4, r->textures.all);
r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
@@ -1376,7 +1376,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
@@ -1391,7 +1391,7 @@ flush(struct vl_mpeg12_mc_renderer *r)
if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) {
r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
- r->pipe->set_vertex_elements(r->pipe, 8, r->vertex_elems);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems[2]);
r->textures.individual.ref[0] = r->past;
r->textures.individual.ref[1] = r->future;
r->pipe->set_fragment_sampler_textures(r->pipe, 5, r->textures.all);
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
index f00b8c7b8b1..a11a3e7307b 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
@@ -66,8 +66,8 @@ struct vl_mpeg12_mc_renderer
struct pipe_buffer *vs_const_buf;
struct pipe_buffer *fs_const_buf;
struct pipe_framebuffer_state fb_state;
- struct pipe_vertex_element vertex_elems[8];
-
+ void *vertex_elems[3];
+
union
{
void *all[5];
diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt
new file mode 100644
index 00000000000..0baf2682871
--- /dev/null
+++ b/src/gallium/docs/d3d11ddi.txt
@@ -0,0 +1,492 @@
+This document compares the D3D10/D3D11 device driver interface with Gallium.
+It is written from the perspective of a developer implementing a D3D10/D3D11 driver as a Gallium state tracker.
+
+Note that naming and other cosmetic differences are not noted, since they don't really matter and would severely clutter the document.
+Gallium/OpenGL terminology is used in preference to D3D terminology.
+
+NOTE: this document tries to be complete but most likely isn't fully complete and also not fully correct: please submit patches if you spot anything incorrect
+
+Also note that this is specifically for the DirectX 10/11 Windows Vista/7 DDI interfaces.
+DirectX 9 has both user-mode (for Vista) and kernel mode (pre-Vista) interfaces, but they are significantly different from Gallium due to the presence of a lot of fixed function functionality.
+
+The user-visible DirectX 10/11 interfaces are distinct from the kernel DDI, but they match very closely.
+
+* Accessing Microsoft documentation
+
+See http://msdn.microsoft.com/en-us/library/dd445501.aspx ("D3D11DDI_DEVICEFUNCS") for D3D documentation.
+
+Also see http://download.microsoft.com/download/f/2/d/f2d5ee2c-b7ba-4cd0-9686-b6508b5479a1/direct3d10_web.pdf ("The Direct3D 10 System" by David Blythe) for an introduction to Direct3D 10 and the rationale for its design.
+
+The Windows Driver Kit contains the actual headers, as well as shader bytecode documentation.
+
+To get the headers from Linux, run the following, in a dedicated directory:
+wget http://download.microsoft.com/download/4/A/2/4A25C7D5-EFBE-4182-B6A9-AE6850409A78/GRMWDK_EN_7600_1.ISO
+sudo mount -o loop GRMWDK_EN_7600_1.ISO /mnt/tmp
+cabextract -x /mnt/tmp/wdk/headers_cab001.cab
+rename 's/^_(.*)_[0-9]*$/$1/' *
+sudo umount /mnt/tmp
+
+d3d10umddi.h contains the DDI interface analyzed in this document: note that it is much easier to read this online on MSDN.
+d3d{10,11}TokenizedProgramFormat.hpp contains the shader bytecode definitions: this is not available on MSDN.
+d3d9types.h contains DX9 shader bytecode, and DX9 types
+d3dumddi.h contains the DirectX 9 DDI interface
+
+* Glossary
+
+BC1: DXT1
+BC2: DXT3
+BC3: DXT5
+BC5: RGTC
+BC6H: BPTC float
+BC7: BPTC
+CS = compute shader: OpenCL-like shader
+DS = domain shader: tessellation evaluation shader
+HS = hull shader: tessellation control shader
+IA = input assembler: primitive assembly
+Input layout: vertex elements
+OM = output merger: blender
+PS = pixel shader: fragment shader
+Primitive topology: primitive type
+Resource: buffer or texture
+Shader resource (view): sampler view
+SO = stream out: transform feedback
+Unordered access view: view supporting random read/write access (usually from compute shaders)
+
+* Legend
+
+-: features D3D11 has and Gallium lacks
++: features Gallium has and D3D11 lacks
+!: differences between D3D11 and Gallium
+*: possible improvements to Gallium
+>: references to comparisons of special enumerations
+#: comment
+
+* Gallium functions with no direct D3D10/D3D11 equivalent
+
+clear
+ + Gallium supports clearing both render targets and depth/stencil with a single call
+
+draw_range_elements
+ + Gallium supports indexed draw with explicit range
+
+fence_signalled
+fence_finish
+ + D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported
+
+set_clip_state
+ + Gallium supports fixed function user clip planes, D3D10/D3D11 only support using the vertex shader for them
+
+set_polygon_stipple
+ + Gallium supports polygon stipple
+
+surface_fill
+ + Gallium supports subrectangle fills of surfaces, D3D10 only supports full clears of views
+
+* DirectX 10/11 DDI functions and Gallium equivalents
+
+AbandonCommandList (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CalcPrivateBlendStateSize
+CalcPrivateDepthStencilStateSize
+CalcPrivateDepthStencilViewSize
+CalcPrivateElementLayoutSize
+CalcPrivateGeometryShaderWithStreamOutput
+CalcPrivateOpenedResourceSize
+CalcPrivateQuerySize
+CalcPrivateRasterizerStateSize
+CalcPrivateRenderTargetViewSize
+CalcPrivateResourceSize
+CalcPrivateSamplerSize
+CalcPrivateShaderResourceViewSize
+CalcPrivateShaderSize
+CalcDeferredContextHandleSize (D3D11 only)
+CalcPrivateCommandListSize (D3D11 only)
+CalcPrivateDeferredContextSize (D3D11 only)
+CalcPrivateTessellationShaderSize (D3D11 only)
+CalcPrivateUnorderedAccessViewSize (D3D11 only)
+ ! D3D11 allocates private objects itself, using the size computed here
+ * Gallium could do something similar to be able to put the private data inline into state tracker objects: this would allow them to fit in the same cacheline and improve performance
+
+CheckDeferredContextHandleSizes (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CheckFormatSupport -> screen->is_format_supported
+ ! Gallium passes usages to this function, D3D11 returns them
+ - Gallium does not differentiate between blendable and non-blendable render targets
+ - Gallium lacks multisampled-texture and multisampled-render-target usages
+
+CheckMultisampleQualityLevels
+ * could merge this with is_format_supported
+ - Gallium lacks multisampling support
+
+CommandListExecute (D3D11 only)
+ - Gallium does not support command lists
+
+CopyStructureCount (D3D11 only)
+ - Gallium does not support unordered access views (views that can be written to arbitrarily from compute shaders)
+
+ClearDepthStencilView -> clear
+ClearRenderTargetView -> clear
+ # D3D11 is not totally clear about whether this applies to any view or only a "currently-bound view"
+ + Gallium allows to clear both depth/stencil and render target(s) in a single operation
+ + Gallium supports double-precision depth values (but not rgba values!)
+ * May want to also support double-precision rgba or use "float" for "depth"
+
+ClearUnorderedAccessViewFloat (D3D11 only)
+ClearUnorderedAccessViewUint (D3D11 only)
+ - Gallium does not support unordered access views (views that can be written to arbitrarily from compute shaders)
+
+CreateBlendState (extended in D3D10.1) -> create_blend_state
+ # D3D10 does not support per-RT blending, only D3D10.1 does
+ - Gallium lacks alpha-to-coverage
+ + Gallium supports logic ops
+ + Gallium supports dithering
+ + Gallium supports using the broadcast alpha component of the blend constant color
+
+CreateCommandList (D3D11 only)
+ - Gallium does not support command lists
+
+CreateComputeShader (D3D11 only)
+ - Gallium does not support compute shaders
+
+CreateDeferredContext (D3D11 only)
+ - Gallium does not support deferred contexts
+
+CreateDomainShader (D3D11 only)
+ - Gallium does not support domain shaders
+
+CreateHullShader (D3D11 only)
+ - Gallium does not support hull shaders
+
+CreateUnorderedAccessView (D3D11 only)
+ - Gallium does not support unordered access views
+
+CreateDepthStencilState -> create_depth_stencil_alpha_state
+ ! D3D11 has both a global stencil enable, and front/back enables; Gallium has only front/back enables
+ + Gallium has per-face writemask/valuemasks, D3D11 uses the same value for back and front
+ + Gallium supports the alpha test, which D3D11 lacks
+
+CreateDepthStencilView -> get_tex_surface
+CreateRenderTargetView -> get_tex_surface
+ ! Gallium merges depthstencil and rendertarget views into pipe_surface, which also doubles as a 2D surface abstraction
+ - lack of texture array support
+ - lack of render-to-buffer support
+ + Gallium supports using 3D texture zslices as a depth/stencil buffer (in theory)
+
+CreateElementLayout -> create_vertex_elements_state
+ ! D3D11 allows sparse vertex elements (via InputRegister); in Gallium they must be specified sequentially
+ ! D3D11 has an extra flag (InputSlotClass) that is the same as instance_divisor == 0
+
+CreateGeometryShader -> create_gs_state
+CreateGeometryShaderWithStreamOutput -> create_gs_state
+CreatePixelShader -> create_fs_state
+CreateVertexShader -> create_vs_state
+ > bytecode is different (see D3d10tokenizedprogramformat.hpp)
+ ! D3D11 describes input/outputs separately from bytecode; Gallium has the tgsi_scan.c module to extract it from TGSI
+ @ TODO: look into DirectX 10/11 semantics specification and bytecode
+
+CheckCounter
+CheckCounterInfo
+CreateQuery -> create_query
+ - Gallium only supports occlusion, primitives generated and primitives emitted queries
+ ! D3D11 implements fences with "event" queries
+ * TIMESTAMP could be implemented as an additional fields for other queries: some cards have hardware support for exactly this
+ * OCCLUSIONPREDICATE is required for the OpenGL v2 occlusion query functionality
+ * others are performance counters, we may want them but they are not critical
+
+CreateRasterizerState
+ - Gallium lacks clamping of polygon offset depth biases
+ - Gallium lacks support to disable depth clipping
+ - Gallium lacks multisampling
+ + Gallium, like OpenGL, supports PIPE_POLYGON_MODE_POINT
+ + Gallium, like OpenGL, supports per-face polygon fill modes
+ + Gallium, like OpenGL, supports culling everything
+ + Gallium, like OpenGL, supports two-side lighting; D3D11 only has the facing attribute
+ + Gallium, like OpenGL, supports per-fill-mode polygon offset enables
+ + Gallium, like OpenGL, supports polygon smoothing
+ + Gallium, like OpenGL, supports polygon stipple
+ + Gallium, like OpenGL, supports point smoothing
+ + Gallium, like OpenGL, supports point sprites
+ + Gallium supports specifying point quad rasterization
+ + Gallium, like OpenGL, supports per-point point size
+ + Gallium, like OpenGL, supports line smoothing
+ + Gallium, like OpenGL, supports line stipple
+ + Gallium supports line last pixel rule specification
+ + Gallium, like OpenGL, supports provoking vertex convention
+ + Gallium supports D3D9 rasterization rules
+ + Gallium supports fixed line width
+ + Gallium supports fixed point size
+
+CreateResource -> texture_create or buffer_create
+ ! D3D11 passes the dimensions of all mipmap levels to the create call, while Gallium has an implicit floor(x/2) rule
+ # Note that hardware often has the implicit rule, so the D3D11 interface seems to make little sense
+ # Also, the D3D11 API does not allow the user to specify mipmap sizes, so this really seems a dubious decision on Microsoft's part
+ - D3D11 supports specifying initial data to write in the resource
+ - Gallium lacks support for stream output buffer usage
+ - Gallium does not support unordered access buffers
+ ! D3D11 specifies mapping flags (i.e. read/write/discard);:it's unclear what they are used for here
+ - D3D11 supports odd things in the D3D10_DDI_RESOURCE_MISC_FLAG enum (D3D10_DDI_RESOURCE_MISC_DISCARD_ON_PRESENT, D3D11_DDI_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS, D3D11_DDI_RESOURCE_MISC_BUFFER_STRUCTURED)
+ - Gallium does not support indirect draw call parameter buffers
+ - Gallium lacks multisampling
+ - Gallium lacks array textures
+ ! D3D11 supports specifying hardware modes and other stuff here for scanout resources
+ + Gallium allows specifying minimum buffer alignment
+ ! D3D11 implements cube maps as 2D array textures
+
+CreateSampler
+ - D3D11 supports a monochrome convolution filter for "text filtering"
+ + Gallium supports non-normalized coordinates
+ + Gallium supports CLAMP, MIRROR_CLAMP and MIRROR_CLAMP_TO_BORDER
+ + Gallium supports setting min/max/mip filters and anisotropy independently
+
+CreateShaderResourceView (extended in D3D10.1) -> create_sampler_view
+ - Gallium lacks sampler views over buffers
+ - Gallium lacks texture arrays, and cube map views over texture arrays
+ + Gallium supports specifying a swizzle
+ ! D3D11 implements "cube views" as views into a 2D array texture
+
+CsSetConstantBuffers (D3D11 only)
+CsSetSamplers (D3D11 only)
+CsSetShader (D3D11 only)
+CsSetShaderResources (D3D11 only)
+CsSetShaderWithIfaces (D3D11 only)
+CsSetUnorderedAccessViews (D3D11 only)
+ - Gallium does not support compute shaders
+
+DestroyBlendState
+DestroyCommandList (D3D11 only)
+DestroyDepthStencilState
+DestroyDepthStencilView
+DestroyDevice
+DestroyElementLayout
+DestroyQuery
+DestroyRasterizerState
+DestroyRenderTargetView
+DestroyResource
+DestroySampler
+DestroyShader
+DestroyShaderResourceView
+DestroyUnorderedAccessView (D3D11 only)
+ # these are trivial
+
+Dispatch (D3D11 only)
+ - Gallium does not support compute shaders
+
+DispatchIndirect (D3D11 only)
+ - Gallium does not support compute shaders
+
+Draw -> draw_arrays
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+
+DrawAuto
+ - Gallium lacks stream out and DrawAuto
+
+DrawIndexed -> draw_elements
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+ * may want to add a separate set_index_buffer
+ - Gallium lacks base vertex for indexed draw calls
+ + D3D11 lacks draw_range_elements functionality, which is required for OpenGL
+
+DrawIndexedInstanced -> draw_elements_instanced
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+ * may want to add a separate set_index_buffer
+ - Gallium lacks base vertex for indexed draw calls
+
+DrawIndexedInstancedIndirect (D3D11 only) -> call draw_elements_instanced multiple times in software
+ # this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls
+ - Gallium does not support draw call parameter buffers and indirect draw
+
+DrawInstanced -> draw_arrays_instanced
+ ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better
+
+DrawInstancedIndirect (D3D11 only) -> call draw_arrays_instanced multiple times in software
+ # this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls
+ - Gallium does not support draw call parameter buffers and indirect draws
+
+DsSetConstantBuffers (D3D11 only)
+DsSetSamplers (D3D11 only)
+DsSetShader (D3D11 only)
+DsSetShaderResources (D3D11 only)
+DsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support domain shaders
+
+Flush -> flush
+ ! Gallium supports fencing and several kinds of flushing here, D3D11 just has a dumb glFlush-like function
+
+GenMips
+ - Gallium lacks a mipmap generation interface, and does this manually with the 3D engine
+ * it may be useful to add a mipmap generation interface, since the hardware (especially older cards) may have a better way than using the 3D engine
+
+GsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_GEOMETRY, i, phBuffers[i])
+
+GsSetSamplers
+ - Gallium does not support sampling in geometry shaders
+
+GsSetShader -> bind_gs_state
+
+GsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+GsSetShaderResources
+ - Gallium does not support sampling in geometry shaders
+
+HsSetConstantBuffers (D3D11 only)
+HsSetSamplers (D3D11 only)
+HsSetShader (D3D11 only)
+HsSetShaderResources (D3D11 only)
+HsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support hull shaders
+
+IaSetIndexBuffer
+ ! Gallium passes this to the draw_elements or draw_elements_instanced calls
+ + Gallium supports 8-bit indices
+ ! the D3D11 interface allows index-size-unaligned byte offsets into index buffers; it's not clear whether they actually work
+
+IaSetInputLayout -> bind_vertex_elements_state
+
+IaSetTopology
+ ! Gallium passes the topology = primitive type to the draw calls
+ * may want to add an interface for this
+ - Gallium lacks support for DirectX 11 tessellated primitives
+ + Gallium supports line loops, triangle fans, quads, quad strips and polygons
+
+IaSetVertexBuffers -> set_vertex_buffers
+ + Gallium allows to specify a max_index here
+ - Gallium only allows setting all vertex buffers at once, while D3D11 supports setting a subset
+
+OpenResource -> texture_from_handle
+
+PsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_FRAGMENT, i, phBuffers[i])
+ * may want to split into fragment/vertex-specific versions
+
+PsSetSamplers -> bind_fragment_sampler_states
+ * may want to allow binding subsets instead of all at once
+
+PsSetShader -> bind_fs_state
+
+PsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+PsSetShaderResources -> set_fragment_sampler_views
+ * may want to allow binding subsets instead of all at once
+
+QueryBegin -> begin_query
+
+QueryEnd -> end_query
+
+QueryGetData -> get_query_result
+ - D3D11 supports reading an arbitrary data chunk for query results, Gallium only supports reading a 64-bit integer
+ + D3D11 doesn't seem to support actually waiting for the query result (?!)
+ - D3D11 supports optionally not flushing command buffers here and instead returning DXGI_DDI_ERR_WASSTILLDRAWING
+
+RecycleCommandList (D3D11 only)
+RecycleCreateCommandList (D3D11 only)
+RecycleDestroyCommandList (D3D11 only)
+ - Gallium does not support command lists
+
+RecycleCreateDeferredContext (D3D11 only)
+ - Gallium does not support deferred contexts
+
+RelocateDeviceFuncs
+ - Gallium does not support moving pipe_context, while D3D11 seems to, using this
+
+ResetPrimitiveID (D3D10.1+ only, #ifdef D3D10PSGP)
+ # used to do vertex processing on the GPU on Intel G45 chipsets when it is faster this way (see www.intel.com/Assets/PDF/whitepaper/322931.pdf)
+ # presumably this resets the primitive id system value
+ - Gallium does not support vertex pipeline bypass anymore
+
+ResourceCopy
+ResourceCopyRegion
+ResourceConvert (D3D10.1+ only)
+ResourceConvertRegion (D3D10.1+ only)
+ -> surface_copy
+ - Gallium does not support hardware buffer copies
+ - Gallium does not support copying 3D texture subregions in a single call
+
+ResourceIsStagingBusy -> is_texture_referenced, is_buffer_referenced
+ - Gallium does not support checking reference for a whole texture, but only a specific surface
+
+ResourceReadAfterWriteHazard
+ ! Gallium specifies hides this, except for the render and texture caches
+
+ResourceResolveSubresource
+ - Gallium does not support multisample sample resolution
+
+ResourceMap
+ResourceUnmap
+DynamicConstantBufferMapDiscard
+DynamicConstantBufferUnmap
+DynamicIABufferMapDiscard
+DynamicIABufferMapNoOverwrite
+DynamicIABufferUnmap
+DynamicResourceMapDiscard
+DynamicResourceUnmap
+StagingResourceMap
+StagingResourceUnmap
+ -> buffer_map / buffer_unmap
+ -> transfer functions
+ ! Gallium and D3D have different semantics for transfers
+ * D3D separates vertex/index buffers from constant buffers
+ ! D3D separates some buffer flags into specialized calls
+
+ResourceUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources
+DefaultConstantBufferUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources
+
+SetBlendState -> bind_blend_state and set_blend_color
+ ! D3D11 fuses bind_blend_state and set_blend_color in a single function
+ - Gallium lacks the sample mask
+
+SetDepthStencilState -> bind_depth_stencil_alpha_state and set_stencil_ref
+ ! D3D11 fuses bind_depth_stencil_alpha_state and set_stencil_ref in a single function
+
+SetPredication -> render_condition
+ # here both D3D11 and Gallium seem very limited (hardware is too, probably though)
+ # ideally, we should support nested conditional rendering, as well as more complex tests (checking for an arbitrary range, after an AND with arbitrary mask )
+ # of couse, hardware support is probably as limited as OpenGL/D3D11
+ + Gallium, like NV_conditional_render, supports by-region and wait flags
+ - D3D11 supports predication conditional on being equal any value (along with occlusion predicates); Gallium only supports on non-zero
+
+SetRasterizerState -> bind_rasterizer_state
+
+SetRenderTargets (extended in D3D11) -> set_framebuffer_state
+ ! Gallium passed a width/height here, D3D11 does not
+ ! Gallium lacks ClearTargets (but this is redundant and the driver can trivially compute this if desired)
+ - Gallium does not support unordered access views
+ - Gallium does not support geometry shader selection of texture array image / 3D texture zslice
+
+SetResourceMinLOD (D3D11 only)
+ - Gallium does not support min lod directly on textures
+
+SetScissorRects
+ - Gallium lacks support for multiple geometry-shader-selectable scissor rectangles D3D11 has
+
+SetTextFilterSize
+ - Gallium lacks support for text filters
+
+SetVertexPipelineOutput (D3D10.1+ only)
+ # used to do vertex processing on the GPU on Intel G45 chipsets when it is faster this way (see www.intel.com/Assets/PDF/whitepaper/322931.pdf)
+ - Gallium does not support vertex pipeline bypass anymore
+
+SetViewports
+ - Gallium lacks support for multiple geometry-shader-selectable viewports D3D11 has
+
+ShaderResourceViewReadAfterWriteHazard -> flush(PIPE_FLUSH_RENDER_CACHE)
+ - Gallium does not support specifying this per-render-target/view
+
+SoSetTargets
+ - Gallium does not support stream out
+
+VsSetConstantBuffers -> for(i = StartBuffer; i < NumBuffers; ++i) set_constant_buffer(PIPE_SHADER_VERTEX, i, phBuffers[i])
+ * may want to split into fragment/vertex-specific versions
+
+VsSetSamplers -> bind_vertex_sampler_states
+ * may want to allow binding subsets instead of all at once
+
+VsSetShader -> bind_vs_state
+
+VsSetShaderWithIfaces (D3D11 only)
+ - Gallium does not support shader interfaces
+
+VsSetShaderResources -> set_fragment_sampler_views
+ * may want to allow binding subsets instead of all at once
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 9080addba44..2b0941010b0 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -24,6 +24,7 @@ CSO objects handled by the context object:
* :ref:`Depth, Stencil, & Alpha`: ``*_depth_stencil_alpha_state``
* :ref:`Shader`: These have two sets of methods. ``*_fs_state`` is for
fragment shaders, and ``*_vs_state`` is for vertex shaders.
+* :ref:`Vertex Elements`: ``*_vertex_elements_state``
Resource Binding State
@@ -39,8 +40,7 @@ buffers, surfaces) are bound to the driver.
are mostly restricted to the first one right now).
* ``set_framebuffer_state``
-* ``set_fragment_sampler_textures``
-* ``set_vertex_sampler_textures``
+
* ``set_vertex_buffers``
@@ -50,6 +50,7 @@ Non-CSO State
These pieces of state are too small, variable, and/or trivial to have CSO
objects. They all follow simple, one-method binding calls, e.g.
``set_blend_color``.
+
* ``set_stencil_ref`` sets the stencil front and back reference values
which are used as comparison values in stencil test.
* ``set_blend_color``
@@ -60,7 +61,41 @@ objects. They all follow simple, one-method binding calls, e.g.
not have the scissor test enabled, then the scissor bounds never need to
be set since they will not be used.
* ``set_viewport_state``
-* ``set_vertex_elements``
+
+
+Sampler Views
+^^^^^^^^^^^^^
+
+These are the means to bind textures to shader stages. To create one, specify
+its format, swizzle and LOD range in sampler view template.
+
+If texture format is different than template format, it is said the texture
+is being cast to another format. Casting can be done only between compatible
+formats, that is formats that have matching component order and sizes.
+
+Swizzle fields specify they way in which fetched texel components are placed
+in the result register. For example, ``swizzle_r`` specifies what is going to be
+placed in first component of result register.
+
+The ``first_level`` and ``last_level`` fields of sampler view template specify
+the LOD range the texture is going to be constrained to.
+
+* ``set_fragment_sampler_views`` binds an array of sampler views to
+ fragment shader stage. Every binding point acquires a reference
+ to a respective sampler view and releases a reference to the previous
+ sampler view.
+
+* ``set_vertex_sampler_views`` binds an array of sampler views to vertex
+ shader stage. Every binding point acquires a reference to a respective
+ sampler view and releases a reference to the previous sampler view.
+
+* ``create_sampler_view`` creates a new sampler view. ``texture`` is associated
+ with the sampler view which results in sampler view holding a reference
+ to the texture. Format specified in template must be compatible
+ with texture format.
+
+* ``sampler_view_destroy`` destroys a sampler view and releases its reference
+ to associated texture.
Clearing
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index ccd9136a2eb..e8dc82964fa 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -7,7 +7,7 @@ The rasterizer state controls the rendering of points, lines and triangles.
Attributes include polygon culling state, line width, line stipple,
multisample state, scissoring and flat/smooth shading.
-Members
+Shading
-------
flatshade
@@ -46,6 +46,49 @@ There are several important exceptions to the specification of this rule.
second vertex, not the first. This permits each segment of the fan to have
a different color.
+Points
+------
+
+sprite_coord_enable
+^^^^^^^^^^^^^^^^^^^
+
+Specifies if a texture unit has its texture coordinates replaced or not. This
+is a packed bitfield containing the enable for all texcoords -- if all bits
+are zero, point sprites are effectively disabled. If any bit is set, then
+point_smooth and point_quad_rasterization are ignored; point smoothing is
+disabled and points are always rasterized as quads. If enabled, the four
+vertices of the resulting quad will be assigned texture coordinates,
+according to sprite_coord_mode.
+
+sprite_coord_mode
+^^^^^^^^^^^^^^^^^
+
+Specifies how the value for each shader output should be computed when drawing
+point sprites. For PIPE_SPRITE_COORD_LOWER_LEFT, the lower-left vertex will
+have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left
+vertex will have coordinates (0,0,0,1).
+This state is used by :ref:`Draw` to generate texcoords.
+
+.. note::
+
+ When geometry shaders are available, a special geometry shader could be
+ used instead of this functionality, to convert incoming points into quads
+ with the proper texture coordinates.
+
+point_quad_rasterization
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Determines if points should be rasterized as quads or points. Certain APIs,
+like Direct3D, always use quad rasterization for points, regardless of
+whether point sprites are enabled or not. If this state is enabled, point
+smoothing and antialiasing are disabled, and sprite coordinates are not
+generated.
+
+.. note::
+
+ Some renderers always internally translate points into quads; this state
+ still affects those renderers by overriding other rasterization state.
+
Other Members
^^^^^^^^^^^^^
@@ -107,37 +150,6 @@ point_size_per_vertex
Whether vertices have a point size element.
point_size
The size of points, if not specified per-vertex.
-sprite_coord_enable
- Specifies if a coord has its texture coordinates replaced or not. This
- is a packed bitfield containing the enable for all coords - if all are 0
- point sprites are effectively disabled, though points may still be
- rendered slightly different according to point_quad_rasterization.
- If any coord is non-zero, point_smooth should be disabled, and
- point_quad_rasterization enabled.
- If enabled, the four vertices of the resulting quad will be assigned
- texture coordinates, according to sprite_coord_mode.
-sprite_coord_mode
- Specifies how the value for each shader output should be computed when
- drawing sprites, for each coord which has sprite_coord_enable set.
- For PIPE_SPRITE_COORD_LOWER_LEFT, the lower left vertex will have
- coordinate (0,0,0,1).
- For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have
- coordinate (0,0,0,1).
- This state is needed by :ref:`Draw` because that's where each
- point vertex is converted into four quad vertices. There's no other
- place to emit the new vertex texture coordinates which are required for
- sprite rendering.
- Note that when geometry shaders are available, this state could be
- removed. A special geometry shader defined by the state tracker could
- convert the incoming points into quads with the proper texture coords.
-point_quad_rasterization
- This determines if points should be rasterized as quads or points.
- d3d always uses quad rasterization for points, regardless if point sprites
- are enabled or not, but OGL has different rules. If point_quad_rasterization
- is set, point_smooth should be disabled, and points will be rendered as
- squares even if multisample is enabled.
- sprite_coord_enable should be zero if point_quad_rasterization is not
- enabled.
scissor
Whether the scissor test is enabled.
diff --git a/src/gallium/docs/source/cso/velems.rst b/src/gallium/docs/source/cso/velems.rst
new file mode 100644
index 00000000000..92cde014fb8
--- /dev/null
+++ b/src/gallium/docs/source/cso/velems.rst
@@ -0,0 +1,24 @@
+.. _vertexelements:
+
+Vertex Elements
+===============
+
+This state controls format etc. of the input attributes contained
+in the pipe_vertex_buffer(s). There's one pipe_vertex_element array member
+for each input attribute.
+
+Members
+-------
+
+src_offset
+ The byte offset of the attribute in the buffer given by
+ vertex_buffer_index for the first vertex.
+instance_divisor
+ The instance data rate divisor, used for instancing.
+ 0 means this is per-vertex data, n means per-instance data used for
+ n consecutive instances (n > 0).
+vertex_buffer_index
+ The vertex buffer this attribute lives in. Several attributes may
+ live in the same vertex buffer.
+src_format
+ The format of the attribute data. One of the PIPE_FORMAT tokens.
diff --git a/src/gallium/drivers/cell/ppu/Makefile b/src/gallium/drivers/cell/ppu/Makefile
index c92f8e5cba2..8769b826b5f 100644
--- a/src/gallium/drivers/cell/ppu/Makefile
+++ b/src/gallium/drivers/cell/ppu/Makefile
@@ -21,6 +21,7 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a
SOURCES = \
cell_batch.c \
+ cell_buffer.c \
cell_clear.c \
cell_context.c \
cell_draw_arrays.c \
diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.c b/src/gallium/drivers/cell/ppu/cell_buffer.c
new file mode 100644
index 00000000000..f56a28d62e2
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "cell_screen.h"
+#include "cell_buffer.h"
+
+
+static void *
+cell_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct cell_buffer *cell_buf = cell_buffer(buf);
+ return cell_buf->data;
+}
+
+
+static void
+cell_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+cell_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct cell_buffer *sbuf = cell_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+cell_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct cell_buffer *buffer = CALLOC_STRUCT(cell_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+cell_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct cell_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(cell_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = cell_buffer_create;
+ screen->user_buffer_create = cell_user_buffer_create;
+ screen->buffer_map = cell_buffer_map;
+ screen->buffer_unmap = cell_buffer_unmap;
+ screen->buffer_destroy = cell_buffer_destroy;
+}
diff --git a/src/gallium/drivers/cell/ppu/cell_buffer.h b/src/gallium/drivers/cell/ppu/cell_buffer.h
new file mode 100644
index 00000000000..ef0a8a70e59
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_buffer.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef SP_BUFFER_H
+#define SP_BUFFER_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+struct cell_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
+
+
+/** Cast wrapper */
+static INLINE struct cell_buffer *
+cell_buffer( struct pipe_buffer *buf )
+{
+ return (struct cell_buffer *)buf;
+}
+
+
+void
+cell_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 5bff9869fd0..f6cb1fc9be7 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -36,7 +36,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_format.h"
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_screen.h"
#include "draw/draw_context.h"
@@ -137,7 +136,7 @@ cell_create_context(struct pipe_screen *screen,
memset(cell, 0, sizeof(*cell));
cell->winsys = NULL; /* XXX: fixme - get this from screen? */
- cell->pipe.winsys = screen->winsys;
+ cell->pipe.winsys = NULL;
cell->pipe.screen = screen;
cell->pipe.priv = priv;
cell->pipe.destroy = cell_destroy_context;
@@ -159,6 +158,7 @@ cell_create_context(struct pipe_screen *screen,
cell_init_shader_functions(cell);
cell_init_surface_functions(cell);
cell_init_vertex_functions(cell);
+ cell_init_texture_transfer_funcs(cell);
cell->draw = cell_draw_create(cell);
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index a77cc5b9067..f7e2284445d 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -34,7 +34,7 @@
#include "pipe/p_defines.h"
#include "draw/draw_vertex.h"
#include "draw/draw_vbuf.h"
-#include "cell_winsys.h"
+/*#include "cell_winsys.h"*/
#include "cell/common.h"
#include "rtasm/rtasm_ppc_spe.h"
#include "tgsi/tgsi_scan.h"
@@ -93,6 +93,11 @@ struct cell_buffer_list
struct cell_buffer_node *head;
};
+struct cell_velems_state
+{
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
/**
* Per-context state, subclass of pipe_context.
@@ -110,6 +115,7 @@ struct cell_context
const struct pipe_rasterizer_state *rasterizer;
const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs;
+ const struct cell_velems_state *velems;
struct spe_function logic_op;
@@ -121,12 +127,11 @@ struct cell_context
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct cell_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
uint num_textures;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- uint num_vertex_elements;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index bffd0fac6fe..15d4e8338f4 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -33,48 +33,18 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_state.h"
#include "cell_flush.h"
+#include "cell_buffer.h"
#include "draw/draw_context.h"
-static void
-cell_map_constant_buffers(struct cell_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- for (i = 0; i < 2; i++) {
- if (sp->constants[i] && sp->constants[i]->size) {
- sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i],
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, sp->mapped_constants[i],
- sp->constants[i]->size);
- }
- }
-
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0,
- sp->mapped_constants[PIPE_SHADER_VERTEX],
- sp->constants[PIPE_SHADER_VERTEX]->size);
-}
-
-static void
-cell_unmap_constant_buffers(struct cell_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- for (i = 0; i < 2; i++) {
- if (sp->constants[i] && sp->constants[i]->size)
- ws->buffer_unmap(ws, sp->constants[i]);
- sp->mapped_constants[i] = NULL;
- }
-}
@@ -93,33 +63,27 @@ cell_draw_range_elements(struct pipe_context *pipe,
unsigned max_index,
unsigned mode, unsigned start, unsigned count)
{
- struct cell_context *sp = cell_context(pipe);
- struct draw_context *draw = sp->draw;
+ struct cell_context *cell = cell_context(pipe);
+ struct draw_context *draw = cell->draw;
unsigned i;
- if (sp->dirty)
- cell_update_derived( sp );
+ if (cell->dirty)
+ cell_update_derived( cell );
#if 0
- cell_map_surfaces(sp);
+ cell_map_surfaces(cell);
#endif
- cell_map_constant_buffers(sp);
/*
* Map vertex buffers
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
+ void *buf = cell_buffer(cell->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = cell_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -134,17 +98,19 @@ cell_draw_range_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < sp->num_vertex_buffers; i++) {
+ for (i = 0; i < cell->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- cell_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c
index e10071529a8..035ef41b898 100644
--- a/src/gallium/drivers/cell/ppu/cell_fence.c
+++ b/src/gallium/drivers/cell/ppu/cell_fence.c
@@ -92,7 +92,6 @@ cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list,
struct pipe_buffer *buffer)
{
- struct pipe_screen *ps = cell->pipe.screen;
struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node);
/* create new list node which references the buffer, insert at head */
if (node) {
@@ -157,8 +156,13 @@ cell_add_fenced_textures(struct cell_context *cell)
printf("Adding texture %p buffer %p to list\n",
ct, ct->tiled_buffer[level]);
#endif
- if (ct->buffer)
+#if 00
+ /* XXX this needs to be fixed/restored!
+ * Maybe keep pointers to textures, not buffers.
+ */
+ if (ct->base.buffer)
cell_add_buffer_to_list(cell, list, ct->buffer);
+#endif
}
}
}
diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
index 3d8b4409c75..059ce8597bc 100644
--- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c
+++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c
@@ -257,8 +257,9 @@ cell_delete_sampler_state(struct pipe_context *pipe,
static void
-cell_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+cell_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct cell_context *cell = cell_context(pipe);
uint i, changed = 0x0;
@@ -266,10 +267,14 @@ cell_set_sampler_textures(struct pipe_context *pipe,
assert(num <= CELL_MAX_SAMPLERS);
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
- struct cell_texture *new_tex = cell_texture(i < num ? texture[i] : NULL);
- struct cell_texture *old_tex = cell->texture[i];
- if (old_tex != new_tex) {
+ struct pipe_sampler_view *new_view = i < num ? views[i] : NULL;
+ struct pipe_sampler_view *old_view = cell->fragment_sampler_views[i];
+ if (old_view != new_view) {
+ struct pipe_texture *new_tex = new_view ? new_view->texture : NULL;
+
+ pipe_sampler_view_reference(&cell->fragment_sampler_views[i],
+ views[i]);
pipe_texture_reference((struct pipe_texture **) &cell->texture[i],
(struct pipe_texture *) new_tex);
@@ -286,23 +291,57 @@ cell_set_sampler_textures(struct pipe_context *pipe,
}
+static struct pipe_sampler_view *
+cell_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+cell_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
/**
* Map color and z/stencil framebuffer surfaces.
*/
static void
cell_map_surfaces(struct cell_context *cell)
{
+#if 0
struct pipe_screen *screen = cell->pipe.screen;
+#endif
uint i;
for (i = 0; i < 1; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->cbuf_map[i] = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->cbuf_map[i] = ct->data;
+#endif
}
}
@@ -310,10 +349,14 @@ cell_map_surfaces(struct cell_context *cell)
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps) {
struct cell_texture *ct = cell_texture(ps->texture);
+#if 0
cell->zsbuf_map = screen->buffer_map(screen,
ct->buffer,
(PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE));
+#else
+ cell->zsbuf_map = ct->data;
+#endif
}
}
}
@@ -325,17 +368,17 @@ cell_map_surfaces(struct cell_context *cell)
static void
cell_unmap_surfaces(struct cell_context *cell)
{
- struct pipe_screen *screen = cell->pipe.screen;
+ /*struct pipe_screen *screen = cell->pipe.screen;*/
uint i;
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
struct pipe_surface *ps = cell->framebuffer.cbufs[i];
if (ps && cell->cbuf_map[i]) {
- struct cell_texture *ct = cell_texture(ps->texture);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
assert(ps->texture);
- assert(ct->buffer);
+ /*assert(ct->buffer);*/
- screen->buffer_unmap(screen, ct->buffer);
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->cbuf_map[i] = NULL;
}
}
@@ -343,8 +386,8 @@ cell_unmap_surfaces(struct cell_context *cell)
{
struct pipe_surface *ps = cell->framebuffer.zsbuf;
if (ps && cell->zsbuf_map) {
- struct cell_texture *ct = cell_texture(ps->texture);
- screen->buffer_unmap(screen, ct->buffer);
+ /*struct cell_texture *ct = cell_texture(ps->texture);*/
+ /*screen->buffer_unmap(screen, ct->buffer);*/
cell->zsbuf_map = NULL;
}
}
@@ -399,7 +442,9 @@ cell_init_state_functions(struct cell_context *cell)
cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states;
cell->pipe.delete_sampler_state = cell_delete_sampler_state;
- cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures;
+ cell->pipe.set_fragment_sampler_views = cell_set_fragment_sampler_views;
+ cell->pipe.create_sampler_view = cell_create_sampler_view;
+ cell->pipe.sampler_view_destroy = cell_sampler_view_destroy;
cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;
cell->pipe.bind_depth_stencil_alpha_state = cell_bind_depth_stencil_alpha_state;
diff --git a/src/gallium/drivers/cell/ppu/cell_public.h b/src/gallium/drivers/cell/ppu/cell_public.h
new file mode 100644
index 00000000000..7e2e093565d
--- /dev/null
+++ b/src/gallium/drivers/cell/ppu/cell_public.h
@@ -0,0 +1,10 @@
+#ifndef CELL_PUBLIC_H
+#define CELL_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+cell_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 7957e0149d7..42045744060 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -28,7 +28,6 @@
#include "util/u_memory.h"
#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -36,7 +35,10 @@
#include "cell_context.h"
#include "cell_screen.h"
#include "cell_texture.h"
-#include "cell_winsys.h"
+#include "cell_buffer.h"
+#include "cell_public.h"
+
+#include "state_tracker/sw_winsys.h"
static const char *
@@ -136,6 +138,13 @@ cell_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
+ if (tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
+ return FALSE;
+ }
+
/* only a few formats are known to work at this time */
switch (format) {
case PIPE_FORMAT_Z24S8_UNORM:
@@ -152,7 +161,8 @@ cell_is_format_supported( struct pipe_screen *screen,
static void
cell_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct cell_screen *sp_screen = cell_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -161,32 +171,34 @@ cell_destroy_screen( struct pipe_screen *screen )
}
+
/**
* Create a new pipe_screen object
* Note: we're not presently subclassing pipe_screen (no cell_screen) but
* that would be the place to put SPU thread/context info...
*/
struct pipe_screen *
-cell_create_screen(struct pipe_winsys *winsys)
+cell_create_screen(struct sw_winsys *winsys)
{
- struct pipe_screen *screen = CALLOC_STRUCT(pipe_screen);
+ struct cell_screen *screen = CALLOC_STRUCT(cell_screen);
if (!screen)
return NULL;
screen->winsys = winsys;
+ screen->base.winsys = NULL;
- screen->destroy = cell_destroy_screen;
+ screen->base.destroy = cell_destroy_screen;
- screen->get_name = cell_get_name;
- screen->get_vendor = cell_get_vendor;
- screen->get_param = cell_get_param;
- screen->get_paramf = cell_get_paramf;
- screen->is_format_supported = cell_is_format_supported;
- screen->context_create = cell_create_context;
+ screen->base.get_name = cell_get_name;
+ screen->base.get_vendor = cell_get_vendor;
+ screen->base.get_param = cell_get_param;
+ screen->base.get_paramf = cell_get_paramf;
+ screen->base.is_format_supported = cell_is_format_supported;
+ screen->base.context_create = cell_create_context;
- cell_init_screen_texture_funcs(screen);
- u_simple_screen_init(screen);
+ cell_init_screen_texture_funcs(&screen->base);
+ cell_init_screen_buffer_funcs(&screen->base);
- return screen;
+ return &screen->base;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.h b/src/gallium/drivers/cell/ppu/cell_screen.h
index c7e15889d66..baff9d3b7d4 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.h
+++ b/src/gallium/drivers/cell/ppu/cell_screen.h
@@ -30,12 +30,26 @@
#define CELL_SCREEN_H
-struct pipe_screen;
-struct pipe_winsys;
+#include "pipe/p_screen.h"
+struct sw_winsys;
-extern struct pipe_screen *
-cell_create_screen(struct pipe_winsys *winsys);
+struct cell_screen {
+ struct pipe_screen base;
+
+ struct sw_winsys *winsys;
+
+ /* Increments whenever textures are modified. Contexts can track
+ * this.
+ */
+ unsigned timestamp;
+};
+
+static INLINE struct cell_screen *
+cell_screen( struct pipe_screen *pipe )
+{
+ return (struct cell_screen *)pipe;
+}
#endif /* CELL_SCREEN_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index a59c7828ac3..424e2628a95 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -245,16 +245,13 @@ cell_emit_state(struct cell_context *cell)
uint i, j;
float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float)));
uint32_t *ibuf = (uint32_t *) buf;
- const float *constants = pipe_buffer_map(cell->pipe.screen,
- cell->constants[shader],
- PIPE_BUFFER_USAGE_CPU_READ);
+ const float *constants = cell->mapped_constants[shader];
ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS;
ibuf[4] = num_const;
j = 8;
for (i = 0; i < num_const; i++) {
buf[j++] = constants[i];
}
- pipe_buffer_unmap(cell->pipe.screen, cell->constants[shader]);
}
if (cell->dirty & (CELL_NEW_FRAMEBUFFER |
diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index 9b2f86fdfba..9e29ddc2d45 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -28,13 +28,13 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_parse.h"
#include "cell_context.h"
#include "cell_state.h"
#include "cell_gen_fp.h"
+#include "cell_buffer.h"
/** cast wrapper */
@@ -183,17 +183,29 @@ cell_delete_vs_state(struct pipe_context *pipe, void *vs)
static void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct cell_context *cell = cell_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? cell_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
+ if (cell->constants[shader] == constants)
+ return;
+
draw_flush(cell->draw);
/* note: reference counting */
- pipe_buffer_reference(&cell->constants[shader], buf);
+ pipe_buffer_reference(&cell->constants[shader], constants);
+
+ if(shader == PIPE_SHADER_VERTEX) {
+ draw_set_mapped_constant_buffer(cell->draw, PIPE_SHADER_VERTEX, 0,
+ data, size);
+ }
+
+ cell->mapped_constants[shader] = data;
if (shader == PIPE_SHADER_VERTEX)
cell->dirty |= CELL_NEW_VS_CONSTANTS;
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index fbe55c84721..9510ea9ac2b 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -32,24 +32,44 @@
#include "cell_context.h"
#include "cell_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
-static void
-cell_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+void *
+cell_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct cell_context *cell = cell_context(pipe);
-
+ struct cell_velems_state *velems;
assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct cell_velems_state *) MALLOC(sizeof(struct cell_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+void
+cell_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct cell_context *cell = cell_context(pipe);
+ struct cell_velems_state *cell_velems = (struct cell_velems_state *) velems;
- memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
- cell->num_vertex_elements = count;
+ cell->velems = cell_velems;
cell->dirty |= CELL_NEW_VERTEX;
- draw_set_vertex_elements(cell->draw, count, elements);
+ if (cell_velems)
+ draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem);
+}
+
+void
+cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
}
@@ -75,5 +95,7 @@ void
cell_init_vertex_functions(struct cell_context *cell)
{
cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
- cell->pipe.set_vertex_elements = cell_set_vertex_elements;
+ cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
+ cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
+ cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index fad290dfa0e..5b169afaf88 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -34,20 +34,23 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
-#include "util/u_simple_screen.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "cell_context.h"
+#include "cell_screen.h"
#include "cell_state.h"
#include "cell_texture.h"
+#include "state_tracker/sw_winsys.h"
-static void
-cell_texture_layout(struct cell_texture *ct)
+
+static boolean
+cell_texture_layout(struct pipe_screen *screen,
+ struct cell_texture *ct)
{
struct pipe_texture *pt = &ct->base;
unsigned level;
@@ -83,9 +86,35 @@ cell_texture_layout(struct cell_texture *ct)
height = u_minify(height, 1);
depth = u_minify(depth, 1);
}
+
+ ct->data = align_malloc(ct->buffer_size, 16);
+
+ return ct->data != NULL;
}
+/**
+ * Texture layout for simple color buffers.
+ */
+static boolean
+cell_displaytarget_layout(struct pipe_screen *screen,
+ struct cell_texture * ct)
+{
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ ct->dt = winsys->displaytarget_create(winsys,
+ ct->base->tex_usage,
+ ct->base.format,
+ ct->base.width0,
+ ct->base.height0,
+ 16,
+ &ct->dt_stride );
+
+ return ct->dt != NULL;
+}
+
static struct pipe_texture *
cell_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
@@ -98,31 +127,46 @@ cell_texture_create(struct pipe_screen *screen,
pipe_reference_init(&ct->base.reference, 1);
ct->base.screen = screen;
- cell_texture_layout(ct);
+ /* Create both a displaytarget (linear) and regular texture
+ * (twiddled). Convert twiddled->linear at flush_frontbuffer time.
+ */
+ if (ct->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if (!cell_displaytarget_layout(screen, ct))
+ goto fail;
+ }
- ct->buffer = screen->buffer_create(screen, 32, PIPE_BUFFER_USAGE_PIXEL,
- ct->buffer_size);
+ if (!cell_texture_layout(screen, ct))
+ goto fail;
- if (!ct->buffer) {
- FREE(ct);
- return NULL;
+ return &ct->base;
+
+fail:
+ if (ct->dt) {
+ struct sw_winsys *winsys = cell_screen(screen)->winsys;
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- return &ct->base;
+ FREE(ct);
+
+ return NULL;
}
static void
cell_texture_destroy(struct pipe_texture *pt)
{
+ struct cell_screen *screen = cell_screen(pt->screen);
+ struct sw_winsys *winsys = screen->winsys;
struct cell_texture *ct = cell_texture(pt);
- if (ct->mapped) {
- pipe_buffer_unmap(ct->buffer->screen, ct->buffer);
- ct->mapped = NULL;
+ if (ct->dt) {
+ /* display target */
+ winsys->displaytarget_destroy(winsys, ct->dt);
}
- pipe_buffer_reference(&ct->buffer, NULL);
+ align_free(ct->data);
FREE(ct);
}
@@ -312,7 +356,7 @@ cell_tex_surface_destroy(struct pipe_surface *surf)
* back out for glGetTexImage).
*/
static struct pipe_transfer *
-cell_get_tex_transfer(struct pipe_screen *screen,
+cell_get_tex_transfer(struct pipe_context *ctx,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -359,7 +403,7 @@ cell_get_tex_transfer(struct pipe_screen *screen,
static void
-cell_tex_transfer_destroy(struct pipe_transfer *t)
+cell_tex_transfer_destroy(struct pipe_context *ctx, struct pipe_transfer *t)
{
struct cell_transfer *transfer = cell_transfer(t);
/* Effectively do the texture_update work here - if texture images
@@ -376,7 +420,7 @@ cell_tex_transfer_destroy(struct pipe_transfer *t)
* Return pointer to texture image data in linear layout.
*/
static void *
-cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
+cell_transfer_map(struct pipe_context *ctx, struct pipe_transfer *transfer)
{
struct cell_transfer *ctrans = cell_transfer(transfer);
struct pipe_texture *pt = transfer->texture;
@@ -389,10 +433,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
assert(transfer->texture);
- if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- pipe_transfer_buffer_flags(transfer));
+ if (ct->mapped == NULL) {
+ ct->mapped = ct->data;
}
/*
@@ -430,7 +472,7 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
* to tiled data.
*/
static void
-cell_transfer_unmap(struct pipe_screen *screen,
+cell_transfer_unmap(struct pipe_context *ctx,
struct pipe_transfer *transfer)
{
struct cell_transfer *ctrans = cell_transfer(transfer);
@@ -442,9 +484,8 @@ cell_transfer_unmap(struct pipe_screen *screen,
const uint stride = ct->stride[level];
if (!ct->mapped) {
- /* map now */
- ct->mapped = pipe_buffer_map(screen, ct->buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ assert(0);
+ return;
}
if (transfer->usage & PIPE_TRANSFER_WRITE) {
@@ -467,6 +508,50 @@ cell_transfer_unmap(struct pipe_screen *screen,
}
+
+/* This used to be overriden by the co-state tracker, but really needs
+ * to be active with sw_winsys.
+ *
+ * Contrasting with llvmpipe and softpipe, this is the only place
+ * where we use the ct->dt display target in any real sense.
+ *
+ * Basically just untwiddle our local data into the linear
+ * displaytarget.
+ */
+static void
+cell_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct cell_screen *screen = cell_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct cell_texture *ct = cell_texture(surface->texture);
+
+ if (!ct->dt)
+ return;
+
+ /* Need to untwiddle from our internal representation here:
+ */
+ {
+ unsigned *map = winsys->displaytarget_map(winsys, ct->dt,
+ (PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE));
+ unsigned *src = (unsigned *)(ct->data + ct->level_offset[surface->level]);
+
+ untwiddle_image_uint(surface->width,
+ surface->height,
+ TILE_SIZE,
+ map,
+ ct->dt_stride,
+ src);
+
+ winsys->displaytarget_unmap(winsys, ct->dt);
+ }
+
+ winsys->displaytarget_display(winsys, ct->dt, context_private);
+}
+
+
void
cell_init_screen_texture_funcs(struct pipe_screen *screen)
{
@@ -476,9 +561,14 @@ cell_init_screen_texture_funcs(struct pipe_screen *screen)
screen->get_tex_surface = cell_get_tex_surface;
screen->tex_surface_destroy = cell_tex_surface_destroy;
- screen->get_tex_transfer = cell_get_tex_transfer;
- screen->tex_transfer_destroy = cell_tex_transfer_destroy;
+ screen->flush_frontbuffer = cell_flush_frontbuffer;
+}
- screen->transfer_map = cell_transfer_map;
- screen->transfer_unmap = cell_transfer_unmap;
+void
+cell_init_texture_transfer_funcs(struct cell_context *cell)
+{
+ cell->pipe.get_tex_transfer = cell_get_tex_transfer;
+ cell->pipe.tex_transfer_destroy = cell_tex_transfer_destroy;
+ cell->pipe.transfer_map = cell_transfer_map;
+ cell->pipe.transfer_unmap = cell_transfer_unmap;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.h b/src/gallium/drivers/cell/ppu/cell_texture.h
index 3ffc0bfdb51..ac0b9167750 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.h
+++ b/src/gallium/drivers/cell/ppu/cell_texture.h
@@ -28,6 +28,7 @@
#ifndef CELL_TEXTURE_H
#define CELL_TEXTURE_H
+#include "cell/common.h"
struct cell_context;
struct pipe_texture;
@@ -43,8 +44,20 @@ struct cell_texture
unsigned long level_offset[CELL_MAX_TEXTURE_LEVELS];
unsigned long stride[CELL_MAX_TEXTURE_LEVELS];
- /** The tiled texture data is held in this buffer */
- struct pipe_buffer *buffer;
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
+ */
+ struct sw_displaytarget *dt;
+ unsigned dt_stride;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
+
+ /* Size of the linear buffer??
+ */
unsigned long buffer_size;
/** The buffer above, mapped. This is the memory from which the
@@ -82,5 +95,7 @@ cell_transfer(struct pipe_transfer *pt)
extern void
cell_init_screen_texture_funcs(struct pipe_screen *screen);
+extern void
+cell_init_texture_transfer_funcs(struct cell_context *cell);
#endif /* CELL_TEXTURE_H */
diff --git a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
index cf8cd411598..3d389d6ea36 100644
--- a/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_vertex_shader.c
@@ -31,7 +31,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_math.h"
#include "cell_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index 2ccc5d3e605..659e40cbf03 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -27,7 +27,6 @@
#include "pipe/p_defines.h"
-#include "util/u_simple_screen.h"
#include "util/u_memory.h"
#include "pipe/p_context.h"
diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h
index bb1a168ea7a..73031321d98 100644
--- a/src/gallium/drivers/failover/fo_context.h
+++ b/src/gallium/drivers/failover/fo_context.h
@@ -47,7 +47,7 @@
#define FO_NEW_ALPHA_TEST 0x100
#define FO_NEW_DEPTH_STENCIL 0x200
#define FO_NEW_SAMPLER 0x400
-#define FO_NEW_TEXTURE 0x800
+#define FO_NEW_SAMPLER_VIEW 0x800
#define FO_NEW_VERTEX 0x2000
#define FO_NEW_VERTEX_SHADER 0x4000
#define FO_NEW_BLEND_COLOR 0x8000
@@ -65,6 +65,13 @@ struct fo_state {
void *sw_state;
void *hw_state;
};
+
+struct fo_sampler_view {
+ struct pipe_sampler_view base;
+ struct pipe_sampler_view *sw;
+ struct pipe_sampler_view *hw;
+};
+
struct failover_context {
struct pipe_context pipe; /**< base class */
@@ -78,6 +85,7 @@ struct failover_context {
const struct fo_state *rasterizer;
const struct fo_state *fragment_shader;
const struct fo_state *vertex_shader;
+ const struct fo_state *vertex_elements;
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
@@ -85,26 +93,25 @@ struct failover_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
uint num_vertex_buffers;
- uint num_vertex_elements;
void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS];
void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];
+ struct fo_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct fo_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ unsigned num_fragment_sampler_views;
+ unsigned num_vertex_sampler_views;
+
unsigned dirty;
unsigned num_samplers;
unsigned num_vertex_samplers;
- unsigned num_textures;
- unsigned num_vertex_textures;
unsigned mode;
struct pipe_context *hw;
diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c
index 970606a3f50..25c62735705 100644
--- a/src/gallium/drivers/failover/fo_state.c
+++ b/src/gallium/drivers/failover/fo_state.c
@@ -255,9 +255,52 @@ failover_delete_vs_state(struct pipe_context *pipe,
free(state);
}
+
+
+static void *
+failover_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *velems )
+{
+ struct fo_state *state = malloc(sizeof(struct fo_state));
+ struct failover_context *failover = failover_context(pipe);
+
+ state->sw_state = failover->sw->create_vertex_elements_state(failover->sw, count, velems);
+ state->hw_state = failover->hw->create_vertex_elements_state(failover->hw, count, velems);
+
+ return state;
+}
+
+static void
+failover_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems )
+{
+ struct failover_context *failover = failover_context(pipe);
+ struct fo_state *state = (struct fo_state*)velems;
+
+ failover->vertex_elements = state;
+ failover->dirty |= FO_NEW_VERTEX_ELEMENT;
+ failover->sw->bind_vertex_elements_state( failover->sw, velems );
+ failover->hw->bind_vertex_elements_state( failover->hw, velems );
+}
+
+static void
+failover_delete_vertex_elements_state( struct pipe_context *pipe,
+ void *velems )
+{
+ struct fo_state *state = (struct fo_state*)velems;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->delete_vertex_elements_state(failover->sw, state->sw_state);
+ failover->hw->delete_vertex_elements_state(failover->hw, state->hw_state);
+ state->sw_state = 0;
+ state->hw_state = 0;
+ free(state);
+}
+
static void
failover_set_polygon_stipple( struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple )
+ const struct pipe_poly_stipple *stipple )
{
struct failover_context *failover = failover_context(pipe);
@@ -404,60 +447,96 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
}
+static struct pipe_sampler_view *
+failover_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct fo_sampler_view *view = malloc(sizeof(struct fo_sampler_view));
+ struct failover_context *failover = failover_context(pipe);
+
+ view->sw = failover->sw->create_sampler_view(failover->sw, texture, templ);
+ view->hw = failover->hw->create_sampler_view(failover->hw, texture, templ);
+
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.texture = NULL;
+ pipe_texture_reference(&view->base.texture, texture);
+ view->base.context = pipe;
+
+ return &view->base;
+}
+
+static void
+failover_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)view;
+ struct failover_context *failover = failover_context(pipe);
+
+ failover->sw->sampler_view_destroy(failover->sw, fo_view->sw);
+ failover->hw->sampler_view_destroy(failover->hw, fo_view->hw);
+
+ pipe_texture_reference(&fo_view->base.texture, NULL);
+ free(fo_view);
+}
+
static void
-failover_set_fragment_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+failover_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct failover_context *failover = failover_context(pipe);
+ struct pipe_sampler_view *hw_views[PIPE_MAX_SAMPLERS];
uint i;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == failover->num_textures &&
- !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == failover->num_fragment_sampler_views &&
+ !memcmp(failover->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
- for (i = 0; i < num; i++)
- pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
- texture[i]);
- for (i = num; i < failover->num_textures; i++)
- pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
- NULL);
- failover->dirty |= FO_NEW_TEXTURE;
- failover->num_textures = num;
- failover->sw->set_fragment_sampler_textures( failover->sw, num, texture );
- failover->hw->set_fragment_sampler_textures( failover->hw, num, texture );
+ for (i = 0; i < num; i++) {
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i];
+
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], views[i]);
+ hw_views[i] = fo_view->hw;
+ }
+ for (i = num; i < failover->num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], NULL);
+ failover->dirty |= FO_NEW_SAMPLER_VIEW;
+ failover->num_fragment_sampler_views = num;
+ failover->hw->set_fragment_sampler_views(failover->hw, num, hw_views);
}
static void
-failover_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+failover_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct failover_context *failover = failover_context(pipe);
+ struct pipe_sampler_view *hw_views[PIPE_MAX_VERTEX_SAMPLERS];
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == failover->num_vertex_textures &&
- !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == failover->num_vertex_sampler_views &&
+ !memcmp(failover->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
- for (i = 0; i < num_textures; i++) {
- pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
- textures[i]);
- }
- for (i = num_textures; i < failover->num_vertex_textures; i++) {
- pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i],
- NULL);
+ for (i = 0; i < num; i++) {
+ struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i];
+
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], views[i]);
+ hw_views[i] = fo_view->hw;
}
- failover->dirty |= FO_NEW_TEXTURE;
- failover->num_vertex_textures = num_textures;
- failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures);
- failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures);
+ for (i = num; i < failover->num_vertex_sampler_views; i++)
+ pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], NULL);
+ failover->dirty |= FO_NEW_SAMPLER_VIEW;
+ failover->num_vertex_sampler_views = num;
+ failover->hw->set_vertex_sampler_views(failover->hw, num, hw_views);
}
@@ -490,22 +569,6 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
}
-static void
-failover_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct failover_context *failover = failover_context(pipe);
-
- memcpy(failover->vertex_elements, vertex_elements,
- count * sizeof(vertex_elements[0]));
-
- failover->dirty |= FO_NEW_VERTEX_ELEMENT;
- failover->num_vertex_elements = count;
- failover->sw->set_vertex_elements( failover->sw, count, vertex_elements );
- failover->hw->set_vertex_elements( failover->hw, count, vertex_elements );
-}
-
void
failover_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
@@ -543,6 +606,9 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.create_vs_state = failover_create_vs_state;
failover->pipe.bind_vs_state = failover_bind_vs_state;
failover->pipe.delete_vs_state = failover_delete_vs_state;
+ failover->pipe.create_vertex_elements_state = failover_create_vertex_elements_state;
+ failover->pipe.bind_vertex_elements_state = failover_bind_vertex_elements_state;
+ failover->pipe.delete_vertex_elements_state = failover_delete_vertex_elements_state;
failover->pipe.set_blend_color = failover_set_blend_color;
failover->pipe.set_stencil_ref = failover_set_stencil_ref;
@@ -550,10 +616,11 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
failover->pipe.set_scissor_state = failover_set_scissor_state;
- failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures;
- failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures;
+ failover->pipe.set_fragment_sampler_views = failover_set_fragment_sampler_views;
+ failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
- failover->pipe.set_vertex_elements = failover_set_vertex_elements;
failover->pipe.set_constant_buffer = failover_set_constant_buffer;
+ failover->pipe.create_sampler_view = failover_create_sampler_view;
+ failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;
}
diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c
index 5c000808425..42bd6929a7f 100644
--- a/src/gallium/drivers/failover/fo_state_emit.c
+++ b/src/gallium/drivers/failover/fo_state_emit.c
@@ -81,6 +81,10 @@ failover_state_emit( struct failover_context *failover )
failover->sw->bind_vs_state( failover->sw,
failover->vertex_shader->sw_state );
+ if (failover->dirty & FO_NEW_VERTEX_ELEMENT)
+ failover->sw->bind_vertex_elements_state( failover->sw,
+ failover->vertex_elements->sw_state );
+
if (failover->dirty & FO_NEW_STIPPLE)
failover->sw->set_polygon_stipple( failover->sw, &failover->poly_stipple );
@@ -102,12 +106,24 @@ failover_state_emit( struct failover_context *failover )
failover->sw_vertex_sampler_state);
}
- if (failover->dirty & FO_NEW_TEXTURE) {
- failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures,
- failover->texture );
- failover->sw->set_vertex_sampler_textures(failover->sw,
- failover->num_vertex_textures,
- failover->vertex_textures);
+ if (failover->dirty & FO_NEW_SAMPLER_VIEW) {
+ struct pipe_sampler_view *fragment_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_views[PIPE_MAX_VERTEX_SAMPLERS];
+ uint i;
+
+ for (i = 0; i < failover->num_fragment_sampler_views; i++) {
+ fragment_views[i] = failover->fragment_sampler_views[i]->sw;
+ }
+ failover->sw->set_fragment_sampler_views(failover->sw,
+ failover->num_fragment_sampler_views,
+ fragment_views);
+
+ for (i = 0; i < failover->num_vertex_sampler_views; i++) {
+ vertex_views[i] = failover->vertex_sampler_views[i]->sw;
+ }
+ failover->sw->set_vertex_sampler_views(failover->sw,
+ failover->num_vertex_sampler_views,
+ vertex_views);
}
if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
@@ -116,11 +132,5 @@ failover_state_emit( struct failover_context *failover )
failover->vertex_buffers );
}
- if (failover->dirty & FO_NEW_VERTEX_ELEMENT) {
- failover->sw->set_vertex_elements( failover->sw,
- failover->num_vertex_elements,
- failover->vertex_elements );
- }
-
failover->dirty = 0;
}
diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h
index b813784723f..f0086695d16 100644
--- a/src/gallium/drivers/i915/i915_batch.h
+++ b/src/gallium/drivers/i915/i915_batch.h
@@ -28,19 +28,19 @@
#ifndef I915_BATCH_H
#define I915_BATCH_H
-#include "intel_batchbuffer.h"
+#include "i915_batchbuffer.h"
#define BEGIN_BATCH(dwords, relocs) \
- (intel_batchbuffer_check(i915->batch, dwords, relocs))
+ (i915_winsys_batchbuffer_check(i915->batch, dwords, relocs))
#define OUT_BATCH(dword) \
- intel_batchbuffer_dword(i915->batch, dword)
+ i915_winsys_batchbuffer_dword(i915->batch, dword)
#define OUT_RELOC(buf, usage, offset) \
- intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
+ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset)
#define FLUSH_BATCH(fence) do { \
- intel_batchbuffer_flush(i915->batch, fence); \
+ i915_winsys_batchbuffer_flush(i915->batch, fence); \
i915->hardware_dirty = ~0; \
} while (0)
diff --git a/src/gallium/drivers/i915/intel_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h
index db12dfd2ac2..27ccaa6b1fa 100644
--- a/src/gallium/drivers/i915/intel_batchbuffer.h
+++ b/src/gallium/drivers/i915/i915_batchbuffer.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,11 +10,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,34 +22,34 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
-#ifndef INTEL_BATCH_H
-#define INTEL_BATCH_H
+#ifndef I915_BATCHBUFFER_H
+#define I915_BATCHBUFFER_H
-#include "intel_winsys.h"
+#include "i915_winsys.h"
static INLINE boolean
-intel_batchbuffer_check(struct intel_batchbuffer *batch,
- size_t dwords,
- size_t relocs)
+i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
+ size_t dwords,
+ size_t relocs)
{
return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
relocs <= (batch->max_relocs - batch->relocs);
}
static INLINE size_t
-intel_batchbuffer_space(struct intel_batchbuffer *batch)
+i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
{
return batch->size - (batch->ptr - batch->map);
}
static INLINE void
-intel_batchbuffer_dword(struct intel_batchbuffer *batch,
- unsigned dword)
+i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch,
+ unsigned dword)
{
- if (intel_batchbuffer_space(batch) < 4)
+ if (i915_winsys_batchbuffer_space(batch) < 4)
return;
*(unsigned *)batch->ptr = dword;
@@ -57,11 +57,11 @@ intel_batchbuffer_dword(struct intel_batchbuffer *batch,
}
static INLINE void
-intel_batchbuffer_write(struct intel_batchbuffer *batch,
- void *data,
- size_t size)
+i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch,
+ void *data,
+ size_t size)
{
- if (intel_batchbuffer_space(batch) < size)
+ if (i915_winsys_batchbuffer_space(batch) < size)
return;
memcpy(data, batch->ptr, size);
@@ -69,17 +69,17 @@ intel_batchbuffer_write(struct intel_batchbuffer *batch,
}
static INLINE int
-intel_batchbuffer_reloc(struct intel_batchbuffer *batch,
- struct intel_buffer *buffer,
- enum intel_buffer_usage usage,
- size_t offset)
+i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
+ size_t offset)
{
return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
}
static INLINE void
-intel_batchbuffer_flush(struct intel_batchbuffer *batch,
- struct pipe_fence_handle **fence)
+i915_winsys_batchbuffer_flush(struct i915_winsys_batchbuffer *batch,
+ struct pipe_fence_handle **fence)
{
batch->iws->batchbuffer_flush(batch, fence);
}
diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c
index 83dfc335288..533fa81219b 100644
--- a/src/gallium/drivers/i915/i915_blit.c
+++ b/src/gallium/drivers/i915/i915_blit.c
@@ -37,7 +37,7 @@ void
i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h,
@@ -77,7 +77,7 @@ i915_fill_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w));
- OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
OUT_BATCH(color);
FLUSH_BATCH(NULL);
}
@@ -87,10 +87,10 @@ i915_copy_blit(struct i915_context *i915,
unsigned do_flip,
unsigned cpp,
unsigned short src_pitch,
- struct intel_buffer *src_buffer,
+ struct i915_winsys_buffer *src_buffer,
unsigned src_offset,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short src_x, short src_y,
short dst_x, short dst_y,
@@ -143,9 +143,9 @@ i915_copy_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2);
- OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
+ OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
OUT_BATCH((src_y << 16) | src_x);
OUT_BATCH(((int) src_pitch & 0xffff));
- OUT_RELOC(src_buffer, INTEL_USAGE_2D_SOURCE, src_offset);
+ OUT_RELOC(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
FLUSH_BATCH(NULL);
}
diff --git a/src/gallium/drivers/i915/i915_blit.h b/src/gallium/drivers/i915/i915_blit.h
index 8ce3220cfd9..db576ed4c90 100644
--- a/src/gallium/drivers/i915/i915_blit.h
+++ b/src/gallium/drivers/i915/i915_blit.h
@@ -34,10 +34,10 @@ extern void i915_copy_blit(struct i915_context *i915,
unsigned do_flip,
unsigned cpp,
unsigned short src_pitch,
- struct intel_buffer *src_buffer,
+ struct i915_winsys_buffer *src_buffer,
unsigned src_offset,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short srcx, short srcy,
short dstx, short dsty,
@@ -46,7 +46,7 @@ extern void i915_copy_blit(struct i915_context *i915,
extern void i915_fill_blit(struct i915_context *i915,
unsigned cpp,
unsigned short dst_pitch,
- struct intel_buffer *dst_buffer,
+ struct i915_winsys_buffer *dst_buffer,
unsigned dst_offset,
short x, short y,
short w, short h, unsigned color);
diff --git a/src/gallium/drivers/i915/i915_buffer.c b/src/gallium/drivers/i915/i915_buffer.c
index 0f76a59e93a..1247de320d4 100644
--- a/src/gallium/drivers/i915/i915_buffer.c
+++ b/src/gallium/drivers/i915/i915_buffer.c
@@ -28,13 +28,13 @@
#include "i915_screen.h"
#include "i915_buffer.h"
-struct intel_buffer;
+struct i915_winsys_buffer;
struct i915_buffer
{
struct pipe_buffer base;
- struct intel_buffer *ibuf; /** hw buffer */
+ struct i915_winsys_buffer *ibuf; /** hw buffer */
void *data; /**< user and malloc data */
boolean own; /**< we own the data incase of malloc */
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 3d45a22b7e7..130519ffa50 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -221,6 +221,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915_init_surface_functions(i915);
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
+ i915_init_texture_functions(i915);
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index da769e7b290..8df4dce8653 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -38,9 +38,9 @@
#include "tgsi/tgsi_scan.h"
-struct intel_winsys;
-struct intel_buffer;
-struct intel_batchbuffer;
+struct i915_winsys;
+struct i915_winsys_buffer;
+struct i915_winsys_batchbuffer;
#define I915_TEX_UNITS 8
@@ -148,7 +148,7 @@ struct i915_state
/** Describes the current hardware vertex layout */
struct vertex_info vertex_info;
-
+
unsigned id; /* track lost context events */
};
@@ -187,6 +187,14 @@ struct i915_sampler_state {
unsigned maxlod;
};
+struct i915_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
+#define I915_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define I915_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct i915_texture {
struct pipe_texture base;
@@ -199,7 +207,7 @@ struct i915_texture {
unsigned sw_tiled; /**< tiled with software flags */
unsigned hw_tiled; /**< tiled with hardware fences */
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS];
/* Explicitly store the offset of each image for each cube face or
* depth value. Pretty much have to accept that hardware formats
@@ -207,18 +215,18 @@ struct i915_texture {
* compute the offsets of depth/cube images within a mipmap level,
* so have to store them as a lookup table:
*/
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
+ unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; /**< array [depth] of offsets */
/* The data is held here:
*/
- struct intel_buffer *buffer;
+ struct i915_winsys_buffer *buffer;
};
struct i915_context
{
struct pipe_context base;
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
struct draw_context *draw;
@@ -239,21 +247,20 @@ struct i915_context
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct i915_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
unsigned dirty;
unsigned num_samplers;
- unsigned num_textures;
- unsigned num_vertex_elements;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_buffers;
- struct intel_batchbuffer *batch;
+ struct i915_winsys_batchbuffer *batch;
/** Vertex buffer */
- struct intel_buffer *vbo;
+ struct i915_winsys_buffer *vbo;
size_t vbo_offset;
unsigned vbo_flushed;
@@ -276,7 +283,7 @@ struct i915_context
#define I915_NEW_ALPHA_TEST 0x100
#define I915_NEW_DEPTH_STENCIL 0x200
#define I915_NEW_SAMPLER 0x400
-#define I915_NEW_TEXTURE 0x800
+#define I915_NEW_SAMPLER_VIEW 0x800
#define I915_NEW_CONSTANTS 0x1000
#define I915_NEW_VBO 0x2000
#define I915_NEW_VS 0x4000
@@ -343,6 +350,12 @@ struct pipe_context *i915_create_context(struct pipe_screen *screen,
/***********************************************************************
+ * i915_texture.c
+ */
+void i915_init_texture_functions(struct i915_context *i915 );
+
+
+/***********************************************************************
* Inline conversion functions. These are better-typed than the
* macros used previously:
*/
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index 237654d26b2..663fac3055c 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -863,7 +863,7 @@ static boolean i915_debug_packet( struct debug_stream *stream )
void
-i915_dump_batchbuffer( struct intel_batchbuffer *batch )
+i915_dump_batchbuffer( struct i915_winsys_batchbuffer *batch )
{
struct debug_stream stream;
unsigned *start = (unsigned*)batch->map;
diff --git a/src/gallium/drivers/i915/i915_debug.h b/src/gallium/drivers/i915/i915_debug.h
index 8f7484797de..67b8d9c2f63 100644
--- a/src/gallium/drivers/i915/i915_debug.h
+++ b/src/gallium/drivers/i915/i915_debug.h
@@ -104,9 +104,9 @@ I915_DBG(
#endif
-struct intel_batchbuffer;
+struct i915_winsys_batchbuffer;
-void i915_dump_batchbuffer( struct intel_batchbuffer *i915 );
+void i915_dump_batchbuffer( struct i915_winsys_batchbuffer *i915 );
void i915_debug_init( struct i915_context *i915 );
diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c
index 066e7392d18..f41c51f2991 100644
--- a/src/gallium/drivers/i915/i915_debug_fp.c
+++ b/src/gallium/drivers/i915/i915_debug_fp.c
@@ -28,7 +28,6 @@
#include "i915_reg.h"
#include "i915_debug.h"
-#include "util/u_simple_screen.h"
#include "util/u_debug.h"
diff --git a/src/gallium/drivers/i915/i915_prim_emit.c b/src/gallium/drivers/i915/i915_prim_emit.c
index d9a5c40ab97..dd997e2cf48 100644
--- a/src/gallium/drivers/i915/i915_prim_emit.c
+++ b/src/gallium/drivers/i915/i915_prim_emit.c
@@ -102,6 +102,13 @@ emit_hw_vertex( struct i915_context *i915,
count += 4;
break;
case EMIT_4UB:
+ OUT_BATCH( pack_ub4(float_to_ubyte( attrib[0] ),
+ float_to_ubyte( attrib[1] ),
+ float_to_ubyte( attrib[2] ),
+ float_to_ubyte( attrib[3] )) );
+ count += 1;
+ break;
+ case EMIT_4UB_BGRA:
OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ),
float_to_ubyte( attrib[1] ),
float_to_ubyte( attrib[0] ),
diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c
index cad4109ee6b..df9e68af4fc 100644
--- a/src/gallium/drivers/i915/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915/i915_prim_vbuf.c
@@ -76,7 +76,7 @@ struct i915_vbuf_render {
unsigned fallback;
/* Stuff for the vbo */
- struct intel_buffer *vbo;
+ struct i915_winsys_buffer *vbo;
size_t vbo_size; /**< current size of allocated buffer */
size_t vbo_alloc_size; /**< minimum buffer size to allocate */
size_t vbo_offset;
@@ -141,7 +141,7 @@ static void
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
{
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
if (i915_render->vbo) {
#ifdef VBUF_USE_FIFO
@@ -172,7 +172,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
if (i915_render->vbo_size != i915_render->pool_buffer_size) {
i915_render->pool_not_used = TRUE;
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
- INTEL_NEW_VERTEX);
+ I915_NEW_VERTEX);
} else {
i915_render->pool_not_used = FALSE;
@@ -185,7 +185,7 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
}
#else
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
- 64, INTEL_NEW_VERTEX);
+ 64, I915_NEW_VERTEX);
#endif
}
@@ -225,7 +225,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
if (i915->vbo_flushed)
debug_printf("%s bad vbo flush occured stalling on hw\n", __FUNCTION__);
@@ -246,7 +246,7 @@ i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
#ifdef VBUF_MAP_BUFFER
@@ -621,7 +621,7 @@ static struct vbuf_render *
i915_vbuf_render_create(struct i915_context *i915)
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
- struct intel_winsys *iws = i915->iws;
+ struct i915_winsys *iws = i915->iws;
int i;
i915_render->i915 = i915;
@@ -662,7 +662,7 @@ i915_vbuf_render_create(struct i915_context *i915)
for (i = 0; i < 6; i++)
u_fifo_add(i915_render->pool_fifo,
iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
- INTEL_NEW_VERTEX));
+ I915_NEW_VERTEX));
#else
(void)i;
(void)iws;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 72bd2635506..53ef6e50f6c 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -35,7 +35,7 @@
#include "i915_screen.h"
#include "i915_buffer.h"
#include "i915_texture.h"
-#include "intel_winsys.h"
+#include "i915_winsys.h"
/*
@@ -116,11 +116,11 @@ i915_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return I915_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return I915_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
@@ -165,8 +165,12 @@ i915_is_format_supported(struct pipe_screen *screen,
unsigned geom_flags)
{
static const enum pipe_format tex_supported[] = {
- PIPE_FORMAT_A8B8G8R8_UNORM,
PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+#if 0
+ PIPE_FORMAT_R8G8B8X8_UNORM,
+#endif
PIPE_FORMAT_B5G6R5_UNORM,
PIPE_FORMAT_L8_UNORM,
PIPE_FORMAT_A8_UNORM,
@@ -256,7 +260,7 @@ i915_destroy_screen(struct pipe_screen *screen)
* Create a new i915_screen object
*/
struct pipe_screen *
-i915_create_screen(struct intel_winsys *iws, uint pci_id)
+i915_create_screen(struct i915_winsys *iws, uint pci_id)
{
struct i915_screen *is = CALLOC_STRUCT(i915_screen);
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index 5126485caa7..7f9e02fc0f6 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -32,7 +32,7 @@
#include "pipe/p_screen.h"
-struct intel_winsys;
+struct i915_winsys;
/**
@@ -42,7 +42,7 @@ struct i915_screen
{
struct pipe_screen base;
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
boolean is_i945;
uint pci_id;
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 62169918e2b..0f7395246cc 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -560,9 +560,9 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
}
-static void i915_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void i915_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct i915_context *i915 = i915_context(pipe);
uint i;
@@ -570,27 +570,54 @@ static void i915_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == i915->num_textures &&
- !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == i915->num_fragment_sampler_views &&
+ !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
/* Fixes wrong texture in texobj with VBUF */
draw_flush(i915->draw);
for (i = 0; i < num; i++)
- pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
- texture[i]);
+ pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
+ views[i]);
- for (i = num; i < i915->num_textures; i++)
- pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
- NULL);
+ for (i = num; i < i915->num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference(&i915->fragment_sampler_views[i],
+ NULL);
- i915->num_textures = num;
+ i915->num_fragment_sampler_views = num;
- i915->dirty |= I915_NEW_TEXTURE;
+ i915->dirty |= I915_NEW_SAMPLER_VIEW;
}
+static struct pipe_sampler_view *
+i915_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+i915_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void i915_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
@@ -742,21 +769,45 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(i915->draw, count, buffers);
}
-static void i915_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+static void *
+i915_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct i915_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
+static void
+i915_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct i915_context *i915 = i915_context(pipe);
+ struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems;
+
/* Because we change state before the draw_set_vertex_buffers call
* we need a flush here, just to be sure.
*/
draw_flush(i915->draw);
- i915->num_vertex_elements = count;
/* pass-through to draw module */
- draw_set_vertex_elements(i915->draw, count, elements);
+ if (i915_velems) {
+ draw_set_vertex_elements(i915->draw,
+ i915_velems->count, i915_velems->velem);
+ }
}
+static void
+i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
i915_init_state_functions( struct i915_context *i915 )
@@ -782,6 +833,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.create_vs_state = i915_create_vs_state;
i915->base.bind_vs_state = i915_bind_vs_state;
i915->base.delete_vs_state = i915_delete_vs_state;
+ i915->base.create_vertex_elements_state = i915_create_vertex_elements_state;
+ i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state;
+ i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state;
i915->base.set_blend_color = i915_set_blend_color;
i915->base.set_stencil_ref = i915_set_stencil_ref;
@@ -791,8 +845,9 @@ i915_init_state_functions( struct i915_context *i915 )
i915->base.set_polygon_stipple = i915_set_polygon_stipple;
i915->base.set_scissor_state = i915_set_scissor_state;
- i915->base.set_fragment_sampler_textures = i915_set_sampler_textures;
+ i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views;
+ i915->base.create_sampler_view = i915_create_sampler_view;
+ i915->base.sampler_view_destroy = i915_sampler_view_destroy;
i915->base.set_viewport_state = i915_set_viewport_state;
i915->base.set_vertex_buffers = i915_set_vertex_buffers;
- i915->base.set_vertex_elements = i915_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index f5b0e9f011e..4da46772b5d 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -101,14 +101,14 @@ static void calculate_vertex_layout( struct i915_context *i915 )
/* primary color */
if (colors[0]) {
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
/* secondary color */
if (colors[1]) {
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
- draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
+ draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
@@ -157,10 +157,10 @@ void i915_update_derived( struct i915_context *i915 )
if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS))
calculate_vertex_layout( i915 );
- if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE))
+ if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW))
i915_update_samplers(i915);
- if (i915->dirty & I915_NEW_TEXTURE)
+ if (i915->dirty & I915_NEW_SAMPLER_VIEW)
i915_update_textures(i915);
if (i915->dirty)
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 51f0ef12baf..04a3924aaf7 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -182,7 +182,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
if(i915->vbo)
OUT_RELOC(i915->vbo,
- INTEL_USAGE_VERTEX,
+ I915_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]);
else
/* FIXME: we should not do this */
@@ -226,7 +226,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
ctile);
OUT_RELOC(tex->buffer,
- INTEL_USAGE_RENDER,
+ I915_USAGE_RENDER,
cbuf_surface->offset);
}
@@ -250,7 +250,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
ztile);
OUT_RELOC(tex->buffer,
- INTEL_USAGE_RENDER,
+ I915_USAGE_RENDER,
depth_surface->offset);
}
@@ -290,13 +290,14 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
- struct intel_buffer *buf = i915->texture[unit]->buffer;
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+ struct i915_winsys_buffer *buf = texture->buffer;
uint offset = 0;
assert(buf);
count++;
- OUT_RELOC(buf, INTEL_USAGE_SAMPLER, offset);
+ OUT_RELOC(buf, I915_USAGE_SAMPLER, offset);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
diff --git a/src/gallium/drivers/i915/i915_state_immediate.c b/src/gallium/drivers/i915/i915_state_immediate.c
index d2c6f151434..8cec699285c 100644
--- a/src/gallium/drivers/i915/i915_state_immediate.c
+++ b/src/gallium/drivers/i915/i915_state_immediate.c
@@ -52,11 +52,11 @@ static void upload_S0S1(struct i915_context *i915)
{
unsigned LIS0, LIS1;
- /* INTEL_NEW_VBO */
+ /* I915_NEW_VBO */
/* TODO: re-use vertex buffers here? */
LIS0 = i915->vbo_offset;
- /* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated!
+ /* I915_NEW_VERTEX_SIZE -- do this where the vertex size is calculated!
*/
{
unsigned vertex_size = i915->current.vertex_info.size;
@@ -65,7 +65,7 @@ static void upload_S0S1(struct i915_context *i915)
(vertex_size << 16));
}
- /* INTEL_NEW_VBO */
+ /* I915_NEW_VBO */
/* TODO: use a vertex generation number to track vbo changes */
if (1 ||
i915->current.immediate[I915_IMMEDIATE_S0] != LIS0 ||
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index 9813290b51b..4c326561cb9 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -144,20 +144,22 @@ void i915_update_samplers( struct i915_context *i915 )
i915->current.sampler_enable_nr = 0;
i915->current.sampler_enable_flags = 0x0;
- for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+ for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
- if (i915->texture[unit]) {
+ if (i915->fragment_sampler_views[unit]) {
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+
update_sampler( i915,
unit,
i915->sampler[unit], /* sampler state */
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->current.sampler[unit] /* the result */
);
i915_update_texture( i915,
unit,
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->sampler[unit], /* sampler state */
i915->current.texbuffer[unit] );
@@ -190,6 +192,14 @@ translate_texture_format(enum pipe_format pipeFormat)
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
case PIPE_FORMAT_B8G8R8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_XRGB8888;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_ABGR8888;
+#if 0
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_XBGR8888;
+#endif
case PIPE_FORMAT_YUYV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case PIPE_FORMAT_UYVY:
@@ -281,14 +291,16 @@ i915_update_textures(struct i915_context *i915)
{
uint unit;
- for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
+ for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
- if (i915->texture[unit]) {
+ if (i915->fragment_sampler_views[unit]) {
+ struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture;
+
i915_update_texture( i915,
unit,
- i915->texture[unit], /* texture */
+ texture, /* texture */
i915->sampler[unit], /* sampler state */
i915->current.texbuffer[unit] );
}
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index 7ba222c78b7..8c405c2443e 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -41,7 +41,7 @@
#include "i915_context.h"
#include "i915_texture.h"
#include "i915_screen.h"
-#include "intel_winsys.h"
+#include "i915_winsys.h"
/*
@@ -96,7 +96,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
unsigned nr_images,
unsigned w, unsigned h, unsigned d)
{
- assert(level < PIPE_MAX_TEXTURE_LEVELS);
+ assert(level < Elements(tex->nr_images));
tex->nr_images[level] = nr_images;
@@ -162,7 +162,7 @@ i915_scanout_layout(struct i915_texture *tex)
if (pt->width0 >= 240) {
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
- tex->hw_tiled = INTEL_TILE_X;
+ tex->hw_tiled = I915_TILE_X;
} else if (pt->width0 == 64 && pt->height0 == 64) {
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
@@ -200,7 +200,7 @@ i915_display_target_layout(struct i915_texture *tex)
tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
- tex->hw_tiled = INTEL_TILE_X;
+ tex->hw_tiled = I915_TILE_X;
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
pt->width0, pt->height0, util_format_get_blocksize(pt->format),
@@ -219,12 +219,12 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
/* used for scanouts that need special layouts */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use something very like scanout */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -369,12 +369,12 @@ i945_miptree_layout_2d(struct i915_texture *tex)
unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
/* used for scanouts that need special layouts */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
if (i915_scanout_layout(tex))
return;
- /* for shared buffers we use some very like scanout */
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ /* shared buffers needs to be compatible with X servers */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED)
if (i915_display_target_layout(tex))
return;
@@ -617,7 +617,7 @@ i915_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct i915_screen *is = i915_screen(screen);
- struct intel_winsys *iws = is->iws;
+ struct i915_winsys *iws = is->iws;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
unsigned buf_usage = 0;
@@ -642,10 +642,10 @@ i915_texture_create(struct pipe_screen *screen,
/* for scanouts and cursors, cursors arn't scanouts */
- if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width0 != 64)
- buf_usage = INTEL_NEW_SCANOUT;
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
+ buf_usage = I915_NEW_SCANOUT;
else
- buf_usage = INTEL_NEW_TEXTURE;
+ buf_usage = I915_NEW_TEXTURE;
tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
if (!tex->buffer)
@@ -653,7 +653,7 @@ i915_texture_create(struct pipe_screen *screen,
/* setup any hw fences */
if (tex->hw_tiled) {
- assert(tex->sw_tiled == INTEL_TILE_NONE);
+ assert(tex->sw_tiled == I915_TILE_NONE);
iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
}
@@ -673,19 +673,24 @@ fail:
}
static struct pipe_texture *
-i915_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+i915_texture_from_handle(struct pipe_screen * screen,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle)
{
-#if 0
+ struct i915_screen *is = i915_screen(screen);
struct i915_texture *tex;
+ struct i915_winsys *iws = is->iws;
+ struct i915_winsys_buffer *buffer;
+ unsigned stride;
+
assert(screen);
+ buffer = iws->buffer_from_handle(iws, whandle, &stride);
+
/* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
+ if (templat->target != PIPE_TEXTURE_2D ||
+ templat->last_level != 0 ||
+ templat->depth0 != 1) {
return NULL;
}
@@ -693,28 +698,38 @@ i915_texture_blanket(struct pipe_screen * screen,
if (!tex)
return NULL;
- tex->base = *base;
+ tex->base = *templat;
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
- tex->stride = stride[0];
+ tex->stride = stride;
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
+ i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
- pipe_buffer_reference(&tex->buffer, buffer);
+ tex->buffer = buffer;
return &tex->base;
-#else
- return NULL;
-#endif
}
+static boolean
+i915_texture_get_handle(struct pipe_screen * screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct i915_screen *is = i915_screen(screen);
+ struct i915_texture *tex = (struct i915_texture *)texture;
+ struct i915_winsys *iws = is->iws;
+
+ return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
+}
+
+
static void
i915_texture_destroy(struct pipe_texture *pt)
{
struct i915_texture *tex = (struct i915_texture *)pt;
- struct intel_winsys *iws = i915_screen(pt->screen)->iws;
+ struct i915_winsys *iws = i915_screen(pt->screen)->iws;
uint i;
/*
@@ -723,7 +738,7 @@ i915_texture_destroy(struct pipe_texture *pt)
iws->buffer_destroy(iws, tex->buffer);
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ for (i = 0; i < Elements(tex->image_offset); i++)
if (tex->image_offset[i])
FREE(tex->image_offset[i]);
@@ -780,12 +795,12 @@ i915_tex_surface_destroy(struct pipe_surface *surf)
/*
- * Screen transfer functions
+ * Texture transfer functions
*/
-static struct pipe_transfer*
-i915_get_tex_transfer(struct pipe_screen *screen,
+static struct pipe_transfer *
+i915_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
@@ -822,11 +837,11 @@ i915_get_tex_transfer(struct pipe_screen *screen,
}
static void *
-i915_transfer_map(struct pipe_screen *screen,
+i915_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ struct i915_winsys *iws = i915_screen(tex->base.screen)->iws;
char *map;
boolean write = FALSE;
enum pipe_format format = tex->base.format;
@@ -844,16 +859,17 @@ i915_transfer_map(struct pipe_screen *screen,
}
static void
-i915_transfer_unmap(struct pipe_screen *screen,
+i915_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ struct i915_winsys *iws = i915_screen(tex->base.screen)->iws;
iws->buffer_unmap(iws, tex->buffer);
}
static void
-i915_tex_transfer_destroy(struct pipe_transfer *trans)
+i915_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *trans)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
@@ -864,67 +880,22 @@ i915_tex_transfer_destroy(struct pipe_transfer *trans)
* Other texture functions
*/
+void
+i915_init_texture_functions(struct i915_context *i915 )
+{
+ i915->base.get_tex_transfer = i915_get_tex_transfer;
+ i915->base.transfer_map = i915_transfer_map;
+ i915->base.transfer_unmap = i915_transfer_unmap;
+ i915->base.tex_transfer_destroy = i915_tex_transfer_destroy;
+}
void
i915_init_screen_texture_functions(struct i915_screen *is)
{
is->base.texture_create = i915_texture_create;
- is->base.texture_blanket = i915_texture_blanket;
+ is->base.texture_from_handle = i915_texture_from_handle;
+ is->base.texture_get_handle = i915_texture_get_handle;
is->base.texture_destroy = i915_texture_destroy;
is->base.get_tex_surface = i915_get_tex_surface;
is->base.tex_surface_destroy = i915_tex_surface_destroy;
- is->base.get_tex_transfer = i915_get_tex_transfer;
- is->base.transfer_map = i915_transfer_map;
- is->base.transfer_unmap = i915_transfer_unmap;
- is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
-}
-
-struct pipe_texture *
-i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *base,
- unsigned stride,
- struct intel_buffer *buffer)
-{
- struct i915_texture *tex;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- tex = CALLOC_STRUCT(i915_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- tex->stride = stride;
-
- i915_miptree_set_level_info(tex, 0, 1, base->width0, base->height0, 1);
- i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
-
- tex->buffer = buffer;
-
- return &tex->base;
-}
-
-boolean
-i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride)
-{
- struct i915_texture *tex = (struct i915_texture *)texture;
-
- if (!texture)
- return FALSE;
-
- *stride = tex->stride;
- *buffer = tex->buffer;
-
- return TRUE;
}
diff --git a/src/gallium/drivers/i915/intel_winsys.h b/src/gallium/drivers/i915/i915_winsys.h
index b3a802b0e29..246e95b00d6 100644
--- a/src/gallium/drivers/i915/intel_winsys.h
+++ b/src/gallium/drivers/i915/i915_winsys.h
@@ -23,45 +23,46 @@
*
**************************************************************************/
-#ifndef INTEL_WINSYS_H
-#define INTEL_WINSYS_H
+#ifndef I915_WINSYS_H
+#define I915_WINSYS_H
#include "pipe/p_compiler.h"
-struct intel_winsys;
-struct intel_buffer;
-struct intel_batchbuffer;
+struct i915_winsys;
+struct i915_winsys_buffer;
+struct i915_winsys_batchbuffer;
struct pipe_texture;
struct pipe_fence_handle;
+struct winsys_handle;
-enum intel_buffer_usage
+enum i915_winsys_buffer_usage
{
/* use on textures */
- INTEL_USAGE_RENDER = 0x01,
- INTEL_USAGE_SAMPLER = 0x02,
- INTEL_USAGE_2D_TARGET = 0x04,
- INTEL_USAGE_2D_SOURCE = 0x08,
+ I915_USAGE_RENDER = 0x01,
+ I915_USAGE_SAMPLER = 0x02,
+ I915_USAGE_2D_TARGET = 0x04,
+ I915_USAGE_2D_SOURCE = 0x08,
/* use on vertex */
- INTEL_USAGE_VERTEX = 0x10
+ I915_USAGE_VERTEX = 0x10
};
-enum intel_buffer_type
+enum i915_winsys_buffer_type
{
- INTEL_NEW_TEXTURE,
- INTEL_NEW_SCANOUT, /**< a texture used for scanning out from */
- INTEL_NEW_VERTEX
+ I915_NEW_TEXTURE,
+ I915_NEW_SCANOUT, /**< a texture used for scanning out from */
+ I915_NEW_VERTEX
};
-enum intel_buffer_tile
+enum i915_winsys_buffer_tile
{
- INTEL_TILE_NONE,
- INTEL_TILE_X,
- INTEL_TILE_Y
+ I915_TILE_NONE,
+ I915_TILE_X,
+ I915_TILE_Y
};
-struct intel_batchbuffer {
+struct i915_winsys_batchbuffer {
- struct intel_winsys *iws;
+ struct i915_winsys *iws;
/**
* Values exported to speed up the writing the batchbuffer,
@@ -78,7 +79,7 @@ struct intel_batchbuffer {
/*@}*/
};
-struct intel_winsys {
+struct i915_winsys {
/**
* Batchbuffer functions.
@@ -87,7 +88,8 @@ struct intel_winsys {
/**
* Create a new batchbuffer.
*/
- struct intel_batchbuffer *(*batchbuffer_create)(struct intel_winsys *iws);
+ struct i915_winsys_batchbuffer *
+ (*batchbuffer_create)(struct i915_winsys *iws);
/**
* Emit a relocation to a buffer.
@@ -99,21 +101,21 @@ struct intel_winsys {
* @offset add this to the reloc buffers address
* @target buffer where to write the address, null for batchbuffer.
*/
- int (*batchbuffer_reloc)(struct intel_batchbuffer *batch,
- struct intel_buffer *reloc,
- enum intel_buffer_usage usage,
+ int (*batchbuffer_reloc)(struct i915_winsys_batchbuffer *batch,
+ struct i915_winsys_buffer *reloc,
+ enum i915_winsys_buffer_usage usage,
unsigned offset);
/**
* Flush a bufferbatch.
*/
- void (*batchbuffer_flush)(struct intel_batchbuffer *batch,
+ void (*batchbuffer_flush)(struct i915_winsys_batchbuffer *batch,
struct pipe_fence_handle **fence);
/**
* Destroy a batchbuffer.
*/
- void (*batchbuffer_destroy)(struct intel_batchbuffer *batch);
+ void (*batchbuffer_destroy)(struct i915_winsys_batchbuffer *batch);
/*@}*/
@@ -124,45 +126,66 @@ struct intel_winsys {
/**
* Create a buffer.
*/
- struct intel_buffer *(*buffer_create)(struct intel_winsys *iws,
- unsigned size, unsigned alignment,
- enum intel_buffer_type type);
+ struct i915_winsys_buffer *
+ (*buffer_create)(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type);
+
+ /**
+ * Creates a buffer from a handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ * Also provides the stride information needed for the
+ * texture via the stride argument.
+ */
+ struct i915_winsys_buffer *
+ (*buffer_from_handle)(struct i915_winsys *iws,
+ struct winsys_handle *whandle,
+ unsigned *stride);
+
+ /**
+ * Used to implement pipe_screen::texture_get_handle.
+ * The winsys might need the stride information.
+ */
+ boolean (*buffer_get_handle)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride);
/**
* Fence a buffer with a fence reg.
* Not to be confused with pipe_fence_handle.
*/
- int (*buffer_set_fence_reg)(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+ int (*buffer_set_fence_reg)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
unsigned stride,
- enum intel_buffer_tile tile);
+ enum i915_winsys_buffer_tile tile);
/**
* Map a buffer.
*/
- void *(*buffer_map)(struct intel_winsys *iws,
- struct intel_buffer *buffer,
+ void *(*buffer_map)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
boolean write);
/**
* Unmap a buffer.
*/
- void (*buffer_unmap)(struct intel_winsys *iws,
- struct intel_buffer *buffer);
+ void (*buffer_unmap)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer);
/**
* Write to a buffer.
*
* Arguments follows pipe_buffer_write.
*/
- int (*buffer_write)(struct intel_winsys *iws,
- struct intel_buffer *dst,
+ int (*buffer_write)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *dst,
size_t offset,
size_t size,
const void *data);
- void (*buffer_destroy)(struct intel_winsys *iws,
- struct intel_buffer *buffer);
+ void (*buffer_destroy)(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer);
/*@}*/
@@ -173,20 +196,20 @@ struct intel_winsys {
/**
* Reference fence and set ptr to fence.
*/
- void (*fence_reference)(struct intel_winsys *iws,
+ void (*fence_reference)(struct i915_winsys *iws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence);
/**
* Check if a fence has finished.
*/
- int (*fence_signalled)(struct intel_winsys *iws,
+ int (*fence_signalled)(struct i915_winsys *iws,
struct pipe_fence_handle *fence);
/**
* Wait on a fence to finish.
*/
- int (*fence_finish)(struct intel_winsys *iws,
+ int (*fence_finish)(struct i915_winsys *iws,
struct pipe_fence_handle *fence);
/*@}*/
@@ -194,33 +217,14 @@ struct intel_winsys {
/**
* Destroy the winsys.
*/
- void (*destroy)(struct intel_winsys *iws);
+ void (*destroy)(struct i915_winsys *iws);
};
/**
* Create i915 pipe_screen.
*/
-struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
-
-
-/**
- * Get the intel_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
- struct intel_buffer **buffer,
- unsigned *stride);
+struct pipe_screen *i915_create_screen(struct i915_winsys *iws, unsigned pci_id);
-/**
- * Wrap a intel_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
- struct pipe_texture *tmplt,
- unsigned pitch,
- struct intel_buffer *buffer);
#endif
diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c
index 3dbe2b91308..4bcdcdd17eb 100644
--- a/src/gallium/drivers/i965/brw_context.c
+++ b/src/gallium/drivers/i965/brw_context.c
@@ -118,6 +118,7 @@ struct pipe_context *brw_create_context(struct pipe_screen *screen,
brw->sws = brw_screen(screen)->sws;
brw->chipset = brw_screen(screen)->chipset;
+ brw_tex_init( brw );
brw_pipe_blend_init( brw );
brw_pipe_depth_stencil_init( brw );
brw_pipe_framebuffer_init( brw );
diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h
index 12cfa7b049c..dab881fea24 100644
--- a/src/gallium/drivers/i965/brw_context.h
+++ b/src/gallium/drivers/i965/brw_context.h
@@ -351,7 +351,7 @@ struct brw_vs_prog_data {
/* Size == 0 if output either not written, or always [0,0,0,1]
*/
-struct brw_vs_ouput_sizes {
+struct brw_vs_output_sizes {
GLubyte output_size[PIPE_MAX_SHADER_OUTPUTS];
};
@@ -546,15 +546,14 @@ struct brw_context
const struct brw_blend_state *blend;
const struct brw_rasterizer_state *rast;
const struct brw_depth_stencil_state *zstencil;
+ const struct brw_vertex_element_packet *velems;
const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];
unsigned num_samplers;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- unsigned num_vertex_elements;
- unsigned num_textures;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_buffers;
struct pipe_scissor_state scissor;
diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c
index 9f136eec71c..0820ba20a08 100644
--- a/src/gallium/drivers/i965/brw_draw_upload.c
+++ b/src/gallium/drivers/i965/brw_draw_upload.c
@@ -42,141 +42,6 @@
-static unsigned brw_translate_surface_format( unsigned id )
-{
- switch (id) {
- case PIPE_FORMAT_R64_FLOAT:
- return BRW_SURFACEFORMAT_R64_FLOAT;
- case PIPE_FORMAT_R64G64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64_FLOAT;
- case PIPE_FORMAT_R64G64B64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
- case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
-
- case PIPE_FORMAT_R32_FLOAT:
- return BRW_SURFACEFORMAT_R32_FLOAT;
- case PIPE_FORMAT_R32G32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32_FLOAT;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
-
- case PIPE_FORMAT_R32_UNORM:
- return BRW_SURFACEFORMAT_R32_UNORM;
- case PIPE_FORMAT_R32G32_UNORM:
- return BRW_SURFACEFORMAT_R32G32_UNORM;
- case PIPE_FORMAT_R32G32B32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32_UNORM;
- case PIPE_FORMAT_R32G32B32A32_UNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
-
- case PIPE_FORMAT_R32_USCALED:
- return BRW_SURFACEFORMAT_R32_USCALED;
- case PIPE_FORMAT_R32G32_USCALED:
- return BRW_SURFACEFORMAT_R32G32_USCALED;
- case PIPE_FORMAT_R32G32B32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32_USCALED;
- case PIPE_FORMAT_R32G32B32A32_USCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
-
- case PIPE_FORMAT_R32_SNORM:
- return BRW_SURFACEFORMAT_R32_SNORM;
- case PIPE_FORMAT_R32G32_SNORM:
- return BRW_SURFACEFORMAT_R32G32_SNORM;
- case PIPE_FORMAT_R32G32B32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32_SNORM;
- case PIPE_FORMAT_R32G32B32A32_SNORM:
- return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
-
- case PIPE_FORMAT_R32_SSCALED:
- return BRW_SURFACEFORMAT_R32_SSCALED;
- case PIPE_FORMAT_R32G32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32_SSCALED;
- case PIPE_FORMAT_R32G32B32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
- case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
-
- case PIPE_FORMAT_R16_UNORM:
- return BRW_SURFACEFORMAT_R16_UNORM;
- case PIPE_FORMAT_R16G16_UNORM:
- return BRW_SURFACEFORMAT_R16G16_UNORM;
- case PIPE_FORMAT_R16G16B16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16_UNORM;
- case PIPE_FORMAT_R16G16B16A16_UNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
-
- case PIPE_FORMAT_R16_USCALED:
- return BRW_SURFACEFORMAT_R16_USCALED;
- case PIPE_FORMAT_R16G16_USCALED:
- return BRW_SURFACEFORMAT_R16G16_USCALED;
- case PIPE_FORMAT_R16G16B16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16_USCALED;
- case PIPE_FORMAT_R16G16B16A16_USCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
-
- case PIPE_FORMAT_R16_SNORM:
- return BRW_SURFACEFORMAT_R16_SNORM;
- case PIPE_FORMAT_R16G16_SNORM:
- return BRW_SURFACEFORMAT_R16G16_SNORM;
- case PIPE_FORMAT_R16G16B16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16_SNORM;
- case PIPE_FORMAT_R16G16B16A16_SNORM:
- return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
-
- case PIPE_FORMAT_R16_SSCALED:
- return BRW_SURFACEFORMAT_R16_SSCALED;
- case PIPE_FORMAT_R16G16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16_SSCALED;
- case PIPE_FORMAT_R16G16B16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
-
- case PIPE_FORMAT_R8_UNORM:
- return BRW_SURFACEFORMAT_R8_UNORM;
- case PIPE_FORMAT_R8G8_UNORM:
- return BRW_SURFACEFORMAT_R8G8_UNORM;
- case PIPE_FORMAT_R8G8B8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8_UNORM;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
-
- case PIPE_FORMAT_R8_USCALED:
- return BRW_SURFACEFORMAT_R8_USCALED;
- case PIPE_FORMAT_R8G8_USCALED:
- return BRW_SURFACEFORMAT_R8G8_USCALED;
- case PIPE_FORMAT_R8G8B8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8_USCALED;
- case PIPE_FORMAT_R8G8B8A8_USCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
-
- case PIPE_FORMAT_R8_SNORM:
- return BRW_SURFACEFORMAT_R8_SNORM;
- case PIPE_FORMAT_R8G8_SNORM:
- return BRW_SURFACEFORMAT_R8G8_SNORM;
- case PIPE_FORMAT_R8G8B8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8_SNORM;
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
-
- case PIPE_FORMAT_R8_SSCALED:
- return BRW_SURFACEFORMAT_R8_SSCALED;
- case PIPE_FORMAT_R8G8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8_SSCALED;
- case PIPE_FORMAT_R8G8B8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
- case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
-
- default:
- assert(0);
- return 0;
- }
-}
-
static unsigned get_index_type(int type)
{
switch (type) {
@@ -315,75 +180,16 @@ static int brw_emit_vertex_buffers( struct brw_context *brw )
-
static int brw_emit_vertex_elements(struct brw_context *brw)
{
- GLuint nr = brw->curr.num_vertex_elements;
- GLuint i;
+ const struct brw_vertex_element_packet *brw_velems = brw->curr.velems;
+ unsigned size = brw_velems->header.length + 2;
+ /* why is this here */
brw_emit_query_begin(brw);
- /* If the VS doesn't read any inputs (calculating vertex position from
- * a state variable for some reason, for example), emit a single pad
- * VERTEX_ELEMENT struct and bail.
- *
- * The stale VB state stays in place, but they don't do anything unless
- * a VE loads from them.
- */
- if (nr == 0) {
- BEGIN_BATCH(3, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
- OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
- (0 << BRW_VE0_SRC_OFFSET_SHIFT));
- OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
- (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
- ADVANCE_BATCH();
- return 0;
- }
-
- /* Now emit vertex element (VEP) state packets.
- *
- */
- BEGIN_BATCH(1 + nr * 2, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr * 2) - 2));
- for (i = 0; i < nr; i++) {
- const struct pipe_vertex_element *input = &brw->curr.vertex_element[i];
- uint32_t format = brw_translate_surface_format( input->src_format );
- uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
- uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
-
- switch (input->nr_components) {
- case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
- case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
- break;
- }
-
- OUT_BATCH((input->vertex_buffer_index << BRW_VE0_INDEX_SHIFT) |
- BRW_VE0_VALID |
- (format << BRW_VE0_FORMAT_SHIFT) |
- (input->src_offset << BRW_VE0_SRC_OFFSET_SHIFT));
+ brw_batchbuffer_data(brw->batch, brw_velems, size * 4, IGNORE_CLIPRECTS);
- if (BRW_IS_IGDNG(brw))
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT));
- else
- OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
- (comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
- (comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
- (comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
- ((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
- }
- ADVANCE_BATCH();
return 0;
}
@@ -396,10 +202,11 @@ static int brw_emit_vertices( struct brw_context *brw )
if (ret)
return ret;
+ /* XXX should separate this? */
ret = brw_emit_vertex_elements( brw );
if (ret)
return ret;
-
+
return 0;
}
@@ -407,7 +214,8 @@ static int brw_emit_vertices( struct brw_context *brw )
const struct brw_tracked_state brw_vertices = {
.dirty = {
.mesa = (PIPE_NEW_INDEX_RANGE |
- PIPE_NEW_VERTEX_BUFFER),
+ PIPE_NEW_VERTEX_BUFFER |
+ PIPE_NEW_VERTEX_ELEMENT),
.brw = BRW_NEW_BATCH,
.cache = 0,
},
diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c
index c7c0e2ae95e..d2aa2bc9f35 100644
--- a/src/gallium/drivers/i965/brw_pipe_sampler.c
+++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
@@ -183,26 +183,26 @@ static void brw_delete_sampler_state(struct pipe_context *pipe,
FREE(cso);
}
-static void brw_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void brw_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct brw_context *brw = brw_context(pipe);
int i;
for (i = 0; i < num; i++)
- pipe_texture_reference(&brw->curr.texture[i], texture[i]);
+ pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], views[i]);
- for (i = num; i < brw->curr.num_textures; i++)
- pipe_texture_reference(&brw->curr.texture[i], NULL);
+ for (i = num; i < brw->curr.num_fragment_sampler_views; i++)
+ pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], NULL);
- brw->curr.num_textures = num;
+ brw->curr.num_fragment_sampler_views = num;
brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;
}
-static void brw_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static void brw_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
}
@@ -212,17 +212,47 @@ static void brw_bind_vertex_sampler_state(struct pipe_context *pipe,
}
+static struct pipe_sampler_view *
+brw_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+brw_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
void brw_pipe_sampler_init( struct brw_context *brw )
{
brw->base.create_sampler_state = brw_create_sampler_state;
brw->base.delete_sampler_state = brw_delete_sampler_state;
- brw->base.set_fragment_sampler_textures = brw_set_sampler_textures;
+ brw->base.set_fragment_sampler_views = brw_set_fragment_sampler_views;
brw->base.bind_fragment_sampler_states = brw_bind_sampler_state;
- brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures;
+ brw->base.set_vertex_sampler_views = brw_set_vertex_sampler_views;
brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state;
+ brw->base.create_sampler_view = brw_create_sampler_view;
+ brw->base.sampler_view_destroy = brw_sampler_view_destroy;
}
void brw_pipe_sampler_cleanup( struct brw_context *brw )
{
diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c
index e3c48e31493..d6a840857ec 100644
--- a/src/gallium/drivers/i965/brw_pipe_vertex.c
+++ b/src/gallium/drivers/i965/brw_pipe_vertex.c
@@ -1,22 +1,251 @@
#include "brw_context.h"
+#include "brw_defines.h"
+#include "brw_structs.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
-static void brw_set_vertex_elements( struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements )
+
+static unsigned brw_translate_surface_format( unsigned id )
+{
+ switch (id) {
+ case PIPE_FORMAT_R64_FLOAT:
+ return BRW_SURFACEFORMAT_R64_FLOAT;
+ case PIPE_FORMAT_R64G64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64_FLOAT;
+ case PIPE_FORMAT_R64G64B64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64_FLOAT;
+ case PIPE_FORMAT_R64G64B64A64_FLOAT:
+ return BRW_SURFACEFORMAT_R64G64B64A64_FLOAT;
+
+ case PIPE_FORMAT_R32_FLOAT:
+ return BRW_SURFACEFORMAT_R32_FLOAT;
+ case PIPE_FORMAT_R32G32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32_FLOAT;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32_FLOAT;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+
+ case PIPE_FORMAT_R32_UNORM:
+ return BRW_SURFACEFORMAT_R32_UNORM;
+ case PIPE_FORMAT_R32G32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32_UNORM;
+ case PIPE_FORMAT_R32G32B32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_UNORM;
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_UNORM;
+
+ case PIPE_FORMAT_R32_USCALED:
+ return BRW_SURFACEFORMAT_R32_USCALED;
+ case PIPE_FORMAT_R32G32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32_USCALED;
+ case PIPE_FORMAT_R32G32B32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_USCALED;
+ case PIPE_FORMAT_R32G32B32A32_USCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_USCALED;
+
+ case PIPE_FORMAT_R32_SNORM:
+ return BRW_SURFACEFORMAT_R32_SNORM;
+ case PIPE_FORMAT_R32G32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32_SNORM;
+ case PIPE_FORMAT_R32G32B32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32_SNORM;
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SNORM;
+
+ case PIPE_FORMAT_R32_SSCALED:
+ return BRW_SURFACEFORMAT_R32_SSCALED;
+ case PIPE_FORMAT_R32G32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32_SSCALED;
+ case PIPE_FORMAT_R32G32B32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32_SSCALED;
+ case PIPE_FORMAT_R32G32B32A32_SSCALED:
+ return BRW_SURFACEFORMAT_R32G32B32A32_SSCALED;
+
+ case PIPE_FORMAT_R16_UNORM:
+ return BRW_SURFACEFORMAT_R16_UNORM;
+ case PIPE_FORMAT_R16G16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16_UNORM;
+ case PIPE_FORMAT_R16G16B16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_UNORM;
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_UNORM;
+
+ case PIPE_FORMAT_R16_USCALED:
+ return BRW_SURFACEFORMAT_R16_USCALED;
+ case PIPE_FORMAT_R16G16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16_USCALED;
+ case PIPE_FORMAT_R16G16B16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_USCALED;
+ case PIPE_FORMAT_R16G16B16A16_USCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_USCALED;
+
+ case PIPE_FORMAT_R16_SNORM:
+ return BRW_SURFACEFORMAT_R16_SNORM;
+ case PIPE_FORMAT_R16G16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16_SNORM;
+ case PIPE_FORMAT_R16G16B16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16_SNORM;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SNORM;
+
+ case PIPE_FORMAT_R16_SSCALED:
+ return BRW_SURFACEFORMAT_R16_SSCALED;
+ case PIPE_FORMAT_R16G16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16_SSCALED;
+ case PIPE_FORMAT_R16G16B16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16_SSCALED;
+ case PIPE_FORMAT_R16G16B16A16_SSCALED:
+ return BRW_SURFACEFORMAT_R16G16B16A16_SSCALED;
+
+ case PIPE_FORMAT_R8_UNORM:
+ return BRW_SURFACEFORMAT_R8_UNORM;
+ case PIPE_FORMAT_R8G8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8_UNORM;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+
+ case PIPE_FORMAT_R8_USCALED:
+ return BRW_SURFACEFORMAT_R8_USCALED;
+ case PIPE_FORMAT_R8G8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8_USCALED;
+ case PIPE_FORMAT_R8G8B8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_USCALED;
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_USCALED;
+
+ case PIPE_FORMAT_R8_SNORM:
+ return BRW_SURFACEFORMAT_R8_SNORM;
+ case PIPE_FORMAT_R8G8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8_SNORM;
+ case PIPE_FORMAT_R8G8B8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8_SNORM;
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SNORM;
+
+ case PIPE_FORMAT_R8_SSCALED:
+ return BRW_SURFACEFORMAT_R8_SSCALED;
+ case PIPE_FORMAT_R8G8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8_SSCALED;
+ case PIPE_FORMAT_R8G8B8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8_SSCALED;
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ return BRW_SURFACEFORMAT_R8G8B8A8_SSCALED;
+
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void brw_translate_vertex_elements(struct brw_context *brw,
+ struct brw_vertex_element_packet *brw_velems,
+ const struct pipe_vertex_element *attribs,
+ unsigned count)
+{
+ unsigned i;
+
+ /* If the VS doesn't read any inputs (calculating vertex position from
+ * a state variable for some reason, for example), emit a single pad
+ * VERTEX_ELEMENT struct and bail.
+ *
+ * The stale VB state stays in place, but they don't do anything unless
+ * a VE loads from them.
+ */
+ brw_velems->header.opcode = CMD_VERTEX_ELEMENT;
+
+ if (count == 0) {
+ brw_velems->header.length = 1;
+ brw_velems->ve[0].ve0.src_offset = 0;
+ brw_velems->ve[0].ve0.src_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
+ brw_velems->ve[0].ve0.valid = 1;
+ brw_velems->ve[0].ve0.vertex_buffer_index = 0;
+ brw_velems->ve[0].ve1.dst_offset = 0;
+ brw_velems->ve[0].ve1.vfcomponent0 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent1 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent2 = BRW_VE1_COMPONENT_STORE_0;
+ brw_velems->ve[0].ve1.vfcomponent3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ return;
+ }
+
+
+ /* Now emit vertex element (VEP) state packets.
+ *
+ */
+ brw_velems->header.length = (1 + count * 2) - 2;
+ for (i = 0; i < count; i++) {
+ const struct pipe_vertex_element *input = &attribs[i];
+ unsigned nr_components = util_format_get_nr_components(input->src_format);
+
+ uint32_t format = brw_translate_surface_format( input->src_format );
+ uint32_t comp0 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp1 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp2 = BRW_VE1_COMPONENT_STORE_SRC;
+ uint32_t comp3 = BRW_VE1_COMPONENT_STORE_SRC;
+
+ switch (nr_components) {
+ case 0: comp0 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 1: comp1 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 2: comp2 = BRW_VE1_COMPONENT_STORE_0; /* fallthrough */
+ case 3: comp3 = BRW_VE1_COMPONENT_STORE_1_FLT;
+ break;
+ }
+
+ brw_velems->ve[i].ve0.src_offset = input->src_offset;
+ brw_velems->ve[i].ve0.src_format = format;
+ brw_velems->ve[i].ve0.valid = 1;
+ brw_velems->ve[i].ve0.vertex_buffer_index = input->vertex_buffer_index;
+ brw_velems->ve[i].ve1.vfcomponent0 = comp0;
+ brw_velems->ve[i].ve1.vfcomponent1 = comp1;
+ brw_velems->ve[i].ve1.vfcomponent2 = comp2;
+ brw_velems->ve[i].ve1.vfcomponent3 = comp3;
+
+ if (BRW_IS_IGDNG(brw))
+ brw_velems->ve[i].ve1.dst_offset = 0;
+ else
+ brw_velems->ve[i].ve1.dst_offset = i * 4;
+ }
+}
+
+static void* brw_create_vertex_elements_state( struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs )
{
+ /* note: for the brw_swtnl.c code (if ever we need draw fallback) we'd also need
+ to store the original data */
struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *velems;
+ assert(count <= BRW_VEP_MAX);
+ velems = (struct brw_vertex_element_packet *) MALLOC(sizeof(struct brw_vertex_element_packet));
+ if (velems) {
+ brw_translate_vertex_elements(brw, velems, attribs, count);
+ }
+ return velems;
+}
- memcpy(brw->curr.vertex_element, elements, count * sizeof(elements[0]));
- brw->curr.num_vertex_elements = count;
+static void brw_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_element_packet *brw_velems = (struct brw_vertex_element_packet *) velems;
+
+ brw->curr.velems = brw_velems;
brw->state.dirty.mesa |= PIPE_NEW_VERTEX_ELEMENT;
}
+static void brw_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
+
static void brw_set_vertex_buffers(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_buffer *buffers)
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
{
struct brw_context *brw = brw_context(pipe);
unsigned i;
@@ -49,7 +278,9 @@ void
brw_pipe_vertex_init( struct brw_context *brw )
{
brw->base.set_vertex_buffers = brw_set_vertex_buffers;
- brw->base.set_vertex_elements = brw_set_vertex_elements;
+ brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
+ brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
+ brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 66f3aad8b21..cef83ffea80 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -174,11 +174,11 @@ brw_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return BRW_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 11; /* max 1024x1024 */
+ return BRW_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
diff --git a/src/gallium/drivers/i965/brw_screen.h b/src/gallium/drivers/i965/brw_screen.h
index 7226d9228b7..e3a7c64d489 100644
--- a/src/gallium/drivers/i965/brw_screen.h
+++ b/src/gallium/drivers/i965/brw_screen.h
@@ -100,6 +100,9 @@ struct brw_surface
};
+#define BRW_MAX_TEXTURE_2D_LEVELS 11 /* max 1024x1024 */
+#define BRW_MAX_TEXTURE_3D_LEVELS 8 /* max 128x128x128 */
+
struct brw_texture
{
@@ -107,9 +110,9 @@ struct brw_texture
struct brw_winsys_buffer *bo;
struct brw_surface_state ss;
- unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
- unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned *image_offset[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned nr_images[BRW_MAX_TEXTURE_2D_LEVELS];
+ unsigned level_offset[BRW_MAX_TEXTURE_2D_LEVELS];
boolean compressed;
unsigned brw_target;
@@ -178,6 +181,10 @@ void brw_update_texture( struct brw_screen *brw_screen,
struct brw_texture *tex );
+/* brw_screen_texture.h
+ */
+struct brw_context;
+void brw_tex_init( struct brw_context *brw );
void brw_screen_tex_init( struct brw_screen *brw_screen );
void brw_screen_tex_surface_init( struct brw_screen *brw_screen );
diff --git a/src/gallium/drivers/i965/brw_screen_texture.c b/src/gallium/drivers/i965/brw_screen_texture.c
index e38fdf1869b..f9f17bdabac 100644
--- a/src/gallium/drivers/i965/brw_screen_texture.c
+++ b/src/gallium/drivers/i965/brw_screen_texture.c
@@ -37,6 +37,8 @@
#include "brw_defines.h"
#include "brw_structs.h"
#include "brw_winsys.h"
+#include "brw_context.h"
+
@@ -204,7 +206,7 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
/* XXX: compressed textures need special treatment here
*/
tex->cpp = util_format_get_blocksize(tex->base.format);
- tex->compressed = util_format_is_compressed(tex->base.format);
+ tex->compressed = util_format_is_s3tc(tex->base.format);
make_empty_list(&tex->views[0]);
make_empty_list(&tex->views[1]);
@@ -231,8 +233,8 @@ static struct pipe_texture *brw_texture_create( struct pipe_screen *screen,
goto fail;
- if (templ->tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ if (templ->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
buffer_type = BRW_BUFFER_TYPE_SCANOUT;
}
else {
@@ -303,14 +305,121 @@ fail:
return NULL;
}
-static struct pipe_texture *brw_texture_blanket(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static struct pipe_texture *
+brw_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex;
+ struct brw_winsys_buffer *buffer;
+ unsigned tiling;
+ unsigned pitch;
+
+ if (templ->target != PIPE_TEXTURE_2D ||
+ templ->last_level != 0 ||
+ templ->depth0 != 1)
+ return NULL;
+
+ if (util_format_is_s3tc(templ->format))
+ return NULL;
+
+ tex = CALLOC_STRUCT(brw_texture);
+ if (!tex)
+ return NULL;
+
+ if (bscreen->sws->bo_from_handle(bscreen->sws, whandle, &pitch, &tiling, &buffer) != PIPE_OK)
+ goto fail;
+
+ memcpy(&tex->base, templ, sizeof *templ);
+ pipe_reference_init(&tex->base.reference, 1);
+ tex->base.screen = screen;
+
+ /* XXX: cpp vs. blocksize
+ */
+ tex->cpp = util_format_get_blocksize(tex->base.format);
+ tex->tiling = tiling;
+
+ make_empty_list(&tex->views[0]);
+ make_empty_list(&tex->views[1]);
+
+ if (!brw_texture_layout(bscreen, tex))
+ goto fail;
+
+ /* XXX Maybe some more checks? */
+ if ((pitch / tex->cpp) < tex->pitch)
+ goto fail;
+
+ tex->pitch = pitch / tex->cpp;
+
+ tex->bo = buffer;
+
+ /* fix this warning */
+#if 0
+ if (tex->size > buffer->size)
+ goto fail;
+#endif
+
+ tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
+ tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
+ tex->ss.ss0.surface_format = translate_tex_format(tex->base.format);
+ assert(tex->ss.ss0.surface_format != BRW_SURFACEFORMAT_INVALID);
+
+ /* This is ok for all textures with channel width 8bit or less:
+ */
+/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
+
+
+ /* XXX: what happens when tex->bo->offset changes???
+ */
+ tex->ss.ss1.base_addr = 0; /* reloc */
+ tex->ss.ss2.mip_count = tex->base.last_level;
+ tex->ss.ss2.width = tex->base.width0 - 1;
+ tex->ss.ss2.height = tex->base.height0 - 1;
+
+ switch (tex->tiling) {
+ case BRW_TILING_NONE:
+ tex->ss.ss3.tiled_surface = 0;
+ tex->ss.ss3.tile_walk = 0;
+ break;
+ case BRW_TILING_X:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
+ break;
+ case BRW_TILING_Y:
+ tex->ss.ss3.tiled_surface = 1;
+ tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
+ break;
+ }
+
+ tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
+ tex->ss.ss3.depth = tex->base.depth0 - 1;
+
+ tex->ss.ss4.min_lod = 0;
+
+ return &tex->base;
+
+fail:
+ FREE(tex);
return NULL;
}
+static boolean
+brw_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct brw_screen *bscreen = brw_screen(screen);
+ struct brw_texture *tex = brw_texture(texture);
+ unsigned stride;
+
+ stride = tex->pitch * tex->cpp;
+
+ return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
+}
+
+
+
static void brw_texture_destroy(struct pipe_texture *pt)
{
struct brw_texture *tex = brw_texture(pt);
@@ -372,7 +481,7 @@ boolean brw_is_texture_referenced_by_bo( struct brw_screen *brw_screen,
*/
static struct pipe_transfer*
-brw_get_tex_transfer(struct pipe_screen *screen,
+brw_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage, unsigned x, unsigned y,
@@ -407,11 +516,11 @@ brw_get_tex_transfer(struct pipe_screen *screen,
}
static void *
-brw_transfer_map(struct pipe_screen *screen,
+brw_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct brw_texture *tex = brw_texture(transfer->texture);
- struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+ struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws;
char *map;
unsigned usage = transfer->usage;
@@ -434,146 +543,37 @@ brw_transfer_map(struct pipe_screen *screen,
}
static void
-brw_transfer_unmap(struct pipe_screen *screen,
+brw_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct brw_texture *tex = brw_texture(transfer->texture);
- struct brw_winsys_screen *sws = brw_screen(screen)->sws;
+ struct brw_winsys_screen *sws = brw_screen(pipe->screen)->sws;
sws->bo_unmap(tex->bo);
}
static void
-brw_tex_transfer_destroy(struct pipe_transfer *trans)
+brw_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *trans)
{
pipe_texture_reference(&trans->texture, NULL);
FREE(trans);
}
-/*
- * Functions exported to the winsys
- */
-
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride)
-{
- struct brw_texture *tex = brw_texture(texture);
-
- *buffer = tex->bo;
- if (stride)
- *stride = tex->pitch * tex->cpp;
-
- return TRUE;
-}
-
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *templ,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer)
+void brw_tex_init( struct brw_context *brw )
{
- struct brw_screen *bscreen = brw_screen(screen);
- struct brw_texture *tex;
- GLuint format;
-
- if (templ->target != PIPE_TEXTURE_2D ||
- templ->last_level != 0 ||
- templ->depth0 != 1)
- return NULL;
-
- if (util_format_is_compressed(templ->format))
- return NULL;
-
- tex = CALLOC_STRUCT(brw_texture);
- if (!tex)
- return NULL;
-
- memcpy(&tex->base, templ, sizeof *templ);
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- /* XXX: cpp vs. blocksize
- */
- tex->cpp = util_format_get_blocksize(tex->base.format);
- tex->tiling = tiling;
-
- make_empty_list(&tex->views[0]);
- make_empty_list(&tex->views[1]);
-
- if (!brw_texture_layout(bscreen, tex))
- goto fail;
-
- /* XXX Maybe some more checks? */
- if ((pitch / tex->cpp) < tex->pitch)
- goto fail;
-
- tex->pitch = pitch / tex->cpp;
-
- tex->bo = buffer;
-
- /* fix this warning */
-#if 0
- if (tex->size > buffer->size)
- goto fail;
-#endif
-
- tex->ss.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
- tex->ss.ss0.surface_type = translate_tex_target(tex->base.target);
-
- format = translate_tex_format(tex->base.format);
- assert(format != BRW_SURFACEFORMAT_INVALID);
- tex->ss.ss0.surface_format = format;
-
- /* This is ok for all textures with channel width 8bit or less:
- */
-/* tex->ss.ss0.data_return_format = BRW_SURFACERETURNFORMAT_S1; */
-
-
- /* XXX: what happens when tex->bo->offset changes???
- */
- tex->ss.ss1.base_addr = 0; /* reloc */
- tex->ss.ss2.mip_count = tex->base.last_level;
- tex->ss.ss2.width = tex->base.width0 - 1;
- tex->ss.ss2.height = tex->base.height0 - 1;
-
- switch (tex->tiling) {
- case BRW_TILING_NONE:
- tex->ss.ss3.tiled_surface = 0;
- tex->ss.ss3.tile_walk = 0;
- break;
- case BRW_TILING_X:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
- break;
- case BRW_TILING_Y:
- tex->ss.ss3.tiled_surface = 1;
- tex->ss.ss3.tile_walk = BRW_TILEWALK_YMAJOR;
- break;
- }
-
- tex->ss.ss3.pitch = (tex->pitch * tex->cpp) - 1;
- tex->ss.ss3.depth = tex->base.depth0 - 1;
-
- tex->ss.ss4.min_lod = 0;
-
- return &tex->base;
-
-fail:
- FREE(tex);
- return NULL;
+ brw->base.get_tex_transfer = brw_get_tex_transfer;
+ brw->base.transfer_map = brw_transfer_map;
+ brw->base.transfer_unmap = brw_transfer_unmap;
+ brw->base.tex_transfer_destroy = brw_tex_transfer_destroy;
}
void brw_screen_tex_init( struct brw_screen *brw_screen )
{
brw_screen->base.is_format_supported = brw_is_format_supported;
brw_screen->base.texture_create = brw_texture_create;
+ brw_screen->base.texture_from_handle = brw_texture_from_handle;
+ brw_screen->base.texture_get_handle = brw_texture_get_handle;
brw_screen->base.texture_destroy = brw_texture_destroy;
- brw_screen->base.texture_blanket = brw_texture_blanket;
- brw_screen->base.get_tex_transfer = brw_get_tex_transfer;
- brw_screen->base.transfer_map = brw_transfer_map;
- brw_screen->base.transfer_unmap = brw_transfer_unmap;
- brw_screen->base.tex_transfer_destroy = brw_tex_transfer_destroy;
}
diff --git a/src/gallium/drivers/i965/brw_structs.h b/src/gallium/drivers/i965/brw_structs.h
index bf10bc04de7..e97ddeb5e1c 100644
--- a/src/gallium/drivers/i965/brw_structs.h
+++ b/src/gallium/drivers/i965/brw_structs.h
@@ -28,7 +28,7 @@
* Authors:
* Keith Whitwell <[email protected]>
*/
-
+
#ifndef BRW_STRUCTS_H
#define BRW_STRUCTS_H
@@ -1149,7 +1149,7 @@ struct brw_vertex_element_state
GLuint valid:1;
GLuint vertex_buffer_index:5;
} ve0;
-
+
struct
{
GLuint dst_offset:8;
diff --git a/src/gallium/drivers/i965/brw_winsys.h b/src/gallium/drivers/i965/brw_winsys.h
index c82d00f4a47..f30c7f18132 100644
--- a/src/gallium/drivers/i965/brw_winsys.h
+++ b/src/gallium/drivers/i965/brw_winsys.h
@@ -162,6 +162,16 @@ struct brw_winsys_screen {
unsigned alignment,
struct brw_winsys_buffer **bo_out);
+ enum pipe_error (*bo_from_handle)(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tiling,
+ struct brw_winsys_buffer **bo_out);
+
+ enum pipe_error (*bo_get_handle)(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride);
+
/* Destroy a buffer when our refcount goes to zero:
*/
void (*bo_destroy)(struct brw_winsys_buffer *buffer);
@@ -257,28 +267,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
-/**
- * Get the brw_winsys buffer backing the texture.
- *
- * TODO UGLY
- */
-struct pipe_texture;
-boolean brw_texture_get_winsys_buffer(struct pipe_texture *texture,
- struct brw_winsys_buffer **buffer,
- unsigned *stride);
-
-/**
- * Wrap a brw_winsys buffer with a texture blanket.
- *
- * TODO UGLY
- */
-struct pipe_texture *
-brw_texture_blanket_winsys_buffer(struct pipe_screen *screen,
- const struct pipe_texture *template,
- unsigned pitch,
- unsigned tiling,
- struct brw_winsys_buffer *buffer);
-
/*************************************************************************
* Cooperative dumping between winsys and driver. TODO: make this
diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c
index dfb718e64fe..7ed2378ec04 100644
--- a/src/gallium/drivers/i965/brw_wm.c
+++ b/src/gallium/drivers/i965/brw_wm.c
@@ -251,8 +251,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* PIPE_NEW_BOUND_TEXTURES */
- for (i = 0; i < brw->curr.num_textures; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
if (tex->base.format == PIPE_FORMAT_UYVY)
key->yuvtex_mask |= 1 << i;
diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c
index 6a6086fc51b..3f18062c584 100644
--- a/src/gallium/drivers/i965/brw_wm_sampler_state.c
+++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c
@@ -78,11 +78,11 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
memset(key, 0, sizeof(*key));
- key->sampler_count = MIN2(brw->curr.num_textures,
+ key->sampler_count = MIN2(brw->curr.num_fragment_sampler_views,
brw->curr.num_samplers);
for (i = 0; i < key->sampler_count; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
const struct brw_sampler *sampler = brw->curr.sampler[i];
struct brw_sampler_state *entry = &key->sampler[i];
@@ -122,12 +122,12 @@ static enum pipe_error
brw_wm_sampler_update_default_colors(struct brw_context *brw)
{
enum pipe_error ret;
- int nr = MIN2(brw->curr.num_textures,
+ int nr = MIN2(brw->curr.num_fragment_sampler_views,
brw->curr.num_samplers);
int i;
for (i = 0; i < nr; i++) {
- const struct brw_texture *tex = brw_texture(brw->curr.texture[i]);
+ const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);
const struct brw_sampler *sampler = brw->curr.sampler[i];
const float *bc;
float bordercolor[4] = {
diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c
index b01a7f194b7..2368ae3f808 100644
--- a/src/gallium/drivers/i965/brw_wm_surface_state.c
+++ b/src/gallium/drivers/i965/brw_wm_surface_state.c
@@ -242,9 +242,9 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
/* PIPE_NEW_TEXTURE
*/
- for (i = 0; i < brw->curr.num_textures; i++) {
+ for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {
ret = brw_update_texture_surface(brw,
- brw_texture(brw->curr.texture[i]),
+ brw_texture(brw->curr.fragment_sampler_views[i]->texture),
&brw->wm.surf_bo[BTI_TEXTURE(i)]);
if (ret)
return ret;
@@ -261,7 +261,7 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )
bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);
/* XXX: no pipe_max_textures define?? */
- for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++)
+ for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++)
bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);
if (brw->wm.nr_surfaces != nr_surfaces) {
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index 8248b2a4132..00a542215ad 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -377,6 +377,42 @@ identity_delete_vs_state(struct pipe_context *_pipe,
vs);
}
+
+static void *
+identity_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *vertex_elements)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ return pipe->create_vertex_elements_state(pipe,
+ num_elements,
+ vertex_elements);
+}
+
+static void
+identity_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->bind_vertex_elements_state(pipe,
+ velems);
+}
+
+static void
+identity_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *velems)
+{
+ struct identity_context *id_pipe = identity_context(_pipe);
+ struct pipe_context *pipe = id_pipe->pipe;
+
+ pipe->delete_vertex_elements_state(pipe,
+ velems);
+}
+
static void
identity_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *blend_color)
@@ -492,53 +528,49 @@ identity_set_viewport_state(struct pipe_context *_pipe,
}
static void
-identity_set_fragment_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **_textures)
+identity_set_fragment_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **_views)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
- struct pipe_texture **textures = NULL;
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view **views = NULL;
unsigned i;
- if (_textures) {
- for (i = 0; i < num_textures; i++)
- unwrapped_textures[i] = identity_texture_unwrap(_textures[i]);
+ if (_views) {
+ for (i = 0; i < num; i++)
+ unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);
for (; i < PIPE_MAX_SAMPLERS; i++)
- unwrapped_textures[i] = NULL;
+ unwrapped_views[i] = NULL;
- textures = unwrapped_textures;
+ views = unwrapped_views;
}
- pipe->set_fragment_sampler_textures(pipe,
- num_textures,
- textures);
+ pipe->set_fragment_sampler_views(pipe, num, views);
}
static void
-identity_set_vertex_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **_textures)
+identity_set_vertex_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **_views)
{
struct identity_context *id_pipe = identity_context(_pipe);
struct pipe_context *pipe = id_pipe->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
- struct pipe_texture **textures = NULL;
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view **views = NULL;
unsigned i;
- if (_textures) {
- for (i = 0; i < num_textures; i++)
- unwrapped_textures[i] = identity_texture_unwrap(_textures[i]);
+ if (_views) {
+ for (i = 0; i < num; i++)
+ unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);
for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
- unwrapped_textures[i] = NULL;
+ unwrapped_views[i] = NULL;
- textures = unwrapped_textures;
+ views = unwrapped_views;
}
- pipe->set_vertex_sampler_textures(pipe,
- num_textures,
- textures);
+ pipe->set_vertex_sampler_views(pipe, num, views);
}
static void
@@ -563,20 +595,6 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
num_buffers,
buffers);
}
-
-static void
-identity_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *vertex_elements)
-{
- struct identity_context *id_pipe = identity_context(_pipe);
- struct pipe_context *pipe = id_pipe->pipe;
-
- pipe->set_vertex_elements(pipe,
- num_elements,
- vertex_elements);
-}
-
static void
identity_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *_dst,
@@ -689,6 +707,115 @@ identity_is_buffer_referenced(struct pipe_context *_pipe,
buffer);
}
+static struct pipe_sampler_view *
+identity_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct identity_context *id_pipe = identity_context(pipe);
+ struct identity_texture *id_texture = identity_texture(texture);
+ struct pipe_context *pipe_unwrapped = id_pipe->pipe;
+ struct pipe_texture *texture_unwrapped = id_texture->texture;
+ struct identity_sampler_view *view = malloc(sizeof(struct identity_sampler_view));
+
+ view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped,
+ texture_unwrapped,
+ templ);
+
+ view->base = *templ;
+ view->base.reference.count = 1;
+ view->base.texture = NULL;
+ pipe_texture_reference(&view->base.texture, texture);
+ view->base.context = pipe;
+
+ return &view->base;
+}
+
+static void
+identity_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ struct identity_context *id_pipe = identity_context(pipe);
+ struct identity_sampler_view *id_view = identity_sampler_view(view);
+ struct pipe_context *pipe_unwrapped = id_pipe->pipe;
+ struct pipe_sampler_view *view_unwrapped = id_view->sampler_view;
+
+ pipe_unwrapped->sampler_view_destroy(pipe_unwrapped,
+ view_unwrapped);
+
+ pipe_texture_reference(&view->texture, NULL);
+ free(view);
+}
+
+
+static struct pipe_transfer *
+identity_context_get_tex_transfer(struct pipe_context *_context,
+ struct pipe_texture *_texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x,
+ unsigned y,
+ unsigned w,
+ unsigned h)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_texture *id_texture = identity_texture(_texture);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_texture *texture = id_texture->texture;
+ struct pipe_transfer *result;
+
+ result = context->get_tex_transfer(context,
+ texture,
+ face,
+ level,
+ zslice,
+ usage,
+ x,
+ y,
+ w,
+ h);
+
+ if (result)
+ return identity_transfer_create(id_context, id_texture, result);
+ return NULL;
+}
+
+static void
+identity_context_tex_transfer_destroy(struct pipe_context *_pipe,
+ struct pipe_transfer *_transfer)
+{
+ identity_transfer_destroy(identity_context(_pipe),
+ identity_transfer(_transfer));
+}
+
+static void *
+identity_context_transfer_map(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_transfer *id_transfer = identity_transfer(_transfer);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_transfer *transfer = id_transfer->transfer;
+
+ return context->transfer_map(context,
+ transfer);
+}
+
+static void
+identity_context_transfer_unmap(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct identity_context *id_context = identity_context(_context);
+ struct identity_transfer *id_transfer = identity_transfer(_transfer);
+ struct pipe_context *context = id_context->pipe;
+ struct pipe_transfer *transfer = id_transfer->transfer;
+
+ context->transfer_unmap(context,
+ transfer);
+}
+
struct pipe_context *
identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
{
@@ -733,6 +860,9 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.create_vs_state = identity_create_vs_state;
id_pipe->base.bind_vs_state = identity_bind_vs_state;
id_pipe->base.delete_vs_state = identity_delete_vs_state;
+ id_pipe->base.create_vertex_elements_state = identity_create_vertex_elements_state;
+ id_pipe->base.bind_vertex_elements_state = identity_bind_vertex_elements_state;
+ id_pipe->base.delete_vertex_elements_state = identity_delete_vertex_elements_state;
id_pipe->base.set_blend_color = identity_set_blend_color;
id_pipe->base.set_stencil_ref = identity_set_stencil_ref;
id_pipe->base.set_clip_state = identity_set_clip_state;
@@ -741,16 +871,21 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;
id_pipe->base.set_scissor_state = identity_set_scissor_state;
id_pipe->base.set_viewport_state = identity_set_viewport_state;
- id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
- id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
+ id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
+ id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
- id_pipe->base.set_vertex_elements = identity_set_vertex_elements;
id_pipe->base.surface_copy = identity_surface_copy;
id_pipe->base.surface_fill = identity_surface_fill;
id_pipe->base.clear = identity_clear;
id_pipe->base.flush = identity_flush;
id_pipe->base.is_texture_referenced = identity_is_texture_referenced;
id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced;
+ id_pipe->base.create_sampler_view = identity_create_sampler_view;
+ id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy;
+ id_pipe->base.get_tex_transfer = identity_context_get_tex_transfer;
+ id_pipe->base.tex_transfer_destroy = identity_context_tex_transfer_destroy;
+ id_pipe->base.transfer_map = identity_context_transfer_map;
+ id_pipe->base.transfer_unmap = identity_context_transfer_unmap;
id_pipe->pipe = pipe;
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index f258c38cd71..26920fed08d 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -31,7 +31,6 @@
#include "id_drm.h"
#include "id_screen.h"
#include "id_public.h"
-#include "id_screen.h"
#include "id_objects.h"
struct identity_drm_api
@@ -63,62 +62,6 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
return identity_screen_create(screen);
}
-
-static struct pipe_texture *
-identity_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct drm_api *api = id_api->api;
- struct pipe_texture *result;
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = identity_texture_create(identity_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-identity_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-
-static boolean
-identity_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
-}
-
static void
identity_drm_destroy(struct drm_api *_api)
{
@@ -145,9 +88,6 @@ identity_drm_create(struct drm_api *api)
id_api->base.name = api->name;
id_api->base.driver_name = api->driver_name;
id_api->base.create_screen = identity_drm_create_screen;
- id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
- id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
- id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
id_api->base.destroy = identity_drm_destroy;
id_api->api = api;
diff --git a/src/gallium/drivers/identity/id_objects.c b/src/gallium/drivers/identity/id_objects.c
index 2b1a60c1bf1..d37fb0042e5 100644
--- a/src/gallium/drivers/identity/id_objects.c
+++ b/src/gallium/drivers/identity/id_objects.c
@@ -30,6 +30,7 @@
#include "id_screen.h"
#include "id_objects.h"
+#include "id_context.h"
struct pipe_buffer *
identity_buffer_create(struct identity_screen *id_screen,
@@ -142,7 +143,8 @@ identity_surface_destroy(struct identity_surface *id_surface)
struct pipe_transfer *
-identity_transfer_create(struct identity_texture *id_texture,
+identity_transfer_create(struct identity_context *id_context,
+ struct identity_texture *id_texture,
struct pipe_transfer *transfer)
{
struct identity_transfer *id_transfer;
@@ -159,25 +161,25 @@ identity_transfer_create(struct identity_texture *id_texture,
memcpy(&id_transfer->base, transfer, sizeof(struct pipe_transfer));
id_transfer->base.texture = NULL;
- pipe_texture_reference(&id_transfer->base.texture, &id_texture->base);
id_transfer->transfer = transfer;
+
+ pipe_texture_reference(&id_transfer->base.texture, &id_texture->base);
assert(id_transfer->base.texture == &id_texture->base);
return &id_transfer->base;
error:
- transfer->texture->screen->tex_transfer_destroy(transfer);
+ id_context->pipe->tex_transfer_destroy(id_context->pipe, transfer);
return NULL;
}
void
-identity_transfer_destroy(struct identity_transfer *id_transfer)
+identity_transfer_destroy(struct identity_context *id_context,
+ struct identity_transfer *id_transfer)
{
- struct identity_screen *id_screen = identity_screen(id_transfer->base.texture->screen);
- struct pipe_screen *screen = id_screen->screen;
-
pipe_texture_reference(&id_transfer->base.texture, NULL);
- screen->tex_transfer_destroy(id_transfer->transfer);
+ id_context->pipe->tex_transfer_destroy(id_context->pipe,
+ id_transfer->transfer);
FREE(id_transfer);
}
diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h
index 77cc7190798..9a07ebe8d72 100644
--- a/src/gallium/drivers/identity/id_objects.h
+++ b/src/gallium/drivers/identity/id_objects.h
@@ -35,6 +35,7 @@
#include "id_screen.h"
+struct identity_context;
struct identity_buffer
{
@@ -52,6 +53,14 @@ struct identity_texture
};
+struct identity_sampler_view
+{
+ struct pipe_sampler_view base;
+
+ struct pipe_sampler_view *sampler_view;
+};
+
+
struct identity_surface
{
struct pipe_surface base;
@@ -64,6 +73,7 @@ struct identity_transfer
{
struct pipe_transfer base;
+ struct pipe_context *pipe;
struct pipe_transfer *transfer;
};
@@ -94,6 +104,15 @@ identity_texture(struct pipe_texture *_texture)
return (struct identity_texture *)_texture;
}
+static INLINE struct identity_sampler_view *
+identity_sampler_view(struct pipe_sampler_view *_sampler_view)
+{
+ if (!_sampler_view) {
+ return NULL;
+ }
+ return (struct identity_sampler_view *)_sampler_view;
+}
+
static INLINE struct identity_surface *
identity_surface(struct pipe_surface *_surface)
{
@@ -138,6 +157,15 @@ identity_texture_unwrap(struct pipe_texture *_texture)
return identity_texture(_texture)->texture;
}
+static INLINE struct pipe_sampler_view *
+identity_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view)
+{
+ if (!_sampler_view) {
+ return NULL;
+ }
+ return identity_sampler_view(_sampler_view)->sampler_view;
+}
+
static INLINE struct pipe_surface *
identity_surface_unwrap(struct pipe_surface *_surface)
{
@@ -177,11 +205,13 @@ void
identity_surface_destroy(struct identity_surface *id_surface);
struct pipe_transfer *
-identity_transfer_create(struct identity_texture *id_texture,
+identity_transfer_create(struct identity_context *id_context,
+ struct identity_texture *id_texture,
struct pipe_transfer *transfer);
void
-identity_transfer_destroy(struct identity_transfer *id_transfer);
+identity_transfer_destroy(struct identity_context *id_context,
+ struct identity_transfer *id_transfer);
struct pipe_video_surface *
identity_video_surface_create(struct identity_screen *id_screen,
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index b85492114a3..419b1465787 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -135,27 +135,40 @@ identity_screen_texture_create(struct pipe_screen *_screen,
}
static struct pipe_texture *
-identity_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *_buffer)
+identity_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_buffer *id_buffer = identity_buffer(_buffer);
struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *buffer = id_buffer->buffer;
struct pipe_texture *result;
- result = screen->texture_blanket(screen,
- templat,
- stride,
- buffer);
+ /* TODO trace call */
- if (result)
- return identity_texture_create(id_screen, result);
- return NULL;
+ result = screen->texture_from_handle(screen, templ, handle);
+
+ result = identity_texture_create(identity_screen(_screen), result);
+
+ return result;
}
+static boolean
+identity_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct identity_screen *id_screen = identity_screen(_screen);
+ struct identity_texture *id_texture = identity_texture(_texture);
+ struct pipe_screen *screen = id_screen->screen;
+ struct pipe_texture *texture = id_texture->texture;
+
+ /* TODO trace call */
+
+ return screen->texture_get_handle(screen, texture, handle);
+}
+
+
+
static void
identity_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -194,71 +207,6 @@ identity_screen_tex_surface_destroy(struct pipe_surface *_surface)
identity_surface_destroy(identity_surface(_surface));
}
-static struct pipe_transfer *
-identity_screen_get_tex_transfer(struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned face,
- unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x,
- unsigned y,
- unsigned w,
- unsigned h)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_texture *id_texture = identity_texture(_texture);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_texture *texture = id_texture->texture;
- struct pipe_transfer *result;
-
- result = screen->get_tex_transfer(screen,
- texture,
- face,
- level,
- zslice,
- usage,
- x,
- y,
- w,
- h);
-
- if (result)
- return identity_transfer_create(id_texture, result);
- return NULL;
-}
-
-static void
-identity_screen_tex_transfer_destroy(struct pipe_transfer *_transfer)
-{
- identity_transfer_destroy(identity_transfer(_transfer));
-}
-
-static void *
-identity_screen_transfer_map(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_transfer *id_transfer = identity_transfer(_transfer);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_transfer *transfer = id_transfer->transfer;
-
- return screen->transfer_map(screen,
- transfer);
-}
-
-static void
-identity_screen_transfer_unmap(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_transfer *id_transfer = identity_transfer(_transfer);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_transfer *transfer = id_transfer->transfer;
-
- screen->transfer_unmap(screen,
- transfer);
-}
static struct pipe_buffer *
identity_screen_buffer_create(struct pipe_screen *_screen,
@@ -298,31 +246,6 @@ identity_screen_user_buffer_create(struct pipe_screen *_screen,
return NULL;
}
-static struct pipe_buffer *
-identity_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- struct identity_screen *id_screen = identity_screen(_screen);
- struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *result;
-
- result = screen->surface_buffer_create(screen,
- width,
- height,
- format,
- usage,
- tex_usage,
- stride);
-
- if (result)
- return identity_buffer_create(id_screen, result);
- return NULL;
-}
static void *
identity_screen_buffer_map(struct pipe_screen *_screen,
@@ -495,17 +418,13 @@ identity_screen_create(struct pipe_screen *screen)
id_screen->base.is_format_supported = identity_screen_is_format_supported;
id_screen->base.context_create = identity_screen_context_create;
id_screen->base.texture_create = identity_screen_texture_create;
- id_screen->base.texture_blanket = identity_screen_texture_blanket;
+ id_screen->base.texture_from_handle = identity_screen_texture_from_handle;
+ id_screen->base.texture_get_handle = identity_screen_texture_get_handle;
id_screen->base.texture_destroy = identity_screen_texture_destroy;
id_screen->base.get_tex_surface = identity_screen_get_tex_surface;
id_screen->base.tex_surface_destroy = identity_screen_tex_surface_destroy;
- id_screen->base.get_tex_transfer = identity_screen_get_tex_transfer;
- id_screen->base.tex_transfer_destroy = identity_screen_tex_transfer_destroy;
- id_screen->base.transfer_map = identity_screen_transfer_map;
- id_screen->base.transfer_unmap = identity_screen_transfer_unmap;
id_screen->base.buffer_create = identity_screen_buffer_create;
id_screen->base.user_buffer_create = identity_screen_user_buffer_create;
- id_screen->base.surface_buffer_create = identity_screen_surface_buffer_create;
if (screen->buffer_map)
id_screen->base.buffer_map = identity_screen_buffer_map;
if (screen->buffer_map_range)
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 41ac1cee72d..b37c6754c08 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -42,6 +42,11 @@ C_SOURCES = \
CPP_SOURCES = \
+PROGS := lp_test_format \
+ lp_test_blend \
+ lp_test_conv \
+ lp_test_printf
+
include ../../Makefile.template
@@ -49,13 +54,7 @@ lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxil
python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@
-testprogs := lp_test_format \
- lp_test_blend \
- lp_test_conv
-
-LIBS += $(GL_LIB_DEPS) -L. -lllvmpipe -L../../auxiliary/ -lgallium
+LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium
-$(testprogs): lp_test_% : lp_test_%.o lp_test_main.o libllvmpipe.a
- $(LD) $(filter %.o,$^) -o $@ -Wl,--start-group $(LIBS) -Wl,--end-group
+$(PROGS): lp_test_main.o
-default: $(testprogs)
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index bf4c9a5727c..3c3fd386b52 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -12,7 +12,11 @@ Done so far is:
- depth testing
- - texture sampling (not all state/formats are supported)
+ - texture sampling
+ - 1D/2D/3D/cube maps supported
+ - all texture wrap modes supported
+ - all texture filtering modes supported
+ - perhaps not all texture formats yet supported
- fragment shader TGSI translation
- same level of support as the TGSI SSE2 exec machine, with the exception
@@ -37,8 +41,6 @@ To do (probably by this order):
- code generate stipple and stencil testing
- - translate the remaining bits of texture sampling state
-
- translate TGSI control flow instructions, and all other remaining opcodes
- integrate with the draw module for VS code generation
@@ -57,7 +59,7 @@ Requirements
See /proc/cpuinfo to know what your CPU supports.
- - LLVM 2.6.
+ - LLVM 2.6 (or later)
For Linux, on a recent Debian based distribution do:
@@ -67,6 +69,9 @@ Requirements
http://people.freedesktop.org/~jrfonseca/llvm/ and set the LLVM environment
variable to the extracted path.
+ The version of LLVM from SVN ("2.7svn") from mid-March 2010 seems pretty
+ stable and has some features not in version 2.6.
+
- scons (optional)
- udis86, http://udis86.sourceforge.net/ (optional):
@@ -140,11 +145,13 @@ Development Notes
then skim through the lp_bld_* functions called in there, and the comments
at the top of the lp_bld_*.c functions.
-- All lp_bld_*.[ch] are isolated from the rest of the driver, and could/may be
- put in a stand-alone Gallium state -> LLVM IR translation module.
+- The driver-independent parts of the LLVM / Gallium code are found in
+ src/gallium/auxiliary/gallivm/. The filenames and function prefixes
+ need to be renamed from "lp_bld_" to something else though.
- We use LLVM-C bindings for now. They are not documented, but follow the C++
interfaces very closely, and appear to be complete enough for code
generation. See
http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
for a stand-alone example.
+ See the llvm-c/Core.h file for reference.
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c
index 9eda9720818..6e0f37393e9 100644
--- a/src/gallium/drivers/llvmpipe/lp_buffer.c
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.c
@@ -30,7 +30,6 @@
#include "util/u_memory.h"
#include "util/u_math.h"
-#include "lp_winsys.h"
#include "lp_screen.h"
#include "lp_buffer.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index e31ae6a3fc1..951a695f964 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -68,11 +68,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- pipe_texture_reference(&llvmpipe->texture[i], NULL);
+ pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL);
+ pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], NULL);
}
for (i = 0; i < Elements(llvmpipe->constants); i++) {
@@ -145,6 +145,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
+ llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
+ llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
+ llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
+
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
@@ -152,12 +156,13 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
- llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures;
- llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures;
+ llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
+ llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
+ llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
+ llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
- llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
@@ -170,6 +175,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced;
llvmpipe_init_query_funcs( llvmpipe );
+ llvmpipe_init_context_texture_funcs( &llvmpipe->pipe );
/*
* Create drawing context and plug our rendering stage into it.
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 955c7eb8e0e..71f991049e5 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -45,7 +45,8 @@ struct draw_stage;
struct lp_fragment_shader;
struct lp_vertex_shader;
struct lp_blend_state;
-struct setup_context;
+struct lp_setup_context;
+struct lp_velems_state;
struct llvmpipe_context {
struct pipe_context pipe; /**< base class */
@@ -58,6 +59,7 @@ struct llvmpipe_context {
const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs;
const struct lp_vertex_shader *vs;
+ const struct lp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -67,17 +69,15 @@ struct llvmpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_fragment_sampler_views;
unsigned num_vertex_samplers;
- unsigned num_vertex_textures;
- unsigned num_vertex_elements;
+ unsigned num_vertex_sampler_views;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of LP_NEW_x flags */
@@ -98,7 +98,7 @@ struct llvmpipe_context {
int psize_slot;
/** The tiling engine */
- struct setup_context *setup;
+ struct lp_setup_context *setup;
/** The primitive drawing context */
struct draw_context *draw;
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c
index 525c117f316..00dc3eab6b1 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.c
+++ b/src/gallium/drivers/llvmpipe/lp_fence.c
@@ -29,6 +29,7 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "lp_debug.h"
#include "lp_fence.h"
@@ -99,6 +100,21 @@ llvmpipe_fence_finish(struct pipe_screen *screen,
}
+void
+lp_fence_signal(struct lp_fence *fence)
+{
+ pipe_mutex_lock(fence->mutex);
+
+ fence->count++;
+ assert(fence->count <= fence->rank);
+
+ LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__,
+ fence->count, fence->rank);
+
+ pipe_condvar_signal(fence->signalled);
+
+ pipe_mutex_unlock(fence->mutex);
+}
void
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.h b/src/gallium/drivers/llvmpipe/lp_fence.h
index c90e6de423b..d9270f5784a 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.h
+++ b/src/gallium/drivers/llvmpipe/lp_fence.h
@@ -54,6 +54,10 @@ lp_fence_create(unsigned rank);
void
+lp_fence_signal(struct lp_fence *fence);
+
+
+void
llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index bf832433be1..782669a1e77 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -79,12 +79,12 @@ llvmpipe_flush( struct pipe_context *pipe,
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no);
- debug_dump_surface(filename, llvmpipe->framebuffer.cbufs[i]);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[0]);
}
if (0) {
util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no);
- debug_dump_surface(filename, llvmpipe->framebuffer.zsbuf);
+ debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf);
}
++frame_no;
@@ -92,3 +92,67 @@ llvmpipe_flush( struct pipe_context *pipe,
#endif
}
+
+/**
+ * Flush context if necessary.
+ *
+ * TODO: move this logic to an auxiliary library?
+ *
+ * FIXME: We must implement DISCARD/DONTBLOCK/UNSYNCHRONIZED/etc for
+ * textures to avoid blocking.
+ */
+boolean
+llvmpipe_flush_texture(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_flush)
+{
+ unsigned referenced;
+
+ referenced = pipe->is_texture_referenced(pipe, texture, face, level);
+
+ if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
+ ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
+
+ if (do_not_flush)
+ return FALSE;
+
+ /*
+ * 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 (cpu_access) {
+ /*
+ * Flush and wait.
+ */
+
+ struct pipe_fence_handle *fence = NULL;
+
+ pipe->flush(pipe, flush_flags, &fence);
+
+ if (fence) {
+ pipe->screen->fence_finish(pipe->screen, fence, 0);
+ pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+ }
+ } else {
+ /*
+ * Just flush.
+ */
+
+ pipe->flush(pipe, flush_flags, NULL);
+ }
+ }
+
+ return TRUE;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
index 10b2b525836..e13f57ccec5 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.h
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -28,10 +28,22 @@
#ifndef LP_FLUSH_H
#define LP_FLUSH_H
+#include "pipe/p_compiler.h"
+
struct pipe_context;
struct pipe_fence_handle;
void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence);
+boolean
+llvmpipe_flush_texture(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned flush_flags,
+ boolean read_only,
+ boolean cpu_access,
+ boolean do_not_flush);
+
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index bacff500d63..927e472ff26 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -57,8 +57,11 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
+ LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_2D_LEVELS);
+ elem_types[LP_JIT_TEXTURE_DATA] =
+ LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+ LP_MAX_TEXTURE_2D_LEVELS);
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
@@ -74,9 +77,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
screen->target, texture_type,
LP_JIT_TEXTURE_LAST_LEVEL);
- LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
screen->target, texture_type,
- LP_JIT_TEXTURE_STRIDE);
+ LP_JIT_TEXTURE_ROW_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
screen->target, texture_type,
LP_JIT_TEXTURE_DATA);
@@ -88,36 +91,53 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
/* struct lp_jit_context */
{
- LLVMTypeRef elem_types[8];
+ LLVMTypeRef elem_types[LP_JIT_CTX_COUNT];
LLVMTypeRef context_type;
- elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
- elem_types[1] = LLVMFloatType(); /* alpha_ref_value */ elem_types[2] = LLVMFloatType(); /* scissor_xmin */
- elem_types[3] = LLVMFloatType(); /* scissor_ymin */
- elem_types[4] = LLVMFloatType(); /* scissor_xmax */
- elem_types[5] = LLVMFloatType(); /* scissor_ymax */
- elem_types[6] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
- elem_types[7] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
+ elem_types[LP_JIT_CTX_CONSTANTS] = LLVMPointerType(LLVMFloatType(), 0);
+ elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = LLVMInt32Type();
+ elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32Type();
+ elem_types[LP_JIT_CTX_SCISSOR_XMIN] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_YMIN] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_XMAX] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_SCISSOR_YMAX] = LLVMFloatType();
+ elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
+ PIPE_MAX_SAMPLERS);
context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
- screen->target, context_type, 0);
+ screen->target, context_type,
+ LP_JIT_CTX_CONSTANTS);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
- screen->target, context_type, 1);
+ screen->target, context_type,
+ LP_JIT_CTX_ALPHA_REF);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front,
+ screen->target, context_type,
+ LP_JIT_CTX_STENCIL_REF_FRONT);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
+ screen->target, context_type,
+ LP_JIT_CTX_STENCIL_REF_BACK);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin,
- screen->target, context_type, 2);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_XMIN);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin,
- screen->target, context_type, 3);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_YMIN);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax,
- screen->target, context_type, 4);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_XMAX);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax,
- screen->target, context_type, 5);
+ screen->target, context_type,
+ LP_JIT_CTX_SCISSOR_YMAX);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
- screen->target, context_type, 6);
+ screen->target, context_type,
+ LP_JIT_CTX_BLEND_COLOR);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
screen->target, context_type,
- LP_JIT_CONTEXT_TEXTURES_INDEX);
+ LP_JIT_CTX_TEXTURES);
LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
screen->target, context_type);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 0ebb2826fa2..4930ff02e6b 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -39,6 +39,7 @@
#include "gallivm/lp_bld_struct.h"
#include "pipe/p_state.h"
+#include "lp_texture.h"
struct llvmpipe_screen;
@@ -50,8 +51,8 @@ struct lp_jit_texture
uint32_t height;
uint32_t depth;
uint32_t last_level;
- uint32_t stride;
- const void *data;
+ uint32_t row_stride[LP_MAX_TEXTURE_2D_LEVELS];
+ const void *data[LP_MAX_TEXTURE_2D_LEVELS];
};
@@ -60,7 +61,7 @@ enum {
LP_JIT_TEXTURE_HEIGHT,
LP_JIT_TEXTURE_DEPTH,
LP_JIT_TEXTURE_LAST_LEVEL,
- LP_JIT_TEXTURE_STRIDE,
+ LP_JIT_TEXTURE_ROW_STRIDE,
LP_JIT_TEXTURE_DATA
};
@@ -83,6 +84,8 @@ struct lp_jit_context
float alpha_ref_value;
+ uint32_t stencil_ref_front, stencil_ref_back;
+
/** floats, not ints */
float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax;
@@ -93,37 +96,66 @@ struct lp_jit_context
};
+/**
+ * These enum values must match the position of the fields in the
+ * lp_jit_context struct above.
+ */
+enum {
+ LP_JIT_CTX_CONSTANTS = 0,
+ LP_JIT_CTX_ALPHA_REF,
+ LP_JIT_CTX_STENCIL_REF_FRONT,
+ LP_JIT_CTX_STENCIL_REF_BACK,
+ LP_JIT_CTX_SCISSOR_XMIN,
+ LP_JIT_CTX_SCISSOR_YMIN,
+ LP_JIT_CTX_SCISSOR_XMAX,
+ LP_JIT_CTX_SCISSOR_YMAX,
+ LP_JIT_CTX_BLEND_COLOR,
+ LP_JIT_CTX_TEXTURES,
+ LP_JIT_CTX_COUNT
+};
+
+
#define lp_jit_context_constants(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 0, "constants")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_CONSTANTS, "constants")
#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 1, "alpha_ref_value")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_ALPHA_REF, "alpha_ref_value")
+
+#define lp_jit_context_stencil_ref_front_value(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_FRONT, "stencil_ref_front")
+
+#define lp_jit_context_stencil_ref_back_value(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back")
#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 2, "scissor_xmin")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMIN, "scissor_xmin")
#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 3, "scissor_ymin")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMIN, "scissor_ymin")
#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 4, "scissor_xmax")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMAX, "scissor_xmax")
#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 5, "scissor_ymax")
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMAX, "scissor_ymax")
#define lp_jit_context_blend_color(_builder, _ptr) \
- lp_build_struct_get(_builder, _ptr, 6, "blend_color")
-
-#define LP_JIT_CONTEXT_TEXTURES_INDEX 7
+ lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color")
#define lp_jit_context_textures(_builder, _ptr) \
- lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
+ lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES, "textures")
+
+
+/** Indexes into jit_function[] array */
+#define RAST_WHOLE 0
+#define RAST_EDGE_TEST 1
typedef void
(*lp_jit_frag_func)(const struct lp_jit_context *context,
uint32_t x,
uint32_t y,
+ float facing,
const void *a0,
const void *dadx,
const void *dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_public.h b/src/gallium/drivers/llvmpipe/lp_public.h
new file mode 100644
index 00000000000..ec6b660b48e
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_public.h
@@ -0,0 +1,10 @@
+#ifndef LP_PUBLIC_H
+#define LP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+llvmpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index dd9a8e8856f..8352f175598 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -62,18 +62,20 @@ lp_rast_begin( struct lp_rasterizer *rast,
rast->state.write_color = write_color;
for (i = 0; i < rast->state.nr_cbufs; i++) {
+ struct pipe_surface *cbuf = scene->fb.cbufs[i];
rast->cbuf[i].map = scene->cbuf_map[i];
- rast->cbuf[i].format = scene->cbuf_transfer[i]->texture->format;
- rast->cbuf[i].width = scene->cbuf_transfer[i]->width;
- rast->cbuf[i].height = scene->cbuf_transfer[i]->height;
- rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride;
+ rast->cbuf[i].format = cbuf->texture->format;
+ rast->cbuf[i].width = cbuf->width;
+ rast->cbuf[i].height = cbuf->height;
+ rast->cbuf[i].stride = llvmpipe_texture_stride(cbuf->texture, cbuf->level);
}
if (write_zstencil) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
rast->zsbuf.map = scene->zsbuf_map;
- rast->zsbuf.stride = scene->zsbuf_transfer->stride;
+ rast->zsbuf.stride = llvmpipe_texture_stride(zsbuf->texture, zsbuf->level);
rast->zsbuf.blocksize =
- util_format_get_blocksize(scene->zsbuf_transfer->texture->format);
+ util_format_get_blocksize(zsbuf->texture->format);
}
lp_scene_bin_iter_begin( scene );
@@ -187,7 +189,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
- assert(rast->zsbuf.map);
+ /*assert(rast->zsbuf.map);*/
if (!rast->zsbuf.map)
return;
@@ -310,15 +312,16 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
depth = lp_rast_depth_pointer(rast, tile_x + x, tile_y + y);
/* run shader */
- state->jit_function[0]( &state->jit_context,
- tile_x + x, tile_y + y,
- inputs->a0,
- inputs->dadx,
- inputs->dady,
- color,
- depth,
- INT_MIN, INT_MIN, INT_MIN,
- NULL, NULL, NULL );
+ state->jit_function[RAST_WHOLE]( &state->jit_context,
+ tile_x + x, tile_y + y,
+ inputs->facing,
+ inputs->a0,
+ inputs->dadx,
+ inputs->dady,
+ color,
+ depth,
+ INT_MIN, INT_MIN, INT_MIN,
+ NULL, NULL, NULL );
}
}
}
@@ -373,15 +376,18 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
assert(lp_check_alignment(inputs->step[2], 16));
/* run shader */
- state->jit_function[1]( &state->jit_context,
- x, y,
- inputs->a0,
- inputs->dadx,
- inputs->dady,
- color,
- depth,
- c1, c2, c3,
- inputs->step[0], inputs->step[1], inputs->step[2]);
+ state->jit_function[RAST_EDGE_TEST]( &state->jit_context,
+ x, y,
+ inputs->facing,
+ inputs->a0,
+ inputs->dadx,
+ inputs->dady,
+ color,
+ depth,
+ c1, c2, c3,
+ inputs->step[0],
+ inputs->step[1],
+ inputs->step[2]);
}
@@ -485,18 +491,7 @@ lp_rast_fence(struct lp_rasterizer_task *task,
const union lp_rast_cmd_arg arg)
{
struct lp_fence *fence = arg.fence;
-
- pipe_mutex_lock( fence->mutex );
-
- fence->count++;
- assert(fence->count <= fence->rank);
-
- LP_DBG(DEBUG_RAST, "%s count=%u rank=%u\n", __FUNCTION__,
- fence->count, fence->rank);
-
- pipe_condvar_signal( fence->signalled );
-
- pipe_mutex_unlock( fence->mutex );
+ lp_fence_signal(fence);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index dc5fc5fc7d6..ae838f3fbef 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -82,6 +82,8 @@ struct lp_rast_state {
* These pointers point into the bin data buffer.
*/
struct lp_rast_shader_inputs {
+ float facing; /** Positive for front-facing, negative for back-facing */
+
float (*a0)[4];
float (*dadx)[4];
float (*dady)[4];
@@ -95,7 +97,7 @@ struct lp_rast_shader_inputs {
* Rasterization information for a triangle known to be in this bin,
* plus inputs to run the shader:
* These fields are tile- and bin-independent.
- * Objects of this type are put into the setup_context::data buffer.
+ * Objects of this type are put into the lp_setup_context::data buffer.
*/
struct lp_rast_triangle {
#ifdef DEBUG
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index 39bf2c25879..6ee9bcaae3a 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -195,6 +195,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
/* run shader */
state->jit_function[0]( &state->jit_context,
x, y,
+ inputs->facing,
inputs->a0,
inputs->dadx,
inputs->dady,
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 72492c0f0ca..681ce674d49 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -397,7 +397,6 @@ end:
static boolean
lp_scene_map_buffers( struct lp_scene *scene )
{
- struct pipe_screen *screen = scene->pipe->screen;
struct pipe_surface *cbuf, *zsbuf;
int i;
@@ -409,20 +408,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
for (i = 0; i < scene->fb.nr_cbufs; i++) {
cbuf = scene->fb.cbufs[i];
if (cbuf) {
- scene->cbuf_transfer[i] = screen->get_tex_transfer(screen,
- cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice,
- PIPE_TRANSFER_READ_WRITE,
- 0, 0,
- cbuf->width,
- cbuf->height);
- if (!scene->cbuf_transfer[i])
- goto fail;
-
- scene->cbuf_map[i] = screen->transfer_map(screen,
- scene->cbuf_transfer[i]);
+ scene->cbuf_map[i] = llvmpipe_texture_map(cbuf->texture,
+ cbuf->face,
+ cbuf->level,
+ cbuf->zslice);
if (!scene->cbuf_map[i])
goto fail;
}
@@ -432,20 +421,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
*/
zsbuf = scene->fb.zsbuf;
if (zsbuf) {
- scene->zsbuf_transfer = screen->get_tex_transfer(screen,
- zsbuf->texture,
- zsbuf->face,
- zsbuf->level,
- zsbuf->zslice,
- PIPE_TRANSFER_READ_WRITE,
- 0, 0,
- zsbuf->width,
- zsbuf->height);
- if (!scene->zsbuf_transfer)
- goto fail;
-
- scene->zsbuf_map = screen->transfer_map(screen,
- scene->zsbuf_transfer);
+ scene->zsbuf_map = llvmpipe_texture_map(zsbuf->texture,
+ zsbuf->face,
+ zsbuf->level,
+ zsbuf->zslice);
if (!scene->zsbuf_map)
goto fail;
}
@@ -469,28 +448,27 @@ fail:
static void
lp_scene_unmap_buffers( struct lp_scene *scene )
{
- struct pipe_screen *screen = scene->pipe->screen;
unsigned i;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
- if (scene->cbuf_map[i])
- screen->transfer_unmap(screen, scene->cbuf_transfer[i]);
-
- if (scene->cbuf_transfer[i])
- screen->tex_transfer_destroy(scene->cbuf_transfer[i]);
-
- scene->cbuf_transfer[i] = NULL;
- scene->cbuf_map[i] = NULL;
+ if (scene->cbuf_map[i]) {
+ struct pipe_surface *cbuf = scene->fb.cbufs[i];
+ llvmpipe_texture_unmap(cbuf->texture,
+ cbuf->face,
+ cbuf->level,
+ cbuf->zslice);
+ scene->cbuf_map[i] = NULL;
+ }
}
- if (scene->zsbuf_map)
- screen->transfer_unmap(screen, scene->zsbuf_transfer);
-
- if (scene->zsbuf_transfer)
- screen->tex_transfer_destroy(scene->zsbuf_transfer);
-
- scene->zsbuf_transfer = NULL;
- scene->zsbuf_map = NULL;
+ if (scene->zsbuf_map) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
+ llvmpipe_texture_unmap(zsbuf->texture,
+ zsbuf->face,
+ zsbuf->level,
+ zsbuf->zslice);
+ scene->zsbuf_map = NULL;
+ }
util_unreference_framebuffer_state( &scene->fb );
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index 739ac229089..b602b1e8a05 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -114,8 +114,6 @@ struct texture_ref {
*/
struct lp_scene {
struct pipe_context *pipe;
- struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS];
- struct pipe_transfer *zsbuf_transfer;
/* Scene's buffers are mapped at the time the scene is enqueued:
*/
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index f84ede675b3..f1bbc2092c4 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -34,11 +34,13 @@
#include "lp_texture.h"
#include "lp_buffer.h"
#include "lp_fence.h"
-#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
#include "lp_context.h"
#include "lp_debug.h"
+#include "lp_public.h"
+
+#include "state_tracker/sw_winsys.h"
#ifdef DEBUG
int LP_DEBUG = 0;
@@ -107,11 +109,11 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return LP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return LP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -167,7 +169,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
unsigned geom_flags )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
const struct util_format_description *format_desc;
format_desc = util_format_description(format);
@@ -202,8 +204,10 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
return FALSE;
}
- if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if(!winsys->is_displaytarget_format_supported(winsys, format))
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
return FALSE;
}
@@ -238,18 +242,6 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
}
-static struct pipe_buffer *
-llvmpipe_surface_buffer_create(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned tex_usage,
- unsigned usage,
- unsigned *stride)
-{
- /* This function should never be used */
- assert(0);
- return NULL;
-}
static void
@@ -258,7 +250,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
void *context_private)
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
assert(texture->dt);
@@ -271,7 +263,7 @@ static void
llvmpipe_destroy_screen( struct pipe_screen *_screen )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
lp_jit_screen_cleanup(screen);
@@ -288,7 +280,7 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
* Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
*/
struct pipe_screen *
-llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+llvmpipe_create_screen(struct sw_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
@@ -309,7 +301,6 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
screen->base.get_paramf = llvmpipe_get_paramf;
screen->base.is_format_supported = llvmpipe_is_format_supported;
- screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
screen->base.context_create = llvmpipe_create_context;
screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index 4a1b4d6f3e2..af25e043cc9 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -34,23 +34,21 @@
#ifndef LP_SCREEN_H
#define LP_SCREEN_H
-#include <llvm-c/Core.h>
-#include <llvm-c/Analysis.h>
-#include <llvm-c/Target.h>
+#include "gallivm/lp_bld.h"
#include <llvm-c/ExecutionEngine.h>
#include "pipe/p_screen.h"
#include "pipe/p_defines.h"
-struct llvmpipe_winsys;
+struct sw_winsys;
struct llvmpipe_screen
{
struct pipe_screen base;
- struct llvmpipe_winsys *winsys;
+ struct sw_winsys *winsys;
LLVMModuleRef module;
LLVMExecutionEngineRef engine;
@@ -76,4 +74,5 @@ llvmpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* LP_SCREEN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b0713c3b71d..76a8b87a309 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -46,17 +46,17 @@
#include "lp_rast.h"
#include "lp_setup_context.h"
#include "lp_screen.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
-static void set_scene_state( struct setup_context *, unsigned );
+static void set_scene_state( struct lp_setup_context *, unsigned );
struct lp_scene *
-lp_setup_get_current_scene(struct setup_context *setup)
+lp_setup_get_current_scene(struct lp_setup_context *setup)
{
if (!setup->scene) {
@@ -74,7 +74,7 @@ lp_setup_get_current_scene(struct setup_context *setup)
static void
-first_triangle( struct setup_context *setup,
+first_triangle( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4])
@@ -85,7 +85,7 @@ first_triangle( struct setup_context *setup,
}
static void
-first_line( struct setup_context *setup,
+first_line( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4])
{
@@ -95,7 +95,7 @@ first_line( struct setup_context *setup,
}
static void
-first_point( struct setup_context *setup,
+first_point( struct lp_setup_context *setup,
const float (*v0)[4])
{
set_scene_state( setup, SETUP_ACTIVE );
@@ -103,7 +103,7 @@ first_point( struct setup_context *setup,
setup->point( setup, v0 );
}
-static void reset_context( struct setup_context *setup )
+static void reset_context( struct lp_setup_context *setup )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -131,7 +131,7 @@ static void reset_context( struct setup_context *setup )
/** Rasterize all scene's bins */
static void
-lp_setup_rasterize_scene( struct setup_context *setup,
+lp_setup_rasterize_scene( struct lp_setup_context *setup,
boolean write_depth )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
@@ -148,7 +148,7 @@ lp_setup_rasterize_scene( struct setup_context *setup,
static void
-begin_binning( struct setup_context *setup )
+begin_binning( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
@@ -184,7 +184,7 @@ begin_binning( struct setup_context *setup )
* TODO: fast path for fullscreen clears and no triangles.
*/
static void
-execute_clears( struct setup_context *setup )
+execute_clears( struct lp_setup_context *setup )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -194,7 +194,7 @@ execute_clears( struct setup_context *setup )
static void
-set_scene_state( struct setup_context *setup,
+set_scene_state( struct lp_setup_context *setup,
unsigned new_state )
{
unsigned old_state = setup->state;
@@ -229,7 +229,7 @@ set_scene_state( struct setup_context *setup,
void
-lp_setup_flush( struct setup_context *setup,
+lp_setup_flush( struct lp_setup_context *setup,
unsigned flags )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -239,7 +239,7 @@ lp_setup_flush( struct setup_context *setup,
void
-lp_setup_bind_framebuffer( struct setup_context *setup,
+lp_setup_bind_framebuffer( struct lp_setup_context *setup,
const struct pipe_framebuffer_state *fb )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -256,7 +256,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup,
void
-lp_setup_clear( struct setup_context *setup,
+lp_setup_clear( struct lp_setup_context *setup,
const float *color,
double depth,
unsigned stencil,
@@ -314,7 +314,7 @@ lp_setup_clear( struct setup_context *setup,
* Emit a fence.
*/
struct pipe_fence_handle *
-lp_setup_fence( struct setup_context *setup )
+lp_setup_fence( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
@@ -334,10 +334,11 @@ lp_setup_fence( struct setup_context *setup )
void
-lp_setup_set_triangle_state( struct setup_context *setup,
+lp_setup_set_triangle_state( struct lp_setup_context *setup,
unsigned cull_mode,
boolean ccw_is_frontface,
- boolean scissor )
+ boolean scissor,
+ boolean gl_rasterization_rules)
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -345,12 +346,13 @@ lp_setup_set_triangle_state( struct setup_context *setup,
setup->cullmode = cull_mode;
setup->triangle = first_triangle;
setup->scissor_test = scissor;
+ setup->pixel_offset = gl_rasterization_rules ? 0.5f : 0.0f;
}
void
-lp_setup_set_fs_inputs( struct setup_context *setup,
+lp_setup_set_fs_inputs( struct lp_setup_context *setup,
const struct lp_shader_input *input,
unsigned nr )
{
@@ -361,7 +363,7 @@ lp_setup_set_fs_inputs( struct setup_context *setup,
}
void
-lp_setup_set_fs_functions( struct setup_context *setup,
+lp_setup_set_fs_functions( struct lp_setup_context *setup,
lp_jit_frag_func jit_function0,
lp_jit_frag_func jit_function1,
boolean opaque )
@@ -376,7 +378,7 @@ lp_setup_set_fs_functions( struct setup_context *setup,
}
void
-lp_setup_set_fs_constants(struct setup_context *setup,
+lp_setup_set_fs_constants(struct lp_setup_context *setup,
struct pipe_buffer *buffer)
{
LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) buffer);
@@ -388,7 +390,7 @@ lp_setup_set_fs_constants(struct setup_context *setup,
void
-lp_setup_set_alpha_ref_value( struct setup_context *setup,
+lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
float alpha_ref_value )
{
LP_DBG(DEBUG_SETUP, "%s %f\n", __FUNCTION__, alpha_ref_value);
@@ -400,7 +402,21 @@ lp_setup_set_alpha_ref_value( struct setup_context *setup,
}
void
-lp_setup_set_blend_color( struct setup_context *setup,
+lp_setup_set_stencil_ref_values( struct lp_setup_context *setup,
+ const ubyte refs[2] )
+{
+ LP_DBG(DEBUG_SETUP, "%s %d %d\n", __FUNCTION__, refs[0], refs[1]);
+
+ if (setup->fs.current.jit_context.stencil_ref_front != refs[0] ||
+ setup->fs.current.jit_context.stencil_ref_back != refs[1]) {
+ setup->fs.current.jit_context.stencil_ref_front = refs[0];
+ setup->fs.current.jit_context.stencil_ref_back = refs[1];
+ setup->dirty |= LP_SETUP_NEW_FS;
+ }
+}
+
+void
+lp_setup_set_blend_color( struct lp_setup_context *setup,
const struct pipe_blend_color *blend_color )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -415,7 +431,7 @@ lp_setup_set_blend_color( struct setup_context *setup,
void
-lp_setup_set_scissor( struct setup_context *setup,
+lp_setup_set_scissor( struct lp_setup_context *setup,
const struct pipe_scissor_state *scissor )
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -430,7 +446,7 @@ lp_setup_set_scissor( struct setup_context *setup,
void
-lp_setup_set_flatshade_first( struct setup_context *setup,
+lp_setup_set_flatshade_first( struct lp_setup_context *setup,
boolean flatshade_first )
{
setup->flatshade_first = flatshade_first;
@@ -438,7 +454,7 @@ lp_setup_set_flatshade_first( struct setup_context *setup,
void
-lp_setup_set_vertex_info( struct setup_context *setup,
+lp_setup_set_vertex_info( struct lp_setup_context *setup,
struct vertex_info *vertex_info )
{
/* XXX: just silently holding onto the pointer:
@@ -448,11 +464,12 @@ lp_setup_set_vertex_info( struct setup_context *setup,
/**
- * Called during state validation when LP_NEW_TEXTURE is set.
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
*/
void
-lp_setup_set_sampler_textures( struct setup_context *setup,
- unsigned num, struct pipe_texture **texture)
+lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
unsigned i;
@@ -461,9 +478,10 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
assert(num <= PIPE_MAX_SAMPLERS);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- if(tex) {
+ if(view) {
+ struct pipe_texture *tex = view->texture;
struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
struct lp_jit_texture *jit_tex;
jit_tex = &setup->fs.current.jit_context.textures[i];
@@ -471,26 +489,33 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
jit_tex->height = tex->height0;
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
- jit_tex->stride = lp_tex->stride[0];
- if(!lp_tex->dt) {
- jit_tex->data = lp_tex->data;
+
+ /* We're referencing the texture's internal data, so save a
+ * reference to it.
+ */
+ pipe_texture_reference(&setup->fs.current_tex[i], tex);
+
+ if (!lp_tex->dt) {
+ /* regular texture - setup array of mipmap level pointers */
+ int j;
+ for (j = 0; j <= tex->last_level; j++) {
+ jit_tex->data[j] =
+ (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+ jit_tex->row_stride[j] = lp_tex->stride[j];
+ }
}
else {
+ /* display target texture/surface */
/*
* XXX: Where should this be unmapped?
*/
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
- struct llvmpipe_winsys *winsys = screen->winsys;
- jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
+ struct sw_winsys *winsys = screen->winsys;
+ jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_BUFFER_USAGE_CPU_READ);
- assert(jit_tex->data);
- }
-
- /* the scene references this texture */
- {
- struct lp_scene *scene = lp_setup_get_current_scene(setup);
- lp_scene_texture_reference(scene, tex);
+ jit_tex->row_stride[0] = lp_tex->stride[0];
+ assert(jit_tex->data[0]);
}
}
}
@@ -505,7 +530,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
* being rendered and the current scene being built.
*/
unsigned
-lp_setup_is_texture_referenced( const struct setup_context *setup,
+lp_setup_is_texture_referenced( const struct lp_setup_context *setup,
const struct pipe_texture *texture )
{
unsigned i;
@@ -534,7 +559,7 @@ lp_setup_is_texture_referenced( const struct setup_context *setup,
* Called by vbuf code when we're about to draw something.
*/
void
-lp_setup_update_state( struct setup_context *setup )
+lp_setup_update_state( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
@@ -626,6 +651,7 @@ lp_setup_update_state( struct setup_context *setup )
* the new, current state. So allocate a new lp_rast_state object
* and append it to the bin's setup data buffer.
*/
+ uint i;
struct lp_rast_state *stored =
(struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored);
if(stored) {
@@ -639,6 +665,14 @@ lp_setup_update_state( struct setup_context *setup )
lp_rast_set_state,
lp_rast_arg_state(setup->fs.stored) );
}
+
+ /* The scene now references the textures in the rasterization
+ * state record. Note that now.
+ */
+ for (i = 0; i < Elements(setup->fs.current_tex); i++) {
+ if (setup->fs.current_tex[i])
+ lp_scene_texture_reference(scene, setup->fs.current_tex[i]);
+ }
}
}
@@ -652,10 +686,16 @@ lp_setup_update_state( struct setup_context *setup )
/* Only caller is lp_setup_vbuf_destroy()
*/
void
-lp_setup_destroy( struct setup_context *setup )
+lp_setup_destroy( struct lp_setup_context *setup )
{
+ uint i;
+
reset_context( setup );
+ for (i = 0; i < Elements(setup->fs.current_tex); i++) {
+ pipe_texture_reference(&setup->fs.current_tex[i], NULL);
+ }
+
pipe_buffer_reference(&setup->constants.current, NULL);
/* free the scenes in the 'empty' queue */
@@ -677,12 +717,12 @@ lp_setup_destroy( struct setup_context *setup )
* the draw module. Currently also creates a rasterizer to use with
* it.
*/
-struct setup_context *
+struct lp_setup_context *
lp_setup_create( struct pipe_context *pipe,
struct draw_context *draw )
{
unsigned i;
- struct setup_context *setup = CALLOC_STRUCT(setup_context);
+ struct lp_setup_context *setup = CALLOC_STRUCT(lp_setup_context);
if (!setup)
return NULL;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 17c112b5289..dbfc1bf8d4c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -61,78 +61,84 @@ struct pipe_framebuffer_state;
struct lp_fragment_shader;
struct lp_jit_context;
-struct setup_context *
+struct lp_setup_context *
lp_setup_create( struct pipe_context *pipe,
struct draw_context *draw );
void
-lp_setup_clear(struct setup_context *setup,
+lp_setup_clear(struct lp_setup_context *setup,
const float *clear_color,
double clear_depth,
unsigned clear_stencil,
unsigned flags);
struct pipe_fence_handle *
-lp_setup_fence( struct setup_context *setup );
+lp_setup_fence( struct lp_setup_context *setup );
void
-lp_setup_flush( struct setup_context *setup,
+lp_setup_flush( struct lp_setup_context *setup,
unsigned flags );
void
-lp_setup_bind_framebuffer( struct setup_context *setup,
+lp_setup_bind_framebuffer( struct lp_setup_context *setup,
const struct pipe_framebuffer_state *fb );
void
-lp_setup_set_triangle_state( struct setup_context *setup,
+lp_setup_set_triangle_state( struct lp_setup_context *setup,
unsigned cullmode,
boolean front_is_ccw,
- boolean scissor );
+ boolean scissor,
+ boolean gl_rasterization_rules );
void
-lp_setup_set_fs_inputs( struct setup_context *setup,
+lp_setup_set_fs_inputs( struct lp_setup_context *setup,
const struct lp_shader_input *interp,
unsigned nr );
void
-lp_setup_set_fs_functions( struct setup_context *setup,
+lp_setup_set_fs_functions( struct lp_setup_context *setup,
lp_jit_frag_func jit_function0,
lp_jit_frag_func jit_function1,
boolean opaque );
void
-lp_setup_set_fs_constants(struct setup_context *setup,
+lp_setup_set_fs_constants(struct lp_setup_context *setup,
struct pipe_buffer *buffer);
void
-lp_setup_set_alpha_ref_value( struct setup_context *setup,
+lp_setup_set_alpha_ref_value( struct lp_setup_context *setup,
float alpha_ref_value );
void
-lp_setup_set_blend_color( struct setup_context *setup,
+lp_setup_set_stencil_ref_values( struct lp_setup_context *setup,
+ const ubyte refs[2] );
+
+void
+lp_setup_set_blend_color( struct lp_setup_context *setup,
const struct pipe_blend_color *blend_color );
void
-lp_setup_set_scissor( struct setup_context *setup,
+lp_setup_set_scissor( struct lp_setup_context *setup,
const struct pipe_scissor_state *scissor );
void
-lp_setup_set_sampler_textures( struct setup_context *setup,
- unsigned num, struct pipe_texture **texture);
+lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
+ unsigned num,
+ struct pipe_sampler_view **views);
unsigned
-lp_setup_is_texture_referenced( const struct setup_context *setup,
+lp_setup_is_texture_referenced( const struct lp_setup_context *setup,
const struct pipe_texture *texture );
void
-lp_setup_set_flatshade_first( struct setup_context *setup,
+lp_setup_set_flatshade_first( struct lp_setup_context *setup,
boolean flatshade_first );
void
-lp_setup_set_vertex_info( struct setup_context *setup,
+lp_setup_set_vertex_info( struct lp_setup_context *setup,
struct vertex_info *info );
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h
index a5fc34e54a2..ca0dafab627 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h
@@ -65,7 +65,7 @@ struct lp_scene_queue;
* Subclass of vbuf_render, plugged directly into the draw module as
* the rendering backend.
*/
-struct setup_context
+struct lp_setup_context
{
struct vbuf_render base;
@@ -89,6 +89,7 @@ struct setup_context
boolean ccw_is_frontface;
boolean scissor_test;
unsigned cullmode;
+ float pixel_offset;
struct pipe_framebuffer_state fb;
@@ -110,6 +111,7 @@ struct setup_context
const struct lp_rast_state *stored; /**< what's in the scene */
struct lp_rast_state current; /**< currently set state */
+ struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS];
} fs;
/** fragment shader constants */
@@ -131,29 +133,29 @@ struct setup_context
unsigned dirty; /**< bitmask of LP_SETUP_NEW_x bits */
- void (*point)( struct setup_context *,
+ void (*point)( struct lp_setup_context *,
const float (*v0)[4]);
- void (*line)( struct setup_context *,
+ void (*line)( struct lp_setup_context *,
const float (*v0)[4],
const float (*v1)[4]);
- void (*triangle)( struct setup_context *,
+ void (*triangle)( struct lp_setup_context *,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4]);
};
-void lp_setup_choose_triangle( struct setup_context *setup );
-void lp_setup_choose_line( struct setup_context *setup );
-void lp_setup_choose_point( struct setup_context *setup );
+void lp_setup_choose_triangle( struct lp_setup_context *setup );
+void lp_setup_choose_line( struct lp_setup_context *setup );
+void lp_setup_choose_point( struct lp_setup_context *setup );
-struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup);
+struct lp_scene *lp_setup_get_current_scene(struct lp_setup_context *setup);
-void lp_setup_init_vbuf(struct setup_context *setup);
+void lp_setup_init_vbuf(struct lp_setup_context *setup);
-void lp_setup_update_state( struct setup_context *setup );
+void lp_setup_update_state( struct lp_setup_context *setup );
-void lp_setup_destroy( struct setup_context *setup );
+void lp_setup_destroy( struct lp_setup_context *setup );
#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c
index feea79d3943..be41c44e6f5 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_line.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c
@@ -31,7 +31,7 @@
#include "lp_setup_context.h"
-static void line_nop( struct setup_context *setup,
+static void line_nop( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4] )
{
@@ -39,7 +39,7 @@ static void line_nop( struct setup_context *setup,
void
-lp_setup_choose_line( struct setup_context *setup )
+lp_setup_choose_line( struct lp_setup_context *setup )
{
setup->line = line_nop;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index f03ca729b24..9f69e6c5ce2 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -31,14 +31,14 @@
#include "lp_setup_context.h"
-static void point_nop( struct setup_context *setup,
+static void point_nop( struct lp_setup_context *setup,
const float (*v0)[4] )
{
}
void
-lp_setup_choose_point( struct setup_context *setup )
+lp_setup_choose_point( struct lp_setup_context *setup )
{
setup->point = point_nop;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index e75412ac9aa..ce689d3d568 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -41,7 +41,8 @@
/**
* Compute a0 for a constant-valued coefficient (GL_FLAT shading).
*/
-static void constant_coef( struct lp_rast_triangle *tri,
+static void constant_coef( struct lp_setup_context *setup,
+ struct lp_rast_triangle *tri,
unsigned slot,
const float value,
unsigned i )
@@ -56,7 +57,8 @@ static void constant_coef( struct lp_rast_triangle *tri,
* Compute a0, dadx and dady for a linearly interpolated coefficient,
* for a triangle.
*/
-static void linear_coef( struct lp_rast_triangle *tri,
+static void linear_coef( struct lp_setup_context *setup,
+ struct lp_rast_triangle *tri,
float oneoverarea,
unsigned slot,
const float (*v1)[4],
@@ -90,8 +92,8 @@ static void linear_coef( struct lp_rast_triangle *tri,
* instead - i'll switch to this later.
*/
tri->inputs.a0[slot][i] = (a1 -
- (dadx * (v1[0][0] - 0.5f) +
- dady * (v1[0][1] - 0.5f)));
+ (dadx * (v1[0][0] - setup->pixel_offset) +
+ dady * (v1[0][1] - setup->pixel_offset)));
}
@@ -103,7 +105,8 @@ static void linear_coef( struct lp_rast_triangle *tri,
* Later, when we compute the value at a particular fragment position we'll
* divide the interpolated value by the interpolated W at that fragment.
*/
-static void perspective_coef( struct lp_rast_triangle *tri,
+static void perspective_coef( struct lp_setup_context *setup,
+ struct lp_rast_triangle *tri,
float oneoverarea,
unsigned slot,
const float (*v1)[4],
@@ -125,8 +128,8 @@ static void perspective_coef( struct lp_rast_triangle *tri,
tri->inputs.dadx[slot][i] = dadx;
tri->inputs.dady[slot][i] = dady;
tri->inputs.a0[slot][i] = (a1 -
- (dadx * (v1[0][0] - 0.5f) +
- dady * (v1[0][1] - 0.5f)));
+ (dadx * (v1[0][0] - setup->pixel_offset) +
+ dady * (v1[0][1] - setup->pixel_offset)));
}
@@ -137,7 +140,8 @@ static void perspective_coef( struct lp_rast_triangle *tri,
* We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
*/
static void
-setup_fragcoord_coef(struct lp_rast_triangle *tri,
+setup_fragcoord_coef(struct lp_setup_context *setup,
+ struct lp_rast_triangle *tri,
float oneoverarea,
unsigned slot,
const float (*v1)[4],
@@ -153,27 +157,28 @@ setup_fragcoord_coef(struct lp_rast_triangle *tri,
tri->inputs.dadx[slot][1] = 0.0;
tri->inputs.dady[slot][1] = 1.0;
/*Z*/
- linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 2);
+ linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 2);
/*W*/
- linear_coef(tri, oneoverarea, slot, v1, v2, v3, 0, 3);
+ linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 3);
}
-static void setup_facing_coef( struct lp_rast_triangle *tri,
+static void setup_facing_coef( struct lp_setup_context *setup,
+ struct lp_rast_triangle *tri,
unsigned slot,
boolean frontface )
{
- constant_coef( tri, slot, 1.0f - frontface, 0 );
- constant_coef( tri, slot, 0.0f, 1 ); /* wasted */
- constant_coef( tri, slot, 0.0f, 2 ); /* wasted */
- constant_coef( tri, slot, 0.0f, 3 ); /* wasted */
+ constant_coef( setup, tri, slot, 1.0f - frontface, 0 );
+ constant_coef( setup, tri, slot, 0.0f, 1 ); /* wasted */
+ constant_coef( setup, tri, slot, 0.0f, 2 ); /* wasted */
+ constant_coef( setup, tri, slot, 0.0f, 3 ); /* wasted */
}
/**
* Compute the tri->coef[] array dadx, dady, a0 values.
*/
-static void setup_tri_coefficients( struct setup_context *setup,
+static void setup_tri_coefficients( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
float oneoverarea,
const float (*v1)[4],
@@ -185,7 +190,7 @@ static void setup_tri_coefficients( struct setup_context *setup,
/* The internal position input is in slot zero:
*/
- setup_fragcoord_coef(tri, oneoverarea, 0, v1, v2, v3);
+ setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v3);
/* setup interpolation for all the remaining attributes:
*/
@@ -196,27 +201,27 @@ static void setup_tri_coefficients( struct setup_context *setup,
switch (setup->fs.input[slot].interp) {
case LP_INTERP_CONSTANT:
for (i = 0; i < NUM_CHANNELS; i++)
- constant_coef(tri, slot+1, v3[vert_attr][i], i);
+ constant_coef(setup, tri, slot+1, v3[vert_attr][i], i);
break;
case LP_INTERP_LINEAR:
for (i = 0; i < NUM_CHANNELS; i++)
- linear_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+ linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
break;
case LP_INTERP_PERSPECTIVE:
for (i = 0; i < NUM_CHANNELS; i++)
- perspective_coef(tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+ perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
break;
case LP_INTERP_POSITION:
/* XXX: fix me - duplicates the values in slot zero.
*/
- setup_fragcoord_coef(tri, oneoverarea, slot+1, v1, v2, v3);
+ setup_fragcoord_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3);
break;
case LP_INTERP_FACING:
- setup_facing_coef(tri, slot+1, frontface);
+ setup_facing_coef(setup, tri, slot+1, frontface);
break;
default:
@@ -274,19 +279,19 @@ alloc_triangle(struct lp_scene *scene, unsigned nr_inputs, unsigned *tri_size)
* bins for the tiles which we overlap.
*/
static void
-do_triangle_ccw(struct setup_context *setup,
+do_triangle_ccw(struct lp_setup_context *setup,
const float (*v1)[4],
const float (*v2)[4],
const float (*v3)[4],
boolean frontfacing )
{
/* x/y positions in fixed point */
- const int x1 = subpixel_snap(v1[0][0]);
- const int x2 = subpixel_snap(v2[0][0]);
- const int x3 = subpixel_snap(v3[0][0]);
- const int y1 = subpixel_snap(v1[0][1]);
- const int y2 = subpixel_snap(v2[0][1]);
- const int y3 = subpixel_snap(v3[0][1]);
+ const int x1 = subpixel_snap(v1[0][0] + 0.5 - setup->pixel_offset);
+ const int x2 = subpixel_snap(v2[0][0] + 0.5 - setup->pixel_offset);
+ const int x3 = subpixel_snap(v3[0][0] + 0.5 - setup->pixel_offset);
+ const int y1 = subpixel_snap(v1[0][1] + 0.5 - setup->pixel_offset);
+ const int y2 = subpixel_snap(v2[0][1] + 0.5 - setup->pixel_offset);
+ const int y3 = subpixel_snap(v3[0][1] + 0.5 - setup->pixel_offset);
struct lp_scene *scene = lp_setup_get_current_scene(setup);
struct lp_rast_triangle *tri;
@@ -356,6 +361,8 @@ do_triangle_ccw(struct setup_context *setup,
*/
setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing );
+ tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
+
/* half-edge constants, will be interated over the whole render target.
*/
tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
@@ -565,7 +572,7 @@ do_triangle_ccw(struct setup_context *setup,
}
-static void triangle_cw( struct setup_context *setup,
+static void triangle_cw( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4] )
@@ -574,7 +581,7 @@ static void triangle_cw( struct setup_context *setup,
}
-static void triangle_ccw( struct setup_context *setup,
+static void triangle_ccw( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4] )
@@ -583,7 +590,7 @@ static void triangle_ccw( struct setup_context *setup,
}
-static void triangle_both( struct setup_context *setup,
+static void triangle_both( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4] )
@@ -602,7 +609,7 @@ static void triangle_both( struct setup_context *setup,
}
-static void triangle_nop( struct setup_context *setup,
+static void triangle_nop( struct lp_setup_context *setup,
const float (*v0)[4],
const float (*v1)[4],
const float (*v2)[4] )
@@ -611,7 +618,7 @@ static void triangle_nop( struct setup_context *setup,
void
-lp_setup_choose_triangle( struct setup_context *setup )
+lp_setup_choose_triangle( struct lp_setup_context *setup )
{
switch (setup->cullmode) {
case PIPE_WINDING_NONE:
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
index 24291da91e4..d7336d82b21 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
@@ -48,10 +48,10 @@
/** cast wrapper */
-static struct setup_context *
-setup_context(struct vbuf_render *vbr)
+static struct lp_setup_context *
+lp_setup_context(struct vbuf_render *vbr)
{
- return (struct setup_context *) vbr;
+ return (struct lp_setup_context *) vbr;
}
@@ -59,7 +59,7 @@ setup_context(struct vbuf_render *vbr)
static const struct vertex_info *
lp_setup_get_vertex_info(struct vbuf_render *vbr)
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
return setup->vertex_info;
}
@@ -68,7 +68,7 @@ static boolean
lp_setup_allocate_vertices(struct vbuf_render *vbr,
ushort vertex_size, ushort nr_vertices)
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
unsigned size = vertex_size * nr_vertices;
if (setup->vertex_buffer_size < size) {
@@ -92,7 +92,7 @@ lp_setup_release_vertices(struct vbuf_render *vbr)
static void *
lp_setup_map_vertices(struct vbuf_render *vbr)
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
return setup->vertex_buffer;
}
@@ -101,7 +101,7 @@ lp_setup_unmap_vertices(struct vbuf_render *vbr,
ushort min_index,
ushort max_index )
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size );
/* do nothing */
}
@@ -110,7 +110,7 @@ lp_setup_unmap_vertices(struct vbuf_render *vbr,
static boolean
lp_setup_set_primitive(struct vbuf_render *vbr, unsigned prim)
{
- setup_context(vbr)->prim = prim;
+ lp_setup_context(vbr)->prim = prim;
return TRUE;
}
@@ -129,7 +129,7 @@ static INLINE const_float4_ptr get_vert( const void *vertex_buffer,
static void
lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
const unsigned stride = setup->vertex_info->size * sizeof(float);
const void *vertex_buffer = setup->vertex_buffer;
unsigned i;
@@ -231,57 +231,29 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride),
- get_vert(vertex_buffer, indices[i-0], stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
}
break;
@@ -312,7 +284,7 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
static void
lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
{
- struct setup_context *setup = setup_context(vbr);
+ struct lp_setup_context *setup = lp_setup_context(vbr);
const unsigned stride = setup->vertex_info->size * sizeof(float);
const void *vertex_buffer =
(void *) get_vert(setup->vertex_buffer, start, stride);
@@ -415,57 +387,28 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 4) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (setup->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- setup->triangle( setup,
-
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- setup->triangle( setup,
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride) );
- setup->triangle( setup,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride),
- get_vert(vertex_buffer, i-0, stride) );
- }
+ for (i = 3; i < nr; i += 2) {
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ setup->triangle( setup,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-0, stride) );
}
break;
@@ -493,7 +436,7 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
static void
lp_setup_vbuf_destroy(struct vbuf_render *vbr)
{
- lp_setup_destroy(setup_context(vbr));
+ lp_setup_destroy(lp_setup_context(vbr));
}
@@ -501,7 +444,7 @@ lp_setup_vbuf_destroy(struct vbuf_render *vbr)
* Create the post-transform vertex handler for the given context.
*/
void
-lp_setup_init_vbuf(struct setup_context *setup)
+lp_setup_init_vbuf(struct lp_setup_context *setup)
{
setup->base.max_indices = LP_MAX_VBUF_INDEXES;
setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE;
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 9beba32271f..74ebf90d580 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -31,7 +31,7 @@
#ifndef LP_STATE_H
#define LP_STATE_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
@@ -50,7 +50,7 @@
#define LP_NEW_DEPTH_STENCIL_ALPHA 0x100
#define LP_NEW_CONSTANTS 0x200
#define LP_NEW_SAMPLER 0x400
-#define LP_NEW_TEXTURE 0x800
+#define LP_NEW_SAMPLER_VIEW 0x800
#define LP_NEW_VERTEX 0x1000
#define LP_NEW_VS 0x2000
#define LP_NEW_QUERY 0x4000
@@ -67,6 +67,7 @@ struct lp_fragment_shader;
struct lp_fragment_shader_variant_key
{
struct pipe_depth_state depth;
+ struct pipe_stencil_state stencil[2];
struct pipe_alpha_state alpha;
struct pipe_blend_state blend;
enum pipe_format zsbuf_format;
@@ -119,6 +120,10 @@ struct lp_vertex_shader {
struct draw_vertex_shader *draw_data;
};
+struct lp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
void *
@@ -176,28 +181,39 @@ void *llvmpipe_create_vs_state(struct pipe_context *,
void llvmpipe_bind_vs_state(struct pipe_context *, void *);
void llvmpipe_delete_vs_state(struct pipe_context *, void *);
+void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void llvmpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
-void llvmpipe_set_sampler_textures( struct pipe_context *,
- unsigned num,
- struct pipe_texture ** );
+void llvmpipe_set_fragment_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
+
+void
+llvmpipe_set_vertex_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
+
+struct pipe_sampler_view *
+llvmpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ);
void
-llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void llvmpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void llvmpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index bdd906e1a73..777871638f6 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -150,7 +150,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
*/
if (llvmpipe->tex_timestamp != lp_screen->timestamp) {
llvmpipe->tex_timestamp = lp_screen->timestamp;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}
if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
@@ -164,7 +164,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
LP_NEW_DEPTH_STENCIL_ALPHA |
LP_NEW_RASTERIZER |
LP_NEW_SAMPLER |
- LP_NEW_TEXTURE))
+ LP_NEW_SAMPLER_VIEW))
llvmpipe_update_fs( llvmpipe );
if (llvmpipe->dirty & LP_NEW_BLEND_COLOR)
@@ -174,18 +174,21 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
if (llvmpipe->dirty & LP_NEW_SCISSOR)
lp_setup_set_scissor(llvmpipe->setup, &llvmpipe->scissor);
- if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA)
+ if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA) {
lp_setup_set_alpha_ref_value(llvmpipe->setup,
llvmpipe->depth_stencil->alpha.ref_value);
+ lp_setup_set_stencil_ref_values(llvmpipe->setup,
+ llvmpipe->stencil_ref.ref_value);
+ }
if (llvmpipe->dirty & LP_NEW_CONSTANTS)
lp_setup_set_fs_constants(llvmpipe->setup,
llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
- if (llvmpipe->dirty & LP_NEW_TEXTURE)
- lp_setup_set_sampler_textures(llvmpipe->setup,
- llvmpipe->num_textures,
- llvmpipe->texture);
+ if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
+ lp_setup_set_fragment_sampler_views(llvmpipe->setup,
+ llvmpipe->num_fragment_sampler_views,
+ llvmpipe->fragment_sampler_views);
llvmpipe->dirty = 0;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index c4b79dd4156..7bbf348e0b8 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -40,7 +40,7 @@
* - depth/stencil test (stencil TBI)
* - blending
*
- * This file has only the glue to assembly the fragment pipeline. The actual
+ * This file has only the glue to assemble the fragment pipeline. The actual
* plumbing of converting Gallium state into LLVM IR is done elsewhere, in the
* lp_bld_*.[ch] files, and in a complete generic and reusable way. Here we
* muster the LLVM JIT execution engine to create a function that follows an
@@ -95,6 +95,9 @@
#include "lp_tex_sample.h"
+#include <llvm-c/Analysis.h>
+
+
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
@@ -135,20 +138,22 @@ generate_pos0(LLVMBuilderRef builder,
/**
- * Generate the depth test.
+ * Generate the depth /stencil test code.
*/
static void
-generate_depth(LLVMBuilderRef builder,
- const struct lp_fragment_shader_variant_key *key,
- struct lp_type src_type,
- struct lp_build_mask_context *mask,
- LLVMValueRef src,
- LLVMValueRef dst_ptr)
+generate_depth_stencil(LLVMBuilderRef builder,
+ const struct lp_fragment_shader_variant_key *key,
+ struct lp_type src_type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef stencil_refs[2],
+ LLVMValueRef src,
+ LLVMValueRef dst_ptr,
+ LLVMValueRef facing)
{
const struct util_format_description *format_desc;
struct lp_type dst_type;
- if(!key->depth.enabled)
+ if (!key->depth.enabled && !key->stencil[0].enabled && !key->stencil[1].enabled)
return;
format_desc = util_format_description(key->zsbuf_format);
@@ -175,19 +180,22 @@ generate_depth(LLVMBuilderRef builder,
assert(dst_type.width == src_type.width);
assert(dst_type.length == src_type.length);
+ /* Convert fragment Z from float to integer */
lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
dst_ptr = LLVMBuildBitCast(builder,
dst_ptr,
LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
-
- lp_build_depth_test(builder,
- &key->depth,
- dst_type,
- format_desc,
- mask,
- src,
- dst_ptr);
+ lp_build_depth_stencil_test(builder,
+ &key->depth,
+ key->stencil,
+ dst_type,
+ format_desc,
+ mask,
+ stencil_refs,
+ src,
+ dst_ptr,
+ facing);
}
@@ -249,7 +257,7 @@ generate_tri_edge_mask(LLVMBuilderRef builder,
LLVMConstInt(LLVMInt32Type(), INT_MIN, 0),
"");
- in_out_mask = lp_build_int_const_scalar(i32_type, ~0);
+ in_out_mask = lp_build_const_int_vec(i32_type, ~0);
lp_build_flow_scope_declare(flow, &in_out_mask);
@@ -364,7 +372,7 @@ build_int32_vec_const(int value)
i32_type.norm = FALSE; /* values are not normalized */
i32_type.width = 32; /* 32-bit int values */
i32_type.length = 4; /* 4 elements per vector */
- return lp_build_int_const_scalar(i32_type, value);
+ return lp_build_const_int_vec(i32_type, value);
}
@@ -387,6 +395,7 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef *pmask,
LLVMValueRef (*color)[4],
LLVMValueRef depth_ptr,
+ LLVMValueRef facing,
unsigned do_tri_test,
LLVMValueRef c0,
LLVMValueRef c1,
@@ -402,15 +411,19 @@ generate_fs(struct llvmpipe_context *lp,
LLVMValueRef consts_ptr;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef z = interp->pos[2];
+ LLVMValueRef stencil_refs[2];
struct lp_build_flow_context *flow;
struct lp_build_mask_context mask;
- boolean early_depth_test;
+ boolean early_depth_stencil_test;
unsigned attrib;
unsigned chan;
unsigned cbuf;
assert(i < 4);
+ stencil_refs[0] = lp_jit_context_stencil_ref_front_value(builder, context_ptr);
+ stencil_refs[1] = lp_jit_context_stencil_ref_back_value(builder, context_ptr);
+
elem_type = lp_build_elem_type(type);
vec_type = lp_build_vec_type(type);
int_vec_type = lp_build_int_vec_type(type);
@@ -450,16 +463,16 @@ generate_fs(struct llvmpipe_context *lp,
lp_build_mask_update(&mask, smask);
}
- early_depth_test =
- key->depth.enabled &&
+ early_depth_stencil_test =
+ (key->depth.enabled || key->stencil[0].enabled) &&
!key->alpha.enabled &&
!shader->info.uses_kill &&
!shader->info.writes_z;
- if(early_depth_test)
- generate_depth(builder, key,
- type, &mask,
- z, depth_ptr);
+ if (early_depth_stencil_test)
+ generate_depth_stencil(builder, key,
+ type, &mask,
+ stencil_refs, z, depth_ptr, facing);
lp_build_tgsi_soa(builder, tokens, type, &mask,
consts_ptr, interp->pos, interp->inputs,
@@ -503,10 +516,10 @@ generate_fs(struct llvmpipe_context *lp,
}
}
- if(!early_depth_test)
- generate_depth(builder, key,
- type, &mask,
- z, depth_ptr);
+ if (!early_depth_stencil_test)
+ generate_depth_stencil(builder, key,
+ type, &mask,
+ stencil_refs, z, depth_ptr, facing);
lp_build_mask_end(&mask);
@@ -582,6 +595,20 @@ generate_blend(const struct pipe_blend_state *blend,
}
+/** casting function to avoid compiler warnings */
+static lp_jit_frag_func
+cast_voidptr_to_lp_jit_frag_func(void *p)
+{
+ union {
+ void *v;
+ lp_jit_frag_func f;
+ } tmp;
+ assert(sizeof(tmp.v) == sizeof(tmp.f));
+ tmp.v = p;
+ return tmp.f;
+}
+
+
/**
* Generate the runtime callable function for the whole fragment pipeline.
* Note that the function which we generate operates on a block of 16
@@ -603,7 +630,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMTypeRef fs_int_vec_type;
LLVMTypeRef blend_vec_type;
LLVMTypeRef blend_int_vec_type;
- LLVMTypeRef arg_types[14];
+ LLVMTypeRef arg_types[15];
LLVMTypeRef func_type;
LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
LLVMValueRef context_ptr;
@@ -626,6 +653,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMValueRef blend_mask;
LLVMValueRef blend_in_color[NUM_CHANNELS];
LLVMValueRef function;
+ LLVMValueRef facing;
unsigned num_fs;
unsigned i;
unsigned chan;
@@ -665,20 +693,21 @@ generate_fragment(struct llvmpipe_context *lp,
arg_types[0] = screen->context_ptr_type; /* context */
arg_types[1] = LLVMInt32Type(); /* x */
arg_types[2] = LLVMInt32Type(); /* y */
- arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */
- arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */
- arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */
- arg_types[6] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
- arg_types[7] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
- arg_types[8] = LLVMInt32Type(); /* c0 */
- arg_types[9] = LLVMInt32Type(); /* c1 */
- arg_types[10] = LLVMInt32Type(); /* c2 */
+ arg_types[3] = LLVMFloatType(); /* facing */
+ arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* a0 */
+ arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dadx */
+ arg_types[6] = LLVMPointerType(fs_elem_type, 0); /* dady */
+ arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0); /* color */
+ arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
+ arg_types[9] = LLVMInt32Type(); /* c0 */
+ arg_types[10] = LLVMInt32Type(); /* c1 */
+ arg_types[11] = LLVMInt32Type(); /* c2 */
/* Note: the step arrays are built as int32[16] but we interpret
* them here as int32_vec4[4].
*/
- arg_types[11] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
- arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
- arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
+ arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
+ arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
+ arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
@@ -698,17 +727,18 @@ generate_fragment(struct llvmpipe_context *lp,
context_ptr = LLVMGetParam(function, 0);
x = LLVMGetParam(function, 1);
y = LLVMGetParam(function, 2);
- a0_ptr = LLVMGetParam(function, 3);
- dadx_ptr = LLVMGetParam(function, 4);
- dady_ptr = LLVMGetParam(function, 5);
- color_ptr_ptr = LLVMGetParam(function, 6);
- depth_ptr = LLVMGetParam(function, 7);
- c0 = LLVMGetParam(function, 8);
- c1 = LLVMGetParam(function, 9);
- c2 = LLVMGetParam(function, 10);
- step0_ptr = LLVMGetParam(function, 11);
- step1_ptr = LLVMGetParam(function, 12);
- step2_ptr = LLVMGetParam(function, 13);
+ facing = LLVMGetParam(function, 3);
+ a0_ptr = LLVMGetParam(function, 4);
+ dadx_ptr = LLVMGetParam(function, 5);
+ dady_ptr = LLVMGetParam(function, 6);
+ color_ptr_ptr = LLVMGetParam(function, 7);
+ depth_ptr = LLVMGetParam(function, 8);
+ c0 = LLVMGetParam(function, 9);
+ c1 = LLVMGetParam(function, 10);
+ c2 = LLVMGetParam(function, 11);
+ step0_ptr = LLVMGetParam(function, 12);
+ step1_ptr = LLVMGetParam(function, 13);
+ step2_ptr = LLVMGetParam(function, 14);
lp_build_name(context_ptr, "context");
lp_build_name(x, "x");
@@ -767,6 +797,7 @@ generate_fragment(struct llvmpipe_context *lp,
&fs_mask[i], /* output */
out_color,
depth_ptr_i,
+ facing,
do_tri_test,
c0, c1, c2,
step0_ptr, step1_ptr, step2_ptr);
@@ -842,10 +873,14 @@ generate_fragment(struct llvmpipe_context *lp,
/*
* Translate the LLVM IR into machine code.
*/
- variant->jit_function[do_tri_test] = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, function);
+ {
+ void *f = LLVMGetPointerToGlobal(screen->engine, function);
+
+ variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f);
- if (LP_DEBUG & DEBUG_ASM)
- lp_disassemble(variant->jit_function[do_tri_test]);
+ if (LP_DEBUG & DEBUG_ASM)
+ lp_disassemble(f);
+ }
}
@@ -1051,10 +1086,15 @@ make_variant_key(struct llvmpipe_context *lp,
memset(key, 0, sizeof *key);
- if(lp->framebuffer.zsbuf &&
- lp->depth_stencil->depth.enabled) {
- key->zsbuf_format = lp->framebuffer.zsbuf->format;
- memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
+ if (lp->framebuffer.zsbuf) {
+ if (lp->depth_stencil->depth.enabled) {
+ key->zsbuf_format = lp->framebuffer.zsbuf->format;
+ memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
+ }
+ if (lp->depth_stencil->stencil[0].enabled) {
+ key->zsbuf_format = lp->framebuffer.zsbuf->format;
+ memcpy(&key->stencil, &lp->depth_stencil->stencil, sizeof key->stencil);
+ }
}
key->alpha.enabled = lp->depth_stencil->alpha.enabled;
@@ -1091,7 +1131,7 @@ make_variant_key(struct llvmpipe_context *lp,
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
- lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]);
+ lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i]->texture, lp->sampler[i]);
}
@@ -1137,6 +1177,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
opaque = !key.blend.logicop_enable &&
!key.blend.rt[0].blend_enable &&
key.blend.rt[0].colormask == 0xf &&
+ !key.stencil[0].enabled &&
!key.alpha.enabled &&
!key.depth.enabled &&
!key.scissor &&
@@ -1144,7 +1185,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
? TRUE : FALSE;
lp_setup_set_fs_functions(lp->setup,
- shader->current->jit_function[0],
- shader->current->jit_function[1],
+ shader->current->jit_function[RAST_WHOLE],
+ shader->current->jit_function[RAST_EDGE_TEST],
opaque);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index feb012816c9..6df3ef25b0e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -62,7 +62,8 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
lp_setup_set_triangle_state( llvmpipe->setup,
llvmpipe->rasterizer->cull_mode,
llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW,
- llvmpipe->rasterizer->scissor);
+ llvmpipe->rasterizer->scissor,
+ llvmpipe->rasterizer->gl_rasterization_rules);
}
llvmpipe->dirty |= LP_NEW_RASTERIZER;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index b30a0757768..2645441b58c 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -105,8 +105,9 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
void
-llvmpipe_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
uint i;
@@ -114,51 +115,79 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == llvmpipe->num_textures &&
- !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == llvmpipe->num_fragment_sampler_views &&
+ !memcmp(llvmpipe->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
draw_flush(llvmpipe->draw);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&llvmpipe->texture[i], tex);
+ pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], view);
}
- llvmpipe->num_textures = num;
+ llvmpipe->num_fragment_sampler_views = num;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
}
void
-llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == llvmpipe->num_vertex_textures &&
- !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == llvmpipe->num_vertex_sampler_views &&
+ !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
draw_flush(llvmpipe->draw);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&llvmpipe->vertex_textures[i], tex);
+ pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view);
}
- llvmpipe->num_vertex_textures = num_textures;
+ llvmpipe->num_vertex_sampler_views = num;
- llvmpipe->dirty |= LP_NEW_TEXTURE;
+ llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
+}
+
+
+struct pipe_sampler_view *
+llvmpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+void
+llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index 57ac25ea0cb..f6427aa908e 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -35,24 +35,41 @@
#include "draw/draw_context.h"
+void *
+llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct lp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct lp_velems_state *) MALLOC(sizeof(struct lp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-llvmpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ struct lp_velems_state *lp_velems = (struct lp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(llvmpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- llvmpipe->num_vertex_elements = count;
+ llvmpipe->velems = lp_velems;
llvmpipe->dirty |= LP_NEW_VERTEX;
- draw_set_vertex_elements(llvmpipe->draw, count, attribs);
+ if (velems)
+ draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
}
+void
+llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 6110b0a193e..ca3d62c3613 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -27,6 +27,7 @@
#include "util/u_rect.h"
#include "lp_context.h"
+#include "lp_flush.h"
#include "lp_surface.h"
@@ -36,6 +37,20 @@ lp_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
+ llvmpipe_flush_texture(pipe,
+ dest->texture, dest->face, dest->level,
+ 0, /* flush_flags */
+ FALSE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_flush */
+
+ llvmpipe_flush_texture(pipe,
+ src->texture, src->face, src->level,
+ 0, /* flush_flags */
+ TRUE, /* read_only */
+ FALSE, /* cpu_access */
+ FALSE); /* do_not_flush */
+
util_surface_copy(pipe, FALSE,
dest, destx, desty,
src, srcx, srcy,
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
index a9b99945f92..338a04a4878 100644
--- a/src/gallium/drivers/llvmpipe/lp_test.h
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -41,7 +41,7 @@
#include <stdio.h>
#include <float.h>
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index d05157991bb..fb595893bd0 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
#include <llvm-c/Analysis.h>
#include <llvm-c/ExecutionEngine.h>
#include <llvm-c/Target.h>
diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c
new file mode 100644
index 00000000000..e5e5925012a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_printf.h"
+
+#include <llvm-c/Analysis.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/Transforms/Scalar.h>
+
+#include "lp_test.h"
+
+
+struct printf_test_case {
+};
+
+void
+write_tsv_header(FILE *fp)
+{
+ fprintf(fp,
+ "result\t"
+ "format\n");
+
+ fflush(fp);
+}
+
+
+
+typedef void (*test_printf_t)(int i);
+
+static LLVMValueRef
+add_printf_test(LLVMModuleRef module)
+{
+ LLVMTypeRef args[1] = { LLVMIntType(32) };
+ LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidType(), args, 1, 0));
+ LLVMBuilderRef builder = LLVMCreateBuilder();
+ LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
+
+ LLVMSetFunctionCallConv(func, LLVMCCallConv);
+
+ LLVMPositionBuilderAtEnd(builder, block);
+ lp_build_printf(builder, "hello, world\n");
+ lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0),
+ LLVMConstInt(LLVMInt32Type(), 6, 0));
+ LLVMBuildRetVoid(builder);
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+PIPE_ALIGN_STACK
+static boolean
+test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase)
+{
+ LLVMModuleRef module = NULL;
+ LLVMValueRef test = NULL;
+ LLVMExecutionEngineRef engine = NULL;
+ LLVMModuleProviderRef provider = NULL;
+ LLVMPassManagerRef pass = NULL;
+ char *error = NULL;
+ test_printf_t test_printf;
+ float unpacked[4];
+ unsigned packed;
+ boolean success = TRUE;
+
+ module = LLVMModuleCreateWithName("test");
+
+ test = add_printf_test(module);
+
+ if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+ LLVMDumpModule(module);
+ abort();
+ }
+ LLVMDisposeMessage(error);
+
+ provider = LLVMCreateModuleProviderForExistingModule(module);
+ if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+ fprintf(stderr, "%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+#if 0
+ pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMAddPromoteMemoryToRegisterPass(pass);
+ LLVMAddGVNPass(pass);
+ LLVMAddCFGSimplificationPass(pass);
+ LLVMRunPassManager(pass, module);
+#else
+ (void)pass;
+#endif
+
+ test_printf = (test_printf_t)LLVMGetPointerToGlobal(engine, test);
+
+ memset(unpacked, 0, sizeof unpacked);
+ packed = 0;
+
+
+ // LLVMDumpModule(module);
+
+ test_printf(0);
+
+ LLVMFreeMachineCodeForFunction(engine, test);
+
+ LLVMDisposeExecutionEngine(engine);
+ if(pass)
+ LLVMDisposePassManager(pass);
+
+ return success;
+}
+
+
+boolean
+test_all(unsigned verbose, FILE *fp)
+{
+ bool success = TRUE;
+
+ test_printf(verbose, fp, NULL);
+
+ return success;
+}
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n)
+{
+ return test_all(verbose, fp);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
index cb59a94464a..1228a831f3b 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.h
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
@@ -29,7 +29,7 @@
#define LP_TEX_SAMPLE_H
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
struct lp_sampler_static_state;
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 632462460a3..4715cfe4f62 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -51,10 +51,11 @@
/**
- * This provides the bridge between the sampler state store in lp_jit_context
- * and lp_jit_texture and the sampler code generator. It provides the
- * texture layout information required by the texture sampler code generator
- * in terms of the state stored in lp_jit_context and lp_jit_texture in runtime.
+ * This provides the bridge between the sampler state store in
+ * lp_jit_context and lp_jit_texture and the sampler code
+ * generator. It provides the texture layout information required by
+ * the texture sampler code generator in terms of the state stored in
+ * lp_jit_context and lp_jit_texture in runtime.
*/
struct llvmpipe_sampler_dynamic_state
{
@@ -79,6 +80,9 @@ struct lp_llvm_sampler_soa
/**
* Fetch the specified member of the lp_jit_texture structure.
+ * \param emit_load if TRUE, emit the LLVM load instruction to actually
+ * fetch the field's value. Otherwise, just emit the
+ * GEP code to address the field.
*
* @sa http://llvm.org/docs/GetElementPtr.html
*/
@@ -87,9 +91,11 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
LLVMBuilderRef builder,
unsigned unit,
unsigned member_index,
- const char *member_name)
+ const char *member_name,
+ boolean emit_load)
{
- struct llvmpipe_sampler_dynamic_state *state = (struct llvmpipe_sampler_dynamic_state *)base;
+ struct llvmpipe_sampler_dynamic_state *state =
+ (struct llvmpipe_sampler_dynamic_state *)base;
LLVMValueRef indices[4];
LLVMValueRef ptr;
LLVMValueRef res;
@@ -99,7 +105,7 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
/* context[0] */
indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
/* context[0].textures */
- indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CONTEXT_TEXTURES_INDEX, 0);
+ indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CTX_TEXTURES, 0);
/* context[0].textures[unit] */
indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
/* context[0].textures[unit].member */
@@ -107,7 +113,10 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
- res = LLVMBuildLoad(builder, ptr, "");
+ if (emit_load)
+ res = LLVMBuildLoad(builder, ptr, "");
+ else
+ res = ptr;
lp_build_name(res, "context.texture%u.%s", unit, member_name);
@@ -116,28 +125,30 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
/**
- * Helper macro to instantiate the functions that generate the code to fetch
- * the members of lp_jit_texture to fulfill the sampler code generator requests.
+ * Helper macro to instantiate the functions that generate the code to
+ * fetch the members of lp_jit_texture to fulfill the sampler code
+ * generator requests.
*
- * This complexity is the price we have to pay to keep the texture sampler code
- * generator a reusable module without dependencies to llvmpipe internals.
+ * This complexity is the price we have to pay to keep the texture
+ * sampler code generator a reusable module without dependencies to
+ * llvmpipe internals.
*/
-#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
LLVMBuilderRef builder, \
unsigned unit) \
{ \
- return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+ return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
}
-LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
-LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
-LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH)
-LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL)
-LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
-LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
+LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
+LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
+LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
+LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
static void
@@ -193,7 +204,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->dynamic_state.base.height = lp_llvm_texture_height;
sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
- sampler->dynamic_state.base.stride = lp_llvm_texture_stride;
+ sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
sampler->dynamic_state.static_state = static_state;
sampler->dynamic_state.context_ptr = context_ptr;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 7f456355428..8137f29af52 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -40,9 +40,10 @@
#include "lp_context.h"
#include "lp_screen.h"
+#include "lp_flush.h"
#include "lp_texture.h"
#include "lp_tile_size.h"
-#include "lp_winsys.h"
+#include "state_tracker/sw_winsys.h"
/**
@@ -93,7 +94,7 @@ static boolean
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
struct llvmpipe_texture *lpt)
{
- struct llvmpipe_winsys *winsys = screen->winsys;
+ struct sw_winsys *winsys = screen->winsys;
/* Round up the surface size to a multiple of the tile size to
* avoid tile clipping.
@@ -102,6 +103,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
unsigned height = align(lpt->base.height0, TILE_SIZE);
lpt->dt = winsys->displaytarget_create(winsys,
+ lpt->base.tex_usage,
lpt->base.format,
width, height,
16,
@@ -125,7 +127,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
lpt->base.screen = &screen->base;
if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!llvmpipe_displaytarget_layout(screen, lpt))
goto fail;
}
@@ -142,60 +145,154 @@ llvmpipe_texture_create(struct pipe_screen *_screen,
}
-static struct pipe_texture *
-llvmpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static void
+llvmpipe_texture_destroy(struct pipe_texture *pt)
{
- /* FIXME */
-#if 0
- struct llvmpipe_texture *lpt;
- assert(screen);
+ struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen);
+ struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
+ if (lpt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = screen->winsys;
+ winsys->displaytarget_destroy(winsys, lpt->dt);
+ }
+ else {
+ /* regular texture */
+ align_free(lpt->data);
+ }
+
+ FREE(lpt);
+}
+
+
+/**
+ * Map a texture. Without any synchronization.
+ */
+void *
+llvmpipe_texture_map(struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+ uint8_t *map;
+
+ if (lpt->dt) {
+ /* display target */
+ struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen);
+ struct sw_winsys *winsys = screen->winsys;
+ const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+
+ assert(face == 0);
+ assert(level == 0);
+ assert(zslice == 0);
+
+ /* FIXME: keep map count? */
+ map = winsys->displaytarget_map(winsys, lpt->dt, usage);
}
+ else {
+ /* regular texture */
+ unsigned offset;
+ unsigned stride;
+
+ map = lpt->data;
+
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+
+ offset = lpt->level_offset[level];
+ stride = lpt->stride[level];
+
+ /* XXX shouldn't that rather be
+ tex_height = align(u_minify(texture->height0, level), 2)
+ to account for alignment done in llvmpipe_texture_layout ?
+ */
+ if (texture->target == PIPE_TEXTURE_CUBE) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += face * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else if (texture->target == PIPE_TEXTURE_3D) {
+ unsigned tex_height = u_minify(texture->height0, level);
+ offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ map += offset;
+ }
+
+ return map;
+}
+
+
+/**
+ * Unmap a texture. Without any synchronization.
+ */
+void
+llvmpipe_texture_unmap(struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+
+ if (lpt->dt) {
+ /* display target */
+ struct llvmpipe_screen *lp_screen = llvmpipe_screen(texture->screen);
+ struct sw_winsys *winsys = lp_screen->winsys;
+
+ assert(face == 0);
+ assert(level == 0);
+ assert(zslice == 0);
+
+ winsys->displaytarget_unmap(winsys, lpt->dt);
+ }
+}
- lpt = CALLOC_STRUCT(llvmpipe_texture);
+
+static struct pipe_texture *
+llvmpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
+ struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
if (!lpt)
return NULL;
- lpt->base = *base;
+ lpt->base = *template;
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = screen;
- lpt->stride[0] = stride[0];
- pipe_buffer_reference(&lpt->buffer, buffer);
+ lpt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &lpt->stride[0]);
+ if (!lpt->dt)
+ goto fail;
return &lpt->base;
-#else
- debug_printf("llvmpipe_texture_blanket() not implemented!");
+
+ fail:
+ FREE(lpt);
return NULL;
-#endif
}
-static void
-llvmpipe_texture_destroy(struct pipe_texture *pt)
+static boolean
+llvmpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
{
- struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen);
+ struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
- if (lpt->dt) {
- /* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
- winsys->displaytarget_destroy(winsys, lpt->dt);
- }
- else {
- /* regular texture */
- align_free(lpt->data);
- }
+ assert(lpt->dt);
+ if (!lpt->dt)
+ return FALSE;
- FREE(lpt);
+ return winsys->displaytarget_get_handle(winsys, lpt->dt, whandle);
}
@@ -217,7 +314,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->format = pt->format;
ps->width = u_minify(pt->width0, level);
ps->height = u_minify(pt->height0, level);
- ps->offset = lpt->level_offset[level];
ps->usage = usage;
/* Because we are llvmpipe, anything that the state tracker
@@ -243,23 +339,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->face = face;
ps->level = level;
ps->zslice = zslice;
-
- /* XXX shouldn't that rather be
- tex_height = align(ps->height, 2);
- to account for alignment done in llvmpipe_texture_layout ?
- */
- if (pt->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = ps->height;
- ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else if (pt->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = ps->height;
- ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
}
return ps;
}
@@ -279,7 +358,7 @@ llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
static struct pipe_transfer *
-llvmpipe_get_tex_transfer(struct pipe_screen *screen,
+llvmpipe_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -305,24 +384,6 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
pt->level = level;
pt->zslice = zslice;
- lpt->offset = lptex->level_offset[level];
-
- /* XXX shouldn't that rather be
- tex_height = align(u_minify(texture->height0, level), 2)
- to account for alignment done in llvmpipe_texture_layout ?
- */
- if (texture->target == PIPE_TEXTURE_CUBE) {
- unsigned tex_height = u_minify(texture->height0, level);
- lpt->offset += face * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
- }
- else if (texture->target == PIPE_TEXTURE_3D) {
- unsigned tex_height = u_minify(texture->height0, level);
- lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
- }
- else {
- assert(face == 0);
- assert(zslice == 0);
- }
return pt;
}
return NULL;
@@ -330,7 +391,8 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
static void
-llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
+llvmpipe_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
@@ -343,11 +405,11 @@ llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
static void *
-llvmpipe_transfer_map( struct pipe_screen *_screen,
+llvmpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
- struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
- ubyte *map, *xfer_map;
+ struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
+ ubyte *map;
struct llvmpipe_texture *lpt;
enum pipe_format format;
@@ -355,52 +417,45 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
lpt = llvmpipe_texture(transfer->texture);
format = lpt->base.format;
- if (lpt->dt) {
- /* display target */
- struct llvmpipe_winsys *winsys = screen->winsys;
+ /*
+ * Transfers, like other pipe operations, must happen in order, so flush the
+ * context if necessary.
+ */
+ llvmpipe_flush_texture(pipe,
+ transfer->texture, transfer->face, transfer->level,
+ 0, /* flush_flags */
+ !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
+ TRUE, /* cpu_access */
+ FALSE); /* do_not_flush */
- map = winsys->displaytarget_map(winsys, lpt->dt,
- pipe_transfer_buffer_flags(transfer));
- if (map == NULL)
- return NULL;
- }
- else {
- /* regular texture */
- map = lpt->data;
- }
+ map = llvmpipe_texture_map(transfer->texture,
+ transfer->face, transfer->level, transfer->zslice);
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
/* Do something to notify sharing contexts of a texture change.
*/
screen->timestamp++;
}
- xfer_map = map + llvmpipe_transfer(transfer)->offset +
+ map +=
transfer->y / util_format_get_blockheight(format) * transfer->stride +
transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
- /*printf("map = %p xfer map = %p\n", map, xfer_map);*/
- return xfer_map;
+
+ return map;
}
static void
-llvmpipe_transfer_unmap(struct pipe_screen *screen,
- struct pipe_transfer *transfer)
+llvmpipe_transfer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
- struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen);
- struct llvmpipe_texture *lpt;
-
assert(transfer->texture);
- lpt = llvmpipe_texture(transfer->texture);
- if (lpt->dt) {
- /* display target */
- struct llvmpipe_winsys *winsys = lp_screen->winsys;
- winsys->displaytarget_unmap(winsys, lpt->dt);
- }
+ llvmpipe_texture_unmap(transfer->texture,
+ transfer->face, transfer->level, transfer->zslice);
}
@@ -408,14 +463,20 @@ void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = llvmpipe_texture_create;
- screen->texture_blanket = llvmpipe_texture_blanket;
screen->texture_destroy = llvmpipe_texture_destroy;
+ screen->texture_from_handle = llvmpipe_texture_from_handle;
+ screen->texture_get_handle = llvmpipe_texture_get_handle;
screen->get_tex_surface = llvmpipe_get_tex_surface;
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
+}
+
- screen->get_tex_transfer = llvmpipe_get_tex_transfer;
- screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
- screen->transfer_map = llvmpipe_transfer_map;
- screen->transfer_unmap = llvmpipe_transfer_unmap;
+void
+llvmpipe_init_context_texture_funcs(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = llvmpipe_get_tex_transfer;
+ pipe->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
+ pipe->transfer_map = llvmpipe_transfer_map;
+ pipe->transfer_unmap = llvmpipe_transfer_unmap;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 87c905bc027..2350c26e4fc 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -32,24 +32,29 @@
#include "pipe/p_state.h"
+#define LP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K for now */
+#define LP_MAX_TEXTURE_3D_LEVELS 10 /* 512 x 512 x 512 for now */
+
+
struct pipe_context;
struct pipe_screen;
struct llvmpipe_context;
-struct llvmpipe_displaytarget;
+
+struct sw_displaytarget;
struct llvmpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[LP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[LP_MAX_TEXTURE_2D_LEVELS];
/**
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
* usage.
*/
- struct llvmpipe_displaytarget *dt;
+ struct sw_displaytarget *dt;
/**
* Malloc'ed data for regular textures, or a mapping to dt above.
@@ -90,8 +95,32 @@ llvmpipe_transfer(struct pipe_transfer *pt)
}
+static INLINE unsigned
+llvmpipe_texture_stride(struct pipe_texture *texture,
+ unsigned level)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+ return lpt->stride[level];
+}
+
+
+void *
+llvmpipe_texture_map(struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice);
+
+void
+llvmpipe_texture_unmap(struct pipe_texture *texture,
+ unsigned face,
+ unsigned level,
+ unsigned zslice);
+
extern void
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
+extern void
+llvmpipe_init_context_texture_funcs(struct pipe_context *pipe);
#endif /* LP_TEXTURE_H */
diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile
index 0e02680bc63..0cb66041d50 100644
--- a/src/gallium/drivers/nouveau/Makefile
+++ b/src/gallium/drivers/nouveau/Makefile
@@ -4,7 +4,6 @@ include $(TOP)/configs/current
LIBNAME = nouveau
C_SOURCES = nouveau_screen.c \
- nouveau_context.c \
- nv04_surface_2d.c
+ nouveau_context.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 3c2f771b51e..b1ad686022a 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -4,6 +4,7 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_format.h"
#include <stdio.h>
#include <errno.h>
@@ -12,6 +13,9 @@
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
+/* XXX this should go away */
+#include "state_tracker/drm_api.h"
+
static const char *
nouveau_screen_get_name(struct pipe_screen *pscreen)
{
@@ -120,7 +124,7 @@ nouveau_screen_map_flags(unsigned pipe)
if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
flags |= NOUVEAU_BO_NOWAIT;
else
- if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
+ if (pipe & PIPE_BUFFER_USAGE_UNSYNCHRONIZED)
flags |= NOUVEAU_BO_NOSYNC;
return flags;
@@ -231,6 +235,72 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
return 0;
}
+
+/*
+ * Both texture_{from|get}_handle use drm api defines directly which they
+ * shouldn't do. The problem is that from|get are pipe functions and as
+ * such they should be defined in the pipe level. If nouveau had a propper
+ * winsys interface we would have added from|get to that interface using
+ * the winsys_handle struct as done with other drivers. However this code
+ * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
+ * we need to translate the handle into something they understand.
+ */
+static struct pipe_texture *
+nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct pipe_texture *pt;
+ struct pipe_buffer *pb;
+ int ret;
+
+ pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
+ if (!pb)
+ return NULL;
+
+ ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
+ if (ret) {
+ debug_printf("%s: ref name 0x%08x failed with %d\n",
+ __func__, whandle->handle, ret);
+ FREE(pb);
+ return NULL;
+ }
+
+ pipe_reference_init(&pb->reference, 1);
+ pb->screen = pscreen;
+ pb->alignment = 0;
+ pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ pb->size = nouveau_bo(pb)->size;
+ pt = nouveau_screen(pscreen)->texture_blanket(pscreen, templ,
+ &whandle->stride, pb);
+ pipe_buffer_reference(&pb, NULL);
+ return pt;
+}
+
+static boolean
+nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
+{
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
+
+ if (!mt || !mt->bo)
+ return false;
+
+ whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = mt->bo->handle;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -258,6 +328,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
pscreen->fence_signalled = nouveau_screen_fence_signalled;
pscreen->fence_finish = nouveau_screen_fence_finish;
+ pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
+ pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
+
return 0;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index a7927d88dfc..f4a7a2bc234 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -6,6 +6,18 @@ struct nouveau_screen {
struct nouveau_device *device;
struct nouveau_channel *channel;
+ /**
+ * Create a new texture object, using the given template info, but on top of
+ * existing memory.
+ *
+ * It is assumed that the buffer data is layed out according to the expected
+ * by the hardware. NULL will be returned if any inconsistency is found.
+ */
+ struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ const unsigned *stride,
+ struct pipe_buffer *buffer);
+
int (*pre_pipebuffer_map_callback) (struct pipe_screen *pscreen,
struct pipe_buffer *pb, unsigned usage);
};
diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h
index a10114beab9..ab7761a31da 100644
--- a/src/gallium/drivers/nouveau/nouveau_util.h
+++ b/src/gallium/drivers/nouveau/nouveau_util.h
@@ -33,7 +33,7 @@ nouveau_vbuf_split(unsigned remaining, unsigned overhead, unsigned vpp,
max = max - (max % 3);
break;
case PIPE_PRIM_QUADS:
- max = max & 3;
+ max = max & ~3;
break;
case PIPE_PRIM_LINE_LOOP:
case PIPE_PRIM_LINE_STRIP:
@@ -88,4 +88,104 @@ static INLINE unsigned log2i(unsigned i)
return r;
}
+struct u_split_prim {
+ void *priv;
+ void (*emit)(void *priv, unsigned start, unsigned count);
+ void (*edge)(void *priv, boolean enabled);
+
+ unsigned mode;
+ unsigned start;
+ unsigned p_start;
+ unsigned p_end;
+
+ int repeat_first:1;
+ int close_first:1;
+ int edgeflag_off:1;
+};
+
+static inline void
+u_split_prim_init(struct u_split_prim *s,
+ unsigned mode, unsigned start, unsigned count)
+{
+ if (mode == PIPE_PRIM_LINE_LOOP) {
+ s->mode = PIPE_PRIM_LINE_STRIP;
+ s->close_first = 1;
+ } else {
+ s->mode = mode;
+ s->close_first = 0;
+ }
+ s->start = start;
+ s->p_start = start;
+ s->p_end = start + count;
+ s->edgeflag_off = 0;
+ s->repeat_first = 0;
+}
+
+static INLINE boolean
+u_split_prim_next(struct u_split_prim *s, unsigned max_verts)
+{
+ int repeat = 0;
+
+ if (s->repeat_first) {
+ s->emit(s->priv, s->start, 1);
+ max_verts--;
+ if (s->edgeflag_off) {
+ s->edge(s->priv, TRUE);
+ s->edgeflag_off = FALSE;
+ }
+ }
+
+ if (s->p_start + s->close_first + max_verts >= s->p_end) {
+ s->emit(s->priv, s->p_start, s->p_end - s->p_start);
+ if (s->close_first)
+ s->emit(s->priv, s->start, 1);
+ return TRUE;
+ }
+
+ switch (s->mode) {
+ case PIPE_PRIM_LINES:
+ max_verts &= ~1;
+ break;
+ case PIPE_PRIM_LINE_STRIP:
+ repeat = 1;
+ break;
+ case PIPE_PRIM_POLYGON:
+ max_verts--;
+ s->emit(s->priv, s->p_start, max_verts);
+ s->edge(s->priv, FALSE);
+ s->emit(s->priv, s->p_start + max_verts, 1);
+ s->p_start += max_verts;
+ s->repeat_first = TRUE;
+ s->edgeflag_off = TRUE;
+ return FALSE;
+ case PIPE_PRIM_TRIANGLES:
+ max_verts = max_verts - (max_verts % 3);
+ break;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ /* to ensure winding stays correct, always split
+ * on an even number of generated triangles
+ */
+ max_verts = max_verts & ~1;
+ repeat = 2;
+ break;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ s->repeat_first = TRUE;
+ repeat = 1;
+ break;
+ case PIPE_PRIM_QUADS:
+ max_verts &= ~3;
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ max_verts &= ~1;
+ repeat = 2;
+ break;
+ default:
+ break;
+ }
+
+ s->emit (s->priv, s->p_start, max_verts);
+ s->p_start += (max_verts - repeat);
+ return FALSE;
+}
+
#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index af9ddd558c8..bed014b9ce0 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -27,10 +27,7 @@
#define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19)
extern struct pipe_screen *
-nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
-
-extern struct pipe_screen *
-nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
+nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_screen *
nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile
deleted file mode 100644
index 364c80d8f3e..00000000000
--- a/src/gallium/drivers/nv30/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = nv30
-
-C_SOURCES = \
- nv30_clear.c \
- nv30_context.c \
- nv30_draw.c \
- nv30_fragprog.c \
- nv30_fragtex.c \
- nv30_miptree.c \
- nv30_query.c \
- nv30_screen.c \
- nv30_state.c \
- nv30_state_blend.c \
- nv30_state_emit.c \
- nv30_state_fb.c \
- nv30_state_rasterizer.c \
- nv30_state_scissor.c \
- nv30_state_stipple.c \
- nv30_state_viewport.c \
- nv30_state_zsa.c \
- nv30_surface.c \
- nv30_transfer.c \
- nv30_vbo.c \
- nv30_vertprog.c
-
-include ../../Makefile.template
diff --git a/src/gallium/drivers/nv30/nv30_clear.c b/src/gallium/drivers/nv30/nv30_clear.c
deleted file mode 100644
index c4ba9266647..00000000000
--- a/src/gallium/drivers/nv30/nv30_clear.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "util/u_clear.h"
-
-#include "nv30_context.h"
-
-void
-nv30_clear(struct pipe_context *pipe, unsigned buffers,
- const float *rgba, double depth, unsigned stencil)
-{
- util_clear(pipe, &nv30_context(pipe)->framebuffer, buffers, rgba, depth,
- stencil);
-}
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
deleted file mode 100644
index 279b74445ca..00000000000
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "draw/draw_context.h"
-#include "pipe/p_defines.h"
-
-#include "nv30_context.h"
-#include "nv30_screen.h"
-
-static void
-nv30_flush(struct pipe_context *pipe, unsigned flags,
- struct pipe_fence_handle **fence)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_screen *screen = nv30->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- BEGIN_RING(chan, rankine, 0x1fd8, 1);
- OUT_RING (chan, 2);
- BEGIN_RING(chan, rankine, 0x1fd8, 1);
- OUT_RING (chan, 1);
- }
-
- FIRE_RING(chan);
- if (fence)
- *fence = NULL;
-}
-
-static void
-nv30_destroy(struct pipe_context *pipe)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- unsigned i;
-
- for (i = 0; i < NV30_STATE_MAX; i++) {
- if (nv30->state.hw[i])
- so_ref(NULL, &nv30->state.hw[i]);
- }
-
- if (nv30->draw)
- draw_destroy(nv30->draw);
- FREE(nv30);
-}
-
-struct pipe_context *
-nv30_create(struct pipe_screen *pscreen, void *priv)
-{
- struct nv30_screen *screen = nv30_screen(pscreen);
- struct pipe_winsys *ws = pscreen->winsys;
- struct nv30_context *nv30;
- struct nouveau_winsys *nvws = screen->nvws;
-
- nv30 = CALLOC(1, sizeof(struct nv30_context));
- if (!nv30)
- return NULL;
- nv30->screen = screen;
-
- nv30->nvws = nvws;
-
- nv30->pipe.winsys = ws;
- nv30->pipe.screen = pscreen;
- nv30->pipe.priv = priv;
- nv30->pipe.destroy = nv30_destroy;
- nv30->pipe.draw_arrays = nv30_draw_arrays;
- nv30->pipe.draw_elements = nv30_draw_elements;
- nv30->pipe.clear = nv30_clear;
- nv30->pipe.flush = nv30_flush;
-
- nv30->pipe.is_texture_referenced = nouveau_is_texture_referenced;
- nv30->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
-
- screen->base.channel->user_private = nv30;
- screen->base.channel->flush_notify = nv30_state_flush_notify;
-
- nv30_init_query_functions(nv30);
- nv30_init_surface_functions(nv30);
- nv30_init_state_functions(nv30);
-
- /* Create, configure, and install fallback swtnl path */
- nv30->draw = draw_create();
- draw_wide_point_threshold(nv30->draw, 9999999.0);
- draw_wide_line_threshold(nv30->draw, 9999999.0);
- draw_enable_line_stipple(nv30->draw, FALSE);
- draw_enable_point_sprites(nv30->draw, FALSE);
- draw_set_rasterize_stage(nv30->draw, nv30_draw_render_stage(nv30));
-
- return &nv30->pipe;
-}
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
deleted file mode 100644
index ea259aadf35..00000000000
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#ifndef __NV30_CONTEXT_H__
-#define __NV30_CONTEXT_H__
-
-#include <stdio.h>
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "pipe/p_compiler.h"
-
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "util/u_inlines.h"
-
-#include "draw/draw_vertex.h"
-
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau/nouveau_gldefs.h"
-#include "nouveau/nouveau_context.h"
-#include "nouveau/nouveau_stateobj.h"
-
-#include "nv30_state.h"
-
-#define NOUVEAU_ERR(fmt, args...) \
- fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
-#define NOUVEAU_MSG(fmt, args...) \
- fprintf(stderr, "nouveau: "fmt, ##args);
-
-enum nv30_state_index {
- NV30_STATE_FB = 0,
- NV30_STATE_VIEWPORT = 1,
- NV30_STATE_BLEND = 2,
- NV30_STATE_RAST = 3,
- NV30_STATE_ZSA = 4,
- NV30_STATE_BCOL = 5,
- NV30_STATE_CLIP = 6,
- NV30_STATE_SCISSOR = 7,
- NV30_STATE_STIPPLE = 8,
- NV30_STATE_FRAGPROG = 9,
- NV30_STATE_VERTPROG = 10,
- NV30_STATE_FRAGTEX0 = 11,
- NV30_STATE_FRAGTEX1 = 12,
- NV30_STATE_FRAGTEX2 = 13,
- NV30_STATE_FRAGTEX3 = 14,
- NV30_STATE_FRAGTEX4 = 15,
- NV30_STATE_FRAGTEX5 = 16,
- NV30_STATE_FRAGTEX6 = 17,
- NV30_STATE_FRAGTEX7 = 18,
- NV30_STATE_FRAGTEX8 = 19,
- NV30_STATE_FRAGTEX9 = 20,
- NV30_STATE_FRAGTEX10 = 21,
- NV30_STATE_FRAGTEX11 = 22,
- NV30_STATE_FRAGTEX12 = 23,
- NV30_STATE_FRAGTEX13 = 24,
- NV30_STATE_FRAGTEX14 = 25,
- NV30_STATE_FRAGTEX15 = 26,
- NV30_STATE_VERTTEX0 = 27,
- NV30_STATE_VERTTEX1 = 28,
- NV30_STATE_VERTTEX2 = 29,
- NV30_STATE_VERTTEX3 = 30,
- NV30_STATE_VTXBUF = 31,
- NV30_STATE_VTXFMT = 32,
- NV30_STATE_VTXATTR = 33,
- NV30_STATE_SR = 34,
- NV30_STATE_MAX = 35
-};
-
-#include "nv30_screen.h"
-
-#define NV30_NEW_BLEND (1 << 0)
-#define NV30_NEW_RAST (1 << 1)
-#define NV30_NEW_ZSA (1 << 2)
-#define NV30_NEW_SAMPLER (1 << 3)
-#define NV30_NEW_FB (1 << 4)
-#define NV30_NEW_STIPPLE (1 << 5)
-#define NV30_NEW_SCISSOR (1 << 6)
-#define NV30_NEW_VIEWPORT (1 << 7)
-#define NV30_NEW_BCOL (1 << 8)
-#define NV30_NEW_VERTPROG (1 << 9)
-#define NV30_NEW_FRAGPROG (1 << 10)
-#define NV30_NEW_ARRAYS (1 << 11)
-#define NV30_NEW_UCP (1 << 12)
-#define NV30_NEW_SR (1 << 13)
-
-struct nv30_rasterizer_state {
- struct pipe_rasterizer_state pipe;
- struct nouveau_stateobj *so;
-};
-
-struct nv30_zsa_state {
- struct pipe_depth_stencil_alpha_state pipe;
- struct nouveau_stateobj *so;
-};
-
-struct nv30_blend_state {
- struct pipe_blend_state pipe;
- struct nouveau_stateobj *so;
-};
-
-
-struct nv30_state {
- unsigned scissor_enabled;
- unsigned stipple_enabled;
- unsigned fp_samplers;
-
- uint64_t dirty;
- struct nouveau_stateobj *hw[NV30_STATE_MAX];
-};
-
-struct nv30_context {
- struct pipe_context pipe;
-
- struct nouveau_winsys *nvws;
- struct nv30_screen *screen;
-
- struct draw_context *draw;
-
- /* HW state derived from pipe states */
- struct nv30_state state;
-
- /* Context state */
- unsigned dirty;
- struct pipe_scissor_state scissor;
- unsigned stipple[32];
- struct nv30_vertex_program *vertprog;
- struct nv30_fragment_program *fragprog;
- struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
- unsigned constbuf_nr[PIPE_SHADER_TYPES];
- struct nv30_rasterizer_state *rasterizer;
- struct nv30_zsa_state *zsa;
- struct nv30_blend_state *blend;
- struct pipe_blend_color blend_colour;
- struct pipe_stencil_ref stencil_ref;
- struct pipe_viewport_state viewport;
- struct pipe_framebuffer_state framebuffer;
- struct pipe_buffer *idxbuf;
- unsigned idxbuf_format;
- struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
- struct nv30_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
- unsigned nr_samplers;
- unsigned nr_textures;
- unsigned dirty_samplers;
- struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
- unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
-};
-
-static INLINE struct nv30_context *
-nv30_context(struct pipe_context *pipe)
-{
- return (struct nv30_context *)pipe;
-}
-
-struct nv30_state_entry {
- boolean (*validate)(struct nv30_context *nv30);
- struct {
- unsigned pipe;
- unsigned hw;
- } dirty;
-};
-
-extern void nv30_init_state_functions(struct nv30_context *nv30);
-extern void nv30_init_surface_functions(struct nv30_context *nv30);
-extern void nv30_init_query_functions(struct nv30_context *nv30);
-
-extern void nv30_screen_init_miptree_functions(struct pipe_screen *pscreen);
-
-/* nv30_draw.c */
-extern struct draw_stage *nv30_draw_render_stage(struct nv30_context *nv30);
-
-/* nv30_vertprog.c */
-extern void nv30_vertprog_destroy(struct nv30_context *,
- struct nv30_vertex_program *);
-
-/* nv30_fragprog.c */
-extern void nv30_fragprog_destroy(struct nv30_context *,
- struct nv30_fragment_program *);
-
-/* nv30_fragtex.c */
-extern void nv30_fragtex_bind(struct nv30_context *);
-
-/* nv30_state.c and friends */
-extern boolean nv30_state_validate(struct nv30_context *nv30);
-extern void nv30_state_emit(struct nv30_context *nv30);
-extern void nv30_state_flush_notify(struct nouveau_channel *chan);
-extern struct nv30_state_entry nv30_state_rasterizer;
-extern struct nv30_state_entry nv30_state_scissor;
-extern struct nv30_state_entry nv30_state_stipple;
-extern struct nv30_state_entry nv30_state_fragprog;
-extern struct nv30_state_entry nv30_state_vertprog;
-extern struct nv30_state_entry nv30_state_blend;
-extern struct nv30_state_entry nv30_state_blend_colour;
-extern struct nv30_state_entry nv30_state_zsa;
-extern struct nv30_state_entry nv30_state_viewport;
-extern struct nv30_state_entry nv30_state_framebuffer;
-extern struct nv30_state_entry nv30_state_fragtex;
-extern struct nv30_state_entry nv30_state_vbo;
-extern struct nv30_state_entry nv30_state_sr;
-
-/* nv30_vbo.c */
-extern void nv30_draw_arrays(struct pipe_context *, unsigned mode,
- unsigned start, unsigned count);
-extern void nv30_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned mode, unsigned start,
- unsigned count);
-
-/* nv30_clear.c */
-extern void nv30_clear(struct pipe_context *pipe, unsigned buffers,
- const float *rgba, double depth, unsigned stencil);
-
-/* nv30_context.c */
-struct pipe_context *
-nv30_create(struct pipe_screen *pscreen, void *priv);
-
-#endif
diff --git a/src/gallium/drivers/nv30/nv30_draw.c b/src/gallium/drivers/nv30/nv30_draw.c
deleted file mode 100644
index 74fc138c051..00000000000
--- a/src/gallium/drivers/nv30/nv30_draw.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "draw/draw_pipe.h"
-
-#include "nv30_context.h"
-
-struct nv30_draw_stage {
- struct draw_stage draw;
- struct nv30_context *nv30;
-};
-
-static void
-nv30_draw_point(struct draw_stage *draw, struct prim_header *prim)
-{
- NOUVEAU_ERR("\n");
-}
-
-static void
-nv30_draw_line(struct draw_stage *draw, struct prim_header *prim)
-{
- NOUVEAU_ERR("\n");
-}
-
-static void
-nv30_draw_tri(struct draw_stage *draw, struct prim_header *prim)
-{
- NOUVEAU_ERR("\n");
-}
-
-static void
-nv30_draw_flush(struct draw_stage *draw, unsigned flags)
-{
-}
-
-static void
-nv30_draw_reset_stipple_counter(struct draw_stage *draw)
-{
- NOUVEAU_ERR("\n");
-}
-
-static void
-nv30_draw_destroy(struct draw_stage *draw)
-{
- FREE(draw);
-}
-
-struct draw_stage *
-nv30_draw_render_stage(struct nv30_context *nv30)
-{
- struct nv30_draw_stage *nv30draw = CALLOC_STRUCT(nv30_draw_stage);
-
- nv30draw->nv30 = nv30;
- nv30draw->draw.draw = nv30->draw;
- nv30draw->draw.point = nv30_draw_point;
- nv30draw->draw.line = nv30_draw_line;
- nv30draw->draw.tri = nv30_draw_tri;
- nv30draw->draw.flush = nv30_draw_flush;
- nv30draw->draw.reset_stipple_counter = nv30_draw_reset_stipple_counter;
- nv30draw->draw.destroy = nv30_draw_destroy;
-
- return &nv30draw->draw;
-}
-
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
deleted file mode 100644
index 2c432c6dfa7..00000000000
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ /dev/null
@@ -1,905 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_util.h"
-
-#include "nv30_context.h"
-
-#define SWZ_X 0
-#define SWZ_Y 1
-#define SWZ_Z 2
-#define SWZ_W 3
-#define MASK_X 1
-#define MASK_Y 2
-#define MASK_Z 4
-#define MASK_W 8
-#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W)
-#define DEF_SCALE NV30_FP_OP_DST_SCALE_1X
-#define DEF_CTEST NV30_FP_OP_COND_TR
-#include "nv30_shader.h"
-
-#define swz(s,x,y,z,w) nv30_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w)
-#define neg(s) nv30_sr_neg((s))
-#define abs(s) nv30_sr_abs((s))
-#define scale(s,v) nv30_sr_scale((s), NV30_FP_OP_DST_SCALE_##v)
-
-#define MAX_CONSTS 128
-#define MAX_IMM 32
-struct nv30_fpc {
- struct nv30_fragment_program *fp;
-
- uint attrib_map[PIPE_MAX_SHADER_INPUTS];
-
- int high_temp;
- int temp_temp_count;
- int num_regs;
-
- uint depth_id;
- uint colour_id;
-
- unsigned inst_offset;
-
- struct {
- int pipe;
- float vals[4];
- } consts[MAX_CONSTS];
- int nr_consts;
-
- struct nv30_sreg imm[MAX_IMM];
- unsigned nr_imm;
-};
-
-static INLINE struct nv30_sreg
-temp(struct nv30_fpc *fpc)
-{
- int idx;
-
- idx = fpc->temp_temp_count++;
- idx += fpc->high_temp + 1;
- return nv30_sr(NV30SR_TEMP, idx);
-}
-
-static INLINE struct nv30_sreg
-constant(struct nv30_fpc *fpc, int pipe, float vals[4])
-{
- int idx;
-
- if (fpc->nr_consts == MAX_CONSTS)
- assert(0);
- idx = fpc->nr_consts++;
-
- fpc->consts[idx].pipe = pipe;
- if (pipe == -1)
- memcpy(fpc->consts[idx].vals, vals, 4 * sizeof(float));
- return nv30_sr(NV30SR_CONST, idx);
-}
-
-#define arith(cc,s,o,d,m,s0,s1,s2) \
- nv30_fp_arith((cc), (s), NV30_FP_OP_OPCODE_##o, \
- (d), (m), (s0), (s1), (s2))
-#define tex(cc,s,o,u,d,m,s0,s1,s2) \
- nv30_fp_tex((cc), (s), NV30_FP_OP_OPCODE_##o, (u), \
- (d), (m), (s0), none, none)
-
-static void
-grow_insns(struct nv30_fpc *fpc, int size)
-{
- struct nv30_fragment_program *fp = fpc->fp;
-
- fp->insn_len += size;
- fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len);
-}
-
-static void
-emit_src(struct nv30_fpc *fpc, int pos, struct nv30_sreg src)
-{
- struct nv30_fragment_program *fp = fpc->fp;
- uint32_t *hw = &fp->insn[fpc->inst_offset];
- uint32_t sr = 0;
-
- switch (src.type) {
- case NV30SR_INPUT:
- sr |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
- hw[0] |= (src.index << NV30_FP_OP_INPUT_SRC_SHIFT);
- break;
- case NV30SR_OUTPUT:
- sr |= NV30_FP_REG_SRC_HALF;
- /* fall-through */
- case NV30SR_TEMP:
- sr |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT);
- sr |= (src.index << NV30_FP_REG_SRC_SHIFT);
- break;
- case NV30SR_CONST:
- grow_insns(fpc, 4);
- hw = &fp->insn[fpc->inst_offset];
- if (fpc->consts[src.index].pipe >= 0) {
- struct nv30_fragment_program_data *fpd;
-
- fp->consts = realloc(fp->consts, ++fp->nr_consts *
- sizeof(*fpd));
- fpd = &fp->consts[fp->nr_consts - 1];
- fpd->offset = fpc->inst_offset + 4;
- fpd->index = fpc->consts[src.index].pipe;
- memset(&fp->insn[fpd->offset], 0, sizeof(uint32_t) * 4);
- } else {
- memcpy(&fp->insn[fpc->inst_offset + 4],
- fpc->consts[src.index].vals,
- sizeof(uint32_t) * 4);
- }
-
- sr |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
- break;
- case NV30SR_NONE:
- sr |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
- break;
- default:
- assert(0);
- }
-
- if (src.negate)
- sr |= NV30_FP_REG_NEGATE;
-
- if (src.abs)
- hw[1] |= (1 << (29 + pos));
-
- sr |= ((src.swz[0] << NV30_FP_REG_SWZ_X_SHIFT) |
- (src.swz[1] << NV30_FP_REG_SWZ_Y_SHIFT) |
- (src.swz[2] << NV30_FP_REG_SWZ_Z_SHIFT) |
- (src.swz[3] << NV30_FP_REG_SWZ_W_SHIFT));
-
- hw[pos + 1] |= sr;
-}
-
-static void
-emit_dst(struct nv30_fpc *fpc, struct nv30_sreg dst)
-{
- struct nv30_fragment_program *fp = fpc->fp;
- uint32_t *hw = &fp->insn[fpc->inst_offset];
-
- switch (dst.type) {
- case NV30SR_TEMP:
- if (fpc->num_regs < (dst.index + 1))
- fpc->num_regs = dst.index + 1;
- break;
- case NV30SR_OUTPUT:
- if (dst.index == 1) {
- fp->fp_control |= 0xe;
- } else {
- hw[0] |= NV30_FP_OP_OUT_REG_HALF;
- }
- break;
- case NV30SR_NONE:
- hw[0] |= (1 << 30);
- break;
- default:
- assert(0);
- }
-
- hw[0] |= (dst.index << NV30_FP_OP_OUT_REG_SHIFT);
-}
-
-static void
-nv30_fp_arith(struct nv30_fpc *fpc, int sat, int op,
- struct nv30_sreg dst, int mask,
- struct nv30_sreg s0, struct nv30_sreg s1, struct nv30_sreg s2)
-{
- struct nv30_fragment_program *fp = fpc->fp;
- uint32_t *hw;
-
- fpc->inst_offset = fp->insn_len;
- grow_insns(fpc, 4);
- hw = &fp->insn[fpc->inst_offset];
- memset(hw, 0, sizeof(uint32_t) * 4);
-
- if (op == NV30_FP_OP_OPCODE_KIL)
- fp->fp_control |= NV34TCL_FP_CONTROL_USES_KIL;
- hw[0] |= (op << NV30_FP_OP_OPCODE_SHIFT);
- hw[0] |= (mask << NV30_FP_OP_OUTMASK_SHIFT);
- hw[2] |= (dst.dst_scale << NV30_FP_OP_DST_SCALE_SHIFT);
-
- if (sat)
- hw[0] |= NV30_FP_OP_OUT_SAT;
-
- if (dst.cc_update)
- hw[0] |= NV30_FP_OP_COND_WRITE_ENABLE;
- hw[1] |= (dst.cc_test << NV30_FP_OP_COND_SHIFT);
- hw[1] |= ((dst.cc_swz[0] << NV30_FP_OP_COND_SWZ_X_SHIFT) |
- (dst.cc_swz[1] << NV30_FP_OP_COND_SWZ_Y_SHIFT) |
- (dst.cc_swz[2] << NV30_FP_OP_COND_SWZ_Z_SHIFT) |
- (dst.cc_swz[3] << NV30_FP_OP_COND_SWZ_W_SHIFT));
-
- emit_dst(fpc, dst);
- emit_src(fpc, 0, s0);
- emit_src(fpc, 1, s1);
- emit_src(fpc, 2, s2);
-}
-
-static void
-nv30_fp_tex(struct nv30_fpc *fpc, int sat, int op, int unit,
- struct nv30_sreg dst, int mask,
- struct nv30_sreg s0, struct nv30_sreg s1, struct nv30_sreg s2)
-{
- struct nv30_fragment_program *fp = fpc->fp;
-
- nv30_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2);
-
- fp->insn[fpc->inst_offset] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT);
- fp->samplers |= (1 << unit);
-}
-
-static INLINE struct nv30_sreg
-tgsi_src(struct nv30_fpc *fpc, const struct tgsi_full_src_register *fsrc)
-{
- struct nv30_sreg src;
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
- src = nv30_sr(NV30SR_INPUT,
- fpc->attrib_map[fsrc->Register.Index]);
- break;
- case TGSI_FILE_CONSTANT:
- src = constant(fpc, fsrc->Register.Index, NULL);
- break;
- case TGSI_FILE_IMMEDIATE:
- assert(fsrc->Register.Index < fpc->nr_imm);
- src = fpc->imm[fsrc->Register.Index];
- break;
- case TGSI_FILE_TEMPORARY:
- src = nv30_sr(NV30SR_TEMP, fsrc->Register.Index + 1);
- if (fpc->high_temp < src.index)
- fpc->high_temp = src.index;
- break;
- /* This is clearly insane, but gallium hands us shaders like this.
- * Luckily fragprog results are just temp regs..
- */
- case TGSI_FILE_OUTPUT:
- if (fsrc->Register.Index == fpc->colour_id)
- return nv30_sr(NV30SR_OUTPUT, 0);
- else
- return nv30_sr(NV30SR_OUTPUT, 1);
- break;
- default:
- NOUVEAU_ERR("bad src file\n");
- break;
- }
-
- src.abs = fsrc->Register.Absolute;
- src.negate = fsrc->Register.Negate;
- src.swz[0] = fsrc->Register.SwizzleX;
- src.swz[1] = fsrc->Register.SwizzleY;
- src.swz[2] = fsrc->Register.SwizzleZ;
- src.swz[3] = fsrc->Register.SwizzleW;
- return src;
-}
-
-static INLINE struct nv30_sreg
-tgsi_dst(struct nv30_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
- int idx;
-
- switch (fdst->Register.File) {
- case TGSI_FILE_OUTPUT:
- if (fdst->Register.Index == fpc->colour_id)
- return nv30_sr(NV30SR_OUTPUT, 0);
- else
- return nv30_sr(NV30SR_OUTPUT, 1);
- break;
- case TGSI_FILE_TEMPORARY:
- idx = fdst->Register.Index + 1;
- if (fpc->high_temp < idx)
- fpc->high_temp = idx;
- return nv30_sr(NV30SR_TEMP, idx);
- case TGSI_FILE_NULL:
- return nv30_sr(NV30SR_NONE, 0);
- default:
- NOUVEAU_ERR("bad dst file %d\n", fdst->Register.File);
- return nv30_sr(NV30SR_NONE, 0);
- }
-}
-
-static INLINE int
-tgsi_mask(uint tgsi)
-{
- int mask = 0;
-
- if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X;
- if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y;
- if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z;
- if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W;
- return mask;
-}
-
-static boolean
-src_native_swz(struct nv30_fpc *fpc, const struct tgsi_full_src_register *fsrc,
- struct nv30_sreg *src)
-{
- const struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0);
- struct nv30_sreg tgsi = tgsi_src(fpc, fsrc);
- uint mask = 0;
- uint c;
-
- for (c = 0; c < 4; c++) {
- switch (tgsi_util_get_full_src_register_swizzle(fsrc, c)) {
- case TGSI_SWIZZLE_X:
- case TGSI_SWIZZLE_Y:
- case TGSI_SWIZZLE_Z:
- case TGSI_SWIZZLE_W:
- mask |= (1 << c);
- break;
- default:
- assert(0);
- }
- }
-
- if (mask == MASK_ALL)
- return TRUE;
-
- *src = temp(fpc);
-
- if (mask)
- arith(fpc, 0, MOV, *src, mask, tgsi, none, none);
-
- return FALSE;
-}
-
-static boolean
-nv30_fragprog_parse_instruction(struct nv30_fpc *fpc,
- const struct tgsi_full_instruction *finst)
-{
- const struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0);
- struct nv30_sreg src[3], dst, tmp;
- int mask, sat, unit = 0;
- int ai = -1, ci = -1;
- int i;
-
- if (finst->Instruction.Opcode == TGSI_OPCODE_END)
- return TRUE;
-
- fpc->temp_temp_count = 0;
- for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *fsrc;
-
- fsrc = &finst->Src[i];
- if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
- src[i] = tgsi_src(fpc, fsrc);
- }
- }
-
- for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *fsrc;
-
- fsrc = &finst->Src[i];
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_TEMPORARY:
- if (!src_native_swz(fpc, fsrc, &src[i]))
- continue;
- break;
- default:
- break;
- }
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
- if (ai == -1 || ai == fsrc->Register.Index) {
- ai = fsrc->Register.Index;
- src[i] = tgsi_src(fpc, fsrc);
- } else {
- NOUVEAU_MSG("extra src attr %d\n",
- fsrc->Register.Index);
- src[i] = temp(fpc);
- arith(fpc, 0, MOV, src[i], MASK_ALL,
- tgsi_src(fpc, fsrc), none, none);
- }
- break;
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_IMMEDIATE:
- if (ci == -1 || ci == fsrc->Register.Index) {
- ci = fsrc->Register.Index;
- src[i] = tgsi_src(fpc, fsrc);
- } else {
- src[i] = temp(fpc);
- arith(fpc, 0, MOV, src[i], MASK_ALL,
- tgsi_src(fpc, fsrc), none, none);
- }
- break;
- case TGSI_FILE_TEMPORARY:
- /* handled above */
- break;
- case TGSI_FILE_SAMPLER:
- unit = fsrc->Register.Index;
- break;
- case TGSI_FILE_OUTPUT:
- break;
- default:
- NOUVEAU_ERR("bad src file\n");
- return FALSE;
- }
- }
-
- dst = tgsi_dst(fpc, &finst->Dst[0]);
- mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
- sat = (finst->Instruction.Saturate == TGSI_SAT_ZERO_ONE);
-
- switch (finst->Instruction.Opcode) {
- case TGSI_OPCODE_ABS:
- arith(fpc, sat, MOV, dst, mask, abs(src[0]), none, none);
- break;
- case TGSI_OPCODE_ADD:
- arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_CMP:
- tmp = nv30_sr(NV30SR_NONE, 0);
- tmp.cc_update = 1;
- arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
- dst.cc_test = NV30_VP_INST_COND_GE;
- arith(fpc, sat, MOV, dst, mask, src[2], none, none);
- dst.cc_test = NV30_VP_INST_COND_LT;
- arith(fpc, sat, MOV, dst, mask, src[1], none, none);
- break;
- case TGSI_OPCODE_COS:
- arith(fpc, sat, COS, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_DP3:
- arith(fpc, sat, DP3, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_DP4:
- arith(fpc, sat, DP4, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_DPH:
- tmp = temp(fpc);
- arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[1], none);
- arith(fpc, sat, ADD, dst, mask, swz(tmp, X, X, X, X),
- swz(src[1], W, W, W, W), none);
- break;
- case TGSI_OPCODE_DST:
- arith(fpc, sat, DST, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_EX2:
- arith(fpc, sat, EX2, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_FLR:
- arith(fpc, sat, FLR, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_FRC:
- arith(fpc, sat, FRC, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_KILP:
- arith(fpc, 0, KIL, none, 0, none, none, none);
- break;
- case TGSI_OPCODE_KIL:
- dst = nv30_sr(NV30SR_NONE, 0);
- dst.cc_update = 1;
- arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none);
- dst.cc_update = 0; dst.cc_test = NV30_FP_OP_COND_LT;
- arith(fpc, 0, KIL, dst, 0, none, none, none);
- break;
- case TGSI_OPCODE_LG2:
- arith(fpc, sat, LG2, dst, mask, src[0], none, none);
- break;
-// case TGSI_OPCODE_LIT:
- case TGSI_OPCODE_LRP:
- arith(fpc, sat, LRP, dst, mask, src[0], src[1], src[2]);
- break;
- case TGSI_OPCODE_MAD:
- arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]);
- break;
- case TGSI_OPCODE_MAX:
- arith(fpc, sat, MAX, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_MIN:
- arith(fpc, sat, MIN, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_MOV:
- arith(fpc, sat, MOV, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_MUL:
- arith(fpc, sat, MUL, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_POW:
- arith(fpc, sat, POW, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_RCP:
- arith(fpc, sat, RCP, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_RET:
- assert(0);
- break;
- case TGSI_OPCODE_RFL:
- arith(fpc, 0, RFL, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_RSQ:
- arith(fpc, sat, RSQ, dst, mask, abs(swz(src[0], X, X, X, X)), none, none);
- break;
- case TGSI_OPCODE_SCS:
- /* avoid overwriting the source */
- if(src[0].swz[SWZ_X] != SWZ_X)
- {
- if (mask & MASK_X) {
- arith(fpc, sat, COS, dst, MASK_X,
- swz(src[0], X, X, X, X), none, none);
- }
- if (mask & MASK_Y) {
- arith(fpc, sat, SIN, dst, MASK_Y,
- swz(src[0], X, X, X, X), none, none);
- }
- }
- else
- {
- if (mask & MASK_Y) {
- arith(fpc, sat, SIN, dst, MASK_Y,
- swz(src[0], X, X, X, X), none, none);
- }
- if (mask & MASK_X) {
- arith(fpc, sat, COS, dst, MASK_X,
- swz(src[0], X, X, X, X), none, none);
- }
- }
- break;
- case TGSI_OPCODE_SIN:
- arith(fpc, sat, SIN, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_SGE:
- arith(fpc, sat, SGE, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SGT:
- arith(fpc, sat, SGT, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SLT:
- arith(fpc, sat, SLT, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SUB:
- arith(fpc, sat, ADD, dst, mask, src[0], neg(src[1]), none);
- break;
- case TGSI_OPCODE_TEX:
- tex(fpc, sat, TEX, unit, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_TXB:
- tex(fpc, sat, TXB, unit, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_TXP:
- tex(fpc, sat, TXP, unit, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_XPD:
- tmp = temp(fpc);
- arith(fpc, 0, MUL, tmp, mask,
- swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none);
- arith(fpc, sat, MAD, dst, (mask & ~MASK_W),
- swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y),
- neg(tmp));
- break;
- default:
- NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static boolean
-nv30_fragprog_parse_decl_attrib(struct nv30_fpc *fpc,
- const struct tgsi_full_declaration *fdec)
-{
- int hw;
-
- switch (fdec->Semantic.Name) {
- case TGSI_SEMANTIC_POSITION:
- hw = NV30_FP_OP_INPUT_SRC_POSITION;
- break;
- case TGSI_SEMANTIC_COLOR:
- if (fdec->Semantic.Index == 0) {
- hw = NV30_FP_OP_INPUT_SRC_COL0;
- } else
- if (fdec->Semantic.Index == 1) {
- hw = NV30_FP_OP_INPUT_SRC_COL1;
- } else {
- NOUVEAU_ERR("bad colour semantic index\n");
- return FALSE;
- }
- break;
- case TGSI_SEMANTIC_FOG:
- hw = NV30_FP_OP_INPUT_SRC_FOGC;
- break;
- case TGSI_SEMANTIC_GENERIC:
- if (fdec->Semantic.Index <= 7) {
- hw = NV30_FP_OP_INPUT_SRC_TC(fdec->Semantic.
- Index);
- } else {
- NOUVEAU_ERR("bad generic semantic index\n");
- return FALSE;
- }
- break;
- default:
- NOUVEAU_ERR("bad input semantic\n");
- return FALSE;
- }
-
- fpc->attrib_map[fdec->Range.First] = hw;
- return TRUE;
-}
-
-static boolean
-nv30_fragprog_parse_decl_output(struct nv30_fpc *fpc,
- const struct tgsi_full_declaration *fdec)
-{
- switch (fdec->Semantic.Name) {
- case TGSI_SEMANTIC_POSITION:
- fpc->depth_id = fdec->Range.First;
- break;
- case TGSI_SEMANTIC_COLOR:
- fpc->colour_id = fdec->Range.First;
- break;
- default:
- NOUVEAU_ERR("bad output semantic\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static boolean
-nv30_fragprog_prepare(struct nv30_fpc *fpc)
-{
- struct tgsi_parse_context p;
- /*int high_temp = -1, i;*/
-
- tgsi_parse_init(&p, fpc->fp->pipe.tokens);
- while (!tgsi_parse_end_of_tokens(&p)) {
- const union tgsi_full_token *tok = &p.FullToken;
-
- tgsi_parse_token(&p);
- switch(tok->Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- {
- const struct tgsi_full_declaration *fdec;
- fdec = &p.FullToken.FullDeclaration;
- switch (fdec->Declaration.File) {
- case TGSI_FILE_INPUT:
- if (!nv30_fragprog_parse_decl_attrib(fpc, fdec))
- goto out_err;
- break;
- case TGSI_FILE_OUTPUT:
- if (!nv30_fragprog_parse_decl_output(fpc, fdec))
- goto out_err;
- break;
- /*case TGSI_FILE_TEMPORARY:
- if (fdec->Range.Last > high_temp) {
- high_temp =
- fdec->Range.Last;
- }
- break;*/
- default:
- break;
- }
- }
- break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- {
- struct tgsi_full_immediate *imm;
- float vals[4];
-
- imm = &p.FullToken.FullImmediate;
- assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
- assert(fpc->nr_imm < MAX_IMM);
-
- vals[0] = imm->u[0].Float;
- vals[1] = imm->u[1].Float;
- vals[2] = imm->u[2].Float;
- vals[3] = imm->u[3].Float;
- fpc->imm[fpc->nr_imm++] = constant(fpc, -1, vals);
- }
- break;
- default:
- break;
- }
- }
- tgsi_parse_free(&p);
-
- /*if (++high_temp) {
- fpc->r_temp = CALLOC(high_temp, sizeof(struct nv30_sreg));
- for (i = 0; i < high_temp; i++)
- fpc->r_temp[i] = temp(fpc);
- fpc->r_temps_discard = 0;
- }*/
-
- return TRUE;
-
-out_err:
- /*if (fpc->r_temp)
- FREE(fpc->r_temp);*/
- tgsi_parse_free(&p);
- return FALSE;
-}
-
-static void
-nv30_fragprog_translate(struct nv30_context *nv30,
- struct nv30_fragment_program *fp)
-{
- struct tgsi_parse_context parse;
- struct nv30_fpc *fpc = NULL;
-
- tgsi_dump(fp->pipe.tokens,0);
-
- fpc = CALLOC(1, sizeof(struct nv30_fpc));
- if (!fpc)
- return;
- fpc->fp = fp;
- fpc->high_temp = -1;
- fpc->num_regs = 2;
-
- if (!nv30_fragprog_prepare(fpc)) {
- FREE(fpc);
- return;
- }
-
- tgsi_parse_init(&parse, fp->pipe.tokens);
-
- while (!tgsi_parse_end_of_tokens(&parse)) {
- tgsi_parse_token(&parse);
-
- switch (parse.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- {
- const struct tgsi_full_instruction *finst;
-
- finst = &parse.FullToken.FullInstruction;
- if (!nv30_fragprog_parse_instruction(fpc, finst))
- goto out_err;
- }
- break;
- default:
- break;
- }
- }
-
- fp->fp_control |= (fpc->num_regs-1)/2;
- fp->fp_reg_control = (1<<16)|0x4;
-
- /* Terminate final instruction */
- fp->insn[fpc->inst_offset] |= 0x00000001;
-
- /* Append NOP + END instruction, may or may not be necessary. */
- fpc->inst_offset = fp->insn_len;
- grow_insns(fpc, 4);
- fp->insn[fpc->inst_offset + 0] = 0x00000001;
- fp->insn[fpc->inst_offset + 1] = 0x00000000;
- fp->insn[fpc->inst_offset + 2] = 0x00000000;
- fp->insn[fpc->inst_offset + 3] = 0x00000000;
-
- fp->translated = TRUE;
- fp->on_hw = FALSE;
-out_err:
- tgsi_parse_free(&parse);
- FREE(fpc);
-}
-
-static void
-nv30_fragprog_upload(struct nv30_context *nv30,
- struct nv30_fragment_program *fp)
-{
- struct pipe_screen *pscreen = nv30->pipe.screen;
- const uint32_t le = 1;
- uint32_t *map;
- int i;
-
- map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
-
-#if 0
- for (i = 0; i < fp->insn_len; i++) {
- fflush(stdout); fflush(stderr);
- NOUVEAU_ERR("%d 0x%08x\n", i, fp->insn[i]);
- fflush(stdout); fflush(stderr);
- }
-#endif
-
- if ((*(const uint8_t *)&le)) {
- for (i = 0; i < fp->insn_len; i++) {
- map[i] = fp->insn[i];
- }
- } else {
- /* Weird swapping for big-endian chips */
- for (i = 0; i < fp->insn_len; i++) {
- map[i] = ((fp->insn[i] & 0xffff) << 16) |
- ((fp->insn[i] >> 16) & 0xffff);
- }
- }
-
- pipe_buffer_unmap(pscreen, fp->buffer);
-}
-
-static boolean
-nv30_fragprog_validate(struct nv30_context *nv30)
-{
- struct nv30_fragment_program *fp = nv30->fragprog;
- struct pipe_buffer *constbuf =
- nv30->constbuf[PIPE_SHADER_FRAGMENT];
- struct pipe_screen *pscreen = nv30->pipe.screen;
- struct nouveau_stateobj *so;
- boolean new_consts = FALSE;
- int i;
-
- if (fp->translated)
- goto update_constants;
-
- /*nv30->fallback_swrast &= ~NV30_NEW_FRAGPROG;*/
- nv30_fragprog_translate(nv30, fp);
- if (!fp->translated) {
- /*nv30->fallback_swrast |= NV30_NEW_FRAGPROG;*/
- return FALSE;
- }
-
- fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
- nv30_fragprog_upload(nv30, fp);
-
- so = so_new(4, 4, 1);
- so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
- so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
- NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
- NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
- so_method(so, nv30->screen->rankine, NV34TCL_FP_CONTROL, 1);
- so_data (so, fp->fp_control);
- so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1);
- so_data (so, fp->fp_reg_control);
- so_method(so, nv30->screen->rankine, NV34TCL_TX_UNITS_ENABLE, 1);
- so_data (so, fp->samplers);
- so_ref(so, &fp->so);
- so_ref(NULL, &so);
-
-update_constants:
- if (fp->nr_consts) {
- float *map;
-
- map = pipe_buffer_map(pscreen, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
- for (i = 0; i < fp->nr_consts; i++) {
- struct nv30_fragment_program_data *fpd = &fp->consts[i];
- uint32_t *p = &fp->insn[fpd->offset];
- uint32_t *cb = (uint32_t *)&map[fpd->index * 4];
-
- if (!memcmp(p, cb, 4 * sizeof(float)))
- continue;
- memcpy(p, cb, 4 * sizeof(float));
- new_consts = TRUE;
- }
- pipe_buffer_unmap(pscreen, constbuf);
-
- if (new_consts)
- nv30_fragprog_upload(nv30, fp);
- }
-
- if (new_consts || fp->so != nv30->state.hw[NV30_STATE_FRAGPROG]) {
- so_ref(fp->so, &nv30->state.hw[NV30_STATE_FRAGPROG]);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-nv30_fragprog_destroy(struct nv30_context *nv30,
- struct nv30_fragment_program *fp)
-{
- if (fp->buffer)
- pipe_buffer_reference(&fp->buffer, NULL);
-
- if (fp->so)
- so_ref(NULL, &fp->so);
-
- if (fp->insn_len)
- FREE(fp->insn);
-}
-
-struct nv30_state_entry nv30_state_fragprog = {
- .validate = nv30_fragprog_validate,
- .dirty = {
- .pipe = NV30_NEW_FRAGPROG,
- .hw = NV30_STATE_FRAGPROG
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
deleted file mode 100644
index 697b1b92ff6..00000000000
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ /dev/null
@@ -1,239 +0,0 @@
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-
-#include "nv30_context.h"
-#include "../nouveau/nv04_surface_2d.h"
-
-static void
-nv30_miptree_layout(struct nv30_miptree *nv30mt)
-{
- struct pipe_texture *pt = &nv30mt->base;
- uint width = pt->width0;
- uint offset = 0;
- int nr_faces, l, f;
- uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_RENDER_TARGET |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- nr_faces = 6;
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- nr_faces = pt->depth0;
- } else {
- nr_faces = 1;
- }
-
- for (l = 0; l <= pt->last_level; l++) {
- if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
- nv30mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64);
- else
- nv30mt->level[l].pitch = util_format_get_stride(pt->format, width);
-
- nv30mt->level[l].image_offset =
- CALLOC(nr_faces, sizeof(unsigned));
-
- width = u_minify(width, 1);
- }
-
- for (f = 0; f < nr_faces; f++) {
- for (l = 0; l < pt->last_level; l++) {
- nv30mt->level[l].image_offset[f] = offset;
-
- if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
- u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1)
- offset += align(nv30mt->level[l].pitch * u_minify(pt->height0, l), 64);
- else
- offset += nv30mt->level[l].pitch * u_minify(pt->height0, l);
- }
-
- nv30mt->level[l].image_offset[f] = offset;
- offset += nv30mt->level[l].pitch * u_minify(pt->height0, l);
- }
-
- nv30mt->total_size = offset;
-}
-
-static struct pipe_texture *
-nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
-{
- struct nv30_miptree *mt;
- unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
- NOUVEAU_BUFFER_USAGE_TEXTURE;
-
- mt = MALLOC(sizeof(struct nv30_miptree));
- if (!mt)
- return NULL;
- mt->base = *pt;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
-
- /* Swizzled textures must be POT */
- if (pt->width0 & (pt->width0 - 1) ||
- pt->height0 & (pt->height0 - 1))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- else
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- else {
- switch (pt->format) {
- /* TODO: Figure out which formats can be swizzled */
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_R16_SNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- {
- if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- break;
- }
- default:
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- }
- }
-
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
- buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
-
- /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear.
- * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy.
- * This also happens for small mipmaps of large textures. */
- if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
-
- nv30_miptree_layout(mt);
-
- mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage,
- mt->total_size);
- if (!mt->buffer) {
- FREE(mt);
- return NULL;
- }
- mt->bo = nouveau_bo(mt->buffer);
-
- return &mt->base;
-}
-
-static struct pipe_texture *
-nv30_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
- const unsigned *stride, struct pipe_buffer *pb)
-{
- struct nv30_miptree *mt;
-
- /* Only supports 2D, non-mipmapped textures for the moment */
- if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
- pt->depth0 != 1)
- return NULL;
-
- mt = CALLOC_STRUCT(nv30_miptree);
- if (!mt)
- return NULL;
-
- mt->base = *pt;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
- mt->level[0].pitch = stride[0];
- mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
-
- /* Assume whoever created this buffer expects it to be linear for now */
- mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
-
- pipe_buffer_reference(&mt->buffer, pb);
- mt->bo = nouveau_bo(mt->buffer);
- return &mt->base;
-}
-
-static void
-nv30_miptree_destroy(struct pipe_texture *pt)
-{
- struct nv30_miptree *mt = (struct nv30_miptree *)pt;
- int l;
-
- pipe_buffer_reference(&mt->buffer, NULL);
- for (l = 0; l <= pt->last_level; l++) {
- if (mt->level[l].image_offset)
- FREE(mt->level[l].image_offset);
- }
-
- FREE(mt);
-}
-
-static struct pipe_surface *
-nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- unsigned flags)
-{
- struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt;
- struct nv04_surface *ns;
-
- ns = CALLOC_STRUCT(nv04_surface);
- if (!ns)
- return NULL;
- pipe_texture_reference(&ns->base.texture, pt);
- ns->base.format = pt->format;
- ns->base.width = u_minify(pt->width0, level);
- ns->base.height = u_minify(pt->height0, level);
- ns->base.usage = flags;
- pipe_reference_init(&ns->base.reference, 1);
- ns->base.face = face;
- ns->base.level = level;
- ns->base.zslice = zslice;
- ns->pitch = nv30mt->level[level].pitch;
-
- if (pt->target == PIPE_TEXTURE_CUBE) {
- ns->base.offset = nv30mt->level[level].image_offset[face];
- } else
- if (pt->target == PIPE_TEXTURE_3D) {
- ns->base.offset = nv30mt->level[level].image_offset[zslice];
- } else {
- ns->base.offset = nv30mt->level[level].image_offset[0];
- }
-
- /* create a linear temporary that we can render into if necessary.
- * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
- * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
- if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
- return &nv04_surface_wrap_for_render(pscreen, ((struct nv30_screen*)pscreen)->eng2d, ns)->base;
-
- return &ns->base;
-}
-
-static void
-nv30_miptree_surface_del(struct pipe_surface *ps)
-{
- struct nv04_surface* ns = (struct nv04_surface*)ps;
- if(ns->backing)
- {
- struct nv30_screen* screen = (struct nv30_screen*)ps->texture->screen;
- if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
- screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
- nv30_miptree_surface_del(&ns->backing->base);
- }
-
- pipe_texture_reference(&ps->texture, NULL);
- FREE(ps);
-}
-
-void
-nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
-{
- pscreen->texture_create = nv30_miptree_create;
- pscreen->texture_blanket = nv30_miptree_blanket;
- pscreen->texture_destroy = nv30_miptree_destroy;
- pscreen->get_tex_surface = nv30_miptree_surface_new;
- pscreen->tex_surface_destroy = nv30_miptree_surface_del;
-}
diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c
deleted file mode 100644
index e27e9ccbf60..00000000000
--- a/src/gallium/drivers/nv30/nv30_query.c
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "pipe/p_context.h"
-
-#include "nv30_context.h"
-
-struct nv30_query {
- struct nouveau_resource *object;
- unsigned type;
- boolean ready;
- uint64_t result;
-};
-
-static INLINE struct nv30_query *
-nv30_query(struct pipe_query *pipe)
-{
- return (struct nv30_query *)pipe;
-}
-
-static struct pipe_query *
-nv30_query_create(struct pipe_context *pipe, unsigned query_type)
-{
- struct nv30_query *q;
-
- q = CALLOC(1, sizeof(struct nv30_query));
- q->type = query_type;
-
- return (struct pipe_query *)q;
-}
-
-static void
-nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv30_query *q = nv30_query(pq);
-
- if (q->object)
- nouveau_resource_free(&q->object);
- FREE(q);
-}
-
-static void
-nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_query *q = nv30_query(pq);
- struct nv30_screen *screen = nv30->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
-
- assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
-
- /* Happens when end_query() is called, then another begin_query()
- * without querying the result in-between. For now we'll wait for
- * the existing query to notify completion, but it could be better.
- */
- if (q->object) {
- uint64_t tmp;
- pipe->get_query_result(pipe, pq, 1, &tmp);
- }
-
- if (nouveau_resource_alloc(nv30->screen->query_heap, 1, NULL, &q->object))
- assert(0);
- nouveau_notifier_reset(nv30->screen->query, q->object->start);
-
- BEGIN_RING(chan, rankine, NV34TCL_QUERY_RESET, 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, rankine, NV34TCL_QUERY_UNK17CC, 1);
- OUT_RING (chan, 1);
-
- q->ready = FALSE;
-}
-
-static void
-nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_screen *screen = nv30->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
- struct nv30_query *q = nv30_query(pq);
-
- BEGIN_RING(chan, rankine, NV34TCL_QUERY_GET, 1);
- OUT_RING (chan, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
- ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
- FIRE_RING(chan);
-}
-
-static boolean
-nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
- boolean wait, uint64_t *result)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_query *q = nv30_query(pq);
-
- assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
-
- if (!q->ready) {
- unsigned status;
-
- status = nouveau_notifier_status(nv30->screen->query,
- q->object->start);
- if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
- if (wait == FALSE)
- return FALSE;
-
- nouveau_notifier_wait_status(nv30->screen->query,
- q->object->start,
- NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
- }
-
- q->result = nouveau_notifier_return_val(nv30->screen->query,
- q->object->start);
- q->ready = TRUE;
- nouveau_resource_free(&q->object);
- }
-
- *result = q->result;
- return TRUE;
-}
-
-void
-nv30_init_query_functions(struct nv30_context *nv30)
-{
- nv30->pipe.create_query = nv30_query_create;
- nv30->pipe.destroy_query = nv30_query_destroy;
- nv30->pipe.begin_query = nv30_query_begin;
- nv30->pipe.end_query = nv30_query_end;
- nv30->pipe.get_query_result = nv30_query_result;
-}
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
deleted file mode 100644
index 85433d20953..00000000000
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ /dev/null
@@ -1,362 +0,0 @@
-#include "pipe/p_screen.h"
-#include "pipe/p_state.h"
-
-#include "nouveau/nouveau_screen.h"
-
-#include "nv30_context.h"
-#include "nv30_screen.h"
-
-#define NV30TCL_CHIPSET_3X_MASK 0x00000003
-#define NV34TCL_CHIPSET_3X_MASK 0x00000010
-#define NV35TCL_CHIPSET_3X_MASK 0x000001e0
-
-/* FIXME: It seems I should not include directly ../../winsys/drm/nouveau/drm/nouveau_drm_api.h
- * to get the pointer to the context front buffer, so I copied nouveau_winsys here.
- * nv30_screen_surface_format_supported() can then use it to enforce creating fbo
- * with same number of bits everywhere.
- */
-struct nouveau_winsys {
- struct pipe_winsys base;
-
- struct pipe_screen *pscreen;
-
- struct pipe_surface *front;
-};
-
-static int
-nv30_screen_get_param(struct pipe_screen *pscreen, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 8;
- case PIPE_CAP_NPOT_TEXTURES:
- return 0;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 1;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 2;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13;
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 10;
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13;
- case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
- return 0;
- case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
- return 1;
- case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- return 0;
- case PIPE_CAP_TGSI_CONT_SUPPORTED:
- return 0;
- case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- return 0;
- case NOUVEAU_CAP_HW_VTXBUF:
- case NOUVEAU_CAP_HW_IDXBUF:
- return 1;
- case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 16;
- case PIPE_CAP_INDEP_BLEND_ENABLE:
- return 0;
- case PIPE_CAP_INDEP_BLEND_FUNC:
- return 0;
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
- return 1;
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
- return 0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0;
- }
-}
-
-static float
-nv30_screen_get_paramf(struct pipe_screen *pscreen, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 10.0;
- case PIPE_CAP_MAX_POINT_WIDTH:
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 64.0;
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 8.0;
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 4.0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0.0;
- }
-}
-
-static boolean
-nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned tex_usage, unsigned geom_flags)
-{
- struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front;
-
- if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- return TRUE;
- default:
- break;
- }
- } else
- if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
- switch (format) {
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- return TRUE;
- case PIPE_FORMAT_Z16_UNORM:
- if (front) {
- return (front->format == PIPE_FORMAT_B5G6R5_UNORM);
- }
- return TRUE;
- default:
- break;
- }
- } else {
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_S8Z24_UNORM:
- return TRUE;
- default:
- break;
- }
- }
-
- return FALSE;
-}
-
-static struct pipe_buffer *
-nv30_surface_buffer(struct pipe_surface *surf)
-{
- struct nv30_miptree *mt = (struct nv30_miptree *)surf->texture;
-
- return mt->buffer;
-}
-
-static void
-nv30_screen_destroy(struct pipe_screen *pscreen)
-{
- struct nv30_screen *screen = nv30_screen(pscreen);
- unsigned i;
-
- for (i = 0; i < NV30_STATE_MAX; i++) {
- if (screen->state[i])
- so_ref(NULL, &screen->state[i]);
- }
-
- nouveau_resource_destroy(&screen->vp_exec_heap);
- nouveau_resource_destroy(&screen->vp_data_heap);
- nouveau_resource_destroy(&screen->query_heap);
- nouveau_notifier_free(&screen->query);
- nouveau_notifier_free(&screen->sync);
- nouveau_grobj_free(&screen->rankine);
- nv04_surface_2d_takedown(&screen->eng2d);
-
- nouveau_screen_fini(&screen->base);
-
- FREE(pscreen);
-}
-
-struct pipe_screen *
-nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
-{
- struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
- struct nouveau_channel *chan;
- struct pipe_screen *pscreen;
- struct nouveau_stateobj *so;
- unsigned rankine_class = 0;
- int ret, i;
-
- if (!screen)
- return NULL;
- pscreen = &screen->base.base;
-
- ret = nouveau_screen_init(&screen->base, dev);
- if (ret) {
- nv30_screen_destroy(pscreen);
- return NULL;
- }
- chan = screen->base.channel;
-
- pscreen->winsys = ws;
- pscreen->destroy = nv30_screen_destroy;
- pscreen->get_param = nv30_screen_get_param;
- pscreen->get_paramf = nv30_screen_get_paramf;
- pscreen->is_format_supported = nv30_screen_surface_format_supported;
- pscreen->context_create = nv30_create;
-
- nv30_screen_init_miptree_functions(pscreen);
- nv30_screen_init_transfer_functions(pscreen);
-
- /* 3D object */
- switch (dev->chipset & 0xf0) {
- case 0x30:
- if (NV30TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
- rankine_class = 0x0397;
- else
- if (NV34TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
- rankine_class = 0x0697;
- else
- if (NV35TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
- rankine_class = 0x0497;
- break;
- default:
- break;
- }
-
- if (!rankine_class) {
- NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", dev->chipset);
- return NULL;
- }
-
- ret = nouveau_grobj_alloc(chan, 0xbeef3097, rankine_class,
- &screen->rankine);
- if (ret) {
- NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
- return FALSE;
- }
-
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(&screen->base);
- screen->eng2d->buf = nv30_surface_buffer;
-
- /* Notifier for sync purposes */
- ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
- if (ret) {
- NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv30_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Query objects */
- ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
- if (ret) {
- NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
- nv30_screen_destroy(pscreen);
- return NULL;
- }
-
- ret = nouveau_resource_init(&screen->query_heap, 0, 32);
- if (ret) {
- NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
- nv30_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Vtxprog resources */
- if (nouveau_resource_init(&screen->vp_exec_heap, 0, 256) ||
- nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
- nv30_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Static rankine initialisation */
- so = so_new(36, 60, 0);
- so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1);
- so_data (so, screen->sync->handle);
- so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->gart->handle);
- so_method(so, screen->rankine, NV34TCL_DMA_COLOR1, 1);
- so_data (so, chan->vram->handle);
- so_method(so, screen->rankine, NV34TCL_DMA_COLOR0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_method(so, screen->rankine, NV34TCL_DMA_VTXBUF0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->gart->handle);
-/* so_method(so, screen->rankine, NV34TCL_DMA_FENCE, 2);
- so_data (so, 0);
- so_data (so, screen->query->handle);*/
- so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY7, 1);
- so_data (so, chan->vram->handle);
- so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY8, 1);
- so_data (so, chan->vram->handle);
-
- for (i=1; i<8; i++) {
- so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1);
- so_data (so, 0);
- so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_VERT(i), 1);
- so_data (so, 0);
- }
-
- so_method(so, screen->rankine, 0x220, 1);
- so_data (so, 1);
-
- so_method(so, screen->rankine, 0x03b0, 1);
- so_data (so, 0x00100000);
- so_method(so, screen->rankine, 0x1454, 1);
- so_data (so, 0);
- so_method(so, screen->rankine, 0x1d80, 1);
- so_data (so, 3);
- so_method(so, screen->rankine, 0x1450, 1);
- so_data (so, 0x00030004);
-
- /* NEW */
- so_method(so, screen->rankine, 0x1e98, 1);
- so_data (so, 0);
- so_method(so, screen->rankine, 0x17e0, 3);
- so_data (so, fui(0.0));
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
- so_method(so, screen->rankine, 0x1f80, 16);
- for (i=0; i<16; i++) {
- so_data (so, (i==8) ? 0x0000ffff : 0);
- }
-
- so_method(so, screen->rankine, 0x120, 3);
- so_data (so, 0);
- so_data (so, 1);
- so_data (so, 2);
-
- so_method(so, screen->rankine, 0x1d88, 1);
- so_data (so, 0x00001200);
-
- so_method(so, screen->rankine, NV34TCL_RC_ENABLE, 1);
- so_data (so, 0);
-
- so_method(so, screen->rankine, NV34TCL_DEPTH_RANGE_NEAR, 2);
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
-
- so_method(so, screen->rankine, NV34TCL_MULTISAMPLE_CONTROL, 1);
- so_data (so, 0xffff0000);
-
- /* enables use of vp rather than fixed-function somehow */
- so_method(so, screen->rankine, 0x1e94, 1);
- so_data (so, 0x13);
-
- so_emit(chan, so);
- so_ref(NULL, &so);
- nouveau_pushbuf_flush(chan, 0);
-
- return pscreen;
-}
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
deleted file mode 100644
index 8591cd31cab..00000000000
--- a/src/gallium/drivers/nv30/nv30_screen.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __NV30_SCREEN_H__
-#define __NV30_SCREEN_H__
-
-#include "nouveau/nouveau_screen.h"
-
-#include "nouveau/nv04_surface_2d.h"
-
-struct nv30_screen {
- struct nouveau_screen base;
-
- struct nouveau_winsys *nvws;
-
- struct nv30_context *cur_ctx;
-
- /* HW graphics objects */
- struct nv04_surface_2d *eng2d;
- struct nouveau_grobj *rankine;
- struct nouveau_notifier *sync;
-
- /* Query object resources */
- struct nouveau_notifier *query;
- struct nouveau_resource *query_heap;
-
- /* Vtxprog resources */
- struct nouveau_resource *vp_exec_heap;
- struct nouveau_resource *vp_data_heap;
-
- /* Current 3D state of channel */
- struct nouveau_stateobj *state[NV30_STATE_MAX];
-};
-
-static INLINE struct nv30_screen *
-nv30_screen(struct pipe_screen *screen)
-{
- return (struct nv30_screen *)screen;
-}
-
-void
-nv30_screen_init_transfer_functions(struct pipe_screen *pscreen);
-
-#endif
diff --git a/src/gallium/drivers/nv30/nv30_shader.h b/src/gallium/drivers/nv30/nv30_shader.h
deleted file mode 100644
index dd3a36f78f3..00000000000
--- a/src/gallium/drivers/nv30/nv30_shader.h
+++ /dev/null
@@ -1,490 +0,0 @@
-#ifndef __NV30_SHADER_H__
-#define __NV30_SHADER_H__
-
-/* Vertex programs instruction set
- *
- * 128bit opcodes, split into 4 32-bit ones for ease of use.
- *
- * Non-native instructions
- * ABS - MOV + NV40_VP_INST0_DEST_ABS
- * POW - EX2 + MUL + LG2
- * SUB - ADD, second source negated
- * SWZ - MOV
- * XPD -
- *
- * Register access
- * - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
- * - Only one CONST can be accessed per-instruction (move extras into TEMPs)
- *
- * Relative Addressing
- * According to the value returned for
- * MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
- *
- * there are only two address registers available. The destination in the
- * ARL instruction is set to TEMP <n> (The temp isn't actually written).
- *
- * When using vanilla ARB_v_p, the proprietary driver will squish both the
- * available ADDRESS regs into the first hardware reg in the X and Y
- * components.
- *
- * To use an address reg as an index into consts, the CONST_SRC is set to
- * (const_base + offset) and INDEX_CONST is set.
- *
- * To access the second address reg use ADDR_REG_SELECT_1. A particular
- * component of the address regs is selected with ADDR_SWZ.
- *
- * Only one address register can be accessed per instruction.
- *
- * Conditional execution (see NV_vertex_program{2,3} for details) Conditional
- * execution of an instruction is enabled by setting COND_TEST_ENABLE, and
- * selecting the condition which will allow the test to pass with
- * COND_{FL,LT,...}. It is possible to swizzle the values in the condition
- * register, which allows for testing against an individual component.
- *
- * Branching:
- *
- * The BRA/CAL instructions seem to follow a slightly different opcode
- * layout. The destination instruction ID (IADDR) overlaps a source field.
- * Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO
- * command, and is incremented automatically on each UPLOAD_INST FIFO
- * command.
- *
- * Conditional branching is achieved by using the condition tests described
- * above. There doesn't appear to be dedicated looping instructions, but
- * this can be done using a temp reg + conditional branching.
- *
- * Subroutines may be uploaded before the main program itself, but the first
- * executed instruction is determined by the PROGRAM_START_ID FIFO command.
- *
- */
-
-/* DWORD 0 */
-
-#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
-#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */
-#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */
-#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */
-#define NV30_VP_INST_VEC_RESULT (1 << 20)
-#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16
-#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16)
-#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15)
-#define NV30_VP_INST_VEC_DEST_TEMP_MASK (0xF << 16)
-#define NV30_VP_INST_COND_TEST_ENABLE (1<<14)
-#define NV30_VP_INST_COND_SHIFT 11
-#define NV30_VP_INST_COND_MASK (0x07 << 11)
-# define NV30_VP_INST_COND_FL 0 /* guess */
-# define NV30_VP_INST_COND_LT 1
-# define NV30_VP_INST_COND_EQ 2
-# define NV30_VP_INST_COND_LE 3
-# define NV30_VP_INST_COND_GT 4
-# define NV30_VP_INST_COND_NE 5
-# define NV30_VP_INST_COND_GE 6
-# define NV30_VP_INST_COND_TR 7 /* guess */
-#define NV30_VP_INST_COND_SWZ_X_SHIFT 9
-#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
-#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
-#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
-#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
-#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
-#define NV30_VP_INST_COND_SWZ_W_SHIFT 3
-#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
-#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
-#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
-#define NV30_VP_INST_ADDR_SWZ_SHIFT 1
-#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
-#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
-#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
-
-/* DWORD 1 */
-#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
-#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
-# define NV30_VP_INST_OP_NOP 0x00
-# define NV30_VP_INST_OP_RCP 0x02
-# define NV30_VP_INST_OP_RCC 0x03
-# define NV30_VP_INST_OP_RSQ 0x04
-# define NV30_VP_INST_OP_EXP 0x05
-# define NV30_VP_INST_OP_LOG 0x06
-# define NV30_VP_INST_OP_LIT 0x07
-# define NV30_VP_INST_OP_BRA 0x09
-# define NV30_VP_INST_OP_CAL 0x0B
-# define NV30_VP_INST_OP_RET 0x0C
-# define NV30_VP_INST_OP_LG2 0x0D
-# define NV30_VP_INST_OP_EX2 0x0E
-# define NV30_VP_INST_OP_SIN 0x0F
-# define NV30_VP_INST_OP_COS 0x10
-#define NV30_VP_INST_VEC_OPCODE_SHIFT 23
-#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
-# define NV30_VP_INST_OP_NOPV 0x00
-# define NV30_VP_INST_OP_MOV 0x01
-# define NV30_VP_INST_OP_MUL 0x02
-# define NV30_VP_INST_OP_ADD 0x03
-# define NV30_VP_INST_OP_MAD 0x04
-# define NV30_VP_INST_OP_DP3 0x05
-# define NV30_VP_INST_OP_DP4 0x07
-# define NV30_VP_INST_OP_DPH 0x06
-# define NV30_VP_INST_OP_DST 0x08
-# define NV30_VP_INST_OP_MIN 0x09
-# define NV30_VP_INST_OP_MAX 0x0A
-# define NV30_VP_INST_OP_SLT 0x0B
-# define NV30_VP_INST_OP_SGE 0x0C
-# define NV30_VP_INST_OP_ARL 0x0D
-# define NV30_VP_INST_OP_FRC 0x0E
-# define NV30_VP_INST_OP_FLR 0x0F
-# define NV30_VP_INST_OP_SEQ 0x10
-# define NV30_VP_INST_OP_SFL 0x11
-# define NV30_VP_INST_OP_SGT 0x12
-# define NV30_VP_INST_OP_SLE 0x13
-# define NV30_VP_INST_OP_SNE 0x14
-# define NV30_VP_INST_OP_STR 0x15
-# define NV30_VP_INST_OP_SSG 0x16
-# define NV30_VP_INST_OP_ARR 0x17
-# define NV30_VP_INST_OP_ARA 0x18
-#define NV30_VP_INST_CONST_SRC_SHIFT 14
-#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
-#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
-#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
-# define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
-# define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
-# define NV30_VP_INST_IN_NORMAL 2
-# define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
-# define NV30_VP_INST_IN_COL1 4
-# define NV30_VP_INST_IN_FOGC 5
-# define NV30_VP_INST_IN_TC0 8
-# define NV30_VP_INST_IN_TC(n) (8+n)
-#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
-#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
-
-/* Please note: the IADDR fields overlap other fields because they are used
- * only for branch instructions. See Branching: label above
- *
- * DWORD 2
- */
-#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
-#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */
-#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
-#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
-#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
-#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/
-#define NV30_VP_INST_IADDR_SHIFT 2
-#define NV30_VP_INST_IADDR_MASK (0xF << 28) /* NV30_VP_SRC2_LOW_MASK << 28 */
-
-/* DWORD 3 */
-#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
-#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
-#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
-#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
-#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
-#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
-#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
-#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
-#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
-#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
-#define NV30_VP_INST_DEST_SHIFT 2
-#define NV30_VP_INST_DEST_MASK (0x0F << 2)
-# define NV30_VP_INST_DEST_POS 0
-# define NV30_VP_INST_DEST_BFC0 1
-# define NV30_VP_INST_DEST_BFC1 2
-# define NV30_VP_INST_DEST_COL0 3
-# define NV30_VP_INST_DEST_COL1 4
-# define NV30_VP_INST_DEST_FOGC 5
-# define NV30_VP_INST_DEST_PSZ 6
-# define NV30_VP_INST_DEST_TC(n) (8+n)
-
-#define NV30_VP_INST_LAST (1 << 0)
-
-/* Useful to split the source selection regs into their pieces */
-#define NV30_VP_SRC0_HIGH_SHIFT 6
-#define NV30_VP_SRC0_HIGH_MASK 0x00007FC0
-#define NV30_VP_SRC0_LOW_MASK 0x0000003F
-#define NV30_VP_SRC2_HIGH_SHIFT 4
-#define NV30_VP_SRC2_HIGH_MASK 0x00007FF0
-#define NV30_VP_SRC2_LOW_MASK 0x0000000F
-
-
-/* Source-register definition - matches NV20 exactly */
-#define NV30_VP_SRC_NEGATE (1<<14)
-#define NV30_VP_SRC_SWZ_X_SHIFT 12
-#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
-#define NV30_VP_SRC_SWZ_Y_SHIFT 10
-#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
-#define NV30_VP_SRC_SWZ_Z_SHIFT 8
-#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
-#define NV30_VP_SRC_SWZ_W_SHIFT 6
-#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
-#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
-#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
-#define NV30_VP_SRC_TEMP_SRC_SHIFT 2
-#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
-#define NV30_VP_SRC_REG_TYPE_SHIFT 0
-#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
-#define NV30_VP_SRC_REG_TYPE_TEMP 1
-#define NV30_VP_SRC_REG_TYPE_INPUT 2
-#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
-
-/*
- * Each fragment program opcode appears to be comprised of 4 32-bit values.
- *
- * 0 - Opcode, output reg/mask, ATTRIB source
- * 1 - Source 0
- * 2 - Source 1
- * 3 - Source 2
- *
- * There appears to be no special difference between result regs and temp regs.
- * result.color == R0.xyzw
- * result.depth == R1.z
- * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
- * otherwise it is set to 1.
- *
- * Constants are inserted directly after the instruction that uses them.
- *
- * It appears that it's not possible to use two input registers in one
- * instruction as the input sourcing is done in the instruction dword
- * and not the source selection dwords. As such instructions such as:
- *
- * ADD result.color, fragment.color, fragment.texcoord[0];
- *
- * must be split into two MOV's and then an ADD (nvidia does this) but
- * I'm not sure why it's not just one MOV and then source the second input
- * in the ADD instruction..
- *
- * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
- * negation requires multiplication with a const.
- *
- * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
- * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
- * is implemented simply by not writing to the relevant components of the destination.
- *
- * Conditional execution
- * TODO
- *
- * Non-native instructions:
- * LIT
- * LRP - MAD+MAD
- * SUB - ADD, negate second source
- * RSQ - LG2 + EX2
- * POW - LG2 + MUL + EX2
- * SCS - COS + SIN
- * XPD
- */
-
-//== Opcode / Destination selection ==
-#define NV30_FP_OP_PROGRAM_END (1 << 0)
-#define NV30_FP_OP_OUT_REG_SHIFT 1
-#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
-/* Needs to be set when writing outputs to get expected result.. */
-#define NV30_FP_OP_OUT_REG_HALF (1 << 7)
-#define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8)
-#define NV30_FP_OP_OUTMASK_SHIFT 9
-#define NV30_FP_OP_OUTMASK_MASK (0xF << 9)
-# define NV30_FP_OP_OUT_X (1<<9)
-# define NV30_FP_OP_OUT_Y (1<<10)
-# define NV30_FP_OP_OUT_Z (1<<11)
-# define NV30_FP_OP_OUT_W (1<<12)
-/* Uncertain about these, especially the input_src values.. it's possible that
- * they can be dynamically changed.
- */
-#define NV30_FP_OP_INPUT_SRC_SHIFT 13
-#define NV30_FP_OP_INPUT_SRC_MASK (15 << 13)
-# define NV30_FP_OP_INPUT_SRC_POSITION 0x0
-# define NV30_FP_OP_INPUT_SRC_COL0 0x1
-# define NV30_FP_OP_INPUT_SRC_COL1 0x2
-# define NV30_FP_OP_INPUT_SRC_FOGC 0x3
-# define NV30_FP_OP_INPUT_SRC_TC0 0x4
-# define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
-#define NV30_FP_OP_TEX_UNIT_SHIFT 17
-#define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
-#define NV30_FP_OP_PRECISION_SHIFT 22
-#define NV30_FP_OP_PRECISION_MASK (3 << 22)
-# define NV30_FP_PRECISION_FP32 0
-# define NV30_FP_PRECISION_FP16 1
-# define NV30_FP_PRECISION_FX12 2
-#define NV30_FP_OP_OPCODE_SHIFT 24
-#define NV30_FP_OP_OPCODE_MASK (0x3F << 24)
-# define NV30_FP_OP_OPCODE_NOP 0x00
-# define NV30_FP_OP_OPCODE_MOV 0x01
-# define NV30_FP_OP_OPCODE_MUL 0x02
-# define NV30_FP_OP_OPCODE_ADD 0x03
-# define NV30_FP_OP_OPCODE_MAD 0x04
-# define NV30_FP_OP_OPCODE_DP3 0x05
-# define NV30_FP_OP_OPCODE_DP4 0x06
-# define NV30_FP_OP_OPCODE_DST 0x07
-# define NV30_FP_OP_OPCODE_MIN 0x08
-# define NV30_FP_OP_OPCODE_MAX 0x09
-# define NV30_FP_OP_OPCODE_SLT 0x0A
-# define NV30_FP_OP_OPCODE_SGE 0x0B
-# define NV30_FP_OP_OPCODE_SLE 0x0C
-# define NV30_FP_OP_OPCODE_SGT 0x0D
-# define NV30_FP_OP_OPCODE_SNE 0x0E
-# define NV30_FP_OP_OPCODE_SEQ 0x0F
-# define NV30_FP_OP_OPCODE_FRC 0x10
-# define NV30_FP_OP_OPCODE_FLR 0x11
-# define NV30_FP_OP_OPCODE_KIL 0x12
-# define NV30_FP_OP_OPCODE_PK4B 0x13
-# define NV30_FP_OP_OPCODE_UP4B 0x14
-# define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
-# define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
-# define NV30_FP_OP_OPCODE_TEX 0x17
-# define NV30_FP_OP_OPCODE_TXP 0x18
-# define NV30_FP_OP_OPCODE_TXD 0x19
-# define NV30_FP_OP_OPCODE_RCP 0x1A
-# define NV30_FP_OP_OPCODE_RSQ 0x1B
-# define NV30_FP_OP_OPCODE_EX2 0x1C
-# define NV30_FP_OP_OPCODE_LG2 0x1D
-# define NV30_FP_OP_OPCODE_LIT 0x1E
-# define NV30_FP_OP_OPCODE_LRP 0x1F
-# define NV30_FP_OP_OPCODE_STR 0x20
-# define NV30_FP_OP_OPCODE_SFL 0x21
-# define NV30_FP_OP_OPCODE_COS 0x22
-# define NV30_FP_OP_OPCODE_SIN 0x23
-# define NV30_FP_OP_OPCODE_PK2H 0x24
-# define NV30_FP_OP_OPCODE_UP2H 0x25
-# define NV30_FP_OP_OPCODE_POW 0x26
-# define NV30_FP_OP_OPCODE_PK4UB 0x27
-# define NV30_FP_OP_OPCODE_UP4UB 0x28
-# define NV30_FP_OP_OPCODE_PK2US 0x29
-# define NV30_FP_OP_OPCODE_UP2US 0x2A
-# define NV30_FP_OP_OPCODE_DP2A 0x2E
-# define NV30_FP_OP_OPCODE_TXB 0x31
-# define NV30_FP_OP_OPCODE_RFL 0x36
-# define NV30_FP_OP_OPCODE_DIV 0x3A
-#define NV30_FP_OP_OUT_SAT (1 << 31)
-
-/* high order bits of SRC0 */
-#define NV30_FP_OP_OUT_ABS (1 << 29)
-#define NV30_FP_OP_COND_SWZ_W_SHIFT 27
-#define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27)
-#define NV30_FP_OP_COND_SWZ_Z_SHIFT 25
-#define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25)
-#define NV30_FP_OP_COND_SWZ_Y_SHIFT 23
-#define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23)
-#define NV30_FP_OP_COND_SWZ_X_SHIFT 21
-#define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21)
-#define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21
-#define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
-#define NV30_FP_OP_COND_SHIFT 18
-#define NV30_FP_OP_COND_MASK (0x07 << 18)
-# define NV30_FP_OP_COND_FL 0
-# define NV30_FP_OP_COND_LT 1
-# define NV30_FP_OP_COND_EQ 2
-# define NV30_FP_OP_COND_LE 3
-# define NV30_FP_OP_COND_GT 4
-# define NV30_FP_OP_COND_NE 5
-# define NV30_FP_OP_COND_GE 6
-# define NV30_FP_OP_COND_TR 7
-
-/* high order bits of SRC1 */
-#define NV30_FP_OP_DST_SCALE_SHIFT 28
-#define NV30_FP_OP_DST_SCALE_MASK (3 << 28)
-#define NV30_FP_OP_DST_SCALE_1X 0
-#define NV30_FP_OP_DST_SCALE_2X 1
-#define NV30_FP_OP_DST_SCALE_4X 2
-#define NV30_FP_OP_DST_SCALE_8X 3
-#define NV30_FP_OP_DST_SCALE_INV_2X 5
-#define NV30_FP_OP_DST_SCALE_INV_4X 6
-#define NV30_FP_OP_DST_SCALE_INV_8X 7
-
-
-/* high order bits of SRC2 */
-#define NV30_FP_OP_INDEX_INPUT (1 << 30)
-
-//== Register selection ==
-#define NV30_FP_REG_TYPE_SHIFT 0
-#define NV30_FP_REG_TYPE_MASK (3 << 0)
-# define NV30_FP_REG_TYPE_TEMP 0
-# define NV30_FP_REG_TYPE_INPUT 1
-# define NV30_FP_REG_TYPE_CONST 2
-#define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */
-#define NV30_FP_REG_SRC_MASK (31 << 2)
-#define NV30_FP_REG_SRC_HALF (1 << 8)
-#define NV30_FP_REG_SWZ_ALL_SHIFT 9
-#define NV30_FP_REG_SWZ_ALL_MASK (255 << 9)
-#define NV30_FP_REG_SWZ_X_SHIFT 9
-#define NV30_FP_REG_SWZ_X_MASK (3 << 9)
-#define NV30_FP_REG_SWZ_Y_SHIFT 11
-#define NV30_FP_REG_SWZ_Y_MASK (3 << 11)
-#define NV30_FP_REG_SWZ_Z_SHIFT 13
-#define NV30_FP_REG_SWZ_Z_MASK (3 << 13)
-#define NV30_FP_REG_SWZ_W_SHIFT 15
-#define NV30_FP_REG_SWZ_W_MASK (3 << 15)
-# define NV30_FP_SWIZZLE_X 0
-# define NV30_FP_SWIZZLE_Y 1
-# define NV30_FP_SWIZZLE_Z 2
-# define NV30_FP_SWIZZLE_W 3
-#define NV30_FP_REG_NEGATE (1 << 17)
-
-#define NV30SR_NONE 0
-#define NV30SR_OUTPUT 1
-#define NV30SR_INPUT 2
-#define NV30SR_TEMP 3
-#define NV30SR_CONST 4
-
-struct nv30_sreg {
- int type;
- int index;
-
- int dst_scale;
-
- int negate;
- int abs;
- int swz[4];
-
- int cc_update;
- int cc_update_reg;
- int cc_test;
- int cc_test_reg;
- int cc_swz[4];
-};
-
-static INLINE struct nv30_sreg
-nv30_sr(int type, int index)
-{
- struct nv30_sreg temp = {
- .type = type,
- .index = index,
- .dst_scale = DEF_SCALE,
- .abs = 0,
- .negate = 0,
- .swz = { 0, 1, 2, 3 },
- .cc_update = 0,
- .cc_update_reg = 0,
- .cc_test = DEF_CTEST,
- .cc_test_reg = 0,
- .cc_swz = { 0, 1, 2, 3 },
- };
- return temp;
-}
-
-static INLINE struct nv30_sreg
-nv30_sr_swz(struct nv30_sreg src, int x, int y, int z, int w)
-{
- struct nv30_sreg dst = src;
-
- dst.swz[SWZ_X] = src.swz[x];
- dst.swz[SWZ_Y] = src.swz[y];
- dst.swz[SWZ_Z] = src.swz[z];
- dst.swz[SWZ_W] = src.swz[w];
- return dst;
-}
-
-static INLINE struct nv30_sreg
-nv30_sr_neg(struct nv30_sreg src)
-{
- src.negate = !src.negate;
- return src;
-}
-
-static INLINE struct nv30_sreg
-nv30_sr_abs(struct nv30_sreg src)
-{
- src.abs = 1;
- return src;
-}
-
-static INLINE struct nv30_sreg
-nv30_sr_scale(struct nv30_sreg src, int scale)
-{
- src.dst_scale = scale;
- return src;
-}
-
-#endif
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
deleted file mode 100644
index d911c807074..00000000000
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ /dev/null
@@ -1,728 +0,0 @@
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "tgsi/tgsi_parse.h"
-
-#include "nv30_context.h"
-#include "nv30_state.h"
-
-static void *
-nv30_blend_state_create(struct pipe_context *pipe,
- const struct pipe_blend_state *cso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nouveau_grobj *rankine = nv30->screen->rankine;
- struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso));
- struct nouveau_stateobj *so = so_new(5, 8, 0);
-
- if (cso->rt[0].blend_enable) {
- so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3);
- so_data (so, 1);
- so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
- nvgl_blend_func(cso->rt[0].rgb_src_factor));
- so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 |
- nvgl_blend_func(cso->rt[0].rgb_dst_factor));
- /* FIXME: Gallium assumes GL_EXT_blend_func_separate.
- It is not the case for NV30 */
- so_method(so, rankine, NV34TCL_BLEND_EQUATION, 1);
- so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
- } else {
- so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_method(so, rankine, NV34TCL_COLOR_MASK, 1);
- so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
-
- if (cso->logicop_enable) {
- so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2);
- so_data (so, 1);
- so_data (so, nvgl_logicop_func(cso->logicop_func));
- } else {
- so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_method(so, rankine, NV34TCL_DITHER_ENABLE, 1);
- so_data (so, cso->dither ? 1 : 0);
-
- so_ref(so, &bso->so);
- so_ref(NULL, &so);
- bso->pipe = *cso;
- return (void *)bso;
-}
-
-static void
-nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->blend = hwcso;
- nv30->dirty |= NV30_NEW_BLEND;
-}
-
-static void
-nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_blend_state *bso = hwcso;
-
- so_ref(NULL, &bso->so);
- FREE(bso);
-}
-
-
-static INLINE unsigned
-wrap_mode(unsigned wrap) {
- unsigned ret;
-
- switch (wrap) {
- case PIPE_TEX_WRAP_REPEAT:
- ret = NV34TCL_TX_WRAP_S_REPEAT;
- break;
- case PIPE_TEX_WRAP_MIRROR_REPEAT:
- ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
- break;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
- break;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
- break;
- case PIPE_TEX_WRAP_CLAMP:
- ret = NV34TCL_TX_WRAP_S_CLAMP;
- break;
-/* case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
- break;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
- break;
- case PIPE_TEX_WRAP_MIRROR_CLAMP:
- ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP;
- break;*/
- default:
- NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
- ret = NV34TCL_TX_WRAP_S_REPEAT;
- break;
- }
-
- return ret >> NV34TCL_TX_WRAP_S_SHIFT;
-}
-
-static void *
-nv30_sampler_state_create(struct pipe_context *pipe,
- const struct pipe_sampler_state *cso)
-{
- struct nv30_sampler_state *ps;
- uint32_t filter = 0;
-
- ps = MALLOC(sizeof(struct nv30_sampler_state));
-
- ps->fmt = 0;
- /* TODO: Not all RECTs formats have this bit set, bits 15-8 of format
- are the tx format to use. We should store normalized coord flag
- in sampler state structure, and set appropriate format in
- nvxx_fragtex_build()
- */
- /*NV34TCL_TX_FORMAT_RECT*/
- /*if (!cso->normalized_coords) {
- ps->fmt |= (1<<14) ;
- }*/
-
- ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
- (wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
- (wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT));
-
- ps->en = 0;
-
- if (cso->max_anisotropy >= 8) {
- ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
- } else
- if (cso->max_anisotropy >= 4) {
- ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
- } else
- if (cso->max_anisotropy >= 2) {
- ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
- }
-
- switch (cso->mag_img_filter) {
- case PIPE_TEX_FILTER_LINEAR:
- filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
- break;
- case PIPE_TEX_FILTER_NEAREST:
- default:
- filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
- break;
- }
-
- switch (cso->min_img_filter) {
- case PIPE_TEX_FILTER_LINEAR:
- switch (cso->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NEAREST:
- filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
- break;
- case PIPE_TEX_MIPFILTER_LINEAR:
- filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
- break;
- case PIPE_TEX_MIPFILTER_NONE:
- default:
- filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
- break;
- }
- break;
- case PIPE_TEX_FILTER_NEAREST:
- default:
- switch (cso->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NEAREST:
- filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
- break;
- case PIPE_TEX_MIPFILTER_LINEAR:
- filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
- break;
- case PIPE_TEX_MIPFILTER_NONE:
- default:
- filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
- break;
- }
- break;
- }
-
- ps->filt = filter;
-
- {
- float limit;
-
- limit = CLAMP(cso->lod_bias, -16.0, 15.0);
- ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
-
- limit = CLAMP(cso->max_lod, 0.0, 15.0);
- ps->en |= (int)(limit) << 14 /*NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT*/;
-
- limit = CLAMP(cso->min_lod, 0.0, 15.0);
- ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/;
- }
-
- if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- switch (cso->compare_func) {
- case PIPE_FUNC_NEVER:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NEVER;
- break;
- case PIPE_FUNC_GREATER:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GREATER;
- break;
- case PIPE_FUNC_EQUAL:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_EQUAL;
- break;
- case PIPE_FUNC_GEQUAL:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GEQUAL;
- break;
- case PIPE_FUNC_LESS:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LESS;
- break;
- case PIPE_FUNC_NOTEQUAL:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
- break;
- case PIPE_FUNC_LEQUAL:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LEQUAL;
- break;
- case PIPE_FUNC_ALWAYS:
- ps->wrap |= NV34TCL_TX_WRAP_RCOMP_ALWAYS;
- break;
- default:
- break;
- }
- }
-
- ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
- (float_to_ubyte(cso->border_color[0]) << 16) |
- (float_to_ubyte(cso->border_color[1]) << 8) |
- (float_to_ubyte(cso->border_color[2]) << 0));
-
- return (void *)ps;
-}
-
-static void
-nv30_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- unsigned unit;
-
- for (unit = 0; unit < nr; unit++) {
- nv30->tex_sampler[unit] = sampler[unit];
- nv30->dirty_samplers |= (1 << unit);
- }
-
- for (unit = nr; unit < nv30->nr_samplers; unit++) {
- nv30->tex_sampler[unit] = NULL;
- nv30->dirty_samplers |= (1 << unit);
- }
-
- nv30->nr_samplers = nr;
- nv30->dirty |= NV30_NEW_SAMPLER;
-}
-
-static void
-nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- FREE(hwcso);
-}
-
-static void
-nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
- struct pipe_texture **miptree)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- unsigned unit;
-
- for (unit = 0; unit < nr; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nv30->tex_miptree[unit], miptree[unit]);
- nv30->dirty_samplers |= (1 << unit);
- }
-
- for (unit = nr; unit < nv30->nr_textures; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nv30->tex_miptree[unit], NULL);
- nv30->dirty_samplers |= (1 << unit);
- }
-
- nv30->nr_textures = nr;
- nv30->dirty |= NV30_NEW_SAMPLER;
-}
-
-static void *
-nv30_rasterizer_state_create(struct pipe_context *pipe,
- const struct pipe_rasterizer_state *cso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
- struct nouveau_stateobj *so = so_new(9, 19, 0);
- struct nouveau_grobj *rankine = nv30->screen->rankine;
-
- /*XXX: ignored:
- * light_twoside
- * point_smooth -nohw
- * multisample
- */
-
- so_method(so, rankine, NV34TCL_SHADE_MODEL, 1);
- so_data (so, cso->flatshade ? NV34TCL_SHADE_MODEL_FLAT :
- NV34TCL_SHADE_MODEL_SMOOTH);
-
- so_method(so, rankine, NV34TCL_LINE_WIDTH, 2);
- so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
- so_data (so, cso->line_smooth ? 1 : 0);
- so_method(so, rankine, NV34TCL_LINE_STIPPLE_ENABLE, 2);
- so_data (so, cso->line_stipple_enable ? 1 : 0);
- so_data (so, (cso->line_stipple_pattern << 16) |
- cso->line_stipple_factor);
-
- so_method(so, rankine, NV34TCL_POINT_SIZE, 1);
- so_data (so, fui(cso->point_size));
-
- so_method(so, rankine, NV34TCL_POLYGON_MODE_FRONT, 6);
- if (cso->front_winding == PIPE_WINDING_CCW) {
- so_data(so, nvgl_polygon_mode(cso->fill_ccw));
- so_data(so, nvgl_polygon_mode(cso->fill_cw));
- switch (cso->cull_mode) {
- case PIPE_WINDING_CCW:
- so_data(so, NV34TCL_CULL_FACE_FRONT);
- break;
- case PIPE_WINDING_CW:
- so_data(so, NV34TCL_CULL_FACE_BACK);
- break;
- case PIPE_WINDING_BOTH:
- so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
- break;
- default:
- so_data(so, NV34TCL_CULL_FACE_BACK);
- break;
- }
- so_data(so, NV34TCL_FRONT_FACE_CCW);
- } else {
- so_data(so, nvgl_polygon_mode(cso->fill_cw));
- so_data(so, nvgl_polygon_mode(cso->fill_ccw));
- switch (cso->cull_mode) {
- case PIPE_WINDING_CCW:
- so_data(so, NV34TCL_CULL_FACE_BACK);
- break;
- case PIPE_WINDING_CW:
- so_data(so, NV34TCL_CULL_FACE_FRONT);
- break;
- case PIPE_WINDING_BOTH:
- so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
- break;
- default:
- so_data(so, NV34TCL_CULL_FACE_BACK);
- break;
- }
- so_data(so, NV34TCL_FRONT_FACE_CW);
- }
- so_data(so, cso->poly_smooth ? 1 : 0);
- so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0);
-
- so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, cso->poly_stipple_enable ? 1 : 0);
-
- so_method(so, rankine, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
- so_data(so, 1);
- else
- so_data(so, 0);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
- so_data(so, 1);
- else
- so_data(so, 0);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
- so_data(so, 1);
- else
- so_data(so, 0);
- if (cso->offset_cw || cso->offset_ccw) {
- so_method(so, rankine, NV34TCL_POLYGON_OFFSET_FACTOR, 2);
- so_data (so, fui(cso->offset_scale));
- so_data (so, fui(cso->offset_units * 2));
- }
-
- so_method(so, rankine, NV34TCL_POINT_SPRITE, 1);
- if (cso->point_quad_rasterization) {
- unsigned psctl = (1 << 0), i;
-
- for (i = 0; i < 8; i++) {
- if ((cso->sprite_coord_enable >> i) & 1)
- psctl |= (1 << (8 + i));
- }
-
- so_data(so, psctl);
- } else {
- so_data(so, 0);
- }
-
- so_ref(so, &rsso->so);
- so_ref(NULL, &so);
- rsso->pipe = *cso;
- return (void *)rsso;
-}
-
-static void
-nv30_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->rasterizer = hwcso;
- nv30->dirty |= NV30_NEW_RAST;
- /*nv30->draw_dirty |= NV30_NEW_RAST;*/
-}
-
-static void
-nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_rasterizer_state *rsso = hwcso;
-
- so_ref(NULL, &rsso->so);
- FREE(rsso);
-}
-
-static void *
-nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe,
- const struct pipe_depth_stencil_alpha_state *cso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
- struct nouveau_stateobj *so = so_new(6, 20, 0);
- struct nouveau_grobj *rankine = nv30->screen->rankine;
-
- so_method(so, rankine, NV34TCL_DEPTH_FUNC, 3);
- so_data (so, nvgl_comparison_op(cso->depth.func));
- so_data (so, cso->depth.writemask ? 1 : 0);
- so_data (so, cso->depth.enabled ? 1 : 0);
-
- so_method(so, rankine, NV34TCL_ALPHA_FUNC_ENABLE, 3);
- so_data (so, cso->alpha.enabled ? 1 : 0);
- so_data (so, nvgl_comparison_op(cso->alpha.func));
- so_data (so, float_to_ubyte(cso->alpha.ref_value));
-
- if (cso->stencil[0].enabled) {
- so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 3);
- so_data (so, cso->stencil[0].enabled ? 1 : 0);
- so_data (so, cso->stencil[0].writemask);
- so_data (so, nvgl_comparison_op(cso->stencil[0].func));
- so_method(so, rankine, NV34TCL_STENCIL_FRONT_FUNC_MASK, 4);
- so_data (so, cso->stencil[0].valuemask);
- so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
- } else {
- so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1);
- so_data (so, 0);
- }
-
- if (cso->stencil[1].enabled) {
- so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 3);
- so_data (so, cso->stencil[1].enabled ? 1 : 0);
- so_data (so, cso->stencil[1].writemask);
- so_data (so, nvgl_comparison_op(cso->stencil[1].func));
- so_method(so, rankine, NV34TCL_STENCIL_BACK_FUNC_MASK, 4);
- so_data (so, cso->stencil[1].valuemask);
- so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
- } else {
- so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_ref(so, &zsaso->so);
- so_ref(NULL, &so);
- zsaso->pipe = *cso;
- return (void *)zsaso;
-}
-
-static void
-nv30_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->zsa = hwcso;
- nv30->dirty |= NV30_NEW_ZSA;
-}
-
-static void
-nv30_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_zsa_state *zsaso = hwcso;
-
- so_ref(NULL, &zsaso->so);
- FREE(zsaso);
-}
-
-static void *
-nv30_vp_state_create(struct pipe_context *pipe,
- const struct pipe_shader_state *cso)
-{
- /*struct nv30_context *nv30 = nv30_context(pipe);*/
- struct nv30_vertex_program *vp;
-
- vp = CALLOC(1, sizeof(struct nv30_vertex_program));
- vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
- /*vp->draw = draw_create_vertex_shader(nv30->draw, &vp->pipe);*/
-
- return (void *)vp;
-}
-
-static void
-nv30_vp_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->vertprog = hwcso;
- nv30->dirty |= NV30_NEW_VERTPROG;
- /*nv30->draw_dirty |= NV30_NEW_VERTPROG;*/
-}
-
-static void
-nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_vertex_program *vp = hwcso;
-
- /*draw_delete_vertex_shader(nv30->draw, vp->draw);*/
- nv30_vertprog_destroy(nv30, vp);
- FREE((void*)vp->pipe.tokens);
- FREE(vp);
-}
-
-static void *
-nv30_fp_state_create(struct pipe_context *pipe,
- const struct pipe_shader_state *cso)
-{
- struct nv30_fragment_program *fp;
-
- fp = CALLOC(1, sizeof(struct nv30_fragment_program));
- fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
-
- tgsi_scan_shader(fp->pipe.tokens, &fp->info);
-
- return (void *)fp;
-}
-
-static void
-nv30_fp_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->fragprog = hwcso;
- nv30->dirty |= NV30_NEW_FRAGPROG;
-}
-
-static void
-nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_fragment_program *fp = hwcso;
-
- nv30_fragprog_destroy(nv30, fp);
- FREE((void*)fp->pipe.tokens);
- FREE(fp);
-}
-
-static void
-nv30_set_blend_color(struct pipe_context *pipe,
- const struct pipe_blend_color *bcol)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->blend_colour = *bcol;
- nv30->dirty |= NV30_NEW_BCOL;
-}
-
-static void
-nv30_set_stencil_ref(struct pipe_context *pipe,
- const struct pipe_stencil_ref *sr)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->stencil_ref = *sr;
- nv30->dirty |= NV30_NEW_SR;
-}
-
-static void
-nv30_set_clip_state(struct pipe_context *pipe,
- const struct pipe_clip_state *clip)
-{
-}
-
-static void
-nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_buffer *buf )
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->constbuf[shader] = buf;
- nv30->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
-
- if (shader == PIPE_SHADER_VERTEX) {
- nv30->dirty |= NV30_NEW_VERTPROG;
- } else
- if (shader == PIPE_SHADER_FRAGMENT) {
- nv30->dirty |= NV30_NEW_FRAGPROG;
- }
-}
-
-static void
-nv30_set_framebuffer_state(struct pipe_context *pipe,
- const struct pipe_framebuffer_state *fb)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->framebuffer = *fb;
- nv30->dirty |= NV30_NEW_FB;
-}
-
-static void
-nv30_set_polygon_stipple(struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- memcpy(nv30->stipple, stipple->stipple, 4 * 32);
- nv30->dirty |= NV30_NEW_STIPPLE;
-}
-
-static void
-nv30_set_scissor_state(struct pipe_context *pipe,
- const struct pipe_scissor_state *s)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->scissor = *s;
- nv30->dirty |= NV30_NEW_SCISSOR;
-}
-
-static void
-nv30_set_viewport_state(struct pipe_context *pipe,
- const struct pipe_viewport_state *vpt)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- nv30->viewport = *vpt;
- nv30->dirty |= NV30_NEW_VIEWPORT;
- /*nv30->draw_dirty |= NV30_NEW_VIEWPORT;*/
-}
-
-static void
-nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_buffer *vb)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count);
- nv30->vtxbuf_nr = count;
-
- nv30->dirty |= NV30_NEW_ARRAYS;
- /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
-}
-
-static void
-nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
-{
- struct nv30_context *nv30 = nv30_context(pipe);
-
- memcpy(nv30->vtxelt, ve, sizeof(*ve) * count);
- nv30->vtxelt_nr = count;
-
- nv30->dirty |= NV30_NEW_ARRAYS;
- /*nv30->draw_dirty |= NV30_NEW_ARRAYS;*/
-}
-
-void
-nv30_init_state_functions(struct nv30_context *nv30)
-{
- nv30->pipe.create_blend_state = nv30_blend_state_create;
- nv30->pipe.bind_blend_state = nv30_blend_state_bind;
- nv30->pipe.delete_blend_state = nv30_blend_state_delete;
-
- nv30->pipe.create_sampler_state = nv30_sampler_state_create;
- nv30->pipe.bind_fragment_sampler_states = nv30_sampler_state_bind;
- nv30->pipe.delete_sampler_state = nv30_sampler_state_delete;
- nv30->pipe.set_fragment_sampler_textures = nv30_set_sampler_texture;
-
- nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create;
- nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind;
- nv30->pipe.delete_rasterizer_state = nv30_rasterizer_state_delete;
-
- nv30->pipe.create_depth_stencil_alpha_state =
- nv30_depth_stencil_alpha_state_create;
- nv30->pipe.bind_depth_stencil_alpha_state =
- nv30_depth_stencil_alpha_state_bind;
- nv30->pipe.delete_depth_stencil_alpha_state =
- nv30_depth_stencil_alpha_state_delete;
-
- nv30->pipe.create_vs_state = nv30_vp_state_create;
- nv30->pipe.bind_vs_state = nv30_vp_state_bind;
- nv30->pipe.delete_vs_state = nv30_vp_state_delete;
-
- nv30->pipe.create_fs_state = nv30_fp_state_create;
- nv30->pipe.bind_fs_state = nv30_fp_state_bind;
- nv30->pipe.delete_fs_state = nv30_fp_state_delete;
-
- nv30->pipe.set_blend_color = nv30_set_blend_color;
- nv30->pipe.set_stencil_ref = nv30_set_stencil_ref;
- nv30->pipe.set_clip_state = nv30_set_clip_state;
- nv30->pipe.set_constant_buffer = nv30_set_constant_buffer;
- nv30->pipe.set_framebuffer_state = nv30_set_framebuffer_state;
- nv30->pipe.set_polygon_stipple = nv30_set_polygon_stipple;
- nv30->pipe.set_scissor_state = nv30_set_scissor_state;
- nv30->pipe.set_viewport_state = nv30_set_viewport_state;
-
- nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
- nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
-}
-
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
deleted file mode 100644
index e42e872de75..00000000000
--- a/src/gallium/drivers/nv30/nv30_state.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef __NV30_STATE_H__
-#define __NV30_STATE_H__
-
-#include "pipe/p_state.h"
-#include "tgsi/tgsi_scan.h"
-
-struct nv30_sampler_state {
- uint32_t fmt;
- uint32_t wrap;
- uint32_t en;
- uint32_t filt;
- uint32_t bcol;
-};
-
-struct nv30_vertex_program_exec {
- uint32_t data[4];
- boolean has_branch_offset;
- int const_index;
-};
-
-struct nv30_vertex_program_data {
- int index; /* immediates == -1 */
- float value[4];
-};
-
-struct nv30_vertex_program {
- struct pipe_shader_state pipe;
-
- boolean translated;
-
- struct nv30_vertex_program_exec *insns;
- unsigned nr_insns;
- struct nv30_vertex_program_data *consts;
- unsigned nr_consts;
-
- struct nouveau_resource *exec;
- unsigned exec_start;
- struct nouveau_resource *data;
- unsigned data_start;
- unsigned data_start_min;
-
- uint32_t ir;
- uint32_t or;
- struct nouveau_stateobj *so;
-};
-
-struct nv30_fragment_program_data {
- unsigned offset;
- unsigned index;
-};
-
-struct nv30_fragment_program {
- struct pipe_shader_state pipe;
- struct tgsi_shader_info info;
-
- boolean translated;
- boolean on_hw;
- unsigned samplers;
-
- uint32_t *insn;
- int insn_len;
-
- struct nv30_fragment_program_data *consts;
- unsigned nr_consts;
-
- struct pipe_buffer *buffer;
-
- uint32_t fp_control;
- uint32_t fp_reg_control;
- struct nouveau_stateobj *so;
-};
-
-struct nv30_miptree {
- struct pipe_texture base;
- struct nouveau_bo *bo;
-
- struct pipe_buffer *buffer;
- uint total_size;
-
- struct {
- uint pitch;
- uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
-};
-
-#endif
diff --git a/src/gallium/drivers/nv30/nv30_state_blend.c b/src/gallium/drivers/nv30/nv30_state_blend.c
deleted file mode 100644
index c36d58c040c..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_blend.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_blend_validate(struct nv30_context *nv30)
-{
- so_ref(nv30->blend->so, &nv30->state.hw[NV30_STATE_BLEND]);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_blend = {
- .validate = nv30_state_blend_validate,
- .dirty = {
- .pipe = NV30_NEW_BLEND,
- .hw = NV30_STATE_BLEND
- }
-};
-
-static boolean
-nv30_state_blend_colour_validate(struct nv30_context *nv30)
-{
- struct nouveau_stateobj *so = so_new(1, 1, 0);
- struct pipe_blend_color *bcol = &nv30->blend_colour;
-
- so_method(so, nv30->screen->rankine, NV34TCL_BLEND_COLOR, 1);
- so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) |
- (float_to_ubyte(bcol->color[0]) << 16) |
- (float_to_ubyte(bcol->color[1]) << 8) |
- (float_to_ubyte(bcol->color[2]) << 0)));
-
- so_ref(so, &nv30->state.hw[NV30_STATE_BCOL]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_blend_colour = {
- .validate = nv30_state_blend_colour_validate,
- .dirty = {
- .pipe = NV30_NEW_BCOL,
- .hw = NV30_STATE_BCOL
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c
deleted file mode 100644
index deefe7fd8db..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_emit.c
+++ /dev/null
@@ -1,122 +0,0 @@
-#include "nv30_context.h"
-#include "nv30_state.h"
-
-static struct nv30_state_entry *render_states[] = {
- &nv30_state_framebuffer,
- &nv30_state_rasterizer,
- &nv30_state_scissor,
- &nv30_state_stipple,
- &nv30_state_fragprog,
- &nv30_state_fragtex,
- &nv30_state_vertprog,
- &nv30_state_blend,
- &nv30_state_blend_colour,
- &nv30_state_zsa,
- &nv30_state_sr,
- &nv30_state_viewport,
- &nv30_state_vbo,
- NULL
-};
-
-static void
-nv30_state_do_validate(struct nv30_context *nv30,
- struct nv30_state_entry **states)
-{
- while (*states) {
- struct nv30_state_entry *e = *states;
-
- if (nv30->dirty & e->dirty.pipe) {
- if (e->validate(nv30)) {
- nv30->state.dirty |= (1ULL << e->dirty.hw);
- }
- }
-
- states++;
- }
- nv30->dirty = 0;
-}
-
-void
-nv30_state_emit(struct nv30_context *nv30)
-{
- struct nouveau_channel *chan = nv30->screen->base.channel;
- struct nv30_state *state = &nv30->state;
- struct nv30_screen *screen = nv30->screen;
- unsigned i;
- uint64_t states;
-
- /* XXX: racy!
- */
- if (nv30 != screen->cur_ctx) {
- for (i = 0; i < NV30_STATE_MAX; i++) {
- if (state->hw[i] && screen->state[i] != state->hw[i])
- state->dirty |= (1ULL << i);
- }
-
- screen->cur_ctx = nv30;
- }
-
- for (i = 0, states = state->dirty; states; i++) {
- if (!(states & (1ULL << i)))
- continue;
- so_ref (state->hw[i], &nv30->screen->state[i]);
- if (state->hw[i])
- so_emit(chan, nv30->screen->state[i]);
- states &= ~(1ULL << i);
- }
-
- state->dirty = 0;
-}
-
-void
-nv30_state_flush_notify(struct nouveau_channel *chan)
-{
- struct nv30_context *nv30 = chan->user_private;
- struct nv30_state *state = &nv30->state;
- unsigned i, samplers;
-
- so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]);
- for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
- if (!(samplers & (1 << i)))
- continue;
- so_emit_reloc_markers(chan,
- state->hw[NV30_STATE_FRAGTEX0+i]);
- samplers &= ~(1ULL << i);
- }
- so_emit_reloc_markers(chan, state->hw[NV30_STATE_FRAGPROG]);
- if (state->hw[NV30_STATE_VTXBUF] /*&& nv30->render_mode == HW*/)
- so_emit_reloc_markers(chan, state->hw[NV30_STATE_VTXBUF]);
-}
-
-boolean
-nv30_state_validate(struct nv30_context *nv30)
-{
-#if 0
- boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
-
- if (nv30->render_mode != HW) {
- /* Don't even bother trying to go back to hw if none
- * of the states that caused swtnl previously have changed.
- */
- if ((nv30->fallback_swtnl & nv30->dirty)
- != nv30->fallback_swtnl)
- return FALSE;
-
- /* Attempt to go to hwtnl again */
- nv30->pipe.flush(&nv30->pipe, 0, NULL);
- nv30->dirty |= (NV30_NEW_VIEWPORT |
- NV30_NEW_VERTPROG |
- NV30_NEW_ARRAYS);
- nv30->render_mode = HW;
- }
-#endif
- nv30_state_do_validate(nv30, render_states);
-#if 0
- if (nv30->fallback_swtnl || nv30->fallback_swrast)
- return FALSE;
-
- if (was_sw)
- NOUVEAU_ERR("swtnl->hw\n");
-#endif
- return TRUE;
-}
diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c
deleted file mode 100644
index f7fe9833c77..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_fb.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "nv30_context.h"
-#include "nouveau/nouveau_util.h"
-
-static boolean
-nv30_state_framebuffer_validate(struct nv30_context *nv30)
-{
- struct pipe_framebuffer_state *fb = &nv30->framebuffer;
- struct nouveau_channel *chan = nv30->screen->base.channel;
- struct nouveau_grobj *rankine = nv30->screen->rankine;
- struct nv04_surface *rt[2], *zeta = NULL;
- uint32_t rt_enable = 0, rt_format = 0;
- int i, colour_format = 0, zeta_format = 0, depth_only = 0;
- struct nouveau_stateobj *so = so_new(12, 18, 10);
- unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
- unsigned w = fb->width;
- unsigned h = fb->height;
- struct nv30_miptree *nv30mt;
- int colour_bits = 32, zeta_bits = 32;
-
- for (i = 0; i < fb->nr_cbufs; i++) {
- if (colour_format) {
- assert(colour_format == fb->cbufs[i]->format);
- } else {
- colour_format = fb->cbufs[i]->format;
- rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
- rt[i] = (struct nv04_surface *)fb->cbufs[i];
- }
- }
-
- if (rt_enable & NV34TCL_RT_ENABLE_COLOR1)
- rt_enable |= NV34TCL_RT_ENABLE_MRT;
-
- if (fb->zsbuf) {
- zeta_format = fb->zsbuf->format;
- zeta = (struct nv04_surface *)fb->zsbuf;
- }
-
- if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0|NV34TCL_RT_ENABLE_COLOR1)) {
- /* Render to at least a colour buffer */
- if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
- assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
- for (i = 1; i < fb->nr_cbufs; i++)
- assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
-
- rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
- (log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
- (log2i(rt[0]->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
- }
- else
- rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
- } else if (fb->zsbuf) {
- depth_only = 1;
-
- /* Render to depth buffer only */
- if (!(zeta->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
- assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
-
- rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
- (log2i(zeta->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
- (log2i(zeta->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
- }
- else
- rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
- } else {
- return FALSE;
- }
-
- switch (colour_format) {
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- rt_format |= NV34TCL_RT_FORMAT_COLOR_X8R8G8B8;
- break;
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case 0:
- rt_format |= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8;
- break;
- case PIPE_FORMAT_B5G6R5_UNORM:
- rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5;
- colour_bits = 16;
- break;
- default:
- assert(0);
- }
-
- switch (zeta_format) {
- case PIPE_FORMAT_Z16_UNORM:
- rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16;
- zeta_bits = 16;
- break;
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case 0:
- rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8;
- break;
- default:
- assert(0);
- }
-
- if (colour_bits > zeta_bits) {
- return FALSE;
- }
-
- if (depth_only || (rt_enable & NV34TCL_RT_ENABLE_COLOR0)) {
- struct nv04_surface *rt0 = (depth_only ? zeta : rt[0]);
- uint32_t pitch = rt0->pitch;
-
- if (zeta) {
- pitch |= (zeta->pitch << 16);
- } else {
- pitch |= (pitch << 16);
- }
-
- nv30mt = (struct nv30_miptree *) rt0->base.texture;
- so_method(so, rankine, NV34TCL_DMA_COLOR0, 1);
- so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, rankine, NV34TCL_COLOR0_PITCH, 2);
- so_data (so, pitch);
- so_reloc (so, nouveau_bo(nv30mt->buffer), rt0->base.offset,
- rt_flags | NOUVEAU_BO_LOW, 0, 0);
- }
-
- if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
- nv30mt = (struct nv30_miptree *)rt[1]->base.texture;
- so_method(so, rankine, NV34TCL_DMA_COLOR1, 1);
- so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, rankine, NV34TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nouveau_bo(nv30mt->buffer), rt[1]->base.offset,
- rt_flags | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, rt[1]->pitch);
- }
-
- if (zeta_format) {
- nv30mt = (struct nv30_miptree *)zeta->base.texture;
- so_method(so, rankine, NV34TCL_DMA_ZETA, 1);
- so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, rankine, NV34TCL_ZETA_OFFSET, 1);
- so_reloc (so, nouveau_bo(nv30mt->buffer), zeta->base.offset,
- rt_flags | NOUVEAU_BO_LOW, 0, 0);
- /* TODO: allocate LMA depth buffer */
- }
-
- so_method(so, rankine, NV34TCL_RT_ENABLE, 1);
- so_data (so, rt_enable);
- so_method(so, rankine, NV34TCL_RT_HORIZ, 3);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_data (so, rt_format);
- so_method(so, rankine, NV34TCL_VIEWPORT_HORIZ, 2);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_method(so, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
- so_data (so, ((w - 1) << 16) | 0);
- so_data (so, ((h - 1) << 16) | 0);
- so_method(so, rankine, 0x1d88, 1);
- so_data (so, (1 << 12) | h);
- /* Wonder why this is needed, context should all be set to zero on init */
- so_method(so, rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
- so_data (so, 0);
-
- so_ref(so, &nv30->state.hw[NV30_STATE_FB]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_framebuffer = {
- .validate = nv30_state_framebuffer_validate,
- .dirty = {
- .pipe = NV30_NEW_FB,
- .hw = NV30_STATE_FB
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_rasterizer.c b/src/gallium/drivers/nv30/nv30_state_rasterizer.c
deleted file mode 100644
index 6d1b60e043d..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_rasterizer.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_rasterizer_validate(struct nv30_context *nv30)
-{
- so_ref(nv30->rasterizer->so,
- &nv30->state.hw[NV30_STATE_RAST]);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_rasterizer = {
- .validate = nv30_state_rasterizer_validate,
- .dirty = {
- .pipe = NV30_NEW_RAST,
- .hw = NV30_STATE_RAST
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_scissor.c b/src/gallium/drivers/nv30/nv30_state_scissor.c
deleted file mode 100644
index ba61a9e24a4..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_scissor.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_scissor_validate(struct nv30_context *nv30)
-{
- struct pipe_rasterizer_state *rast = &nv30->rasterizer->pipe;
- struct pipe_scissor_state *s = &nv30->scissor;
- struct nouveau_stateobj *so;
-
- if (nv30->state.hw[NV30_STATE_SCISSOR] &&
- (rast->scissor == 0 && nv30->state.scissor_enabled == 0))
- return FALSE;
- nv30->state.scissor_enabled = rast->scissor;
-
- so = so_new(1, 2, 0);
- so_method(so, nv30->screen->rankine, NV34TCL_SCISSOR_HORIZ, 2);
- if (nv30->state.scissor_enabled) {
- so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
- so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
- } else {
- so_data (so, 4096 << 16);
- so_data (so, 4096 << 16);
- }
-
- so_ref(so, &nv30->state.hw[NV30_STATE_SCISSOR]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_scissor = {
- .validate = nv30_state_scissor_validate,
- .dirty = {
- .pipe = NV30_NEW_SCISSOR | NV30_NEW_RAST,
- .hw = NV30_STATE_SCISSOR
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_stipple.c b/src/gallium/drivers/nv30/nv30_state_stipple.c
deleted file mode 100644
index ed520a4f439..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_stipple.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_stipple_validate(struct nv30_context *nv30)
-{
- struct pipe_rasterizer_state *rast = &nv30->rasterizer->pipe;
- struct nouveau_grobj *rankine = nv30->screen->rankine;
- struct nouveau_stateobj *so;
-
- if (nv30->state.hw[NV30_STATE_STIPPLE] &&
- (rast->poly_stipple_enable == 0 && nv30->state.stipple_enabled == 0))
- return FALSE;
-
- if (rast->poly_stipple_enable) {
- unsigned i;
-
- so = so_new(2, 33, 0);
- so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, 1);
- so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, nv30->stipple[i]);
- } else {
- so = so_new(1, 1, 0);
- so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_ref(so, &nv30->state.hw[NV30_STATE_STIPPLE]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_stipple = {
- .validate = nv30_state_stipple_validate,
- .dirty = {
- .pipe = NV30_NEW_STIPPLE | NV30_NEW_RAST,
- .hw = NV30_STATE_STIPPLE,
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_viewport.c b/src/gallium/drivers/nv30/nv30_state_viewport.c
deleted file mode 100644
index 6fccd6b60e7..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_viewport.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_viewport_validate(struct nv30_context *nv30)
-{
- struct pipe_viewport_state *vpt = &nv30->viewport;
- struct nouveau_stateobj *so;
-
- if (nv30->state.hw[NV30_STATE_VIEWPORT] &&
- !(nv30->dirty & NV30_NEW_VIEWPORT))
- return FALSE;
-
- so = so_new(3, 10, 0);
- so_method(so, nv30->screen->rankine,
- NV34TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(vpt->translate[0]));
- so_data (so, fui(vpt->translate[1]));
- so_data (so, fui(vpt->translate[2]));
- so_data (so, fui(vpt->translate[3]));
- so_data (so, fui(vpt->scale[0]));
- so_data (so, fui(vpt->scale[1]));
- so_data (so, fui(vpt->scale[2]));
- so_data (so, fui(vpt->scale[3]));
-/* so_method(so, nv30->screen->rankine, 0x1d78, 1);
- so_data (so, 1);
-*/
- /* TODO/FIXME: never saw value 0x0110 in renouveau dumps, only 0x0001 */
- so_method(so, nv30->screen->rankine, 0x1d78, 1);
- so_data (so, 1);
-
- so_ref(so, &nv30->state.hw[NV30_STATE_VIEWPORT]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_viewport = {
- .validate = nv30_state_viewport_validate,
- .dirty = {
- .pipe = NV30_NEW_VIEWPORT | NV30_NEW_RAST,
- .hw = NV30_STATE_VIEWPORT
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_state_zsa.c b/src/gallium/drivers/nv30/nv30_state_zsa.c
deleted file mode 100644
index 88cd74f180a..00000000000
--- a/src/gallium/drivers/nv30/nv30_state_zsa.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "nv30_context.h"
-
-static boolean
-nv30_state_zsa_validate(struct nv30_context *nv30)
-{
- so_ref(nv30->zsa->so,
- &nv30->state.hw[NV30_STATE_ZSA]);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_zsa = {
- .validate = nv30_state_zsa_validate,
- .dirty = {
- .pipe = NV30_NEW_ZSA,
- .hw = NV30_STATE_ZSA
- }
-};
-
-static boolean
-nv30_state_sr_validate(struct nv30_context *nv30)
-{
- struct nouveau_stateobj *so = so_new(2, 2, 0);
- struct pipe_stencil_ref *sr = &nv30->stencil_ref;
-
- so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_FRONT_FUNC_REF, 1);
- so_data (so, sr->ref_value[0]);
- so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_BACK_FUNC_REF, 1);
- so_data (so, sr->ref_value[1]);
-
- so_ref(so, &nv30->state.hw[NV30_STATE_SR]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv30_state_entry nv30_state_sr = {
- .validate = nv30_state_sr_validate,
- .dirty = {
- .pipe = NV30_NEW_SR,
- .hw = NV30_STATE_SR
- }
-};
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
deleted file mode 100644
index 3aeda51ea19..00000000000
--- a/src/gallium/drivers/nv30/nv30_transfer.c
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "nouveau/nouveau_winsys.h"
-#include "nv30_context.h"
-#include "nv30_screen.h"
-#include "nv30_state.h"
-
-struct nv30_transfer {
- struct pipe_transfer base;
- struct pipe_surface *surface;
- boolean direct;
-};
-
-static void
-nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
- struct pipe_texture *template)
-{
- memset(template, 0, sizeof(struct pipe_texture));
- template->target = pt->target;
- template->format = pt->format;
- template->width0 = width;
- template->height0 = height;
- template->depth0 = 1;
- template->last_level = 0;
- template->nr_samples = pt->nr_samples;
-
- template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
-}
-
-static struct pipe_transfer *
-nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- struct nv30_miptree *mt = (struct nv30_miptree *)pt;
- struct nv30_transfer *tx;
- struct pipe_texture tx_tex_template, *tx_tex;
-
- tx = CALLOC_STRUCT(nv30_transfer);
- if (!tx)
- return NULL;
-
- pipe_texture_reference(&tx->base.texture, pt);
- tx->base.x = x;
- tx->base.y = y;
- tx->base.width = w;
- tx->base.height = h;
- tx->base.stride = mt->level[level].pitch;
- tx->base.usage = usage;
- tx->base.face = face;
- tx->base.level = level;
- tx->base.zslice = zslice;
-
- /* Direct access to texture */
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
- pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
- {
- tx->direct = true;
- tx->surface = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
- pipe_transfer_buffer_flags(&tx->base));
- return &tx->base;
- }
-
- tx->direct = false;
-
- nv30_compatible_transfer_tex(pt, w, h, &tx_tex_template);
-
- tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
- if (!tx_tex)
- {
- FREE(tx);
- return NULL;
- }
-
- tx->base.stride = ((struct nv30_miptree*)tx_tex)->level[0].pitch;
-
- tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
- 0, 0, 0,
- pipe_transfer_buffer_flags(&tx->base));
-
- pipe_texture_reference(&tx_tex, NULL);
-
- if (!tx->surface)
- {
- pipe_surface_reference(&tx->surface, NULL);
- FREE(tx);
- return NULL;
- }
-
- if (usage & PIPE_TRANSFER_READ) {
- struct nv30_screen *nvscreen = nv30_screen(pscreen);
- struct pipe_surface *src;
-
- src = pscreen->get_tex_surface(pscreen, pt,
- face, level, zslice,
- PIPE_BUFFER_USAGE_GPU_READ);
-
- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
- /* TODO: Check if SIFM can un-swizzle */
- nvscreen->eng2d->copy(nvscreen->eng2d,
- tx->surface, 0, 0,
- src, x, y,
- w, h);
-
- pipe_surface_reference(&src, NULL);
- }
-
- return &tx->base;
-}
-
-static void
-nv30_transfer_del(struct pipe_transfer *ptx)
-{
- struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
-
- if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = ptx->texture->screen;
- struct nv30_screen *nvscreen = nv30_screen(pscreen);
- struct pipe_surface *dst;
-
- dst = pscreen->get_tex_surface(pscreen, ptx->texture,
- ptx->face, ptx->level, ptx->zslice,
- PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER);
-
- /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
- nvscreen->eng2d->copy(nvscreen->eng2d,
- dst, tx->base.x, tx->base.y,
- tx->surface, 0, 0,
- tx->base.width, tx->base.height);
-
- pipe_surface_reference(&dst, NULL);
- }
-
- pipe_surface_reference(&tx->surface, NULL);
- pipe_texture_reference(&ptx->texture, NULL);
- FREE(ptx);
-}
-
-static void *
-nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
-{
- struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
- struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
- struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
- void *map = pipe_buffer_map(pscreen, mt->buffer,
- pipe_transfer_buffer_flags(ptx));
-
- if(!tx->direct)
- return map + ns->base.offset;
- else
- return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format);
-}
-
-static void
-nv30_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
-{
- struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
- struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
-
- pipe_buffer_unmap(pscreen, mt->buffer);
-}
-
-void
-nv30_screen_init_transfer_functions(struct pipe_screen *pscreen)
-{
- pscreen->get_tex_transfer = nv30_transfer_new;
- pscreen->tex_transfer_destroy = nv30_transfer_del;
- pscreen->transfer_map = nv30_transfer_map;
- pscreen->transfer_unmap = nv30_transfer_unmap;
-}
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
deleted file mode 100644
index 809be3712da..00000000000
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ /dev/null
@@ -1,842 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_dump.h"
-
-#include "nv30_context.h"
-#include "nv30_state.h"
-
-/* TODO (at least...):
- * 1. Indexed consts + ARL
- * 2. Arb. swz/negation
- * 3. NV_vp11, NV_vp2, NV_vp3 features
- * - extra arith opcodes
- * - branching
- * - texture sampling
- * - indexed attribs
- * - indexed results
- * 4. bugs
- */
-
-#define SWZ_X 0
-#define SWZ_Y 1
-#define SWZ_Z 2
-#define SWZ_W 3
-#define MASK_X 8
-#define MASK_Y 4
-#define MASK_Z 2
-#define MASK_W 1
-#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W)
-#define DEF_SCALE 0
-#define DEF_CTEST 0
-#include "nv30_shader.h"
-
-#define swz(s,x,y,z,w) nv30_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w)
-#define neg(s) nv30_sr_neg((s))
-#define abs(s) nv30_sr_abs((s))
-
-struct nv30_vpc {
- struct nv30_vertex_program *vp;
-
- struct nv30_vertex_program_exec *vpi;
-
- unsigned output_map[PIPE_MAX_SHADER_OUTPUTS];
-
- int high_temp;
- int temp_temp_count;
-
- struct nv30_sreg *imm;
- unsigned nr_imm;
-};
-
-static struct nv30_sreg
-temp(struct nv30_vpc *vpc)
-{
- int idx;
-
- idx = vpc->temp_temp_count++;
- idx += vpc->high_temp + 1;
- return nv30_sr(NV30SR_TEMP, idx);
-}
-
-static struct nv30_sreg
-constant(struct nv30_vpc *vpc, int pipe, float x, float y, float z, float w)
-{
- struct nv30_vertex_program *vp = vpc->vp;
- struct nv30_vertex_program_data *vpd;
- int idx;
-
- if (pipe >= 0) {
- for (idx = 0; idx < vp->nr_consts; idx++) {
- if (vp->consts[idx].index == pipe)
- return nv30_sr(NV30SR_CONST, idx);
- }
- }
-
- idx = vp->nr_consts++;
- vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts);
- vpd = &vp->consts[idx];
-
- vpd->index = pipe;
- vpd->value[0] = x;
- vpd->value[1] = y;
- vpd->value[2] = z;
- vpd->value[3] = w;
- return nv30_sr(NV30SR_CONST, idx);
-}
-
-#define arith(cc,s,o,d,m,s0,s1,s2) \
- nv30_vp_arith((cc), (s), NV30_VP_INST_##o, (d), (m), (s0), (s1), (s2))
-
-static void
-emit_src(struct nv30_vpc *vpc, uint32_t *hw, int pos, struct nv30_sreg src)
-{
- struct nv30_vertex_program *vp = vpc->vp;
- uint32_t sr = 0;
-
- switch (src.type) {
- case NV30SR_TEMP:
- sr |= (NV30_VP_SRC_REG_TYPE_TEMP << NV30_VP_SRC_REG_TYPE_SHIFT);
- sr |= (src.index << NV30_VP_SRC_TEMP_SRC_SHIFT);
- break;
- case NV30SR_INPUT:
- sr |= (NV30_VP_SRC_REG_TYPE_INPUT <<
- NV30_VP_SRC_REG_TYPE_SHIFT);
- vp->ir |= (1 << src.index);
- hw[1] |= (src.index << NV30_VP_INST_INPUT_SRC_SHIFT);
- break;
- case NV30SR_CONST:
- sr |= (NV30_VP_SRC_REG_TYPE_CONST <<
- NV30_VP_SRC_REG_TYPE_SHIFT);
- assert(vpc->vpi->const_index == -1 ||
- vpc->vpi->const_index == src.index);
- vpc->vpi->const_index = src.index;
- break;
- case NV30SR_NONE:
- sr |= (NV30_VP_SRC_REG_TYPE_INPUT <<
- NV30_VP_SRC_REG_TYPE_SHIFT);
- break;
- default:
- assert(0);
- }
-
- if (src.negate)
- sr |= NV30_VP_SRC_NEGATE;
-
- if (src.abs)
- hw[0] |= (1 << (21 + pos));
-
- sr |= ((src.swz[0] << NV30_VP_SRC_SWZ_X_SHIFT) |
- (src.swz[1] << NV30_VP_SRC_SWZ_Y_SHIFT) |
- (src.swz[2] << NV30_VP_SRC_SWZ_Z_SHIFT) |
- (src.swz[3] << NV30_VP_SRC_SWZ_W_SHIFT));
-
-/*
- * |VVV|
- * d�.�b
- * \u/
- *
- */
-
- switch (pos) {
- case 0:
- hw[1] |= ((sr & NV30_VP_SRC0_HIGH_MASK) >>
- NV30_VP_SRC0_HIGH_SHIFT) << NV30_VP_INST_SRC0H_SHIFT;
- hw[2] |= (sr & NV30_VP_SRC0_LOW_MASK) <<
- NV30_VP_INST_SRC0L_SHIFT;
- break;
- case 1:
- hw[2] |= sr << NV30_VP_INST_SRC1_SHIFT;
- break;
- case 2:
- hw[2] |= ((sr & NV30_VP_SRC2_HIGH_MASK) >>
- NV30_VP_SRC2_HIGH_SHIFT) << NV30_VP_INST_SRC2H_SHIFT;
- hw[3] |= (sr & NV30_VP_SRC2_LOW_MASK) <<
- NV30_VP_INST_SRC2L_SHIFT;
- break;
- default:
- assert(0);
- }
-}
-
-static void
-emit_dst(struct nv30_vpc *vpc, uint32_t *hw, int slot, struct nv30_sreg dst)
-{
- struct nv30_vertex_program *vp = vpc->vp;
-
- switch (dst.type) {
- case NV30SR_TEMP:
- hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT);
- break;
- case NV30SR_OUTPUT:
- switch (dst.index) {
- case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break;
- case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break;
- case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break;
- case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break;
- case NV30_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break;
- case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
- case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break;
- case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break;
- case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break;
- case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break;
- case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break;
- case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
- case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
- case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
- default:
- break;
- }
-
- hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT);
- hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
-
- /*XXX: no way this is entirely correct, someone needs to
- * figure out what exactly it is.
- */
- hw[3] |= 0x800;
- break;
- default:
- assert(0);
- }
-}
-
-static void
-nv30_vp_arith(struct nv30_vpc *vpc, int slot, int op,
- struct nv30_sreg dst, int mask,
- struct nv30_sreg s0, struct nv30_sreg s1,
- struct nv30_sreg s2)
-{
- struct nv30_vertex_program *vp = vpc->vp;
- uint32_t *hw;
-
- vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi));
- vpc->vpi = &vp->insns[vp->nr_insns - 1];
- memset(vpc->vpi, 0, sizeof(*vpc->vpi));
- vpc->vpi->const_index = -1;
-
- hw = vpc->vpi->data;
-
- hw[0] |= (NV30_VP_INST_COND_TR << NV30_VP_INST_COND_SHIFT);
- hw[0] |= ((0 << NV30_VP_INST_COND_SWZ_X_SHIFT) |
- (1 << NV30_VP_INST_COND_SWZ_Y_SHIFT) |
- (2 << NV30_VP_INST_COND_SWZ_Z_SHIFT) |
- (3 << NV30_VP_INST_COND_SWZ_W_SHIFT));
-
- hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT);
-// hw[3] |= NV30_VP_INST_SCA_DEST_TEMP_MASK;
-// hw[3] |= (mask << NV30_VP_INST_VEC_WRITEMASK_SHIFT);
-
- if (dst.type == NV30SR_OUTPUT) {
- if (slot)
- hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT);
- else
- hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT);
- } else {
- if (slot)
- hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT);
- else
- hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT);
- }
-
- emit_dst(vpc, hw, slot, dst);
- emit_src(vpc, hw, 0, s0);
- emit_src(vpc, hw, 1, s1);
- emit_src(vpc, hw, 2, s2);
-}
-
-static INLINE struct nv30_sreg
-tgsi_src(struct nv30_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
- struct nv30_sreg src;
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
- src = nv30_sr(NV30SR_INPUT, fsrc->Register.Index);
- break;
- case TGSI_FILE_CONSTANT:
- src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
- break;
- case TGSI_FILE_IMMEDIATE:
- src = vpc->imm[fsrc->Register.Index];
- break;
- case TGSI_FILE_TEMPORARY:
- if (vpc->high_temp < fsrc->Register.Index)
- vpc->high_temp = fsrc->Register.Index;
- src = nv30_sr(NV30SR_TEMP, fsrc->Register.Index);
- break;
- default:
- NOUVEAU_ERR("bad src file\n");
- break;
- }
-
- src.abs = fsrc->Register.Absolute;
- src.negate = fsrc->Register.Negate;
- src.swz[0] = fsrc->Register.SwizzleX;
- src.swz[1] = fsrc->Register.SwizzleY;
- src.swz[2] = fsrc->Register.SwizzleZ;
- src.swz[3] = fsrc->Register.SwizzleW;
- return src;
-}
-
-static INLINE struct nv30_sreg
-tgsi_dst(struct nv30_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
- struct nv30_sreg dst;
-
- switch (fdst->Register.File) {
- case TGSI_FILE_OUTPUT:
- dst = nv30_sr(NV30SR_OUTPUT,
- vpc->output_map[fdst->Register.Index]);
-
- break;
- case TGSI_FILE_TEMPORARY:
- dst = nv30_sr(NV30SR_TEMP, fdst->Register.Index);
- if (vpc->high_temp < dst.index)
- vpc->high_temp = dst.index;
- break;
- default:
- NOUVEAU_ERR("bad dst file\n");
- break;
- }
-
- return dst;
-}
-
-static INLINE int
-tgsi_mask(uint tgsi)
-{
- int mask = 0;
-
- if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X;
- if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y;
- if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z;
- if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W;
- return mask;
-}
-
-static boolean
-nv30_vertprog_parse_instruction(struct nv30_vpc *vpc,
- const struct tgsi_full_instruction *finst)
-{
- struct nv30_sreg src[3], dst, tmp;
- struct nv30_sreg none = nv30_sr(NV30SR_NONE, 0);
- int mask;
- int ai = -1, ci = -1;
- int i;
-
- if (finst->Instruction.Opcode == TGSI_OPCODE_END)
- return TRUE;
-
- vpc->temp_temp_count = 0;
- for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *fsrc;
-
- fsrc = &finst->Src[i];
- if (fsrc->Register.File == TGSI_FILE_TEMPORARY) {
- src[i] = tgsi_src(vpc, fsrc);
- }
- }
-
- for (i = 0; i < finst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *fsrc;
-
- fsrc = &finst->Src[i];
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
- if (ai == -1 || ai == fsrc->Register.Index) {
- ai = fsrc->Register.Index;
- src[i] = tgsi_src(vpc, fsrc);
- } else {
- src[i] = temp(vpc);
- arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
- tgsi_src(vpc, fsrc), none, none);
- }
- break;
- /*XXX: index comparison is broken now that consts come from
- * two different register files.
- */
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_IMMEDIATE:
- if (ci == -1 || ci == fsrc->Register.Index) {
- ci = fsrc->Register.Index;
- src[i] = tgsi_src(vpc, fsrc);
- } else {
- src[i] = temp(vpc);
- arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
- tgsi_src(vpc, fsrc), none, none);
- }
- break;
- case TGSI_FILE_TEMPORARY:
- /* handled above */
- break;
- default:
- NOUVEAU_ERR("bad src file\n");
- return FALSE;
- }
- }
-
- dst = tgsi_dst(vpc, &finst->Dst[0]);
- mask = tgsi_mask(finst->Dst[0].Register.WriteMask);
-
- switch (finst->Instruction.Opcode) {
- case TGSI_OPCODE_ABS:
- arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
- break;
- case TGSI_OPCODE_ADD:
- arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]);
- break;
- case TGSI_OPCODE_ARL:
- arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_DP3:
- arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_DP4:
- arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_DPH:
- arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_DST:
- arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_EX2:
- arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_EXP:
- arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_FLR:
- arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_FRC:
- arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_LG2:
- arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_LIT:
- arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_LOG:
- arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_MAD:
- arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]);
- break;
- case TGSI_OPCODE_MAX:
- arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_MIN:
- arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_MOV:
- arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none);
- break;
- case TGSI_OPCODE_MUL:
- arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_POW:
- tmp = temp(vpc);
- arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none,
- swz(src[0], X, X, X, X));
- arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X),
- swz(src[1], X, X, X, X), none);
- arith(vpc, 1, OP_EX2, dst, mask, none, none,
- swz(tmp, X, X, X, X));
- break;
- case TGSI_OPCODE_RCP:
- arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_RET:
- break;
- case TGSI_OPCODE_RSQ:
- arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]);
- break;
- case TGSI_OPCODE_SGE:
- arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SGT:
- arith(vpc, 0, OP_SGT, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SLT:
- arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none);
- break;
- case TGSI_OPCODE_SUB:
- arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1]));
- break;
- case TGSI_OPCODE_XPD:
- tmp = temp(vpc);
- arith(vpc, 0, OP_MUL, tmp, mask,
- swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none);
- arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W),
- swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y),
- neg(tmp));
- break;
- default:
- NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static boolean
-nv30_vertprog_parse_decl_output(struct nv30_vpc *vpc,
- const struct tgsi_full_declaration *fdec)
-{
- int hw;
-
- switch (fdec->Semantic.Name) {
- case TGSI_SEMANTIC_POSITION:
- hw = NV30_VP_INST_DEST_POS;
- break;
- case TGSI_SEMANTIC_COLOR:
- if (fdec->Semantic.Index == 0) {
- hw = NV30_VP_INST_DEST_COL0;
- } else
- if (fdec->Semantic.Index == 1) {
- hw = NV30_VP_INST_DEST_COL1;
- } else {
- NOUVEAU_ERR("bad colour semantic index\n");
- return FALSE;
- }
- break;
- case TGSI_SEMANTIC_BCOLOR:
- if (fdec->Semantic.Index == 0) {
- hw = NV30_VP_INST_DEST_BFC0;
- } else
- if (fdec->Semantic.Index == 1) {
- hw = NV30_VP_INST_DEST_BFC1;
- } else {
- NOUVEAU_ERR("bad bcolour semantic index\n");
- return FALSE;
- }
- break;
- case TGSI_SEMANTIC_FOG:
- hw = NV30_VP_INST_DEST_FOGC;
- break;
- case TGSI_SEMANTIC_PSIZE:
- hw = NV30_VP_INST_DEST_PSZ;
- break;
- case TGSI_SEMANTIC_GENERIC:
- if (fdec->Semantic.Index <= 7) {
- hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index);
- } else {
- NOUVEAU_ERR("bad generic semantic index\n");
- return FALSE;
- }
- break;
- case TGSI_SEMANTIC_EDGEFLAG:
- NOUVEAU_ERR("cannot handle edgeflag output\n");
- return FALSE;
- default:
- NOUVEAU_ERR("bad output semantic\n");
- return FALSE;
- }
-
- vpc->output_map[fdec->Range.First] = hw;
- return TRUE;
-}
-
-static boolean
-nv30_vertprog_prepare(struct nv30_vpc *vpc)
-{
- struct tgsi_parse_context p;
- int nr_imm = 0;
-
- tgsi_parse_init(&p, vpc->vp->pipe.tokens);
- while (!tgsi_parse_end_of_tokens(&p)) {
- const union tgsi_full_token *tok = &p.FullToken;
-
- tgsi_parse_token(&p);
- switch(tok->Token.Type) {
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- nr_imm++;
- break;
- default:
- break;
- }
- }
- tgsi_parse_free(&p);
-
- if (nr_imm) {
- vpc->imm = CALLOC(nr_imm, sizeof(struct nv30_sreg));
- assert(vpc->imm);
- }
-
- return TRUE;
-}
-
-static void
-nv30_vertprog_translate(struct nv30_context *nv30,
- struct nv30_vertex_program *vp)
-{
- struct tgsi_parse_context parse;
- struct nv30_vpc *vpc = NULL;
-
- tgsi_dump(vp->pipe.tokens,0);
-
- vpc = CALLOC(1, sizeof(struct nv30_vpc));
- if (!vpc)
- return;
- vpc->vp = vp;
- vpc->high_temp = -1;
-
- if (!nv30_vertprog_prepare(vpc)) {
- FREE(vpc);
- return;
- }
-
- tgsi_parse_init(&parse, vp->pipe.tokens);
-
- while (!tgsi_parse_end_of_tokens(&parse)) {
- tgsi_parse_token(&parse);
-
- switch (parse.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- {
- const struct tgsi_full_declaration *fdec;
- fdec = &parse.FullToken.FullDeclaration;
- switch (fdec->Declaration.File) {
- case TGSI_FILE_OUTPUT:
- if (!nv30_vertprog_parse_decl_output(vpc, fdec))
- goto out_err;
- break;
- default:
- break;
- }
- }
- break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- {
- const struct tgsi_full_immediate *imm;
-
- imm = &parse.FullToken.FullImmediate;
- assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
- assert(imm->Immediate.NrTokens == 4 + 1);
- vpc->imm[vpc->nr_imm++] =
- constant(vpc, -1,
- imm->u[0].Float,
- imm->u[1].Float,
- imm->u[2].Float,
- imm->u[3].Float);
- }
- break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- {
- const struct tgsi_full_instruction *finst;
- finst = &parse.FullToken.FullInstruction;
- if (!nv30_vertprog_parse_instruction(vpc, finst))
- goto out_err;
- }
- break;
- default:
- break;
- }
- }
-
- vp->insns[vp->nr_insns - 1].data[3] |= NV30_VP_INST_LAST;
- vp->translated = TRUE;
-out_err:
- tgsi_parse_free(&parse);
- FREE(vpc);
-}
-
-static boolean
-nv30_vertprog_validate(struct nv30_context *nv30)
-{
- struct pipe_screen *pscreen = nv30->pipe.screen;
- struct nv30_screen *screen = nv30->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
- struct nv30_vertex_program *vp;
- struct pipe_buffer *constbuf;
- boolean upload_code = FALSE, upload_data = FALSE;
- int i;
-
- vp = nv30->vertprog;
- constbuf = nv30->constbuf[PIPE_SHADER_VERTEX];
-
- /* Translate TGSI shader into hw bytecode */
- if (!vp->translated) {
- nv30_vertprog_translate(nv30, vp);
- if (!vp->translated)
- return FALSE;
- }
-
- /* Allocate hw vtxprog exec slots */
- if (!vp->exec) {
- struct nouveau_resource *heap = nv30->screen->vp_exec_heap;
- struct nouveau_stateobj *so;
- uint vplen = vp->nr_insns;
-
- if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec)) {
- while (heap->next && heap->size < vplen) {
- struct nv30_vertex_program *evict;
-
- evict = heap->next->priv;
- nouveau_resource_free(&evict->exec);
- }
-
- if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec))
- assert(0);
- }
-
- so = so_new(1, 1, 0);
- so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1);
- so_data (so, vp->exec->start);
- so_ref(so, &vp->so);
- so_ref(NULL, &so);
-
- upload_code = TRUE;
- }
-
- /* Allocate hw vtxprog const slots */
- if (vp->nr_consts && !vp->data) {
- struct nouveau_resource *heap = nv30->screen->vp_data_heap;
-
- if (nouveau_resource_alloc(heap, vp->nr_consts, vp, &vp->data)) {
- while (heap->next && heap->size < vp->nr_consts) {
- struct nv30_vertex_program *evict;
-
- evict = heap->next->priv;
- nouveau_resource_free(&evict->data);
- }
-
- if (nouveau_resource_alloc(heap, vp->nr_consts, vp,
- &vp->data))
- assert(0);
- }
-
- /*XXX: handle this some day */
- assert(vp->data->start >= vp->data_start_min);
-
- upload_data = TRUE;
- if (vp->data_start != vp->data->start)
- upload_code = TRUE;
- }
-
- /* If exec or data segments moved we need to patch the program to
- * fixup offsets and register IDs.
- */
- if (vp->exec_start != vp->exec->start) {
- for (i = 0; i < vp->nr_insns; i++) {
- struct nv30_vertex_program_exec *vpi = &vp->insns[i];
-
- if (vpi->has_branch_offset) {
- assert(0);
- }
- }
-
- vp->exec_start = vp->exec->start;
- }
-
- if (vp->nr_consts && vp->data_start != vp->data->start) {
- for (i = 0; i < vp->nr_insns; i++) {
- struct nv30_vertex_program_exec *vpi = &vp->insns[i];
-
- if (vpi->const_index >= 0) {
- vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK;
- vpi->data[1] |=
- (vpi->const_index + vp->data->start) <<
- NV30_VP_INST_CONST_SRC_SHIFT;
-
- }
- }
-
- vp->data_start = vp->data->start;
- }
-
- /* Update + Upload constant values */
- if (vp->nr_consts) {
- float *map = NULL;
-
- if (constbuf) {
- map = pipe_buffer_map(pscreen, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
- }
-
- for (i = 0; i < vp->nr_consts; i++) {
- struct nv30_vertex_program_data *vpd = &vp->consts[i];
-
- if (vpd->index >= 0) {
- if (!upload_data &&
- !memcmp(vpd->value, &map[vpd->index * 4],
- 4 * sizeof(float)))
- continue;
- memcpy(vpd->value, &map[vpd->index * 4],
- 4 * sizeof(float));
- }
-
- BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5);
- OUT_RING (chan, i + vp->data->start);
- OUT_RINGp (chan, (uint32_t *)vpd->value, 4);
- }
-
- if (constbuf)
- pipe_buffer_unmap(pscreen, constbuf);
- }
-
- /* Upload vtxprog */
- if (upload_code) {
-#if 0
- for (i = 0; i < vp->nr_insns; i++) {
- NOUVEAU_MSG("VP inst %d: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- i, vp->insns[i].data[0], vp->insns[i].data[1],
- vp->insns[i].data[2], vp->insns[i].data[3]);
- }
-#endif
- BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1);
- OUT_RING (chan, vp->exec->start);
- for (i = 0; i < vp->nr_insns; i++) {
- BEGIN_RING(chan, rankine, NV34TCL_VP_UPLOAD_INST(0), 4);
- OUT_RINGp (chan, vp->insns[i].data, 4);
- }
- }
-
- if (vp->so != nv30->state.hw[NV30_STATE_VERTPROG]) {
- so_ref(vp->so, &nv30->state.hw[NV30_STATE_VERTPROG]);
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp)
-{
- vp->translated = FALSE;
-
- if (vp->nr_insns) {
- FREE(vp->insns);
- vp->insns = NULL;
- vp->nr_insns = 0;
- }
-
- if (vp->nr_consts) {
- FREE(vp->consts);
- vp->consts = NULL;
- vp->nr_consts = 0;
- }
-
- nouveau_resource_free(&vp->exec);
- vp->exec_start = 0;
- nouveau_resource_free(&vp->data);
- vp->data_start = 0;
- vp->data_start_min = 0;
-
- vp->ir = vp->or = 0;
- so_ref(NULL, &vp->so);
-}
-
-struct nv30_state_entry nv30_state_vertprog = {
- .validate = nv30_vertprog_validate,
- .dirty = {
- .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/,
- .hw = NV30_STATE_VERTPROG,
- }
-};
diff --git a/src/gallium/drivers/nv40/Makefile b/src/gallium/drivers/nv40/Makefile
deleted file mode 100644
index 0ecae2b4913..00000000000
--- a/src/gallium/drivers/nv40/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-LIBNAME = nv40
-
-C_SOURCES = \
- nv40_clear.c \
- nv40_context.c \
- nv40_draw.c \
- nv40_fragprog.c \
- nv40_fragtex.c \
- nv40_miptree.c \
- nv40_query.c \
- nv40_screen.c \
- nv40_state.c \
- nv40_state_blend.c \
- nv40_state_emit.c \
- nv40_state_fb.c \
- nv40_state_rasterizer.c \
- nv40_state_scissor.c \
- nv40_state_stipple.c \
- nv40_state_viewport.c \
- nv40_state_zsa.c \
- nv40_surface.c \
- nv40_transfer.c \
- nv40_vbo.c \
- nv40_vertprog.c
-
-include ../../Makefile.template
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
deleted file mode 100644
index 65dc73e88b3..00000000000
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "draw/draw_context.h"
-#include "pipe/p_defines.h"
-
-#include "nv40_context.h"
-#include "nv40_screen.h"
-
-static void
-nv40_flush(struct pipe_context *pipe, unsigned flags,
- struct pipe_fence_handle **fence)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- BEGIN_RING(chan, curie, 0x1fd8, 1);
- OUT_RING (chan, 2);
- BEGIN_RING(chan, curie, 0x1fd8, 1);
- OUT_RING (chan, 1);
- }
-
- FIRE_RING(chan);
- if (fence)
- *fence = NULL;
-}
-
-static void
-nv40_destroy(struct pipe_context *pipe)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- unsigned i;
-
- for (i = 0; i < NV40_STATE_MAX; i++) {
- if (nv40->state.hw[i])
- so_ref(NULL, &nv40->state.hw[i]);
- }
-
- if (nv40->draw)
- draw_destroy(nv40->draw);
- FREE(nv40);
-}
-
-struct pipe_context *
-nv40_create(struct pipe_screen *pscreen, void *priv)
-{
- struct nv40_screen *screen = nv40_screen(pscreen);
- struct pipe_winsys *ws = pscreen->winsys;
- struct nv40_context *nv40;
- struct nouveau_winsys *nvws = screen->nvws;
-
- nv40 = CALLOC(1, sizeof(struct nv40_context));
- if (!nv40)
- return NULL;
- nv40->screen = screen;
-
- nv40->nvws = nvws;
-
- nv40->pipe.winsys = ws;
- nv40->pipe.priv = priv;
- nv40->pipe.screen = pscreen;
- nv40->pipe.destroy = nv40_destroy;
- nv40->pipe.draw_arrays = nv40_draw_arrays;
- nv40->pipe.draw_elements = nv40_draw_elements;
- nv40->pipe.clear = nv40_clear;
- nv40->pipe.flush = nv40_flush;
-
- nv40->pipe.is_texture_referenced = nouveau_is_texture_referenced;
- nv40->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
-
- screen->base.channel->user_private = nv40;
- screen->base.channel->flush_notify = nv40_state_flush_notify;
-
- nv40_init_query_functions(nv40);
- nv40_init_surface_functions(nv40);
- nv40_init_state_functions(nv40);
-
- /* Create, configure, and install fallback swtnl path */
- nv40->draw = draw_create();
- draw_wide_point_threshold(nv40->draw, 9999999.0);
- draw_wide_line_threshold(nv40->draw, 9999999.0);
- draw_enable_line_stipple(nv40->draw, FALSE);
- draw_enable_point_sprites(nv40->draw, FALSE);
- draw_set_rasterize_stage(nv40->draw, nv40_draw_render_stage(nv40));
-
- return &nv40->pipe;
-}
diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
deleted file mode 100644
index 97fb6a2ef94..00000000000
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ /dev/null
@@ -1,239 +0,0 @@
-#ifndef __NV40_CONTEXT_H__
-#define __NV40_CONTEXT_H__
-
-#include <stdio.h>
-
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "pipe/p_compiler.h"
-
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "util/u_inlines.h"
-
-#include "draw/draw_vertex.h"
-
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau/nouveau_gldefs.h"
-#include "nouveau/nouveau_context.h"
-#include "nouveau/nouveau_stateobj.h"
-
-#include "nv40_state.h"
-
-#define NOUVEAU_ERR(fmt, args...) \
- fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
-#define NOUVEAU_MSG(fmt, args...) \
- fprintf(stderr, "nouveau: "fmt, ##args);
-
-enum nv40_state_index {
- NV40_STATE_FB = 0,
- NV40_STATE_VIEWPORT = 1,
- NV40_STATE_BLEND = 2,
- NV40_STATE_RAST = 3,
- NV40_STATE_ZSA = 4,
- NV40_STATE_BCOL = 5,
- NV40_STATE_CLIP = 6,
- NV40_STATE_SCISSOR = 7,
- NV40_STATE_STIPPLE = 8,
- NV40_STATE_FRAGPROG = 9,
- NV40_STATE_VERTPROG = 10,
- NV40_STATE_FRAGTEX0 = 11,
- NV40_STATE_FRAGTEX1 = 12,
- NV40_STATE_FRAGTEX2 = 13,
- NV40_STATE_FRAGTEX3 = 14,
- NV40_STATE_FRAGTEX4 = 15,
- NV40_STATE_FRAGTEX5 = 16,
- NV40_STATE_FRAGTEX6 = 17,
- NV40_STATE_FRAGTEX7 = 18,
- NV40_STATE_FRAGTEX8 = 19,
- NV40_STATE_FRAGTEX9 = 20,
- NV40_STATE_FRAGTEX10 = 21,
- NV40_STATE_FRAGTEX11 = 22,
- NV40_STATE_FRAGTEX12 = 23,
- NV40_STATE_FRAGTEX13 = 24,
- NV40_STATE_FRAGTEX14 = 25,
- NV40_STATE_FRAGTEX15 = 26,
- NV40_STATE_VERTTEX0 = 27,
- NV40_STATE_VERTTEX1 = 28,
- NV40_STATE_VERTTEX2 = 29,
- NV40_STATE_VERTTEX3 = 30,
- NV40_STATE_VTXBUF = 31,
- NV40_STATE_VTXFMT = 32,
- NV40_STATE_VTXATTR = 33,
- NV40_STATE_SR = 34,
- NV40_STATE_MAX = 35
-};
-
-#include "nv40_screen.h"
-
-#define NV40_NEW_BLEND (1 << 0)
-#define NV40_NEW_RAST (1 << 1)
-#define NV40_NEW_ZSA (1 << 2)
-#define NV40_NEW_SAMPLER (1 << 3)
-#define NV40_NEW_FB (1 << 4)
-#define NV40_NEW_STIPPLE (1 << 5)
-#define NV40_NEW_SCISSOR (1 << 6)
-#define NV40_NEW_VIEWPORT (1 << 7)
-#define NV40_NEW_BCOL (1 << 8)
-#define NV40_NEW_VERTPROG (1 << 9)
-#define NV40_NEW_FRAGPROG (1 << 10)
-#define NV40_NEW_ARRAYS (1 << 11)
-#define NV40_NEW_UCP (1 << 12)
-#define NV40_NEW_SR (1 << 13)
-
-struct nv40_rasterizer_state {
- struct pipe_rasterizer_state pipe;
- struct nouveau_stateobj *so;
-};
-
-struct nv40_zsa_state {
- struct pipe_depth_stencil_alpha_state pipe;
- struct nouveau_stateobj *so;
-};
-
-struct nv40_blend_state {
- struct pipe_blend_state pipe;
- struct nouveau_stateobj *so;
-};
-
-
-struct nv40_state {
- unsigned scissor_enabled;
- unsigned stipple_enabled;
- unsigned fp_samplers;
-
- uint64_t dirty;
- struct nouveau_stateobj *hw[NV40_STATE_MAX];
-};
-
-struct nv40_context {
- struct pipe_context pipe;
-
- struct nouveau_winsys *nvws;
- struct nv40_screen *screen;
-
- struct draw_context *draw;
-
- /* HW state derived from pipe states */
- struct nv40_state state;
- struct {
- struct nv40_vertex_program *vertprog;
-
- unsigned nr_attribs;
- unsigned hw[PIPE_MAX_SHADER_INPUTS];
- unsigned draw[PIPE_MAX_SHADER_INPUTS];
- unsigned emit[PIPE_MAX_SHADER_INPUTS];
- } swtnl;
-
- enum {
- HW, SWTNL, SWRAST
- } render_mode;
- unsigned fallback_swtnl;
- unsigned fallback_swrast;
-
- /* Context state */
- unsigned dirty, draw_dirty;
- struct pipe_scissor_state scissor;
- unsigned stipple[32];
- struct pipe_clip_state clip;
- struct nv40_vertex_program *vertprog;
- struct nv40_fragment_program *fragprog;
- struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
- unsigned constbuf_nr[PIPE_SHADER_TYPES];
- struct nv40_rasterizer_state *rasterizer;
- struct nv40_zsa_state *zsa;
- struct nv40_blend_state *blend;
- struct pipe_blend_color blend_colour;
- struct pipe_stencil_ref stencil_ref;
- struct pipe_viewport_state viewport;
- struct pipe_framebuffer_state framebuffer;
- struct pipe_buffer *idxbuf;
- unsigned idxbuf_format;
- struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
- struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
- unsigned nr_samplers;
- unsigned nr_textures;
- unsigned dirty_samplers;
- struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
- unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
-};
-
-static INLINE struct nv40_context *
-nv40_context(struct pipe_context *pipe)
-{
- return (struct nv40_context *)pipe;
-}
-
-struct nv40_state_entry {
- boolean (*validate)(struct nv40_context *nv40);
- struct {
- unsigned pipe;
- unsigned hw;
- } dirty;
-};
-
-extern void nv40_init_state_functions(struct nv40_context *nv40);
-extern void nv40_init_surface_functions(struct nv40_context *nv40);
-extern void nv40_init_query_functions(struct nv40_context *nv40);
-
-extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen);
-
-/* nv40_draw.c */
-extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40);
-extern void nv40_draw_elements_swtnl(struct pipe_context *pipe,
- struct pipe_buffer *idxbuf,
- unsigned ib_size, unsigned mode,
- unsigned start, unsigned count);
-
-/* nv40_vertprog.c */
-extern void nv40_vertprog_destroy(struct nv40_context *,
- struct nv40_vertex_program *);
-
-/* nv40_fragprog.c */
-extern void nv40_fragprog_destroy(struct nv40_context *,
- struct nv40_fragment_program *);
-
-/* nv40_fragtex.c */
-extern void nv40_fragtex_bind(struct nv40_context *);
-
-/* nv40_state.c and friends */
-extern boolean nv40_state_validate(struct nv40_context *nv40);
-extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40);
-extern void nv40_state_emit(struct nv40_context *nv40);
-extern void nv40_state_flush_notify(struct nouveau_channel *chan);
-extern struct nv40_state_entry nv40_state_rasterizer;
-extern struct nv40_state_entry nv40_state_scissor;
-extern struct nv40_state_entry nv40_state_stipple;
-extern struct nv40_state_entry nv40_state_fragprog;
-extern struct nv40_state_entry nv40_state_vertprog;
-extern struct nv40_state_entry nv40_state_blend;
-extern struct nv40_state_entry nv40_state_blend_colour;
-extern struct nv40_state_entry nv40_state_zsa;
-extern struct nv40_state_entry nv40_state_viewport;
-extern struct nv40_state_entry nv40_state_framebuffer;
-extern struct nv40_state_entry nv40_state_fragtex;
-extern struct nv40_state_entry nv40_state_vbo;
-extern struct nv40_state_entry nv40_state_vtxfmt;
-extern struct nv40_state_entry nv40_state_sr;
-
-/* nv40_vbo.c */
-extern void nv40_draw_arrays(struct pipe_context *, unsigned mode,
- unsigned start, unsigned count);
-extern void nv40_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned mode, unsigned start,
- unsigned count);
-
-/* nv40_clear.c */
-extern void nv40_clear(struct pipe_context *pipe, unsigned buffers,
- const float *rgba, double depth, unsigned stencil);
-
-/* nv40_context.c */
-struct pipe_context *
-nv40_create(struct pipe_screen *pscreen, void *priv);
-
-#endif
diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c
deleted file mode 100644
index 48bd84d16c5..00000000000
--- a/src/gallium/drivers/nv40/nv40_draw.c
+++ /dev/null
@@ -1,360 +0,0 @@
-#include "pipe/p_shader_tokens.h"
-#include "util/u_inlines.h"
-
-#include "util/u_pack_color.h"
-
-#include "draw/draw_context.h"
-#include "draw/draw_vertex.h"
-#include "draw/draw_pipe.h"
-
-#include "nv40_context.h"
-#define NV40_SHADER_NO_FUCKEDNESS
-#include "nv40_shader.h"
-
-/* Simple, but crappy, swtnl path, hopefully we wont need to hit this very
- * often at all. Uses "quadro style" vertex submission + a fixed vertex
- * layout to avoid the need to generate a vertex program or vtxfmt.
- */
-
-struct nv40_render_stage {
- struct draw_stage stage;
- struct nv40_context *nv40;
- unsigned prim;
-};
-
-static INLINE struct nv40_render_stage *
-nv40_render_stage(struct draw_stage *stage)
-{
- return (struct nv40_render_stage *)stage;
-}
-
-static INLINE void
-nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v)
-{
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- unsigned i;
-
- for (i = 0; i < nv40->swtnl.nr_attribs; i++) {
- unsigned idx = nv40->swtnl.draw[i];
- unsigned hw = nv40->swtnl.hw[i];
-
- switch (nv40->swtnl.emit[i]) {
- case EMIT_OMIT:
- break;
- case EMIT_1F:
- BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_1F(hw), 1);
- OUT_RING (chan, fui(v->data[idx][0]));
- break;
- case EMIT_2F:
- BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_2F_X(hw), 2);
- OUT_RING (chan, fui(v->data[idx][0]));
- OUT_RING (chan, fui(v->data[idx][1]));
- break;
- case EMIT_3F:
- BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_3F_X(hw), 3);
- OUT_RING (chan, fui(v->data[idx][0]));
- OUT_RING (chan, fui(v->data[idx][1]));
- OUT_RING (chan, fui(v->data[idx][2]));
- break;
- case EMIT_4F:
- BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_4F_X(hw), 4);
- OUT_RING (chan, fui(v->data[idx][0]));
- OUT_RING (chan, fui(v->data[idx][1]));
- OUT_RING (chan, fui(v->data[idx][2]));
- OUT_RING (chan, fui(v->data[idx][3]));
- break;
- case EMIT_4UB:
- BEGIN_RING(chan, curie, NV40TCL_VTX_ATTR_4UB(hw), 1);
- OUT_RING (chan, pack_ub4(float_to_ubyte(v->data[idx][0]),
- float_to_ubyte(v->data[idx][1]),
- float_to_ubyte(v->data[idx][2]),
- float_to_ubyte(v->data[idx][3])));
- break;
- default:
- assert(0);
- break;
- }
- }
-}
-
-static INLINE void
-nv40_render_prim(struct draw_stage *stage, struct prim_header *prim,
- unsigned mode, unsigned count)
-{
- struct nv40_render_stage *rs = nv40_render_stage(stage);
- struct nv40_context *nv40 = rs->nv40;
-
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- unsigned i;
-
- /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */
- if (AVAIL_RING(chan) < ((count * 20) + 6)) {
- if (rs->prim != NV40TCL_BEGIN_END_STOP) {
- NOUVEAU_ERR("AIII, missed flush\n");
- assert(0);
- }
- FIRE_RING(chan);
- nv40_state_emit(nv40);
- }
-
- /* Switch primitive modes if necessary */
- if (rs->prim != mode) {
- if (rs->prim != NV40TCL_BEGIN_END_STOP) {
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, NV40TCL_BEGIN_END_STOP);
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, mode);
- rs->prim = mode;
- }
-
- /* Emit vertex data */
- for (i = 0; i < count; i++)
- nv40_render_vertex(nv40, prim->v[i]);
-
- /* If it's likely we'll need to empty the push buffer soon, finish
- * off the primitive now.
- */
- if (AVAIL_RING(chan) < ((count * 20) + 6)) {
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, NV40TCL_BEGIN_END_STOP);
- rs->prim = NV40TCL_BEGIN_END_STOP;
- }
-}
-
-static void
-nv40_render_point(struct draw_stage *draw, struct prim_header *prim)
-{
- nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_POINTS, 1);
-}
-
-static void
-nv40_render_line(struct draw_stage *draw, struct prim_header *prim)
-{
- nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_LINES, 2);
-}
-
-static void
-nv40_render_tri(struct draw_stage *draw, struct prim_header *prim)
-{
- nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_TRIANGLES, 3);
-}
-
-static void
-nv40_render_flush(struct draw_stage *draw, unsigned flags)
-{
- struct nv40_render_stage *rs = nv40_render_stage(draw);
- struct nv40_context *nv40 = rs->nv40;
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- if (rs->prim != NV40TCL_BEGIN_END_STOP) {
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, NV40TCL_BEGIN_END_STOP);
- rs->prim = NV40TCL_BEGIN_END_STOP;
- }
-}
-
-static void
-nv40_render_reset_stipple_counter(struct draw_stage *draw)
-{
-}
-
-static void
-nv40_render_destroy(struct draw_stage *draw)
-{
- FREE(draw);
-}
-
-static INLINE void
-emit_mov(struct nv40_vertex_program *vp,
- unsigned dst, unsigned src, unsigned vor, unsigned mask)
-{
- struct nv40_vertex_program_exec *inst;
-
- vp->insns = realloc(vp->insns,
- sizeof(struct nv40_vertex_program_exec) *
- ++vp->nr_insns);
- inst = &vp->insns[vp->nr_insns - 1];
-
- inst->data[0] = 0x401f9c6c;
- inst->data[1] = 0x0040000d | (src << 8);
- inst->data[2] = 0x8106c083;
- inst->data[3] = 0x6041ff80 | (dst << 2) | (mask << 13);
- inst->const_index = -1;
- inst->has_branch_offset = FALSE;
-
- vp->ir |= (1 << src);
- if (vor != ~0)
- vp->or |= (1 << vor);
-}
-
-static struct nv40_vertex_program *
-create_drawvp(struct nv40_context *nv40)
-{
- struct nv40_vertex_program *vp = CALLOC_STRUCT(nv40_vertex_program);
- unsigned i;
-
- emit_mov(vp, NV40_VP_INST_DEST_POS, 0, ~0, 0xf);
- emit_mov(vp, NV40_VP_INST_DEST_COL0, 3, 0, 0xf);
- emit_mov(vp, NV40_VP_INST_DEST_COL1, 4, 1, 0xf);
- emit_mov(vp, NV40_VP_INST_DEST_BFC0, 3, 2, 0xf);
- emit_mov(vp, NV40_VP_INST_DEST_BFC1, 4, 3, 0xf);
- emit_mov(vp, NV40_VP_INST_DEST_FOGC, 5, 4, 0x8);
- for (i = 0; i < 8; i++)
- emit_mov(vp, NV40_VP_INST_DEST_TC(i), 8 + i, 14 + i, 0xf);
-
- vp->insns[vp->nr_insns - 1].data[3] |= 1;
- vp->translated = TRUE;
- return vp;
-}
-
-struct draw_stage *
-nv40_draw_render_stage(struct nv40_context *nv40)
-{
- struct nv40_render_stage *render = CALLOC_STRUCT(nv40_render_stage);
-
- if (!nv40->swtnl.vertprog)
- nv40->swtnl.vertprog = create_drawvp(nv40);
-
- render->nv40 = nv40;
- render->stage.draw = nv40->draw;
- render->stage.point = nv40_render_point;
- render->stage.line = nv40_render_line;
- render->stage.tri = nv40_render_tri;
- render->stage.flush = nv40_render_flush;
- render->stage.reset_stipple_counter = nv40_render_reset_stipple_counter;
- render->stage.destroy = nv40_render_destroy;
-
- return &render->stage;
-}
-
-void
-nv40_draw_elements_swtnl(struct pipe_context *pipe,
- struct pipe_buffer *idxbuf, unsigned idxbuf_size,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct pipe_screen *pscreen = pipe->screen;
- unsigned i;
- void *map;
-
- if (!nv40_state_validate_swtnl(nv40))
- return;
- nv40->state.dirty &= ~(1ULL << NV40_STATE_VTXBUF);
- nv40_state_emit(nv40);
-
- for (i = 0; i < nv40->vtxbuf_nr; i++) {
- map = pipe_buffer_map(pscreen, nv40->vtxbuf[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_vertex_buffer(nv40->draw, i, map);
- }
-
- if (idxbuf) {
- map = pipe_buffer_map(pscreen, idxbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map);
- } else {
- draw_set_mapped_element_buffer(nv40->draw, 0, NULL);
- }
-
- if (nv40->constbuf[PIPE_SHADER_VERTEX]) {
- const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX];
-
- map = pipe_buffer_map(pscreen,
- nv40->constbuf[PIPE_SHADER_VERTEX],
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, 0,
- map, nr);
- }
-
- draw_arrays(nv40->draw, mode, start, count);
-
- for (i = 0; i < nv40->vtxbuf_nr; i++)
- pipe_buffer_unmap(pscreen, nv40->vtxbuf[i].buffer);
-
- if (idxbuf)
- pipe_buffer_unmap(pscreen, idxbuf);
-
- if (nv40->constbuf[PIPE_SHADER_VERTEX])
- pipe_buffer_unmap(pscreen, nv40->constbuf[PIPE_SHADER_VERTEX]);
-
- draw_flush(nv40->draw);
- pipe->flush(pipe, 0, NULL);
-}
-
-static INLINE void
-emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit,
- unsigned semantic, unsigned index)
-{
- unsigned draw_out = draw_find_shader_output(nv40->draw, semantic, index);
- unsigned a = nv40->swtnl.nr_attribs++;
-
- nv40->swtnl.hw[a] = hw;
- nv40->swtnl.emit[a] = emit;
- nv40->swtnl.draw[a] = draw_out;
-}
-
-static boolean
-nv40_state_vtxfmt_validate(struct nv40_context *nv40)
-{
- struct nv40_fragment_program *fp = nv40->fragprog;
- unsigned colour = 0, texcoords = 0, fog = 0, i;
-
- /* Determine needed fragprog inputs */
- for (i = 0; i < fp->info.num_inputs; i++) {
- switch (fp->info.input_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- break;
- case TGSI_SEMANTIC_COLOR:
- colour |= (1 << fp->info.input_semantic_index[i]);
- break;
- case TGSI_SEMANTIC_GENERIC:
- texcoords |= (1 << fp->info.input_semantic_index[i]);
- break;
- case TGSI_SEMANTIC_FOG:
- fog = 1;
- break;
- default:
- assert(0);
- }
- }
-
- nv40->swtnl.nr_attribs = 0;
-
- /* Map draw vtxprog output to hw attribute IDs */
- for (i = 0; i < 2; i++) {
- if (!(colour & (1 << i)))
- continue;
- emit_attrib(nv40, 3 + i, EMIT_4UB, TGSI_SEMANTIC_COLOR, i);
- }
-
- for (i = 0; i < 8; i++) {
- if (!(texcoords & (1 << i)))
- continue;
- emit_attrib(nv40, 8 + i, EMIT_4F, TGSI_SEMANTIC_GENERIC, i);
- }
-
- if (fog) {
- emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0);
- }
-
- emit_attrib(nv40, 0, EMIT_3F, TGSI_SEMANTIC_POSITION, 0);
-
- return FALSE;
-}
-
-struct nv40_state_entry nv40_state_vtxfmt = {
- .validate = nv40_state_vtxfmt_validate,
- .dirty = {
- .pipe = NV40_NEW_ARRAYS | NV40_NEW_FRAGPROG,
- .hw = 0
- }
-};
-
diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c
deleted file mode 100644
index 8ed4a67dd03..00000000000
--- a/src/gallium/drivers/nv40/nv40_query.c
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "pipe/p_context.h"
-
-#include "nv40_context.h"
-
-struct nv40_query {
- struct nouveau_resource *object;
- unsigned type;
- boolean ready;
- uint64_t result;
-};
-
-static INLINE struct nv40_query *
-nv40_query(struct pipe_query *pipe)
-{
- return (struct nv40_query *)pipe;
-}
-
-static struct pipe_query *
-nv40_query_create(struct pipe_context *pipe, unsigned query_type)
-{
- struct nv40_query *q;
-
- q = CALLOC(1, sizeof(struct nv40_query));
- q->type = query_type;
-
- return (struct pipe_query *)q;
-}
-
-static void
-nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv40_query *q = nv40_query(pq);
-
- if (q->object)
- nouveau_resource_free(&q->object);
- FREE(q);
-}
-
-static void
-nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_query *q = nv40_query(pq);
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
-
- /* Happens when end_query() is called, then another begin_query()
- * without querying the result in-between. For now we'll wait for
- * the existing query to notify completion, but it could be better.
- */
- if (q->object) {
- uint64_t tmp;
- pipe->get_query_result(pipe, pq, 1, &tmp);
- }
-
- if (nouveau_resource_alloc(nv40->screen->query_heap, 1, NULL, &q->object))
- assert(0);
- nouveau_notifier_reset(nv40->screen->query, q->object->start);
-
- BEGIN_RING(chan, curie, NV40TCL_QUERY_RESET, 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, curie, NV40TCL_QUERY_UNK17CC, 1);
- OUT_RING (chan, 1);
-
- q->ready = FALSE;
-}
-
-static void
-nv40_query_end(struct pipe_context *pipe, struct pipe_query *pq)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_query *q = nv40_query(pq);
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- BEGIN_RING(chan, curie, NV40TCL_QUERY_GET, 1);
- OUT_RING (chan, (0x01 << NV40TCL_QUERY_GET_UNK24_SHIFT) |
- ((q->object->start * 32) << NV40TCL_QUERY_GET_OFFSET_SHIFT));
- FIRE_RING(chan);
-}
-
-static boolean
-nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq,
- boolean wait, uint64_t *result)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_query *q = nv40_query(pq);
-
- assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
-
- if (!q->ready) {
- unsigned status;
-
- status = nouveau_notifier_status(nv40->screen->query,
- q->object->start);
- if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
- if (wait == FALSE)
- return FALSE;
- nouveau_notifier_wait_status(nv40->screen->query,
- q->object->start,
- NV_NOTIFY_STATE_STATUS_COMPLETED,
- 0);
- }
-
- q->result = nouveau_notifier_return_val(nv40->screen->query,
- q->object->start);
- q->ready = TRUE;
- nouveau_resource_free(&q->object);
- }
-
- *result = q->result;
- return TRUE;
-}
-
-void
-nv40_init_query_functions(struct nv40_context *nv40)
-{
- nv40->pipe.create_query = nv40_query_create;
- nv40->pipe.destroy_query = nv40_query_destroy;
- nv40->pipe.begin_query = nv40_query_begin;
- nv40->pipe.end_query = nv40_query_end;
- nv40->pipe.get_query_result = nv40_query_result;
-}
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
deleted file mode 100644
index b216c5e38c9..00000000000
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ /dev/null
@@ -1,320 +0,0 @@
-#include "pipe/p_screen.h"
-
-#include "nv40_context.h"
-#include "nv40_screen.h"
-
-#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
-#define NV4X_GRCLASS4497_CHIPSETS 0x00005450
-#define NV6X_GRCLASS4497_CHIPSETS 0x00000088
-
-static int
-nv40_screen_get_param(struct pipe_screen *pscreen, int param)
-{
- struct nv40_screen *screen = nv40_screen(pscreen);
-
- switch (param) {
- case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
- return 16;
- case PIPE_CAP_NPOT_TEXTURES:
- return 1;
- case PIPE_CAP_TWO_SIDED_STENCIL:
- return 1;
- case PIPE_CAP_GLSL:
- return 0;
- case PIPE_CAP_ANISOTROPIC_FILTER:
- return 1;
- case PIPE_CAP_POINT_SPRITE:
- return 1;
- case PIPE_CAP_MAX_RENDER_TARGETS:
- return 4;
- case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
- case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 1;
- case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13;
- case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 10;
- case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13;
- case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
- case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
- return 1;
- case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
- return 0; /* We have 4 - but unsupported currently */
- case PIPE_CAP_TGSI_CONT_SUPPORTED:
- return 0;
- case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- return 1;
- case NOUVEAU_CAP_HW_VTXBUF:
- return 1;
- case NOUVEAU_CAP_HW_IDXBUF:
- if (screen->curie->grclass == NV40TCL)
- return 1;
- return 0;
- case PIPE_CAP_INDEP_BLEND_ENABLE:
- return 0;
- case PIPE_CAP_INDEP_BLEND_FUNC:
- return 0;
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
- return 1;
- case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
- case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
- return 0;
- case PIPE_CAP_MAX_COMBINED_SAMPLERS:
- return 16;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0;
- }
-}
-
-static float
-nv40_screen_get_paramf(struct pipe_screen *pscreen, int param)
-{
- switch (param) {
- case PIPE_CAP_MAX_LINE_WIDTH:
- case PIPE_CAP_MAX_LINE_WIDTH_AA:
- return 10.0;
- case PIPE_CAP_MAX_POINT_WIDTH:
- case PIPE_CAP_MAX_POINT_WIDTH_AA:
- return 64.0;
- case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 16.0;
- case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
- return 16.0;
- default:
- NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
- return 0.0;
- }
-}
-
-static boolean
-nv40_screen_surface_format_supported(struct pipe_screen *pscreen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned tex_usage, unsigned geom_flags)
-{
- if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- return TRUE;
- default:
- break;
- }
- } else
- if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
- switch (format) {
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- return TRUE;
- default:
- break;
- }
- } else {
- switch (format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_R16_SNORM:
- case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_A8_UNORM:
- case PIPE_FORMAT_I8_UNORM:
- case PIPE_FORMAT_L8A8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_DXT1_RGB:
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- return TRUE;
- default:
- break;
- }
- }
-
- return FALSE;
-}
-
-static struct pipe_buffer *
-nv40_surface_buffer(struct pipe_surface *surf)
-{
- struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture;
-
- return mt->buffer;
-}
-
-static void
-nv40_screen_destroy(struct pipe_screen *pscreen)
-{
- struct nv40_screen *screen = nv40_screen(pscreen);
- unsigned i;
-
- for (i = 0; i < NV40_STATE_MAX; i++) {
- if (screen->state[i])
- so_ref(NULL, &screen->state[i]);
- }
-
- nouveau_resource_destroy(&screen->vp_exec_heap);
- nouveau_resource_destroy(&screen->vp_data_heap);
- nouveau_resource_destroy(&screen->query_heap);
- nouveau_notifier_free(&screen->query);
- nouveau_notifier_free(&screen->sync);
- nouveau_grobj_free(&screen->curie);
- nv04_surface_2d_takedown(&screen->eng2d);
-
- nouveau_screen_fini(&screen->base);
-
- FREE(pscreen);
-}
-
-struct pipe_screen *
-nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
-{
- struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen);
- struct nouveau_channel *chan;
- struct pipe_screen *pscreen;
- struct nouveau_stateobj *so;
- unsigned curie_class = 0;
- int ret;
-
- if (!screen)
- return NULL;
- pscreen = &screen->base.base;
-
- ret = nouveau_screen_init(&screen->base, dev);
- if (ret) {
- nv40_screen_destroy(pscreen);
- return NULL;
- }
- chan = screen->base.channel;
-
- pscreen->winsys = ws;
- pscreen->destroy = nv40_screen_destroy;
- pscreen->get_param = nv40_screen_get_param;
- pscreen->get_paramf = nv40_screen_get_paramf;
- pscreen->is_format_supported = nv40_screen_surface_format_supported;
- pscreen->context_create = nv40_create;
-
- nv40_screen_init_miptree_functions(pscreen);
- nv40_screen_init_transfer_functions(pscreen);
-
- /* 3D object */
- switch (dev->chipset & 0xf0) {
- case 0x40:
- if (NV4X_GRCLASS4097_CHIPSETS & (1 << (dev->chipset & 0x0f)))
- curie_class = NV40TCL;
- else
- if (NV4X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
- curie_class = NV44TCL;
- break;
- case 0x60:
- if (NV6X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
- curie_class = NV44TCL;
- break;
- }
-
- if (!curie_class) {
- NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", dev->chipset);
- return NULL;
- }
-
- ret = nouveau_grobj_alloc(chan, 0xbeef3097, curie_class, &screen->curie);
- if (ret) {
- NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
- return FALSE;
- }
-
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(&screen->base);
- screen->eng2d->buf = nv40_surface_buffer;
-
- /* Notifier for sync purposes */
- ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
- if (ret) {
- NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv40_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Query objects */
- ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
- if (ret) {
- NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
- nv40_screen_destroy(pscreen);
- return NULL;
- }
-
- nouveau_resource_init(&screen->query_heap, 0, 32);
- if (ret) {
- NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
- nv40_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Vtxprog resources */
- if (nouveau_resource_init(&screen->vp_exec_heap, 0, 512) ||
- nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
- nv40_screen_destroy(pscreen);
- return NULL;
- }
-
- /* Static curie initialisation */
- so = so_new(16, 25, 0);
- so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1);
- so_data (so, screen->sync->handle);
- so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->gart->handle);
- so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1);
- so_data (so, chan->vram->handle);
- so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->gart->handle);
- so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2);
- so_data (so, 0);
- so_data (so, screen->query->handle);
- so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
-
- so_method(so, screen->curie, 0x1ea4, 3);
- so_data (so, 0x00000010);
- so_data (so, 0x01000100);
- so_data (so, 0xff800006);
-
- /* vtxprog output routing */
- so_method(so, screen->curie, 0x1fc4, 1);
- so_data (so, 0x06144321);
- so_method(so, screen->curie, 0x1fc8, 2);
- so_data (so, 0xedcba987);
- so_data (so, 0x00000021);
- so_method(so, screen->curie, 0x1fd0, 1);
- so_data (so, 0x00171615);
- so_method(so, screen->curie, 0x1fd4, 1);
- so_data (so, 0x001b1a19);
-
- so_method(so, screen->curie, 0x1ef8, 1);
- so_data (so, 0x0020ffff);
- so_method(so, screen->curie, 0x1d64, 1);
- so_data (so, 0x00d30000);
- so_method(so, screen->curie, 0x1e94, 1);
- so_data (so, 0x00000001);
-
- so_emit(chan, so);
- so_ref(NULL, &so);
- nouveau_pushbuf_flush(chan, 0);
-
- return pscreen;
-}
-
diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h
deleted file mode 100644
index 854dccf5486..00000000000
--- a/src/gallium/drivers/nv40/nv40_shader.h
+++ /dev/null
@@ -1,556 +0,0 @@
-#ifndef __NV40_SHADER_H__
-#define __NV40_SHADER_H__
-
-/* Vertex programs instruction set
- *
- * The NV40 instruction set is very similar to NV30. Most fields are in
- * a slightly different position in the instruction however.
- *
- * Merged instructions
- * In some cases it is possible to put two instructions into one opcode
- * slot. The rules for when this is OK is not entirely clear to me yet.
- *
- * There are separate writemasks and dest temp register fields for each
- * grouping of instructions. There is however only one field with the
- * ID of a result register. Writing to temp/result regs is selected by
- * setting VEC_RESULT/SCA_RESULT.
- *
- * Temporary registers
- * The source/dest temp register fields have been extended by 1 bit, to
- * give a total of 32 temporary registers.
- *
- * Relative Addressing
- * NV40 can use an address register to index into vertex attribute regs.
- * This is done by putting the offset value into INPUT_SRC and setting
- * the INDEX_INPUT flag.
- *
- * Conditional execution (see NV_vertex_program{2,3} for details)
- * There is a second condition code register on NV40, it's use is enabled
- * by setting the COND_REG_SELECT_1 flag.
- *
- * Texture lookup
- * TODO
- */
-
-/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */
-#define NV40_VP_INST_VEC_RESULT (1 << 30)
-/* uncertain.. */
-#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29)
-/* use address reg as index into attribs */
-#define NV40_VP_INST_INDEX_INPUT (1 << 27)
-#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25)
-#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
-#define NV40_VP_INST_SRC2_ABS (1 << 23)
-#define NV40_VP_INST_SRC1_ABS (1 << 22)
-#define NV40_VP_INST_SRC0_ABS (1 << 21)
-#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15
-#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15)
-#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13)
-#define NV40_VP_INST_COND_SHIFT 10
-#define NV40_VP_INST_COND_MASK (0x7 << 10)
-# define NV40_VP_INST_COND_FL 0
-# define NV40_VP_INST_COND_LT 1
-# define NV40_VP_INST_COND_EQ 2
-# define NV40_VP_INST_COND_LE 3
-# define NV40_VP_INST_COND_GT 4
-# define NV40_VP_INST_COND_NE 5
-# define NV40_VP_INST_COND_GE 6
-# define NV40_VP_INST_COND_TR 7
-#define NV40_VP_INST_COND_SWZ_X_SHIFT 8
-#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8)
-#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6
-#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6)
-#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4
-#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4)
-#define NV40_VP_INST_COND_SWZ_W_SHIFT 2
-#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2)
-#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2
-#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2)
-#define NV40_VP_INST_ADDR_SWZ_SHIFT 0
-#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0)
-#define NV40_VP_INST0_KNOWN ( \
- NV40_VP_INST_INDEX_INPUT | \
- NV40_VP_INST_COND_REG_SELECT_1 | \
- NV40_VP_INST_ADDR_REG_SELECT_1 | \
- NV40_VP_INST_SRC2_ABS | \
- NV40_VP_INST_SRC1_ABS | \
- NV40_VP_INST_SRC0_ABS | \
- NV40_VP_INST_VEC_DEST_TEMP_MASK | \
- NV40_VP_INST_COND_TEST_ENABLE | \
- NV40_VP_INST_COND_MASK | \
- NV40_VP_INST_COND_SWZ_ALL_MASK | \
- NV40_VP_INST_ADDR_SWZ_MASK)
-
-/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */
-#define NV40_VP_INST_VEC_OPCODE_SHIFT 22
-#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22)
-# define NV40_VP_INST_OP_NOP 0x00
-# define NV40_VP_INST_OP_MOV 0x01
-# define NV40_VP_INST_OP_MUL 0x02
-# define NV40_VP_INST_OP_ADD 0x03
-# define NV40_VP_INST_OP_MAD 0x04
-# define NV40_VP_INST_OP_DP3 0x05
-# define NV40_VP_INST_OP_DPH 0x06
-# define NV40_VP_INST_OP_DP4 0x07
-# define NV40_VP_INST_OP_DST 0x08
-# define NV40_VP_INST_OP_MIN 0x09
-# define NV40_VP_INST_OP_MAX 0x0A
-# define NV40_VP_INST_OP_SLT 0x0B
-# define NV40_VP_INST_OP_SGE 0x0C
-# define NV40_VP_INST_OP_ARL 0x0D
-# define NV40_VP_INST_OP_FRC 0x0E
-# define NV40_VP_INST_OP_FLR 0x0F
-# define NV40_VP_INST_OP_SEQ 0x10
-# define NV40_VP_INST_OP_SFL 0x11
-# define NV40_VP_INST_OP_SGT 0x12
-# define NV40_VP_INST_OP_SLE 0x13
-# define NV40_VP_INST_OP_SNE 0x14
-# define NV40_VP_INST_OP_STR 0x15
-# define NV40_VP_INST_OP_SSG 0x16
-# define NV40_VP_INST_OP_ARR 0x17
-# define NV40_VP_INST_OP_ARA 0x18
-# define NV40_VP_INST_OP_TXL 0x19
-#define NV40_VP_INST_SCA_OPCODE_SHIFT 27
-#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27)
-# define NV40_VP_INST_OP_NOP 0x00
-# define NV40_VP_INST_OP_MOV 0x01
-# define NV40_VP_INST_OP_RCP 0x02
-# define NV40_VP_INST_OP_RCC 0x03
-# define NV40_VP_INST_OP_RSQ 0x04
-# define NV40_VP_INST_OP_EXP 0x05
-# define NV40_VP_INST_OP_LOG 0x06
-# define NV40_VP_INST_OP_LIT 0x07
-# define NV40_VP_INST_OP_BRA 0x09
-# define NV40_VP_INST_OP_CAL 0x0B
-# define NV40_VP_INST_OP_RET 0x0C
-# define NV40_VP_INST_OP_LG2 0x0D
-# define NV40_VP_INST_OP_EX2 0x0E
-# define NV40_VP_INST_OP_SIN 0x0F
-# define NV40_VP_INST_OP_COS 0x10
-# define NV40_VP_INST_OP_PUSHA 0x13
-# define NV40_VP_INST_OP_POPA 0x14
-#define NV40_VP_INST_CONST_SRC_SHIFT 12
-#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12)
-#define NV40_VP_INST_INPUT_SRC_SHIFT 8
-#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8)
-# define NV40_VP_INST_IN_POS 0
-# define NV40_VP_INST_IN_WEIGHT 1
-# define NV40_VP_INST_IN_NORMAL 2
-# define NV40_VP_INST_IN_COL0 3
-# define NV40_VP_INST_IN_COL1 4
-# define NV40_VP_INST_IN_FOGC 5
-# define NV40_VP_INST_IN_TC0 8
-# define NV40_VP_INST_IN_TC(n) (8+n)
-#define NV40_VP_INST_SRC0H_SHIFT 0
-#define NV40_VP_INST_SRC0H_MASK (0xFF << 0)
-#define NV40_VP_INST1_KNOWN ( \
- NV40_VP_INST_VEC_OPCODE_MASK | \
- NV40_VP_INST_SCA_OPCODE_MASK | \
- NV40_VP_INST_CONST_SRC_MASK | \
- NV40_VP_INST_INPUT_SRC_MASK | \
- NV40_VP_INST_SRC0H_MASK \
- )
-
-/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */
-#define NV40_VP_INST_SRC0L_SHIFT 23
-#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23)
-#define NV40_VP_INST_SRC1_SHIFT 6
-#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6)
-#define NV40_VP_INST_SRC2H_SHIFT 0
-#define NV40_VP_INST_SRC2H_MASK (0x3F << 0)
-#define NV40_VP_INST_IADDRH_SHIFT 0
-#define NV40_VP_INST_IADDRH_MASK (0x1F << 0)
-
-/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */
-#define NV40_VP_INST_IADDRL_SHIFT 29
-#define NV40_VP_INST_IADDRL_MASK (7 << 29)
-#define NV40_VP_INST_SRC2L_SHIFT 21
-#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21)
-#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17
-#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17)
-# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20)
-# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19)
-# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18)
-# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17)
-#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13
-#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13)
-# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16)
-# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15)
-# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14)
-# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13)
-#define NV40_VP_INST_SCA_RESULT (1 << 12)
-#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7
-#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7)
-#define NV40_VP_INST_DEST_SHIFT 2
-#define NV40_VP_INST_DEST_MASK (31 << 2)
-# define NV40_VP_INST_DEST_POS 0
-# define NV40_VP_INST_DEST_COL0 1
-# define NV40_VP_INST_DEST_COL1 2
-# define NV40_VP_INST_DEST_BFC0 3
-# define NV40_VP_INST_DEST_BFC1 4
-# define NV40_VP_INST_DEST_FOGC 5
-# define NV40_VP_INST_DEST_PSZ 6
-# define NV40_VP_INST_DEST_TC0 7
-# define NV40_VP_INST_DEST_TC(n) (7+n)
-# define NV40_VP_INST_DEST_TEMP 0x1F
-#define NV40_VP_INST_INDEX_CONST (1 << 1)
-#define NV40_VP_INST_LAST (1 << 0)
-#define NV40_VP_INST3_KNOWN ( \
- NV40_VP_INST_SRC2L_MASK |\
- NV40_VP_INST_SCA_WRITEMASK_MASK |\
- NV40_VP_INST_VEC_WRITEMASK_MASK |\
- NV40_VP_INST_SCA_DEST_TEMP_MASK |\
- NV40_VP_INST_DEST_MASK |\
- NV40_VP_INST_INDEX_CONST)
-
-/* Useful to split the source selection regs into their pieces */
-#define NV40_VP_SRC0_HIGH_SHIFT 9
-#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00
-#define NV40_VP_SRC0_LOW_MASK 0x000001FF
-#define NV40_VP_SRC2_HIGH_SHIFT 11
-#define NV40_VP_SRC2_HIGH_MASK 0x0001F800
-#define NV40_VP_SRC2_LOW_MASK 0x000007FF
-
-/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */
-#define NV40_VP_SRC_NEGATE (1 << 16)
-#define NV40_VP_SRC_SWZ_X_SHIFT 14
-#define NV40_VP_SRC_SWZ_X_MASK (3 << 14)
-#define NV40_VP_SRC_SWZ_Y_SHIFT 12
-#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12)
-#define NV40_VP_SRC_SWZ_Z_SHIFT 10
-#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10)
-#define NV40_VP_SRC_SWZ_W_SHIFT 8
-#define NV40_VP_SRC_SWZ_W_MASK (3 << 8)
-#define NV40_VP_SRC_SWZ_ALL_SHIFT 8
-#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8)
-#define NV40_VP_SRC_TEMP_SRC_SHIFT 2
-#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2)
-#define NV40_VP_SRC_REG_TYPE_SHIFT 0
-#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0)
-# define NV40_VP_SRC_REG_TYPE_UNK0 0
-# define NV40_VP_SRC_REG_TYPE_TEMP 1
-# define NV40_VP_SRC_REG_TYPE_INPUT 2
-# define NV40_VP_SRC_REG_TYPE_CONST 3
-
-
-/*
- * Each fragment program opcode appears to be comprised of 4 32-bit values.
- *
- * 0 - Opcode, output reg/mask, ATTRIB source
- * 1 - Source 0
- * 2 - Source 1
- * 3 - Source 2
- *
- * There appears to be no special difference between result regs and temp regs.
- * result.color == R0.xyzw
- * result.depth == R1.z
- * When the fragprog contains instructions to write depth,
- * NV30_TCL_PRIMITIVE_3D_UNK1D78=0 otherwise it is set to 1.
- *
- * Constants are inserted directly after the instruction that uses them.
- *
- * It appears that it's not possible to use two input registers in one
- * instruction as the input sourcing is done in the instruction dword
- * and not the source selection dwords. As such instructions such as:
- *
- * ADD result.color, fragment.color, fragment.texcoord[0];
- *
- * must be split into two MOV's and then an ADD (nvidia does this) but
- * I'm not sure why it's not just one MOV and then source the second input
- * in the ADD instruction..
- *
- * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
- * negation requires multiplication with a const.
- *
- * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO and
- * SWIZZLE_ONE.
- *
- * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as
- * SWIZZLE_ZERO is implemented simply by not writing to the relevant components
- * of the destination.
- *
- * Looping
- * Loops appear to be fairly expensive on NV40 at least, the proprietary
- * driver goes to a lot of effort to avoid using the native looping
- * instructions. If the total number of *executed* instructions between
- * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
- * The maximum loop count is 255.
- *
- * Conditional execution
- * TODO
- *
- * Non-native instructions:
- * LIT
- * LRP - MAD+MAD
- * SUB - ADD, negate second source
- * RSQ - LG2 + EX2
- * POW - LG2 + MUL + EX2
- * SCS - COS + SIN
- * XPD
- * DP2 - MUL + ADD
- * NRM
- */
-
-//== Opcode / Destination selection ==
-#define NV40_FP_OP_PROGRAM_END (1 << 0)
-#define NV40_FP_OP_OUT_REG_SHIFT 1
-#define NV40_FP_OP_OUT_REG_MASK (63 << 1)
-/* Needs to be set when writing outputs to get expected result.. */
-#define NV40_FP_OP_OUT_REG_HALF (1 << 7)
-#define NV40_FP_OP_COND_WRITE_ENABLE (1 << 8)
-#define NV40_FP_OP_OUTMASK_SHIFT 9
-#define NV40_FP_OP_OUTMASK_MASK (0xF << 9)
-# define NV40_FP_OP_OUT_X (1 << 9)
-# define NV40_FP_OP_OUT_Y (1 <<10)
-# define NV40_FP_OP_OUT_Z (1 <<11)
-# define NV40_FP_OP_OUT_W (1 <<12)
-/* Uncertain about these, especially the input_src values.. it's possible that
- * they can be dynamically changed.
- */
-#define NV40_FP_OP_INPUT_SRC_SHIFT 13
-#define NV40_FP_OP_INPUT_SRC_MASK (15 << 13)
-# define NV40_FP_OP_INPUT_SRC_POSITION 0x0
-# define NV40_FP_OP_INPUT_SRC_COL0 0x1
-# define NV40_FP_OP_INPUT_SRC_COL1 0x2
-# define NV40_FP_OP_INPUT_SRC_FOGC 0x3
-# define NV40_FP_OP_INPUT_SRC_TC0 0x4
-# define NV40_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
-# define NV40_FP_OP_INPUT_SRC_FACING 0xE
-#define NV40_FP_OP_TEX_UNIT_SHIFT 17
-#define NV40_FP_OP_TEX_UNIT_MASK (0xF << 17)
-#define NV40_FP_OP_PRECISION_SHIFT 22
-#define NV40_FP_OP_PRECISION_MASK (3 << 22)
-# define NV40_FP_PRECISION_FP32 0
-# define NV40_FP_PRECISION_FP16 1
-# define NV40_FP_PRECISION_FX12 2
-#define NV40_FP_OP_OPCODE_SHIFT 24
-#define NV40_FP_OP_OPCODE_MASK (0x3F << 24)
-# define NV40_FP_OP_OPCODE_NOP 0x00
-# define NV40_FP_OP_OPCODE_MOV 0x01
-# define NV40_FP_OP_OPCODE_MUL 0x02
-# define NV40_FP_OP_OPCODE_ADD 0x03
-# define NV40_FP_OP_OPCODE_MAD 0x04
-# define NV40_FP_OP_OPCODE_DP3 0x05
-# define NV40_FP_OP_OPCODE_DP4 0x06
-# define NV40_FP_OP_OPCODE_DST 0x07
-# define NV40_FP_OP_OPCODE_MIN 0x08
-# define NV40_FP_OP_OPCODE_MAX 0x09
-# define NV40_FP_OP_OPCODE_SLT 0x0A
-# define NV40_FP_OP_OPCODE_SGE 0x0B
-# define NV40_FP_OP_OPCODE_SLE 0x0C
-# define NV40_FP_OP_OPCODE_SGT 0x0D
-# define NV40_FP_OP_OPCODE_SNE 0x0E
-# define NV40_FP_OP_OPCODE_SEQ 0x0F
-# define NV40_FP_OP_OPCODE_FRC 0x10
-# define NV40_FP_OP_OPCODE_FLR 0x11
-# define NV40_FP_OP_OPCODE_KIL 0x12
-# define NV40_FP_OP_OPCODE_PK4B 0x13
-# define NV40_FP_OP_OPCODE_UP4B 0x14
-/* DDX/DDY can only write to XY */
-# define NV40_FP_OP_OPCODE_DDX 0x15
-# define NV40_FP_OP_OPCODE_DDY 0x16
-# define NV40_FP_OP_OPCODE_TEX 0x17
-# define NV40_FP_OP_OPCODE_TXP 0x18
-# define NV40_FP_OP_OPCODE_TXD 0x19
-# define NV40_FP_OP_OPCODE_RCP 0x1A
-# define NV40_FP_OP_OPCODE_EX2 0x1C
-# define NV40_FP_OP_OPCODE_LG2 0x1D
-# define NV40_FP_OP_OPCODE_STR 0x20
-# define NV40_FP_OP_OPCODE_SFL 0x21
-# define NV40_FP_OP_OPCODE_COS 0x22
-# define NV40_FP_OP_OPCODE_SIN 0x23
-# define NV40_FP_OP_OPCODE_PK2H 0x24
-# define NV40_FP_OP_OPCODE_UP2H 0x25
-# define NV40_FP_OP_OPCODE_PK4UB 0x27
-# define NV40_FP_OP_OPCODE_UP4UB 0x28
-# define NV40_FP_OP_OPCODE_PK2US 0x29
-# define NV40_FP_OP_OPCODE_UP2US 0x2A
-# define NV40_FP_OP_OPCODE_DP2A 0x2E
-# define NV40_FP_OP_OPCODE_TXL 0x2F
-# define NV40_FP_OP_OPCODE_TXB 0x31
-# define NV40_FP_OP_OPCODE_DIV 0x3A
-# define NV40_FP_OP_OPCODE_UNK_LIT 0x3C
-/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
-# define NV40_FP_OP_BRA_OPCODE_BRK 0x0
-# define NV40_FP_OP_BRA_OPCODE_CAL 0x1
-# define NV40_FP_OP_BRA_OPCODE_IF 0x2
-# define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
-# define NV40_FP_OP_BRA_OPCODE_REP 0x4
-# define NV40_FP_OP_BRA_OPCODE_RET 0x5
-#define NV40_FP_OP_OUT_SAT (1 << 31)
-
-/* high order bits of SRC0 */
-#define NV40_FP_OP_OUT_ABS (1 << 29)
-#define NV40_FP_OP_COND_SWZ_W_SHIFT 27
-#define NV40_FP_OP_COND_SWZ_W_MASK (3 << 27)
-#define NV40_FP_OP_COND_SWZ_Z_SHIFT 25
-#define NV40_FP_OP_COND_SWZ_Z_MASK (3 << 25)
-#define NV40_FP_OP_COND_SWZ_Y_SHIFT 23
-#define NV40_FP_OP_COND_SWZ_Y_MASK (3 << 23)
-#define NV40_FP_OP_COND_SWZ_X_SHIFT 21
-#define NV40_FP_OP_COND_SWZ_X_MASK (3 << 21)
-#define NV40_FP_OP_COND_SWZ_ALL_SHIFT 21
-#define NV40_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
-#define NV40_FP_OP_COND_SHIFT 18
-#define NV40_FP_OP_COND_MASK (0x07 << 18)
-# define NV40_FP_OP_COND_FL 0
-# define NV40_FP_OP_COND_LT 1
-# define NV40_FP_OP_COND_EQ 2
-# define NV40_FP_OP_COND_LE 3
-# define NV40_FP_OP_COND_GT 4
-# define NV40_FP_OP_COND_NE 5
-# define NV40_FP_OP_COND_GE 6
-# define NV40_FP_OP_COND_TR 7
-
-/* high order bits of SRC1 */
-#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
-#define NV40_FP_OP_DST_SCALE_SHIFT 28
-#define NV40_FP_OP_DST_SCALE_MASK (3 << 28)
-#define NV40_FP_OP_DST_SCALE_1X 0
-#define NV40_FP_OP_DST_SCALE_2X 1
-#define NV40_FP_OP_DST_SCALE_4X 2
-#define NV40_FP_OP_DST_SCALE_8X 3
-#define NV40_FP_OP_DST_SCALE_INV_2X 5
-#define NV40_FP_OP_DST_SCALE_INV_4X 6
-#define NV40_FP_OP_DST_SCALE_INV_8X 7
-
-/* SRC1 LOOP */
-#define NV40_FP_OP_LOOP_INCR_SHIFT 19
-#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
-#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
-#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
-#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
-#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
-
-/* SRC1 IF */
-#define NV40_FP_OP_ELSE_ID_SHIFT 2
-#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
-
-/* SRC1 CAL */
-#define NV40_FP_OP_IADDR_SHIFT 2
-#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
-
-/* SRC1 REP
- * I have no idea why there are 3 count values here.. but they
- * have always been filled with the same value in my tests so
- * far..
- */
-#define NV40_FP_OP_REP_COUNT1_SHIFT 2
-#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
-#define NV40_FP_OP_REP_COUNT2_SHIFT 10
-#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
-#define NV40_FP_OP_REP_COUNT3_SHIFT 19
-#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
-
-/* SRC2 REP/IF */
-#define NV40_FP_OP_END_ID_SHIFT 2
-#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
-
-// SRC2 high-order
-#define NV40_FP_OP_INDEX_INPUT (1 << 30)
-#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
-#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
-
-//== Register selection ==
-#define NV40_FP_REG_TYPE_SHIFT 0
-#define NV40_FP_REG_TYPE_MASK (3 << 0)
-# define NV40_FP_REG_TYPE_TEMP 0
-# define NV40_FP_REG_TYPE_INPUT 1
-# define NV40_FP_REG_TYPE_CONST 2
-#define NV40_FP_REG_SRC_SHIFT 2
-#define NV40_FP_REG_SRC_MASK (63 << 2)
-#define NV40_FP_REG_SRC_HALF (1 << 8)
-#define NV40_FP_REG_SWZ_ALL_SHIFT 9
-#define NV40_FP_REG_SWZ_ALL_MASK (255 << 9)
-#define NV40_FP_REG_SWZ_X_SHIFT 9
-#define NV40_FP_REG_SWZ_X_MASK (3 << 9)
-#define NV40_FP_REG_SWZ_Y_SHIFT 11
-#define NV40_FP_REG_SWZ_Y_MASK (3 << 11)
-#define NV40_FP_REG_SWZ_Z_SHIFT 13
-#define NV40_FP_REG_SWZ_Z_MASK (3 << 13)
-#define NV40_FP_REG_SWZ_W_SHIFT 15
-#define NV40_FP_REG_SWZ_W_MASK (3 << 15)
-# define NV40_FP_SWIZZLE_X 0
-# define NV40_FP_SWIZZLE_Y 1
-# define NV40_FP_SWIZZLE_Z 2
-# define NV40_FP_SWIZZLE_W 3
-#define NV40_FP_REG_NEGATE (1 << 17)
-
-#ifndef NV40_SHADER_NO_FUCKEDNESS
-#define NV40SR_NONE 0
-#define NV40SR_OUTPUT 1
-#define NV40SR_INPUT 2
-#define NV40SR_TEMP 3
-#define NV40SR_CONST 4
-
-struct nv40_sreg {
- int type;
- int index;
-
- int dst_scale;
-
- int negate;
- int abs;
- int swz[4];
-
- int cc_update;
- int cc_update_reg;
- int cc_test;
- int cc_test_reg;
- int cc_swz[4];
-};
-
-static INLINE struct nv40_sreg
-nv40_sr(int type, int index)
-{
- struct nv40_sreg temp = {
- .type = type,
- .index = index,
- .dst_scale = DEF_SCALE,
- .abs = 0,
- .negate = 0,
- .swz = { 0, 1, 2, 3 },
- .cc_update = 0,
- .cc_update_reg = 0,
- .cc_test = DEF_CTEST,
- .cc_test_reg = 0,
- .cc_swz = { 0, 1, 2, 3 },
- };
- return temp;
-}
-
-static INLINE struct nv40_sreg
-nv40_sr_swz(struct nv40_sreg src, int x, int y, int z, int w)
-{
- struct nv40_sreg dst = src;
-
- dst.swz[SWZ_X] = src.swz[x];
- dst.swz[SWZ_Y] = src.swz[y];
- dst.swz[SWZ_Z] = src.swz[z];
- dst.swz[SWZ_W] = src.swz[w];
- return dst;
-}
-
-static INLINE struct nv40_sreg
-nv40_sr_neg(struct nv40_sreg src)
-{
- src.negate = !src.negate;
- return src;
-}
-
-static INLINE struct nv40_sreg
-nv40_sr_abs(struct nv40_sreg src)
-{
- src.abs = 1;
- return src;
-}
-
-static INLINE struct nv40_sreg
-nv40_sr_scale(struct nv40_sreg src, int scale)
-{
- src.dst_scale = scale;
- return src;
-}
-#endif
-
-#endif
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
deleted file mode 100644
index 4f28675e64c..00000000000
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ /dev/null
@@ -1,743 +0,0 @@
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "draw/draw_context.h"
-
-#include "tgsi/tgsi_parse.h"
-
-#include "nv40_context.h"
-#include "nv40_state.h"
-
-static void *
-nv40_blend_state_create(struct pipe_context *pipe,
- const struct pipe_blend_state *cso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_grobj *curie = nv40->screen->curie;
- struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso));
- struct nouveau_stateobj *so = so_new(5, 8, 0);
-
- if (cso->rt[0].blend_enable) {
- so_method(so, curie, NV40TCL_BLEND_ENABLE, 3);
- so_data (so, 1);
- so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
- nvgl_blend_func(cso->rt[0].rgb_src_factor));
- so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 |
- nvgl_blend_func(cso->rt[0].rgb_dst_factor));
- so_method(so, curie, NV40TCL_BLEND_EQUATION, 1);
- so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 |
- nvgl_blend_eqn(cso->rt[0].rgb_func));
- } else {
- so_method(so, curie, NV40TCL_BLEND_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_method(so, curie, NV40TCL_COLOR_MASK, 1);
- so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
- ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
-
- if (cso->logicop_enable) {
- so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 2);
- so_data (so, 1);
- so_data (so, nvgl_logicop_func(cso->logicop_func));
- } else {
- so_method(so, curie, NV40TCL_COLOR_LOGIC_OP_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_method(so, curie, NV40TCL_DITHER_ENABLE, 1);
- so_data (so, cso->dither ? 1 : 0);
-
- so_ref(so, &bso->so);
- so_ref(NULL, &so);
- bso->pipe = *cso;
- return (void *)bso;
-}
-
-static void
-nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->blend = hwcso;
- nv40->dirty |= NV40_NEW_BLEND;
-}
-
-static void
-nv40_blend_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_blend_state *bso = hwcso;
-
- so_ref(NULL, &bso->so);
- FREE(bso);
-}
-
-
-static INLINE unsigned
-wrap_mode(unsigned wrap) {
- unsigned ret;
-
- switch (wrap) {
- case PIPE_TEX_WRAP_REPEAT:
- ret = NV40TCL_TEX_WRAP_S_REPEAT;
- break;
- case PIPE_TEX_WRAP_MIRROR_REPEAT:
- ret = NV40TCL_TEX_WRAP_S_MIRRORED_REPEAT;
- break;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_EDGE;
- break;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- ret = NV40TCL_TEX_WRAP_S_CLAMP_TO_BORDER;
- break;
- case PIPE_TEX_WRAP_CLAMP:
- ret = NV40TCL_TEX_WRAP_S_CLAMP;
- break;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
- break;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
- break;
- case PIPE_TEX_WRAP_MIRROR_CLAMP:
- ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
- break;
- default:
- NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
- ret = NV40TCL_TEX_WRAP_S_REPEAT;
- break;
- }
-
- return ret >> NV40TCL_TEX_WRAP_S_SHIFT;
-}
-
-static void *
-nv40_sampler_state_create(struct pipe_context *pipe,
- const struct pipe_sampler_state *cso)
-{
- struct nv40_sampler_state *ps;
- uint32_t filter = 0;
-
- ps = MALLOC(sizeof(struct nv40_sampler_state));
-
- ps->fmt = 0;
- if (!cso->normalized_coords)
- ps->fmt |= NV40TCL_TEX_FORMAT_RECT;
-
- ps->wrap = ((wrap_mode(cso->wrap_s) << NV40TCL_TEX_WRAP_S_SHIFT) |
- (wrap_mode(cso->wrap_t) << NV40TCL_TEX_WRAP_T_SHIFT) |
- (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT));
-
- ps->en = 0;
- if (cso->max_anisotropy >= 2) {
- /* no idea, binary driver sets it, works without it.. meh.. */
- ps->wrap |= (1 << 5);
-
- if (cso->max_anisotropy >= 16) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
- } else
- if (cso->max_anisotropy >= 12) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
- } else
- if (cso->max_anisotropy >= 10) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
- } else
- if (cso->max_anisotropy >= 8) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
- } else
- if (cso->max_anisotropy >= 6) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
- } else
- if (cso->max_anisotropy >= 4) {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
- } else {
- ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
- }
- }
-
- switch (cso->mag_img_filter) {
- case PIPE_TEX_FILTER_LINEAR:
- filter |= NV40TCL_TEX_FILTER_MAG_LINEAR;
- break;
- case PIPE_TEX_FILTER_NEAREST:
- default:
- filter |= NV40TCL_TEX_FILTER_MAG_NEAREST;
- break;
- }
-
- switch (cso->min_img_filter) {
- case PIPE_TEX_FILTER_LINEAR:
- switch (cso->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NEAREST:
- filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_NEAREST;
- break;
- case PIPE_TEX_MIPFILTER_LINEAR:
- filter |= NV40TCL_TEX_FILTER_MIN_LINEAR_MIPMAP_LINEAR;
- break;
- case PIPE_TEX_MIPFILTER_NONE:
- default:
- filter |= NV40TCL_TEX_FILTER_MIN_LINEAR;
- break;
- }
- break;
- case PIPE_TEX_FILTER_NEAREST:
- default:
- switch (cso->min_mip_filter) {
- case PIPE_TEX_MIPFILTER_NEAREST:
- filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_NEAREST;
- break;
- case PIPE_TEX_MIPFILTER_LINEAR:
- filter |= NV40TCL_TEX_FILTER_MIN_NEAREST_MIPMAP_LINEAR;
- break;
- case PIPE_TEX_MIPFILTER_NONE:
- default:
- filter |= NV40TCL_TEX_FILTER_MIN_NEAREST;
- break;
- }
- break;
- }
-
- ps->filt = filter;
-
- {
- float limit;
-
- limit = CLAMP(cso->lod_bias, -16.0, 15.0);
- ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
-
- limit = CLAMP(cso->max_lod, 0.0, 15.0);
- ps->en |= (int)(limit * 256.0) << 7;
-
- limit = CLAMP(cso->min_lod, 0.0, 15.0);
- ps->en |= (int)(limit * 256.0) << 19;
- }
-
-
- if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- switch (cso->compare_func) {
- case PIPE_FUNC_NEVER:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NEVER;
- break;
- case PIPE_FUNC_GREATER:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GREATER;
- break;
- case PIPE_FUNC_EQUAL:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_EQUAL;
- break;
- case PIPE_FUNC_GEQUAL:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_GEQUAL;
- break;
- case PIPE_FUNC_LESS:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LESS;
- break;
- case PIPE_FUNC_NOTEQUAL:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_NOTEQUAL;
- break;
- case PIPE_FUNC_LEQUAL:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_LEQUAL;
- break;
- case PIPE_FUNC_ALWAYS:
- ps->wrap |= NV40TCL_TEX_WRAP_RCOMP_ALWAYS;
- break;
- default:
- break;
- }
- }
-
- ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
- (float_to_ubyte(cso->border_color[0]) << 16) |
- (float_to_ubyte(cso->border_color[1]) << 8) |
- (float_to_ubyte(cso->border_color[2]) << 0));
-
- return (void *)ps;
-}
-
-static void
-nv40_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- unsigned unit;
-
- for (unit = 0; unit < nr; unit++) {
- nv40->tex_sampler[unit] = sampler[unit];
- nv40->dirty_samplers |= (1 << unit);
- }
-
- for (unit = nr; unit < nv40->nr_samplers; unit++) {
- nv40->tex_sampler[unit] = NULL;
- nv40->dirty_samplers |= (1 << unit);
- }
-
- nv40->nr_samplers = nr;
- nv40->dirty |= NV40_NEW_SAMPLER;
-}
-
-static void
-nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- FREE(hwcso);
-}
-
-static void
-nv40_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
- struct pipe_texture **miptree)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- unsigned unit;
-
- for (unit = 0; unit < nr; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nv40->tex_miptree[unit], miptree[unit]);
- nv40->dirty_samplers |= (1 << unit);
- }
-
- for (unit = nr; unit < nv40->nr_textures; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nv40->tex_miptree[unit], NULL);
- nv40->dirty_samplers |= (1 << unit);
- }
-
- nv40->nr_textures = nr;
- nv40->dirty |= NV40_NEW_SAMPLER;
-}
-
-static void *
-nv40_rasterizer_state_create(struct pipe_context *pipe,
- const struct pipe_rasterizer_state *cso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
- struct nouveau_stateobj *so = so_new(9, 19, 0);
- struct nouveau_grobj *curie = nv40->screen->curie;
-
- /*XXX: ignored:
- * light_twoside
- * point_smooth -nohw
- * multisample
- */
-
- so_method(so, curie, NV40TCL_SHADE_MODEL, 1);
- so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT :
- NV40TCL_SHADE_MODEL_SMOOTH);
-
- so_method(so, curie, NV40TCL_LINE_WIDTH, 2);
- so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
- so_data (so, cso->line_smooth ? 1 : 0);
- so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2);
- so_data (so, cso->line_stipple_enable ? 1 : 0);
- so_data (so, (cso->line_stipple_pattern << 16) |
- cso->line_stipple_factor);
-
- so_method(so, curie, NV40TCL_POINT_SIZE, 1);
- so_data (so, fui(cso->point_size));
-
- so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6);
- if (cso->front_winding == PIPE_WINDING_CCW) {
- so_data(so, nvgl_polygon_mode(cso->fill_ccw));
- so_data(so, nvgl_polygon_mode(cso->fill_cw));
- switch (cso->cull_mode) {
- case PIPE_WINDING_CCW:
- so_data(so, NV40TCL_CULL_FACE_FRONT);
- break;
- case PIPE_WINDING_CW:
- so_data(so, NV40TCL_CULL_FACE_BACK);
- break;
- case PIPE_WINDING_BOTH:
- so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK);
- break;
- default:
- so_data(so, NV40TCL_CULL_FACE_BACK);
- break;
- }
- so_data(so, NV40TCL_FRONT_FACE_CCW);
- } else {
- so_data(so, nvgl_polygon_mode(cso->fill_cw));
- so_data(so, nvgl_polygon_mode(cso->fill_ccw));
- switch (cso->cull_mode) {
- case PIPE_WINDING_CCW:
- so_data(so, NV40TCL_CULL_FACE_BACK);
- break;
- case PIPE_WINDING_CW:
- so_data(so, NV40TCL_CULL_FACE_FRONT);
- break;
- case PIPE_WINDING_BOTH:
- so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK);
- break;
- default:
- so_data(so, NV40TCL_CULL_FACE_BACK);
- break;
- }
- so_data(so, NV40TCL_FRONT_FACE_CW);
- }
- so_data(so, cso->poly_smooth ? 1 : 0);
- so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0);
-
- so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, cso->poly_stipple_enable ? 1 : 0);
-
- so_method(so, curie, NV40TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
- so_data(so, 1);
- else
- so_data(so, 0);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
- so_data(so, 1);
- else
- so_data(so, 0);
- if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
- (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
- so_data(so, 1);
- else
- so_data(so, 0);
- if (cso->offset_cw || cso->offset_ccw) {
- so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2);
- so_data (so, fui(cso->offset_scale));
- so_data (so, fui(cso->offset_units * 2));
- }
-
- so_method(so, curie, NV40TCL_POINT_SPRITE, 1);
- if (cso->point_quad_rasterization) {
- unsigned psctl = (1 << 0), i;
-
- for (i = 0; i < 8; i++) {
- if ((cso->sprite_coord_enable >> i) & 1)
- psctl |= (1 << (8 + i));
- }
-
- so_data(so, psctl);
- } else {
- so_data(so, 0);
- }
-
- so_ref(so, &rsso->so);
- so_ref(NULL, &so);
- rsso->pipe = *cso;
- return (void *)rsso;
-}
-
-static void
-nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->rasterizer = hwcso;
- nv40->dirty |= NV40_NEW_RAST;
- nv40->draw_dirty |= NV40_NEW_RAST;
-}
-
-static void
-nv40_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_rasterizer_state *rsso = hwcso;
-
- so_ref(NULL, &rsso->so);
- FREE(rsso);
-}
-
-static void *
-nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
- const struct pipe_depth_stencil_alpha_state *cso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
- struct nouveau_stateobj *so = so_new(6, 20, 0);
- struct nouveau_grobj *curie = nv40->screen->curie;
-
- so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
- so_data (so, nvgl_comparison_op(cso->depth.func));
- so_data (so, cso->depth.writemask ? 1 : 0);
- so_data (so, cso->depth.enabled ? 1 : 0);
-
- so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
- so_data (so, cso->alpha.enabled ? 1 : 0);
- so_data (so, nvgl_comparison_op(cso->alpha.func));
- so_data (so, float_to_ubyte(cso->alpha.ref_value));
-
- if (cso->stencil[0].enabled) {
- so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 3);
- so_data (so, cso->stencil[0].enabled ? 1 : 0);
- so_data (so, cso->stencil[0].writemask);
- so_data (so, nvgl_comparison_op(cso->stencil[0].func));
- so_method(so, curie, NV40TCL_STENCIL_FRONT_FUNC_MASK, 4);
- so_data (so, cso->stencil[0].valuemask);
- so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
- } else {
- so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
- so_data (so, 0);
- }
-
- if (cso->stencil[1].enabled) {
- so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 3);
- so_data (so, cso->stencil[1].enabled ? 1 : 0);
- so_data (so, cso->stencil[1].writemask);
- so_data (so, nvgl_comparison_op(cso->stencil[1].func));
- so_method(so, curie, NV40TCL_STENCIL_BACK_FUNC_MASK, 4);
- so_data (so, cso->stencil[1].valuemask);
- so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
- so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
- } else {
- so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_ref(so, &zsaso->so);
- so_ref(NULL, &so);
- zsaso->pipe = *cso;
- return (void *)zsaso;
-}
-
-static void
-nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->zsa = hwcso;
- nv40->dirty |= NV40_NEW_ZSA;
-}
-
-static void
-nv40_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_zsa_state *zsaso = hwcso;
-
- so_ref(NULL, &zsaso->so);
- FREE(zsaso);
-}
-
-static void *
-nv40_vp_state_create(struct pipe_context *pipe,
- const struct pipe_shader_state *cso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_vertex_program *vp;
-
- vp = CALLOC(1, sizeof(struct nv40_vertex_program));
- vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
- vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe);
-
- return (void *)vp;
-}
-
-static void
-nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->vertprog = hwcso;
- nv40->dirty |= NV40_NEW_VERTPROG;
- nv40->draw_dirty |= NV40_NEW_VERTPROG;
-}
-
-static void
-nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_vertex_program *vp = hwcso;
-
- draw_delete_vertex_shader(nv40->draw, vp->draw);
- nv40_vertprog_destroy(nv40, vp);
- FREE((void*)vp->pipe.tokens);
- FREE(vp);
-}
-
-static void *
-nv40_fp_state_create(struct pipe_context *pipe,
- const struct pipe_shader_state *cso)
-{
- struct nv40_fragment_program *fp;
-
- fp = CALLOC(1, sizeof(struct nv40_fragment_program));
- fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
-
- tgsi_scan_shader(fp->pipe.tokens, &fp->info);
-
- return (void *)fp;
-}
-
-static void
-nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->fragprog = hwcso;
- nv40->dirty |= NV40_NEW_FRAGPROG;
-}
-
-static void
-nv40_fp_state_delete(struct pipe_context *pipe, void *hwcso)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_fragment_program *fp = hwcso;
-
- nv40_fragprog_destroy(nv40, fp);
- FREE((void*)fp->pipe.tokens);
- FREE(fp);
-}
-
-static void
-nv40_set_blend_color(struct pipe_context *pipe,
- const struct pipe_blend_color *bcol)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->blend_colour = *bcol;
- nv40->dirty |= NV40_NEW_BCOL;
-}
-
- static void
-nv40_set_stencil_ref(struct pipe_context *pipe,
- const struct pipe_stencil_ref *sr)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->stencil_ref = *sr;
- nv40->dirty |= NV40_NEW_SR;
-}
-
-static void
-nv40_set_clip_state(struct pipe_context *pipe,
- const struct pipe_clip_state *clip)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->clip = *clip;
- nv40->dirty |= NV40_NEW_UCP;
- nv40->draw_dirty |= NV40_NEW_UCP;
-}
-
-static void
-nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
- struct pipe_buffer *buf )
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->constbuf[shader] = buf;
- nv40->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
-
- if (shader == PIPE_SHADER_VERTEX) {
- nv40->dirty |= NV40_NEW_VERTPROG;
- } else
- if (shader == PIPE_SHADER_FRAGMENT) {
- nv40->dirty |= NV40_NEW_FRAGPROG;
- }
-}
-
-static void
-nv40_set_framebuffer_state(struct pipe_context *pipe,
- const struct pipe_framebuffer_state *fb)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->framebuffer = *fb;
- nv40->dirty |= NV40_NEW_FB;
-}
-
-static void
-nv40_set_polygon_stipple(struct pipe_context *pipe,
- const struct pipe_poly_stipple *stipple)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- memcpy(nv40->stipple, stipple->stipple, 4 * 32);
- nv40->dirty |= NV40_NEW_STIPPLE;
-}
-
-static void
-nv40_set_scissor_state(struct pipe_context *pipe,
- const struct pipe_scissor_state *s)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->scissor = *s;
- nv40->dirty |= NV40_NEW_SCISSOR;
-}
-
-static void
-nv40_set_viewport_state(struct pipe_context *pipe,
- const struct pipe_viewport_state *vpt)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- nv40->viewport = *vpt;
- nv40->dirty |= NV40_NEW_VIEWPORT;
- nv40->draw_dirty |= NV40_NEW_VIEWPORT;
-}
-
-static void
-nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_buffer *vb)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count);
- nv40->vtxbuf_nr = count;
-
- nv40->dirty |= NV40_NEW_ARRAYS;
- nv40->draw_dirty |= NV40_NEW_ARRAYS;
-}
-
-static void
-nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
-
- memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
- nv40->vtxelt_nr = count;
-
- nv40->dirty |= NV40_NEW_ARRAYS;
- nv40->draw_dirty |= NV40_NEW_ARRAYS;
-}
-
-void
-nv40_init_state_functions(struct nv40_context *nv40)
-{
- nv40->pipe.create_blend_state = nv40_blend_state_create;
- nv40->pipe.bind_blend_state = nv40_blend_state_bind;
- nv40->pipe.delete_blend_state = nv40_blend_state_delete;
-
- nv40->pipe.create_sampler_state = nv40_sampler_state_create;
- nv40->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind;
- nv40->pipe.delete_sampler_state = nv40_sampler_state_delete;
- nv40->pipe.set_fragment_sampler_textures = nv40_set_sampler_texture;
-
- nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create;
- nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind;
- nv40->pipe.delete_rasterizer_state = nv40_rasterizer_state_delete;
-
- nv40->pipe.create_depth_stencil_alpha_state =
- nv40_depth_stencil_alpha_state_create;
- nv40->pipe.bind_depth_stencil_alpha_state =
- nv40_depth_stencil_alpha_state_bind;
- nv40->pipe.delete_depth_stencil_alpha_state =
- nv40_depth_stencil_alpha_state_delete;
-
- nv40->pipe.create_vs_state = nv40_vp_state_create;
- nv40->pipe.bind_vs_state = nv40_vp_state_bind;
- nv40->pipe.delete_vs_state = nv40_vp_state_delete;
-
- nv40->pipe.create_fs_state = nv40_fp_state_create;
- nv40->pipe.bind_fs_state = nv40_fp_state_bind;
- nv40->pipe.delete_fs_state = nv40_fp_state_delete;
-
- nv40->pipe.set_blend_color = nv40_set_blend_color;
- nv40->pipe.set_stencil_ref = nv40_set_stencil_ref;
- nv40->pipe.set_clip_state = nv40_set_clip_state;
- nv40->pipe.set_constant_buffer = nv40_set_constant_buffer;
- nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state;
- nv40->pipe.set_polygon_stipple = nv40_set_polygon_stipple;
- nv40->pipe.set_scissor_state = nv40_set_scissor_state;
- nv40->pipe.set_viewport_state = nv40_set_viewport_state;
-
- nv40->pipe.set_vertex_buffers = nv40_set_vertex_buffers;
- nv40->pipe.set_vertex_elements = nv40_set_vertex_elements;
-}
-
diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c
deleted file mode 100644
index 3ff00a37f66..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_blend.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_blend_validate(struct nv40_context *nv40)
-{
- so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_blend = {
- .validate = nv40_state_blend_validate,
- .dirty = {
- .pipe = NV40_NEW_BLEND,
- .hw = NV40_STATE_BLEND
- }
-};
-
-static boolean
-nv40_state_blend_colour_validate(struct nv40_context *nv40)
-{
- struct nouveau_stateobj *so = so_new(1, 1, 0);
- struct pipe_blend_color *bcol = &nv40->blend_colour;
-
- so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1);
- so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) |
- (float_to_ubyte(bcol->color[0]) << 16) |
- (float_to_ubyte(bcol->color[1]) << 8) |
- (float_to_ubyte(bcol->color[2]) << 0)));
-
- so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_blend_colour = {
- .validate = nv40_state_blend_colour_validate,
- .dirty = {
- .pipe = NV40_NEW_BCOL,
- .hw = NV40_STATE_BCOL
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
deleted file mode 100644
index 8990f303ce4..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "nv40_context.h"
-#include "nv40_state.h"
-#include "draw/draw_context.h"
-
-static struct nv40_state_entry *render_states[] = {
- &nv40_state_framebuffer,
- &nv40_state_rasterizer,
- &nv40_state_scissor,
- &nv40_state_stipple,
- &nv40_state_fragprog,
- &nv40_state_fragtex,
- &nv40_state_vertprog,
- &nv40_state_blend,
- &nv40_state_blend_colour,
- &nv40_state_zsa,
- &nv40_state_sr,
- &nv40_state_viewport,
- &nv40_state_vbo,
- NULL
-};
-
-static struct nv40_state_entry *swtnl_states[] = {
- &nv40_state_framebuffer,
- &nv40_state_rasterizer,
- &nv40_state_scissor,
- &nv40_state_stipple,
- &nv40_state_fragprog,
- &nv40_state_fragtex,
- &nv40_state_vertprog,
- &nv40_state_blend,
- &nv40_state_blend_colour,
- &nv40_state_zsa,
- &nv40_state_sr,
- &nv40_state_viewport,
- &nv40_state_vtxfmt,
- NULL
-};
-
-static void
-nv40_state_do_validate(struct nv40_context *nv40,
- struct nv40_state_entry **states)
-{
- while (*states) {
- struct nv40_state_entry *e = *states;
-
- if (nv40->dirty & e->dirty.pipe) {
- if (e->validate(nv40))
- nv40->state.dirty |= (1ULL << e->dirty.hw);
- }
-
- states++;
- }
- nv40->dirty = 0;
-}
-
-void
-nv40_state_emit(struct nv40_context *nv40)
-{
- struct nv40_state *state = &nv40->state;
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- unsigned i;
- uint64_t states;
-
- /* XXX: race conditions
- */
- if (nv40 != screen->cur_ctx) {
- for (i = 0; i < NV40_STATE_MAX; i++) {
- if (state->hw[i] && screen->state[i] != state->hw[i])
- state->dirty |= (1ULL << i);
- }
-
- screen->cur_ctx = nv40;
- }
-
- for (i = 0, states = state->dirty; states; i++) {
- if (!(states & (1ULL << i)))
- continue;
- so_ref (state->hw[i], &nv40->screen->state[i]);
- if (state->hw[i])
- so_emit(chan, nv40->screen->state[i]);
- states &= ~(1ULL << i);
- }
-
- if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) |
- (1ULL << NV40_STATE_FRAGTEX0))) {
- BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
- OUT_RING (chan, 2);
- BEGIN_RING(chan, curie, NV40TCL_TEX_CACHE_CTL, 1);
- OUT_RING (chan, 1);
- }
-
- state->dirty = 0;
-}
-
-void
-nv40_state_flush_notify(struct nouveau_channel *chan)
-{
- struct nv40_context *nv40 = chan->user_private;
- struct nv40_state *state = &nv40->state;
- unsigned i, samplers;
-
- so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]);
- for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
- if (!(samplers & (1 << i)))
- continue;
- so_emit_reloc_markers(chan,
- state->hw[NV40_STATE_FRAGTEX0+i]);
- samplers &= ~(1ULL << i);
- }
- so_emit_reloc_markers(chan, state->hw[NV40_STATE_FRAGPROG]);
- if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW)
- so_emit_reloc_markers(chan, state->hw[NV40_STATE_VTXBUF]);
-}
-
-boolean
-nv40_state_validate(struct nv40_context *nv40)
-{
- boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE;
-
- if (nv40->render_mode != HW) {
- /* Don't even bother trying to go back to hw if none
- * of the states that caused swtnl previously have changed.
- */
- if ((nv40->fallback_swtnl & nv40->dirty)
- != nv40->fallback_swtnl)
- return FALSE;
-
- /* Attempt to go to hwtnl again */
- nv40->pipe.flush(&nv40->pipe, 0, NULL);
- nv40->dirty |= (NV40_NEW_VIEWPORT |
- NV40_NEW_VERTPROG |
- NV40_NEW_ARRAYS);
- nv40->render_mode = HW;
- }
-
- nv40_state_do_validate(nv40, render_states);
- if (nv40->fallback_swtnl || nv40->fallback_swrast)
- return FALSE;
-
- if (was_sw)
- NOUVEAU_ERR("swtnl->hw\n");
-
- return TRUE;
-}
-
-boolean
-nv40_state_validate_swtnl(struct nv40_context *nv40)
-{
- struct draw_context *draw = nv40->draw;
-
- /* Setup for swtnl */
- if (nv40->render_mode == HW) {
- NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
- nv40->pipe.flush(&nv40->pipe, 0, NULL);
- nv40->dirty |= (NV40_NEW_VIEWPORT |
- NV40_NEW_VERTPROG |
- NV40_NEW_ARRAYS);
- nv40->render_mode = SWTNL;
- }
-
- if (nv40->draw_dirty & NV40_NEW_VERTPROG)
- draw_bind_vertex_shader(draw, nv40->vertprog->draw);
-
- if (nv40->draw_dirty & NV40_NEW_RAST)
- draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe);
-
- if (nv40->draw_dirty & NV40_NEW_UCP)
- draw_set_clip_state(draw, &nv40->clip);
-
- if (nv40->draw_dirty & NV40_NEW_VIEWPORT)
- draw_set_viewport_state(draw, &nv40->viewport);
-
- if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
- draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
- draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
- }
-
- nv40_state_do_validate(nv40, swtnl_states);
- if (nv40->fallback_swrast) {
- NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
- return FALSE;
- }
-
- nv40->draw_dirty = 0;
- return TRUE;
-}
-
diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c
deleted file mode 100644
index fd3fdfddc09..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_fb.c
+++ /dev/null
@@ -1,175 +0,0 @@
-#include "nv40_context.h"
-#include "nouveau/nouveau_util.h"
-
-static struct pipe_buffer *
-nv40_do_surface_buffer(struct pipe_surface *surface)
-{
- struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture;
- return mt->buffer;
-}
-
-#define nv40_surface_buffer(ps) nouveau_bo(nv40_do_surface_buffer(ps))
-
-static boolean
-nv40_state_framebuffer_validate(struct nv40_context *nv40)
-{
- struct nouveau_channel *chan = nv40->screen->base.channel;
- struct nouveau_grobj *curie = nv40->screen->curie;
- struct pipe_framebuffer_state *fb = &nv40->framebuffer;
- struct nv04_surface *rt[4], *zeta;
- uint32_t rt_enable, rt_format;
- int i, colour_format = 0, zeta_format = 0;
- struct nouveau_stateobj *so = so_new(18, 24, 10);
- unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
- unsigned w = fb->width;
- unsigned h = fb->height;
-
- rt_enable = 0;
- for (i = 0; i < fb->nr_cbufs; i++) {
- if (colour_format) {
- assert(colour_format == fb->cbufs[i]->format);
- } else {
- colour_format = fb->cbufs[i]->format;
- rt_enable |= (NV40TCL_RT_ENABLE_COLOR0 << i);
- rt[i] = (struct nv04_surface *)fb->cbufs[i];
- }
- }
-
- if (rt_enable & (NV40TCL_RT_ENABLE_COLOR1 | NV40TCL_RT_ENABLE_COLOR2 |
- NV40TCL_RT_ENABLE_COLOR3))
- rt_enable |= NV40TCL_RT_ENABLE_MRT;
-
- if (fb->zsbuf) {
- zeta_format = fb->zsbuf->format;
- zeta = (struct nv04_surface *)fb->zsbuf;
- }
-
- if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
- assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
- for (i = 1; i < fb->nr_cbufs; i++)
- assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
-
- rt_format = NV40TCL_RT_FORMAT_TYPE_SWIZZLED |
- log2i(fb->width) << NV40TCL_RT_FORMAT_LOG2_WIDTH_SHIFT |
- log2i(fb->height) << NV40TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT;
- }
- else
- rt_format = NV40TCL_RT_FORMAT_TYPE_LINEAR;
-
- switch (colour_format) {
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- rt_format |= NV40TCL_RT_FORMAT_COLOR_X8R8G8B8;
- break;
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case 0:
- rt_format |= NV40TCL_RT_FORMAT_COLOR_A8R8G8B8;
- break;
- case PIPE_FORMAT_B5G6R5_UNORM:
- rt_format |= NV40TCL_RT_FORMAT_COLOR_R5G6B5;
- break;
- default:
- assert(0);
- }
-
- switch (zeta_format) {
- case PIPE_FORMAT_Z16_UNORM:
- rt_format |= NV40TCL_RT_FORMAT_ZETA_Z16;
- break;
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case 0:
- rt_format |= NV40TCL_RT_FORMAT_ZETA_Z24S8;
- break;
- default:
- assert(0);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) {
- so_method(so, curie, NV40TCL_DMA_COLOR0, 1);
- so_reloc (so, nv40_surface_buffer(&rt[0]->base), 0,
- rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, curie, NV40TCL_COLOR0_PITCH, 2);
- so_data (so, rt[0]->pitch);
- so_reloc (so, nv40_surface_buffer(&rt[0]->base),
- rt[0]->base.offset, rt_flags | NOUVEAU_BO_LOW,
- 0, 0);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) {
- so_method(so, curie, NV40TCL_DMA_COLOR1, 1);
- so_reloc (so, nv40_surface_buffer(&rt[1]->base), 0,
- rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, curie, NV40TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nv40_surface_buffer(&rt[1]->base),
- rt[1]->base.offset, rt_flags | NOUVEAU_BO_LOW,
- 0, 0);
- so_data (so, rt[1]->pitch);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
- so_method(so, curie, NV40TCL_DMA_COLOR2, 1);
- so_reloc (so, nv40_surface_buffer(&rt[2]->base), 0,
- rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, curie, NV40TCL_COLOR2_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&rt[2]->base),
- rt[2]->base.offset, rt_flags | NOUVEAU_BO_LOW,
- 0, 0);
- so_method(so, curie, NV40TCL_COLOR2_PITCH, 1);
- so_data (so, rt[2]->pitch);
- }
-
- if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
- so_method(so, curie, NV40TCL_DMA_COLOR3, 1);
- so_reloc (so, nv40_surface_buffer(&rt[3]->base), 0,
- rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, curie, NV40TCL_COLOR3_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&rt[3]->base),
- rt[3]->base.offset, rt_flags | NOUVEAU_BO_LOW,
- 0, 0);
- so_method(so, curie, NV40TCL_COLOR3_PITCH, 1);
- so_data (so, rt[3]->pitch);
- }
-
- if (zeta_format) {
- so_method(so, curie, NV40TCL_DMA_ZETA, 1);
- so_reloc (so, nv40_surface_buffer(&zeta->base), 0,
- rt_flags | NOUVEAU_BO_OR,
- chan->vram->handle, chan->gart->handle);
- so_method(so, curie, NV40TCL_ZETA_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&zeta->base),
- zeta->base.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
- so_method(so, curie, NV40TCL_ZETA_PITCH, 1);
- so_data (so, zeta->pitch);
- }
-
- so_method(so, curie, NV40TCL_RT_ENABLE, 1);
- so_data (so, rt_enable);
- so_method(so, curie, NV40TCL_RT_HORIZ, 3);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_data (so, rt_format);
- so_method(so, curie, NV40TCL_VIEWPORT_HORIZ, 2);
- so_data (so, (w << 16) | 0);
- so_data (so, (h << 16) | 0);
- so_method(so, curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
- so_data (so, ((w - 1) << 16) | 0);
- so_data (so, ((h - 1) << 16) | 0);
- so_method(so, curie, 0x1d88, 1);
- so_data (so, (1 << 12) | h);
-
- so_ref(so, &nv40->state.hw[NV40_STATE_FB]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_framebuffer = {
- .validate = nv40_state_framebuffer_validate,
- .dirty = {
- .pipe = NV40_NEW_FB,
- .hw = NV40_STATE_FB
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c
deleted file mode 100644
index 9ecda5990f0..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_rasterizer.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_rasterizer_validate(struct nv40_context *nv40)
-{
- so_ref(nv40->rasterizer->so,
- &nv40->state.hw[NV40_STATE_RAST]);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_rasterizer = {
- .validate = nv40_state_rasterizer_validate,
- .dirty = {
- .pipe = NV40_NEW_RAST,
- .hw = NV40_STATE_RAST
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c
deleted file mode 100644
index 753a505e934..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_scissor.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_scissor_validate(struct nv40_context *nv40)
-{
- struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe;
- struct pipe_scissor_state *s = &nv40->scissor;
- struct nouveau_stateobj *so;
-
- if (nv40->state.hw[NV40_STATE_SCISSOR] &&
- (rast->scissor == 0 && nv40->state.scissor_enabled == 0))
- return FALSE;
- nv40->state.scissor_enabled = rast->scissor;
-
- so = so_new(1, 2, 0);
- so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2);
- if (nv40->state.scissor_enabled) {
- so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
- so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
- } else {
- so_data (so, 4096 << 16);
- so_data (so, 4096 << 16);
- }
-
- so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_scissor = {
- .validate = nv40_state_scissor_validate,
- .dirty = {
- .pipe = NV40_NEW_SCISSOR | NV40_NEW_RAST,
- .hw = NV40_STATE_SCISSOR
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c
deleted file mode 100644
index 2b371ebfec0..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_stipple.c
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_stipple_validate(struct nv40_context *nv40)
-{
- struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe;
- struct nouveau_grobj *curie = nv40->screen->curie;
- struct nouveau_stateobj *so;
-
- if (nv40->state.hw[NV40_STATE_STIPPLE] &&
- (rast->poly_stipple_enable == 0 && nv40->state.stipple_enabled == 0))
- return FALSE;
-
- if (rast->poly_stipple_enable) {
- unsigned i;
-
- so = so_new(2, 33, 0);
- so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, 1);
- so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, nv40->stipple[i]);
- } else {
- so = so_new(1, 1, 0);
- so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1);
- so_data (so, 0);
- }
-
- so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_stipple = {
- .validate = nv40_state_stipple_validate,
- .dirty = {
- .pipe = NV40_NEW_STIPPLE | NV40_NEW_RAST,
- .hw = NV40_STATE_STIPPLE,
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c
deleted file mode 100644
index 3aacb00f996..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_viewport.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_viewport_validate(struct nv40_context *nv40)
-{
- struct pipe_viewport_state *vpt = &nv40->viewport;
- struct nouveau_stateobj *so;
-
- if (nv40->state.hw[NV40_STATE_VIEWPORT] &&
- !(nv40->dirty & NV40_NEW_VIEWPORT))
- return FALSE;
-
- so = so_new(2, 9, 0);
- so_method(so, nv40->screen->curie,
- NV40TCL_VIEWPORT_TRANSLATE_X, 8);
- so_data (so, fui(vpt->translate[0]));
- so_data (so, fui(vpt->translate[1]));
- so_data (so, fui(vpt->translate[2]));
- so_data (so, fui(vpt->translate[3]));
- so_data (so, fui(vpt->scale[0]));
- so_data (so, fui(vpt->scale[1]));
- so_data (so, fui(vpt->scale[2]));
- so_data (so, fui(vpt->scale[3]));
- so_method(so, nv40->screen->curie, 0x1d78, 1);
- so_data (so, 1);
-
- so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_viewport = {
- .validate = nv40_state_viewport_validate,
- .dirty = {
- .pipe = NV40_NEW_VIEWPORT | NV40_NEW_RAST,
- .hw = NV40_STATE_VIEWPORT
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c
deleted file mode 100644
index 9cbe7da6db1..00000000000
--- a/src/gallium/drivers/nv40/nv40_state_zsa.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "nv40_context.h"
-
-static boolean
-nv40_state_zsa_validate(struct nv40_context *nv40)
-{
- so_ref(nv40->zsa->so,
- &nv40->state.hw[NV40_STATE_ZSA]);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_zsa = {
- .validate = nv40_state_zsa_validate,
- .dirty = {
- .pipe = NV40_NEW_ZSA,
- .hw = NV40_STATE_ZSA
- }
-};
-
-static boolean
-nv40_state_sr_validate(struct nv40_context *nv40)
-{
- struct nouveau_stateobj *so = so_new(2, 2, 0);
- struct pipe_stencil_ref *sr = &nv40->stencil_ref;
-
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_FUNC_REF, 1);
- so_data (so, sr->ref_value[0]);
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_FUNC_REF, 1);
- so_data (so, sr->ref_value[1]);
-
- so_ref(so, &nv40->state.hw[NV40_STATE_SR]);
- so_ref(NULL, &so);
- return TRUE;
-}
-
-struct nv40_state_entry nv40_state_sr = {
- .validate = nv40_state_sr_validate,
- .dirty = {
- .pipe = NV40_NEW_SR,
- .hw = NV40_STATE_SR
- }
-};
diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c
deleted file mode 100644
index 02ecfd7bbb7..00000000000
--- a/src/gallium/drivers/nv40/nv40_surface.c
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-
-#include "util/u_tile.h"
-
-#include "nv40_context.h"
-
-static void
-nv40_surface_copy(struct pipe_context *pipe,
- struct pipe_surface *dest, unsigned destx, unsigned desty,
- struct pipe_surface *src, unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv04_surface_2d *eng2d = nv40->screen->eng2d;
-
- eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
-}
-
-static void
-nv40_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
- unsigned destx, unsigned desty, unsigned width,
- unsigned height, unsigned value)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv04_surface_2d *eng2d = nv40->screen->eng2d;
-
- eng2d->fill(eng2d, dest, destx, desty, width, height, value);
-}
-
-void
-nv40_init_surface_functions(struct nv40_context *nv40)
-{
- nv40->pipe.surface_copy = nv40_surface_copy;
- nv40->pipe.surface_fill = nv40_surface_fill;
-}
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
deleted file mode 100644
index 7812460d2ed..00000000000
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ /dev/null
@@ -1,565 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-
-#include "nv40_context.h"
-#include "nv40_state.h"
-
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_util.h"
-
-#define FORCE_SWTNL 0
-
-static INLINE int
-nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
-{
- switch (pipe) {
- case PIPE_FORMAT_R32_FLOAT:
- case PIPE_FORMAT_R32G32_FLOAT:
- case PIPE_FORMAT_R32G32B32_FLOAT:
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- *fmt = NV40TCL_VTXFMT_TYPE_FLOAT;
- break;
- case PIPE_FORMAT_R8_UNORM:
- case PIPE_FORMAT_R8G8_UNORM:
- case PIPE_FORMAT_R8G8B8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- *fmt = NV40TCL_VTXFMT_TYPE_UBYTE;
- break;
- case PIPE_FORMAT_R16_SSCALED:
- case PIPE_FORMAT_R16G16_SSCALED:
- case PIPE_FORMAT_R16G16B16_SSCALED:
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- *fmt = NV40TCL_VTXFMT_TYPE_USHORT;
- break;
- default:
- NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
- return 1;
- }
-
- switch (pipe) {
- case PIPE_FORMAT_R8_UNORM:
- case PIPE_FORMAT_R32_FLOAT:
- case PIPE_FORMAT_R16_SSCALED:
- *ncomp = 1;
- break;
- case PIPE_FORMAT_R8G8_UNORM:
- case PIPE_FORMAT_R32G32_FLOAT:
- case PIPE_FORMAT_R16G16_SSCALED:
- *ncomp = 2;
- break;
- case PIPE_FORMAT_R8G8B8_UNORM:
- case PIPE_FORMAT_R32G32B32_FLOAT:
- case PIPE_FORMAT_R16G16B16_SSCALED:
- *ncomp = 3;
- break;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- case PIPE_FORMAT_R16G16B16A16_SSCALED:
- *ncomp = 4;
- break;
- default:
- NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe));
- return 1;
- }
-
- return 0;
-}
-
-static boolean
-nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib,
- unsigned ib_size)
-{
- struct pipe_screen *pscreen = &nv40->screen->base.base;
- unsigned type;
-
- if (!ib) {
- nv40->idxbuf = NULL;
- nv40->idxbuf_format = 0xdeadbeef;
- return FALSE;
- }
-
- if (!pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF) || ib_size == 1)
- return FALSE;
-
- switch (ib_size) {
- case 2:
- type = NV40TCL_IDXBUF_FORMAT_TYPE_U16;
- break;
- case 4:
- type = NV40TCL_IDXBUF_FORMAT_TYPE_U32;
- break;
- default:
- return FALSE;
- }
-
- if (ib != nv40->idxbuf ||
- type != nv40->idxbuf_format) {
- nv40->dirty |= NV40_NEW_ARRAYS;
- nv40->idxbuf = ib;
- nv40->idxbuf_format = type;
- }
-
- return TRUE;
-}
-
-static boolean
-nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so,
- int attrib, struct pipe_vertex_element *ve,
- struct pipe_vertex_buffer *vb)
-{
- struct pipe_screen *pscreen = nv40->pipe.screen;
- struct nouveau_grobj *curie = nv40->screen->curie;
- unsigned type, ncomp;
- void *map;
-
- if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp))
- return FALSE;
-
- map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- map += vb->buffer_offset + ve->src_offset;
-
- switch (type) {
- case NV40TCL_VTXFMT_TYPE_FLOAT:
- {
- float *v = map;
-
- switch (ncomp) {
- case 4:
- so_method(so, curie, NV40TCL_VTX_ATTR_4F_X(attrib), 4);
- so_data (so, fui(v[0]));
- so_data (so, fui(v[1]));
- so_data (so, fui(v[2]));
- so_data (so, fui(v[3]));
- break;
- case 3:
- so_method(so, curie, NV40TCL_VTX_ATTR_3F_X(attrib), 3);
- so_data (so, fui(v[0]));
- so_data (so, fui(v[1]));
- so_data (so, fui(v[2]));
- break;
- case 2:
- so_method(so, curie, NV40TCL_VTX_ATTR_2F_X(attrib), 2);
- so_data (so, fui(v[0]));
- so_data (so, fui(v[1]));
- break;
- case 1:
- so_method(so, curie, NV40TCL_VTX_ATTR_1F(attrib), 1);
- so_data (so, fui(v[0]));
- break;
- default:
- pipe_buffer_unmap(pscreen, vb->buffer);
- return FALSE;
- }
- }
- break;
- default:
- pipe_buffer_unmap(pscreen, vb->buffer);
- return FALSE;
- }
-
- pipe_buffer_unmap(pscreen, vb->buffer);
-
- return TRUE;
-}
-
-void
-nv40_draw_arrays(struct pipe_context *pipe,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- unsigned restart;
-
- nv40_vbo_set_idxbuf(nv40, NULL, 0);
- if (FORCE_SWTNL || !nv40_state_validate(nv40)) {
- nv40_draw_elements_swtnl(pipe, NULL, 0,
- mode, start, count);
- return;
- }
-
- while (count) {
- unsigned vc, nr;
-
- nv40_state_emit(nv40);
-
- vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
- mode, start, count, &restart);
- if (!vc) {
- FIRE_RING(chan);
- continue;
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, nvgl_primitive(mode));
-
- nr = (vc & 0xff);
- if (nr) {
- BEGIN_RING(chan, curie, NV40TCL_VB_VERTEX_BATCH, 1);
- OUT_RING (chan, ((nr - 1) << 24) | start);
- start += nr;
- }
-
- nr = vc >> 8;
- while (nr) {
- unsigned push = nr > 2047 ? 2047 : nr;
-
- nr -= push;
-
- BEGIN_RING_NI(chan, curie, NV40TCL_VB_VERTEX_BATCH, push);
- while (push--) {
- OUT_RING(chan, ((0x100 - 1) << 24) | start);
- start += 0x100;
- }
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, 0);
-
- count -= vc;
- start = restart;
- }
-
- pipe->flush(pipe, 0, NULL);
-}
-
-static INLINE void
-nv40_draw_elements_u08(struct nv40_context *nv40, void *ib,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- while (count) {
- uint8_t *elts = (uint8_t *)ib + start;
- unsigned vc, push, restart;
-
- nv40_state_emit(nv40);
-
- vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
- mode, start, count, &restart);
- if (vc == 0) {
- FIRE_RING(chan);
- continue;
- }
- count -= vc;
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, nvgl_primitive(mode));
-
- if (vc & 1) {
- BEGIN_RING(chan, curie, NV40TCL_VB_ELEMENT_U32, 1);
- OUT_RING (chan, elts[0]);
- elts++; vc--;
- }
-
- while (vc) {
- unsigned i;
-
- push = MIN2(vc, 2047 * 2);
-
- BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
- for (i = 0; i < push; i+=2)
- OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
- vc -= push;
- elts += push;
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, 0);
-
- start = restart;
- }
-}
-
-static INLINE void
-nv40_draw_elements_u16(struct nv40_context *nv40, void *ib,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- while (count) {
- uint16_t *elts = (uint16_t *)ib + start;
- unsigned vc, push, restart;
-
- nv40_state_emit(nv40);
-
- vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
- mode, start, count, &restart);
- if (vc == 0) {
- FIRE_RING(chan);
- continue;
- }
- count -= vc;
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, nvgl_primitive(mode));
-
- if (vc & 1) {
- BEGIN_RING(chan, curie, NV40TCL_VB_ELEMENT_U32, 1);
- OUT_RING (chan, elts[0]);
- elts++; vc--;
- }
-
- while (vc) {
- unsigned i;
-
- push = MIN2(vc, 2047 * 2);
-
- BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U16, push >> 1);
- for (i = 0; i < push; i+=2)
- OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
-
- vc -= push;
- elts += push;
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, 0);
-
- start = restart;
- }
-}
-
-static INLINE void
-nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
-
- while (count) {
- uint32_t *elts = (uint32_t *)ib + start;
- unsigned vc, push, restart;
-
- nv40_state_emit(nv40);
-
- vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
- mode, start, count, &restart);
- if (vc == 0) {
- FIRE_RING(chan);
- continue;
- }
- count -= vc;
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, nvgl_primitive(mode));
-
- while (vc) {
- push = MIN2(vc, 2047);
-
- BEGIN_RING_NI(chan, curie, NV40TCL_VB_ELEMENT_U32, push);
- OUT_RINGp (chan, elts, push);
-
- vc -= push;
- elts += push;
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, 0);
-
- start = restart;
- }
-}
-
-static void
-nv40_draw_elements_inline(struct pipe_context *pipe,
- struct pipe_buffer *ib, unsigned ib_size,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
-
- map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
- if (!ib) {
- NOUVEAU_ERR("failed mapping ib\n");
- return;
- }
-
- switch (ib_size) {
- case 1:
- nv40_draw_elements_u08(nv40, map, mode, start, count);
- break;
- case 2:
- nv40_draw_elements_u16(nv40, map, mode, start, count);
- break;
- case 4:
- nv40_draw_elements_u32(nv40, map, mode, start, count);
- break;
- default:
- NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
- break;
- }
-
- pipe_buffer_unmap(pscreen, ib);
-}
-
-static void
-nv40_draw_elements_vbo(struct pipe_context *pipe,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- struct nv40_screen *screen = nv40->screen;
- struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- unsigned restart;
-
- while (count) {
- unsigned nr, vc;
-
- nv40_state_emit(nv40);
-
- vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
- mode, start, count, &restart);
- if (!vc) {
- FIRE_RING(chan);
- continue;
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, nvgl_primitive(mode));
-
- nr = (vc & 0xff);
- if (nr) {
- BEGIN_RING(chan, curie, NV40TCL_VB_INDEX_BATCH, 1);
- OUT_RING (chan, ((nr - 1) << 24) | start);
- start += nr;
- }
-
- nr = vc >> 8;
- while (nr) {
- unsigned push = nr > 2047 ? 2047 : nr;
-
- nr -= push;
-
- BEGIN_RING_NI(chan, curie, NV40TCL_VB_INDEX_BATCH, push);
- while (push--) {
- OUT_RING(chan, ((0x100 - 1) << 24) | start);
- start += 0x100;
- }
- }
-
- BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1);
- OUT_RING (chan, 0);
-
- count -= vc;
- start = restart;
- }
-}
-
-void
-nv40_draw_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer, unsigned indexSize,
- unsigned mode, unsigned start, unsigned count)
-{
- struct nv40_context *nv40 = nv40_context(pipe);
- boolean idxbuf;
-
- idxbuf = nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize);
- if (FORCE_SWTNL || !nv40_state_validate(nv40)) {
- nv40_draw_elements_swtnl(pipe, NULL, 0,
- mode, start, count);
- return;
- }
-
- if (idxbuf) {
- nv40_draw_elements_vbo(pipe, mode, start, count);
- } else {
- nv40_draw_elements_inline(pipe, indexBuffer, indexSize,
- mode, start, count);
- }
-
- pipe->flush(pipe, 0, NULL);
-}
-
-static boolean
-nv40_vbo_validate(struct nv40_context *nv40)
-{
- struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
- struct nouveau_grobj *curie = nv40->screen->curie;
- struct pipe_buffer *ib = nv40->idxbuf;
- unsigned ib_format = nv40->idxbuf_format;
- unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
- int hw;
-
- vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, curie, NV40TCL_VTXBUF_ADDRESS(0), nv40->vtxelt_nr);
- vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, curie, NV40TCL_VTXFMT(0), nv40->vtxelt_nr);
-
- for (hw = 0; hw < nv40->vtxelt_nr; hw++) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
- unsigned type, ncomp;
-
- ve = &nv40->vtxelt[hw];
- vb = &nv40->vtxbuf[ve->vertex_buffer_index];
-
- if (!vb->stride) {
- if (!sattr)
- sattr = so_new(16, 16 * 4, 0);
-
- if (nv40_vbo_static_attrib(nv40, sattr, hw, ve, vb)) {
- so_data(vtxbuf, 0);
- so_data(vtxfmt, NV40TCL_VTXFMT_TYPE_FLOAT);
- continue;
- }
- }
-
- if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
- nv40->fallback_swtnl |= NV40_NEW_ARRAYS;
- so_ref(NULL, &vtxbuf);
- so_ref(NULL, &vtxfmt);
- return FALSE;
- }
-
- so_reloc(vtxbuf, nouveau_bo(vb->buffer),
- vb->buffer_offset + ve->src_offset,
- vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- 0, NV40TCL_VTXBUF_ADDRESS_DMA1);
- so_data (vtxfmt, ((vb->stride << NV40TCL_VTXFMT_STRIDE_SHIFT) |
- (ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type));
- }
-
- if (ib) {
- struct nouveau_bo *bo = nouveau_bo(ib);
-
- so_method(vtxbuf, curie, NV40TCL_IDXBUF_ADDRESS, 2);
- so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
- 0, NV40TCL_IDXBUF_FORMAT_DMA1);
- }
-
- so_method(vtxbuf, curie, 0x1710, 1);
- so_data (vtxbuf, 0);
-
- so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]);
- so_ref(NULL, &vtxbuf);
- nv40->state.dirty |= (1ULL << NV40_STATE_VTXBUF);
- so_ref(vtxfmt, &nv40->state.hw[NV40_STATE_VTXFMT]);
- so_ref(NULL, &vtxfmt);
- nv40->state.dirty |= (1ULL << NV40_STATE_VTXFMT);
- so_ref(sattr, &nv40->state.hw[NV40_STATE_VTXATTR]);
- so_ref(NULL, &sattr);
- nv40->state.dirty |= (1ULL << NV40_STATE_VTXATTR);
- return FALSE;
-}
-
-struct nv40_state_entry nv40_state_vbo = {
- .validate = nv40_vbo_validate,
- .dirty = {
- .pipe = NV40_NEW_ARRAYS,
- .hw = 0,
- }
-};
-
diff --git a/src/gallium/drivers/nv50/Makefile b/src/gallium/drivers/nv50/Makefile
index 612aea28a34..5d622e1c13c 100644
--- a/src/gallium/drivers/nv50/Makefile
+++ b/src/gallium/drivers/nv50/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
nv50_surface.c \
nv50_tex.c \
nv50_transfer.c \
- nv50_vbo.c
+ nv50_vbo.c \
+ nv50_push.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index e0b2d2880b0..5447904e9ca 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -35,8 +35,11 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned mode = 0, i;
+ const unsigned dirty = nv50->dirty;
- if (!nv50_state_validate(nv50))
+ /* don't need NEW_BLEND, NV50TCL_COLOR_MASK doesn't affect CLEAR_BUFFERS */
+ nv50->dirty &= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
+ if (!nv50_state_validate(nv50, 64))
return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
@@ -64,5 +67,6 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
OUT_RING (chan, (i << 6) | 0x3c);
}
+ nv50->dirty = dirty;
}
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 7be12fcdef4..aa14e17872d 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -46,43 +46,13 @@ static void
nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ int i;
- if (nv50->state.fb)
- so_ref(NULL, &nv50->state.fb);
- if (nv50->state.blend)
- so_ref(NULL, &nv50->state.blend);
- if (nv50->state.blend_colour)
- so_ref(NULL, &nv50->state.blend_colour);
- if (nv50->state.zsa)
- so_ref(NULL, &nv50->state.zsa);
- if (nv50->state.rast)
- so_ref(NULL, &nv50->state.rast);
- if (nv50->state.stipple)
- so_ref(NULL, &nv50->state.stipple);
- if (nv50->state.scissor)
- so_ref(NULL, &nv50->state.scissor);
- if (nv50->state.viewport)
- so_ref(NULL, &nv50->state.viewport);
- if (nv50->state.tsc_upload)
- so_ref(NULL, &nv50->state.tsc_upload);
- if (nv50->state.tic_upload)
- so_ref(NULL, &nv50->state.tic_upload);
- if (nv50->state.vertprog)
- so_ref(NULL, &nv50->state.vertprog);
- if (nv50->state.fragprog)
- so_ref(NULL, &nv50->state.fragprog);
- if (nv50->state.geomprog)
- so_ref(NULL, &nv50->state.geomprog);
- if (nv50->state.fp_linkage)
- so_ref(NULL, &nv50->state.fp_linkage);
- if (nv50->state.gp_linkage)
- so_ref(NULL, &nv50->state.gp_linkage);
- if (nv50->state.vtxfmt)
- so_ref(NULL, &nv50->state.vtxfmt);
- if (nv50->state.vtxbuf)
- so_ref(NULL, &nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_ref(NULL, &nv50->state.vtxattr);
+ for (i = 0; i < 64; i++) {
+ if (!nv50->state.hw[i])
+ continue;
+ so_ref(NULL, &nv50->state.hw[i]);
+ }
draw_destroy(nv50->draw);
@@ -123,11 +93,11 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nv50->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
screen->base.channel->user_private = nv50;
- screen->base.channel->flush_notify = nv50_state_flush_notify;
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
+ nv50_init_transfer_functions(nv50);
nv50->draw = draw_create();
assert(nv50->draw);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index c540594b949..bc7831d9aca 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -72,6 +72,23 @@ struct nv50_sampler_stateobj {
unsigned tsc[8];
};
+struct nv50_sampler_view {
+ struct pipe_sampler_view pipe;
+ uint32_t tic[8];
+};
+
+struct nv50_vtxelt_stateobj {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+ uint32_t hw[16];
+};
+
+static INLINE struct nv50_sampler_view *
+nv50_sampler_view(struct pipe_sampler_view *view)
+{
+ return (struct nv50_sampler_view *)view;
+}
+
static INLINE unsigned
get_tile_height(uint32_t tile_mode)
{
@@ -90,10 +107,12 @@ struct nv50_miptree_level {
unsigned tile_mode;
};
+#define NV50_MAX_TEXTURE_LEVELS 16
+
struct nv50_miptree {
struct nouveau_miptree base;
- struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
+ struct nv50_miptree_level level[NV50_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};
@@ -115,30 +134,12 @@ nv50_surface(struct pipe_surface *pt)
}
struct nv50_state {
- unsigned dirty;
+ struct nouveau_stateobj *hw[64];
+ uint64_t hw_dirty;
- struct nouveau_stateobj *fb;
- struct nouveau_stateobj *blend;
- struct nouveau_stateobj *blend_colour;
- struct nouveau_stateobj *zsa;
- struct nouveau_stateobj *stencil_ref;
- struct nouveau_stateobj *rast;
- struct nouveau_stateobj *stipple;
- struct nouveau_stateobj *scissor;
- unsigned scissor_enabled;
- struct nouveau_stateobj *viewport;
- struct nouveau_stateobj *tsc_upload;
- struct nouveau_stateobj *tic_upload;
- unsigned miptree_nr[PIPE_SHADER_TYPES];
- struct nouveau_stateobj *vertprog;
- struct nouveau_stateobj *fragprog;
- struct nouveau_stateobj *geomprog;
- struct nouveau_stateobj *fp_linkage;
- struct nouveau_stateobj *gp_linkage;
- struct nouveau_stateobj *vtxfmt;
+ unsigned sampler_view_nr[3];
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
- struct nouveau_stateobj *instbuf;
unsigned vtxelt_nr;
};
@@ -167,14 +168,13 @@ struct nv50_context {
struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned vtxbuf_nr;
- struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
- unsigned vtxelt_nr;
- struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
- unsigned sampler_nr[PIPE_SHADER_TYPES];
- struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
- unsigned miptree_nr[PIPE_SHADER_TYPES];
+ struct nv50_vtxelt_stateobj *vtxelt;
+ struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
+ unsigned sampler_nr[3];
+ struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS];
+ unsigned sampler_view_nr[3];
- uint16_t vbo_fifo;
+ unsigned vbo_fifo;
};
static INLINE struct nv50_context *
@@ -186,6 +186,7 @@ nv50_context(struct pipe_context *pipe)
extern void nv50_init_surface_functions(struct nv50_context *nv50);
extern void nv50_init_state_functions(struct nv50_context *nv50);
extern void nv50_init_query_functions(struct nv50_context *nv50);
+extern void nv50_init_transfer_functions(struct nv50_context *nv50);
extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen);
@@ -216,24 +217,36 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned count,
unsigned startInstance,
unsigned instanceCount);
-extern void nv50_vbo_validate(struct nv50_context *nv50);
+extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
+extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
+
+/* nv50_push.c */
+extern void
+nv50_push_elements_instanced(struct pipe_context *, struct pipe_buffer *,
+ unsigned idxsize, unsigned mode, unsigned start,
+ unsigned count, unsigned i_start,
+ unsigned i_count);
/* nv50_clear.c */
extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
const float *rgba, double depth, unsigned stencil);
/* nv50_program.c */
-extern void nv50_vertprog_validate(struct nv50_context *nv50);
-extern void nv50_fragprog_validate(struct nv50_context *nv50);
-extern void nv50_geomprog_validate(struct nv50_context *nv50);
-extern void nv50_fp_linkage_validate(struct nv50_context *nv50);
-extern void nv50_gp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_vertprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fragprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_geomprog_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_fp_linkage_validate(struct nv50_context *nv50);
+extern struct nouveau_stateobj *
+nv50_gp_linkage_validate(struct nv50_context *nv50);
extern void nv50_program_destroy(struct nv50_context *nv50,
struct nv50_program *p);
/* nv50_state_validate.c */
-extern boolean nv50_state_validate(struct nv50_context *nv50);
-extern void nv50_state_flush_notify(struct nouveau_channel *chan);
+extern boolean nv50_state_validate(struct nv50_context *nv50, unsigned dwords);
extern void nv50_so_init_sifc(struct nv50_context *nv50,
struct nouveau_stateobj *so,
@@ -241,7 +254,9 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,
unsigned offset, unsigned size);
/* nv50_tex.c */
-extern void nv50_tex_validate(struct nv50_context *);
+extern boolean nv50_tex_construct(struct nv50_sampler_view *view);
+extern void nv50_tex_relocs(struct nv50_context *);
+extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *);
/* nv50_transfer.c */
extern void
@@ -255,4 +270,35 @@ nv50_upload_sifc(struct nv50_context *nv50,
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, void *priv);
+static INLINE unsigned
+nv50_prim(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
+ case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
+ case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
+ case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
+ case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
+ case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
+ case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
+ case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
+ case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
+ case PIPE_PRIM_LINES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
+ case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
+ case PIPE_PRIM_TRIANGLES_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
+ case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+ return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
+ default:
+ break;
+ }
+
+ NOUVEAU_ERR("invalid primitive type %d\n", mode);
+ return NV50TCL_VERTEX_BEGIN_POINTS;
+}
+
#endif
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 3f9d869d7a4..e091cae6024 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -104,7 +104,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
tile_flags = 0x7400;
break;
default:
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) &&
util_format_get_blocksizebits(pt->format) == 32)
tile_flags = 0x7a00;
else
@@ -255,9 +255,10 @@ void
nv50_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv50_miptree_create;
- pscreen->texture_blanket = nv50_miptree_blanket;
pscreen->texture_destroy = nv50_miptree_destroy;
pscreen->get_tex_surface = nv50_miptree_surface_new;
pscreen->tex_surface_destroy = nv50_miptree_surface_del;
+
+ nouveau_screen(pscreen)->texture_blanket = nv50_miptree_blanket;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 2372cbbef69..d7e06c93272 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -3762,7 +3762,7 @@ nv50_program_tx_prep(struct nv50_pc *pc)
p->cfg.in[n].hw = rid = aid;
i = p->cfg.in[n].id;
- if (p->info.input_semantic_name[n] ==
+ if (p->info.input_semantic_name[i] ==
TGSI_SEMANTIC_FACE) {
load_frontfacing(pc, &pc->attr[i * 4]);
continue;
@@ -4270,7 +4270,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
FREE(up);
}
-void
+struct nouveau_stateobj *
nv50_vertprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4286,6 +4286,9 @@ nv50_vertprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_VERTPROG))
+ return NULL;
+
so = so_new(5, 7, 2);
so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4301,11 +4304,10 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.high_temp);
so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.vertprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_fragprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4321,6 +4323,9 @@ nv50_fragprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_FRAGPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4337,11 +4342,10 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.regs[3]);
so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */
- so_ref(so, &nv50->state.fragprog);
- so_ref(NULL, &so);
+ return so;
}
-void
+struct nouveau_stateobj *
nv50_geomprog_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4357,6 +4361,9 @@ nv50_geomprog_validate(struct nv50_context *nv50)
nv50_program_validate_data(nv50, p);
nv50_program_validate_code(nv50, p);
+ if (!(nv50->dirty & NV50_NEW_GEOMPROG))
+ return NULL;
+
so = so_new(6, 7, 2);
so_method(so, tesla, NV50TCL_GP_ADDRESS_HIGH, 2);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
@@ -4373,8 +4380,7 @@ nv50_geomprog_validate(struct nv50_context *nv50)
so_data (so, p->cfg.vert_count);
so_method(so, tesla, NV50TCL_GP_START_ID, 1);
so_data (so, 0);
- so_ref(so, &nv50->state.geomprog);
- so_ref(NULL, &so);
+ return so;
}
static uint32_t
@@ -4454,7 +4460,7 @@ nv50_vec4_map(uint32_t *map32, int mid, uint8_t zval, uint32_t lin[4],
return mid;
}
-void
+struct nouveau_stateobj *
nv50_fp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4580,8 +4586,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_GP_ENABLE, 1);
so_data (so, (vp->type == PIPE_SHADER_GEOMETRY) ? 1 : 0);
- so_ref(so, &nv50->state.fp_linkage);
- so_ref(NULL, &so);
+ return so;
}
static int
@@ -4615,7 +4620,7 @@ construct_vp_gp_mapping(uint32_t *map32, int m,
return m;
}
-void
+struct nouveau_stateobj *
nv50_gp_linkage_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -4625,10 +4630,8 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
uint32_t map[16];
int m = 0;
- if (!gp) {
- so_ref(NULL, &nv50->state.gp_linkage);
- return;
- }
+ if (!gp)
+ return NULL;
memset(map, 0, sizeof(map));
m = construct_vp_gp_mapping(map, m, vp, gp);
@@ -4646,8 +4649,7 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), m);
so_datap (so, map, m);
- so_ref(so, &nv50->state.gp_linkage);
- so_ref(NULL, &so);
+ return so;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
new file mode 100644
index 00000000000..96a1f32d304
--- /dev/null
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -0,0 +1,326 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+
+#include "nouveau/nouveau_util.h"
+#include "nv50_context.h"
+
+struct push_context {
+ struct nv50_context *nv50;
+
+ unsigned vtx_size;
+
+ void *idxbuf;
+ unsigned idxsize;
+
+ float edgeflag;
+ int edgeflag_attr;
+
+ struct {
+ void *map;
+ unsigned stride;
+ unsigned divisor;
+ unsigned step;
+ void (*push)(struct nouveau_channel *, void *);
+ } attr[16];
+ unsigned attr_nr;
+};
+
+static void
+emit_b32_1(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b32_2(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+}
+
+static void
+emit_b32_3(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b32_4(struct nouveau_channel *chan, void *data)
+{
+ uint32_t *v = data;
+
+ OUT_RING(chan, v[0]);
+ OUT_RING(chan, v[1]);
+ OUT_RING(chan, v[2]);
+ OUT_RING(chan, v[3]);
+}
+
+static void
+emit_b16_1(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b16_3(struct nouveau_channel *chan, void *data)
+{
+ uint16_t *v = data;
+
+ OUT_RING(chan, (v[1] << 16) | v[0]);
+ OUT_RING(chan, v[2]);
+}
+
+static void
+emit_b08_1(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, v[0]);
+}
+
+static void
+emit_b08_3(struct nouveau_channel *chan, void *data)
+{
+ uint8_t *v = data;
+
+ OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
+}
+
+static INLINE void
+emit_vertex(struct push_context *ctx, unsigned n)
+{
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ int i;
+
+ if (ctx->edgeflag_attr < 16) {
+ float *edgeflag = ctx->attr[ctx->edgeflag_attr].map +
+ ctx->attr[ctx->edgeflag_attr].stride * n;
+
+ if (*edgeflag != ctx->edgeflag) {
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, *edgeflag ? 1 : 0);
+ ctx->edgeflag = *edgeflag;
+ }
+ }
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
+ for (i = 0; i < ctx->attr_nr; i++)
+ ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n);
+}
+
+static void
+emit_edgeflag(void *priv, boolean enabled)
+{
+ struct push_context *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+emit_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint8_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt16(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint16_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct push_context *ctx = priv;
+ uint32_t *idxbuf = ctx->idxbuf;
+
+ while (count--)
+ emit_vertex(ctx, idxbuf[start++]);
+}
+
+static void
+emit_verts(void *priv, unsigned start, unsigned count)
+{
+ while (count--)
+ emit_vertex(priv, start++);
+}
+
+void
+nv50_push_elements_instanced(struct pipe_context *pipe,
+ struct pipe_buffer *idxbuf, unsigned idxsize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned i_start, unsigned i_count)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ struct push_context ctx;
+ const unsigned p_overhead = 4 + /* begin/end */
+ 4; /* potential edgeflag enable/disable */
+ const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */
+ 2; /* potential edgeflag modification */
+ struct u_split_prim s;
+ unsigned vtx_size;
+ boolean nzi = FALSE;
+ int i;
+
+ ctx.nv50 = nv50;
+ ctx.attr_nr = 0;
+ ctx.idxbuf = NULL;
+ ctx.vtx_size = 0;
+ ctx.edgeflag = 0.5f;
+ ctx.edgeflag_attr = nv50->vertprog->cfg.edgeflag_in;
+
+ /* map vertex buffers, determine vertex size */
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index];
+ struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ unsigned size, nr_components, n;
+
+ if (!(nv50->vbo_fifo & (1 << i)))
+ continue;
+ n = ctx.attr_nr++;
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset;
+ nouveau_bo_unmap(bo);
+
+ ctx.attr[n].stride = vb->stride;
+ ctx.attr[n].divisor = ve->instance_divisor;
+ if (ctx.attr[n].divisor) {
+ ctx.attr[n].step = i_start % ve->instance_divisor;
+ ctx.attr[n].map += i_start * vb->stride;
+ }
+
+ size = util_format_get_component_bits(ve->src_format,
+ UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(ve->src_format);
+ switch (size) {
+ case 8:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b08_1; break;
+ case 2: ctx.attr[n].push = emit_b16_1; break;
+ case 3: ctx.attr[n].push = emit_b08_3; break;
+ case 4: ctx.attr[n].push = emit_b32_1; break;
+ }
+ ctx.vtx_size++;
+ break;
+ case 16:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b16_1; break;
+ case 2: ctx.attr[n].push = emit_b32_1; break;
+ case 3: ctx.attr[n].push = emit_b16_3; break;
+ case 4: ctx.attr[n].push = emit_b32_2; break;
+ }
+ ctx.vtx_size += (nr_components + 1) >> 1;
+ break;
+ case 32:
+ switch (nr_components) {
+ case 1: ctx.attr[n].push = emit_b32_1; break;
+ case 2: ctx.attr[n].push = emit_b32_2; break;
+ case 3: ctx.attr[n].push = emit_b32_3; break;
+ case 4: ctx.attr[n].push = emit_b32_4; break;
+ }
+ ctx.vtx_size += nr_components;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+ }
+ vtx_size = ctx.vtx_size + v_overhead;
+
+ /* map index buffer, if present */
+ if (idxbuf) {
+ struct nouveau_bo *bo = nouveau_bo(idxbuf);
+
+ if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) {
+ assert(bo->map);
+ return;
+ }
+ ctx.idxbuf = bo->map;
+ ctx.idxsize = idxsize;
+ nouveau_bo_unmap(bo);
+ }
+
+ s.priv = &ctx;
+ s.edge = emit_edgeflag;
+ if (idxbuf) {
+ if (idxsize == 1)
+ s.emit = emit_elt08;
+ else
+ if (idxsize == 2)
+ s.emit = emit_elt16;
+ else
+ s.emit = emit_elt32;
+ } else
+ s.emit = emit_verts;
+
+ /* per-instance loop */
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, i_start);
+ while (i_count--) {
+ unsigned max_verts;
+ boolean done;
+
+ for (i = 0; i < ctx.attr_nr; i++) {
+ if (!ctx.attr[i].divisor ||
+ ctx.attr[i].divisor != ++ctx.attr[i].step)
+ continue;
+ ctx.attr[i].step = 0;
+ ctx.attr[i].map += ctx.attr[i].stride;
+ }
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, p_overhead + (6 * vtx_size))) {
+ assert(0);
+ return;
+ }
+ }
+
+ max_verts = AVAIL_RING(chan);
+ max_verts -= p_overhead;
+ max_verts /= vtx_size;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
+
+ nzi = TRUE;
+ }
+}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index eed6031eafa..1a4606d9e25 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -95,6 +95,8 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
static int
nv50_screen_get_param(struct pipe_screen *pscreen, int param)
{
+ struct nv50_screen *screen = nv50_screen(pscreen);
+
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32;
@@ -107,7 +109,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_TWO_SIDED_STENCIL:
return 1;
case PIPE_CAP_GLSL:
- return 0;
+ return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
@@ -132,9 +134,9 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
case NOUVEAU_CAP_HW_VTXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case NOUVEAU_CAP_HW_IDXBUF:
- return 1;
+ return screen->force_push ? 0 : 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
@@ -188,8 +190,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->tic);
if (screen->tsc)
nouveau_bo_ref(NULL, &screen->tsc);
- if (screen->static_init)
- so_ref(NULL, &screen->static_init);
nouveau_notifier_free(&screen->sync);
nouveau_grobj_free(&screen->tesla);
@@ -202,26 +202,53 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
FREE(screen);
}
-static int
-nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
- unsigned usage)
+#define BGN_RELOC(ch, bo, gr, m, n, fl) \
+ OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0)
+
+void
+nv50_screen_relocs(struct nv50_screen *screen)
{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nv50_context *ctx = screen->cur_ctx;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *tesla = screen->tesla;
+ unsigned i;
+ const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
- if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX))
- return 0;
+ MARK_RING (chan, 28, 26);
- /* Our vtxbuf got mapped, it can no longer be considered part of current
- * state, remove it to avoid emitting reloc markers.
- */
- if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf,
- nouveau_bo(pb))) {
- so_ref(NULL, &ctx->state.vtxbuf);
- ctx->dirty |= NV50_NEW_ARRAYS;
- }
+ /* cause grobj autobind */
+ BEGIN_RING(chan, tesla, 0x0100, 1);
+ OUT_RING (chan, 0);
+
+ BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl);
+ OUT_RELOCh(chan, screen->tic, 0, rl);
+ OUT_RELOCl(chan, screen->tic, 0, rl);
+
+ BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl);
+ OUT_RELOCh(chan, screen->tsc, 0, rl);
+ OUT_RELOCl(chan, screen->tsc, 0, rl);
- return 0;
+ BGN_RELOC (chan, screen->constbuf_misc[0],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOC (chan, screen->constbuf_misc[0],
+ (NV50_CB_PMISC << 16) | 0x0200, rl, 0, 0);
+
+ BGN_RELOC (chan, screen->constbuf_misc[0],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOC (chan, screen->constbuf_misc[0],
+ (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0);
+
+ for (i = 0; i < 3; ++i) {
+ BGN_RELOC (chan, screen->constbuf_parm[i],
+ tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl);
+ OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOC (chan, screen->constbuf_parm[i],
+ ((NV50_CB_PVP + i) << 16) | 0x0800, rl, 0, 0);
+ }
}
struct pipe_screen *
@@ -230,10 +257,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
struct nouveau_channel *chan;
struct pipe_screen *pscreen;
- struct nouveau_stateobj *so;
unsigned chipset = dev->chipset;
unsigned tesla_class = 0;
int ret, i;
+ const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
if (!screen)
return NULL;
@@ -252,10 +279,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->get_paramf = nv50_screen_get_paramf;
pscreen->is_format_supported = nv50_screen_is_format_supported;
pscreen->context_create = nv50_create;
- screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map;
nv50_screen_init_miptree_functions(pscreen);
- nv50_transfer_init_screen_functions(pscreen);
/* DMA engine object */
ret = nouveau_grobj_alloc(chan, 0xbeef5039,
@@ -318,64 +343,58 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
}
/* Static M2MF init */
- so = so_new(1, 3, 0);
- so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
- so_data (so, screen->sync->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_emit(chan, so);
- so_ref (NULL, &so);
+ BEGIN_RING(chan, screen->m2mf,
+ NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
+ OUT_RING (chan, screen->sync->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
/* Static 2D init */
- so = so_new(4, 7, 0);
- so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
- so_data (so, screen->sync->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_data (so, chan->vram->handle);
- so_method(so, screen->eng2d, NV50_2D_OPERATION, 1);
- so_data (so, NV50_2D_OPERATION_SRCCOPY);
- so_method(so, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
- so_data (so, 0);
- so_method(so, screen->eng2d, 0x0888, 1);
- so_data (so, 1);
- so_emit(chan, so);
- so_ref(NULL, &so);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
+ OUT_RING (chan, screen->sync->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1);
+ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
+ BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, screen->eng2d, 0x0888, 1);
+ OUT_RING (chan, 1);
/* Static tesla init */
- so = so_new(47, 95, 24);
-
- so_method(so, screen->tesla, NV50TCL_COND_MODE, 1);
- so_data (so, NV50TCL_COND_MODE_ALWAYS);
- so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
- so_data (so, screen->sync->handle);
- so_method(so, screen->tesla, NV50TCL_DMA_ZETA, 11);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1);
+ OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1);
+ OUT_RING (chan, screen->sync->handle);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11);
for (i = 0; i < 11; i++)
- so_data(so, chan->vram->handle);
- so_method(so, screen->tesla, NV50TCL_DMA_COLOR(0),
- NV50TCL_DMA_COLOR__SIZE);
+ OUT_RING (chan, chan->vram->handle);
+ BEGIN_RING(chan, screen->tesla,
+ NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE);
for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++)
- so_data(so, chan->vram->handle);
- so_method(so, screen->tesla, NV50TCL_RT_CONTROL, 1);
- so_data (so, 1);
+ OUT_RING (chan, chan->vram->handle);
+
+ BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1);
+ OUT_RING (chan, 1);
/* activate all 32 lanes (threads) in a warp */
- so_method(so, screen->tesla, NV50TCL_WARP_HALVES, 1);
- so_data (so, 0x2);
- so_method(so, screen->tesla, 0x1400, 1);
- so_data (so, 0xf);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_WARP_HALVES, 1);
+ OUT_RING (chan, 2);
+ BEGIN_RING(chan, screen->tesla, 0x1400, 1);
+ OUT_RING (chan, 0xf);
/* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */
for (i = 0; i < 3; ++i) {
- so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
- so_data (so, 0x54);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1);
+ OUT_RING (chan, 0x54);
}
/* origin is top left (set to 1 for bottom left) */
- so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
- so_data (so, 0);
- so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
- so_data (so, 8);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
+ OUT_RING (chan, 8);
/* constant buffers for immediates and VP/FP parameters */
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4,
@@ -384,6 +403,14 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl);
+ OUT_RING (chan, (NV50_CB_PMISC << 16) | 0x0200);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl);
+ OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200);
for (i = 0; i < 3; i++) {
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4,
@@ -392,6 +419,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl);
+ OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0800);
}
if (nouveau_resource_init(&screen->immd_heap[0], 0, 128) ||
@@ -403,123 +434,69 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- /*
- // map constant buffers:
- // B = buffer ID (maybe more than 1 byte)
- // N = CB index used in shader instruction
- // P = program type (0 = VP, 2 = GP, 3 = FP)
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x000BBNP1);
- */
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PMISC << 16) | 0x00000200);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000001 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000021 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000031 | (NV50_CB_PMISC << 12));
-
- /* bind auxiliary constbuf to immediate data bo */
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_AUX << 16) | 0x00000200);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000201 | (NV50_CB_AUX << 12));
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000221 | (NV50_CB_AUX << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PVP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000101 | (NV50_CB_PVP << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PGP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000121 | (NV50_CB_PGP << 12));
-
- so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PFP << 16) | 0x00000800);
- so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
- so_data (so, 0x00000131 | (NV50_CB_PFP << 12));
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
&screen->tic);
if (ret) {
nv50_screen_destroy(pscreen);
return NULL;
}
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RING (chan, 3 * 32 - 1);
- so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
- so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, PIPE_SHADER_TYPES * 32 - 1);
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),
&screen->tsc);
if (ret) {
nv50_screen_destroy(pscreen);
return NULL;
}
-
- so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
- so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, 0x00000000); /* ignored if TSC_LINKED (0x1234) = 1 */
-
+ BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RING (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */
+
+ /* map constant buffers:
+ * B = buffer ID (maybe more than 1 byte)
+ * N = CB index used in shader instruction
+ * P = program type (0 = VP, 2 = GP, 3 = FP)
+ * SET_PROGRAM_CB = 0x000BBNP1
+ */
+ BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8);
+ /* bind immediate buffer */
+ OUT_RING (chan, 0x001 | (NV50_CB_PMISC << 12));
+ OUT_RING (chan, 0x021 | (NV50_CB_PMISC << 12));
+ OUT_RING (chan, 0x031 | (NV50_CB_PMISC << 12));
+ /* bind auxiliary constbuf to immediate data bo */
+ OUT_RING (chan, 0x201 | (NV50_CB_AUX << 12));
+ OUT_RING (chan, 0x221 | (NV50_CB_AUX << 12));
+ /* bind parameter buffers */
+ OUT_RING (chan, 0x101 | (NV50_CB_PVP << 12));
+ OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12));
+ OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12));
/* Vertex array limits - max them out */
for (i = 0; i < 16; i++) {
- so_method(so, screen->tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
- so_data (so, 0x000000ff);
- so_data (so, 0xffffffff);
+ BEGIN_RING(chan, screen->tesla,
+ NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2);
+ OUT_RING (chan, 0x000000ff);
+ OUT_RING (chan, 0xffffffff);
}
- so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
- so_data (so, fui(0.0));
- so_data (so, fui(1.0));
+ BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2);
+ OUT_RINGf (chan, 0.0f);
+ OUT_RINGf (chan, 1.0f);
/* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
- so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1);
- so_data (so, 1);
-
- /* activate first scissor rectangle */
- so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
- so_data (so, 1);
+ BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
+ OUT_RING (chan, 1);
- so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
- so_data (so, 1); /* default edgeflag to TRUE */
+ BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, 1); /* default edgeflag to TRUE */
- so_emit(chan, so);
- so_ref (so, &screen->static_init);
- so_ref (NULL, &so);
- nouveau_pushbuf_flush(chan, 0);
+ FIRE_RING (chan);
+ screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
return pscreen;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 2687b721277..15bd4eed399 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -27,7 +27,7 @@ struct nv50_screen {
struct nouveau_bo *tic;
struct nouveau_bo *tsc;
- struct nouveau_stateobj *static_init;
+ boolean force_push;
};
static INLINE struct nv50_screen *
@@ -36,6 +36,6 @@ nv50_screen(struct pipe_screen *screen)
return (struct nv50_screen *)screen;
}
-void nv50_transfer_init_screen_functions(struct pipe_screen *);
+extern void nv50_screen_relocs(struct nv50_screen *);
#endif
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 7d304907b65..c1628089285 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -238,6 +238,9 @@ nv50_sampler_state_create(struct pipe_context *pipe,
return (void *)sso;
}
+/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the
+ * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.)
+ */
static INLINE void
nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
unsigned nr, void **sampler)
@@ -253,13 +256,13 @@ nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,
static void
nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
{
- nv50_sampler_state_bind(pipe, PIPE_SHADER_VERTEX, nr, s);
+ nv50_sampler_state_bind(pipe, 0, nr, s);
}
static void
nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)
{
- nv50_sampler_state_bind(pipe, PIPE_SHADER_FRAGMENT, nr, s);
+ nv50_sampler_state_bind(pipe, 2, nr, s);
}
static void
@@ -269,40 +272,74 @@ nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
}
static INLINE void
-nv50_set_sampler_texture(struct pipe_context *pipe, unsigned type,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_sampler_views(struct pipe_context *pipe, unsigned p,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
struct nv50_context *nv50 = nv50_context(pipe);
unsigned i;
for (i = 0; i < nr; i++)
- pipe_texture_reference((void *)&nv50->miptree[type][i], pt[i]);
- for (i = nr; i < nv50->miptree_nr[type]; i++)
- pipe_texture_reference((void *)&nv50->miptree[type][i], NULL);
+ pipe_sampler_view_reference(&nv50->sampler_views[p][i],
+ views[i]);
+
+ for (i = nr; i < nv50->sampler_view_nr[p]; i++)
+ pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL);
- nv50->miptree_nr[type] = nr;
+ nv50->sampler_view_nr[p] = nr;
nv50->dirty |= NV50_NEW_TEXTURE;
}
static void
-nv50_set_vp_sampler_textures(struct pipe_context *pipe,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_vp_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
- nv50_set_sampler_texture(pipe, PIPE_SHADER_VERTEX, nr, pt);
+ nv50_set_sampler_views(pipe, 0, nr, views);
}
static void
-nv50_set_fp_sampler_textures(struct pipe_context *pipe,
- unsigned nr, struct pipe_texture **pt)
+nv50_set_fp_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
+{
+ nv50_set_sampler_views(pipe, 2, nr, views);
+}
+
+static void
+nv50_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(nv50_sampler_view(view));
+}
+
+static struct pipe_sampler_view *
+nv50_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
{
- nv50_set_sampler_texture(pipe, PIPE_SHADER_FRAGMENT, nr, pt);
+ struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view);
+
+ view->pipe = *templ;
+ view->pipe.reference.count = 1;
+ view->pipe.texture = NULL;
+ pipe_texture_reference(&view->pipe.texture, texture);
+ view->pipe.context = pipe;
+
+ if (!nv50_tex_construct(view)) {
+ nv50_sampler_view_destroy(pipe, &view->pipe);
+ return NULL;
+ }
+ return &view->pipe;
}
+
static void *
nv50_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
- struct nouveau_stateobj *so = so_new(15, 21, 0);
+ struct nouveau_stateobj *so = so_new(16, 22, 0);
struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
struct nv50_rasterizer_stateobj *rso =
CALLOC_STRUCT(nv50_rasterizer_stateobj);
@@ -314,6 +351,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
* - point_sprite / sprite_coord_mode
*/
+ so_method(so, tesla, NV50TCL_SCISSOR_ENABLE(0), 1);
+ so_data (so, cso->scissor);
+
so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
NV50TCL_SHADE_MODEL_SMOOTH);
@@ -720,15 +760,34 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
nv50->dirty |= NV50_NEW_ARRAYS;
}
+static void *
+nv50_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nv50_vtxelt_stateobj *cso = CALLOC_STRUCT(nv50_vtxelt_stateobj);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+ nv50_vtxelt_construct(cso);
+
+ return (void *)cso;
+}
+
static void
-nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
- const struct pipe_vertex_element *ve)
+nv50_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
{
- struct nv50_context *nv50 = nv50_context(pipe);
+ FREE(hwcso);
+}
- memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
- nv50->vtxelt_nr = count;
+static void
+nv50_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ nv50->vtxelt = hwcso;
nv50->dirty |= NV50_NEW_ARRAYS;
}
@@ -743,8 +802,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind;
nv50->pipe.bind_vertex_sampler_states = nv50_vp_sampler_state_bind;
- nv50->pipe.set_fragment_sampler_textures = nv50_set_fp_sampler_textures;
- nv50->pipe.set_vertex_sampler_textures = nv50_set_vp_sampler_textures;
+ nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views;
+ nv50->pipe.set_vertex_sampler_views = nv50_set_vp_sampler_views;
+ nv50->pipe.create_sampler_view = nv50_create_sampler_view;
+ nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;
nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
@@ -778,7 +839,10 @@ nv50_init_state_functions(struct nv50_context *nv50)
nv50->pipe.set_scissor_state = nv50_set_scissor_state;
nv50->pipe.set_viewport_state = nv50_set_viewport_state;
+ nv50->pipe.create_vertex_elements_state = nv50_vtxelts_state_create;
+ nv50->pipe.delete_vertex_elements_state = nv50_vtxelts_state_delete;
+ nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
+
nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
- nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index c974cc92dcc..b7e355283c8 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -25,8 +25,8 @@
#include "nv50_context.h"
#include "nouveau/nouveau_stateobj.h"
-static void
-nv50_state_validate_fb(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_fb(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so = so_new(32, 79, 18);
@@ -167,12 +167,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, w << 16);
so_data (so, h << 16);
- /* we set scissors to framebuffer size when they're 'turned off' */
- nv50->dirty |= NV50_NEW_SCISSOR;
- so_ref(NULL, &nv50->state.scissor);
-
- so_ref(so, &nv50->state.fb);
- so_ref(NULL, &so);
+ return so;
}
static void
@@ -199,263 +194,254 @@ nv50_validate_samplers(struct nv50_context *nv50, struct nouveau_stateobj *so,
}
}
-static void
-nv50_state_emit(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_blend(struct nv50_context *nv50)
{
- struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->blend->so, &so);
+ return so;
+}
- /* XXX: this is racy for multiple contexts active on separate
- * threads.
- */
- if (screen->cur_ctx != nv50) {
- if (nv50->state.fb)
- nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
- if (nv50->state.blend)
- nv50->state.dirty |= NV50_NEW_BLEND;
- if (nv50->state.zsa)
- nv50->state.dirty |= NV50_NEW_ZSA;
- if (nv50->state.vertprog)
- nv50->state.dirty |= NV50_NEW_VERTPROG;
- if (nv50->state.fragprog)
- nv50->state.dirty |= NV50_NEW_FRAGPROG;
- if (nv50->state.geomprog)
- nv50->state.dirty |= NV50_NEW_GEOMPROG;
- if (nv50->state.rast)
- nv50->state.dirty |= NV50_NEW_RASTERIZER;
- if (nv50->state.blend_colour)
- nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
- if (nv50->state.stencil_ref)
- nv50->state.dirty |= NV50_NEW_STENCIL_REF;
- if (nv50->state.stipple)
- nv50->state.dirty |= NV50_NEW_STIPPLE;
- if (nv50->state.scissor)
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- if (nv50->state.viewport)
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
- if (nv50->state.tsc_upload)
- nv50->state.dirty |= NV50_NEW_SAMPLER;
- if (nv50->state.tic_upload)
- nv50->state.dirty |= NV50_NEW_TEXTURE;
- if (nv50->state.vtxfmt && nv50->state.vtxbuf)
- nv50->state.dirty |= NV50_NEW_ARRAYS;
- screen->cur_ctx = nv50;
- }
+static struct nouveau_stateobj *
+validate_zsa(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->zsa->so, &so);
+ return so;
+}
- if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
- so_emit(chan, nv50->state.fb);
- if (nv50->state.dirty & NV50_NEW_BLEND)
- so_emit(chan, nv50->state.blend);
- if (nv50->state.dirty & NV50_NEW_ZSA)
- so_emit(chan, nv50->state.zsa);
- if (nv50->state.dirty & NV50_NEW_VERTPROG)
- so_emit(chan, nv50->state.vertprog);
- if (nv50->state.dirty & NV50_NEW_FRAGPROG)
- so_emit(chan, nv50->state.fragprog);
- if (nv50->state.dirty & NV50_NEW_GEOMPROG && nv50->state.geomprog)
- so_emit(chan, nv50->state.geomprog);
- if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- so_emit(chan, nv50->state.fp_linkage);
- if ((nv50->state.dirty & (NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG))
- && nv50->state.gp_linkage)
- so_emit(chan, nv50->state.gp_linkage);
- if (nv50->state.dirty & NV50_NEW_RASTERIZER)
- so_emit(chan, nv50->state.rast);
- if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
- so_emit(chan, nv50->state.blend_colour);
- if (nv50->state.dirty & NV50_NEW_STENCIL_REF)
- so_emit(chan, nv50->state.stencil_ref);
- if (nv50->state.dirty & NV50_NEW_STIPPLE)
- so_emit(chan, nv50->state.stipple);
- if (nv50->state.dirty & NV50_NEW_SCISSOR)
- so_emit(chan, nv50->state.scissor);
- if (nv50->state.dirty & NV50_NEW_VIEWPORT)
- so_emit(chan, nv50->state.viewport);
- if (nv50->state.dirty & NV50_NEW_SAMPLER)
- so_emit(chan, nv50->state.tsc_upload);
- if (nv50->state.dirty & NV50_NEW_TEXTURE)
- so_emit(chan, nv50->state.tic_upload);
- if (nv50->state.dirty & NV50_NEW_ARRAYS) {
- so_emit(chan, nv50->state.vtxfmt);
- so_emit(chan, nv50->state.vtxbuf);
- if (nv50->state.vtxattr)
- so_emit(chan, nv50->state.vtxattr);
- }
- nv50->state.dirty = 0;
+static struct nouveau_stateobj *
+validate_rast(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->rasterizer->so, &so);
+ return so;
+}
+
+static struct nouveau_stateobj *
+validate_blend_colour(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 4, 0);
+
+ so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
+ so_data (so, fui(nv50->blend_colour.color[0]));
+ so_data (so, fui(nv50->blend_colour.color[1]));
+ so_data (so, fui(nv50->blend_colour.color[2]));
+ so_data (so, fui(nv50->blend_colour.color[3]));
+ return so;
}
-void
-nv50_state_flush_notify(struct nouveau_channel *chan)
+static struct nouveau_stateobj *
+validate_stencil_ref(struct nv50_context *nv50)
{
- struct nv50_context *nv50 = chan->user_private;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so = so_new(2, 2, 0);
- if (nv50->state.tic_upload && !(nv50->dirty & NV50_NEW_TEXTURE))
- so_emit(chan, nv50->state.tic_upload);
+ so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[0]);
+ so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
+ so_data (so, nv50->stencil_ref.ref_value[1]);
+ return so;
+}
- so_emit_reloc_markers(chan, nv50->state.fb);
- so_emit_reloc_markers(chan, nv50->state.vertprog);
- so_emit_reloc_markers(chan, nv50->state.fragprog);
- so_emit_reloc_markers(chan, nv50->state.vtxbuf);
- so_emit_reloc_markers(chan, nv50->screen->static_init);
+static struct nouveau_stateobj *
+validate_stipple(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(1, 32, 0);
+ int i;
- if (nv50->state.instbuf)
- so_emit_reloc_markers(chan, nv50->state.instbuf);
+ so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
+ for (i = 0; i < 32; i++)
+ so_data(so, util_bswap32(nv50->stipple.stipple[i]));
+ return so;
}
-boolean
-nv50_state_validate(struct nv50_context *nv50)
+static struct nouveau_stateobj *
+validate_scissor(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct pipe_scissor_state *s = &nv50->scissor;
struct nouveau_stateobj *so;
- unsigned i;
-
- if (nv50->dirty & NV50_NEW_FRAMEBUFFER)
- nv50_state_validate_fb(nv50);
- if (nv50->dirty & NV50_NEW_BLEND)
- so_ref(nv50->blend->so, &nv50->state.blend);
+ so = so_new(1, 2, 0);
+ so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
+ so_data (so, (s->maxx << 16) | s->minx);
+ so_data (so, (s->maxy << 16) | s->miny);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_ZSA)
- so_ref(nv50->zsa->so, &nv50->state.zsa);
+static struct nouveau_stateobj *
+validate_viewport(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so = so_new(5, 9, 0);
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
+ so_data (so, fui(nv50->viewport.translate[0]));
+ so_data (so, fui(nv50->viewport.translate[1]));
+ so_data (so, fui(nv50->viewport.translate[2]));
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
+ so_data (so, fui(nv50->viewport.scale[0]));
+ so_data (so, fui(nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[2]));
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+ so_data (so, 1);
+ /* 0x0000 = remove whole primitive only (xyz)
+ * 0x1018 = remove whole primitive only (xy), clamp z
+ * 0x1080 = clip primitive (xyz)
+ * 0x1098 = clip primitive (xy), clamp z
+ */
+ so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+ so_data (so, 0x1080);
+ /* no idea what 0f90 does */
+ so_method(so, tesla, 0x0f90, 1);
+ so_data (so, 0);
- if (nv50->dirty & (NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB))
- nv50_vertprog_validate(nv50);
+ return so;
+}
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
- nv50_fragprog_validate(nv50);
+static struct nouveau_stateobj *
+validate_sampler(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_stateobj *so;
+ unsigned nr = 0, i;
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB))
- nv50_geomprog_validate(nv50);
+ for (i = 0; i < 3; ++i)
+ nr += nv50->sampler_nr[i];
- if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG |
- NV50_NEW_GEOMPROG | NV50_NEW_RASTERIZER))
- nv50_fp_linkage_validate(nv50);
+ so = so_new(1 + 5 * 3, 1 + 19 * 3 + nr * 8, 3 * 2);
- if (nv50->dirty & (NV50_NEW_GEOMPROG | NV50_NEW_VERTPROG))
- nv50_gp_linkage_validate(nv50);
+ nv50_validate_samplers(nv50, so, 0); /* VP */
+ nv50_validate_samplers(nv50, so, 2); /* FP */
- if (nv50->dirty & NV50_NEW_RASTERIZER)
- so_ref(nv50->rasterizer->so, &nv50->state.rast);
+ so_method(so, tesla, 0x1334, 1); /* flush TSC */
+ so_data (so, 0);
- if (nv50->dirty & NV50_NEW_BLEND_COLOUR) {
- so = so_new(1, 4, 0);
- so_method(so, tesla, NV50TCL_BLEND_COLOR(0), 4);
- so_data (so, fui(nv50->blend_colour.color[0]));
- so_data (so, fui(nv50->blend_colour.color[1]));
- so_data (so, fui(nv50->blend_colour.color[2]));
- so_data (so, fui(nv50->blend_colour.color[3]));
- so_ref(so, &nv50->state.blend_colour);
- so_ref(NULL, &so);
- }
+ return so;
+}
- if (nv50->dirty & NV50_NEW_STENCIL_REF) {
- so = so_new(2, 2, 0);
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[0]);
- so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1);
- so_data (so, nv50->stencil_ref.ref_value[1]);
- so_ref(so, &nv50->state.stencil_ref);
- so_ref(NULL, &so);
- }
+static struct nouveau_stateobj *
+validate_vtxbuf(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxbuf, &so);
+ return so;
+}
- if (nv50->dirty & NV50_NEW_STIPPLE) {
- so = so_new(1, 32, 0);
- so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32);
- for (i = 0; i < 32; i++)
- so_data(so, util_bswap32(nv50->stipple.stipple[i]));
- so_ref(so, &nv50->state.stipple);
- so_ref(NULL, &so);
- }
+static struct nouveau_stateobj *
+validate_vtxattr(struct nv50_context *nv50)
+{
+ struct nouveau_stateobj *so = NULL;
+ so_ref(nv50->state.vtxattr, &so);
+ return so;
+}
- if (nv50->dirty & (NV50_NEW_SCISSOR | NV50_NEW_RASTERIZER)) {
- struct pipe_rasterizer_state *rast = &nv50->rasterizer->pipe;
- struct pipe_scissor_state *s = &nv50->scissor;
+struct state_validate {
+ struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
+ unsigned states;
+} validate_list[] = {
+ { validate_fb , NV50_NEW_FRAMEBUFFER },
+ { validate_blend , NV50_NEW_BLEND },
+ { validate_zsa , NV50_NEW_ZSA },
+ { nv50_vertprog_validate , NV50_NEW_VERTPROG | NV50_NEW_VERTPROG_CB },
+ { nv50_fragprog_validate , NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB },
+ { nv50_geomprog_validate , NV50_NEW_GEOMPROG | NV50_NEW_GEOMPROG_CB },
+ { nv50_fp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG |
+ NV50_NEW_FRAGPROG | NV50_NEW_RASTERIZER },
+ { nv50_gp_linkage_validate, NV50_NEW_VERTPROG | NV50_NEW_GEOMPROG },
+ { validate_rast , NV50_NEW_RASTERIZER },
+ { validate_blend_colour , NV50_NEW_BLEND_COLOUR },
+ { validate_stencil_ref , NV50_NEW_STENCIL_REF },
+ { validate_stipple , NV50_NEW_STIPPLE },
+ { validate_scissor , NV50_NEW_SCISSOR },
+ { validate_viewport , NV50_NEW_VIEWPORT },
+ { validate_sampler , NV50_NEW_SAMPLER },
+ { nv50_tex_validate , NV50_NEW_TEXTURE | NV50_NEW_SAMPLER },
+ { nv50_vbo_validate , NV50_NEW_ARRAYS },
+ { validate_vtxbuf , NV50_NEW_ARRAYS },
+ { validate_vtxattr , NV50_NEW_ARRAYS },
+ {}
+};
+#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
- if (nv50->state.scissor &&
- (rast->scissor == 0 && nv50->state.scissor_enabled == 0))
- goto scissor_uptodate;
- nv50->state.scissor_enabled = rast->scissor;
+boolean
+nv50_state_validate(struct nv50_context *nv50, unsigned wait_dwords)
+{
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ unsigned nr_relocs = 128, nr_dwords = wait_dwords + 128 + 4;
+ int ret, i;
- so = so_new(1, 2, 0);
- so_method(so, tesla, NV50TCL_SCISSOR_HORIZ(0), 2);
- if (nv50->state.scissor_enabled) {
- so_data(so, (s->maxx << 16) | s->minx);
- so_data(so, (s->maxy << 16) | s->miny);
- } else {
- so_data(so, (nv50->framebuffer.width << 16));
- so_data(so, (nv50->framebuffer.height << 16));
- }
- so_ref(so, &nv50->state.scissor);
- so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_SCISSOR;
- }
-scissor_uptodate:
-
- if (nv50->dirty & (NV50_NEW_VIEWPORT | NV50_NEW_RASTERIZER)) {
- if (nv50->state.viewport &&
- !(nv50->dirty & NV50_NEW_VIEWPORT))
- goto viewport_uptodate;
-
- so = so_new(5, 9, 0);
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
- so_data (so, fui(nv50->viewport.translate[0]));
- so_data (so, fui(nv50->viewport.translate[1]));
- so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_SCALE_X(0), 3);
- so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(nv50->viewport.scale[1]));
- so_data (so, fui(nv50->viewport.scale[2]));
-
- so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
- so_data (so, 1);
- /* 0x0000 = remove whole primitive only (xyz)
- * 0x1018 = remove whole primitive only (xy), clamp z
- * 0x1080 = clip primitive (xyz)
- * 0x1098 = clip primitive (xy), clamp z
- */
- so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
- so_data (so, 0x1080);
- /* no idea what 0f90 does */
- so_method(so, tesla, 0x0f90, 1);
- so_data (so, 0);
+ for (i = 0; i < validate_list_len; i++) {
+ struct state_validate *validate = &validate_list[i];
+ struct nouveau_stateobj *so;
- so_ref(so, &nv50->state.viewport);
- so_ref(NULL, &so);
- nv50->state.dirty |= NV50_NEW_VIEWPORT;
- }
-viewport_uptodate:
+ if (!(nv50->dirty & validate->states))
+ continue;
- if (nv50->dirty & NV50_NEW_SAMPLER) {
- unsigned nr = 0;
+ so = validate->func(nv50);
+ if (!so)
+ continue;
- for (i = 0; i < PIPE_SHADER_TYPES; ++i)
- nr += nv50->sampler_nr[i];
+ nr_dwords += (so->total + so->cur);
+ nr_relocs += so->cur_reloc;
- so = so_new(1 + 5 * PIPE_SHADER_TYPES,
- 1 + 19 * PIPE_SHADER_TYPES + nr * 8,
- PIPE_SHADER_TYPES * 2);
+ so_ref(so, &nv50->state.hw[i]);
+ so_ref(NULL, &so);
+ nv50->state.hw_dirty |= (1 << i);
+ }
+ nv50->dirty = 0;
- nv50_validate_samplers(nv50, so, PIPE_SHADER_VERTEX);
- nv50_validate_samplers(nv50, so, PIPE_SHADER_FRAGMENT);
+ if (nv50->screen->cur_ctx != nv50) {
+ for (i = 0; i < validate_list_len; i++) {
+ if (!nv50->state.hw[i] ||
+ (nv50->state.hw_dirty & (1 << i)))
+ continue;
- so_method(so, tesla, 0x1334, 1); /* flush TSC */
- so_data (so, 0);
+ nr_dwords += (nv50->state.hw[i]->total +
+ nv50->state.hw[i]->cur);
+ nr_relocs += nv50->state.hw[i]->cur_reloc;
+ nv50->state.hw_dirty |= (1 << i);
+ }
- so_ref(so, &nv50->state.tsc_upload);
- so_ref(NULL, &so);
+ nv50->screen->cur_ctx = nv50;
}
- if (nv50->dirty & (NV50_NEW_TEXTURE | NV50_NEW_SAMPLER))
- nv50_tex_validate(nv50);
+ ret = MARK_RING(chan, nr_dwords, nr_relocs);
+ if (ret) {
+ debug_printf("MARK_RING(%d, %d) failed: %d\n",
+ nr_dwords, nr_relocs, ret);
+ return FALSE;
+ }
- if (nv50->dirty & NV50_NEW_ARRAYS)
- nv50_vbo_validate(nv50);
+ while (nv50->state.hw_dirty) {
+ i = ffs(nv50->state.hw_dirty) - 1;
+ nv50->state.hw_dirty &= ~(1 << i);
- nv50->state.dirty |= nv50->dirty;
- nv50->dirty = 0;
- nv50_state_emit(nv50);
+ so_emit(chan, nv50->state.hw[i]);
+ }
+ /* Yes, really, we need to do this. If a buffer that is referenced
+ * on the hardware isn't part of changed state above, without doing
+ * this the kernel is given no clue that the buffer is being used
+ * still. This can cause all sorts of fun issues.
+ */
+ nv50_tex_relocs(nv50);
+ so_emit_reloc_markers(chan, nv50->state.hw[0]); /* fb */
+ so_emit_reloc_markers(chan, nv50->state.hw[3]); /* vp */
+ so_emit_reloc_markers(chan, nv50->state.hw[4]); /* fp */
+ so_emit_reloc_markers(chan, nv50->state.hw[17]); /* vb */
+ nv50_screen_relocs(nv50->screen);
+
+ /* No idea.. */
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, tesla, 0x142c, 1);
+ OUT_RING (chan, 0);
return TRUE;
}
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index cabd148bc5b..6467c48a32a 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -28,6 +28,7 @@
#include "util/u_inlines.h"
#include "util/u_tile.h"
+#include "util/u_format.h"
static INLINE int
nv50_format(enum pipe_format format)
@@ -37,10 +38,35 @@ nv50_format(enum pipe_format format)
return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
case PIPE_FORMAT_B8G8R8X8_UNORM:
return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return NV50_2D_DST_FORMAT_A8R8G8B8_SRGB;
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ return NV50_2D_DST_FORMAT_X8R8G8B8_SRGB;
case PIPE_FORMAT_B5G6R5_UNORM:
return NV50_2D_DST_FORMAT_R5G6B5_UNORM;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return NV50_2D_DST_FORMAT_A1R5G5B5_UNORM;
case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
return NV50_2D_DST_FORMAT_R8_UNORM;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT;
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT;
+ case PIPE_FORMAT_Z32_FLOAT:
+ return NV50_2D_DST_FORMAT_R32_FLOAT;
+
+ /* only because we require src format == dst format: */
+ case PIPE_FORMAT_R16G16_SNORM:
+ case PIPE_FORMAT_R16G16_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return NV50_2D_DST_FORMAT_R16_UNORM;
+
default:
return -1;
}
@@ -57,8 +83,11 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
format = nv50_format(ps->format);
- if (format < 0)
+ if (format < 0) {
+ NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+ util_format_name(ps->format));
return 1;
+ }
if (!bo->tile_flags) {
MARK_RING (chan, 9, 2); /* flush on lack of space or relocs */
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index de0560e20cd..85ab947c006 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -24,30 +24,21 @@
#include "nv50_texture.h"
#include "nouveau/nouveau_stateobj.h"
+#include "nouveau/nouveau_reloc.h"
#include "util/u_format.h"
#define _MIXED(pf, t0, t1, t2, t3, cr, cg, cb, ca, f) \
-{ \
- PIPE_FORMAT_##pf, \
+[PIPE_FORMAT_##pf] = ( \
NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 | \
NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 | \
NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 | \
NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 | \
- NV50TIC_0_0_FMT_##f \
-}
+ NV50TIC_0_0_FMT_##f)
#define _(pf, t, cr, cg, cb, ca, f) _MIXED(pf, t, t, t, t, cr, cg, cb, ca, f)
-struct nv50_texture_format {
- enum pipe_format pf;
- uint32_t hw;
-};
-
-#define NV50_TEX_FORMAT_LIST_SIZE \
- (sizeof(nv50_tex_format_list) / sizeof(struct nv50_texture_format))
-
-static const struct nv50_texture_format nv50_tex_format_list[] =
+static const uint32_t nv50_texture_formats[PIPE_FORMAT_COUNT] =
{
_(B8G8R8A8_UNORM, UNORM, C2, C1, C0, C3, 8_8_8_8),
_(B8G8R8A8_SRGB, UNORM, C2, C1, C0, C3, 8_8_8_8),
@@ -59,10 +50,12 @@ static const struct nv50_texture_format nv50_tex_format_list[] =
_(B5G6R5_UNORM, UNORM, C2, C1, C0, ONE, 5_6_5),
_(L8_UNORM, UNORM, C0, C0, C0, ONE, 8),
+ _(L8_SRGB, UNORM, C0, C0, C0, ONE, 8),
_(A8_UNORM, UNORM, ZERO, ZERO, ZERO, C0, 8),
_(I8_UNORM, UNORM, C0, C0, C0, C0, 8),
_(L8A8_UNORM, UNORM, C0, C0, C0, C1, 8_8),
+ _(L8A8_SRGB, UNORM, C0, C0, C0, C1, 8_8),
_(DXT1_RGB, UNORM, C0, C1, C2, ONE, DXT1),
_(DXT1_RGBA, UNORM, C0, C1, C2, C3, DXT1),
@@ -80,149 +73,207 @@ static const struct nv50_texture_format nv50_tex_format_list[] =
_(R16G16_UNORM, UNORM, C0, C1, ZERO, ONE, 16_16),
_MIXED(Z32_FLOAT, FLOAT, UINT, UINT, UINT, C0, C0, C0, ONE, 32_DEPTH)
-
};
#undef _
#undef _MIXED
-static int
-nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
- struct nv50_miptree *mt, int unit, unsigned p)
+static INLINE uint32_t
+nv50_tic_swizzle(uint32_t tc, unsigned swz)
+{
+ switch (swz) {
+ case PIPE_SWIZZLE_RED:
+ return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT;
+ case PIPE_SWIZZLE_GREEN:
+ return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT;
+ case PIPE_SWIZZLE_BLUE:
+ return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT;
+ case PIPE_SWIZZLE_ALPHA:
+ return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT;
+ case PIPE_SWIZZLE_ONE:
+ return 7;
+ case PIPE_SWIZZLE_ZERO:
+ default:
+ return 0;
+ }
+}
+
+boolean
+nv50_tex_construct(struct nv50_sampler_view *view)
{
- unsigned i;
- uint32_t mode;
const struct util_format_description *desc;
+ struct nv50_miptree *mt = nv50_miptree(view->pipe.texture);
+ uint32_t swz[4], *tic = view->tic;
- for (i = 0; i < NV50_TEX_FORMAT_LIST_SIZE; i++)
- if (nv50_tex_format_list[i].pf == mt->base.base.format)
- break;
- if (i == NV50_TEX_FORMAT_LIST_SIZE)
- return 1;
-
- if (nv50->sampler[p][unit]->normalized)
- mode = 0x50001000 | (1 << 31);
- else {
- mode = 0x50001000 | (7 << 14);
- assert(mt->base.base.target == PIPE_TEXTURE_2D);
- }
+ tic[0] = nv50_texture_formats[view->pipe.format];
- mode |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
- ((mt->base.bo->tile_mode & 0xf0) << 21);
+ swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r);
+ swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g);
+ swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b);
+ swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a);
+ view->tic[0] = (tic[0] & ~NV50TIC_0_0_SWIZZLE_MASK) |
+ (swz[0] << NV50TIC_0_0_MAPR_SHIFT) |
+ (swz[1] << NV50TIC_0_0_MAPG_SHIFT) |
+ (swz[2] << NV50TIC_0_0_MAPB_SHIFT) |
+ (swz[3] << NV50TIC_0_0_MAPA_SHIFT);
- desc = util_format_description(mt->base.base.format);
- assert(desc);
+ tic[2] = 0x50001000;
+ tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) |
+ ((mt->base.bo->tile_mode & 0xf0) << 21);
+ desc = util_format_description(mt->base.base.format);
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
- mode |= 0x0400;
+ tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB;
switch (mt->base.base.target) {
case PIPE_TEXTURE_1D:
+ tic[2] |= NV50TIC_0_2_TARGET_1D;
break;
case PIPE_TEXTURE_2D:
- mode |= (1 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_2D;
break;
case PIPE_TEXTURE_3D:
- mode |= (2 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_3D;
break;
case PIPE_TEXTURE_CUBE:
- mode |= (3 << 14);
+ tic[2] |= NV50TIC_0_2_TARGET_CUBE;
break;
default:
- assert(!"unsupported texture target");
- break;
+ NOUVEAU_ERR("invalid texture target: %d\n",
+ mt->base.base.target);
+ return FALSE;
}
- so_data (so, nv50_tex_format_list[i].hw);
- so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
- NOUVEAU_BO_RD, 0, 0);
- so_data (so, mode);
- so_data (so, 0x00300000);
- so_data (so, mt->base.base.width0 | (1 << 31));
- so_data (so, (mt->base.base.last_level << 28) |
- (mt->base.base.depth0 << 16) | mt->base.base.height0);
- so_data (so, 0x03000000);
- so_data (so, mt->base.base.last_level << 4);
-
- return 0;
-}
+ tic[3] = 0x00300000;
+
+ tic[4] = (1 << 31) | mt->base.base.width0;
+ tic[5] = (mt->base.base.last_level << 28) |
+ (mt->base.base.depth0 << 16) | mt->base.base.height0;
-#ifndef NV50TCL_BIND_TIC
-#define NV50TCL_BIND_TIC(n) (0x1448 + 8 * n)
-#endif
+ tic[6] = 0x03000000;
-static boolean
+ tic[7] = (view->pipe.last_level << 4) | view->pipe.first_level;
+
+ return TRUE;
+}
+
+static int
nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,
unsigned p)
{
- static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 };
-
struct nouveau_grobj *eng2d = nv50->screen->eng2d;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned unit, j, p_hw = p_remap[p];
+ unsigned unit, j;
+
+ const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW;
+ const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH
+ | NOUVEAU_BO_OR;
nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM,
- p * (32 * 8 * 4), nv50->miptree_nr[p] * 8 * 4);
+ p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4);
- for (unit = 0; unit < nv50->miptree_nr[p]; ++unit) {
- struct nv50_miptree *mt = nv50->miptree[p][unit];
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) {
+ struct nv50_sampler_view *view =
+ nv50_sampler_view(nv50->sampler_views[p][unit]);
so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8);
- if (mt) {
- if (nv50_tex_construct(nv50, so, mt, unit, p))
- return FALSE;
+ if (view) {
+ uint32_t tic2 = view->tic[2];
+ struct nv50_miptree *mt =
+ nv50_miptree(view->pipe.texture);
+
+ if (nv50->sampler[p][unit]->normalized)
+ tic2 |= NV50TIC_0_2_NORMALIZED_COORDS;
+
+ so_data (so, view->tic[0]);
+ so_reloc (so, mt->base.bo, 0, rll, 0, 0);
+ so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2);
+ so_datap (so, &view->tic[3], 5);
+
/* Set TEX insn $t src binding $unit in program type p
* to TIC, TSC entry (32 * p + unit), mark valid (1).
*/
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, ((32 * p + unit) << 9) | (unit << 1) | 1);
} else {
for (j = 0; j < 8; ++j)
so_data(so, 0);
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, (unit << 1) | 0);
}
}
- for (; unit < nv50->state.miptree_nr[p]; unit++) {
+ for (; unit < nv50->state.sampler_view_nr[p]; unit++) {
/* Make other bindings invalid. */
- so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1);
+ so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);
so_data (so, (unit << 1) | 0);
}
- nv50->state.miptree_nr[p] = nv50->miptree_nr[p];
+ nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p];
return TRUE;
}
void
+nv50_tex_relocs(struct nv50_context *nv50)
+{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
+ int p, unit;
+
+ p = PIPE_SHADER_FRAGMENT;
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) {
+ struct pipe_sampler_view *view = nv50->sampler_views[p][unit];
+ if (!view)
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50_miptree(view->texture)->base.bo, 0, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_RD, 0, 0);
+ }
+
+ p = PIPE_SHADER_VERTEX;
+ for (unit = 0; unit < nv50->sampler_view_nr[p]; unit++) {
+ struct pipe_sampler_view *view = nv50->sampler_views[p][unit];
+ if (!view)
+ continue;
+ nouveau_reloc_emit(chan, nv50->screen->tic,
+ ((p * 32) + unit) * 32, NULL,
+ nv50_miptree(view->texture)->base.bo, 0, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_RD, 0, 0);
+ }
+}
+
+struct nouveau_stateobj *
nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_stateobj *so;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned p, start, push, nrlc;
-
- for (nrlc = 0, start = 0, push = 0, p = 0; p < PIPE_SHADER_TYPES; ++p) {
- start += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
- push += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]);
- nrlc += nv50->miptree_nr[p];
+ unsigned p, m = 0, d = 0, r = 0;
+
+ for (p = 0; p < 3; ++p) {
+ unsigned nr = MAX2(nv50->sampler_view_nr[p],
+ nv50->state.sampler_view_nr[p]);
+ m += nr;
+ d += nr;
+ r += nv50->sampler_view_nr[p];
}
- start = start * 2 + 4 * PIPE_SHADER_TYPES + 2;
- push = push * 9 + 19 * PIPE_SHADER_TYPES + 2;
- nrlc = nrlc * 2 + 2 * PIPE_SHADER_TYPES;
+ m = m * 2 + 3 * 4 + 1;
+ d = d * 9 + 3 * 19 + 1;
+ r = r * 2 + 3 * 2;
- so = so_new(start, push, nrlc);
+ so = so_new(m, d, r);
- if (nv50_validate_textures(nv50, so, PIPE_SHADER_VERTEX) == FALSE ||
- nv50_validate_textures(nv50, so, PIPE_SHADER_FRAGMENT) == FALSE) {
+ if (nv50_validate_textures(nv50, so, 0) == FALSE ||
+ nv50_validate_textures(nv50, so, 2) == FALSE) {
so_ref(NULL, &so);
NOUVEAU_ERR("failed tex validate\n");
- return;
+ return NULL;
}
so_method(so, tesla, 0x1330, 1); /* flush TIC */
so_data (so, 0);
- so_ref(so, &nv50->state.tic_upload);
- so_ref(NULL, &so);
+ return so;
}
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index b870302019a..3475d3e4326 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -7,7 +7,9 @@
*/
/* Texture image control block */
+#define NV50TIC_0_0_SWIZZLE_MASK 0x3ffc0000
#define NV50TIC_0_0_MAPA_MASK 0x38000000
+#define NV50TIC_0_0_MAPA_SHIFT 27
#define NV50TIC_0_0_MAPA_ZERO 0x00000000
#define NV50TIC_0_0_MAPA_C0 0x10000000
#define NV50TIC_0_0_MAPA_C1 0x18000000
@@ -15,6 +17,7 @@
#define NV50TIC_0_0_MAPA_C3 0x28000000
#define NV50TIC_0_0_MAPA_ONE 0x38000000
#define NV50TIC_0_0_MAPB_MASK 0x07000000
+#define NV50TIC_0_0_MAPB_SHIFT 24
#define NV50TIC_0_0_MAPB_ZERO 0x00000000
#define NV50TIC_0_0_MAPB_C0 0x02000000
#define NV50TIC_0_0_MAPB_C1 0x03000000
@@ -22,6 +25,7 @@
#define NV50TIC_0_0_MAPB_C3 0x05000000
#define NV50TIC_0_0_MAPB_ONE 0x07000000
#define NV50TIC_0_0_MAPG_MASK 0x00e00000
+#define NV50TIC_0_0_MAPG_SHIFT 21
#define NV50TIC_0_0_MAPG_ZERO 0x00000000
#define NV50TIC_0_0_MAPG_C0 0x00400000
#define NV50TIC_0_0_MAPG_C1 0x00600000
@@ -29,6 +33,7 @@
#define NV50TIC_0_0_MAPG_C3 0x00a00000
#define NV50TIC_0_0_MAPG_ONE 0x00e00000
#define NV50TIC_0_0_MAPR_MASK 0x001c0000
+#define NV50TIC_0_0_MAPR_SHIFT 18
#define NV50TIC_0_0_MAPR_ZERO 0x00000000
#define NV50TIC_0_0_MAPR_C0 0x00080000
#define NV50TIC_0_0_MAPR_C1 0x000c0000
@@ -89,22 +94,39 @@
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
-#define NV50TIC_0_2_UNKNOWN_MASK 0xffffffff
+#define NV50TIC_0_2_COLORSPACE_SRGB 0x00000400
+#define NV50TIC_0_2_TARGET_1D 0x00000000
+#define NV50TIC_0_2_TARGET_2D 0x00004000
+#define NV50TIC_0_2_TARGET_3D 0x00008000
+#define NV50TIC_0_2_TARGET_CUBE 0x0000c000
+#define NV50TIC_0_2_TARGET_1D_ARRAY 0x00010000
+#define NV50TIC_0_2_TARGET_2D_ARRAY 0x00014000
+#define NV50TIC_0_2_TARGET_BUFFER 0x00018000
+#define NV50TIC_0_2_TARGET_RECT 0x0001c000
+/* #define NV50TIC_0_0_TILE_MODE_LINEAR 0x00040000 */
+#define NV50TIC_0_2_TILE_MODE_Y_MASK 0x01c00000
+#define NV50TIC_0_2_TILE_MODE_Y_SHIFT 22
+#define NV50TIC_0_2_TILE_MODE_Z_MASK 0x0e000000
+#define NV50TIC_0_2_TILE_MODE_Z_SHIFT 25
+#define NV50TIC_0_2_NORMALIZED_COORDS 0x80000000
#define NV50TIC_0_3_UNKNOWN_MASK 0xffffffff
#define NV50TIC_0_4_WIDTH_MASK 0x0000ffff
#define NV50TIC_0_4_WIDTH_SHIFT 0
-#define NV50TIC_0_5_DEPTH_MASK 0xffff0000
+#define NV50TIC_0_5_LAST_LEVEL_MASK 0xf0000000
+#define NV50TIC_0_5_LAST_LEVEL_SHIFT 28
+#define NV50TIC_0_5_DEPTH_MASK 0x0fff0000
#define NV50TIC_0_5_DEPTH_SHIFT 16
#define NV50TIC_0_5_HEIGHT_MASK 0x0000ffff
#define NV50TIC_0_5_HEIGHT_SHIFT 0
-
#define NV50TIC_0_6_UNKNOWN_MASK 0xffffffff
-#define NV50TIC_0_7_OFFSET_HIGH_MASK 0xffffffff
-#define NV50TIC_0_7_OFFSET_HIGH_SHIFT 0
+#define NV50TIC_0_7_BASE_LEVEL_MASK 0x0000000f
+#define NV50TIC_0_7_BASE_LEVEL_SHIFT 0
+#define NV50TIC_0_7_MAX_LEVEL_MASK 0x000000f0
+#define NV50TIC_0_7_MAX_LEVEL_SHIFT 4
/* Texture sampler control block */
#define NV50TSC_1_0_WRAPS_MASK 0x00000007
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index 7c360e9e73a..9eb223eca65 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -121,11 +121,12 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
}
static struct pipe_transfer *
-nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nv50_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
+ struct pipe_screen *pscreen = pcontext->screen;
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = nv50_miptree(pt);
struct nv50_miptree_level *lvl = &mt->level[level];
@@ -186,7 +187,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
static void
-nv50_transfer_del(struct pipe_transfer *ptx)
+nv50_transfer_del(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
struct nv50_miptree *mt = nv50_miptree(ptx->texture);
@@ -196,7 +197,7 @@ nv50_transfer_del(struct pipe_transfer *ptx)
unsigned ny = util_format_get_nblocksy(pt->format, tx->base.height);
if (ptx->usage & PIPE_TRANSFER_WRITE) {
- struct pipe_screen *pscreen = pt->screen;
+ struct pipe_screen *pscreen = pcontext->screen;
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0,
tx->base.stride, tx->bo->tile_mode,
@@ -218,7 +219,7 @@ nv50_transfer_del(struct pipe_transfer *ptx)
}
static void *
-nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv50_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
unsigned flags = 0;
@@ -236,7 +237,7 @@ nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
static void
-nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nv50_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
@@ -244,12 +245,12 @@ nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
void
-nv50_transfer_init_screen_functions(struct pipe_screen *pscreen)
+nv50_init_transfer_functions(struct nv50_context *nv50)
{
- pscreen->get_tex_transfer = nv50_transfer_new;
- pscreen->tex_transfer_destroy = nv50_transfer_del;
- pscreen->transfer_map = nv50_transfer_map;
- pscreen->transfer_unmap = nv50_transfer_unmap;
+ nv50->pipe.get_tex_transfer = nv50_transfer_new;
+ nv50->pipe.tex_transfer_destroy = nv50_transfer_del;
+ nv50->pipe.transfer_map = nv50_transfer_map;
+ nv50->pipe.transfer_unmap = nv50_transfer_unmap;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 1c8ee0b9adf..50472868063 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -25,53 +25,9 @@
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "nouveau/nouveau_util.h"
#include "nv50_context.h"
-static boolean
-nv50_push_elements_u08(struct nv50_context *, uint8_t *, unsigned);
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *, uint16_t *, unsigned);
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *, uint32_t *, unsigned);
-
-static boolean
-nv50_push_arrays(struct nv50_context *, unsigned, unsigned);
-
-#define NV50_USING_LOATHED_EDGEFLAG(ctx) ((ctx)->vertprog->cfg.edgeflag_in < 16)
-
-static INLINE unsigned
-nv50_prim(unsigned mode)
-{
- switch (mode) {
- case PIPE_PRIM_POINTS: return NV50TCL_VERTEX_BEGIN_POINTS;
- case PIPE_PRIM_LINES: return NV50TCL_VERTEX_BEGIN_LINES;
- case PIPE_PRIM_LINE_LOOP: return NV50TCL_VERTEX_BEGIN_LINE_LOOP;
- case PIPE_PRIM_LINE_STRIP: return NV50TCL_VERTEX_BEGIN_LINE_STRIP;
- case PIPE_PRIM_TRIANGLES: return NV50TCL_VERTEX_BEGIN_TRIANGLES;
- case PIPE_PRIM_TRIANGLE_STRIP:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP;
- case PIPE_PRIM_TRIANGLE_FAN: return NV50TCL_VERTEX_BEGIN_TRIANGLE_FAN;
- case PIPE_PRIM_QUADS: return NV50TCL_VERTEX_BEGIN_QUADS;
- case PIPE_PRIM_QUAD_STRIP: return NV50TCL_VERTEX_BEGIN_QUAD_STRIP;
- case PIPE_PRIM_POLYGON: return NV50TCL_VERTEX_BEGIN_POLYGON;
- case PIPE_PRIM_LINES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINES_ADJACENCY;
- case PIPE_PRIM_LINE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_LINE_STRIP_ADJACENCY;
- case PIPE_PRIM_TRIANGLES_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLES_ADJACENCY;
- case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
- return NV50TCL_VERTEX_BEGIN_TRIANGLE_STRIP_ADJACENCY;
- default:
- break;
- }
-
- NOUVEAU_ERR("invalid primitive type %d\n", mode);
- return NV50TCL_VERTEX_BEGIN_POINTS;
-}
-
static INLINE uint32_t
nv50_vbo_type_to_hw(enum pipe_format format)
{
@@ -139,15 +95,16 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
uint32_t hw_type, hw_size;
enum pipe_format pf = ve->src_format;
const struct util_format_description *desc;
- unsigned size;
+ unsigned size, nr_components;
desc = util_format_description(pf);
assert(desc);
size = util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0);
+ nr_components = util_format_get_nr_components(pf);
hw_type = nv50_vbo_type_to_hw(pf);
- hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
+ hw_size = nv50_vbo_size_to_hw(size, nr_components);
if (!hw_type || !hw_size) {
NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf));
@@ -161,250 +118,58 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
return (hw_type | hw_size);
}
-/* For instanced drawing from user buffers, hitting the FIFO repeatedly
- * with the same vertex data is probably worse than uploading all data.
- */
-static boolean
-nv50_upload_vtxbuf(struct nv50_context *nv50, unsigned i)
-{
- struct nv50_screen *nscreen = nv50->screen;
- struct pipe_screen *pscreen = &nscreen->base.base;
- struct pipe_buffer *buf = nscreen->strm_vbuf[i];
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- uint8_t *src;
- unsigned size = align(vb->buffer->size, 4096);
-
- if (buf && buf->size < size)
- pipe_buffer_reference(&nscreen->strm_vbuf[i], NULL);
-
- if (!nscreen->strm_vbuf[i]) {
- nscreen->strm_vbuf[i] = pipe_buffer_create(
- pscreen, 0, PIPE_BUFFER_USAGE_VERTEX, size);
- buf = nscreen->strm_vbuf[i];
- }
-
- src = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
- if (!src)
- return FALSE;
- src += vb->buffer_offset;
-
- size = (vb->max_index + 1) * vb->stride + 16; /* + 16 is for stride 0 */
- if (vb->buffer_offset + size > vb->buffer->size)
- size = vb->buffer->size - vb->buffer_offset;
-
- pipe_buffer_write(pscreen, buf, vb->buffer_offset, size, src);
- pipe_buffer_unmap(pscreen, vb->buffer);
-
- vb->buffer = buf; /* don't pipe_reference, this is a private copy */
- return TRUE;
-}
-
-static void
-nv50_upload_user_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- if (nv50->vbo_fifo)
- nv50->dirty |= NV50_NEW_ARRAYS;
- if (!(nv50->dirty & NV50_NEW_ARRAYS))
- return;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- if (nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX)
- continue;
- nv50_upload_vtxbuf(nv50, i);
- }
-}
-
-static void
-nv50_set_static_vtxattr(struct nv50_context *nv50, unsigned i, void *data)
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- float v[4];
-
- util_format_read_4f(nv50->vtxelt[i].src_format,
- v, 0, data, 0, 0, 0, 1, 1);
-
- switch (nv50->vtxelt[i].nr_components) {
- case 4:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_4F_X(i), 4);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- OUT_RINGf (chan, v[3]);
- break;
- case 3:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_3F_X(i), 3);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- break;
- case 2:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_2F_X(i), 2);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- break;
- case 1:
- BEGIN_RING(chan, tesla, NV50TCL_VTX_ATTR_1F(i), 1);
- OUT_RINGf (chan, v[0]);
- break;
- default:
- assert(0);
- break;
- }
-}
-
-static unsigned
-init_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_bo *bo;
- unsigned i, b, count = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
- if (!bo->map)
- nouveau_bo_map(bo, NOUVEAU_BO_RD);
-
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
- }
-
- return count;
-}
-
-static unsigned
-init_per_instance_arrays(struct nv50_context *nv50,
- unsigned startInstance,
- unsigned pos[16], unsigned step[16])
-{
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
+struct instance {
struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b, count = 0;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo)
- return init_per_instance_arrays_immd(nv50, startInstance,
- pos, step);
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- ++count;
- b = nv50->vtxelt[i].vertex_buffer_index;
-
- pos[i] = nv50->vtxelt[i].src_offset +
- nv50->vtxbuf[b].buffer_offset +
- startInstance * nv50->vtxbuf[b].stride;
-
- if (!startInstance) {
- step[i] = 0;
- continue;
- }
- step[i] = startInstance % nv50->vtxelt[i].instance_divisor;
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
- }
-
- if (count && startInstance) {
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_emit(chan, nv50->state.instbuf);
- }
- so_ref (NULL, &so);
-
- return count;
-}
+ unsigned delta;
+ unsigned stride;
+ unsigned step;
+ unsigned divisor;
+};
static void
-step_per_instance_arrays_immd(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_init(struct nv50_context *nv50, struct instance *a, unsigned first)
{
- struct nouveau_bo *bo;
- unsigned i, b;
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
- continue;
- if (++step[i] != nv50->vtxelt[i].instance_divisor)
- continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
+ struct pipe_vertex_buffer *vb;
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ a[i].divisor = ve->instance_divisor;
+ if (a[i].divisor) {
+ vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
+ a[i].bo = nouveau_bo(vb->buffer);
+ a[i].stride = vb->stride;
+ a[i].step = first % a[i].divisor;
+ a[i].delta = vb->buffer_offset + ve->src_offset +
+ (first * a[i].stride);
+ }
}
}
static void
-step_per_instance_arrays(struct nv50_context *nv50,
- unsigned pos[16], unsigned step[16])
+instance_step(struct nv50_context *nv50, struct instance *a)
{
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct nouveau_bo *bo;
- struct nouveau_stateobj *so;
- unsigned i, b;
- const uint32_t rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
-
- if (nv50->vbo_fifo) {
- step_per_instance_arrays_immd(nv50, pos, step);
- return;
- }
-
- so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 2, nv50->vtxelt_nr * 2);
+ int i;
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- if (!nv50->vtxelt[i].instance_divisor)
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ if (!a[i].divisor)
continue;
- b = nv50->vtxelt[i].vertex_buffer_index;
- if (++step[i] == nv50->vtxelt[i].instance_divisor) {
- step[i] = 0;
- pos[i] += nv50->vtxbuf[b].stride;
+ BEGIN_RING(chan, tesla,
+ NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
+ OUT_RELOCh(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ OUT_RELOCl(chan, a[i].bo, a[i].delta, NOUVEAU_BO_RD |
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ if (++a[i].step == a[i].divisor) {
+ a[i].step = 0;
+ a[i].delta += a[i].stride;
}
-
- bo = nouveau_bo(nv50->vtxbuf[b].buffer);
-
- so_method(so, tesla, NV50TCL_VERTEX_ARRAY_START_HIGH(i), 2);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, bo, pos[i], rl | NOUVEAU_BO_LOW, 0, 0);
}
-
- so_ref (so, &nv50->state.instbuf); /* for flush notify */
- so_ref (NULL, &so);
-
- so_emit(chan, nv50->state.instbuf);
-}
-
-static INLINE void
-nv50_unmap_vbufs(struct nv50_context *nv50)
-{
- unsigned i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
- if (nouveau_bo(nv50->vtxbuf[i].buffer)->map)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
}
void
@@ -415,198 +180,207 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 10 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, NULL, 0, mode, start,
+ count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 7 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, prim);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
OUT_RING (chan, start);
OUT_RING (chan, count);
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; i++) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- if (nv50->vbo_fifo)
- nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- boolean ret;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (nv50->vbo_fifo)
- ret = nv50_push_arrays(nv50, start, count);
- else {
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BUFFER_FIRST, 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- ret = TRUE;
- }
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- nv50_unmap_vbufs(nv50);
-
- /* XXX: not sure what to do if ret != TRUE: flush and retry?
- */
- assert(ret);
+ nv50_draw_arrays_instanced(pipe, mode, start, count, 0, 1);
}
-static INLINE boolean
-nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
- unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
+struct inline_ctx {
+ struct nv50_context *nv50;
+ void *map;
+};
- if (nv50->vbo_fifo)
- return nv50_push_elements_u08(nv50, map, count);
+static void
+inline_elt08(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint8_t *map = (uint8_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
map++;
- count--;
+ count &= ~1;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt16(void *priv, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
-
- map += start;
-
- if (nv50->vbo_fifo)
- return nv50_push_elements_u16(nv50, map, count);
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+ uint16_t *map = (uint16_t *)ctx->map + start;
if (count & 1) {
BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, map[0]);
+ count &= ~1;
map++;
- count--;
}
- while (count) {
- unsigned nr = count > 2046 ? 2046 : count;
- int i;
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, nr >> 1);
- for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[i + 1] << 16) | map[i]);
+ count >>= 1;
+ if (!count)
+ return;
- count -= nr;
- map += nr;
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U16, count);
+ while (count--) {
+ OUT_RING(chan, (map[1] << 16) | map[0]);
+ map += 2;
}
- return TRUE;
}
-static INLINE boolean
-nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
- unsigned start, unsigned count)
+static void
+inline_elt32(void *priv, unsigned start, unsigned count)
+{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, count);
+ OUT_RINGp (chan, (uint32_t *)ctx->map + start, count);
+}
+
+static void
+inline_edgeflag(void *priv, boolean enabled)
{
+ struct inline_ctx *ctx = priv;
+ struct nouveau_grobj *tesla = ctx->nv50->screen->tesla;
+ struct nouveau_channel *chan = tesla->channel;
+
+ BEGIN_RING(chan, tesla, NV50TCL_EDGEFLAG_ENABLE, 1);
+ OUT_RING (chan, enabled ? 1 : 0);
+}
+
+static void
+nv50_draw_elements_inline(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer, unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned startInstance, unsigned instanceCount)
+{
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct instance a[16];
+ struct inline_ctx ctx;
+ struct u_split_prim s;
+ boolean nzi = FALSE;
+ unsigned overhead;
+
+ overhead = 16*3; /* potential instance adjustments */
+ overhead += 4; /* Begin()/End() */
+ overhead += 4; /* potential edgeflag disable/reenable */
+ overhead += 3; /* potentially 3 VTX_ELT_U16/U32 packet headers */
+
+ s.priv = &ctx;
+ if (indexSize == 1)
+ s.emit = inline_elt08;
+ else
+ if (indexSize == 2)
+ s.emit = inline_elt16;
+ else
+ s.emit = inline_elt32;
+ s.edge = inline_edgeflag;
+
+ ctx.nv50 = nv50;
+ ctx.map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(ctx.map);
+ if (!ctx.map)
+ return;
- map += start;
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, overhead + 6 + 3))
+ return;
- if (nv50->vbo_fifo)
- return nv50_push_elements_u32(nv50, map, count);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
+ OUT_RING (chan, NV50_CB_AUX | (24 << 8));
+ OUT_RING (chan, startInstance);
+ while (instanceCount--) {
+ unsigned max_verts;
+ boolean done;
+
+ u_split_prim_init(&s, mode, start, count);
+ do {
+ if (AVAIL_RING(chan) < (overhead + 6)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, (overhead + 6))) {
+ assert(0);
+ return;
+ }
+ }
- while (count) {
- unsigned nr = count > 2047 ? 2047 : count;
+ max_verts = AVAIL_RING(chan) - overhead;
+ if (max_verts > 2047)
+ max_verts = 2047;
+ if (indexSize != 4)
+ max_verts <<= 1;
+ instance_step(nv50, a);
- BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr);
- OUT_RINGp (chan, map, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
+ OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0));
+ done = u_split_prim_next(&s, max_verts);
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ } while (!done);
- count -= nr;
- map += nr;
+ nzi = TRUE;
}
- return TRUE;
-}
-static INLINE void
-nv50_draw_elements_inline(struct nv50_context *nv50,
- void *map, unsigned indexSize,
- unsigned start, unsigned count)
-{
- switch (indexSize) {
- case 1:
- nv50_draw_elements_inline_u08(nv50, map, start, count);
- break;
- case 2:
- nv50_draw_elements_inline_u16(nv50, map, start, count);
- break;
- case 4:
- nv50_draw_elements_inline_u32(nv50, map, start, count);
- break;
- }
+ pipe_buffer_unmap(pscreen, indexBuffer);
}
void
@@ -617,49 +391,68 @@ nv50_draw_elements_instanced(struct pipe_context *pipe,
unsigned startInstance, unsigned instanceCount)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_channel *chan = tesla->channel;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
- unsigned i, nz_divisors;
- unsigned step[16], pos[16];
+ struct instance a[16];
+ unsigned prim = nv50_prim(mode);
- map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
-
- if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50_upload_user_vbufs(nv50);
-
- nv50_state_validate(nv50);
+ instance_init(nv50, a, startInstance);
+ if (!nv50_state_validate(nv50, 13 + 16*3))
+ return;
- nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+ if (nv50->vbo_fifo) {
+ nv50_push_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ } else
+ if (!(indexBuffer->usage & PIPE_BUFFER_USAGE_INDEX) || indexSize == 1) {
+ nv50_draw_elements_inline(pipe, indexBuffer, indexSize,
+ mode, start, count, startInstance,
+ instanceCount);
+ return;
+ }
BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 2);
OUT_RING (chan, NV50_CB_AUX | (24 << 8));
OUT_RING (chan, startInstance);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
-
- for (i = 1; i < instanceCount; ++i) {
- if (nz_divisors) /* any non-zero array divisors ? */
- step_per_instance_arrays(nv50, pos, step);
+ while (instanceCount--) {
+ if (AVAIL_RING(chan) < (7 + 16*3)) {
+ FIRE_RING(chan);
+ if (!nv50_state_validate(nv50, 10 + 16*3)) {
+ assert(0);
+ return;
+ }
+ }
+ instance_step(nv50, a);
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode) | (1 << 28));
-
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
-
+ OUT_RING (chan, prim);
+ if (indexSize == 4) {
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
+ OUT_RING (chan, count);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ start << 2, count << 2);
+ } else
+ if (indexSize == 2) {
+ unsigned vb_start = (start & ~1);
+ unsigned vb_end = (start + count + 1) & ~1;
+ unsigned dwords = (vb_end - vb_start) >> 1;
+
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, ((start & 1) << 31) | count);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
+ OUT_RING (chan, dwords);
+ nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
+ vb_start << 1, dwords << 2);
+ BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
+ OUT_RING (chan, 0);
+ }
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
- }
- nv50_unmap_vbufs(nv50);
- so_ref(NULL, &nv50->state.instbuf);
+ prim |= (1 << 28);
+ }
}
void
@@ -667,51 +460,8 @@ nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->tesla->channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_screen *pscreen = pipe->screen;
- void *map;
-
- nv50_state_validate(nv50);
-
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, tesla, 0x142c, 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
- OUT_RING (chan, nv50_prim(mode));
-
- if (!nv50->vbo_fifo && indexSize == 4) {
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0);
- OUT_RING (chan, count);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- start << 2, count << 2);
- } else
- if (!nv50->vbo_fifo && indexSize == 2) {
- unsigned vb_start = (start & ~1);
- unsigned vb_end = (start + count + 1) & ~1;
- unsigned dwords = (vb_end - vb_start) >> 1;
-
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, ((start & 1) << 31) | count);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0);
- OUT_RING (chan, dwords);
- nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer),
- vb_start << 1, dwords << 2);
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1);
- OUT_RING (chan, 0);
- } else {
- map = pipe_buffer_map(pscreen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- nv50_draw_elements_inline(nv50, map, indexSize, start, count);
- nv50_unmap_vbufs(nv50);
- pipe_buffer_unmap(pscreen, indexBuffer);
- }
-
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
- OUT_RING (chan, 0);
+ nv50_draw_elements_instanced(pipe, indexBuffer, indexSize,
+ mode, start, count, 0, 1);
}
static INLINE boolean
@@ -726,6 +476,7 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
float v[4];
int ret;
+ unsigned nr_components = util_format_get_nr_components(ve->src_format);
ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
if (ret)
@@ -736,9 +487,10 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
0, 0, 1, 1);
so = *pso;
if (!so)
- *pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
+ *pso = so = so_new(nv50->vtxelt->num_elements,
+ nv50->vtxelt->num_elements * 4, 0);
- switch (ve->nr_components) {
+ switch (nr_components) {
case 4:
so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
so_data (so, fui(v[0]));
@@ -775,6 +527,18 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
}
void
+nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso)
+{
+ unsigned i;
+
+ for (i = 0; i < cso->num_elements; ++i) {
+ struct pipe_vertex_element *ve = &cso->pipe[i];
+
+ cso->hw[i] = nv50_vbo_vtxelt_to_hw(ve);
+ }
+}
+
+struct nouveau_stateobj *
nv50_vbo_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
@@ -783,30 +547,32 @@ nv50_vbo_validate(struct nv50_context *nv50)
/* don't validate if Gallium took away our buffers */
if (nv50->vtxbuf_nr == 0)
- return;
+ return NULL;
+
nv50->vbo_fifo = 0;
+ if (nv50->screen->force_push ||
+ nv50->vertprog->cfg.edgeflag_in < 16)
+ nv50->vbo_fifo = 0xffff;
- for (i = 0; i < nv50->vtxbuf_nr; ++i)
+ for (i = 0; i < nv50->vtxbuf_nr; i++) {
if (nv50->vtxbuf[i].stride &&
!(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))
nv50->vbo_fifo = 0xffff;
+ }
- if (NV50_USING_LOATHED_EDGEFLAG(nv50))
- nv50->vbo_fifo = 0xffff; /* vertprog can't set edgeflag */
-
- n_ve = MAX2(nv50->vtxelt_nr, nv50->state.vtxelt_nr);
+ n_ve = MAX2(nv50->vtxelt->num_elements, nv50->state.vtxelt_nr);
vtxattr = NULL;
- vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt_nr * 4);
+ vtxbuf = so_new(n_ve * 2, n_ve * 5, nv50->vtxelt->num_elements * 4);
vtxfmt = so_new(1, n_ve, 0);
so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), n_ve);
- for (i = 0; i < nv50->vtxelt_nr; i++) {
- struct pipe_vertex_element *ve = &nv50->vtxelt[i];
+ for (i = 0; i < nv50->vtxelt->num_elements; i++) {
+ struct pipe_vertex_element *ve = &nv50->vtxelt->pipe[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
- uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
+ uint32_t hw = nv50->vtxelt->hw[i];
if (!vb->stride &&
nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
@@ -821,13 +587,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
}
if (nv50->vbo_fifo) {
- so_data (vtxfmt, hw |
- (ve->instance_divisor ? (1 << 4) : i));
+ so_data (vtxfmt, hw | (ve->instance_divisor ? (1 << 4) : i));
so_method(vtxbuf, tesla,
NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
continue;
}
+
so_data(vtxfmt, hw | i);
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
@@ -855,355 +621,13 @@ nv50_vbo_validate(struct nv50_context *nv50)
so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
so_data (vtxbuf, 0);
}
- nv50->state.vtxelt_nr = nv50->vtxelt_nr;
+ nv50->state.vtxelt_nr = nv50->vtxelt->num_elements;
- so_ref (vtxfmt, &nv50->state.vtxfmt);
so_ref (vtxbuf, &nv50->state.vtxbuf);
so_ref (vtxattr, &nv50->state.vtxattr);
so_ref (NULL, &vtxbuf);
- so_ref (NULL, &vtxfmt);
so_ref (NULL, &vtxattr);
+ return vtxfmt;
}
-typedef void (*pfn_push)(struct nouveau_channel *, void *);
-
-struct nv50_vbo_emitctx
-{
- pfn_push push[16];
- uint8_t *map[16];
- unsigned stride[16];
- unsigned nr_ve;
- unsigned vtx_dwords;
- unsigned vtx_max;
-
- float edgeflag;
- unsigned ve_edgeflag;
-};
-
-static INLINE void
-emit_vtx_next(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i) {
- emit->push[i](chan, emit->map[i]);
- emit->map[i] += emit->stride[i];
- }
-}
-
-static INLINE void
-emit_vtx(struct nouveau_channel *chan, struct nv50_vbo_emitctx *emit,
- uint32_t vi)
-{
- unsigned i;
-
- for (i = 0; i < emit->nr_ve; ++i)
- emit->push[i](chan, emit->map[i] + emit->stride[i] * vi);
-}
-
-static INLINE boolean
-nv50_map_vbufs(struct nv50_context *nv50)
-{
- int i;
-
- for (i = 0; i < nv50->vtxbuf_nr; ++i) {
- struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- unsigned size = vb->stride * (vb->max_index + 1) + 16;
-
- if (nouveau_bo(vb->buffer)->map)
- continue;
-
- size = vb->stride * (vb->max_index + 1) + 16;
- size = MIN2(size, vb->buffer->size);
- if (!size)
- size = vb->buffer->size;
-
- if (nouveau_bo_map_range(nouveau_bo(vb->buffer),
- 0, size, NOUVEAU_BO_RD))
- break;
- }
-
- if (i == nv50->vtxbuf_nr)
- return TRUE;
- for (; i >= 0; --i)
- nouveau_bo_unmap(nouveau_bo(nv50->vtxbuf[i].buffer));
- return FALSE;
-}
-
-static void
-emit_b32_1(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b32_2(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
-}
-
-static void
-emit_b32_3(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b32_4(struct nouveau_channel *chan, void *data)
-{
- uint32_t *v = data;
-
- OUT_RING(chan, v[0]);
- OUT_RING(chan, v[1]);
- OUT_RING(chan, v[2]);
- OUT_RING(chan, v[3]);
-}
-
-static void
-emit_b16_1(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b16_3(struct nouveau_channel *chan, void *data)
-{
- uint16_t *v = data;
-
- OUT_RING(chan, (v[1] << 16) | v[0]);
- OUT_RING(chan, v[2]);
-}
-
-static void
-emit_b08_1(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, v[0]);
-}
-
-static void
-emit_b08_3(struct nouveau_channel *chan, void *data)
-{
- uint8_t *v = data;
-
- OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]);
-}
-
-static boolean
-emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,
- unsigned start)
-{
- unsigned i;
-
- if (nv50_map_vbufs(nv50) == FALSE)
- return FALSE;
-
- emit->ve_edgeflag = nv50->vertprog->cfg.edgeflag_in;
-
- emit->edgeflag = 0.5f;
- emit->nr_ve = 0;
- emit->vtx_dwords = 0;
-
- for (i = 0; i < nv50->vtxelt_nr; ++i) {
- struct pipe_vertex_element *ve;
- struct pipe_vertex_buffer *vb;
- unsigned n, size;
- const struct util_format_description *desc;
-
- ve = &nv50->vtxelt[i];
- vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor)
- continue;
- n = emit->nr_ve++;
-
- emit->stride[n] = vb->stride;
- emit->map[n] = (uint8_t *)nouveau_bo(vb->buffer)->map +
- vb->buffer_offset +
- (start * vb->stride + ve->src_offset);
-
- desc = util_format_description(ve->src_format);
- assert(desc);
-
- size = util_format_get_component_bits(
- ve->src_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
-
- assert(ve->nr_components > 0 && ve->nr_components <= 4);
-
- /* It shouldn't be necessary to push the implicit 1s
- * for case 3 and size 8 cases 1, 2, 3.
- */
- switch (size) {
- default:
- NOUVEAU_ERR("unsupported vtxelt size: %u\n", size);
- return FALSE;
- case 32:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b32_1; break;
- case 2: emit->push[n] = emit_b32_2; break;
- case 3: emit->push[n] = emit_b32_3; break;
- case 4: emit->push[n] = emit_b32_4; break;
- }
- emit->vtx_dwords += ve->nr_components;
- break;
- case 16:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b16_1; break;
- case 2: emit->push[n] = emit_b32_1; break;
- case 3: emit->push[n] = emit_b16_3; break;
- case 4: emit->push[n] = emit_b32_2; break;
- }
- emit->vtx_dwords += (ve->nr_components + 1) >> 1;
- break;
- case 8:
- switch (ve->nr_components) {
- case 1: emit->push[n] = emit_b08_1; break;
- case 2: emit->push[n] = emit_b16_1; break;
- case 3: emit->push[n] = emit_b08_3; break;
- case 4: emit->push[n] = emit_b32_1; break;
- }
- emit->vtx_dwords += 1;
- break;
- }
- }
-
- emit->vtx_max = 512 / emit->vtx_dwords;
- if (emit->ve_edgeflag < 16)
- emit->vtx_max = 1;
-
- return TRUE;
-}
-
-static INLINE void
-set_edgeflag(struct nouveau_channel *chan,
- struct nouveau_grobj *tesla,
- struct nv50_vbo_emitctx *emit, uint32_t index)
-{
- unsigned i = emit->ve_edgeflag;
-
- if (i < 16) {
- float f = *((float *)(emit->map[i] + index * emit->stride[i]));
-
- if (emit->edgeflag != f) {
- emit->edgeflag = f;
-
- BEGIN_RING(chan, tesla, 0x15e4, 1);
- OUT_RING (chan, f ? 1 : 0);
- }
- }
-}
-
-static boolean
-nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
- if (emit_prepare(nv50, &emit, start) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx_next(chan, &emit);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
-
-static boolean
-nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count)
-{
- struct nouveau_channel *chan = nv50->screen->base.channel;
- struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nv50_vbo_emitctx emit;
-
- if (emit_prepare(nv50, &emit, 0) == FALSE)
- return FALSE;
-
- while (count) {
- unsigned i, dw, nr = MIN2(count, emit.vtx_max);
- dw = nr * emit.vtx_dwords;
-
- set_edgeflag(chan, tesla, &emit, *map);
-
- BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
- for (i = 0; i < nr; ++i)
- emit_vtx(chan, &emit, *map++);
-
- count -= nr;
- }
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile
new file mode 100644
index 00000000000..dfe97e6ed5f
--- /dev/null
+++ b/src/gallium/drivers/nvfx/Makefile
@@ -0,0 +1,32 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nvfx
+
+C_SOURCES = \
+ nv04_surface_2d.c \
+ nvfx_context.c \
+ nvfx_clear.c \
+ nvfx_draw.c \
+ nvfx_fragprog.c \
+ nvfx_fragtex.c \
+ nv30_fragtex.c \
+ nv40_fragtex.c \
+ nvfx_miptree.c \
+ nvfx_query.c \
+ nvfx_screen.c \
+ nvfx_state.c \
+ nvfx_state_blend.c \
+ nvfx_state_emit.c \
+ nvfx_state_fb.c \
+ nvfx_state_rasterizer.c \
+ nvfx_state_scissor.c \
+ nvfx_state_stipple.c \
+ nvfx_state_viewport.c \
+ nvfx_state_zsa.c \
+ nvfx_surface.c \
+ nvfx_transfer.c \
+ nvfx_vbo.c \
+ nvfx_vertprog.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/nouveau/nv04_surface_2d.c b/src/gallium/drivers/nvfx/nv04_surface_2d.c
index b074547c4da..ed18c9f24dc 100644
--- a/src/gallium/drivers/nouveau/nv04_surface_2d.c
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.c
@@ -518,7 +518,6 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
ns->base.usage = PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER | PIPE_BUFFER_USAGE_GPU_READ;
}
- struct nv40_screen* screen = (struct nv40_screen*)pscreen;
ns->base.usage = PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE;
struct pipe_texture templ;
@@ -544,4 +543,3 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface_2d
return temp_ns;
}
-
diff --git a/src/gallium/drivers/nouveau/nv04_surface_2d.h b/src/gallium/drivers/nvfx/nv04_surface_2d.h
index ce696a11a39..ce696a11a39 100644
--- a/src/gallium/drivers/nouveau/nv04_surface_2d.h
+++ b/src/gallium/drivers/nvfx/nv04_surface_2d.h
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index f7d98f3f208..54e47574c4d 100644
--- a/src/gallium/drivers/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -1,7 +1,37 @@
#include "util/u_format.h"
-#include "nv30_context.h"
+#include "nvfx_context.h"
#include "nouveau/nouveau_util.h"
+#include "nvfx_tex.h"
+
+void
+nv30_sampler_state_init(struct pipe_context *pipe,
+ struct nvfx_sampler_state *ps,
+ const struct pipe_sampler_state *cso)
+{
+ if (cso->max_anisotropy >= 8) {
+ ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
+ } else
+ if (cso->max_anisotropy >= 4) {
+ ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
+ } else
+ if (cso->max_anisotropy >= 2) {
+ ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
+ }
+
+ {
+ float limit;
+
+ limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+ ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
+
+ limit = CLAMP(cso->max_lod, 0.0, 15.0);
+ ps->en |= (int)(limit) << 14 /*NV34TCL_TX_ENABLE_MIPMAP_MAX_LOD_SHIFT*/;
+
+ limit = CLAMP(cso->min_lod, 0.0, 15.0);
+ ps->en |= (int)(limit) << 26 /*NV34TCL_TX_ENABLE_MIPMAP_MIN_LOD_SHIFT*/;
+ }
+}
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w) \
{ \
@@ -57,11 +87,11 @@ nv30_fragtex_format(uint pipe_format)
}
-static struct nouveau_stateobj *
-nv30_fragtex_build(struct nv30_context *nv30, int unit)
+struct nouveau_stateobj *
+nv30_fragtex_build(struct nvfx_context *nvfx, int unit)
{
- struct nv30_sampler_state *ps = nv30->tex_sampler[unit];
- struct nv30_miptree *nv30mt = nv30->tex_miptree[unit];
+ struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
+ struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct pipe_texture *pt = &nv30mt->base;
struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
struct nv30_texture_format *tf;
@@ -101,7 +131,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
txs = tf->swizzle;
so = so_new(1, 8, 2);
- so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_TX_OFFSET(unit), 8);
so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
@@ -115,47 +145,3 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
return so;
}
-
-static boolean
-nv30_fragtex_validate(struct nv30_context *nv30)
-{
- struct nv30_fragment_program *fp = nv30->fragprog;
- struct nv30_state *state = &nv30->state;
- struct nouveau_stateobj *so;
- unsigned samplers, unit;
-
- samplers = state->fp_samplers & ~fp->samplers;
- while (samplers) {
- unit = ffs(samplers) - 1;
- samplers &= ~(1 << unit);
-
- so = so_new(1, 1, 0);
- so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1);
- so_data (so, 0);
- so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
- so_ref(NULL, &so);
- state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
- }
-
- samplers = nv30->dirty_samplers & fp->samplers;
- while (samplers) {
- unit = ffs(samplers) - 1;
- samplers &= ~(1 << unit);
-
- so = nv30_fragtex_build(nv30, unit);
- so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
- so_ref(NULL, &so);
- state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
- }
-
- nv30->state.fp_samplers = fp->samplers;
- return FALSE;
-}
-
-struct nv30_state_entry nv30_state_fragtex = {
- .validate = nv30_fragtex_validate,
- .dirty = {
- .pipe = NV30_NEW_SAMPLER | NV30_NEW_FRAGPROG,
- .hw = 0
- }
-};
diff --git a/src/gallium/drivers/nvfx/nv30_vertprog.h b/src/gallium/drivers/nvfx/nv30_vertprog.h
new file mode 100644
index 00000000000..ec0444c07f8
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nv30_vertprog.h
@@ -0,0 +1,169 @@
+#ifndef __NV30_SHADER_H__
+#define __NV30_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * 128bit opcodes, split into 4 32-bit ones for ease of use.
+ *
+ * Non-native instructions
+ * ABS - MOV + NV40_VP_INST0_DEST_ABS
+ * POW - EX2 + MUL + LG2
+ * SUB - ADD, second source negated
+ * SWZ - MOV
+ * XPD -
+ *
+ * Register access
+ * - Only one INPUT can be accessed per-instruction (move extras into TEMPs)
+ * - Only one CONST can be accessed per-instruction (move extras into TEMPs)
+ *
+ * Relative Addressing
+ * According to the value returned for
+ * MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
+ *
+ * there are only two address registers available. The destination in the
+ * ARL instruction is set to TEMP <n> (The temp isn't actually written).
+ *
+ * When using vanilla ARB_v_p, the proprietary driver will squish both the
+ * available ADDRESS regs into the first hardware reg in the X and Y
+ * components.
+ *
+ * To use an address reg as an index into consts, the CONST_SRC is set to
+ * (const_base + offset) and INDEX_CONST is set.
+ *
+ * To access the second address reg use ADDR_REG_SELECT_1. A particular
+ * component of the address regs is selected with ADDR_SWZ.
+ *
+ * Only one address register can be accessed per instruction.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details) Conditional
+ * execution of an instruction is enabled by setting COND_TEST_ENABLE, and
+ * selecting the condition which will allow the test to pass with
+ * COND_{FL,LT,...}. It is possible to swizzle the values in the condition
+ * register, which allows for testing against an individual component.
+ *
+ * Branching:
+ *
+ * The BRA/CAL instructions seem to follow a slightly different opcode
+ * layout. The destination instruction ID (IADDR) overlaps a source field.
+ * Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO
+ * command, and is incremented automatically on each UPLOAD_INST FIFO
+ * command.
+ *
+ * Conditional branching is achieved by using the condition tests described
+ * above. There doesn't appear to be dedicated looping instructions, but
+ * this can be done using a temp reg + conditional branching.
+ *
+ * Subroutines may be uploaded before the main program itself, but the first
+ * executed instruction is determined by the PROGRAM_START_ID FIFO command.
+ *
+ */
+
+/* DWORD 0 */
+
+#define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
+#define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */
+#define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */
+#define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */
+#define NV30_VP_INST_VEC_RESULT (1 << 20)
+#define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16
+#define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16)
+#define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15)
+#define NV30_VP_INST_VEC_DEST_TEMP_MASK (0xF << 16)
+#define NV30_VP_INST_COND_TEST_ENABLE (1<<14)
+#define NV30_VP_INST_COND_SHIFT 11
+#define NV30_VP_INST_COND_MASK (0x07 << 11)
+#define NV30_VP_INST_COND_SWZ_X_SHIFT 9
+#define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
+#define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
+#define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
+#define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
+#define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
+#define NV30_VP_INST_COND_SWZ_W_SHIFT 3
+#define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
+#define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
+#define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
+#define NV30_VP_INST_ADDR_SWZ_SHIFT 1
+#define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
+#define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
+#define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
+
+/* DWORD 1 */
+#define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
+#define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
+#define NV30_VP_INST_VEC_OPCODE_SHIFT 23
+#define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
+#define NV30_VP_INST_CONST_SRC_SHIFT 14
+#define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
+#define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
+#define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
+#define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
+#define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
+
+/* Please note: the IADDR fields overlap other fields because they are used
+ * only for branch instructions. See Branching: label above
+ *
+ * DWORD 2
+ */
+#define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
+#define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */
+#define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
+#define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
+#define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
+#define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/
+#define NV30_VP_INST_IADDR_SHIFT 2
+#define NV30_VP_INST_IADDR_MASK (0xF << 28) /* NV30_VP_SRC2_LOW_MASK << 28 */
+
+/* DWORD 3 */
+#define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
+#define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
+#define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
+#define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
+#define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
+#define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
+#define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
+#define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
+#define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
+#define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
+#define NV30_VP_INST_DEST_SHIFT 2
+#define NV30_VP_INST_DEST_MASK (0x0F << 2)
+# define NV30_VP_INST_DEST_POS 0
+# define NV30_VP_INST_DEST_BFC0 1
+# define NV30_VP_INST_DEST_BFC1 2
+# define NV30_VP_INST_DEST_COL0 3
+# define NV30_VP_INST_DEST_COL1 4
+# define NV30_VP_INST_DEST_FOGC 5
+# define NV30_VP_INST_DEST_PSZ 6
+# define NV30_VP_INST_DEST_TC(n) (8+n)
+
+/* Useful to split the source selection regs into their pieces */
+#define NV30_VP_SRC0_HIGH_SHIFT 6
+#define NV30_VP_SRC0_HIGH_MASK 0x00007FC0
+#define NV30_VP_SRC0_LOW_MASK 0x0000003F
+#define NV30_VP_SRC2_HIGH_SHIFT 4
+#define NV30_VP_SRC2_HIGH_MASK 0x00007FF0
+#define NV30_VP_SRC2_LOW_MASK 0x0000000F
+
+
+/* Source-register definition - matches NV20 exactly */
+#define NV30_VP_SRC_NEGATE (1<<14)
+#define NV30_VP_SRC_SWZ_X_SHIFT 12
+#define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
+#define NV30_VP_SRC_SWZ_Y_SHIFT 10
+#define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
+#define NV30_VP_SRC_SWZ_Z_SHIFT 8
+#define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
+#define NV30_VP_SRC_SWZ_W_SHIFT 6
+#define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
+#define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
+#define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
+#define NV30_VP_SRC_TEMP_SRC_SHIFT 2
+#define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
+#define NV30_VP_SRC_REG_TYPE_SHIFT 0
+#define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
+#define NV30_VP_SRC_REG_TYPE_TEMP 1
+#define NV30_VP_SRC_REG_TYPE_INPUT 2
+#define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
+
+#include "nvfx_shader.h"
+
+#endif
diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c
index b60118922a2..05506e28099 100644
--- a/src/gallium/drivers/nv40/nv40_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv40_fragtex.c
@@ -1,18 +1,63 @@
#include "util/u_format.h"
+#include "nvfx_context.h"
+#include "nvfx_tex.h"
-#include "nv40_context.h"
+void
+nv40_sampler_state_init(struct pipe_context *pipe,
+ struct nvfx_sampler_state *ps,
+ const struct pipe_sampler_state *cso)
+{
+ if (cso->max_anisotropy >= 2) {
+ /* no idea, binary driver sets it, works without it.. meh.. */
+ ps->wrap |= (1 << 5);
+
+ if (cso->max_anisotropy >= 16) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X;
+ } else
+ if (cso->max_anisotropy >= 12) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X;
+ } else
+ if (cso->max_anisotropy >= 10) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X;
+ } else
+ if (cso->max_anisotropy >= 8) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X;
+ } else
+ if (cso->max_anisotropy >= 6) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X;
+ } else
+ if (cso->max_anisotropy >= 4) {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X;
+ } else {
+ ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X;
+ }
+ }
+
+ {
+ float limit;
+
+ limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+ ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
+
+ limit = CLAMP(cso->max_lod, 0.0, 15.0);
+ ps->en |= (int)(limit * 256.0) << 7;
+
+ limit = CLAMP(cso->min_lod, 0.0, 15.0);
+ ps->en |= (int)(limit * 256.0) << 19;
+ }
+}
#define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \
{ \
TRUE, \
PIPE_FORMAT_##m, \
NV40TCL_TEX_FORMAT_FORMAT_##tf, \
- (NV40TCL_TEX_SWIZZLE_S0_X_##ts0x | NV40TCL_TEX_SWIZZLE_S0_Y_##ts0y | \
- NV40TCL_TEX_SWIZZLE_S0_Z_##ts0z | NV40TCL_TEX_SWIZZLE_S0_W_##ts0w | \
- NV40TCL_TEX_SWIZZLE_S1_X_##ts1x | NV40TCL_TEX_SWIZZLE_S1_Y_##ts1y | \
- NV40TCL_TEX_SWIZZLE_S1_Z_##ts1z | NV40TCL_TEX_SWIZZLE_S1_W_##ts1w), \
- ((NV40TCL_TEX_FILTER_SIGNED_RED*sx) | (NV40TCL_TEX_FILTER_SIGNED_GREEN*sy) | \
- (NV40TCL_TEX_FILTER_SIGNED_BLUE*sz) | (NV40TCL_TEX_FILTER_SIGNED_ALPHA*sw)) \
+ (NV34TCL_TX_SWIZZLE_S0_X_##ts0x | NV34TCL_TX_SWIZZLE_S0_Y_##ts0y | \
+ NV34TCL_TX_SWIZZLE_S0_Z_##ts0z | NV34TCL_TX_SWIZZLE_S0_W_##ts0w | \
+ NV34TCL_TX_SWIZZLE_S1_X_##ts1x | NV34TCL_TX_SWIZZLE_S1_Y_##ts1y | \
+ NV34TCL_TX_SWIZZLE_S1_Z_##ts1z | NV34TCL_TX_SWIZZLE_S1_W_##ts1w), \
+ ((NV34TCL_TX_FILTER_SIGNED_RED*sx) | (NV34TCL_TX_FILTER_SIGNED_GREEN*sy) | \
+ (NV34TCL_TX_FILTER_SIGNED_BLUE*sz) | (NV34TCL_TX_FILTER_SIGNED_ALPHA*sw)) \
}
struct nv40_texture_format {
@@ -60,11 +105,11 @@ nv40_fragtex_format(uint pipe_format)
}
-static struct nouveau_stateobj *
-nv40_fragtex_build(struct nv40_context *nv40, int unit)
+struct nouveau_stateobj *
+nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
{
- struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
- struct nv40_miptree *nv40mt = nv40->tex_miptree[unit];
+ struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
+ struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
struct pipe_texture *pt = &nv40mt->base;
struct nv40_texture_format *tf;
@@ -81,20 +126,20 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
txf |= ((pt->last_level + 1) << NV40TCL_TEX_FORMAT_MIPMAP_COUNT_SHIFT);
if (1) /* XXX */
- txf |= NV40TCL_TEX_FORMAT_NO_BORDER;
+ txf |= NV34TCL_TX_FORMAT_NO_BORDER;
switch (pt->target) {
case PIPE_TEXTURE_CUBE:
- txf |= NV40TCL_TEX_FORMAT_CUBIC;
+ txf |= NV34TCL_TX_FORMAT_CUBIC;
/* fall-through */
case PIPE_TEXTURE_2D:
- txf |= NV40TCL_TEX_FORMAT_DIMS_2D;
+ txf |= NV34TCL_TX_FORMAT_DIMS_2D;
break;
case PIPE_TEXTURE_3D:
- txf |= NV40TCL_TEX_FORMAT_DIMS_3D;
+ txf |= NV34TCL_TX_FORMAT_DIMS_3D;
break;
case PIPE_TEXTURE_1D:
- txf |= NV40TCL_TEX_FORMAT_DIMS_1D;
+ txf |= NV34TCL_TX_FORMAT_DIMS_1D;
break;
default:
NOUVEAU_ERR("Unknown target %d\n", pt->target);
@@ -111,63 +156,19 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
txs = tf->swizzle;
so = so_new(2, 9, 2);
- so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_TX_OFFSET(unit), 8);
so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
- NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1);
+ NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
so_data (so, ps->wrap);
so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
so_data (so, txs);
so_data (so, ps->filt | tf->sign | 0x2000 /*voodoo*/);
- so_data (so, (pt->width0 << NV40TCL_TEX_SIZE0_W_SHIFT) |
+ so_data (so, (pt->width0 << NV34TCL_TX_NPOT_SIZE_W_SHIFT) |
pt->height0);
so_data (so, ps->bcol);
- so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1);
+ so_method(so, nvfx->screen->eng3d, NV40TCL_TEX_SIZE1(unit), 1);
so_data (so, (pt->depth0 << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp);
return so;
}
-
-static boolean
-nv40_fragtex_validate(struct nv40_context *nv40)
-{
- struct nv40_fragment_program *fp = nv40->fragprog;
- struct nv40_state *state = &nv40->state;
- struct nouveau_stateobj *so;
- unsigned samplers, unit;
-
- samplers = state->fp_samplers & ~fp->samplers;
- while (samplers) {
- unit = ffs(samplers) - 1;
- samplers &= ~(1 << unit);
-
- so = so_new(1, 1, 0);
- so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1);
- so_data (so, 0);
- so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
- state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
- }
-
- samplers = nv40->dirty_samplers & fp->samplers;
- while (samplers) {
- unit = ffs(samplers) - 1;
- samplers &= ~(1 << unit);
-
- so = nv40_fragtex_build(nv40, unit);
- so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]);
- so_ref(NULL, &so);
- state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit));
- }
-
- nv40->state.fp_samplers = fp->samplers;
- return FALSE;
-}
-
-struct nv40_state_entry nv40_state_fragtex = {
- .validate = nv40_fragtex_validate,
- .dirty = {
- .pipe = NV40_NEW_SAMPLER | NV40_NEW_FRAGPROG,
- .hw = 0
- }
-};
-
diff --git a/src/gallium/drivers/nvfx/nv40_vertprog.h b/src/gallium/drivers/nvfx/nv40_vertprog.h
new file mode 100644
index 00000000000..7337293babc
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nv40_vertprog.h
@@ -0,0 +1,177 @@
+#ifndef __NV40_SHADER_H__
+#define __NV40_SHADER_H__
+
+/* Vertex programs instruction set
+ *
+ * The NV40 instruction set is very similar to NV30. Most fields are in
+ * a slightly different position in the instruction however.
+ *
+ * Merged instructions
+ * In some cases it is possible to put two instructions into one opcode
+ * slot. The rules for when this is OK is not entirely clear to me yet.
+ *
+ * There are separate writemasks and dest temp register fields for each
+ * grouping of instructions. There is however only one field with the
+ * ID of a result register. Writing to temp/result regs is selected by
+ * setting VEC_RESULT/SCA_RESULT.
+ *
+ * Temporary registers
+ * The source/dest temp register fields have been extended by 1 bit, to
+ * give a total of 32 temporary registers.
+ *
+ * Relative Addressing
+ * NV40 can use an address register to index into vertex attribute regs.
+ * This is done by putting the offset value into INPUT_SRC and setting
+ * the INDEX_INPUT flag.
+ *
+ * Conditional execution (see NV_vertex_program{2,3} for details)
+ * There is a second condition code register on NV40, it's use is enabled
+ * by setting the COND_REG_SELECT_1 flag.
+ *
+ * Texture lookup
+ * TODO
+ */
+
+/* ---- OPCODE BITS 127:96 / data DWORD 0 --- */
+#define NV40_VP_INST_VEC_RESULT (1 << 30)
+/* uncertain.. */
+#define NV40_VP_INST_COND_UPDATE_ENABLE ((1 << 14)|1<<29)
+/* use address reg as index into attribs */
+#define NV40_VP_INST_INDEX_INPUT (1 << 27)
+#define NV40_VP_INST_COND_REG_SELECT_1 (1 << 25)
+#define NV40_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
+#define NV40_VP_INST_SRC2_ABS (1 << 23)
+#define NV40_VP_INST_SRC1_ABS (1 << 22)
+#define NV40_VP_INST_SRC0_ABS (1 << 21)
+#define NV40_VP_INST_VEC_DEST_TEMP_SHIFT 15
+#define NV40_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 15)
+#define NV40_VP_INST_COND_TEST_ENABLE (1 << 13)
+#define NV40_VP_INST_COND_SHIFT 10
+#define NV40_VP_INST_COND_MASK (0x7 << 10)
+#define NV40_VP_INST_COND_SWZ_X_SHIFT 8
+#define NV40_VP_INST_COND_SWZ_X_MASK (3 << 8)
+#define NV40_VP_INST_COND_SWZ_Y_SHIFT 6
+#define NV40_VP_INST_COND_SWZ_Y_MASK (3 << 6)
+#define NV40_VP_INST_COND_SWZ_Z_SHIFT 4
+#define NV40_VP_INST_COND_SWZ_Z_MASK (3 << 4)
+#define NV40_VP_INST_COND_SWZ_W_SHIFT 2
+#define NV40_VP_INST_COND_SWZ_W_MASK (3 << 2)
+#define NV40_VP_INST_COND_SWZ_ALL_SHIFT 2
+#define NV40_VP_INST_COND_SWZ_ALL_MASK (0xFF << 2)
+#define NV40_VP_INST_ADDR_SWZ_SHIFT 0
+#define NV40_VP_INST_ADDR_SWZ_MASK (0x03 << 0)
+#define NV40_VP_INST0_KNOWN ( \
+ NV40_VP_INST_INDEX_INPUT | \
+ NV40_VP_INST_COND_REG_SELECT_1 | \
+ NV40_VP_INST_ADDR_REG_SELECT_1 | \
+ NV40_VP_INST_SRC2_ABS | \
+ NV40_VP_INST_SRC1_ABS | \
+ NV40_VP_INST_SRC0_ABS | \
+ NV40_VP_INST_VEC_DEST_TEMP_MASK | \
+ NV40_VP_INST_COND_TEST_ENABLE | \
+ NV40_VP_INST_COND_MASK | \
+ NV40_VP_INST_COND_SWZ_ALL_MASK | \
+ NV40_VP_INST_ADDR_SWZ_MASK)
+
+/* ---- OPCODE BITS 95:64 / data DWORD 1 --- */
+#define NV40_VP_INST_VEC_OPCODE_SHIFT 22
+#define NV40_VP_INST_VEC_OPCODE_MASK (0x1F << 22)
+#define NV40_VP_INST_SCA_OPCODE_SHIFT 27
+#define NV40_VP_INST_SCA_OPCODE_MASK (0x1F << 27)
+#define NV40_VP_INST_CONST_SRC_SHIFT 12
+#define NV40_VP_INST_CONST_SRC_MASK (0xFF << 12)
+#define NV40_VP_INST_INPUT_SRC_SHIFT 8
+#define NV40_VP_INST_INPUT_SRC_MASK (0x0F << 8)
+#define NV40_VP_INST_SRC0H_SHIFT 0
+#define NV40_VP_INST_SRC0H_MASK (0xFF << 0)
+#define NV40_VP_INST1_KNOWN ( \
+ NV40_VP_INST_VEC_OPCODE_MASK | \
+ NV40_VP_INST_SCA_OPCODE_MASK | \
+ NV40_VP_INST_CONST_SRC_MASK | \
+ NV40_VP_INST_INPUT_SRC_MASK | \
+ NV40_VP_INST_SRC0H_MASK \
+ )
+
+/* ---- OPCODE BITS 63:32 / data DWORD 2 --- */
+#define NV40_VP_INST_SRC0L_SHIFT 23
+#define NV40_VP_INST_SRC0L_MASK (0x1FF << 23)
+#define NV40_VP_INST_SRC1_SHIFT 6
+#define NV40_VP_INST_SRC1_MASK (0x1FFFF << 6)
+#define NV40_VP_INST_SRC2H_SHIFT 0
+#define NV40_VP_INST_SRC2H_MASK (0x3F << 0)
+#define NV40_VP_INST_IADDRH_SHIFT 0
+#define NV40_VP_INST_IADDRH_MASK (0x1F << 0)
+
+/* ---- OPCODE BITS 31:0 / data DWORD 3 --- */
+#define NV40_VP_INST_IADDRL_SHIFT 29
+#define NV40_VP_INST_IADDRL_MASK (7 << 29)
+#define NV40_VP_INST_SRC2L_SHIFT 21
+#define NV40_VP_INST_SRC2L_MASK (0x7FF << 21)
+#define NV40_VP_INST_SCA_WRITEMASK_SHIFT 17
+#define NV40_VP_INST_SCA_WRITEMASK_MASK (0xF << 17)
+# define NV40_VP_INST_SCA_WRITEMASK_X (1 << 20)
+# define NV40_VP_INST_SCA_WRITEMASK_Y (1 << 19)
+# define NV40_VP_INST_SCA_WRITEMASK_Z (1 << 18)
+# define NV40_VP_INST_SCA_WRITEMASK_W (1 << 17)
+#define NV40_VP_INST_VEC_WRITEMASK_SHIFT 13
+#define NV40_VP_INST_VEC_WRITEMASK_MASK (0xF << 13)
+# define NV40_VP_INST_VEC_WRITEMASK_X (1 << 16)
+# define NV40_VP_INST_VEC_WRITEMASK_Y (1 << 15)
+# define NV40_VP_INST_VEC_WRITEMASK_Z (1 << 14)
+# define NV40_VP_INST_VEC_WRITEMASK_W (1 << 13)
+#define NV40_VP_INST_SCA_RESULT (1 << 12)
+#define NV40_VP_INST_SCA_DEST_TEMP_SHIFT 7
+#define NV40_VP_INST_SCA_DEST_TEMP_MASK (0x1F << 7)
+#define NV40_VP_INST_DEST_SHIFT 2
+#define NV40_VP_INST_DEST_MASK (31 << 2)
+# define NV40_VP_INST_DEST_POS 0
+# define NV40_VP_INST_DEST_COL0 1
+# define NV40_VP_INST_DEST_COL1 2
+# define NV40_VP_INST_DEST_BFC0 3
+# define NV40_VP_INST_DEST_BFC1 4
+# define NV40_VP_INST_DEST_FOGC 5
+# define NV40_VP_INST_DEST_PSZ 6
+# define NV40_VP_INST_DEST_TC0 7
+# define NV40_VP_INST_DEST_TC(n) (7+n)
+# define NV40_VP_INST_DEST_TEMP 0x1F
+#define NV40_VP_INST_INDEX_CONST (1 << 1)
+#define NV40_VP_INST3_KNOWN ( \
+ NV40_VP_INST_SRC2L_MASK |\
+ NV40_VP_INST_SCA_WRITEMASK_MASK |\
+ NV40_VP_INST_VEC_WRITEMASK_MASK |\
+ NV40_VP_INST_SCA_DEST_TEMP_MASK |\
+ NV40_VP_INST_DEST_MASK |\
+ NV40_VP_INST_INDEX_CONST)
+
+/* Useful to split the source selection regs into their pieces */
+#define NV40_VP_SRC0_HIGH_SHIFT 9
+#define NV40_VP_SRC0_HIGH_MASK 0x0001FE00
+#define NV40_VP_SRC0_LOW_MASK 0x000001FF
+#define NV40_VP_SRC2_HIGH_SHIFT 11
+#define NV40_VP_SRC2_HIGH_MASK 0x0001F800
+#define NV40_VP_SRC2_LOW_MASK 0x000007FF
+
+/* Source selection - these are the bits you fill NV40_VP_INST_SRCn with */
+#define NV40_VP_SRC_NEGATE (1 << 16)
+#define NV40_VP_SRC_SWZ_X_SHIFT 14
+#define NV40_VP_SRC_SWZ_X_MASK (3 << 14)
+#define NV40_VP_SRC_SWZ_Y_SHIFT 12
+#define NV40_VP_SRC_SWZ_Y_MASK (3 << 12)
+#define NV40_VP_SRC_SWZ_Z_SHIFT 10
+#define NV40_VP_SRC_SWZ_Z_MASK (3 << 10)
+#define NV40_VP_SRC_SWZ_W_SHIFT 8
+#define NV40_VP_SRC_SWZ_W_MASK (3 << 8)
+#define NV40_VP_SRC_SWZ_ALL_SHIFT 8
+#define NV40_VP_SRC_SWZ_ALL_MASK (0xFF << 8)
+#define NV40_VP_SRC_TEMP_SRC_SHIFT 2
+#define NV40_VP_SRC_TEMP_SRC_MASK (0x1F << 2)
+#define NV40_VP_SRC_REG_TYPE_SHIFT 0
+#define NV40_VP_SRC_REG_TYPE_MASK (3 << 0)
+# define NV40_VP_SRC_REG_TYPE_UNK0 0
+# define NV40_VP_SRC_REG_TYPE_TEMP 1
+# define NV40_VP_SRC_REG_TYPE_INPUT 2
+# define NV40_VP_SRC_REG_TYPE_CONST 3
+
+#include "nvfx_shader.h"
+
+#endif
diff --git a/src/gallium/drivers/nv40/nv40_clear.c b/src/gallium/drivers/nvfx/nvfx_clear.c
index ddf13addf3b..2be70fcee40 100644
--- a/src/gallium/drivers/nv40/nv40_clear.c
+++ b/src/gallium/drivers/nvfx/nvfx_clear.c
@@ -3,12 +3,12 @@
#include "pipe/p_state.h"
#include "util/u_clear.h"
-#include "nv40_context.h"
+#include "nvfx_context.h"
void
-nv40_clear(struct pipe_context *pipe, unsigned buffers,
+nvfx_clear(struct pipe_context *pipe, unsigned buffers,
const float *rgba, double depth, unsigned stencil)
{
- util_clear(pipe, &nv40_context(pipe)->framebuffer, buffers, rgba, depth,
+ util_clear(pipe, &nvfx_context(pipe)->framebuffer, buffers, rgba, depth,
stencil);
}
diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
new file mode 100644
index 00000000000..fc3cbdb558f
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -0,0 +1,90 @@
+#include "draw/draw_context.h"
+#include "pipe/p_defines.h"
+
+#include "nvfx_context.h"
+#include "nvfx_screen.h"
+
+static void
+nvfx_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+
+ 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)
+ *fence = NULL;
+}
+
+static void
+nvfx_destroy(struct pipe_context *pipe)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ unsigned i;
+
+ for (i = 0; i < NVFX_STATE_MAX; i++) {
+ if (nvfx->state.hw[i])
+ so_ref(NULL, &nvfx->state.hw[i]);
+ }
+
+ if (nvfx->draw)
+ draw_destroy(nvfx->draw);
+ FREE(nvfx);
+}
+
+struct pipe_context *
+nvfx_create(struct pipe_screen *pscreen, void *priv)
+{
+ struct nvfx_screen *screen = nvfx_screen(pscreen);
+ struct pipe_winsys *ws = pscreen->winsys;
+ struct nvfx_context *nvfx;
+ struct nouveau_winsys *nvws = screen->nvws;
+
+ nvfx = CALLOC(1, sizeof(struct nvfx_context));
+ if (!nvfx)
+ return NULL;
+ nvfx->screen = screen;
+
+ nvfx->nvws = nvws;
+
+ nvfx->pipe.winsys = ws;
+ nvfx->pipe.screen = pscreen;
+ nvfx->pipe.priv = priv;
+ nvfx->pipe.destroy = nvfx_destroy;
+ nvfx->pipe.draw_arrays = nvfx_draw_arrays;
+ nvfx->pipe.draw_elements = nvfx_draw_elements;
+ nvfx->pipe.clear = nvfx_clear;
+ nvfx->pipe.flush = nvfx_flush;
+
+ nvfx->pipe.is_texture_referenced = nouveau_is_texture_referenced;
+ nvfx->pipe.is_buffer_referenced = nouveau_is_buffer_referenced;
+
+ screen->base.channel->user_private = nvfx;
+ screen->base.channel->flush_notify = nvfx_state_flush_notify;
+
+ nvfx->is_nv4x = screen->is_nv4x;
+
+ nvfx_init_query_functions(nvfx);
+ nvfx_init_surface_functions(nvfx);
+ nvfx_init_state_functions(nvfx);
+ nvfx_init_transfer_functions(nvfx);
+
+ /* Create, configure, and install fallback swtnl path */
+ nvfx->draw = draw_create();
+ draw_wide_point_threshold(nvfx->draw, 9999999.0);
+ draw_wide_line_threshold(nvfx->draw, 9999999.0);
+ draw_enable_line_stipple(nvfx->draw, FALSE);
+ draw_enable_point_sprites(nvfx->draw, FALSE);
+ draw_set_rasterize_stage(nvfx->draw, nvfx_draw_render_stage(nvfx));
+
+ return &nvfx->pipe;
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
new file mode 100644
index 00000000000..ab7225cf6c3
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -0,0 +1,264 @@
+#ifndef __NVFX_CONTEXT_H__
+#define __NVFX_CONTEXT_H__
+
+#include <stdio.h>
+
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "pipe/p_compiler.h"
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_inlines.h"
+
+#include "draw/draw_vertex.h"
+
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_gldefs.h"
+#include "nouveau/nouveau_context.h"
+#include "nouveau/nouveau_stateobj.h"
+
+#include "nvfx_state.h"
+
+#define NOUVEAU_ERR(fmt, args...) \
+ fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
+#define NOUVEAU_MSG(fmt, args...) \
+ fprintf(stderr, "nouveau: "fmt, ##args);
+
+enum nvfx_state_index {
+ NVFX_STATE_FB = 0,
+ NVFX_STATE_VIEWPORT = 1,
+ NVFX_STATE_BLEND = 2,
+ NVFX_STATE_RAST = 3,
+ NVFX_STATE_ZSA = 4,
+ NVFX_STATE_BCOL = 5,
+ NVFX_STATE_CLIP = 6,
+ NVFX_STATE_SCISSOR = 7,
+ NVFX_STATE_STIPPLE = 8,
+ NVFX_STATE_FRAGPROG = 9,
+ NVFX_STATE_VERTPROG = 10,
+ NVFX_STATE_FRAGTEX0 = 11,
+ NVFX_STATE_FRAGTEX1 = 12,
+ NVFX_STATE_FRAGTEX2 = 13,
+ NVFX_STATE_FRAGTEX3 = 14,
+ NVFX_STATE_FRAGTEX4 = 15,
+ NVFX_STATE_FRAGTEX5 = 16,
+ NVFX_STATE_FRAGTEX6 = 17,
+ NVFX_STATE_FRAGTEX7 = 18,
+ NVFX_STATE_FRAGTEX8 = 19,
+ NVFX_STATE_FRAGTEX9 = 20,
+ NVFX_STATE_FRAGTEX10 = 21,
+ NVFX_STATE_FRAGTEX11 = 22,
+ NVFX_STATE_FRAGTEX12 = 23,
+ NVFX_STATE_FRAGTEX13 = 24,
+ NVFX_STATE_FRAGTEX14 = 25,
+ NVFX_STATE_FRAGTEX15 = 26,
+ NVFX_STATE_VERTTEX0 = 27,
+ NVFX_STATE_VERTTEX1 = 28,
+ NVFX_STATE_VERTTEX2 = 29,
+ NVFX_STATE_VERTTEX3 = 30,
+ NVFX_STATE_VTXBUF = 31,
+ NVFX_STATE_VTXFMT = 32,
+ NVFX_STATE_VTXATTR = 33,
+ NVFX_STATE_SR = 34,
+ NVFX_STATE_MAX = 35
+};
+
+#include "nvfx_screen.h"
+
+#define NVFX_NEW_BLEND (1 << 0)
+#define NVFX_NEW_RAST (1 << 1)
+#define NVFX_NEW_ZSA (1 << 2)
+#define NVFX_NEW_SAMPLER (1 << 3)
+#define NVFX_NEW_FB (1 << 4)
+#define NVFX_NEW_STIPPLE (1 << 5)
+#define NVFX_NEW_SCISSOR (1 << 6)
+#define NVFX_NEW_VIEWPORT (1 << 7)
+#define NVFX_NEW_BCOL (1 << 8)
+#define NVFX_NEW_VERTPROG (1 << 9)
+#define NVFX_NEW_FRAGPROG (1 << 10)
+#define NVFX_NEW_ARRAYS (1 << 11)
+#define NVFX_NEW_UCP (1 << 12)
+#define NVFX_NEW_SR (1 << 13)
+
+struct nvfx_rasterizer_state {
+ struct pipe_rasterizer_state pipe;
+ struct nouveau_stateobj *so;
+};
+
+struct nvfx_zsa_state {
+ struct pipe_depth_stencil_alpha_state pipe;
+ struct nouveau_stateobj *so;
+};
+
+struct nvfx_blend_state {
+ struct pipe_blend_state pipe;
+ struct nouveau_stateobj *so;
+};
+
+
+struct nvfx_state {
+ unsigned scissor_enabled;
+ unsigned stipple_enabled;
+ unsigned fp_samplers;
+
+ uint64_t dirty;
+ struct nouveau_stateobj *hw[NVFX_STATE_MAX];
+};
+
+struct nvfx_vtxelt_state {
+ struct pipe_vertex_element pipe[16];
+ unsigned num_elements;
+};
+
+struct nvfx_context {
+ struct pipe_context pipe;
+
+ struct nouveau_winsys *nvws;
+ struct nvfx_screen *screen;
+
+ unsigned is_nv4x; /* either 0 or ~0 */
+
+ struct draw_context *draw;
+
+ /* HW state derived from pipe states */
+ struct nvfx_state state;
+ struct {
+ struct nvfx_vertex_program *vertprog;
+
+ unsigned nr_attribs;
+ unsigned hw[PIPE_MAX_SHADER_INPUTS];
+ unsigned draw[PIPE_MAX_SHADER_INPUTS];
+ unsigned emit[PIPE_MAX_SHADER_INPUTS];
+ } swtnl;
+
+ enum {
+ HW, SWTNL, SWRAST
+ } render_mode;
+ unsigned fallback_swtnl;
+ unsigned fallback_swrast;
+
+ /* Context state */
+ unsigned dirty, draw_dirty;
+ struct pipe_scissor_state scissor;
+ unsigned stipple[32];
+ struct pipe_clip_state clip;
+ struct nvfx_vertex_program *vertprog;
+ struct nvfx_fragment_program *fragprog;
+ struct pipe_buffer *constbuf[PIPE_SHADER_TYPES];
+ unsigned constbuf_nr[PIPE_SHADER_TYPES];
+ struct nvfx_rasterizer_state *rasterizer;
+ struct nvfx_zsa_state *zsa;
+ struct nvfx_blend_state *blend;
+ struct pipe_blend_color blend_colour;
+ struct pipe_stencil_ref stencil_ref;
+ struct pipe_viewport_state viewport;
+ struct pipe_framebuffer_state framebuffer;
+ struct pipe_buffer *idxbuf;
+ unsigned idxbuf_format;
+ struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ unsigned nr_samplers;
+ unsigned nr_textures;
+ unsigned dirty_samplers;
+ struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
+ unsigned vtxbuf_nr;
+ struct nvfx_vtxelt_state *vtxelt;
+};
+
+static INLINE struct nvfx_context *
+nvfx_context(struct pipe_context *pipe)
+{
+ return (struct nvfx_context *)pipe;
+}
+
+struct nvfx_state_entry {
+ boolean (*validate)(struct nvfx_context *nvfx);
+ struct {
+ unsigned pipe;
+ unsigned hw;
+ } dirty;
+};
+
+extern struct nvfx_state_entry nvfx_state_blend;
+extern struct nvfx_state_entry nvfx_state_blend_colour;
+extern struct nvfx_state_entry nvfx_state_fragprog;
+extern struct nvfx_state_entry nvfx_state_fragtex;
+extern struct nvfx_state_entry nvfx_state_framebuffer;
+extern struct nvfx_state_entry nvfx_state_rasterizer;
+extern struct nvfx_state_entry nvfx_state_scissor;
+extern struct nvfx_state_entry nvfx_state_sr;
+extern struct nvfx_state_entry nvfx_state_stipple;
+extern struct nvfx_state_entry nvfx_state_vbo;
+extern struct nvfx_state_entry nvfx_state_vertprog;
+extern struct nvfx_state_entry nvfx_state_viewport;
+extern struct nvfx_state_entry nvfx_state_vtxfmt;
+extern struct nvfx_state_entry nvfx_state_zsa;
+
+extern void nvfx_init_query_functions(struct nvfx_context *nvfx);
+extern void nvfx_init_surface_functions(struct nvfx_context *nvfx);
+
+/* nvfx_context.c */
+struct pipe_context *
+nvfx_create(struct pipe_screen *pscreen, void *priv);
+
+/* nvfx_clear.c */
+extern void nvfx_clear(struct pipe_context *pipe, unsigned buffers,
+ const float *rgba, double depth, unsigned stencil);
+
+/* nvfx_draw.c */
+extern struct draw_stage *nvfx_draw_render_stage(struct nvfx_context *nvfx);
+extern void nvfx_draw_elements_swtnl(struct pipe_context *pipe,
+ struct pipe_buffer *idxbuf,
+ unsigned ib_size, unsigned mode,
+ unsigned start, unsigned count);
+
+/* nvfx_fragprog.c */
+extern void nvfx_fragprog_destroy(struct nvfx_context *,
+ struct nvfx_fragment_program *);
+
+/* nv30_fragtex.c */
+extern void
+nv30_sampler_state_init(struct pipe_context *pipe,
+ struct nvfx_sampler_state *ps,
+ const struct pipe_sampler_state *cso);
+extern void nv30_fragtex_bind(struct nvfx_context *);
+extern struct nouveau_stateobj *
+nv30_fragtex_build(struct nvfx_context *nvfx, int unit);
+
+/* nv40_fragtex.c */
+extern void
+nv40_sampler_state_init(struct pipe_context *pipe,
+ struct nvfx_sampler_state *ps,
+ const struct pipe_sampler_state *cso);
+extern void nv40_fragtex_bind(struct nvfx_context *);
+extern struct nouveau_stateobj *
+nv40_fragtex_build(struct nvfx_context *nvfx, int unit);
+
+/* nvfx_state.c */
+extern void nvfx_init_state_functions(struct nvfx_context *nvfx);
+
+/* nvfx_state_emit.c */
+extern void nvfx_state_flush_notify(struct nouveau_channel *chan);
+extern boolean nvfx_state_validate(struct nvfx_context *nvfx);
+extern boolean nvfx_state_validate_swtnl(struct nvfx_context *nvfx);
+extern void nvfx_state_emit(struct nvfx_context *nvfx);
+
+/* nvfx_transfer.c */
+extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx);
+
+/* nvfx_vbo.c */
+extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode,
+ unsigned start, unsigned count);
+extern void nvfx_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start,
+ unsigned count);
+
+/* nvfx_vertprog.c */
+extern void nvfx_vertprog_destroy(struct nvfx_context *,
+ struct nvfx_vertex_program *);
+
+#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c
new file mode 100644
index 00000000000..68e50a36479
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_draw.c
@@ -0,0 +1,356 @@
+#include "pipe/p_shader_tokens.h"
+#include "util/u_inlines.h"
+#include "tgsi/tgsi_ureg.h"
+
+#include "util/u_pack_color.h"
+
+#include "draw/draw_context.h"
+#include "draw/draw_vertex.h"
+#include "draw/draw_pipe.h"
+
+#include "nvfx_context.h"
+#include "nv30_vertprog.h"
+#include "nv40_vertprog.h"
+
+/* Simple, but crappy, swtnl path, hopefully we wont need to hit this very
+ * often at all. Uses "quadro style" vertex submission + a fixed vertex
+ * layout to avoid the need to generate a vertex program or vtxfmt.
+ */
+
+struct nvfx_render_stage {
+ struct draw_stage stage;
+ struct nvfx_context *nvfx;
+ unsigned prim;
+};
+
+static INLINE struct nvfx_render_stage *
+nvfx_render_stage(struct draw_stage *stage)
+{
+ return (struct nvfx_render_stage *)stage;
+}
+
+static INLINE void
+nvfx_render_vertex(struct nvfx_context *nvfx, const struct vertex_header *v)
+{
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+ unsigned i;
+
+ for (i = 0; i < nvfx->swtnl.nr_attribs; i++) {
+ unsigned idx = nvfx->swtnl.draw[i];
+ unsigned hw = nvfx->swtnl.hw[i];
+
+ switch (nvfx->swtnl.emit[i]) {
+ case EMIT_OMIT:
+ break;
+ case EMIT_1F:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_1F(hw), 1);
+ OUT_RING (chan, fui(v->data[idx][0]));
+ break;
+ case EMIT_2F:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_2F_X(hw), 2);
+ OUT_RING (chan, fui(v->data[idx][0]));
+ OUT_RING (chan, fui(v->data[idx][1]));
+ break;
+ case EMIT_3F:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_3F_X(hw), 3);
+ OUT_RING (chan, fui(v->data[idx][0]));
+ OUT_RING (chan, fui(v->data[idx][1]));
+ OUT_RING (chan, fui(v->data[idx][2]));
+ break;
+ case EMIT_4F:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4F_X(hw), 4);
+ OUT_RING (chan, fui(v->data[idx][0]));
+ OUT_RING (chan, fui(v->data[idx][1]));
+ OUT_RING (chan, fui(v->data[idx][2]));
+ OUT_RING (chan, fui(v->data[idx][3]));
+ break;
+ case 0xff:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4F_X(hw), 4);
+ OUT_RING (chan, fui(v->data[idx][0] / v->data[idx][3]));
+ OUT_RING (chan, fui(v->data[idx][1] / v->data[idx][3]));
+ OUT_RING (chan, fui(v->data[idx][2] / v->data[idx][3]));
+ OUT_RING (chan, fui(1.0f / v->data[idx][3]));
+ break;
+ case EMIT_4UB:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4UB(hw), 1);
+ OUT_RING (chan, pack_ub4(float_to_ubyte(v->data[idx][0]),
+ float_to_ubyte(v->data[idx][1]),
+ float_to_ubyte(v->data[idx][2]),
+ float_to_ubyte(v->data[idx][3])));
+ case EMIT_4UB_BGRA:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4UB(hw), 1);
+ OUT_RING (chan, pack_ub4(float_to_ubyte(v->data[idx][2]),
+ float_to_ubyte(v->data[idx][1]),
+ float_to_ubyte(v->data[idx][0]),
+ float_to_ubyte(v->data[idx][3])));
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+static INLINE void
+nvfx_render_prim(struct draw_stage *stage, struct prim_header *prim,
+ unsigned mode, unsigned count)
+{
+ struct nvfx_render_stage *rs = nvfx_render_stage(stage);
+ struct nvfx_context *nvfx = rs->nvfx;
+
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+ unsigned i;
+
+ /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */
+ if (AVAIL_RING(chan) < ((count * 20) + 6)) {
+ if (rs->prim != NV34TCL_VERTEX_BEGIN_END_STOP) {
+ NOUVEAU_ERR("AIII, missed flush\n");
+ assert(0);
+ }
+ FIRE_RING(chan);
+ nvfx_state_emit(nvfx);
+ }
+
+ /* Switch primitive modes if necessary */
+ if (rs->prim != mode) {
+ if (rs->prim != NV34TCL_VERTEX_BEGIN_END_STOP) {
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+ OUT_RING (chan, NV34TCL_VERTEX_BEGIN_END_STOP);
+ }
+
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+ OUT_RING (chan, mode);
+ rs->prim = mode;
+ }
+
+ /* Emit vertex data */
+ for (i = 0; i < count; i++)
+ nvfx_render_vertex(nvfx, prim->v[i]);
+
+ /* If it's likely we'll need to empty the push buffer soon, finish
+ * off the primitive now.
+ */
+ if (AVAIL_RING(chan) < ((count * 20) + 6)) {
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+ OUT_RING (chan, NV34TCL_VERTEX_BEGIN_END_STOP);
+ rs->prim = NV34TCL_VERTEX_BEGIN_END_STOP;
+ }
+}
+
+static void
+nvfx_render_point(struct draw_stage *draw, struct prim_header *prim)
+{
+ nvfx_render_prim(draw, prim, NV34TCL_VERTEX_BEGIN_END_POINTS, 1);
+}
+
+static void
+nvfx_render_line(struct draw_stage *draw, struct prim_header *prim)
+{
+ nvfx_render_prim(draw, prim, NV34TCL_VERTEX_BEGIN_END_LINES, 2);
+}
+
+static void
+nvfx_render_tri(struct draw_stage *draw, struct prim_header *prim)
+{
+ nvfx_render_prim(draw, prim, NV34TCL_VERTEX_BEGIN_END_TRIANGLES, 3);
+}
+
+static void
+nvfx_render_flush(struct draw_stage *draw, unsigned flags)
+{
+ struct nvfx_render_stage *rs = nvfx_render_stage(draw);
+ struct nvfx_context *nvfx = rs->nvfx;
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+
+ if (rs->prim != NV34TCL_VERTEX_BEGIN_END_STOP) {
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
+ OUT_RING (chan, NV34TCL_VERTEX_BEGIN_END_STOP);
+ rs->prim = NV34TCL_VERTEX_BEGIN_END_STOP;
+ }
+}
+
+static void
+nvfx_render_reset_stipple_counter(struct draw_stage *draw)
+{
+}
+
+static void
+nvfx_render_destroy(struct draw_stage *draw)
+{
+ FREE(draw);
+}
+
+static struct nvfx_vertex_program *
+nvfx_create_drawvp(struct nvfx_context *nvfx)
+{
+ struct ureg_program *ureg;
+ uint i;
+
+ ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
+
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0), ureg_DECL_vs_input(ureg, 0));
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0), ureg_DECL_vs_input(ureg, 3));
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 1), ureg_DECL_vs_input(ureg, 4));
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_BCOLOR, 0), ureg_DECL_vs_input(ureg, 3));
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_BCOLOR, 1), ureg_DECL_vs_input(ureg, 4));
+ ureg_MOV(ureg,
+ ureg_writemask(ureg_DECL_output(ureg, TGSI_SEMANTIC_FOG, 1), TGSI_WRITEMASK_X),
+ ureg_DECL_vs_input(ureg, 5));
+ for (i = 0; i < 8; ++i)
+ ureg_MOV(ureg, ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, i), ureg_DECL_vs_input(ureg, 8 + i));
+
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg, &nvfx->pipe );
+}
+
+struct draw_stage *
+nvfx_draw_render_stage(struct nvfx_context *nvfx)
+{
+ struct nvfx_render_stage *render = CALLOC_STRUCT(nvfx_render_stage);
+
+ if (!nvfx->swtnl.vertprog)
+ nvfx->swtnl.vertprog = nvfx_create_drawvp(nvfx);
+
+ render->nvfx = nvfx;
+ render->stage.draw = nvfx->draw;
+ render->stage.point = nvfx_render_point;
+ render->stage.line = nvfx_render_line;
+ render->stage.tri = nvfx_render_tri;
+ render->stage.flush = nvfx_render_flush;
+ render->stage.reset_stipple_counter = nvfx_render_reset_stipple_counter;
+ render->stage.destroy = nvfx_render_destroy;
+
+ return &render->stage;
+}
+
+void
+nvfx_draw_elements_swtnl(struct pipe_context *pipe,
+ struct pipe_buffer *idxbuf, unsigned idxbuf_size,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct pipe_screen *pscreen = pipe->screen;
+ unsigned i;
+ void *map;
+
+ if (!nvfx_state_validate_swtnl(nvfx))
+ return;
+ nvfx->state.dirty &= ~(1ULL << NVFX_STATE_VTXBUF);
+ nvfx_state_emit(nvfx);
+
+ for (i = 0; i < nvfx->vtxbuf_nr; i++) {
+ map = pipe_buffer_map(pscreen, nvfx->vtxbuf[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_vertex_buffer(nvfx->draw, i, map);
+ }
+
+ if (idxbuf) {
+ map = pipe_buffer_map(pscreen, idxbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_element_buffer(nvfx->draw, idxbuf_size, map);
+ } else {
+ draw_set_mapped_element_buffer(nvfx->draw, 0, NULL);
+ }
+
+ if (nvfx->constbuf[PIPE_SHADER_VERTEX]) {
+ const unsigned nr = nvfx->constbuf_nr[PIPE_SHADER_VERTEX];
+
+ map = pipe_buffer_map(pscreen,
+ nvfx->constbuf[PIPE_SHADER_VERTEX],
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_constant_buffer(nvfx->draw, PIPE_SHADER_VERTEX, 0,
+ map, nr);
+ }
+
+ draw_arrays(nvfx->draw, mode, start, count);
+
+ for (i = 0; i < nvfx->vtxbuf_nr; i++)
+ pipe_buffer_unmap(pscreen, nvfx->vtxbuf[i].buffer);
+
+ if (idxbuf)
+ pipe_buffer_unmap(pscreen, idxbuf);
+
+ if (nvfx->constbuf[PIPE_SHADER_VERTEX])
+ pipe_buffer_unmap(pscreen, nvfx->constbuf[PIPE_SHADER_VERTEX]);
+
+ draw_flush(nvfx->draw);
+ pipe->flush(pipe, 0, NULL);
+}
+
+static INLINE void
+emit_attrib(struct nvfx_context *nvfx, unsigned hw, unsigned emit,
+ unsigned semantic, unsigned index)
+{
+ unsigned draw_out = draw_find_shader_output(nvfx->draw, semantic, index);
+ unsigned a = nvfx->swtnl.nr_attribs++;
+
+ nvfx->swtnl.hw[a] = hw;
+ nvfx->swtnl.emit[a] = emit;
+ nvfx->swtnl.draw[a] = draw_out;
+}
+
+static boolean
+nvfx_state_vtxfmt_validate(struct nvfx_context *nvfx)
+{
+ struct nvfx_fragment_program *fp = nvfx->fragprog;
+ unsigned colour = 0, texcoords = 0, fog = 0, i;
+
+ /* Determine needed fragprog inputs */
+ for (i = 0; i < fp->info.num_inputs; i++) {
+ switch (fp->info.input_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ colour |= (1 << fp->info.input_semantic_index[i]);
+ break;
+ case TGSI_SEMANTIC_GENERIC:
+ texcoords |= (1 << fp->info.input_semantic_index[i]);
+ break;
+ case TGSI_SEMANTIC_FOG:
+ fog = 1;
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ nvfx->swtnl.nr_attribs = 0;
+
+ /* Map draw vtxprog output to hw attribute IDs */
+ for (i = 0; i < 2; i++) {
+ if (!(colour & (1 << i)))
+ continue;
+ emit_attrib(nvfx, 3 + i, EMIT_4F, TGSI_SEMANTIC_COLOR, i);
+ }
+
+ for (i = 0; i < 8; i++) {
+ if (!(texcoords & (1 << i)))
+ continue;
+ emit_attrib(nvfx, 8 + i, EMIT_4F, TGSI_SEMANTIC_GENERIC, i);
+ }
+
+ if (fog) {
+ emit_attrib(nvfx, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0);
+ }
+
+ emit_attrib(nvfx, 0, 0xff, TGSI_SEMANTIC_POSITION, 0);
+
+ return FALSE;
+}
+
+struct nvfx_state_entry nvfx_state_vtxfmt = {
+ .validate = nvfx_state_vtxfmt_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_ARRAYS | NVFX_NEW_FRAGPROG,
+ .hw = 0
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index dc24f9b08a5..b9c91cec8ce 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -7,37 +7,20 @@
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
-#include "nv40_context.h"
-
-#define SWZ_X 0
-#define SWZ_Y 1
-#define SWZ_Z 2
-#define SWZ_W 3
-#define MASK_X 1
-#define MASK_Y 2
-#define MASK_Z 4
-#define MASK_W 8
-#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W)
-#define DEF_SCALE NV40_FP_OP_DST_SCALE_1X
-#define DEF_CTEST NV40_FP_OP_COND_TR
-#include "nv40_shader.h"
-
-#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w)
-#define neg(s) nv40_sr_neg((s))
-#define abs(s) nv40_sr_abs((s))
-#define scale(s,v) nv40_sr_scale((s), NV40_FP_OP_DST_SCALE_##v)
+#include "nvfx_context.h"
+#include "nvfx_shader.h"
#define MAX_CONSTS 128
#define MAX_IMM 32
-struct nv40_fpc {
- struct nv40_fragment_program *fp;
+struct nvfx_fpc {
+ struct nvfx_fragment_program *fp;
uint attrib_map[PIPE_MAX_SHADER_INPUTS];
unsigned r_temps;
unsigned r_temps_discard;
- struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS];
- struct nv40_sreg *r_temp;
+ struct nvfx_sreg r_result[PIPE_MAX_SHADER_OUTPUTS];
+ struct nvfx_sreg *r_temp;
int num_regs;
@@ -50,35 +33,35 @@ struct nv40_fpc {
} consts[MAX_CONSTS];
int nr_consts;
- struct nv40_sreg imm[MAX_IMM];
+ struct nvfx_sreg imm[MAX_IMM];
unsigned nr_imm;
};
-static INLINE struct nv40_sreg
-temp(struct nv40_fpc *fpc)
+static INLINE struct nvfx_sreg
+temp(struct nvfx_fpc *fpc)
{
int idx = ffs(~fpc->r_temps) - 1;
if (idx < 0) {
NOUVEAU_ERR("out of temps!!\n");
assert(0);
- return nv40_sr(NV40SR_TEMP, 0);
+ return nvfx_sr(NVFXSR_TEMP, 0);
}
fpc->r_temps |= (1 << idx);
fpc->r_temps_discard |= (1 << idx);
- return nv40_sr(NV40SR_TEMP, idx);
+ return nvfx_sr(NVFXSR_TEMP, idx);
}
static INLINE void
-release_temps(struct nv40_fpc *fpc)
+release_temps(struct nvfx_fpc *fpc)
{
fpc->r_temps &= ~fpc->r_temps_discard;
fpc->r_temps_discard = 0;
}
-static INLINE struct nv40_sreg
-constant(struct nv40_fpc *fpc, int pipe, float vals[4])
+static INLINE struct nvfx_sreg
+constant(struct nvfx_fpc *fpc, int pipe, float vals[4])
{
int idx;
@@ -89,45 +72,45 @@ constant(struct nv40_fpc *fpc, int pipe, float vals[4])
fpc->consts[idx].pipe = pipe;
if (pipe == -1)
memcpy(fpc->consts[idx].vals, vals, 4 * sizeof(float));
- return nv40_sr(NV40SR_CONST, idx);
+ return nvfx_sr(NVFXSR_CONST, idx);
}
#define arith(cc,s,o,d,m,s0,s1,s2) \
- nv40_fp_arith((cc), (s), NV40_FP_OP_OPCODE_##o, \
+ nvfx_fp_arith((cc), (s), NVFX_FP_OP_OPCODE_##o, \
(d), (m), (s0), (s1), (s2))
#define tex(cc,s,o,u,d,m,s0,s1,s2) \
- nv40_fp_tex((cc), (s), NV40_FP_OP_OPCODE_##o, (u), \
+ nvfx_fp_tex((cc), (s), NVFX_FP_OP_OPCODE_##o, (u), \
(d), (m), (s0), none, none)
static void
-grow_insns(struct nv40_fpc *fpc, int size)
+grow_insns(struct nvfx_fpc *fpc, int size)
{
- struct nv40_fragment_program *fp = fpc->fp;
+ struct nvfx_fragment_program *fp = fpc->fp;
fp->insn_len += size;
fp->insn = realloc(fp->insn, sizeof(uint32_t) * fp->insn_len);
}
static void
-emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src)
+emit_src(struct nvfx_fpc *fpc, int pos, struct nvfx_sreg src)
{
- struct nv40_fragment_program *fp = fpc->fp;
+ struct nvfx_fragment_program *fp = fpc->fp;
uint32_t *hw = &fp->insn[fpc->inst_offset];
uint32_t sr = 0;
switch (src.type) {
- case NV40SR_INPUT:
- sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT);
- hw[0] |= (src.index << NV40_FP_OP_INPUT_SRC_SHIFT);
+ case NVFXSR_INPUT:
+ sr |= (NVFX_FP_REG_TYPE_INPUT << NVFX_FP_REG_TYPE_SHIFT);
+ hw[0] |= (src.index << NVFX_FP_OP_INPUT_SRC_SHIFT);
break;
- case NV40SR_OUTPUT:
- sr |= NV40_FP_REG_SRC_HALF;
+ case NVFXSR_OUTPUT:
+ sr |= NVFX_FP_REG_SRC_HALF;
/* fall-through */
- case NV40SR_TEMP:
- sr |= (NV40_FP_REG_TYPE_TEMP << NV40_FP_REG_TYPE_SHIFT);
- sr |= (src.index << NV40_FP_REG_SRC_SHIFT);
+ case NVFXSR_TEMP:
+ sr |= (NVFX_FP_REG_TYPE_TEMP << NVFX_FP_REG_TYPE_SHIFT);
+ sr |= (src.index << NVFX_FP_REG_SRC_SHIFT);
break;
- case NV40SR_CONST:
+ case NVFXSR_CONST:
if (!fpc->have_const) {
grow_insns(fpc, 4);
fpc->have_const = 1;
@@ -135,7 +118,7 @@ emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src)
hw = &fp->insn[fpc->inst_offset];
if (fpc->consts[src.index].pipe >= 0) {
- struct nv40_fragment_program_data *fpd;
+ struct nvfx_fragment_program_data *fpd;
fp->consts = realloc(fp->consts, ++fp->nr_consts *
sizeof(*fpd));
@@ -149,63 +132,63 @@ emit_src(struct nv40_fpc *fpc, int pos, struct nv40_sreg src)
sizeof(uint32_t) * 4);
}
- sr |= (NV40_FP_REG_TYPE_CONST << NV40_FP_REG_TYPE_SHIFT);
+ sr |= (NVFX_FP_REG_TYPE_CONST << NVFX_FP_REG_TYPE_SHIFT);
break;
- case NV40SR_NONE:
- sr |= (NV40_FP_REG_TYPE_INPUT << NV40_FP_REG_TYPE_SHIFT);
+ case NVFXSR_NONE:
+ sr |= (NVFX_FP_REG_TYPE_INPUT << NVFX_FP_REG_TYPE_SHIFT);
break;
default:
assert(0);
}
if (src.negate)
- sr |= NV40_FP_REG_NEGATE;
+ sr |= NVFX_FP_REG_NEGATE;
if (src.abs)
hw[1] |= (1 << (29 + pos));
- sr |= ((src.swz[0] << NV40_FP_REG_SWZ_X_SHIFT) |
- (src.swz[1] << NV40_FP_REG_SWZ_Y_SHIFT) |
- (src.swz[2] << NV40_FP_REG_SWZ_Z_SHIFT) |
- (src.swz[3] << NV40_FP_REG_SWZ_W_SHIFT));
+ sr |= ((src.swz[0] << NVFX_FP_REG_SWZ_X_SHIFT) |
+ (src.swz[1] << NVFX_FP_REG_SWZ_Y_SHIFT) |
+ (src.swz[2] << NVFX_FP_REG_SWZ_Z_SHIFT) |
+ (src.swz[3] << NVFX_FP_REG_SWZ_W_SHIFT));
hw[pos + 1] |= sr;
}
static void
-emit_dst(struct nv40_fpc *fpc, struct nv40_sreg dst)
+emit_dst(struct nvfx_fpc *fpc, struct nvfx_sreg dst)
{
- struct nv40_fragment_program *fp = fpc->fp;
+ struct nvfx_fragment_program *fp = fpc->fp;
uint32_t *hw = &fp->insn[fpc->inst_offset];
switch (dst.type) {
- case NV40SR_TEMP:
+ case NVFXSR_TEMP:
if (fpc->num_regs < (dst.index + 1))
fpc->num_regs = dst.index + 1;
break;
- case NV40SR_OUTPUT:
+ case NVFXSR_OUTPUT:
if (dst.index == 1) {
fp->fp_control |= 0xe;
} else {
- hw[0] |= NV40_FP_OP_OUT_REG_HALF;
+ hw[0] |= NVFX_FP_OP_OUT_REG_HALF;
}
break;
- case NV40SR_NONE:
+ case NVFXSR_NONE:
hw[0] |= (1 << 30);
break;
default:
assert(0);
}
- hw[0] |= (dst.index << NV40_FP_OP_OUT_REG_SHIFT);
+ hw[0] |= (dst.index << NVFX_FP_OP_OUT_REG_SHIFT);
}
static void
-nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op,
- struct nv40_sreg dst, int mask,
- struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2)
+nvfx_fp_arith(struct nvfx_fpc *fpc, int sat, int op,
+ struct nvfx_sreg dst, int mask,
+ struct nvfx_sreg s0, struct nvfx_sreg s1, struct nvfx_sreg s2)
{
- struct nv40_fragment_program *fp = fpc->fp;
+ struct nvfx_fragment_program *fp = fpc->fp;
uint32_t *hw;
fpc->inst_offset = fp->insn_len;
@@ -214,22 +197,22 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op,
hw = &fp->insn[fpc->inst_offset];
memset(hw, 0, sizeof(uint32_t) * 4);
- if (op == NV40_FP_OP_OPCODE_KIL)
- fp->fp_control |= NV40TCL_FP_CONTROL_KIL;
- hw[0] |= (op << NV40_FP_OP_OPCODE_SHIFT);
- hw[0] |= (mask << NV40_FP_OP_OUTMASK_SHIFT);
- hw[2] |= (dst.dst_scale << NV40_FP_OP_DST_SCALE_SHIFT);
+ if (op == NVFX_FP_OP_OPCODE_KIL)
+ fp->fp_control |= NV34TCL_FP_CONTROL_USES_KIL;
+ hw[0] |= (op << NVFX_FP_OP_OPCODE_SHIFT);
+ hw[0] |= (mask << NVFX_FP_OP_OUTMASK_SHIFT);
+ hw[2] |= (dst.dst_scale << NVFX_FP_OP_DST_SCALE_SHIFT);
if (sat)
- hw[0] |= NV40_FP_OP_OUT_SAT;
+ hw[0] |= NVFX_FP_OP_OUT_SAT;
if (dst.cc_update)
- hw[0] |= NV40_FP_OP_COND_WRITE_ENABLE;
- hw[1] |= (dst.cc_test << NV40_FP_OP_COND_SHIFT);
- hw[1] |= ((dst.cc_swz[0] << NV40_FP_OP_COND_SWZ_X_SHIFT) |
- (dst.cc_swz[1] << NV40_FP_OP_COND_SWZ_Y_SHIFT) |
- (dst.cc_swz[2] << NV40_FP_OP_COND_SWZ_Z_SHIFT) |
- (dst.cc_swz[3] << NV40_FP_OP_COND_SWZ_W_SHIFT));
+ hw[0] |= NVFX_FP_OP_COND_WRITE_ENABLE;
+ hw[1] |= (dst.cc_test << NVFX_FP_OP_COND_SHIFT);
+ hw[1] |= ((dst.cc_swz[0] << NVFX_FP_OP_COND_SWZ_X_SHIFT) |
+ (dst.cc_swz[1] << NVFX_FP_OP_COND_SWZ_Y_SHIFT) |
+ (dst.cc_swz[2] << NVFX_FP_OP_COND_SWZ_Z_SHIFT) |
+ (dst.cc_swz[3] << NVFX_FP_OP_COND_SWZ_W_SHIFT));
emit_dst(fpc, dst);
emit_src(fpc, 0, s0);
@@ -238,26 +221,26 @@ nv40_fp_arith(struct nv40_fpc *fpc, int sat, int op,
}
static void
-nv40_fp_tex(struct nv40_fpc *fpc, int sat, int op, int unit,
- struct nv40_sreg dst, int mask,
- struct nv40_sreg s0, struct nv40_sreg s1, struct nv40_sreg s2)
+nvfx_fp_tex(struct nvfx_fpc *fpc, int sat, int op, int unit,
+ struct nvfx_sreg dst, int mask,
+ struct nvfx_sreg s0, struct nvfx_sreg s1, struct nvfx_sreg s2)
{
- struct nv40_fragment_program *fp = fpc->fp;
+ struct nvfx_fragment_program *fp = fpc->fp;
- nv40_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2);
+ nvfx_fp_arith(fpc, sat, op, dst, mask, s0, s1, s2);
- fp->insn[fpc->inst_offset] |= (unit << NV40_FP_OP_TEX_UNIT_SHIFT);
+ fp->insn[fpc->inst_offset] |= (unit << NVFX_FP_OP_TEX_UNIT_SHIFT);
fp->samplers |= (1 << unit);
}
-static INLINE struct nv40_sreg
-tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc)
+static INLINE struct nvfx_sreg
+tgsi_src(struct nvfx_fpc *fpc, const struct tgsi_full_src_register *fsrc)
{
- struct nv40_sreg src;
+ struct nvfx_sreg src;
switch (fsrc->Register.File) {
case TGSI_FILE_INPUT:
- src = nv40_sr(NV40SR_INPUT,
+ src = nvfx_sr(NVFXSR_INPUT,
fpc->attrib_map[fsrc->Register.Index]);
break;
case TGSI_FILE_CONSTANT:
@@ -288,18 +271,18 @@ tgsi_src(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc)
return src;
}
-static INLINE struct nv40_sreg
-tgsi_dst(struct nv40_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
+static INLINE struct nvfx_sreg
+tgsi_dst(struct nvfx_fpc *fpc, const struct tgsi_full_dst_register *fdst) {
switch (fdst->Register.File) {
case TGSI_FILE_OUTPUT:
return fpc->r_result[fdst->Register.Index];
case TGSI_FILE_TEMPORARY:
return fpc->r_temp[fdst->Register.Index];
case TGSI_FILE_NULL:
- return nv40_sr(NV40SR_NONE, 0);
+ return nvfx_sr(NVFXSR_NONE, 0);
default:
NOUVEAU_ERR("bad dst file %d\n", fdst->Register.File);
- return nv40_sr(NV40SR_NONE, 0);
+ return nvfx_sr(NVFXSR_NONE, 0);
}
}
@@ -308,52 +291,19 @@ tgsi_mask(uint tgsi)
{
int mask = 0;
- if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X;
- if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y;
- if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z;
- if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W;
+ if (tgsi & TGSI_WRITEMASK_X) mask |= NVFX_FP_MASK_X;
+ if (tgsi & TGSI_WRITEMASK_Y) mask |= NVFX_FP_MASK_Y;
+ if (tgsi & TGSI_WRITEMASK_Z) mask |= NVFX_FP_MASK_Z;
+ if (tgsi & TGSI_WRITEMASK_W) mask |= NVFX_FP_MASK_W;
return mask;
}
static boolean
-src_native_swz(struct nv40_fpc *fpc, const struct tgsi_full_src_register *fsrc,
- struct nv40_sreg *src)
-{
- const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0);
- struct nv40_sreg tgsi = tgsi_src(fpc, fsrc);
- uint mask = 0;
- uint c;
-
- for (c = 0; c < 4; c++) {
- switch (tgsi_util_get_full_src_register_swizzle(fsrc, c)) {
- case TGSI_SWIZZLE_X:
- case TGSI_SWIZZLE_Y:
- case TGSI_SWIZZLE_Z:
- case TGSI_SWIZZLE_W:
- mask |= (1 << c);
- break;
- default:
- assert(0);
- }
- }
-
- if (mask == MASK_ALL)
- return TRUE;
-
- *src = temp(fpc);
-
- if (mask)
- arith(fpc, 0, MOV, *src, mask, tgsi, none, none);
-
- return FALSE;
-}
-
-static boolean
-nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
+nvfx_fragprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_fpc *fpc,
const struct tgsi_full_instruction *finst)
{
- const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0);
- struct nv40_sreg src[3], dst, tmp;
+ const struct nvfx_sreg none = nvfx_sr(NVFXSR_NONE, 0);
+ struct nvfx_sreg src[3], dst, tmp;
int mask, sat, unit;
int ai = -1, ci = -1, ii = -1;
int i;
@@ -377,23 +327,12 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
switch (fsrc->Register.File) {
case TGSI_FILE_INPUT:
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_TEMPORARY:
- if (!src_native_swz(fpc, fsrc, &src[i]))
- continue;
- break;
- default:
- break;
- }
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
if (ai == -1 || ai == fsrc->Register.Index) {
ai = fsrc->Register.Index;
src[i] = tgsi_src(fpc, fsrc);
} else {
src[i] = temp(fpc);
- arith(fpc, 0, MOV, src[i], MASK_ALL,
+ arith(fpc, 0, MOV, src[i], NVFX_FP_MASK_ALL,
tgsi_src(fpc, fsrc), none, none);
}
break;
@@ -404,7 +343,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
src[i] = tgsi_src(fpc, fsrc);
} else {
src[i] = temp(fpc);
- arith(fpc, 0, MOV, src[i], MASK_ALL,
+ arith(fpc, 0, MOV, src[i], NVFX_FP_MASK_ALL,
tgsi_src(fpc, fsrc), none, none);
}
break;
@@ -415,7 +354,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
src[i] = tgsi_src(fpc, fsrc);
} else {
src[i] = temp(fpc);
- arith(fpc, 0, MOV, src[i], MASK_ALL,
+ arith(fpc, 0, MOV, src[i], NVFX_FP_MASK_ALL,
tgsi_src(fpc, fsrc), none, none);
}
break;
@@ -445,25 +384,25 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
arith(fpc, sat, ADD, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_CMP:
- tmp = nv40_sr(NV40SR_NONE, 0);
+ tmp = nvfx_sr(NVFXSR_NONE, 0);
tmp.cc_update = 1;
arith(fpc, 0, MOV, tmp, 0xf, src[0], none, none);
- dst.cc_test = NV40_VP_INST_COND_GE;
+ dst.cc_test = NVFX_COND_GE;
arith(fpc, sat, MOV, dst, mask, src[2], none, none);
- dst.cc_test = NV40_VP_INST_COND_LT;
+ dst.cc_test = NVFX_COND_LT;
arith(fpc, sat, MOV, dst, mask, src[1], none, none);
break;
case TGSI_OPCODE_COS:
arith(fpc, sat, COS, dst, mask, src[0], none, none);
break;
case TGSI_OPCODE_DDX:
- if (mask & (MASK_Z | MASK_W)) {
+ if (mask & (NVFX_FP_MASK_Z | NVFX_FP_MASK_W)) {
tmp = temp(fpc);
- arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y,
+ arith(fpc, sat, DDX, tmp, NVFX_FP_MASK_X | NVFX_FP_MASK_Y,
swz(src[0], Z, W, Z, W), none, none);
- arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W,
+ arith(fpc, 0, MOV, tmp, NVFX_FP_MASK_Z | NVFX_FP_MASK_W,
swz(tmp, X, Y, X, Y), none, none);
- arith(fpc, sat, DDX, tmp, MASK_X | MASK_Y, src[0],
+ arith(fpc, sat, DDX, tmp, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, src[0],
none, none);
arith(fpc, 0, MOV, dst, mask, tmp, none, none);
} else {
@@ -471,13 +410,13 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
}
break;
case TGSI_OPCODE_DDY:
- if (mask & (MASK_Z | MASK_W)) {
+ if (mask & (NVFX_FP_MASK_Z | NVFX_FP_MASK_W)) {
tmp = temp(fpc);
- arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y,
+ arith(fpc, sat, DDY, tmp, NVFX_FP_MASK_X | NVFX_FP_MASK_Y,
swz(src[0], Z, W, Z, W), none, none);
- arith(fpc, 0, MOV, tmp, MASK_Z | MASK_W,
+ arith(fpc, 0, MOV, tmp, NVFX_FP_MASK_Z | NVFX_FP_MASK_W,
swz(tmp, X, Y, X, Y), none, none);
- arith(fpc, sat, DDY, tmp, MASK_X | MASK_Y, src[0],
+ arith(fpc, sat, DDY, tmp, NVFX_FP_MASK_X | NVFX_FP_MASK_Y, src[0],
none, none);
arith(fpc, 0, MOV, dst, mask, tmp, none, none);
} else {
@@ -492,7 +431,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
break;
case TGSI_OPCODE_DPH:
tmp = temp(fpc);
- arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[1], none);
+ arith(fpc, 0, DP3, tmp, NVFX_FP_MASK_X, src[0], src[1], none);
arith(fpc, sat, ADD, dst, mask, swz(tmp, X, X, X, X),
swz(src[1], W, W, W, W), none);
break;
@@ -512,10 +451,10 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
arith(fpc, 0, KIL, none, 0, none, none, none);
break;
case TGSI_OPCODE_KIL:
- dst = nv40_sr(NV40SR_NONE, 0);
+ dst = nvfx_sr(NVFXSR_NONE, 0);
dst.cc_update = 1;
- arith(fpc, 0, MOV, dst, MASK_ALL, src[0], none, none);
- dst.cc_update = 0; dst.cc_test = NV40_FP_OP_COND_LT;
+ arith(fpc, 0, MOV, dst, NVFX_FP_MASK_ALL, src[0], none, none);
+ dst.cc_update = 0; dst.cc_test = NVFX_COND_LT;
arith(fpc, 0, KIL, dst, 0, none, none, none);
break;
case TGSI_OPCODE_LG2:
@@ -523,9 +462,13 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
break;
// case TGSI_OPCODE_LIT:
case TGSI_OPCODE_LRP:
- tmp = temp(fpc);
- arith(fpc, 0, MAD, tmp, mask, neg(src[0]), src[2], src[2]);
- arith(fpc, sat, MAD, dst, mask, src[0], src[1], tmp);
+ if(!nvfx->is_nv4x)
+ arith(fpc, sat, LRP_NV30, dst, mask, src[0], src[1], src[2]);
+ else {
+ tmp = temp(fpc);
+ arith(fpc, 0, MAD, tmp, mask, neg(src[0]), src[2], src[2]);
+ arith(fpc, sat, MAD, dst, mask, src[0], src[1], tmp);
+ }
break;
case TGSI_OPCODE_MAD:
arith(fpc, sat, MAD, dst, mask, src[0], src[1], src[2]);
@@ -543,13 +486,17 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
arith(fpc, sat, MUL, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_POW:
- tmp = temp(fpc);
- arith(fpc, 0, LG2, tmp, MASK_X,
- swz(src[0], X, X, X, X), none, none);
- arith(fpc, 0, MUL, tmp, MASK_X, swz(tmp, X, X, X, X),
- swz(src[1], X, X, X, X), none);
- arith(fpc, sat, EX2, dst, mask,
- swz(tmp, X, X, X, X), none, none);
+ if(!nvfx->is_nv4x)
+ arith(fpc, sat, POW_NV30, dst, mask, src[0], src[1], none);
+ else {
+ tmp = temp(fpc);
+ arith(fpc, 0, LG2, tmp, NVFX_FP_MASK_X,
+ swz(src[0], X, X, X, X), none, none);
+ arith(fpc, 0, MUL, tmp, NVFX_FP_MASK_X, swz(tmp, X, X, X, X),
+ swz(src[1], X, X, X, X), none);
+ arith(fpc, sat, EX2, dst, mask,
+ swz(tmp, X, X, X, X), none, none);
+ }
break;
case TGSI_OPCODE_RCP:
arith(fpc, sat, RCP, dst, mask, src[0], none, none);
@@ -558,42 +505,50 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
assert(0);
break;
case TGSI_OPCODE_RFL:
- tmp = temp(fpc);
- arith(fpc, 0, DP3, tmp, MASK_X, src[0], src[0], none);
- arith(fpc, 0, DP3, tmp, MASK_Y, src[0], src[1], none);
- arith(fpc, 0, DIV, scale(tmp, 2X), MASK_Z,
- swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none);
- arith(fpc, sat, MAD, dst, mask,
- swz(tmp, Z, Z, Z, Z), src[0], neg(src[1]));
+ if(!nvfx->is_nv4x)
+ arith(fpc, 0, RFL_NV30, dst, mask, src[0], src[1], none);
+ else {
+ tmp = temp(fpc);
+ arith(fpc, 0, DP3, tmp, NVFX_FP_MASK_X, src[0], src[0], none);
+ arith(fpc, 0, DP3, tmp, NVFX_FP_MASK_Y, src[0], src[1], none);
+ arith(fpc, 0, DIV, scale(tmp, 2X), NVFX_FP_MASK_Z,
+ swz(tmp, Y, Y, Y, Y), swz(tmp, X, X, X, X), none);
+ arith(fpc, sat, MAD, dst, mask,
+ swz(tmp, Z, Z, Z, Z), src[0], neg(src[1]));
+ }
break;
case TGSI_OPCODE_RSQ:
- tmp = temp(fpc);
- arith(fpc, 0, LG2, scale(tmp, INV_2X), MASK_X,
- abs(swz(src[0], X, X, X, X)), none, none);
- arith(fpc, sat, EX2, dst, mask,
- neg(swz(tmp, X, X, X, X)), none, none);
+ if(!nvfx->is_nv4x)
+ arith(fpc, sat, RSQ_NV30, dst, mask, abs(swz(src[0], X, X, X, X)), none, none);
+ else {
+ tmp = temp(fpc);
+ arith(fpc, 0, LG2, scale(tmp, INV_2X), NVFX_FP_MASK_X,
+ abs(swz(src[0], X, X, X, X)), none, none);
+ arith(fpc, sat, EX2, dst, mask,
+ neg(swz(tmp, X, X, X, X)), none, none);
+ }
break;
case TGSI_OPCODE_SCS:
/* avoid overwriting the source */
- if(src[0].swz[SWZ_X] != SWZ_X)
+ if(src[0].swz[NVFX_SWZ_X] != NVFX_SWZ_X)
{
- if (mask & MASK_X) {
- arith(fpc, sat, COS, dst, MASK_X,
+ if (mask & NVFX_FP_MASK_X) {
+ arith(fpc, sat, COS, dst, NVFX_FP_MASK_X,
swz(src[0], X, X, X, X), none, none);
}
- if (mask & MASK_Y) {
- arith(fpc, sat, SIN, dst, MASK_Y,
+ if (mask & NVFX_FP_MASK_Y) {
+ arith(fpc, sat, SIN, dst, NVFX_FP_MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
}
else
{
- if (mask & MASK_Y) {
- arith(fpc, sat, SIN, dst, MASK_Y,
+ if (mask & NVFX_FP_MASK_Y) {
+ arith(fpc, sat, SIN, dst, NVFX_FP_MASK_Y,
swz(src[0], X, X, X, X), none, none);
}
- if (mask & MASK_X) {
- arith(fpc, sat, COS, dst, MASK_X,
+ if (mask & NVFX_FP_MASK_X) {
+ arith(fpc, sat, COS, dst, NVFX_FP_MASK_X,
swz(src[0], X, X, X, X), none, none);
}
}
@@ -641,7 +596,7 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
tmp = temp(fpc);
arith(fpc, 0, MUL, tmp, mask,
swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none);
- arith(fpc, sat, MAD, dst, (mask & ~MASK_W),
+ arith(fpc, sat, MAD, dst, (mask & ~NVFX_FP_MASK_W),
swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y),
neg(tmp));
break;
@@ -655,32 +610,32 @@ nv40_fragprog_parse_instruction(struct nv40_fpc *fpc,
}
static boolean
-nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc,
+nvfx_fragprog_parse_decl_attrib(struct nvfx_context* nvfx, struct nvfx_fpc *fpc,
const struct tgsi_full_declaration *fdec)
{
int hw;
switch (fdec->Semantic.Name) {
case TGSI_SEMANTIC_POSITION:
- hw = NV40_FP_OP_INPUT_SRC_POSITION;
+ hw = NVFX_FP_OP_INPUT_SRC_POSITION;
break;
case TGSI_SEMANTIC_COLOR:
if (fdec->Semantic.Index == 0) {
- hw = NV40_FP_OP_INPUT_SRC_COL0;
+ hw = NVFX_FP_OP_INPUT_SRC_COL0;
} else
if (fdec->Semantic.Index == 1) {
- hw = NV40_FP_OP_INPUT_SRC_COL1;
+ hw = NVFX_FP_OP_INPUT_SRC_COL1;
} else {
NOUVEAU_ERR("bad colour semantic index\n");
return FALSE;
}
break;
case TGSI_SEMANTIC_FOG:
- hw = NV40_FP_OP_INPUT_SRC_FOGC;
+ hw = NVFX_FP_OP_INPUT_SRC_FOGC;
break;
case TGSI_SEMANTIC_GENERIC:
if (fdec->Semantic.Index <= 7) {
- hw = NV40_FP_OP_INPUT_SRC_TC(fdec->Semantic.
+ hw = NVFX_FP_OP_INPUT_SRC_TC(fdec->Semantic.
Index);
} else {
NOUVEAU_ERR("bad generic semantic index\n");
@@ -697,7 +652,7 @@ nv40_fragprog_parse_decl_attrib(struct nv40_fpc *fpc,
}
static boolean
-nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc,
+nvfx_fragprog_parse_decl_output(struct nvfx_context* nvfx, struct nvfx_fpc *fpc,
const struct tgsi_full_declaration *fdec)
{
unsigned idx = fdec->Range.First;
@@ -708,12 +663,14 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc,
hw = 1;
break;
case TGSI_SEMANTIC_COLOR:
+ hw = ~0;
switch (fdec->Semantic.Index) {
case 0: hw = 0; break;
case 1: hw = 2; break;
case 2: hw = 3; break;
case 3: hw = 4; break;
- default:
+ }
+ if(hw > ((nvfx->is_nv4x) ? 4 : 2)) {
NOUVEAU_ERR("bad rcol index\n");
return FALSE;
}
@@ -723,13 +680,13 @@ nv40_fragprog_parse_decl_output(struct nv40_fpc *fpc,
return FALSE;
}
- fpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw);
+ fpc->r_result[idx] = nvfx_sr(NVFXSR_OUTPUT, hw);
fpc->r_temps |= (1 << hw);
return TRUE;
}
static boolean
-nv40_fragprog_prepare(struct nv40_fpc *fpc)
+nvfx_fragprog_prepare(struct nvfx_context* nvfx, struct nvfx_fpc *fpc)
{
struct tgsi_parse_context p;
int high_temp = -1, i;
@@ -746,11 +703,11 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc)
fdec = &p.FullToken.FullDeclaration;
switch (fdec->Declaration.File) {
case TGSI_FILE_INPUT:
- if (!nv40_fragprog_parse_decl_attrib(fpc, fdec))
+ if (!nvfx_fragprog_parse_decl_attrib(nvfx, fpc, fdec))
goto out_err;
break;
case TGSI_FILE_OUTPUT:
- if (!nv40_fragprog_parse_decl_output(fpc, fdec))
+ if (!nvfx_fragprog_parse_decl_output(nvfx, fpc, fdec))
goto out_err;
break;
case TGSI_FILE_TEMPORARY:
@@ -787,7 +744,7 @@ nv40_fragprog_prepare(struct nv40_fpc *fpc)
tgsi_parse_free(&p);
if (++high_temp) {
- fpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg));
+ fpc->r_temp = CALLOC(high_temp, sizeof(struct nvfx_sreg));
for (i = 0; i < high_temp; i++)
fpc->r_temp[i] = temp(fpc);
fpc->r_temps_discard = 0;
@@ -803,19 +760,19 @@ out_err:
}
static void
-nv40_fragprog_translate(struct nv40_context *nv40,
- struct nv40_fragment_program *fp)
+nvfx_fragprog_translate(struct nvfx_context *nvfx,
+ struct nvfx_fragment_program *fp)
{
struct tgsi_parse_context parse;
- struct nv40_fpc *fpc = NULL;
+ struct nvfx_fpc *fpc = NULL;
- fpc = CALLOC(1, sizeof(struct nv40_fpc));
+ fpc = CALLOC(1, sizeof(struct nvfx_fpc));
if (!fpc)
return;
fpc->fp = fp;
fpc->num_regs = 2;
- if (!nv40_fragprog_prepare(fpc)) {
+ if (!nvfx_fragprog_prepare(nvfx, fpc)) {
FREE(fpc);
return;
}
@@ -831,7 +788,7 @@ nv40_fragprog_translate(struct nv40_context *nv40,
const struct tgsi_full_instruction *finst;
finst = &parse.FullToken.FullInstruction;
- if (!nv40_fragprog_parse_instruction(fpc, finst))
+ if (!nvfx_fragprog_parse_instruction(nvfx, fpc, finst))
goto out_err;
}
break;
@@ -840,10 +797,14 @@ nv40_fragprog_translate(struct nv40_context *nv40,
}
}
- fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT;
+ if(!nvfx->is_nv4x)
+ fp->fp_control |= (fpc->num_regs-1)/2;
+ else
+ fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT;
/* Terminate final instruction */
- fp->insn[fpc->inst_offset] |= 0x00000001;
+ if(fp->insn)
+ fp->insn[fpc->inst_offset] |= 0x00000001;
/* Append NOP + END instruction, may or may not be necessary. */
fpc->inst_offset = fp->insn_len;
@@ -862,10 +823,10 @@ out_err:
}
static void
-nv40_fragprog_upload(struct nv40_context *nv40,
- struct nv40_fragment_program *fp)
+nvfx_fragprog_upload(struct nvfx_context *nvfx,
+ struct nvfx_fragment_program *fp)
{
- struct pipe_screen *pscreen = nv40->pipe.screen;
+ struct pipe_screen *pscreen = nvfx->pipe.screen;
const uint32_t le = 1;
uint32_t *map;
int i;
@@ -896,12 +857,12 @@ nv40_fragprog_upload(struct nv40_context *nv40,
}
static boolean
-nv40_fragprog_validate(struct nv40_context *nv40)
+nvfx_fragprog_validate(struct nvfx_context *nvfx)
{
- struct nv40_fragment_program *fp = nv40->fragprog;
+ struct nvfx_fragment_program *fp = nvfx->fragprog;
struct pipe_buffer *constbuf =
- nv40->constbuf[PIPE_SHADER_FRAGMENT];
- struct pipe_screen *pscreen = nv40->pipe.screen;
+ nvfx->constbuf[PIPE_SHADER_FRAGMENT];
+ struct pipe_screen *pscreen = nvfx->pipe.screen;
struct nouveau_stateobj *so;
boolean new_consts = FALSE;
int i;
@@ -909,24 +870,31 @@ nv40_fragprog_validate(struct nv40_context *nv40)
if (fp->translated)
goto update_constants;
- nv40->fallback_swrast &= ~NV40_NEW_FRAGPROG;
- nv40_fragprog_translate(nv40, fp);
+ nvfx->fallback_swrast &= ~NVFX_NEW_FRAGPROG;
+ nvfx_fragprog_translate(nvfx, fp);
if (!fp->translated) {
- nv40->fallback_swrast |= NV40_NEW_FRAGPROG;
+ nvfx->fallback_swrast |= NVFX_NEW_FRAGPROG;
return FALSE;
}
fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
- nv40_fragprog_upload(nv40, fp);
+ nvfx_fragprog_upload(nvfx, fp);
- so = so_new(2, 2, 1);
- so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1);
+ so = so_new(4, 4, 1);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_FP_ACTIVE_PROGRAM, 1);
so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
- NOUVEAU_BO_OR, NV40TCL_FP_ADDRESS_DMA0,
- NV40TCL_FP_ADDRESS_DMA1);
- so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1);
+ NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
+ NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_FP_CONTROL, 1);
so_data (so, fp->fp_control);
+ if(!nvfx->is_nv4x) {
+ so_method(so, nvfx->screen->eng3d, NV34TCL_FP_REG_CONTROL, 1);
+ so_data (so, (1<<16)|0x4);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_TX_UNITS_ENABLE, 1);
+ so_data (so, fp->samplers);
+ }
+
so_ref(so, &fp->so);
so_ref(NULL, &so);
@@ -937,7 +905,7 @@ update_constants:
map = pipe_buffer_map(pscreen, constbuf,
PIPE_BUFFER_USAGE_CPU_READ);
for (i = 0; i < fp->nr_consts; i++) {
- struct nv40_fragment_program_data *fpd = &fp->consts[i];
+ struct nvfx_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
uint32_t *cb = (uint32_t *)&map[fpd->index * 4];
@@ -949,11 +917,11 @@ update_constants:
pipe_buffer_unmap(pscreen, constbuf);
if (new_consts)
- nv40_fragprog_upload(nv40, fp);
+ nvfx_fragprog_upload(nvfx, fp);
}
- if (new_consts || fp->so != nv40->state.hw[NV40_STATE_FRAGPROG]) {
- so_ref(fp->so, &nv40->state.hw[NV40_STATE_FRAGPROG]);
+ if (new_consts || fp->so != nvfx->state.hw[NVFX_STATE_FRAGPROG]) {
+ so_ref(fp->so, &nvfx->state.hw[NVFX_STATE_FRAGPROG]);
return TRUE;
}
@@ -961,8 +929,8 @@ update_constants:
}
void
-nv40_fragprog_destroy(struct nv40_context *nv40,
- struct nv40_fragment_program *fp)
+nvfx_fragprog_destroy(struct nvfx_context *nvfx,
+ struct nvfx_fragment_program *fp)
{
if (fp->buffer)
pipe_buffer_reference(&fp->buffer, NULL);
@@ -974,11 +942,10 @@ nv40_fragprog_destroy(struct nv40_context *nv40,
FREE(fp->insn);
}
-struct nv40_state_entry nv40_state_fragprog = {
- .validate = nv40_fragprog_validate,
+struct nvfx_state_entry nvfx_state_fragprog = {
+ .validate = nvfx_fragprog_validate,
.dirty = {
- .pipe = NV40_NEW_FRAGPROG,
- .hw = NV40_STATE_FRAGPROG
+ .pipe = NVFX_NEW_FRAGPROG,
+ .hw = NVFX_STATE_FRAGPROG
}
};
-
diff --git a/src/gallium/drivers/nvfx/nvfx_fragtex.c b/src/gallium/drivers/nvfx/nvfx_fragtex.c
new file mode 100644
index 00000000000..84e4eb10042
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_fragtex.c
@@ -0,0 +1,49 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_fragtex_validate(struct nvfx_context *nvfx)
+{
+ struct nvfx_fragment_program *fp = nvfx->fragprog;
+ struct nvfx_state *state = &nvfx->state;
+ struct nouveau_stateobj *so;
+ unsigned samplers, unit;
+
+ samplers = state->fp_samplers & ~fp->samplers;
+ while (samplers) {
+ unit = ffs(samplers) - 1;
+ samplers &= ~(1 << unit);
+
+ so = so_new(1, 1, 0);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_TX_ENABLE(unit), 1);
+ so_data (so, 0);
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_FRAGTEX0 + unit]);
+ so_ref(NULL, &so);
+ state->dirty |= (1ULL << (NVFX_STATE_FRAGTEX0 + unit));
+ }
+
+ samplers = nvfx->dirty_samplers & fp->samplers;
+ while (samplers) {
+ unit = ffs(samplers) - 1;
+ samplers &= ~(1 << unit);
+
+ if(!nvfx->is_nv4x)
+ so = nv30_fragtex_build(nvfx, unit);
+ else
+ so = nv40_fragtex_build(nvfx, unit);
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_FRAGTEX0 + unit]);
+ so_ref(NULL, &so);
+ state->dirty |= (1ULL << (NVFX_STATE_FRAGTEX0 + unit));
+ }
+
+ nvfx->state.fp_samplers = fp->samplers;
+ return FALSE;
+}
+
+struct nvfx_state_entry nvfx_state_fragtex = {
+ .validate = nvfx_fragtex_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_SAMPLER | NVFX_NEW_FRAGPROG,
+ .hw = 0
+ }
+};
diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 85d7e1f1972..9de25175e78 100644
--- a/src/gallium/drivers/nv40/nv40_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -4,13 +4,13 @@
#include "util/u_format.h"
#include "util/u_math.h"
-#include "nv40_context.h"
-#include "../nouveau/nv04_surface_2d.h"
+#include "nvfx_context.h"
+#include "nv04_surface_2d.h"
static void
-nv40_miptree_layout(struct nv40_miptree *mt)
+nvfx_miptree_layout(struct nvfx_miptree *mt)
{
struct pipe_texture *pt = &mt->base;
uint width = pt->width0;
@@ -20,7 +20,7 @@ nv40_miptree_layout(struct nv40_miptree *mt)
PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -62,13 +62,16 @@ nv40_miptree_layout(struct nv40_miptree *mt)
}
static struct pipe_texture *
-nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
+nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
{
- struct nv40_miptree *mt;
+ struct nvfx_miptree *mt;
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
NOUVEAU_BUFFER_USAGE_TEXTURE;
+ static int no_swizzle = -1;
+ if(no_swizzle < 0)
+ no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE);
- mt = MALLOC(sizeof(struct nv40_miptree));
+ mt = MALLOC(sizeof(struct nvfx_miptree));
if (!mt)
return NULL;
mt->base = *pt;
@@ -80,7 +83,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
pt->height0 & (pt->height0 - 1))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
- if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
+ if (pt->tex_usage & (PIPE_TEXTURE_USAGE_SCANOUT |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
@@ -89,12 +92,24 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else {
switch (pt->format) {
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ /* TODO: we can actually swizzle these formats on nv40, we
+ are just preserving the pre-unification behavior.
+ The whole 2D code is going to be rewritten anyway. */
+ if(nvfx_screen(pscreen)->is_nv4x) {
+ mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ break;
+ }
/* TODO: Figure out which formats can be swizzled */
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R16_SNORM:
{
- if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
+ if (no_swizzle)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
@@ -112,7 +127,7 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
- nv40_miptree_layout(mt);
+ nvfx_miptree_layout(mt);
mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage, mt->total_size);
if (!mt->buffer) {
@@ -124,17 +139,17 @@ nv40_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
}
static struct pipe_texture *
-nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
+nvfx_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
const unsigned *stride, struct pipe_buffer *pb)
{
- struct nv40_miptree *mt;
+ struct nvfx_miptree *mt;
/* Only supports 2D, non-mipmapped textures for the moment */
if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
pt->depth0 != 1)
return NULL;
- mt = CALLOC_STRUCT(nv40_miptree);
+ mt = CALLOC_STRUCT(nvfx_miptree);
if (!mt)
return NULL;
@@ -153,9 +168,9 @@ nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
}
static void
-nv40_miptree_destroy(struct pipe_texture *pt)
+nvfx_miptree_destroy(struct pipe_texture *pt)
{
- struct nv40_miptree *mt = (struct nv40_miptree *)pt;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
int l;
pipe_buffer_reference(&mt->buffer, NULL);
@@ -168,11 +183,11 @@ nv40_miptree_destroy(struct pipe_texture *pt)
}
static struct pipe_surface *
-nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nvfx_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
- struct nv40_miptree *mt = (struct nv40_miptree *)pt;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nv04_surface *ns;
ns = CALLOC_STRUCT(nv04_surface);
@@ -202,21 +217,21 @@ nv40_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
* Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so
* ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/
if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE)
- return &nv04_surface_wrap_for_render(pscreen, ((struct nv40_screen*)pscreen)->eng2d, ns)->base;
+ return &nv04_surface_wrap_for_render(pscreen, ((struct nvfx_screen*)pscreen)->eng2d, ns)->base;
return &ns->base;
}
static void
-nv40_miptree_surface_del(struct pipe_surface *ps)
+nvfx_miptree_surface_del(struct pipe_surface *ps)
{
struct nv04_surface* ns = (struct nv04_surface*)ps;
if(ns->backing)
{
- struct nv40_screen* screen = (struct nv40_screen*)ps->texture->screen;
+ struct nvfx_screen* screen = (struct nvfx_screen*)ps->texture->screen;
if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE)
screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height);
- nv40_miptree_surface_del(&ns->backing->base);
+ nvfx_miptree_surface_del(&ns->backing->base);
}
pipe_texture_reference(&ps->texture, NULL);
@@ -224,12 +239,12 @@ nv40_miptree_surface_del(struct pipe_surface *ps)
}
void
-nv40_screen_init_miptree_functions(struct pipe_screen *pscreen)
+nvfx_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
- pscreen->texture_create = nv40_miptree_create;
- pscreen->texture_blanket = nv40_miptree_blanket;
- pscreen->texture_destroy = nv40_miptree_destroy;
- pscreen->get_tex_surface = nv40_miptree_surface_new;
- pscreen->tex_surface_destroy = nv40_miptree_surface_del;
-}
+ pscreen->texture_create = nvfx_miptree_create;
+ pscreen->texture_destroy = nvfx_miptree_destroy;
+ pscreen->get_tex_surface = nvfx_miptree_surface_new;
+ pscreen->tex_surface_destroy = nvfx_miptree_surface_del;
+ nouveau_screen(pscreen)->texture_blanket = nvfx_miptree_blanket;
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_query.c b/src/gallium/drivers/nvfx/nvfx_query.c
new file mode 100644
index 00000000000..acbaf75a236
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_query.c
@@ -0,0 +1,127 @@
+#include "pipe/p_context.h"
+
+#include "nvfx_context.h"
+
+struct nvfx_query {
+ struct nouveau_resource *object;
+ unsigned type;
+ boolean ready;
+ uint64_t result;
+};
+
+static INLINE struct nvfx_query *
+nvfx_query(struct pipe_query *pipe)
+{
+ return (struct nvfx_query *)pipe;
+}
+
+static struct pipe_query *
+nvfx_query_create(struct pipe_context *pipe, unsigned query_type)
+{
+ struct nvfx_query *q;
+
+ q = CALLOC(1, sizeof(struct nvfx_query));
+ q->type = query_type;
+
+ return (struct pipe_query *)q;
+}
+
+static void
+nvfx_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
+{
+ struct nvfx_query *q = nvfx_query(pq);
+
+ if (q->object)
+ nouveau_resource_free(&q->object);
+ FREE(q);
+}
+
+static void
+nvfx_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_query *q = nvfx_query(pq);
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+
+ assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+
+ /* Happens when end_query() is called, then another begin_query()
+ * without querying the result in-between. For now we'll wait for
+ * the existing query to notify completion, but it could be better.
+ */
+ if (q->object) {
+ uint64_t tmp;
+ pipe->get_query_result(pipe, pq, 1, &tmp);
+ }
+
+ if (nouveau_resource_alloc(nvfx->screen->query_heap, 1, NULL, &q->object))
+ assert(0);
+ nouveau_notifier_reset(nvfx->screen->query, q->object->start);
+
+ BEGIN_RING(chan, eng3d, NV34TCL_QUERY_RESET, 1);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_QUERY_UNK17CC, 1);
+ OUT_RING (chan, 1);
+
+ q->ready = FALSE;
+}
+
+static void
+nvfx_query_end(struct pipe_context *pipe, struct pipe_query *pq)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+ struct nvfx_query *q = nvfx_query(pq);
+
+ BEGIN_RING(chan, eng3d, NV34TCL_QUERY_GET, 1);
+ OUT_RING (chan, (0x01 << NV34TCL_QUERY_GET_UNK24_SHIFT) |
+ ((q->object->start * 32) << NV34TCL_QUERY_GET_OFFSET_SHIFT));
+ FIRE_RING(chan);
+}
+
+static boolean
+nvfx_query_result(struct pipe_context *pipe, struct pipe_query *pq,
+ boolean wait, uint64_t *result)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_query *q = nvfx_query(pq);
+
+ assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+
+ if (!q->ready) {
+ unsigned status;
+
+ status = nouveau_notifier_status(nvfx->screen->query,
+ q->object->start);
+ if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
+ if (wait == FALSE)
+ return FALSE;
+
+ nouveau_notifier_wait_status(nvfx->screen->query,
+ q->object->start,
+ NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
+ }
+
+ q->result = nouveau_notifier_return_val(nvfx->screen->query,
+ q->object->start);
+ q->ready = TRUE;
+ nouveau_resource_free(&q->object);
+ }
+
+ *result = q->result;
+ return TRUE;
+}
+
+void
+nvfx_init_query_functions(struct nvfx_context *nvfx)
+{
+ nvfx->pipe.create_query = nvfx_query_create;
+ nvfx->pipe.destroy_query = nvfx_query_destroy;
+ nvfx->pipe.begin_query = nvfx_query_begin;
+ nvfx->pipe.end_query = nvfx_query_end;
+ nvfx->pipe.get_query_result = nvfx_query_result;
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
new file mode 100644
index 00000000000..f7f39218944
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -0,0 +1,462 @@
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+
+#include "nouveau/nouveau_screen.h"
+
+#include "nvfx_context.h"
+#include "nvfx_screen.h"
+
+#define NV30TCL_CHIPSET_3X_MASK 0x00000003
+#define NV34TCL_CHIPSET_3X_MASK 0x00000010
+#define NV35TCL_CHIPSET_3X_MASK 0x000001e0
+
+/* FIXME: It seems I should not include directly ../../winsys/drm/nouveau/drm/nouveau_drm_api.h
+* to get the pointer to the context front buffer, so I copied nouveau_winsys here.
+* nv30_screen_surface_format_supported() can then use it to enforce creating fbo
+* with same number of bits everywhere.
+*/
+struct nouveau_winsys {
+ struct pipe_winsys base;
+
+ struct pipe_screen *pscreen;
+
+ struct pipe_surface *front;
+};
+#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf
+#define NV4X_GRCLASS4497_CHIPSETS 0x00005450
+#define NV6X_GRCLASS4497_CHIPSETS 0x00000088
+
+static int
+nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
+{
+ struct nvfx_screen *screen = nvfx_screen(pscreen);
+
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ /* TODO: check this */
+ return screen->is_nv4x ? 16 : 8;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return !!screen->is_nv4x;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 0;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 1;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return screen->is_nv4x ? 4 : 2;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 13;
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 10;
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 13;
+ case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+ return !!screen->is_nv4x;
+ case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+ return 1;
+ case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+ return 0; /* We have 4 on nv40 - but unsupported currently */
+ case PIPE_CAP_TGSI_CONT_SUPPORTED:
+ return 0;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return !!screen->is_nv4x;
+ case NOUVEAU_CAP_HW_VTXBUF:
+ return 0;
+ case NOUVEAU_CAP_HW_IDXBUF:
+ return 0;
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return 16;
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ /* TODO: on nv40 we have separate color masks */
+ /* TODO: nv40 mrt blending is probably broken */
+ return 0;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return 0;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0;
+ }
+}
+
+static float
+nvfx_screen_get_paramf(struct pipe_screen *pscreen, int param)
+{
+ struct nvfx_screen *screen = nvfx_screen(pscreen);
+
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 10.0;
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 64.0;
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return screen->is_nv4x ? 16.0 : 8.0;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return screen->is_nv4x ? 16.0 : 4.0;
+ default:
+ NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
+ return 0.0;
+ }
+}
+
+static boolean
+nvfx_screen_surface_format_supported(struct pipe_screen *pscreen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage, unsigned geom_flags)
+{
+ struct nvfx_screen *screen = nvfx_screen(pscreen);
+ struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front;
+
+ if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return TRUE;
+ default:
+ break;
+ }
+ } else
+ if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
+ switch (format) {
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ return TRUE;
+ case PIPE_FORMAT_Z16_UNORM:
+ /* TODO: this nv30 limitation probably does not exist */
+ if (!screen->is_nv4x && front)
+ return (front->format == PIPE_FORMAT_B5G6R5_UNORM);
+ return TRUE;
+ default:
+ break;
+ }
+ } else {
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ return TRUE;
+ /* TODO: does nv30 support this? */
+ case PIPE_FORMAT_R16_SNORM:
+ return !!screen->is_nv4x;
+ default:
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+static struct pipe_buffer *
+nvfx_surface_buffer(struct pipe_surface *surf)
+{
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)surf->texture;
+
+ return mt->buffer;
+}
+
+static void
+nvfx_screen_destroy(struct pipe_screen *pscreen)
+{
+ struct nvfx_screen *screen = nvfx_screen(pscreen);
+ unsigned i;
+
+ for (i = 0; i < NVFX_STATE_MAX; i++) {
+ if (screen->state[i])
+ so_ref(NULL, &screen->state[i]);
+ }
+
+ nouveau_resource_destroy(&screen->vp_exec_heap);
+ nouveau_resource_destroy(&screen->vp_data_heap);
+ nouveau_resource_destroy(&screen->query_heap);
+ nouveau_notifier_free(&screen->query);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->eng3d);
+ nv04_surface_2d_takedown(&screen->eng2d);
+
+ nouveau_screen_fini(&screen->base);
+
+ FREE(pscreen);
+}
+
+static void nv30_screen_init(struct nvfx_screen *screen, struct nouveau_stateobj* so)
+{
+ int i;
+
+ /* TODO: perhaps we should do some of this on nv40 too? */
+ for (i=1; i<8; i++) {
+ so_method(so, screen->eng3d, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1);
+ so_data (so, 0);
+ so_method(so, screen->eng3d, NV34TCL_VIEWPORT_CLIP_VERT(i), 1);
+ so_data (so, 0);
+ }
+
+ so_method(so, screen->eng3d, 0x220, 1);
+ so_data (so, 1);
+
+ so_method(so, screen->eng3d, 0x03b0, 1);
+ so_data (so, 0x00100000);
+ so_method(so, screen->eng3d, 0x1454, 1);
+ so_data (so, 0);
+ so_method(so, screen->eng3d, 0x1d80, 1);
+ so_data (so, 3);
+ so_method(so, screen->eng3d, 0x1450, 1);
+ so_data (so, 0x00030004);
+
+ /* NEW */
+ so_method(so, screen->eng3d, 0x1e98, 1);
+ so_data (so, 0);
+ so_method(so, screen->eng3d, 0x17e0, 3);
+ so_data (so, fui(0.0));
+ so_data (so, fui(0.0));
+ so_data (so, fui(1.0));
+ so_method(so, screen->eng3d, 0x1f80, 16);
+ for (i=0; i<16; i++) {
+ so_data (so, (i==8) ? 0x0000ffff : 0);
+ }
+
+ so_method(so, screen->eng3d, 0x120, 3);
+ so_data (so, 0);
+ so_data (so, 1);
+ so_data (so, 2);
+
+ so_method(so, screen->eng3d, 0x1d88, 1);
+ so_data (so, 0x00001200);
+
+ so_method(so, screen->eng3d, NV34TCL_RC_ENABLE, 1);
+ so_data (so, 0);
+
+ so_method(so, screen->eng3d, NV34TCL_DEPTH_RANGE_NEAR, 2);
+ so_data (so, fui(0.0));
+ so_data (so, fui(1.0));
+
+ so_method(so, screen->eng3d, NV34TCL_MULTISAMPLE_CONTROL, 1);
+ so_data (so, 0xffff0000);
+
+ /* enables use of vp rather than fixed-function somehow */
+ so_method(so, screen->eng3d, 0x1e94, 1);
+ so_data (so, 0x13);
+}
+
+static void nv40_screen_init(struct nvfx_screen *screen, struct nouveau_stateobj* so)
+{
+ so_method(so, screen->eng3d, NV40TCL_DMA_COLOR2, 2);
+ so_data (so, screen->base.channel->vram->handle);
+ so_data (so, screen->base.channel->vram->handle);
+
+ so_method(so, screen->eng3d, 0x1ea4, 3);
+ so_data (so, 0x00000010);
+ so_data (so, 0x01000100);
+ so_data (so, 0xff800006);
+
+ /* vtxprog output routing */
+ so_method(so, screen->eng3d, 0x1fc4, 1);
+ so_data (so, 0x06144321);
+ so_method(so, screen->eng3d, 0x1fc8, 2);
+ so_data (so, 0xedcba987);
+ so_data (so, 0x00000021);
+ so_method(so, screen->eng3d, 0x1fd0, 1);
+ so_data (so, 0x00171615);
+ so_method(so, screen->eng3d, 0x1fd4, 1);
+ so_data (so, 0x001b1a19);
+
+ so_method(so, screen->eng3d, 0x1ef8, 1);
+ so_data (so, 0x0020ffff);
+ so_method(so, screen->eng3d, 0x1d64, 1);
+ so_data (so, 0x00d30000);
+ so_method(so, screen->eng3d, 0x1e94, 1);
+ so_data (so, 0x00000001);
+}
+
+static void
+nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+{
+ int vram_hack_default = 0;
+ int vram_hack;
+ // TODO: this is a bit of a guess; also add other cards that may need this hack.
+ // It may also depend on the specific card or the AGP/PCIe chipset.
+ if(screen->base.device->chipset == 0x47 /* G70 */
+ || screen->base.device->chipset == 0x49 /* G71 */
+ || screen->base.device->chipset == 0x46 /* G72 */
+ )
+ vram_hack_default = 1;
+ vram_hack = debug_get_bool_option("NOUVEAU_VTXIDX_IN_VRAM", vram_hack_default);
+
+#ifdef DEBUG
+ if(!vram_hack)
+ {
+ fprintf(stderr, "Some systems may experience graphics corruption due to randomly misplaced vertices.\n"
+ "If this is happening, export NOUVEAU_VTXIDX_IN_VRAM=1 may reduce or eliminate the problem\n");
+ }
+ else
+ {
+ fprintf(stderr, "A performance reducing hack is being used to help avoid graphics corruption.\n"
+ "You can try export NOUVEAU_VTXIDX_IN_VRAM=0 to disable it.\n");
+ }
+#endif
+
+ screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+}
+
+struct pipe_screen *
+nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
+{
+ struct nvfx_screen *screen = CALLOC_STRUCT(nvfx_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
+ struct nouveau_stateobj *so;
+ unsigned eng3d_class = 0;
+ int ret;
+
+ if (!screen)
+ return NULL;
+
+ pscreen = &screen->base.base;
+
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nvfx_screen_destroy;
+ pscreen->get_param = nvfx_screen_get_param;
+ pscreen->get_paramf = nvfx_screen_get_paramf;
+ pscreen->is_format_supported = nvfx_screen_surface_format_supported;
+ pscreen->context_create = nvfx_create;
+
+ switch (dev->chipset & 0xf0) {
+ case 0x30:
+ if (NV30TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = 0x0397;
+ else if (NV34TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = 0x0697;
+ else if (NV35TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = 0x0497;
+ break;
+ case 0x40:
+ if (NV4X_GRCLASS4097_CHIPSETS & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = NV40TCL;
+ else if (NV4X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = NV44TCL;
+ screen->is_nv4x = ~0;
+ break;
+ case 0x60:
+ if (NV6X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
+ eng3d_class = NV44TCL;
+ screen->is_nv4x = ~0;
+ break;
+ }
+
+ if (!eng3d_class) {
+ NOUVEAU_ERR("Unknown nv3x/nv4x chipset: nv%02x\n", dev->chipset);
+ return NULL;
+ }
+
+ nvfx_screen_init_buffer_functions(screen);
+ nvfx_screen_init_miptree_functions(pscreen);
+
+ ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
+ if (ret) {
+ NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
+ return FALSE;
+ }
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nvfx_surface_buffer;
+
+ /* Notifier for sync purposes */
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
+ if (ret) {
+ NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ /* Query objects */
+ ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
+ if (ret) {
+ NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ ret = nouveau_resource_init(&screen->query_heap, 0, 32);
+ if (ret) {
+ NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ /* Vtxprog resources */
+ if (nouveau_resource_init(&screen->vp_exec_heap, 0, screen->is_nv4x ? 512 : 256) ||
+ nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ /* Static eng3d initialisation */
+ /* make the so big and don't worry about exact values
+ since we it will be thrown away immediately after use */
+ so = so_new(256, 256, 0);
+ so_method(so, screen->eng3d, NV34TCL_DMA_NOTIFY, 1);
+ so_data (so, screen->sync->handle);
+ so_method(so, screen->eng3d, NV34TCL_DMA_TEXTURE0, 2);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
+ so_method(so, screen->eng3d, NV34TCL_DMA_COLOR1, 1);
+ so_data (so, chan->vram->handle);
+ so_method(so, screen->eng3d, NV34TCL_DMA_COLOR0, 2);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_method(so, screen->eng3d, NV34TCL_DMA_VTXBUF0, 2);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
+
+ so_method(so, screen->eng3d, NV34TCL_DMA_FENCE, 2);
+ so_data (so, 0);
+ so_data (so, screen->query->handle);
+
+ so_method(so, screen->eng3d, NV34TCL_DMA_IN_MEMORY7, 2);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
+
+ if(!screen->is_nv4x)
+ nv30_screen_init(screen, so);
+ else
+ nv40_screen_init(screen, so);
+
+ so_emit(chan, so);
+ so_ref(NULL, &so);
+ nouveau_pushbuf_flush(chan, 0);
+
+ return pscreen;
+}
diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index 9437aa050d4..baa848c47aa 100644
--- a/src/gallium/drivers/nv40/nv40_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -1,19 +1,22 @@
-#ifndef __NV40_SCREEN_H__
-#define __NV40_SCREEN_H__
+#ifndef __NVFX_SCREEN_H__
+#define __NVFX_SCREEN_H__
#include "nouveau/nouveau_screen.h"
-#include "nouveau/nv04_surface_2d.h"
+#include "nv04_surface_2d.h"
-struct nv40_screen {
+struct nvfx_screen {
struct nouveau_screen base;
struct nouveau_winsys *nvws;
- struct nv40_context *cur_ctx;
+ struct nvfx_context *cur_ctx;
+
+ unsigned is_nv4x; /* either 0 or ~0 */
+ int vertex_buffer_flags;
/* HW graphics objects */
struct nv04_surface_2d *eng2d;
- struct nouveau_grobj *curie;
+ struct nouveau_grobj *eng3d;
struct nouveau_notifier *sync;
/* Query object resources */
@@ -25,16 +28,13 @@ struct nv40_screen {
struct nouveau_resource *vp_data_heap;
/* Current 3D state of channel */
- struct nouveau_stateobj *state[NV40_STATE_MAX];
+ struct nouveau_stateobj *state[NVFX_STATE_MAX];
};
-static INLINE struct nv40_screen *
-nv40_screen(struct pipe_screen *screen)
+static INLINE struct nvfx_screen *
+nvfx_screen(struct pipe_screen *screen)
{
- return (struct nv40_screen *)screen;
+ return (struct nvfx_screen *)screen;
}
-void
-nv40_screen_init_transfer_functions(struct pipe_screen *pscreen);
-
#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_shader.h b/src/gallium/drivers/nvfx/nvfx_shader.h
new file mode 100644
index 00000000000..0b2f044f7fe
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_shader.h
@@ -0,0 +1,429 @@
+#ifndef __NVFX_SHADER_H__
+#define __NVFX_SHADER_H__
+
+/* this will resolve to either the NV30 or the NV40 version
+ * depending on the current hardware */
+/* unusual, but very fast and compact method */
+#define NVFX_VP(c) ((NV30_VP_##c) + (nvfx->is_nv4x & ((NV40_VP_##c) - (NV30_VP_##c))))
+
+#define NVFX_VP_INST_SLOT_VEC 0
+#define NVFX_VP_INST_SLOT_SCA 1
+
+#define NVFX_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
+#define NVFX_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
+#define NVFX_VP_INST_IN_NORMAL 2
+#define NVFX_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
+#define NVFX_VP_INST_IN_COL1 4
+#define NVFX_VP_INST_IN_FOGC 5
+#define NVFX_VP_INST_IN_TC0 8
+#define NVFX_VP_INST_IN_TC(n) (8+n)
+
+#define NVFX_VP_INST_SCA_OP_NOP 0x00
+#define NVFX_VP_INST_SCA_OP_MOV 0x01
+#define NVFX_VP_INST_SCA_OP_RCP 0x02
+#define NVFX_VP_INST_SCA_OP_RCC 0x03
+#define NVFX_VP_INST_SCA_OP_RSQ 0x04
+#define NVFX_VP_INST_SCA_OP_EXP 0x05
+#define NVFX_VP_INST_SCA_OP_LOG 0x06
+#define NVFX_VP_INST_SCA_OP_LIT 0x07
+#define NVFX_VP_INST_SCA_OP_BRA 0x09
+#define NVFX_VP_INST_SCA_OP_CAL 0x0B
+#define NVFX_VP_INST_SCA_OP_RET 0x0C
+#define NVFX_VP_INST_SCA_OP_LG2 0x0D
+#define NVFX_VP_INST_SCA_OP_EX2 0x0E
+#define NVFX_VP_INST_SCA_OP_SIN 0x0F
+#define NVFX_VP_INST_SCA_OP_COS 0x10
+
+#define NV40_VP_INST_SCA_OP_PUSHA 0x13
+#define NV40_VP_INST_SCA_OP_POPA 0x14
+
+#define NVFX_VP_INST_VEC_OP_NOP 0x00
+#define NVFX_VP_INST_VEC_OP_MOV 0x01
+#define NVFX_VP_INST_VEC_OP_MUL 0x02
+#define NVFX_VP_INST_VEC_OP_ADD 0x03
+#define NVFX_VP_INST_VEC_OP_MAD 0x04
+#define NVFX_VP_INST_VEC_OP_DP3 0x05
+#define NVFX_VP_INST_VEC_OP_DPH 0x06
+#define NVFX_VP_INST_VEC_OP_DP4 0x07
+#define NVFX_VP_INST_VEC_OP_DST 0x08
+#define NVFX_VP_INST_VEC_OP_MIN 0x09
+#define NVFX_VP_INST_VEC_OP_MAX 0x0A
+#define NVFX_VP_INST_VEC_OP_SLT 0x0B
+#define NVFX_VP_INST_VEC_OP_SGE 0x0C
+#define NVFX_VP_INST_VEC_OP_ARL 0x0D
+#define NVFX_VP_INST_VEC_OP_FRC 0x0E
+#define NVFX_VP_INST_VEC_OP_FLR 0x0F
+#define NVFX_VP_INST_VEC_OP_SEQ 0x10
+#define NVFX_VP_INST_VEC_OP_SFL 0x11
+#define NVFX_VP_INST_VEC_OP_SGT 0x12
+#define NVFX_VP_INST_VEC_OP_SLE 0x13
+#define NVFX_VP_INST_VEC_OP_SNE 0x14
+#define NVFX_VP_INST_VEC_OP_STR 0x15
+#define NVFX_VP_INST_VEC_OP_SSG 0x16
+#define NVFX_VP_INST_VEC_OP_ARR 0x17
+#define NVFX_VP_INST_VEC_OP_ARA 0x18
+
+#define NV40_VP_INST_VEC_OP_TXL 0x19
+
+/* DWORD 3 */
+#define NVFX_VP_INST_LAST (1 << 0)
+
+/*
+ * Each fragment program opcode appears to be comprised of 4 32-bit values.
+ *
+ * 0 - Opcode, output reg/mask, ATTRIB source
+ * 1 - Source 0
+ * 2 - Source 1
+ * 3 - Source 2
+ *
+ * There appears to be no special difference between result regs and temp regs.
+ * result.color == R0.xyzw
+ * result.depth == R1.z
+ * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
+ * otherwise it is set to 1.
+ *
+ * Constants are inserted directly after the instruction that uses them.
+ *
+ * It appears that it's not possible to use two input registers in one
+ * instruction as the input sourcing is done in the instruction dword
+ * and not the source selection dwords. As such instructions such as:
+ *
+ * ADD result.color, fragment.color, fragment.texcoord[0];
+ *
+ * must be split into two MOV's and then an ADD (nvidia does this) but
+ * I'm not sure why it's not just one MOV and then source the second input
+ * in the ADD instruction..
+ *
+ * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
+ * negation requires multiplication with a const.
+ *
+ * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
+ * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
+ * is implemented simply by not writing to the relevant components of the destination.
+ *
+ * Conditional execution
+ * TODO
+ *
+ * Non-native instructions:
+ * LIT
+ * LRP - MAD+MAD
+ * SUB - ADD, negate second source
+ * RSQ - LG2 + EX2
+ * POW - LG2 + MUL + EX2
+ * SCS - COS + SIN
+ * XPD
+ *
+ * NV40 Looping
+ * Loops appear to be fairly expensive on NV40 at least, the proprietary
+ * driver goes to a lot of effort to avoid using the native looping
+ * instructions. If the total number of *executed* instructions between
+ * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
+ * The maximum loop count is 255.
+ *
+ */
+
+//== Opcode / Destination selection ==
+#define NVFX_FP_OP_PROGRAM_END (1 << 0)
+#define NVFX_FP_OP_OUT_REG_SHIFT 1
+#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
+#define NV40_FP_OP_OUT_REG_MASK (63 << 1)
+/* Needs to be set when writing outputs to get expected result.. */
+#define NVFX_FP_OP_OUT_REG_HALF (1 << 7)
+#define NVFX_FP_OP_COND_WRITE_ENABLE (1 << 8)
+#define NVFX_FP_OP_OUTMASK_SHIFT 9
+#define NVFX_FP_OP_OUTMASK_MASK (0xF << 9)
+# define NVFX_FP_OP_OUT_X (1<<9)
+# define NVFX_FP_OP_OUT_Y (1<<10)
+# define NVFX_FP_OP_OUT_Z (1<<11)
+# define NVFX_FP_OP_OUT_W (1<<12)
+/* Uncertain about these, especially the input_src values.. it's possible that
+ * they can be dynamically changed.
+ */
+#define NVFX_FP_OP_INPUT_SRC_SHIFT 13
+#define NVFX_FP_OP_INPUT_SRC_MASK (15 << 13)
+# define NVFX_FP_OP_INPUT_SRC_POSITION 0x0
+# define NVFX_FP_OP_INPUT_SRC_COL0 0x1
+# define NVFX_FP_OP_INPUT_SRC_COL1 0x2
+# define NVFX_FP_OP_INPUT_SRC_FOGC 0x3
+# define NVFX_FP_OP_INPUT_SRC_TC0 0x4
+# define NVFX_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
+# define NV40_FP_OP_INPUT_SRC_FACING 0xE
+#define NVFX_FP_OP_TEX_UNIT_SHIFT 17
+#define NVFX_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
+#define NVFX_FP_OP_PRECISION_SHIFT 22
+#define NVFX_FP_OP_PRECISION_MASK (3 << 22)
+# define NVFX_FP_PRECISION_FP32 0
+# define NVFX_FP_PRECISION_FP16 1
+# define NVFX_FP_PRECISION_FX12 2
+#define NVFX_FP_OP_OPCODE_SHIFT 24
+#define NVFX_FP_OP_OPCODE_MASK (0x3F << 24)
+/* NV30/NV40 fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_NOP 0x00
+#define NVFX_FP_OP_OPCODE_MOV 0x01
+#define NVFX_FP_OP_OPCODE_MUL 0x02
+#define NVFX_FP_OP_OPCODE_ADD 0x03
+#define NVFX_FP_OP_OPCODE_MAD 0x04
+#define NVFX_FP_OP_OPCODE_DP3 0x05
+#define NVFX_FP_OP_OPCODE_DP4 0x06
+#define NVFX_FP_OP_OPCODE_DST 0x07
+#define NVFX_FP_OP_OPCODE_MIN 0x08
+#define NVFX_FP_OP_OPCODE_MAX 0x09
+#define NVFX_FP_OP_OPCODE_SLT 0x0A
+#define NVFX_FP_OP_OPCODE_SGE 0x0B
+#define NVFX_FP_OP_OPCODE_SLE 0x0C
+#define NVFX_FP_OP_OPCODE_SGT 0x0D
+#define NVFX_FP_OP_OPCODE_SNE 0x0E
+#define NVFX_FP_OP_OPCODE_SEQ 0x0F
+#define NVFX_FP_OP_OPCODE_FRC 0x10
+#define NVFX_FP_OP_OPCODE_FLR 0x11
+#define NVFX_FP_OP_OPCODE_KIL 0x12
+#define NVFX_FP_OP_OPCODE_PK4B 0x13
+#define NVFX_FP_OP_OPCODE_UP4B 0x14
+#define NVFX_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
+#define NVFX_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
+#define NVFX_FP_OP_OPCODE_TEX 0x17
+#define NVFX_FP_OP_OPCODE_TXP 0x18
+#define NVFX_FP_OP_OPCODE_TXD 0x19
+#define NVFX_FP_OP_OPCODE_RCP 0x1A
+#define NVFX_FP_OP_OPCODE_EX2 0x1C
+#define NVFX_FP_OP_OPCODE_LG2 0x1D
+#define NVFX_FP_OP_OPCODE_STR 0x20
+#define NVFX_FP_OP_OPCODE_SFL 0x21
+#define NVFX_FP_OP_OPCODE_COS 0x22
+#define NVFX_FP_OP_OPCODE_SIN 0x23
+#define NVFX_FP_OP_OPCODE_PK2H 0x24
+#define NVFX_FP_OP_OPCODE_UP2H 0x25
+#define NVFX_FP_OP_OPCODE_PK4UB 0x27
+#define NVFX_FP_OP_OPCODE_UP4UB 0x28
+#define NVFX_FP_OP_OPCODE_PK2US 0x29
+#define NVFX_FP_OP_OPCODE_UP2US 0x2A
+#define NVFX_FP_OP_OPCODE_DP2A 0x2E
+#define NVFX_FP_OP_OPCODE_TXB 0x31
+#define NVFX_FP_OP_OPCODE_DIV 0x3A
+
+/* NV30 only fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_RSQ_NV30 0x1B
+#define NVFX_FP_OP_OPCODE_LIT_NV30 0x1E
+#define NVFX_FP_OP_OPCODE_LRP_NV30 0x1F
+#define NVFX_FP_OP_OPCODE_POW_NV30 0x26
+#define NVFX_FP_OP_OPCODE_RFL_NV30 0x36
+
+/* NV40 only fragment program opcodes */
+#define NVFX_FP_OP_OPCODE_TXL_NV40 0x31
+/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
+#define NV40_FP_OP_BRA_OPCODE_BRK 0x0
+#define NV40_FP_OP_BRA_OPCODE_CAL 0x1
+#define NV40_FP_OP_BRA_OPCODE_IF 0x2
+#define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
+#define NV40_FP_OP_BRA_OPCODE_REP 0x4
+#define NV40_FP_OP_BRA_OPCODE_RET 0x5
+
+#define NVFX_FP_OP_OUT_SAT (1 << 31)
+
+/* high order bits of SRC0 */
+#define NVFX_FP_OP_OUT_ABS (1 << 29)
+#define NVFX_FP_OP_COND_SWZ_W_SHIFT 27
+#define NVFX_FP_OP_COND_SWZ_W_MASK (3 << 27)
+#define NVFX_FP_OP_COND_SWZ_Z_SHIFT 25
+#define NVFX_FP_OP_COND_SWZ_Z_MASK (3 << 25)
+#define NVFX_FP_OP_COND_SWZ_Y_SHIFT 23
+#define NVFX_FP_OP_COND_SWZ_Y_MASK (3 << 23)
+#define NVFX_FP_OP_COND_SWZ_X_SHIFT 21
+#define NVFX_FP_OP_COND_SWZ_X_MASK (3 << 21)
+#define NVFX_FP_OP_COND_SWZ_ALL_SHIFT 21
+#define NVFX_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
+#define NVFX_FP_OP_COND_SHIFT 18
+#define NVFX_FP_OP_COND_MASK (0x07 << 18)
+# define NVFX_FP_OP_COND_FL 0
+# define NVFX_FP_OP_COND_LT 1
+# define NVFX_FP_OP_COND_EQ 2
+# define NVFX_FP_OP_COND_LE 3
+# define NVFX_FP_OP_COND_GT 4
+# define NVFX_FP_OP_COND_NE 5
+# define NVFX_FP_OP_COND_GE 6
+# define NVFX_FP_OP_COND_TR 7
+
+/* high order bits of SRC1 */
+#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
+#define NVFX_FP_OP_DST_SCALE_SHIFT 28
+#define NVFX_FP_OP_DST_SCALE_MASK (3 << 28)
+#define NVFX_FP_OP_DST_SCALE_1X 0
+#define NVFX_FP_OP_DST_SCALE_2X 1
+#define NVFX_FP_OP_DST_SCALE_4X 2
+#define NVFX_FP_OP_DST_SCALE_8X 3
+#define NVFX_FP_OP_DST_SCALE_INV_2X 5
+#define NVFX_FP_OP_DST_SCALE_INV_4X 6
+#define NVFX_FP_OP_DST_SCALE_INV_8X 7
+
+/* SRC1 LOOP */
+#define NV40_FP_OP_LOOP_INCR_SHIFT 19
+#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
+#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
+#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
+#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
+#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
+
+/* SRC1 IF */
+#define NV40_FP_OP_ELSE_ID_SHIFT 2
+#define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
+
+/* SRC1 CAL */
+#define NV40_FP_OP_IADDR_SHIFT 2
+#define NV40_FP_OP_IADDR_MASK (0xFF << 2)
+
+/* SRC1 REP
+ * I have no idea why there are 3 count values here.. but they
+ * have always been filled with the same value in my tests so
+ * far..
+ */
+#define NV40_FP_OP_REP_COUNT1_SHIFT 2
+#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
+#define NV40_FP_OP_REP_COUNT2_SHIFT 10
+#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
+#define NV40_FP_OP_REP_COUNT3_SHIFT 19
+#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
+
+/* SRC2 REP/IF */
+#define NV40_FP_OP_END_ID_SHIFT 2
+#define NV40_FP_OP_END_ID_MASK (0xFF << 2)
+
+/* high order bits of SRC2 */
+#define NVFX_FP_OP_INDEX_INPUT (1 << 30)
+#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
+#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
+
+//== Register selection ==
+#define NVFX_FP_REG_TYPE_SHIFT 0
+#define NVFX_FP_REG_TYPE_MASK (3 << 0)
+# define NVFX_FP_REG_TYPE_TEMP 0
+# define NVFX_FP_REG_TYPE_INPUT 1
+# define NVFX_FP_REG_TYPE_CONST 2
+#define NVFX_FP_REG_SRC_SHIFT 2
+#define NV30_FP_REG_SRC_MASK (31 << 2)
+#define NV40_FP_REG_SRC_MASK (63 << 2)
+#define NVFX_FP_REG_SRC_HALF (1 << 8)
+#define NVFX_FP_REG_SWZ_ALL_SHIFT 9
+#define NVFX_FP_REG_SWZ_ALL_MASK (255 << 9)
+#define NVFX_FP_REG_SWZ_X_SHIFT 9
+#define NVFX_FP_REG_SWZ_X_MASK (3 << 9)
+#define NVFX_FP_REG_SWZ_Y_SHIFT 11
+#define NVFX_FP_REG_SWZ_Y_MASK (3 << 11)
+#define NVFX_FP_REG_SWZ_Z_SHIFT 13
+#define NVFX_FP_REG_SWZ_Z_MASK (3 << 13)
+#define NVFX_FP_REG_SWZ_W_SHIFT 15
+#define NVFX_FP_REG_SWZ_W_MASK (3 << 15)
+# define NVFX_FP_SWIZZLE_X 0
+# define NVFX_FP_SWIZZLE_Y 1
+# define NVFX_FP_SWIZZLE_Z 2
+# define NVFX_FP_SWIZZLE_W 3
+#define NVFX_FP_REG_NEGATE (1 << 17)
+
+#define NVFXSR_NONE 0
+#define NVFXSR_OUTPUT 1
+#define NVFXSR_INPUT 2
+#define NVFXSR_TEMP 3
+#define NVFXSR_CONST 4
+
+#define NVFX_COND_FL 0
+#define NVFX_COND_LT 1
+#define NVFX_COND_EQ 2
+#define NVFX_COND_LE 3
+#define NVFX_COND_GT 4
+#define NVFX_COND_NE 5
+#define NVFX_COND_GE 6
+#define NVFX_COND_TR 7
+
+/* Yes, this are ordered differently... */
+
+#define NVFX_VP_MASK_X 8
+#define NVFX_VP_MASK_Y 4
+#define NVFX_VP_MASK_Z 2
+#define NVFX_VP_MASK_W 1
+#define NVFX_VP_MASK_ALL 0xf
+
+#define NVFX_FP_MASK_X 1
+#define NVFX_FP_MASK_Y 2
+#define NVFX_FP_MASK_Z 4
+#define NVFX_FP_MASK_W 8
+#define NVFX_FP_MASK_ALL 0xf
+
+#define NVFX_SWZ_X 0
+#define NVFX_SWZ_Y 1
+#define NVFX_SWZ_Z 2
+#define NVFX_SWZ_W 3
+
+#define swz(s,x,y,z,w) nvfx_sr_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
+#define neg(s) nvfx_sr_neg((s))
+#define abs(s) nvfx_sr_abs((s))
+#define scale(s,v) nvfx_sr_scale((s), NVFX_FP_OP_DST_SCALE_##v)
+
+struct nvfx_sreg {
+ int type;
+ int index;
+
+ int dst_scale;
+
+ int negate;
+ int abs;
+ int swz[4];
+
+ int cc_update;
+ int cc_update_reg;
+ int cc_test;
+ int cc_test_reg;
+ int cc_swz[4];
+};
+
+static INLINE struct nvfx_sreg
+nvfx_sr(int type, int index)
+{
+ struct nvfx_sreg temp = {
+ .type = type,
+ .index = index,
+ .dst_scale = 0,
+ .abs = 0,
+ .negate = 0,
+ .swz = { 0, 1, 2, 3 },
+ .cc_update = 0,
+ .cc_update_reg = 0,
+ .cc_test = NVFX_COND_TR,
+ .cc_test_reg = 0,
+ .cc_swz = { 0, 1, 2, 3 },
+ };
+ return temp;
+}
+
+static INLINE struct nvfx_sreg
+nvfx_sr_swz(struct nvfx_sreg src, int x, int y, int z, int w)
+{
+ struct nvfx_sreg dst = src;
+
+ dst.swz[NVFX_SWZ_X] = src.swz[x];
+ dst.swz[NVFX_SWZ_Y] = src.swz[y];
+ dst.swz[NVFX_SWZ_Z] = src.swz[z];
+ dst.swz[NVFX_SWZ_W] = src.swz[w];
+ return dst;
+}
+
+static INLINE struct nvfx_sreg
+nvfx_sr_neg(struct nvfx_sreg src)
+{
+ src.negate = !src.negate;
+ return src;
+}
+
+static INLINE struct nvfx_sreg
+nvfx_sr_abs(struct nvfx_sreg src)
+{
+ src.abs = 1;
+ return src;
+}
+
+static INLINE struct nvfx_sreg
+nvfx_sr_scale(struct nvfx_sreg src, int scale)
+{
+ src.dst_scale = scale;
+ return src;
+}
+
+#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c
new file mode 100644
index 00000000000..ecaa0dcb16a
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -0,0 +1,650 @@
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+
+#include "draw/draw_context.h"
+
+#include "tgsi/tgsi_parse.h"
+
+#include "nvfx_context.h"
+#include "nvfx_state.h"
+#include "nvfx_tex.h"
+
+static void *
+nvfx_blend_state_create(struct pipe_context *pipe,
+ const struct pipe_blend_state *cso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+ struct nvfx_blend_state *bso = CALLOC(1, sizeof(*bso));
+ struct nouveau_stateobj *so = so_new(5, 8, 0);
+
+ if (cso->rt[0].blend_enable) {
+ so_method(so, eng3d, NV34TCL_BLEND_FUNC_ENABLE, 3);
+ so_data (so, 1);
+ so_data (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) |
+ nvgl_blend_func(cso->rt[0].rgb_src_factor));
+ so_data (so, nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16 |
+ nvgl_blend_func(cso->rt[0].rgb_dst_factor));
+ if(nvfx->screen->base.device->chipset < 0x40) {
+ so_method(so, eng3d, NV34TCL_BLEND_EQUATION, 1);
+ so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
+ } else {
+ so_method(so, eng3d, NV40TCL_BLEND_EQUATION, 1);
+ so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func) << 16 |
+ nvgl_blend_eqn(cso->rt[0].rgb_func));
+ }
+ } else {
+ so_method(so, eng3d, NV34TCL_BLEND_FUNC_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ so_method(so, eng3d, NV34TCL_COLOR_MASK, 1);
+ so_data (so, (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
+ ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
+ ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
+ ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
+
+ /* TODO: add NV40 MRT color mask */
+
+ if (cso->logicop_enable) {
+ so_method(so, eng3d, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2);
+ so_data (so, 1);
+ so_data (so, nvgl_logicop_func(cso->logicop_func));
+ } else {
+ so_method(so, eng3d, NV34TCL_COLOR_LOGIC_OP_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ so_method(so, eng3d, NV34TCL_DITHER_ENABLE, 1);
+ so_data (so, cso->dither ? 1 : 0);
+
+ so_ref(so, &bso->so);
+ so_ref(NULL, &so);
+ bso->pipe = *cso;
+ return (void *)bso;
+}
+
+static void
+nvfx_blend_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->blend = hwcso;
+ nvfx->dirty |= NVFX_NEW_BLEND;
+}
+
+static void
+nvfx_blend_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_blend_state *bso = hwcso;
+
+ so_ref(NULL, &bso->so);
+ FREE(bso);
+}
+
+static void *
+nvfx_sampler_state_create(struct pipe_context *pipe,
+ const struct pipe_sampler_state *cso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_sampler_state *ps;
+
+ ps = MALLOC(sizeof(struct nvfx_sampler_state));
+
+ /* on nv30, we use this as an internal flag */
+ ps->fmt = cso->normalized_coords ? 0 : NV40TCL_TEX_FORMAT_RECT;
+ ps->en = 0;
+ ps->filt = nvfx_tex_filter(cso);
+ ps->wrap = (nvfx_tex_wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
+ (nvfx_tex_wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
+ (nvfx_tex_wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT) |
+ nvfx_tex_wrap_compare_mode(cso);
+ ps->bcol = nvfx_tex_border_color(cso->border_color);
+
+ if(nvfx->is_nv4x)
+ nv40_sampler_state_init(pipe, ps, cso);
+ else
+ nv30_sampler_state_init(pipe, ps, cso);
+
+ return (void *)ps;
+}
+
+static void
+nvfx_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ unsigned unit;
+
+ for (unit = 0; unit < nr; unit++) {
+ nvfx->tex_sampler[unit] = sampler[unit];
+ nvfx->dirty_samplers |= (1 << unit);
+ }
+
+ for (unit = nr; unit < nvfx->nr_samplers; unit++) {
+ nvfx->tex_sampler[unit] = NULL;
+ nvfx->dirty_samplers |= (1 << unit);
+ }
+
+ nvfx->nr_samplers = nr;
+ nvfx->dirty |= NVFX_NEW_SAMPLER;
+}
+
+static void
+nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ FREE(hwcso);
+}
+
+static void
+nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ unsigned unit;
+
+ for (unit = 0; unit < nr; unit++) {
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ views[unit]);
+ nvfx->dirty_samplers |= (1 << unit);
+ }
+
+ for (unit = nr; unit < nvfx->nr_textures; unit++) {
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ NULL);
+ nvfx->dirty_samplers |= (1 << unit);
+ }
+
+ nvfx->nr_textures = nr;
+ nvfx->dirty |= NVFX_NEW_SAMPLER;
+}
+
+
+static struct pipe_sampler_view *
+nvfx_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+nvfx_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+static void *
+nvfx_rasterizer_state_create(struct pipe_context *pipe,
+ const struct pipe_rasterizer_state *cso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
+ struct nouveau_stateobj *so = so_new(9, 19, 0);
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+
+ /*XXX: ignored:
+ * light_twoside
+ * point_smooth -nohw
+ * multisample
+ */
+
+ so_method(so, eng3d, NV34TCL_SHADE_MODEL, 1);
+ so_data (so, cso->flatshade ? NV34TCL_SHADE_MODEL_FLAT :
+ NV34TCL_SHADE_MODEL_SMOOTH);
+
+ so_method(so, eng3d, NV34TCL_LINE_WIDTH, 2);
+ so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
+ so_data (so, cso->line_smooth ? 1 : 0);
+ so_method(so, eng3d, NV34TCL_LINE_STIPPLE_ENABLE, 2);
+ so_data (so, cso->line_stipple_enable ? 1 : 0);
+ so_data (so, (cso->line_stipple_pattern << 16) |
+ cso->line_stipple_factor);
+
+ so_method(so, eng3d, NV34TCL_POINT_SIZE, 1);
+ so_data (so, fui(cso->point_size));
+
+ so_method(so, eng3d, NV34TCL_POLYGON_MODE_FRONT, 6);
+ if (cso->front_winding == PIPE_WINDING_CCW) {
+ so_data(so, nvgl_polygon_mode(cso->fill_ccw));
+ so_data(so, nvgl_polygon_mode(cso->fill_cw));
+ switch (cso->cull_mode) {
+ case PIPE_WINDING_CCW:
+ so_data(so, NV34TCL_CULL_FACE_FRONT);
+ break;
+ case PIPE_WINDING_CW:
+ so_data(so, NV34TCL_CULL_FACE_BACK);
+ break;
+ case PIPE_WINDING_BOTH:
+ so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
+ break;
+ default:
+ so_data(so, NV34TCL_CULL_FACE_BACK);
+ break;
+ }
+ so_data(so, NV34TCL_FRONT_FACE_CCW);
+ } else {
+ so_data(so, nvgl_polygon_mode(cso->fill_cw));
+ so_data(so, nvgl_polygon_mode(cso->fill_ccw));
+ switch (cso->cull_mode) {
+ case PIPE_WINDING_CCW:
+ so_data(so, NV34TCL_CULL_FACE_BACK);
+ break;
+ case PIPE_WINDING_CW:
+ so_data(so, NV34TCL_CULL_FACE_FRONT);
+ break;
+ case PIPE_WINDING_BOTH:
+ so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
+ break;
+ default:
+ so_data(so, NV34TCL_CULL_FACE_BACK);
+ break;
+ }
+ so_data(so, NV34TCL_FRONT_FACE_CW);
+ }
+ so_data(so, cso->poly_smooth ? 1 : 0);
+ so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0);
+
+ so_method(so, eng3d, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_data (so, cso->poly_stipple_enable ? 1 : 0);
+
+ so_method(so, eng3d, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
+ (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
+ so_data(so, 1);
+ else
+ so_data(so, 0);
+ if (cso->offset_cw || cso->offset_ccw) {
+ so_method(so, eng3d, NV34TCL_POLYGON_OFFSET_FACTOR, 2);
+ so_data (so, fui(cso->offset_scale));
+ so_data (so, fui(cso->offset_units * 2));
+ }
+
+ so_method(so, eng3d, NV34TCL_POINT_SPRITE, 1);
+ if (cso->point_quad_rasterization) {
+ unsigned psctl = (1 << 0), i;
+
+ for (i = 0; i < 8; i++) {
+ if ((cso->sprite_coord_enable >> i) & 1)
+ psctl |= (1 << (8 + i));
+ }
+
+ so_data(so, psctl);
+ } else {
+ so_data(so, 0);
+ }
+
+ so_ref(so, &rsso->so);
+ so_ref(NULL, &so);
+ rsso->pipe = *cso;
+ return (void *)rsso;
+}
+
+static void
+nvfx_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->rasterizer = hwcso;
+ nvfx->dirty |= NVFX_NEW_RAST;
+ nvfx->draw_dirty |= NVFX_NEW_RAST;
+}
+
+static void
+nvfx_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_rasterizer_state *rsso = hwcso;
+
+ so_ref(NULL, &rsso->so);
+ FREE(rsso);
+}
+
+static void *
+nvfx_depth_stencil_alpha_state_create(struct pipe_context *pipe,
+ const struct pipe_depth_stencil_alpha_state *cso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
+ struct nouveau_stateobj *so = so_new(6, 20, 0);
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+
+ so_method(so, eng3d, NV34TCL_DEPTH_FUNC, 3);
+ so_data (so, nvgl_comparison_op(cso->depth.func));
+ so_data (so, cso->depth.writemask ? 1 : 0);
+ so_data (so, cso->depth.enabled ? 1 : 0);
+
+ so_method(so, eng3d, NV34TCL_ALPHA_FUNC_ENABLE, 3);
+ so_data (so, cso->alpha.enabled ? 1 : 0);
+ so_data (so, nvgl_comparison_op(cso->alpha.func));
+ so_data (so, float_to_ubyte(cso->alpha.ref_value));
+
+ if (cso->stencil[0].enabled) {
+ so_method(so, eng3d, NV34TCL_STENCIL_FRONT_ENABLE, 3);
+ so_data (so, cso->stencil[0].enabled ? 1 : 0);
+ so_data (so, cso->stencil[0].writemask);
+ so_data (so, nvgl_comparison_op(cso->stencil[0].func));
+ so_method(so, eng3d, NV34TCL_STENCIL_FRONT_FUNC_MASK, 4);
+ so_data (so, cso->stencil[0].valuemask);
+ so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
+ so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
+ so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
+ } else {
+ so_method(so, eng3d, NV34TCL_STENCIL_FRONT_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ if (cso->stencil[1].enabled) {
+ so_method(so, eng3d, NV34TCL_STENCIL_BACK_ENABLE, 3);
+ so_data (so, cso->stencil[1].enabled ? 1 : 0);
+ so_data (so, cso->stencil[1].writemask);
+ so_data (so, nvgl_comparison_op(cso->stencil[1].func));
+ so_method(so, eng3d, NV34TCL_STENCIL_BACK_FUNC_MASK, 4);
+ so_data (so, cso->stencil[1].valuemask);
+ so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
+ so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
+ so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
+ } else {
+ so_method(so, eng3d, NV34TCL_STENCIL_BACK_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ so_ref(so, &zsaso->so);
+ so_ref(NULL, &so);
+ zsaso->pipe = *cso;
+ return (void *)zsaso;
+}
+
+static void
+nvfx_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->zsa = hwcso;
+ nvfx->dirty |= NVFX_NEW_ZSA;
+}
+
+static void
+nvfx_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_zsa_state *zsaso = hwcso;
+
+ so_ref(NULL, &zsaso->so);
+ FREE(zsaso);
+}
+
+static void *
+nvfx_vp_state_create(struct pipe_context *pipe,
+ const struct pipe_shader_state *cso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_vertex_program *vp;
+
+ vp = CALLOC(1, sizeof(struct nvfx_vertex_program));
+ vp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+ vp->draw = draw_create_vertex_shader(nvfx->draw, &vp->pipe);
+
+ return (void *)vp;
+}
+
+static void
+nvfx_vp_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->vertprog = hwcso;
+ nvfx->dirty |= NVFX_NEW_VERTPROG;
+ nvfx->draw_dirty |= NVFX_NEW_VERTPROG;
+}
+
+static void
+nvfx_vp_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_vertex_program *vp = hwcso;
+
+ draw_delete_vertex_shader(nvfx->draw, vp->draw);
+ nvfx_vertprog_destroy(nvfx, vp);
+ FREE((void*)vp->pipe.tokens);
+ FREE(vp);
+}
+
+static void *
+nvfx_fp_state_create(struct pipe_context *pipe,
+ const struct pipe_shader_state *cso)
+{
+ struct nvfx_fragment_program *fp;
+
+ fp = CALLOC(1, sizeof(struct nvfx_fragment_program));
+ fp->pipe.tokens = tgsi_dup_tokens(cso->tokens);
+
+ tgsi_scan_shader(fp->pipe.tokens, &fp->info);
+
+ return (void *)fp;
+}
+
+static void
+nvfx_fp_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->fragprog = hwcso;
+ nvfx->dirty |= NVFX_NEW_FRAGPROG;
+}
+
+static void
+nvfx_fp_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_fragment_program *fp = hwcso;
+
+ nvfx_fragprog_destroy(nvfx, fp);
+ FREE((void*)fp->pipe.tokens);
+ FREE(fp);
+}
+
+static void
+nvfx_set_blend_color(struct pipe_context *pipe,
+ const struct pipe_blend_color *bcol)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->blend_colour = *bcol;
+ nvfx->dirty |= NVFX_NEW_BCOL;
+}
+
+static void
+nvfx_set_stencil_ref(struct pipe_context *pipe,
+ const struct pipe_stencil_ref *sr)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->stencil_ref = *sr;
+ nvfx->dirty |= NVFX_NEW_SR;
+}
+
+static void
+nvfx_set_clip_state(struct pipe_context *pipe,
+ const struct pipe_clip_state *clip)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->clip = *clip;
+ nvfx->dirty |= NVFX_NEW_UCP;
+ nvfx->draw_dirty |= NVFX_NEW_UCP;
+}
+
+static void
+nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
+ struct pipe_buffer *buf )
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->constbuf[shader] = buf;
+ nvfx->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
+
+ if (shader == PIPE_SHADER_VERTEX) {
+ nvfx->dirty |= NVFX_NEW_VERTPROG;
+ } else
+ if (shader == PIPE_SHADER_FRAGMENT) {
+ nvfx->dirty |= NVFX_NEW_FRAGPROG;
+ }
+}
+
+static void
+nvfx_set_framebuffer_state(struct pipe_context *pipe,
+ const struct pipe_framebuffer_state *fb)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->framebuffer = *fb;
+ nvfx->dirty |= NVFX_NEW_FB;
+}
+
+static void
+nvfx_set_polygon_stipple(struct pipe_context *pipe,
+ const struct pipe_poly_stipple *stipple)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ memcpy(nvfx->stipple, stipple->stipple, 4 * 32);
+ nvfx->dirty |= NVFX_NEW_STIPPLE;
+}
+
+static void
+nvfx_set_scissor_state(struct pipe_context *pipe,
+ const struct pipe_scissor_state *s)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->scissor = *s;
+ nvfx->dirty |= NVFX_NEW_SCISSOR;
+}
+
+static void
+nvfx_set_viewport_state(struct pipe_context *pipe,
+ const struct pipe_viewport_state *vpt)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->viewport = *vpt;
+ nvfx->dirty |= NVFX_NEW_VIEWPORT;
+ nvfx->draw_dirty |= NVFX_NEW_VIEWPORT;
+}
+
+static void
+nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
+ const struct pipe_vertex_buffer *vb)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ memcpy(nvfx->vtxbuf, vb, sizeof(*vb) * count);
+ nvfx->vtxbuf_nr = count;
+
+ nvfx->dirty |= NVFX_NEW_ARRAYS;
+ nvfx->draw_dirty |= NVFX_NEW_ARRAYS;
+}
+
+static void *
+nvfx_vtxelts_state_create(struct pipe_context *pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct nvfx_vtxelt_state *cso = CALLOC_STRUCT(nvfx_vtxelt_state);
+
+ assert(num_elements < 16); /* not doing fallbacks yet */
+ cso->num_elements = num_elements;
+ memcpy(cso->pipe, elements, num_elements * sizeof(*elements));
+
+/* nvfx_vtxelt_construct(cso);*/
+
+ return (void *)cso;
+}
+
+static void
+nvfx_vtxelts_state_delete(struct pipe_context *pipe, void *hwcso)
+{
+ FREE(hwcso);
+}
+
+static void
+nvfx_vtxelts_state_bind(struct pipe_context *pipe, void *hwcso)
+{
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+
+ nvfx->vtxelt = hwcso;
+ nvfx->dirty |= NVFX_NEW_ARRAYS;
+ /*nvfx->draw_dirty |= NVFX_NEW_ARRAYS;*/
+}
+
+void
+nvfx_init_state_functions(struct nvfx_context *nvfx)
+{
+ nvfx->pipe.create_blend_state = nvfx_blend_state_create;
+ nvfx->pipe.bind_blend_state = nvfx_blend_state_bind;
+ nvfx->pipe.delete_blend_state = nvfx_blend_state_delete;
+
+ nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
+ nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
+ nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
+ nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
+ nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
+ nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
+
+ nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
+ nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;
+ nvfx->pipe.delete_rasterizer_state = nvfx_rasterizer_state_delete;
+
+ nvfx->pipe.create_depth_stencil_alpha_state =
+ nvfx_depth_stencil_alpha_state_create;
+ nvfx->pipe.bind_depth_stencil_alpha_state =
+ nvfx_depth_stencil_alpha_state_bind;
+ nvfx->pipe.delete_depth_stencil_alpha_state =
+ nvfx_depth_stencil_alpha_state_delete;
+
+ nvfx->pipe.create_vs_state = nvfx_vp_state_create;
+ nvfx->pipe.bind_vs_state = nvfx_vp_state_bind;
+ nvfx->pipe.delete_vs_state = nvfx_vp_state_delete;
+
+ nvfx->pipe.create_fs_state = nvfx_fp_state_create;
+ nvfx->pipe.bind_fs_state = nvfx_fp_state_bind;
+ nvfx->pipe.delete_fs_state = nvfx_fp_state_delete;
+
+ nvfx->pipe.set_blend_color = nvfx_set_blend_color;
+ nvfx->pipe.set_stencil_ref = nvfx_set_stencil_ref;
+ nvfx->pipe.set_clip_state = nvfx_set_clip_state;
+ nvfx->pipe.set_constant_buffer = nvfx_set_constant_buffer;
+ nvfx->pipe.set_framebuffer_state = nvfx_set_framebuffer_state;
+ nvfx->pipe.set_polygon_stipple = nvfx_set_polygon_stipple;
+ nvfx->pipe.set_scissor_state = nvfx_set_scissor_state;
+ nvfx->pipe.set_viewport_state = nvfx_set_viewport_state;
+
+ nvfx->pipe.create_vertex_elements_state = nvfx_vtxelts_state_create;
+ nvfx->pipe.delete_vertex_elements_state = nvfx_vtxelts_state_delete;
+ nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind;
+
+ nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers;
+}
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nvfx/nvfx_state.h
index 192074e7471..e585246879b 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nvfx/nvfx_state.h
@@ -1,29 +1,21 @@
-#ifndef __NV40_STATE_H__
-#define __NV40_STATE_H__
+#ifndef __NVFX_STATE_H__
+#define __NVFX_STATE_H__
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
-struct nv40_sampler_state {
- uint32_t fmt;
- uint32_t wrap;
- uint32_t en;
- uint32_t filt;
- uint32_t bcol;
-};
-
-struct nv40_vertex_program_exec {
+struct nvfx_vertex_program_exec {
uint32_t data[4];
boolean has_branch_offset;
int const_index;
};
-struct nv40_vertex_program_data {
+struct nvfx_vertex_program_data {
int index; /* immediates == -1 */
float value[4];
};
-struct nv40_vertex_program {
+struct nvfx_vertex_program {
struct pipe_shader_state pipe;
struct draw_vertex_shader *draw;
@@ -32,9 +24,9 @@ struct nv40_vertex_program {
struct pipe_clip_state ucp;
- struct nv40_vertex_program_exec *insns;
+ struct nvfx_vertex_program_exec *insns;
unsigned nr_insns;
- struct nv40_vertex_program_data *consts;
+ struct nvfx_vertex_program_data *consts;
unsigned nr_consts;
struct nouveau_resource *exec;
@@ -49,12 +41,12 @@ struct nv40_vertex_program {
struct nouveau_stateobj *so;
};
-struct nv40_fragment_program_data {
+struct nvfx_fragment_program_data {
unsigned offset;
unsigned index;
};
-struct nv40_fragment_program {
+struct nvfx_fragment_program {
struct pipe_shader_state pipe;
struct tgsi_shader_info info;
@@ -64,7 +56,7 @@ struct nv40_fragment_program {
uint32_t *insn;
int insn_len;
- struct nv40_fragment_program_data *consts;
+ struct nvfx_fragment_program_data *consts;
unsigned nr_consts;
struct pipe_buffer *buffer;
@@ -73,7 +65,9 @@ struct nv40_fragment_program {
struct nouveau_stateobj *so;
};
-struct nv40_miptree {
+#define NVFX_MAX_TEXTURE_LEVELS 16
+
+struct nvfx_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
@@ -83,7 +77,7 @@ struct nv40_miptree {
struct {
uint pitch;
uint *image_offset;
- } level[PIPE_MAX_TEXTURE_LEVELS];
+ } level[NVFX_MAX_TEXTURE_LEVELS];
};
#endif
diff --git a/src/gallium/drivers/nvfx/nvfx_state_blend.c b/src/gallium/drivers/nvfx/nvfx_state_blend.c
new file mode 100644
index 00000000000..03b6ef8117d
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_blend.c
@@ -0,0 +1,41 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_state_blend_validate(struct nvfx_context *nvfx)
+{
+ so_ref(nvfx->blend->so, &nvfx->state.hw[NVFX_STATE_BLEND]);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_blend = {
+ .validate = nvfx_state_blend_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_BLEND,
+ .hw = NVFX_STATE_BLEND
+ }
+};
+
+static boolean
+nvfx_state_blend_colour_validate(struct nvfx_context *nvfx)
+{
+ struct nouveau_stateobj *so = so_new(1, 1, 0);
+ struct pipe_blend_color *bcol = &nvfx->blend_colour;
+
+ so_method(so, nvfx->screen->eng3d, NV34TCL_BLEND_COLOR, 1);
+ so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) |
+ (float_to_ubyte(bcol->color[0]) << 16) |
+ (float_to_ubyte(bcol->color[1]) << 8) |
+ (float_to_ubyte(bcol->color[2]) << 0)));
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_BCOL]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_blend_colour = {
+ .validate = nvfx_state_blend_colour_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_BCOL,
+ .hw = NVFX_STATE_BCOL
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
new file mode 100644
index 00000000000..72537388ea4
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -0,0 +1,179 @@
+#include "nvfx_context.h"
+#include "nvfx_state.h"
+#include "draw/draw_context.h"
+
+#define RENDER_STATES(name, vbo) \
+static struct nvfx_state_entry *name##render_states[] = { \
+ &nvfx_state_framebuffer, \
+ &nvfx_state_rasterizer, \
+ &nvfx_state_scissor, \
+ &nvfx_state_stipple, \
+ &nvfx_state_fragprog, \
+ &nvfx_state_fragtex, \
+ &nvfx_state_vertprog, \
+ &nvfx_state_blend, \
+ &nvfx_state_blend_colour, \
+ &nvfx_state_zsa, \
+ &nvfx_state_sr, \
+ &nvfx_state_viewport, \
+ &nvfx_state_##vbo, \
+ NULL \
+}
+
+RENDER_STATES(, vbo);
+RENDER_STATES(swtnl_, vtxfmt);
+
+static void
+nvfx_state_do_validate(struct nvfx_context *nvfx,
+ struct nvfx_state_entry **states)
+{
+ while (*states) {
+ struct nvfx_state_entry *e = *states;
+
+ if (nvfx->dirty & e->dirty.pipe) {
+ if (e->validate(nvfx))
+ nvfx->state.dirty |= (1ULL << e->dirty.hw);
+ }
+
+ states++;
+ }
+ nvfx->dirty = 0;
+}
+
+void
+nvfx_state_emit(struct nvfx_context *nvfx)
+{
+ struct nvfx_state *state = &nvfx->state;
+ struct nvfx_screen *screen = nvfx->screen;
+ struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+ unsigned i;
+ uint64_t states;
+
+ /* XXX: race conditions
+ */
+ if (nvfx != screen->cur_ctx) {
+ for (i = 0; i < NVFX_STATE_MAX; i++) {
+ if (state->hw[i] && screen->state[i] != state->hw[i])
+ state->dirty |= (1ULL << i);
+ }
+
+ screen->cur_ctx = nvfx;
+ }
+
+ for (i = 0, states = state->dirty; states; i++) {
+ if (!(states & (1ULL << i)))
+ continue;
+ so_ref (state->hw[i], &nvfx->screen->state[i]);
+ if (state->hw[i])
+ so_emit(chan, nvfx->screen->state[i]);
+ states &= ~(1ULL << i);
+ }
+
+ /* TODO: could nv30 need this or something similar too? */
+ if(nvfx->is_nv4x) {
+ if (state->dirty & ((1ULL << NVFX_STATE_FRAGPROG) |
+ (1ULL << NVFX_STATE_FRAGTEX0))) {
+ BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1);
+ OUT_RING (chan, 2);
+ BEGIN_RING(chan, eng3d, NV40TCL_TEX_CACHE_CTL, 1);
+ OUT_RING (chan, 1);
+ }
+ }
+ state->dirty = 0;
+}
+
+void
+nvfx_state_flush_notify(struct nouveau_channel *chan)
+{
+ struct nvfx_context *nvfx = chan->user_private;
+ struct nvfx_state *state = &nvfx->state;
+ unsigned i, samplers;
+
+ so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FB]);
+ for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
+ if (!(samplers & (1 << i)))
+ continue;
+ so_emit_reloc_markers(chan,
+ state->hw[NVFX_STATE_FRAGTEX0+i]);
+ samplers &= ~(1ULL << i);
+ }
+ so_emit_reloc_markers(chan, state->hw[NVFX_STATE_FRAGPROG]);
+ if (state->hw[NVFX_STATE_VTXBUF] && nvfx->render_mode == HW)
+ so_emit_reloc_markers(chan, state->hw[NVFX_STATE_VTXBUF]);
+}
+
+boolean
+nvfx_state_validate(struct nvfx_context *nvfx)
+{
+ boolean was_sw = nvfx->fallback_swtnl ? TRUE : FALSE;
+
+ if (nvfx->render_mode != HW) {
+ /* Don't even bother trying to go back to hw if none
+ * of the states that caused swtnl previously have changed.
+ */
+ if ((nvfx->fallback_swtnl & nvfx->dirty)
+ != nvfx->fallback_swtnl)
+ return FALSE;
+
+ /* Attempt to go to hwtnl again */
+ nvfx->pipe.flush(&nvfx->pipe, 0, NULL);
+ nvfx->dirty |= (NVFX_NEW_VIEWPORT |
+ NVFX_NEW_VERTPROG |
+ NVFX_NEW_ARRAYS);
+ nvfx->render_mode = HW;
+ }
+
+ nvfx_state_do_validate(nvfx, render_states);
+
+ if (nvfx->fallback_swtnl || nvfx->fallback_swrast)
+ return FALSE;
+
+ if (was_sw)
+ NOUVEAU_ERR("swtnl->hw\n");
+
+ return TRUE;
+}
+
+boolean
+nvfx_state_validate_swtnl(struct nvfx_context *nvfx)
+{
+ struct draw_context *draw = nvfx->draw;
+
+ /* Setup for swtnl */
+ if (nvfx->render_mode == HW) {
+ NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx->fallback_swtnl);
+ nvfx->pipe.flush(&nvfx->pipe, 0, NULL);
+ nvfx->dirty |= (NVFX_NEW_VIEWPORT |
+ NVFX_NEW_VERTPROG |
+ NVFX_NEW_ARRAYS);
+ nvfx->render_mode = SWTNL;
+ }
+
+ if (nvfx->draw_dirty & NVFX_NEW_VERTPROG)
+ draw_bind_vertex_shader(draw, nvfx->vertprog->draw);
+
+ if (nvfx->draw_dirty & NVFX_NEW_RAST)
+ draw_set_rasterizer_state(draw, &nvfx->rasterizer->pipe);
+
+ if (nvfx->draw_dirty & NVFX_NEW_UCP)
+ draw_set_clip_state(draw, &nvfx->clip);
+
+ if (nvfx->draw_dirty & NVFX_NEW_VIEWPORT)
+ draw_set_viewport_state(draw, &nvfx->viewport);
+
+ if (nvfx->draw_dirty & NVFX_NEW_ARRAYS) {
+ draw_set_vertex_buffers(draw, nvfx->vtxbuf_nr, nvfx->vtxbuf);
+ draw_set_vertex_elements(draw, nvfx->vtxelt->num_elements, nvfx->vtxelt->pipe);
+ }
+
+ nvfx_state_do_validate(nvfx, swtnl_render_states);
+
+ if (nvfx->fallback_swrast) {
+ NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nvfx->fallback_swrast);
+ return FALSE;
+ }
+
+ nvfx->draw_dirty = 0;
+ return TRUE;
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_state_fb.c b/src/gallium/drivers/nvfx/nvfx_state_fb.c
new file mode 100644
index 00000000000..dd64ba4193c
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_fb.c
@@ -0,0 +1,234 @@
+#include "nvfx_context.h"
+#include "nouveau/nouveau_util.h"
+
+static struct pipe_buffer *
+nvfx_do_surface_buffer(struct pipe_surface *surface)
+{
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)surface->texture;
+ return mt->buffer;
+}
+
+#define nvfx_surface_buffer(ps) nouveau_bo(nvfx_do_surface_buffer(ps))
+
+static boolean
+nvfx_state_framebuffer_validate(struct nvfx_context *nvfx)
+{
+ struct pipe_framebuffer_state *fb = &nvfx->framebuffer;
+ struct nouveau_channel *chan = nvfx->screen->base.channel;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+ struct nv04_surface *rt[4], *zeta = NULL;
+ uint32_t rt_enable = 0, rt_format = 0;
+ int i, colour_format = 0, zeta_format = 0;
+ int depth_only = 0;
+ struct nouveau_stateobj *so = so_new(18, 24, 10);
+ unsigned rt_flags = NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM;
+ unsigned w = fb->width;
+ unsigned h = fb->height;
+ int colour_bits = 32, zeta_bits = 32;
+
+ if(!nvfx->is_nv4x)
+ assert(fb->nr_cbufs <= 2);
+ else
+ assert(fb->nr_cbufs <= 4);
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ if (colour_format) {
+ assert(colour_format == fb->cbufs[i]->format);
+ } else {
+ colour_format = fb->cbufs[i]->format;
+ rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
+ rt[i] = (struct nv04_surface *)fb->cbufs[i];
+ }
+ }
+
+ if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 |
+ NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3))
+ rt_enable |= NV34TCL_RT_ENABLE_MRT;
+
+ if (fb->zsbuf) {
+ zeta_format = fb->zsbuf->format;
+ zeta = (struct nv04_surface *)fb->zsbuf;
+ }
+
+ if (rt_enable & (NV34TCL_RT_ENABLE_COLOR0 | NV34TCL_RT_ENABLE_COLOR1 |
+ NV40TCL_RT_ENABLE_COLOR2 | NV40TCL_RT_ENABLE_COLOR3)) {
+ /* Render to at least a colour buffer */
+ if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
+ assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
+ for (i = 1; i < fb->nr_cbufs; i++)
+ assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
+
+ rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
+ (log2i(rt[0]->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
+ (log2i(rt[0]->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
+ }
+ else
+ rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
+ } else if (fb->zsbuf) {
+ depth_only = 1;
+
+ /* Render to depth buffer only */
+ if (!(zeta->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
+ assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
+
+ rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
+ (log2i(zeta->base.width) << NV34TCL_RT_FORMAT_LOG2_WIDTH_SHIFT) |
+ (log2i(zeta->base.height) << NV34TCL_RT_FORMAT_LOG2_HEIGHT_SHIFT);
+ }
+ else
+ rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
+ } else {
+ return FALSE;
+ }
+
+ switch (colour_format) {
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ rt_format |= NV34TCL_RT_FORMAT_COLOR_X8R8G8B8;
+ break;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case 0:
+ rt_format |= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8;
+ break;
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5;
+ colour_bits = 16;
+ break;
+ default:
+ assert(0);
+ }
+
+ switch (zeta_format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16;
+ zeta_bits = 16;
+ break;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case 0:
+ rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8;
+ break;
+ default:
+ assert(0);
+ }
+
+ if ((!nvfx->is_nv4x) && colour_bits > zeta_bits) {
+ /* TODO: does this limitation really exist?
+ TODO: can it be worked around somehow? */
+ return FALSE;
+ }
+
+ if ((rt_enable & NV34TCL_RT_ENABLE_COLOR0)
+ || ((!nvfx->is_nv4x) && depth_only)) {
+ struct nv04_surface *rt0 = (depth_only ? zeta : rt[0]);
+ uint32_t pitch = rt0->pitch;
+
+ if(!nvfx->is_nv4x)
+ {
+ if (zeta) {
+ pitch |= (zeta->pitch << 16);
+ } else {
+ pitch |= (pitch << 16);
+ }
+ }
+
+ so_method(so, eng3d, NV34TCL_DMA_COLOR0, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt0->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, eng3d, NV34TCL_COLOR0_PITCH, 2);
+ so_data (so, pitch);
+ so_reloc (so, nvfx_surface_buffer(&rt[0]->base),
+ rt0->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ }
+
+ if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
+ so_method(so, eng3d, NV34TCL_DMA_COLOR1, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt[1]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, eng3d, NV34TCL_COLOR1_OFFSET, 2);
+ so_reloc (so, nvfx_surface_buffer(&rt[1]->base),
+ rt[1]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ so_data (so, rt[1]->pitch);
+ }
+
+ if(nvfx->is_nv4x)
+ {
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
+ so_method(so, eng3d, NV40TCL_DMA_COLOR2, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt[2]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, eng3d, NV40TCL_COLOR2_OFFSET, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt[2]->base),
+ rt[2]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ so_method(so, eng3d, NV40TCL_COLOR2_PITCH, 1);
+ so_data (so, rt[2]->pitch);
+ }
+
+ if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
+ so_method(so, eng3d, NV40TCL_DMA_COLOR3, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt[3]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, eng3d, NV40TCL_COLOR3_OFFSET, 1);
+ so_reloc (so, nvfx_surface_buffer(&rt[3]->base),
+ rt[3]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ so_method(so, eng3d, NV40TCL_COLOR3_PITCH, 1);
+ so_data (so, rt[3]->pitch);
+ }
+ }
+
+ if (zeta_format) {
+ so_method(so, eng3d, NV34TCL_DMA_ZETA, 1);
+ so_reloc (so, nvfx_surface_buffer(&zeta->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, eng3d, NV34TCL_ZETA_OFFSET, 1);
+ /* TODO: reverse engineer LMA */
+ so_reloc (so, nvfx_surface_buffer(&zeta->base),
+ zeta->base.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
+ if(nvfx->is_nv4x) {
+ so_method(so, eng3d, NV40TCL_ZETA_PITCH, 1);
+ so_data (so, zeta->pitch);
+ }
+ }
+
+ so_method(so, eng3d, NV34TCL_RT_ENABLE, 1);
+ so_data (so, rt_enable);
+ so_method(so, eng3d, NV34TCL_RT_HORIZ, 3);
+ so_data (so, (w << 16) | 0);
+ so_data (so, (h << 16) | 0);
+ so_data (so, rt_format);
+ so_method(so, eng3d, NV34TCL_VIEWPORT_HORIZ, 2);
+ so_data (so, (w << 16) | 0);
+ so_data (so, (h << 16) | 0);
+ so_method(so, eng3d, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+ so_data (so, ((w - 1) << 16) | 0);
+ so_data (so, ((h - 1) << 16) | 0);
+ so_method(so, eng3d, 0x1d88, 1);
+ so_data (so, (1 << 12) | h);
+
+ if(!nvfx->is_nv4x) {
+ /* Wonder why this is needed, context should all be set to zero on init */
+ /* TODO: we can most likely remove this, after putting it in context init */
+ so_method(so, eng3d, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
+ so_data (so, 0);
+ }
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_FB]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_framebuffer = {
+ .validate = nvfx_state_framebuffer_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_FB,
+ .hw = NVFX_STATE_FB
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_rasterizer.c b/src/gallium/drivers/nvfx/nvfx_state_rasterizer.c
new file mode 100644
index 00000000000..0d35ecbf209
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_rasterizer.c
@@ -0,0 +1,17 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_state_rasterizer_validate(struct nvfx_context *nvfx)
+{
+ so_ref(nvfx->rasterizer->so,
+ &nvfx->state.hw[NVFX_STATE_RAST]);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_rasterizer = {
+ .validate = nvfx_state_rasterizer_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_RAST,
+ .hw = NVFX_STATE_RAST
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_scissor.c b/src/gallium/drivers/nvfx/nvfx_state_scissor.c
new file mode 100644
index 00000000000..940d8cb5c0c
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_scissor.c
@@ -0,0 +1,36 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_state_scissor_validate(struct nvfx_context *nvfx)
+{
+ struct pipe_rasterizer_state *rast = &nvfx->rasterizer->pipe;
+ struct pipe_scissor_state *s = &nvfx->scissor;
+ struct nouveau_stateobj *so;
+
+ if (nvfx->state.hw[NVFX_STATE_SCISSOR] &&
+ (rast->scissor == 0 && nvfx->state.scissor_enabled == 0))
+ return FALSE;
+ nvfx->state.scissor_enabled = rast->scissor;
+
+ so = so_new(1, 2, 0);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_SCISSOR_HORIZ, 2);
+ if (nvfx->state.scissor_enabled) {
+ so_data (so, ((s->maxx - s->minx) << 16) | s->minx);
+ so_data (so, ((s->maxy - s->miny) << 16) | s->miny);
+ } else {
+ so_data (so, 4096 << 16);
+ so_data (so, 4096 << 16);
+ }
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_SCISSOR]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_scissor = {
+ .validate = nvfx_state_scissor_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_SCISSOR | NVFX_NEW_RAST,
+ .hw = NVFX_STATE_SCISSOR
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_stipple.c b/src/gallium/drivers/nvfx/nvfx_state_stipple.c
new file mode 100644
index 00000000000..57cd3c936a7
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_stipple.c
@@ -0,0 +1,40 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_state_stipple_validate(struct nvfx_context *nvfx)
+{
+ struct pipe_rasterizer_state *rast = &nvfx->rasterizer->pipe;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+ struct nouveau_stateobj *so;
+
+ if (nvfx->state.hw[NVFX_STATE_STIPPLE] &&
+ (rast->poly_stipple_enable == 0 && nvfx->state.stipple_enabled == 0))
+ return FALSE;
+
+ if (rast->poly_stipple_enable) {
+ unsigned i;
+
+ so = so_new(2, 33, 0);
+ so_method(so, eng3d, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_data (so, 1);
+ so_method(so, eng3d, NV34TCL_POLYGON_STIPPLE_PATTERN(0), 32);
+ for (i = 0; i < 32; i++)
+ so_data(so, nvfx->stipple[i]);
+ } else {
+ so = so_new(1, 1, 0);
+ so_method(so, eng3d, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
+ so_data (so, 0);
+ }
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_STIPPLE]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_stipple = {
+ .validate = nvfx_state_stipple_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_STIPPLE | NVFX_NEW_RAST,
+ .hw = NVFX_STATE_STIPPLE,
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_viewport.c b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
new file mode 100644
index 00000000000..ec730e3a9e9
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
@@ -0,0 +1,52 @@
+#include "nvfx_context.h"
+
+/* Having this depend on FB and RAST looks wrong, but it seems
+ necessary to make this work on nv3x
+ TODO: find the right fix
+*/
+
+static boolean
+nvfx_state_viewport_validate(struct nvfx_context *nvfx)
+{
+ struct pipe_viewport_state *vpt = &nvfx->viewport;
+ struct nouveau_stateobj *so;
+
+ so = so_new(2, 9, 0);
+ so_method(so, nvfx->screen->eng3d,
+ NV34TCL_VIEWPORT_TRANSLATE_X, 8);
+ if(nvfx->render_mode == HW) {
+ so_data (so, fui(vpt->translate[0]));
+ so_data (so, fui(vpt->translate[1]));
+ so_data (so, fui(vpt->translate[2]));
+ so_data (so, fui(vpt->translate[3]));
+ so_data (so, fui(vpt->scale[0]));
+ so_data (so, fui(vpt->scale[1]));
+ so_data (so, fui(vpt->scale[2]));
+ so_data (so, fui(vpt->scale[3]));
+ so_method(so, nvfx->screen->eng3d, 0x1d78, 1);
+ so_data (so, 1);
+ } else {
+ so_data (so, fui(0.0f));
+ so_data (so, fui(0.0f));
+ so_data (so, fui(0.0f));
+ so_data (so, fui(0.0f));
+ so_data (so, fui(1.0f));
+ so_data (so, fui(1.0f));
+ so_data (so, fui(1.0f));
+ so_data (so, fui(1.0f));
+ so_method(so, nvfx->screen->eng3d, 0x1d78, 1);
+ so_data (so, nvfx->is_nv4x ? 0x110 : 1);
+ }
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_VIEWPORT]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_viewport = {
+ .validate = nvfx_state_viewport_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_VIEWPORT | NVFX_NEW_FB | NVFX_NEW_RAST,
+ .hw = NVFX_STATE_VIEWPORT
+ }
+};
diff --git a/src/gallium/drivers/nvfx/nvfx_state_zsa.c b/src/gallium/drivers/nvfx/nvfx_state_zsa.c
new file mode 100644
index 00000000000..c84fd041c1e
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_state_zsa.c
@@ -0,0 +1,41 @@
+#include "nvfx_context.h"
+
+static boolean
+nvfx_state_zsa_validate(struct nvfx_context *nvfx)
+{
+ so_ref(nvfx->zsa->so,
+ &nvfx->state.hw[NVFX_STATE_ZSA]);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_zsa = {
+ .validate = nvfx_state_zsa_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_ZSA,
+ .hw = NVFX_STATE_ZSA
+ }
+};
+
+static boolean
+nvfx_state_sr_validate(struct nvfx_context *nvfx)
+{
+ struct nouveau_stateobj *so = so_new(2, 2, 0);
+ struct pipe_stencil_ref *sr = &nvfx->stencil_ref;
+
+ so_method(so, nvfx->screen->eng3d, NV34TCL_STENCIL_FRONT_FUNC_REF, 1);
+ so_data (so, sr->ref_value[0]);
+ so_method(so, nvfx->screen->eng3d, NV34TCL_STENCIL_BACK_FUNC_REF, 1);
+ so_data (so, sr->ref_value[1]);
+
+ so_ref(so, &nvfx->state.hw[NVFX_STATE_SR]);
+ so_ref(NULL, &so);
+ return TRUE;
+}
+
+struct nvfx_state_entry nvfx_state_sr = {
+ .validate = nvfx_state_sr_validate,
+ .dirty = {
+ .pipe = NVFX_NEW_SR,
+ .hw = NVFX_STATE_SR
+ }
+};
diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nvfx/nvfx_surface.c
index bc18e577eee..8a05ad0a571 100644
--- a/src/gallium/drivers/nv30/nv30_surface.c
+++ b/src/gallium/drivers/nvfx/nvfx_surface.c
@@ -1,9 +1,9 @@
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -11,11 +11,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -23,40 +23,40 @@
* 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 "nv30_context.h"
+#include "nvfx_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_tile.h"
static void
-nv30_surface_copy(struct pipe_context *pipe,
+nvfx_surface_copy(struct pipe_context *pipe,
struct pipe_surface *dest, unsigned destx, unsigned desty,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv04_surface_2d *eng2d = nv30->screen->eng2d;
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
}
static void
-nv30_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
+nvfx_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
unsigned destx, unsigned desty, unsigned width,
unsigned height, unsigned value)
{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv04_surface_2d *eng2d = nv30->screen->eng2d;
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nv04_surface_2d *eng2d = nvfx->screen->eng2d;
eng2d->fill(eng2d, dest, destx, desty, width, height, value);
}
void
-nv30_init_surface_functions(struct nv30_context *nv30)
+nvfx_init_surface_functions(struct nvfx_context *nvfx)
{
- nv30->pipe.surface_copy = nv30_surface_copy;
- nv30->pipe.surface_fill = nv30_surface_fill;
+ nvfx->pipe.surface_copy = nvfx_surface_copy;
+ nvfx->pipe.surface_fill = nvfx_surface_fill;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_tex.h b/src/gallium/drivers/nvfx/nvfx_tex.h
new file mode 100644
index 00000000000..69187a79e79
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_tex.h
@@ -0,0 +1,133 @@
+#ifndef NVFX_TEX_H_
+#define NVFX_TEX_H_
+
+static inline unsigned
+nvfx_tex_wrap_mode(unsigned wrap) {
+ unsigned ret;
+
+ switch (wrap) {
+ case PIPE_TEX_WRAP_REPEAT:
+ ret = NV34TCL_TX_WRAP_S_REPEAT;
+ break;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
+ break;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
+ break;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
+ break;
+ case PIPE_TEX_WRAP_CLAMP:
+ ret = NV34TCL_TX_WRAP_S_CLAMP;
+ break;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
+ break;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
+ break;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ ret = NV40TCL_TEX_WRAP_S_MIRROR_CLAMP;
+ break;
+ default:
+ NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
+ ret = NV34TCL_TX_WRAP_S_REPEAT;
+ break;
+ }
+
+ return ret >> NV34TCL_TX_WRAP_S_SHIFT;
+}
+
+static inline unsigned
+nvfx_tex_wrap_compare_mode(const struct pipe_sampler_state* cso)
+{
+ if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ switch (cso->compare_func) {
+ case PIPE_FUNC_NEVER:
+ return NV34TCL_TX_WRAP_RCOMP_NEVER;
+ case PIPE_FUNC_GREATER:
+ return NV34TCL_TX_WRAP_RCOMP_GREATER;
+ case PIPE_FUNC_EQUAL:
+ return NV34TCL_TX_WRAP_RCOMP_EQUAL;
+ case PIPE_FUNC_GEQUAL:
+ return NV34TCL_TX_WRAP_RCOMP_GEQUAL;
+ case PIPE_FUNC_LESS:
+ return NV34TCL_TX_WRAP_RCOMP_LESS;
+ case PIPE_FUNC_NOTEQUAL:
+ return NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
+ case PIPE_FUNC_LEQUAL:
+ return NV34TCL_TX_WRAP_RCOMP_LEQUAL;
+ case PIPE_FUNC_ALWAYS:
+ return NV34TCL_TX_WRAP_RCOMP_ALWAYS;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+static inline unsigned nvfx_tex_filter(const struct pipe_sampler_state* cso)
+{
+ unsigned filter = 0;
+ switch (cso->mag_img_filter) {
+ case PIPE_TEX_FILTER_LINEAR:
+ filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
+ break;
+ case PIPE_TEX_FILTER_NEAREST:
+ default:
+ filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
+ break;
+ }
+
+ switch (cso->min_img_filter) {
+ case PIPE_TEX_FILTER_LINEAR:
+ switch (cso->min_mip_filter) {
+ case PIPE_TEX_MIPFILTER_NEAREST:
+ filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
+ break;
+ case PIPE_TEX_MIPFILTER_LINEAR:
+ filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
+ break;
+ case PIPE_TEX_MIPFILTER_NONE:
+ default:
+ filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
+ break;
+ }
+ break;
+ case PIPE_TEX_FILTER_NEAREST:
+ default:
+ switch (cso->min_mip_filter) {
+ case PIPE_TEX_MIPFILTER_NEAREST:
+ filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
+ break;
+ case PIPE_TEX_MIPFILTER_LINEAR:
+ filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
+ break;
+ case PIPE_TEX_MIPFILTER_NONE:
+ default:
+ filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
+ break;
+ }
+ break;
+ }
+ return filter;
+}
+
+static inline unsigned nvfx_tex_border_color(const float* border_color)
+{
+ return ((float_to_ubyte(border_color[3]) << 24) |
+ (float_to_ubyte(border_color[0]) << 16) |
+ (float_to_ubyte(border_color[1]) << 8) |
+ (float_to_ubyte(border_color[2]) << 0));
+}
+
+struct nvfx_sampler_state {
+ uint32_t fmt;
+ uint32_t wrap;
+ uint32_t en;
+ uint32_t filt;
+ uint32_t bcol;
+};
+
+#endif /* NVFX_TEX_H_ */
diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index 0462a042c38..1c250e9fe44 100644
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -5,18 +5,18 @@
#include "util/u_memory.h"
#include "util/u_math.h"
#include "nouveau/nouveau_winsys.h"
-#include "nv40_context.h"
-#include "nv40_screen.h"
-#include "nv40_state.h"
+#include "nvfx_context.h"
+#include "nvfx_screen.h"
+#include "nvfx_state.h"
-struct nv40_transfer {
+struct nvfx_transfer {
struct pipe_transfer base;
struct pipe_surface *surface;
boolean direct;
};
static void
-nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
+nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height,
struct pipe_texture *template)
{
memset(template, 0, sizeof(struct pipe_texture));
@@ -33,16 +33,20 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
}
static struct pipe_transfer *
-nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
- struct nv40_miptree *mt = (struct nv40_miptree *)pt;
- struct nv40_transfer *tx;
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
+ struct nvfx_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
+ static int no_transfer = -1;
+ if(no_transfer < 0)
+ no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/);
- tx = CALLOC_STRUCT(nv40_transfer);
+ tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
return NULL;
@@ -58,8 +62,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->base.zslice = zslice;
/* Direct access to texture */
- if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
- debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
{
tx->direct = true;
@@ -71,7 +74,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->direct = false;
- nv40_compatible_transfer_tex(pt, w, h, &tx_tex_template);
+ nvfx_compatible_transfer_tex(pt, w, h, &tx_tex_template);
tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
if (!tx_tex)
@@ -80,7 +83,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
return NULL;
}
- tx->base.stride = ((struct nv40_miptree*)tx_tex)->level[0].pitch;
+ tx->base.stride = ((struct nvfx_miptree*)tx_tex)->level[0].pitch;
tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
0, 0, 0,
@@ -96,7 +99,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
if (usage & PIPE_TRANSFER_READ) {
- struct nv40_screen *nvscreen = nv40_screen(pscreen);
+ struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *src;
src = pscreen->get_tex_surface(pscreen, pt,
@@ -117,13 +120,14 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
static void
-nv40_transfer_del(struct pipe_transfer *ptx)
+nvfx_transfer_del(struct pipe_context *pipe,
+ struct pipe_transfer *ptx)
{
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
+ struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = ptx->texture->screen;
- struct nv40_screen *nvscreen = nv40_screen(pscreen);
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *dst;
dst = pscreen->get_tex_surface(pscreen, ptx->texture,
@@ -145,11 +149,12 @@ nv40_transfer_del(struct pipe_transfer *ptx)
}
static void *
-nv40_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nvfx_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
- struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
void *map = pipe_buffer_map(pscreen, mt->buffer,
pipe_transfer_buffer_flags(ptx));
@@ -160,19 +165,20 @@ nv40_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
}
static void
-nv40_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct nv40_transfer *tx = (struct nv40_transfer *)ptx;
- struct nv40_miptree *mt = (struct nv40_miptree *)tx->surface->texture;
+ struct pipe_screen *pscreen = pipe->screen;
+ struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
+ struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
pipe_buffer_unmap(pscreen, mt->buffer);
}
void
-nv40_screen_init_transfer_functions(struct pipe_screen *pscreen)
+nvfx_init_transfer_functions(struct nvfx_context *nvfx)
{
- pscreen->get_tex_transfer = nv40_transfer_new;
- pscreen->tex_transfer_destroy = nv40_transfer_del;
- pscreen->transfer_map = nv40_transfer_map;
- pscreen->transfer_unmap = nv40_transfer_unmap;
+ nvfx->pipe.get_tex_transfer = nvfx_transfer_new;
+ nvfx->pipe.tex_transfer_destroy = nvfx_transfer_del;
+ nvfx->pipe.transfer_map = nvfx_transfer_map;
+ nvfx->pipe.transfer_unmap = nvfx_transfer_unmap;
}
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index e48823a9138..c26536b0e77 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -3,17 +3,24 @@
#include "util/u_inlines.h"
#include "util/u_format.h"
-#include "nv30_context.h"
-#include "nv30_state.h"
+#include "nvfx_context.h"
+#include "nvfx_state.h"
#include "nouveau/nouveau_channel.h"
#include "nouveau/nouveau_pushbuf.h"
#include "nouveau/nouveau_util.h"
-#define FORCE_SWTNL 0
+static boolean
+nvfx_force_swtnl(struct nvfx_context *nvfx)
+{
+ static int force_swtnl = -1;
+ if(force_swtnl < 0)
+ force_swtnl = debug_get_bool_option("NOUVEAU_SWTNL", 0);
+ return force_swtnl;
+}
static INLINE int
-nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
+nvfx_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
{
switch (pipe) {
case PIPE_FORMAT_R32_FLOAT:
@@ -69,15 +76,15 @@ nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
}
static boolean
-nv30_vbo_set_idxbuf(struct nv30_context *nv30, struct pipe_buffer *ib,
+nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_buffer *ib,
unsigned ib_size)
{
- struct pipe_screen *pscreen = &nv30->screen->base.base;
+ struct pipe_screen *pscreen = &nvfx->screen->base.base;
unsigned type;
if (!ib) {
- nv30->idxbuf = NULL;
- nv30->idxbuf_format = 0xdeadbeef;
+ nvfx->idxbuf = NULL;
+ nvfx->idxbuf_format = 0xdeadbeef;
return FALSE;
}
@@ -95,27 +102,27 @@ nv30_vbo_set_idxbuf(struct nv30_context *nv30, struct pipe_buffer *ib,
return FALSE;
}
- if (ib != nv30->idxbuf ||
- type != nv30->idxbuf_format) {
- nv30->dirty |= NV30_NEW_ARRAYS;
- nv30->idxbuf = ib;
- nv30->idxbuf_format = type;
+ if (ib != nvfx->idxbuf ||
+ type != nvfx->idxbuf_format) {
+ nvfx->dirty |= NVFX_NEW_ARRAYS;
+ nvfx->idxbuf = ib;
+ nvfx->idxbuf_format = type;
}
return TRUE;
}
static boolean
-nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
+nvfx_vbo_static_attrib(struct nvfx_context *nvfx, struct nouveau_stateobj *so,
int attrib, struct pipe_vertex_element *ve,
struct pipe_vertex_buffer *vb)
{
- struct pipe_screen *pscreen = nv30->pipe.screen;
- struct nouveau_grobj *rankine = nv30->screen->rankine;
+ struct pipe_screen *pscreen = nvfx->pipe.screen;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
unsigned type, ncomp;
void *map;
- if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp))
+ if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp))
return FALSE;
map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
@@ -128,25 +135,25 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
switch (ncomp) {
case 4:
- so_method(so, rankine, NV34TCL_VTX_ATTR_4F_X(attrib), 4);
+ so_method(so, eng3d, NV34TCL_VTX_ATTR_4F_X(attrib), 4);
so_data (so, fui(v[0]));
so_data (so, fui(v[1]));
so_data (so, fui(v[2]));
so_data (so, fui(v[3]));
break;
case 3:
- so_method(so, rankine, NV34TCL_VTX_ATTR_3F_X(attrib), 3);
+ so_method(so, eng3d, NV34TCL_VTX_ATTR_3F_X(attrib), 3);
so_data (so, fui(v[0]));
so_data (so, fui(v[1]));
so_data (so, fui(v[2]));
break;
case 2:
- so_method(so, rankine, NV34TCL_VTX_ATTR_2F_X(attrib), 2);
+ so_method(so, eng3d, NV34TCL_VTX_ATTR_2F_X(attrib), 2);
so_data (so, fui(v[0]));
so_data (so, fui(v[1]));
break;
case 1:
- so_method(so, rankine, NV34TCL_VTX_ATTR_1F(attrib), 1);
+ so_method(so, eng3d, NV34TCL_VTX_ATTR_1F(attrib), 1);
so_data (so, fui(v[0]));
break;
default:
@@ -165,26 +172,26 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
}
void
-nv30_draw_arrays(struct pipe_context *pipe,
+nvfx_draw_arrays(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_screen *screen = nv30->screen;
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
+ struct nouveau_grobj *eng3d = screen->eng3d;
unsigned restart = 0;
- nv30_vbo_set_idxbuf(nv30, NULL, 0);
- if (FORCE_SWTNL || !nv30_state_validate(nv30)) {
- /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
- mode, start, count);*/
- return;
+ nvfx_vbo_set_idxbuf(nvfx, NULL, 0);
+ if (nvfx_force_swtnl(nvfx) || !nvfx_state_validate(nvfx)) {
+ nvfx_draw_elements_swtnl(pipe, NULL, 0,
+ mode, start, count);
+ return;
}
while (count) {
unsigned vc, nr;
- nv30_state_emit(nv30);
+ nvfx_state_emit(nvfx);
vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
mode, start, count, &restart);
@@ -193,12 +200,12 @@ nv30_draw_arrays(struct pipe_context *pipe,
continue;
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, nvgl_primitive(mode));
nr = (vc & 0xff);
if (nr) {
- BEGIN_RING(chan, rankine, NV34TCL_VB_VERTEX_BATCH, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, 1);
OUT_RING (chan, ((nr - 1) << 24) | start);
start += nr;
}
@@ -209,14 +216,14 @@ nv30_draw_arrays(struct pipe_context *pipe,
nr -= push;
- BEGIN_RING_NI(chan, rankine, NV34TCL_VB_VERTEX_BATCH, push);
+ BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_VERTEX_BATCH, push);
while (push--) {
OUT_RING(chan, ((0x100 - 1) << 24) | start);
start += 0x100;
}
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, 0);
count -= vc;
@@ -227,18 +234,18 @@ nv30_draw_arrays(struct pipe_context *pipe,
}
static INLINE void
-nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
+nvfx_draw_elements_u08(struct nvfx_context *nvfx, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_screen *screen = nv30->screen;
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
+ struct nouveau_grobj *eng3d = screen->eng3d;
while (count) {
uint8_t *elts = (uint8_t *)ib + start;
unsigned vc, push, restart = 0;
- nv30_state_emit(nv30);
+ nvfx_state_emit(nvfx);
vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
mode, start, count, &restart);
@@ -248,11 +255,11 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
}
count -= vc;
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, nvgl_primitive(mode));
if (vc & 1) {
- BEGIN_RING(chan, rankine, NV34TCL_VB_ELEMENT_U32, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, elts[0]);
elts++; vc--;
}
@@ -262,7 +269,7 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
push = MIN2(vc, 2047 * 2);
- BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
+ BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
for (i = 0; i < push; i+=2)
OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
@@ -270,7 +277,7 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
elts += push;
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, 0);
start = restart;
@@ -278,18 +285,18 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
}
static INLINE void
-nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
+nvfx_draw_elements_u16(struct nvfx_context *nvfx, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_screen *screen = nv30->screen;
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
+ struct nouveau_grobj *eng3d = screen->eng3d;
while (count) {
uint16_t *elts = (uint16_t *)ib + start;
unsigned vc, push, restart = 0;
- nv30_state_emit(nv30);
+ nvfx_state_emit(nvfx);
vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2,
mode, start, count, &restart);
@@ -299,11 +306,11 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
}
count -= vc;
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, nvgl_primitive(mode));
if (vc & 1) {
- BEGIN_RING(chan, rankine, NV34TCL_VB_ELEMENT_U32, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VB_ELEMENT_U32, 1);
OUT_RING (chan, elts[0]);
elts++; vc--;
}
@@ -313,7 +320,7 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
push = MIN2(vc, 2047 * 2);
- BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U16, push >> 1);
+ BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U16, push >> 1);
for (i = 0; i < push; i+=2)
OUT_RING(chan, (elts[i+1] << 16) | elts[i]);
@@ -321,7 +328,7 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
elts += push;
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, 0);
start = restart;
@@ -329,18 +336,18 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
}
static INLINE void
-nv30_draw_elements_u32(struct nv30_context *nv30, void *ib,
+nvfx_draw_elements_u32(struct nvfx_context *nvfx, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_screen *screen = nv30->screen;
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
+ struct nouveau_grobj *eng3d = screen->eng3d;
while (count) {
uint32_t *elts = (uint32_t *)ib + start;
unsigned vc, push, restart = 0;
- nv30_state_emit(nv30);
+ nvfx_state_emit(nvfx);
vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1,
mode, start, count, &restart);
@@ -350,20 +357,20 @@ nv30_draw_elements_u32(struct nv30_context *nv30, void *ib,
}
count -= vc;
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, nvgl_primitive(mode));
while (vc) {
push = MIN2(vc, 2047);
- BEGIN_RING_NI(chan, rankine, NV34TCL_VB_ELEMENT_U32, push);
+ BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_ELEMENT_U32, push);
OUT_RINGp (chan, elts, push);
vc -= push;
elts += push;
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, 0);
start = restart;
@@ -371,11 +378,11 @@ nv30_draw_elements_u32(struct nv30_context *nv30, void *ib,
}
static void
-nv30_draw_elements_inline(struct pipe_context *pipe,
+nvfx_draw_elements_inline(struct pipe_context *pipe,
struct pipe_buffer *ib, unsigned ib_size,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_context *nv30 = nv30_context(pipe);
+ struct nvfx_context *nvfx = nvfx_context(pipe);
struct pipe_screen *pscreen = pipe->screen;
void *map;
@@ -387,13 +394,13 @@ nv30_draw_elements_inline(struct pipe_context *pipe,
switch (ib_size) {
case 1:
- nv30_draw_elements_u08(nv30, map, mode, start, count);
+ nvfx_draw_elements_u08(nvfx, map, mode, start, count);
break;
case 2:
- nv30_draw_elements_u16(nv30, map, mode, start, count);
+ nvfx_draw_elements_u16(nvfx, map, mode, start, count);
break;
case 4:
- nv30_draw_elements_u32(nv30, map, mode, start, count);
+ nvfx_draw_elements_u32(nvfx, map, mode, start, count);
break;
default:
NOUVEAU_ERR("invalid idxbuf fmt %d\n", ib_size);
@@ -404,19 +411,19 @@ nv30_draw_elements_inline(struct pipe_context *pipe,
}
static void
-nv30_draw_elements_vbo(struct pipe_context *pipe,
+nvfx_draw_elements_vbo(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_context *nv30 = nv30_context(pipe);
- struct nv30_screen *screen = nv30->screen;
+ struct nvfx_context *nvfx = nvfx_context(pipe);
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *rankine = screen->rankine;
+ struct nouveau_grobj *eng3d = screen->eng3d;
unsigned restart = 0;
while (count) {
unsigned nr, vc;
- nv30_state_emit(nv30);
+ nvfx_state_emit(nvfx);
vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256,
mode, start, count, &restart);
@@ -425,12 +432,12 @@ nv30_draw_elements_vbo(struct pipe_context *pipe,
continue;
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, nvgl_primitive(mode));
nr = (vc & 0xff);
if (nr) {
- BEGIN_RING(chan, rankine, NV34TCL_VB_INDEX_BATCH, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VB_INDEX_BATCH, 1);
OUT_RING (chan, ((nr - 1) << 24) | start);
start += nr;
}
@@ -441,14 +448,14 @@ nv30_draw_elements_vbo(struct pipe_context *pipe,
nr -= push;
- BEGIN_RING_NI(chan, rankine, NV34TCL_VB_INDEX_BATCH, push);
+ BEGIN_RING_NI(chan, eng3d, NV34TCL_VB_INDEX_BATCH, push);
while (push--) {
OUT_RING(chan, ((0x100 - 1) << 24) | start);
start += 0x100;
}
}
- BEGIN_RING(chan, rankine, NV34TCL_VERTEX_BEGIN_END, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VERTEX_BEGIN_END, 1);
OUT_RING (chan, 0);
count -= vc;
@@ -457,24 +464,24 @@ nv30_draw_elements_vbo(struct pipe_context *pipe,
}
void
-nv30_draw_elements(struct pipe_context *pipe,
+nvfx_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct nv30_context *nv30 = nv30_context(pipe);
+ struct nvfx_context *nvfx = nvfx_context(pipe);
boolean idxbuf;
- idxbuf = nv30_vbo_set_idxbuf(nv30, indexBuffer, indexSize);
- if (FORCE_SWTNL || !nv30_state_validate(nv30)) {
- /*return nv30_draw_elements_swtnl(pipe, NULL, 0,
- mode, start, count);*/
+ idxbuf = nvfx_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
+ if (nvfx_force_swtnl(nvfx) || !nvfx_state_validate(nvfx)) {
+ nvfx_draw_elements_swtnl(pipe, indexBuffer, indexSize,
+ mode, start, count);
return;
}
if (idxbuf) {
- nv30_draw_elements_vbo(pipe, mode, start, count);
+ nvfx_draw_elements_vbo(pipe, mode, start, count);
} else {
- nv30_draw_elements_inline(pipe, indexBuffer, indexSize,
+ nvfx_draw_elements_inline(pipe, indexBuffer, indexSize,
mode, start, count);
}
@@ -482,49 +489,50 @@ nv30_draw_elements(struct pipe_context *pipe,
}
static boolean
-nv30_vbo_validate(struct nv30_context *nv30)
+nvfx_vbo_validate(struct nvfx_context *nvfx)
{
struct nouveau_stateobj *vtxbuf, *vtxfmt, *sattr = NULL;
- struct nouveau_grobj *rankine = nv30->screen->rankine;
- struct pipe_buffer *ib = nv30->idxbuf;
- unsigned ib_format = nv30->idxbuf_format;
- unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
+ struct pipe_buffer *ib = nvfx->idxbuf;
+ unsigned ib_format = nvfx->idxbuf_format;
+ unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
int hw;
vtxbuf = so_new(3, 17, 18);
- so_method(vtxbuf, rankine, NV34TCL_VTXBUF_ADDRESS(0), nv30->vtxelt_nr);
+ so_method(vtxbuf, eng3d, NV34TCL_VTXBUF_ADDRESS(0), nvfx->vtxelt->num_elements);
vtxfmt = so_new(1, 16, 0);
- so_method(vtxfmt, rankine, NV34TCL_VTXFMT(0), nv30->vtxelt_nr);
+ so_method(vtxfmt, eng3d, NV34TCL_VTXFMT(0), nvfx->vtxelt->num_elements);
- for (hw = 0; hw < nv30->vtxelt_nr; hw++) {
+ for (hw = 0; hw < nvfx->vtxelt->num_elements; hw++) {
struct pipe_vertex_element *ve;
struct pipe_vertex_buffer *vb;
unsigned type, ncomp;
- ve = &nv30->vtxelt[hw];
- vb = &nv30->vtxbuf[ve->vertex_buffer_index];
+ ve = &nvfx->vtxelt->pipe[hw];
+ vb = &nvfx->vtxbuf[ve->vertex_buffer_index];
if (!vb->stride) {
if (!sattr)
sattr = so_new(16, 16 * 4, 0);
- if (nv30_vbo_static_attrib(nv30, sattr, hw, ve, vb)) {
+ if (nvfx_vbo_static_attrib(nvfx, sattr, hw, ve, vb)) {
so_data(vtxbuf, 0);
so_data(vtxfmt, NV34TCL_VTXFMT_TYPE_FLOAT);
continue;
}
}
- if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
- /*nv30->fallback_swtnl |= NV30_NEW_ARRAYS;*/
+ if (nvfx_vbo_format_to_hw(ve->src_format, &type, &ncomp)) {
+ nvfx->fallback_swtnl |= NVFX_NEW_ARRAYS;
so_ref(NULL, &vtxbuf);
so_ref(NULL, &vtxfmt);
return FALSE;
}
- so_reloc(vtxbuf, nouveau_bo(vb->buffer), vb->buffer_offset +
- ve->src_offset, vb_flags | NOUVEAU_BO_LOW |
- NOUVEAU_BO_OR, 0, NV34TCL_VTXBUF_ADDRESS_DMA1);
+ so_reloc(vtxbuf, nouveau_bo(vb->buffer),
+ vb->buffer_offset + ve->src_offset,
+ vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+ 0, NV34TCL_VTXBUF_ADDRESS_DMA1);
so_data (vtxfmt, ((vb->stride << NV34TCL_VTXFMT_STRIDE_SHIFT) |
(ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type));
}
@@ -532,31 +540,31 @@ nv30_vbo_validate(struct nv30_context *nv30)
if (ib) {
struct nouveau_bo *bo = nouveau_bo(ib);
- so_method(vtxbuf, rankine, NV34TCL_IDXBUF_ADDRESS, 2);
+ so_method(vtxbuf, eng3d, NV34TCL_IDXBUF_ADDRESS, 2);
so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
0, NV34TCL_IDXBUF_FORMAT_DMA1);
}
- so_method(vtxbuf, rankine, 0x1710, 1);
+ so_method(vtxbuf, eng3d, 0x1710, 1);
so_data (vtxbuf, 0);
- so_ref(vtxbuf, &nv30->state.hw[NV30_STATE_VTXBUF]);
+ so_ref(vtxbuf, &nvfx->state.hw[NVFX_STATE_VTXBUF]);
so_ref(NULL, &vtxbuf);
- nv30->state.dirty |= (1ULL << NV30_STATE_VTXBUF);
- so_ref(vtxfmt, &nv30->state.hw[NV30_STATE_VTXFMT]);
+ nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXBUF);
+ so_ref(vtxfmt, &nvfx->state.hw[NVFX_STATE_VTXFMT]);
so_ref(NULL, &vtxfmt);
- nv30->state.dirty |= (1ULL << NV30_STATE_VTXFMT);
- so_ref(sattr, &nv30->state.hw[NV30_STATE_VTXATTR]);
+ nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXFMT);
+ so_ref(sattr, &nvfx->state.hw[NVFX_STATE_VTXATTR]);
so_ref(NULL, &sattr);
- nv30->state.dirty |= (1ULL << NV30_STATE_VTXATTR);
+ nvfx->state.dirty |= (1ULL << NVFX_STATE_VTXATTR);
return FALSE;
}
-struct nv30_state_entry nv30_state_vbo = {
- .validate = nv30_vbo_validate,
+struct nvfx_state_entry nvfx_state_vbo = {
+ .validate = nvfx_vbo_validate,
.dirty = {
- .pipe = NV30_NEW_ARRAYS,
+ .pipe = NVFX_NEW_ARRAYS,
.hw = 0,
}
};
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c
index c93c5d127c4..2d243be16a3 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c
@@ -5,10 +5,11 @@
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_util.h"
-#include "nv40_context.h"
-#include "nv40_state.h"
+#include "nvfx_context.h"
+#include "nvfx_state.h"
/* TODO (at least...):
* 1. Indexed consts + ARL
@@ -21,76 +22,62 @@
* 4. bugs
*/
-#define SWZ_X 0
-#define SWZ_Y 1
-#define SWZ_Z 2
-#define SWZ_W 3
-#define MASK_X 8
-#define MASK_Y 4
-#define MASK_Z 2
-#define MASK_W 1
-#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W)
-#define DEF_SCALE 0
-#define DEF_CTEST 0
-#include "nv40_shader.h"
+#include "nv30_vertprog.h"
+#include "nv40_vertprog.h"
-#define swz(s,x,y,z,w) nv40_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w)
-#define neg(s) nv40_sr_neg((s))
-#define abs(s) nv40_sr_abs((s))
+#define NVFX_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n))
-#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n))
+struct nvfx_vpc {
+ struct nvfx_vertex_program *vp;
-struct nv40_vpc {
- struct nv40_vertex_program *vp;
-
- struct nv40_vertex_program_exec *vpi;
+ struct nvfx_vertex_program_exec *vpi;
unsigned r_temps;
unsigned r_temps_discard;
- struct nv40_sreg r_result[PIPE_MAX_SHADER_OUTPUTS];
- struct nv40_sreg *r_address;
- struct nv40_sreg *r_temp;
+ struct nvfx_sreg r_result[PIPE_MAX_SHADER_OUTPUTS];
+ struct nvfx_sreg *r_address;
+ struct nvfx_sreg *r_temp;
- struct nv40_sreg *imm;
+ struct nvfx_sreg *imm;
unsigned nr_imm;
unsigned hpos_idx;
};
-static struct nv40_sreg
-temp(struct nv40_vpc *vpc)
+static struct nvfx_sreg
+temp(struct nvfx_vpc *vpc)
{
int idx = ffs(~vpc->r_temps) - 1;
if (idx < 0) {
NOUVEAU_ERR("out of temps!!\n");
assert(0);
- return nv40_sr(NV40SR_TEMP, 0);
+ return nvfx_sr(NVFXSR_TEMP, 0);
}
vpc->r_temps |= (1 << idx);
vpc->r_temps_discard |= (1 << idx);
- return nv40_sr(NV40SR_TEMP, idx);
+ return nvfx_sr(NVFXSR_TEMP, idx);
}
static INLINE void
-release_temps(struct nv40_vpc *vpc)
+release_temps(struct nvfx_vpc *vpc)
{
vpc->r_temps &= ~vpc->r_temps_discard;
vpc->r_temps_discard = 0;
}
-static struct nv40_sreg
-constant(struct nv40_vpc *vpc, int pipe, float x, float y, float z, float w)
+static struct nvfx_sreg
+constant(struct nvfx_vpc *vpc, int pipe, float x, float y, float z, float w)
{
- struct nv40_vertex_program *vp = vpc->vp;
- struct nv40_vertex_program_data *vpd;
+ struct nvfx_vertex_program *vp = vpc->vp;
+ struct nvfx_vertex_program_data *vpd;
int idx;
if (pipe >= 0) {
for (idx = 0; idx < vp->nr_consts; idx++) {
if (vp->consts[idx].index == pipe)
- return nv40_sr(NV40SR_CONST, idx);
+ return nvfx_sr(NVFXSR_CONST, idx);
}
}
@@ -103,70 +90,70 @@ constant(struct nv40_vpc *vpc, int pipe, float x, float y, float z, float w)
vpd->value[1] = y;
vpd->value[2] = z;
vpd->value[3] = w;
- return nv40_sr(NV40SR_CONST, idx);
+ return nvfx_sr(NVFXSR_CONST, idx);
}
#define arith(cc,s,o,d,m,s0,s1,s2) \
- nv40_vp_arith((cc), (s), NV40_VP_INST_##o, (d), (m), (s0), (s1), (s2))
+ nvfx_vp_arith(nvfx, (cc), NVFX_VP_INST_SLOT_##s, NVFX_VP_INST_##s##_OP_##o, (d), (m), (s0), (s1), (s2))
static void
-emit_src(struct nv40_vpc *vpc, uint32_t *hw, int pos, struct nv40_sreg src)
+emit_src(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, uint32_t *hw, int pos, struct nvfx_sreg src)
{
- struct nv40_vertex_program *vp = vpc->vp;
+ struct nvfx_vertex_program *vp = vpc->vp;
uint32_t sr = 0;
switch (src.type) {
- case NV40SR_TEMP:
- sr |= (NV40_VP_SRC_REG_TYPE_TEMP << NV40_VP_SRC_REG_TYPE_SHIFT);
- sr |= (src.index << NV40_VP_SRC_TEMP_SRC_SHIFT);
+ case NVFXSR_TEMP:
+ sr |= (NVFX_VP(SRC_REG_TYPE_TEMP) << NVFX_VP(SRC_REG_TYPE_SHIFT));
+ sr |= (src.index << NVFX_VP(SRC_TEMP_SRC_SHIFT));
break;
- case NV40SR_INPUT:
- sr |= (NV40_VP_SRC_REG_TYPE_INPUT <<
- NV40_VP_SRC_REG_TYPE_SHIFT);
+ case NVFXSR_INPUT:
+ sr |= (NVFX_VP(SRC_REG_TYPE_INPUT) <<
+ NVFX_VP(SRC_REG_TYPE_SHIFT));
vp->ir |= (1 << src.index);
- hw[1] |= (src.index << NV40_VP_INST_INPUT_SRC_SHIFT);
+ hw[1] |= (src.index << NVFX_VP(INST_INPUT_SRC_SHIFT));
break;
- case NV40SR_CONST:
- sr |= (NV40_VP_SRC_REG_TYPE_CONST <<
- NV40_VP_SRC_REG_TYPE_SHIFT);
+ case NVFXSR_CONST:
+ sr |= (NVFX_VP(SRC_REG_TYPE_CONST) <<
+ NVFX_VP(SRC_REG_TYPE_SHIFT));
assert(vpc->vpi->const_index == -1 ||
vpc->vpi->const_index == src.index);
vpc->vpi->const_index = src.index;
break;
- case NV40SR_NONE:
- sr |= (NV40_VP_SRC_REG_TYPE_INPUT <<
- NV40_VP_SRC_REG_TYPE_SHIFT);
+ case NVFXSR_NONE:
+ sr |= (NVFX_VP(SRC_REG_TYPE_INPUT) <<
+ NVFX_VP(SRC_REG_TYPE_SHIFT));
break;
default:
assert(0);
}
if (src.negate)
- sr |= NV40_VP_SRC_NEGATE;
+ sr |= NVFX_VP(SRC_NEGATE);
if (src.abs)
hw[0] |= (1 << (21 + pos));
- sr |= ((src.swz[0] << NV40_VP_SRC_SWZ_X_SHIFT) |
- (src.swz[1] << NV40_VP_SRC_SWZ_Y_SHIFT) |
- (src.swz[2] << NV40_VP_SRC_SWZ_Z_SHIFT) |
- (src.swz[3] << NV40_VP_SRC_SWZ_W_SHIFT));
+ sr |= ((src.swz[0] << NVFX_VP(SRC_SWZ_X_SHIFT)) |
+ (src.swz[1] << NVFX_VP(SRC_SWZ_Y_SHIFT)) |
+ (src.swz[2] << NVFX_VP(SRC_SWZ_Z_SHIFT)) |
+ (src.swz[3] << NVFX_VP(SRC_SWZ_W_SHIFT)));
switch (pos) {
case 0:
- hw[1] |= ((sr & NV40_VP_SRC0_HIGH_MASK) >>
- NV40_VP_SRC0_HIGH_SHIFT) << NV40_VP_INST_SRC0H_SHIFT;
- hw[2] |= (sr & NV40_VP_SRC0_LOW_MASK) <<
- NV40_VP_INST_SRC0L_SHIFT;
+ hw[1] |= ((sr & NVFX_VP(SRC0_HIGH_MASK)) >>
+ NVFX_VP(SRC0_HIGH_SHIFT)) << NVFX_VP(INST_SRC0H_SHIFT);
+ hw[2] |= (sr & NVFX_VP(SRC0_LOW_MASK)) <<
+ NVFX_VP(INST_SRC0L_SHIFT);
break;
case 1:
- hw[2] |= sr << NV40_VP_INST_SRC1_SHIFT;
+ hw[2] |= sr << NVFX_VP(INST_SRC1_SHIFT);
break;
case 2:
- hw[2] |= ((sr & NV40_VP_SRC2_HIGH_MASK) >>
- NV40_VP_SRC2_HIGH_SHIFT) << NV40_VP_INST_SRC2H_SHIFT;
- hw[3] |= (sr & NV40_VP_SRC2_LOW_MASK) <<
- NV40_VP_INST_SRC2L_SHIFT;
+ hw[2] |= ((sr & NVFX_VP(SRC2_HIGH_MASK)) >>
+ NVFX_VP(SRC2_HIGH_SHIFT)) << NVFX_VP(INST_SRC2H_SHIFT);
+ hw[3] |= (sr & NVFX_VP(SRC2_LOW_MASK)) <<
+ NVFX_VP(INST_SRC2L_SHIFT);
break;
default:
assert(0);
@@ -174,78 +161,114 @@ emit_src(struct nv40_vpc *vpc, uint32_t *hw, int pos, struct nv40_sreg src)
}
static void
-emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst)
+emit_dst(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, uint32_t *hw, int slot, struct nvfx_sreg dst)
{
- struct nv40_vertex_program *vp = vpc->vp;
+ struct nvfx_vertex_program *vp = vpc->vp;
switch (dst.type) {
- case NV40SR_TEMP:
- hw[3] |= NV40_VP_INST_DEST_MASK;
- if (slot == 0) {
- hw[0] |= (dst.index <<
- NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
- } else {
- hw[3] |= (dst.index <<
- NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ case NVFXSR_TEMP:
+ if(!nvfx->is_nv4x)
+ hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT);
+ else {
+ hw[3] |= NV40_VP_INST_DEST_MASK;
+ if (slot == 0) {
+ hw[0] |= (dst.index <<
+ NV40_VP_INST_VEC_DEST_TEMP_SHIFT);
+ } else {
+ hw[3] |= (dst.index <<
+ NV40_VP_INST_SCA_DEST_TEMP_SHIFT);
+ }
}
break;
- case NV40SR_OUTPUT:
+ case NVFXSR_OUTPUT:
+ /* TODO: this may be wrong because on nv30 COL0 and BFC0 are swapped */
switch (dst.index) {
- case NV40_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break;
- case NV40_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break;
- case NV40_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break;
- case NV40_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break;
- case NV40_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break;
- case NV40_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
- case NV40_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break;
- case NV40_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break;
- case NV40_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break;
- case NV40_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break;
- case NV40_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break;
- case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
- case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
- case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
- case NV40_VP_INST_DEST_CLIP(0):
+ case NVFX_VP_INST_DEST_CLIP(0):
vp->or |= (1 << 6);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0;
- dst.index = NV40_VP_INST_DEST_FOGC;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE0;
+ dst.index = NVFX_VP(INST_DEST_FOGC);
break;
- case NV40_VP_INST_DEST_CLIP(1):
+ case NVFX_VP_INST_DEST_CLIP(1):
vp->or |= (1 << 7);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1;
- dst.index = NV40_VP_INST_DEST_FOGC;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE1;
+ dst.index = NVFX_VP(INST_DEST_FOGC);
break;
- case NV40_VP_INST_DEST_CLIP(2):
+ case NVFX_VP_INST_DEST_CLIP(2):
vp->or |= (1 << 8);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2;
- dst.index = NV40_VP_INST_DEST_FOGC;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE2;
+ dst.index = NVFX_VP(INST_DEST_FOGC);
break;
- case NV40_VP_INST_DEST_CLIP(3):
+ case NVFX_VP_INST_DEST_CLIP(3):
vp->or |= (1 << 9);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3;
- dst.index = NV40_VP_INST_DEST_PSZ;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE3;
+ dst.index = NVFX_VP(INST_DEST_PSZ);
break;
- case NV40_VP_INST_DEST_CLIP(4):
+ case NVFX_VP_INST_DEST_CLIP(4):
vp->or |= (1 << 10);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4;
- dst.index = NV40_VP_INST_DEST_PSZ;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE4;
+ dst.index = NVFX_VP(INST_DEST_PSZ);
break;
- case NV40_VP_INST_DEST_CLIP(5):
+ case NVFX_VP_INST_DEST_CLIP(5):
vp->or |= (1 << 11);
- vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5;
- dst.index = NV40_VP_INST_DEST_PSZ;
+ vp->clip_ctrl |= NV34TCL_VP_CLIP_PLANES_ENABLE_PLANE5;
+ dst.index = NVFX_VP(INST_DEST_PSZ);
break;
default:
+ if(!nvfx->is_nv4x) {
+ switch (dst.index) {
+ case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break;
+ case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break;
+ case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break;
+ case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break;
+ case NV30_VP_INST_DEST_FOGC: vp->or |= (1 << 4); break;
+ case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
+ case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break;
+ case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break;
+ case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break;
+ case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break;
+ case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break;
+ case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
+ case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
+ case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
+ }
+ } else {
+ switch (dst.index) {
+ case NV40_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break;
+ case NV40_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break;
+ case NV40_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break;
+ case NV40_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break;
+ case NV40_VP_INST_DEST_FOGC: vp->or |= (1 << 4); break;
+ case NV40_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break;
+ case NV40_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break;
+ case NV40_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break;
+ case NV40_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break;
+ case NV40_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break;
+ case NV40_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break;
+ case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
+ case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
+ case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
+ }
+ }
break;
}
- hw[3] |= (dst.index << NV40_VP_INST_DEST_SHIFT);
- if (slot == 0) {
- hw[0] |= NV40_VP_INST_VEC_RESULT;
- hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
+ if(!nvfx->is_nv4x) {
+ hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT);
+ hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
+
+ /*XXX: no way this is entirely correct, someone needs to
+ * figure out what exactly it is.
+ */
+ hw[3] |= 0x800;
} else {
- hw[3] |= NV40_VP_INST_SCA_RESULT;
- hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+ hw[3] |= (dst.index << NV40_VP_INST_DEST_SHIFT);
+ if (slot == 0) {
+ hw[0] |= NV40_VP_INST_VEC_RESULT;
+ hw[0] |= NV40_VP_INST_VEC_DEST_TEMP_MASK | (1<<20);
+ } else {
+ hw[3] |= NV40_VP_INST_SCA_RESULT;
+ hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+ }
}
break;
default:
@@ -254,12 +277,12 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst)
}
static void
-nv40_vp_arith(struct nv40_vpc *vpc, int slot, int op,
- struct nv40_sreg dst, int mask,
- struct nv40_sreg s0, struct nv40_sreg s1,
- struct nv40_sreg s2)
+nvfx_vp_arith(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, int slot, int op,
+ struct nvfx_sreg dst, int mask,
+ struct nvfx_sreg s0, struct nvfx_sreg s1,
+ struct nvfx_sreg s2)
{
- struct nv40_vertex_program *vp = vpc->vp;
+ struct nvfx_vertex_program *vp = vpc->vp;
uint32_t *hw;
vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi));
@@ -269,35 +292,53 @@ nv40_vp_arith(struct nv40_vpc *vpc, int slot, int op,
hw = vpc->vpi->data;
- hw[0] |= (NV40_VP_INST_COND_TR << NV40_VP_INST_COND_SHIFT);
- hw[0] |= ((0 << NV40_VP_INST_COND_SWZ_X_SHIFT) |
- (1 << NV40_VP_INST_COND_SWZ_Y_SHIFT) |
- (2 << NV40_VP_INST_COND_SWZ_Z_SHIFT) |
- (3 << NV40_VP_INST_COND_SWZ_W_SHIFT));
-
- if (slot == 0) {
- hw[1] |= (op << NV40_VP_INST_VEC_OPCODE_SHIFT);
- hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
- hw[3] |= (mask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
- } else {
- hw[1] |= (op << NV40_VP_INST_SCA_OPCODE_SHIFT);
- hw[0] |= (NV40_VP_INST_VEC_DEST_TEMP_MASK | (1 << 20));
- hw[3] |= (mask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
+ hw[0] |= (NVFX_COND_TR << NVFX_VP(INST_COND_SHIFT));
+ hw[0] |= ((0 << NVFX_VP(INST_COND_SWZ_X_SHIFT)) |
+ (1 << NVFX_VP(INST_COND_SWZ_Y_SHIFT)) |
+ (2 << NVFX_VP(INST_COND_SWZ_Z_SHIFT)) |
+ (3 << NVFX_VP(INST_COND_SWZ_W_SHIFT)));
+
+ if(!nvfx->is_nv4x) {
+ hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT);
+// hw[3] |= NVFX_VP(INST_SCA_DEST_TEMP_MASK);
+// hw[3] |= (mask << NVFX_VP(INST_VEC_WRITEMASK_SHIFT));
+
+ if (dst.type == NVFXSR_OUTPUT) {
+ if (slot)
+ hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT);
+ else
+ hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT);
+ } else {
+ if (slot)
+ hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT);
+ else
+ hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT);
+ }
+ } else {
+ if (slot == 0) {
+ hw[1] |= (op << NV40_VP_INST_VEC_OPCODE_SHIFT);
+ hw[3] |= NV40_VP_INST_SCA_DEST_TEMP_MASK;
+ hw[3] |= (mask << NV40_VP_INST_VEC_WRITEMASK_SHIFT);
+ } else {
+ hw[1] |= (op << NV40_VP_INST_SCA_OPCODE_SHIFT);
+ hw[0] |= (NV40_VP_INST_VEC_DEST_TEMP_MASK | (1 << 20));
+ hw[3] |= (mask << NV40_VP_INST_SCA_WRITEMASK_SHIFT);
+ }
}
- emit_dst(vpc, hw, slot, dst);
- emit_src(vpc, hw, 0, s0);
- emit_src(vpc, hw, 1, s1);
- emit_src(vpc, hw, 2, s2);
+ emit_dst(nvfx, vpc, hw, slot, dst);
+ emit_src(nvfx, vpc, hw, 0, s0);
+ emit_src(nvfx, vpc, hw, 1, s1);
+ emit_src(nvfx, vpc, hw, 2, s2);
}
-static INLINE struct nv40_sreg
-tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
- struct nv40_sreg src;
+static INLINE struct nvfx_sreg
+tgsi_src(struct nvfx_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
+ struct nvfx_sreg src;
switch (fsrc->Register.File) {
case TGSI_FILE_INPUT:
- src = nv40_sr(NV40SR_INPUT, fsrc->Register.Index);
+ src = nvfx_sr(NVFXSR_INPUT, fsrc->Register.Index);
break;
case TGSI_FILE_CONSTANT:
src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0);
@@ -322,9 +363,9 @@ tgsi_src(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc) {
return src;
}
-static INLINE struct nv40_sreg
-tgsi_dst(struct nv40_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
- struct nv40_sreg dst;
+static INLINE struct nvfx_sreg
+tgsi_dst(struct nvfx_vpc *vpc, const struct tgsi_full_dst_register *fdst) {
+ struct nvfx_sreg dst;
switch (fdst->Register.File) {
case TGSI_FILE_OUTPUT:
@@ -349,52 +390,19 @@ tgsi_mask(uint tgsi)
{
int mask = 0;
- if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X;
- if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y;
- if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z;
- if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W;
+ if (tgsi & TGSI_WRITEMASK_X) mask |= NVFX_VP_MASK_X;
+ if (tgsi & TGSI_WRITEMASK_Y) mask |= NVFX_VP_MASK_Y;
+ if (tgsi & TGSI_WRITEMASK_Z) mask |= NVFX_VP_MASK_Z;
+ if (tgsi & TGSI_WRITEMASK_W) mask |= NVFX_VP_MASK_W;
return mask;
}
static boolean
-src_native_swz(struct nv40_vpc *vpc, const struct tgsi_full_src_register *fsrc,
- struct nv40_sreg *src)
-{
- const struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0);
- struct nv40_sreg tgsi = tgsi_src(vpc, fsrc);
- uint mask = 0;
- uint c;
-
- for (c = 0; c < 4; c++) {
- switch (tgsi_util_get_full_src_register_swizzle(fsrc, c)) {
- case TGSI_SWIZZLE_X:
- case TGSI_SWIZZLE_Y:
- case TGSI_SWIZZLE_Z:
- case TGSI_SWIZZLE_W:
- mask |= tgsi_mask(1 << c);
- break;
- default:
- assert(0);
- }
- }
-
- if (mask == MASK_ALL)
- return TRUE;
-
- *src = temp(vpc);
-
- if (mask)
- arith(vpc, 0, OP_MOV, *src, mask, tgsi, none, none);
-
- return FALSE;
-}
-
-static boolean
-nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
+nvfx_vertprog_parse_instruction(struct nvfx_context* nvfx, struct nvfx_vpc *vpc,
const struct tgsi_full_instruction *finst)
{
- struct nv40_sreg src[3], dst, tmp;
- struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0);
+ struct nvfx_sreg src[3], dst, tmp;
+ struct nvfx_sreg none = nvfx_sr(NVFXSR_NONE, 0);
int mask;
int ai = -1, ci = -1, ii = -1;
int i;
@@ -418,23 +426,12 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
switch (fsrc->Register.File) {
case TGSI_FILE_INPUT:
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_TEMPORARY:
- if (!src_native_swz(vpc, fsrc, &src[i]))
- continue;
- break;
- default:
- break;
- }
-
- switch (fsrc->Register.File) {
- case TGSI_FILE_INPUT:
if (ai == -1 || ai == fsrc->Register.Index) {
ai = fsrc->Register.Index;
src[i] = tgsi_src(vpc, fsrc);
} else {
src[i] = temp(vpc);
- arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
+ arith(vpc, VEC, MOV, src[i], NVFX_VP_MASK_ALL,
tgsi_src(vpc, fsrc), none, none);
}
break;
@@ -445,7 +442,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
src[i] = tgsi_src(vpc, fsrc);
} else {
src[i] = temp(vpc);
- arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
+ arith(vpc, VEC, MOV, src[i], NVFX_VP_MASK_ALL,
tgsi_src(vpc, fsrc), none, none);
}
break;
@@ -456,7 +453,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
src[i] = tgsi_src(vpc, fsrc);
} else {
src[i] = temp(vpc);
- arith(vpc, 0, OP_MOV, src[i], MASK_ALL,
+ arith(vpc, VEC, MOV, src[i], NVFX_VP_MASK_ALL,
tgsi_src(vpc, fsrc), none, none);
}
break;
@@ -474,93 +471,96 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
switch (finst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
- arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
+ arith(vpc, VEC, MOV, dst, mask, abs(src[0]), none, none);
break;
case TGSI_OPCODE_ADD:
- arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]);
+ arith(vpc, VEC, ADD, dst, mask, src[0], none, src[1]);
break;
case TGSI_OPCODE_ARL:
- arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none);
+ arith(vpc, VEC, ARL, dst, mask, src[0], none, none);
break;
case TGSI_OPCODE_DP3:
- arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, DP3, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_DP4:
- arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, DP4, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_DPH:
- arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, DPH, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_DST:
- arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, DST, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_EX2:
- arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, EX2, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_EXP:
- arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, EXP, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_FLR:
- arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none);
+ arith(vpc, VEC, FLR, dst, mask, src[0], none, none);
break;
case TGSI_OPCODE_FRC:
- arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none);
+ arith(vpc, VEC, FRC, dst, mask, src[0], none, none);
break;
case TGSI_OPCODE_LG2:
- arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, LG2, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_LIT:
- arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, LIT, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_LOG:
- arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, LOG, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_MAD:
- arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]);
+ arith(vpc, VEC, MAD, dst, mask, src[0], src[1], src[2]);
break;
case TGSI_OPCODE_MAX:
- arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, MAX, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_MIN:
- arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, MIN, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_MOV:
- arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none);
+ arith(vpc, VEC, MOV, dst, mask, src[0], none, none);
break;
case TGSI_OPCODE_MUL:
- arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, MUL, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_POW:
tmp = temp(vpc);
- arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none,
+ arith(vpc, SCA, LG2, tmp, NVFX_VP_MASK_X, none, none,
swz(src[0], X, X, X, X));
- arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X),
+ arith(vpc, VEC, MUL, tmp, NVFX_VP_MASK_X, swz(tmp, X, X, X, X),
swz(src[1], X, X, X, X), none);
- arith(vpc, 1, OP_EX2, dst, mask, none, none,
+ arith(vpc, SCA, EX2, dst, mask, none, none,
swz(tmp, X, X, X, X));
break;
case TGSI_OPCODE_RCP:
- arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]);
+ arith(vpc, SCA, RCP, dst, mask, none, none, src[0]);
break;
case TGSI_OPCODE_RET:
break;
case TGSI_OPCODE_RSQ:
- arith(vpc, 1, OP_RSQ, dst, mask, none, none, abs(src[0]));
+ arith(vpc, SCA, RSQ, dst, mask, none, none, abs(src[0]));
break;
case TGSI_OPCODE_SGE:
- arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, SGE, dst, mask, src[0], src[1], none);
+ break;
+ case TGSI_OPCODE_SGT:
+ arith(vpc, VEC, SGT, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_SLT:
- arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none);
+ arith(vpc, VEC, SLT, dst, mask, src[0], src[1], none);
break;
case TGSI_OPCODE_SUB:
- arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1]));
+ arith(vpc, VEC, ADD, dst, mask, src[0], none, neg(src[1]));
break;
case TGSI_OPCODE_XPD:
tmp = temp(vpc);
- arith(vpc, 0, OP_MUL, tmp, mask,
+ arith(vpc, VEC, MUL, tmp, mask,
swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none);
- arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W),
+ arith(vpc, VEC, MAD, dst, (mask & ~NVFX_VP_MASK_W),
swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y),
neg(tmp));
break;
@@ -574,7 +574,7 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
}
static boolean
-nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
+nvfx_vertprog_parse_decl_output(struct nvfx_context* nvfx, struct nvfx_vpc *vpc,
const struct tgsi_full_declaration *fdec)
{
unsigned idx = fdec->Range.First;
@@ -582,15 +582,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
switch (fdec->Semantic.Name) {
case TGSI_SEMANTIC_POSITION:
- hw = NV40_VP_INST_DEST_POS;
+ hw = NVFX_VP(INST_DEST_POS);
vpc->hpos_idx = idx;
break;
case TGSI_SEMANTIC_COLOR:
if (fdec->Semantic.Index == 0) {
- hw = NV40_VP_INST_DEST_COL0;
+ hw = NVFX_VP(INST_DEST_COL0);
} else
if (fdec->Semantic.Index == 1) {
- hw = NV40_VP_INST_DEST_COL1;
+ hw = NVFX_VP(INST_DEST_COL1);
} else {
NOUVEAU_ERR("bad colour semantic index\n");
return FALSE;
@@ -598,24 +598,24 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
break;
case TGSI_SEMANTIC_BCOLOR:
if (fdec->Semantic.Index == 0) {
- hw = NV40_VP_INST_DEST_BFC0;
+ hw = NVFX_VP(INST_DEST_BFC0);
} else
if (fdec->Semantic.Index == 1) {
- hw = NV40_VP_INST_DEST_BFC1;
+ hw = NVFX_VP(INST_DEST_BFC1);
} else {
NOUVEAU_ERR("bad bcolour semantic index\n");
return FALSE;
}
break;
case TGSI_SEMANTIC_FOG:
- hw = NV40_VP_INST_DEST_FOGC;
+ hw = NVFX_VP(INST_DEST_FOGC);
break;
case TGSI_SEMANTIC_PSIZE:
- hw = NV40_VP_INST_DEST_PSZ;
+ hw = NVFX_VP(INST_DEST_PSZ);
break;
case TGSI_SEMANTIC_GENERIC:
if (fdec->Semantic.Index <= 7) {
- hw = NV40_VP_INST_DEST_TC(fdec->Semantic.Index);
+ hw = NVFX_VP(INST_DEST_TC(fdec->Semantic.Index));
} else {
NOUVEAU_ERR("bad generic semantic index\n");
return FALSE;
@@ -630,12 +630,12 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
return FALSE;
}
- vpc->r_result[idx] = nv40_sr(NV40SR_OUTPUT, hw);
+ vpc->r_result[idx] = nvfx_sr(NVFXSR_OUTPUT, hw);
return TRUE;
}
static boolean
-nv40_vertprog_prepare(struct nv40_vpc *vpc)
+nvfx_vertprog_prepare(struct nvfx_context* nvfx, struct nvfx_vpc *vpc)
{
struct tgsi_parse_context p;
int high_temp = -1, high_addr = -1, nr_imm = 0, i;
@@ -670,7 +670,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc)
break;
#endif
case TGSI_FILE_OUTPUT:
- if (!nv40_vertprog_parse_decl_output(vpc, fdec))
+ if (!nvfx_vertprog_parse_decl_output(nvfx, vpc, fdec))
return FALSE;
break;
default:
@@ -691,7 +691,7 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc)
if (fdst->Register.Index > high_addr)
high_addr = fdst->Register.Index;
}
-
+
}
break;
#endif
@@ -702,18 +702,18 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc)
tgsi_parse_free(&p);
if (nr_imm) {
- vpc->imm = CALLOC(nr_imm, sizeof(struct nv40_sreg));
+ vpc->imm = CALLOC(nr_imm, sizeof(struct nvfx_sreg));
assert(vpc->imm);
}
if (++high_temp) {
- vpc->r_temp = CALLOC(high_temp, sizeof(struct nv40_sreg));
+ vpc->r_temp = CALLOC(high_temp, sizeof(struct nvfx_sreg));
for (i = 0; i < high_temp; i++)
vpc->r_temp[i] = temp(vpc);
}
if (++high_addr) {
- vpc->r_address = CALLOC(high_addr, sizeof(struct nv40_sreg));
+ vpc->r_address = CALLOC(high_addr, sizeof(struct nvfx_sreg));
for (i = 0; i < high_addr; i++)
vpc->r_address[i] = temp(vpc);
}
@@ -723,20 +723,20 @@ nv40_vertprog_prepare(struct nv40_vpc *vpc)
}
static void
-nv40_vertprog_translate(struct nv40_context *nv40,
- struct nv40_vertex_program *vp)
+nvfx_vertprog_translate(struct nvfx_context *nvfx,
+ struct nvfx_vertex_program *vp)
{
struct tgsi_parse_context parse;
- struct nv40_vpc *vpc = NULL;
- struct nv40_sreg none = nv40_sr(NV40SR_NONE, 0);
+ struct nvfx_vpc *vpc = NULL;
+ struct nvfx_sreg none = nvfx_sr(NVFXSR_NONE, 0);
int i;
- vpc = CALLOC(1, sizeof(struct nv40_vpc));
+ vpc = CALLOC(1, sizeof(struct nvfx_vpc));
if (!vpc)
return;
vpc->vp = vp;
- if (!nv40_vertprog_prepare(vpc)) {
+ if (!nvfx_vertprog_prepare(nvfx, vpc)) {
FREE(vpc);
return;
}
@@ -775,7 +775,7 @@ nv40_vertprog_translate(struct nv40_context *nv40,
{
const struct tgsi_full_instruction *finst;
finst = &parse.FullToken.FullInstruction;
- if (!nv40_vertprog_parse_instruction(vpc, finst))
+ if (!nvfx_vertprog_parse_instruction(nvfx, vpc, finst))
goto out_err;
}
break;
@@ -785,74 +785,74 @@ nv40_vertprog_translate(struct nv40_context *nv40,
}
/* Write out HPOS if it was redirected to a temp earlier */
- if (vpc->r_result[vpc->hpos_idx].type != NV40SR_OUTPUT) {
- struct nv40_sreg hpos = nv40_sr(NV40SR_OUTPUT,
- NV40_VP_INST_DEST_POS);
- struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx];
+ if (vpc->r_result[vpc->hpos_idx].type != NVFXSR_OUTPUT) {
+ struct nvfx_sreg hpos = nvfx_sr(NVFXSR_OUTPUT,
+ NVFX_VP(INST_DEST_POS));
+ struct nvfx_sreg htmp = vpc->r_result[vpc->hpos_idx];
- arith(vpc, 0, OP_MOV, hpos, MASK_ALL, htmp, none, none);
+ arith(vpc, VEC, MOV, hpos, NVFX_VP_MASK_ALL, htmp, none, none);
}
/* Insert code to handle user clip planes */
for (i = 0; i < vp->ucp.nr; i++) {
- struct nv40_sreg cdst = nv40_sr(NV40SR_OUTPUT,
- NV40_VP_INST_DEST_CLIP(i));
- struct nv40_sreg ceqn = constant(vpc, -1,
- nv40->clip.ucp[i][0],
- nv40->clip.ucp[i][1],
- nv40->clip.ucp[i][2],
- nv40->clip.ucp[i][3]);
- struct nv40_sreg htmp = vpc->r_result[vpc->hpos_idx];
+ struct nvfx_sreg cdst = nvfx_sr(NVFXSR_OUTPUT,
+ NVFX_VP_INST_DEST_CLIP(i));
+ struct nvfx_sreg ceqn = constant(vpc, -1,
+ nvfx->clip.ucp[i][0],
+ nvfx->clip.ucp[i][1],
+ nvfx->clip.ucp[i][2],
+ nvfx->clip.ucp[i][3]);
+ struct nvfx_sreg htmp = vpc->r_result[vpc->hpos_idx];
unsigned mask;
switch (i) {
- case 0: case 3: mask = MASK_Y; break;
- case 1: case 4: mask = MASK_Z; break;
- case 2: case 5: mask = MASK_W; break;
+ case 0: case 3: mask = NVFX_VP_MASK_Y; break;
+ case 1: case 4: mask = NVFX_VP_MASK_Z; break;
+ case 2: case 5: mask = NVFX_VP_MASK_W; break;
default:
NOUVEAU_ERR("invalid clip dist #%d\n", i);
goto out_err;
}
- arith(vpc, 0, OP_DP4, cdst, mask, htmp, ceqn, none);
+ arith(vpc, VEC, DP4, cdst, mask, htmp, ceqn, none);
}
- vp->insns[vp->nr_insns - 1].data[3] |= NV40_VP_INST_LAST;
+ vp->insns[vp->nr_insns - 1].data[3] |= NVFX_VP_INST_LAST;
vp->translated = TRUE;
out_err:
tgsi_parse_free(&parse);
if (vpc->r_temp)
- FREE(vpc->r_temp);
+ FREE(vpc->r_temp);
if (vpc->r_address)
- FREE(vpc->r_address);
- if (vpc->imm)
- FREE(vpc->imm);
+ FREE(vpc->r_address);
+ if (vpc->imm)
+ FREE(vpc->imm);
FREE(vpc);
}
static boolean
-nv40_vertprog_validate(struct nv40_context *nv40)
-{
- struct pipe_screen *pscreen = nv40->pipe.screen;
- struct nv40_screen *screen = nv40->screen;
+nvfx_vertprog_validate(struct nvfx_context *nvfx)
+{
+ struct pipe_screen *pscreen = nvfx->pipe.screen;
+ struct nvfx_screen *screen = nvfx->screen;
struct nouveau_channel *chan = screen->base.channel;
- struct nouveau_grobj *curie = screen->curie;
- struct nv40_vertex_program *vp;
+ struct nouveau_grobj *eng3d = screen->eng3d;
+ struct nvfx_vertex_program *vp;
struct pipe_buffer *constbuf;
boolean upload_code = FALSE, upload_data = FALSE;
int i;
- if (nv40->render_mode == HW) {
- vp = nv40->vertprog;
- constbuf = nv40->constbuf[PIPE_SHADER_VERTEX];
+ if (nvfx->render_mode == HW) {
+ vp = nvfx->vertprog;
+ constbuf = nvfx->constbuf[PIPE_SHADER_VERTEX];
- if ((nv40->dirty & NV40_NEW_UCP) ||
- memcmp(&nv40->clip, &vp->ucp, sizeof(vp->ucp))) {
- nv40_vertprog_destroy(nv40, vp);
- memcpy(&vp->ucp, &nv40->clip, sizeof(vp->ucp));
+ if ((nvfx->dirty & NVFX_NEW_UCP) ||
+ memcmp(&nvfx->clip, &vp->ucp, sizeof(vp->ucp))) {
+ nvfx_vertprog_destroy(nvfx, vp);
+ memcpy(&vp->ucp, &nvfx->clip, sizeof(vp->ucp));
}
} else {
- vp = nv40->swtnl.vertprog;
+ vp = nvfx->swtnl.vertprog;
constbuf = NULL;
}
@@ -860,24 +860,24 @@ nv40_vertprog_validate(struct nv40_context *nv40)
if (vp->translated)
goto check_gpu_resources;
- nv40->fallback_swtnl &= ~NV40_NEW_VERTPROG;
- nv40_vertprog_translate(nv40, vp);
+ nvfx->fallback_swtnl &= ~NVFX_NEW_VERTPROG;
+ nvfx_vertprog_translate(nvfx, vp);
if (!vp->translated) {
- nv40->fallback_swtnl |= NV40_NEW_VERTPROG;
- return FALSE;
+ nvfx->fallback_swtnl |= NVFX_NEW_VERTPROG;
+ return FALSE;
}
check_gpu_resources:
/* Allocate hw vtxprog exec slots */
if (!vp->exec) {
- struct nouveau_resource *heap = nv40->screen->vp_exec_heap;
+ struct nouveau_resource *heap = nvfx->screen->vp_exec_heap;
struct nouveau_stateobj *so;
uint vplen = vp->nr_insns;
if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec)) {
while (heap->next && heap->size < vplen) {
- struct nv40_vertex_program *evict;
-
+ struct nvfx_vertex_program *evict;
+
evict = heap->next->priv;
nouveau_resource_free(&evict->exec);
}
@@ -887,12 +887,14 @@ check_gpu_resources:
}
so = so_new(3, 4, 0);
- so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1);
+ so_method(so, eng3d, NV34TCL_VP_START_FROM_ID, 1);
so_data (so, vp->exec->start);
- so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2);
- so_data (so, vp->ir);
- so_data (so, vp->or);
- so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1);
+ if(nvfx->is_nv4x) {
+ so_method(so, eng3d, NV40TCL_VP_ATTRIB_EN, 2);
+ so_data (so, vp->ir);
+ so_data (so, vp->or);
+ }
+ so_method(so, eng3d, NV34TCL_VP_CLIP_PLANES_ENABLE, 1);
so_data (so, vp->clip_ctrl);
so_ref(so, &vp->so);
so_ref(NULL, &so);
@@ -902,12 +904,12 @@ check_gpu_resources:
/* Allocate hw vtxprog const slots */
if (vp->nr_consts && !vp->data) {
- struct nouveau_resource *heap = nv40->screen->vp_data_heap;
+ struct nouveau_resource *heap = nvfx->screen->vp_data_heap;
if (nouveau_resource_alloc(heap, vp->nr_consts, vp, &vp->data)) {
while (heap->next && heap->size < vp->nr_consts) {
- struct nv40_vertex_program *evict;
-
+ struct nvfx_vertex_program *evict;
+
evict = heap->next->priv;
nouveau_resource_free(&evict->data);
}
@@ -929,7 +931,7 @@ check_gpu_resources:
*/
if (vp->exec_start != vp->exec->start) {
for (i = 0; i < vp->nr_insns; i++) {
- struct nv40_vertex_program_exec *vpi = &vp->insns[i];
+ struct nvfx_vertex_program_exec *vpi = &vp->insns[i];
if (vpi->has_branch_offset) {
assert(0);
@@ -941,13 +943,13 @@ check_gpu_resources:
if (vp->nr_consts && vp->data_start != vp->data->start) {
for (i = 0; i < vp->nr_insns; i++) {
- struct nv40_vertex_program_exec *vpi = &vp->insns[i];
+ struct nvfx_vertex_program_exec *vpi = &vp->insns[i];
if (vpi->const_index >= 0) {
- vpi->data[1] &= ~NV40_VP_INST_CONST_SRC_MASK;
+ vpi->data[1] &= ~NVFX_VP(INST_CONST_SRC_MASK);
vpi->data[1] |=
(vpi->const_index + vp->data->start) <<
- NV40_VP_INST_CONST_SRC_SHIFT;
+ NVFX_VP(INST_CONST_SRC_SHIFT);
}
}
@@ -965,7 +967,7 @@ check_gpu_resources:
}
for (i = 0; i < vp->nr_consts; i++) {
- struct nv40_vertex_program_data *vpd = &vp->consts[i];
+ struct nvfx_vertex_program_data *vpd = &vp->consts[i];
if (vpd->index >= 0) {
if (!upload_data &&
@@ -976,13 +978,13 @@ check_gpu_resources:
4 * sizeof(float));
}
- BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_CONST_ID, 5);
+ BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_CONST_ID, 5);
OUT_RING (chan, i + vp->data->start);
OUT_RINGp (chan, (uint32_t *)vpd->value, 4);
}
if (constbuf)
- pscreen->buffer_unmap(pscreen, constbuf);
+ pipe_buffer_unmap(pscreen, constbuf);
}
/* Upload vtxprog */
@@ -995,16 +997,16 @@ check_gpu_resources:
NOUVEAU_MSG("VP %d: 0x%08x\n", i, vp->insns[i].data[3]);
}
#endif
- BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_FROM_ID, 1);
+ BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_FROM_ID, 1);
OUT_RING (chan, vp->exec->start);
for (i = 0; i < vp->nr_insns; i++) {
- BEGIN_RING(chan, curie, NV40TCL_VP_UPLOAD_INST(0), 4);
+ BEGIN_RING(chan, eng3d, NV34TCL_VP_UPLOAD_INST(0), 4);
OUT_RINGp (chan, vp->insns[i].data, 4);
}
}
- if (vp->so != nv40->state.hw[NV40_STATE_VERTPROG]) {
- so_ref(vp->so, &nv40->state.hw[NV40_STATE_VERTPROG]);
+ if (vp->so != nvfx->state.hw[NVFX_STATE_VERTPROG]) {
+ so_ref(vp->so, &nvfx->state.hw[NVFX_STATE_VERTPROG]);
return TRUE;
}
@@ -1012,7 +1014,7 @@ check_gpu_resources:
}
void
-nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp)
+nvfx_vertprog_destroy(struct nvfx_context *nvfx, struct nvfx_vertex_program *vp)
{
vp->translated = FALSE;
@@ -1038,11 +1040,10 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp)
so_ref(NULL, &vp->so);
}
-struct nv40_state_entry nv40_state_vertprog = {
- .validate = nv40_vertprog_validate,
+struct nvfx_state_entry nvfx_state_vertprog = {
+ .validate = nvfx_vertprog_validate,
.dirty = {
- .pipe = NV40_NEW_VERTPROG | NV40_NEW_UCP,
- .hw = NV40_STATE_VERTPROG,
+ .pipe = NVFX_NEW_VERTPROG | NVFX_NEW_UCP,
+ .hw = NVFX_STATE_VERTPROG,
}
};
-
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index 1f69daec819..a6529b20604 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -14,12 +14,14 @@ C_SOURCES = \
r300_query.c \
r300_render.c \
r300_screen.c \
+ r300_screen_buffer.c \
r300_state.c \
r300_state_derived.c \
r300_state_invariant.c \
r300_vs.c \
r300_texture.c \
- r300_tgsi_to_rc.c
+ r300_tgsi_to_rc.c \
+ r300_transfer.c
LIBRARY_INCLUDES = \
-I$(TOP)/src/mesa/drivers/dri/r300/compiler \
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 183aa17f9b3..221878c1c0c 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -24,12 +24,14 @@ r300 = env.ConvenienceLibrary(
'r300_query.c',
'r300_render.c',
'r300_screen.c',
+ 'r300_screen_buffer.c',
'r300_state.c',
'r300_state_derived.c',
'r300_state_invariant.c',
'r300_vs.c',
'r300_texture.c',
'r300_tgsi_to_rc.c',
+ 'r300_transfer.c',
] + r300compiler) + r300compiler
Export('r300')
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 513cc0f5d44..bcdf950df9c 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -36,6 +36,7 @@ static void r300_blitter_save_states(struct r300_context* r300)
util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state);
util_blitter_save_viewport(r300->blitter, &r300->viewport);
util_blitter_save_clip(r300->blitter, &r300->clip);
+ util_blitter_save_vertex_elements(r300->blitter, r300->velems);
}
/* Clear currently bound buffers. */
@@ -112,9 +113,9 @@ static void r300_hw_copy(struct pipe_context* pipe,
util_blitter_save_fragment_sampler_states(
r300->blitter, state->sampler_count, (void**)state->sampler_states);
- util_blitter_save_fragment_sampler_textures(
+ util_blitter_save_fragment_sampler_views(
r300->blitter, state->texture_count,
- (struct pipe_texture**)state->textures);
+ state->fragment_sampler_views);
/* Do a copy */
util_blitter_copy(r300->blitter,
@@ -148,6 +149,9 @@ void r300_surface_copy(struct pipe_context* pipe,
case 4:
new_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
+ case 8:
+ new_format = PIPE_FORMAT_R16G16B16A16_UNORM;
+ break;
default:
debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n"
"r300: surface_copy: Software fallback doesn't work for tiled textures.\n",
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 92de297ef1d..41719862635 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -24,6 +24,8 @@
#include "util/u_debug.h"
+#include <stdio.h>
+
/* r300_chipset: A file all to itself for deducing the various properties of
* Radeons. */
@@ -365,8 +367,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
break;
default:
- debug_printf("r300: Warning: Unknown chipset 0x%x\n",
- caps->pci_id);
- break;
+ fprintf(stderr, "r300: Warning: Unknown chipset 0x%x\n",
+ caps->pci_id);
}
}
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 86b98a4ba52..4b470b2c6af 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -24,6 +24,7 @@
#include "util/u_memory.h"
#include "util/u_simple_list.h"
+#include "util/u_upload_mgr.h"
#include "r300_blit.h"
#include "r300_context.h"
@@ -32,10 +33,10 @@
#include "r300_query.h"
#include "r300_render.h"
#include "r300_screen.h"
+#include "r300_screen_buffer.h"
#include "r300_state_invariant.h"
-#include "r300_texture.h"
-
-#include "radeon_winsys.h"
+#include "r300_transfer.h"
+#include "r300_winsys.h"
static void r300_destroy_context(struct pipe_context* context)
{
@@ -54,13 +55,15 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(query);
}
+ u_upload_destroy(r300->upload_vb);
+ u_upload_destroy(r300->upload_ib);
+
FREE(r300->blend_color_state.state);
FREE(r300->clip_state.state);
FREE(r300->fb_state.state);
FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
FREE(r300->textures_state.state);
- FREE(r300->vertex_stream_state.state);
FREE(r300->vap_output_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
@@ -68,26 +71,23 @@ static void r300_destroy_context(struct pipe_context* context)
}
static unsigned int
-r300_is_texture_referenced(struct pipe_context *pipe,
+r300_is_texture_referenced(struct pipe_context *context,
struct pipe_texture *texture,
unsigned face, unsigned level)
{
- struct pipe_buffer* buf = 0;
-
- r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
+ struct r300_context* r300 = r300_context(context);
+ struct r300_texture* tex = (struct r300_texture*)texture;
- return pipe->is_buffer_referenced(pipe, buf);
+ return r300->rws->is_buffer_referenced(r300->rws, tex->buffer);
}
static unsigned int
-r300_is_buffer_referenced(struct pipe_context *pipe,
+r300_is_buffer_referenced(struct pipe_context *context,
struct pipe_buffer *buf)
{
- /* This only checks to see whether actual hardware buffers are
- * referenced. Since we use managed BOs and transfers, it's actually not
- * possible for pipe_buffers to ever reference the actual hardware, so
- * buffers are never referenced. */
- return 0;
+ struct r300_context* r300 = r300_context(context);
+
+ return r300_buffer_is_referenced(r300, buf);
}
static void r300_flush_cb(void *data)
@@ -143,7 +143,6 @@ static void r300_setup_atoms(struct r300_context* r300)
r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
- r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
r300->vap_output_state.state = CALLOC_STRUCT(r300_vap_output_state);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
@@ -154,14 +153,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
{
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
struct r300_screen* r300screen = r300_screen(screen);
- struct radeon_winsys* radeon_winsys = r300screen->radeon_winsys;
+ struct r300_winsys_screen *rws = r300screen->rws;
if (!r300)
return NULL;
- r300->winsys = radeon_winsys;
+ r300->rws = rws;
- r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
+ r300->context.winsys = (struct pipe_winsys*)rws;
r300->context.screen = screen;
r300->context.priv = priv;
@@ -198,24 +197,42 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
/* Open up the OQ BO. */
r300->oqbo = screen->buffer_create(screen, 4096,
- PIPE_BUFFER_USAGE_VERTEX, 4096);
+ PIPE_BUFFER_USAGE_PIXEL, 4096);
make_empty_list(&r300->query_list);
r300_init_flush_functions(r300);
r300_init_query_functions(r300);
- /* r300_init_surface_functions(r300); */
+ r300_init_transfer_functions(r300);
r300_init_state_functions(r300);
r300->invariant_state.dirty = TRUE;
- r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
- r300->dirty_state = R300_NEW_KITCHEN_SINK;
+ rws->set_flush_cb(r300->rws, r300_flush_cb, r300);
r300->dirty_hw++;
r300->blitter = util_blitter_create(&r300->context);
+ r300->upload_ib = u_upload_create(screen,
+ 32 * 1024, 16,
+ PIPE_BUFFER_USAGE_INDEX);
+
+ if (r300->upload_ib == NULL)
+ goto no_upload_ib;
+
+ r300->upload_vb = u_upload_create(screen,
+ 128 * 1024, 16,
+ PIPE_BUFFER_USAGE_VERTEX);
+ if (r300->upload_vb == NULL)
+ goto no_upload_vb;
+
return &r300->context;
+
+ no_upload_ib:
+ u_upload_destroy(r300->upload_ib);
+ no_upload_vb:
+ FREE(r300);
+ return NULL;
}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 0d1518a05bc..0a82484e89d 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -30,8 +30,10 @@
#include "pipe/p_context.h"
#include "util/u_inlines.h"
+#include "r300_defines.h"
#include "r300_screen.h"
+struct u_upload_mgr;
struct r300_context;
struct r300_fragment_shader;
@@ -126,17 +128,17 @@ struct r300_texture_format_state {
struct r300_texture_fb_state {
/* Colorbuffer. */
- uint32_t colorpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
+ uint32_t colorpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_COLORPITCH[0-3]*/
uint32_t us_out_fmt; /* R300_US_OUT_FMT[0-3] */
/* Zbuffer. */
- uint32_t depthpitch[PIPE_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
+ uint32_t depthpitch[R300_MAX_TEXTURE_LEVELS]; /* R300_RB3D_DEPTHPITCH */
uint32_t zb_format; /* R300_ZB_FORMAT */
};
struct r300_textures_state {
/* Textures. */
- struct r300_texture *textures[8];
+ struct pipe_sampler_view *fragment_sampler_views[8];
int texture_count;
/* Sampler states. */
struct r300_sampler_state *sampler_states[8];
@@ -182,12 +184,6 @@ struct r300_ztop_state {
uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */
};
-#define R300_NEW_FRAGMENT_SHADER 0x00000020
-#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
-#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
-#define R300_NEW_QUERY 0x40000000
-#define R300_NEW_KITCHEN_SINK 0x7fffffff
-
/* The next several objects are not pure Radeon state; they inherit from
* various Gallium classes. */
@@ -225,27 +221,21 @@ struct r300_query {
struct r300_query* next;
};
-enum r300_buffer_tiling {
- R300_BUFFER_LINEAR = 0,
- R300_BUFFER_TILED,
- R300_BUFFER_SQUARETILED
-};
-
struct r300_texture {
/* Parent class */
struct pipe_texture tex;
/* Offsets into the buffer. */
- unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned offset[R300_MAX_TEXTURE_LEVELS];
/* A pitch for each mip-level */
- unsigned pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned pitch[R300_MAX_TEXTURE_LEVELS];
/* Size of one zslice or face based on the texture target */
- unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned layer_size[R300_MAX_TEXTURE_LEVELS];
/* Whether the mipmap level is macrotiled. */
- enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS];
+ enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS];
/**
* If non-zero, override the natural texture layout with
@@ -266,7 +256,7 @@ struct r300_texture {
boolean is_npot;
/* Pipe buffer backing this texture. */
- struct pipe_buffer* buffer;
+ struct r300_winsys_buffer *buffer;
/* Registers carrying texture format data. */
struct r300_texture_format_state state;
@@ -276,6 +266,23 @@ struct r300_texture {
enum r300_buffer_tiling microtile, macrotile;
};
+struct r300_vertex_info {
+ /* Parent class */
+ struct vertex_info vinfo;
+
+ /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
+ uint32_t vap_prog_stream_cntl[8];
+ /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
+ uint32_t vap_prog_stream_cntl_ext[8];
+};
+
+struct r300_vertex_element_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+
+ struct r300_vertex_stream_state vertex_stream;
+};
+
extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
@@ -283,7 +290,7 @@ struct r300_context {
struct pipe_context context;
/* The interface to the windowing system, etc. */
- struct radeon_winsys* winsys;
+ struct r300_winsys_screen *rws;
/* Draw module. Used mostly for SW TCL. */
struct draw_context* draw;
/* Accelerated blit support. */
@@ -348,8 +355,8 @@ struct r300_context {
int vertex_buffer_count;
int vertex_buffer_max_index;
/* Vertex elements for Gallium. */
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
- int vertex_element_count;
+ struct r300_vertex_element_state *velems;
+ bool any_user_vbs;
/* Vertex info for Draw. */
struct vertex_info vertex_info;
@@ -368,6 +375,11 @@ struct r300_context {
boolean polygon_offset_enabled;
/* Z buffer bit depth. */
uint32_t zbuffer_bpp;
+ /* Whether scissor is enabled. */
+ boolean scissor_enabled;
+ /* upload managers */
+ struct u_upload_mgr *upload_vb;
+ struct u_upload_mgr *upload_ib;
};
/* Convenience cast wrapper. */
@@ -384,6 +396,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_surface_functions(struct r300_context* r300);
+void r300_init_tex_functions( struct pipe_context *pipe );
static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags)
{
@@ -396,7 +409,7 @@ static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags,
if (CTX_DBG_ON(ctx, flags)) {
va_list va;
va_start(va, fmt);
- debug_vprintf(fmt, va);
+ vfprintf(stderr, fmt, va);
va_end(va);
}
}
@@ -405,4 +418,3 @@ static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags,
#define DBG CTX_DBG
#endif /* R300_CONTEXT_H */
-
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 151f72b0fe4..456b2ec7b92 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -26,8 +26,7 @@
#include "util/u_math.h"
#include "r300_reg.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
/* Yes, I know macros are ugly. However, they are much prettier than the code
* that they neatly hide away, and don't have the cost of function setup,so
@@ -51,7 +50,7 @@
#define CS_LOCALS(context) \
struct r300_context* const cs_context_copy = (context); \
- struct radeon_winsys* cs_winsys = cs_context_copy->winsys; \
+ struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \
int cs_count = 0; (void) cs_count;
#define CHECK_CS(size) \
@@ -105,22 +104,34 @@
cs_count--; \
} while (0)
-#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
+#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \
"domains (%d, %d, %d)\n", \
bo, offset, rd, wd, flags); \
assert(bo); \
cs_winsys->write_cs_dword(cs_winsys, offset); \
- cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
+ r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \
+ cs_count -= 3; \
+} while (0)
+
+
+#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \
+ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for texture %p, offset %d, " \
+ "domains (%d, %d, %d)\n", \
+ tex, offset, rd, wd, flags); \
+ assert(tex); \
+ cs_winsys->write_cs_dword(cs_winsys, offset); \
+ r300_texture_write_reloc(cs_winsys, tex, rd, wd, flags); \
cs_count -= 3; \
} while (0)
-#define OUT_CS_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
+
+#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, " \
"domains (%d, %d, %d)\n", \
bo, rd, wd, flags); \
assert(bo); \
- cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
+ r300_buffer_write_reloc(cs_winsys, r300_buffer(bo), rd, wd, flags); \
cs_count -= 2; \
} while (0)
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index b881730848a..016e8d66061 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -22,6 +22,7 @@
#include "r300_context.h"
+#include <stdio.h>
struct debug_option {
const char * name;
@@ -37,6 +38,7 @@ static struct debug_option debug_options[] = {
{ "draw", DBG_DRAW, "Draw and emit" },
{ "tex", DBG_TEX, "Textures" },
{ "fall", DBG_FALL, "Fallbacks" },
+ { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking purposes only!)" },
{ "all", ~0, "Convenience option that enables all debug flags" },
@@ -68,7 +70,7 @@ void r300_init_debug(struct r300_screen * screen)
}
if (!opt->name) {
- debug_printf("Unknown debug option: %s\n", options);
+ fprintf(stderr, "Unknown debug option: %s\n", options);
printhint = TRUE;
}
@@ -80,10 +82,13 @@ void r300_init_debug(struct r300_screen * screen)
}
if (printhint || screen->debug & DBG_HELP) {
- debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n"
- "to a comma-separated list of debug options. Available options are:\n");
+ fprintf(stderr, "You can enable debug output by setting "
+ "the RADEON_DEBUG environment variable\n"
+ "to a comma-separated list of debug options. "
+ "Available options are:\n");
+
for(opt = debug_options; opt->name; ++opt) {
- debug_printf(" %s: %s\n", opt->name, opt->description);
+ fprintf(stderr, " %s: %s\n", opt->name, opt->description);
}
}
}
diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h
new file mode 100644
index 00000000000..2e04876de92
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_defines.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Marek Olšák <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef R300_DEFINES_H
+#define R300_DEFINES_H
+
+#include "pipe/p_defines.h"
+
+#define R300_MAX_TEXTURE_LEVELS 13
+#define R300_MAX_DRAW_VBO_SIZE (1024 * 1024)
+
+#define R300_TEXTURE_USAGE_TRANSFER PIPE_TEXTURE_USAGE_CUSTOM
+
+/* Non-atom dirty state flags. */
+#define R300_NEW_FRAGMENT_SHADER 0x00000020
+#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
+#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
+#define R300_NEW_QUERY 0x40000000
+#define R300_NEW_KITCHEN_SINK 0x7fffffff
+
+/* Tiling flags. */
+enum r300_buffer_tiling {
+ R300_BUFFER_LINEAR = 0,
+ R300_BUFFER_TILED,
+ R300_BUFFER_SQUARETILED
+};
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index addb28bded3..15bcf8907f3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -32,6 +32,7 @@
#include "r300_emit.h"
#include "r300_fs.h"
#include "r300_screen.h"
+#include "r300_screen_buffer.h"
#include "r300_vs.h"
void r300_emit_blend_state(struct r300_context* r300,
@@ -144,10 +145,8 @@ static const float * get_shader_constant(
struct rc_constant * constant,
struct r300_constant_buffer * externals)
{
- struct r300_viewport_state* viewport =
- (struct r300_viewport_state*)r300->viewport_state.state;
- struct r300_textures_state* texstate =
- (struct r300_textures_state*)r300->textures_state.state;
+ struct r300_viewport_state* viewport = r300->viewport_state.state;
+ struct r300_textures_state* texstate = r300->textures_state.state;
static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
struct pipe_texture *tex;
@@ -163,7 +162,7 @@ static const float * get_shader_constant(
/* Factor for converting rectangle coords to
* normalized coords. Should only show up on non-r500. */
case RC_STATE_R300_TEXRECT_FACTOR:
- tex = &texstate->textures[constant->u.State[1]]->tex;
+ tex = texstate->fragment_sampler_views[constant->u.State[1]]->texture;
vec[0] = 1.0 / tex->width0;
vec[1] = 1.0 / tex->height0;
break;
@@ -187,13 +186,13 @@ static const float * get_shader_constant(
break;
default:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Unknown RC_CONSTANT type %d\n", constant->u.State[0]);
}
break;
default:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Unhandled constant type %d\n", constant->Type);
}
@@ -415,10 +414,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
- OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
- OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level],
+ OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level],
0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt);
@@ -434,12 +433,12 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format);
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level],
+ OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level],
0, RADEON_GEM_DOMAIN_VRAM, 0);
}
@@ -448,7 +447,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
END_CS;
}
-static void r300_emit_query_start(struct r300_context *r300)
+void r300_emit_query_start(struct r300_context *r300)
{
struct r300_capabilities *caps = r300_screen(r300->context.screen)->caps;
struct r300_query *query = r300->query_current;
@@ -491,13 +490,13 @@ static void r300_emit_query_finish(struct r300_context *r300,
/* pipe 3 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
0, RADEON_GEM_DOMAIN_GTT, 0);
case 3:
/* pipe 2 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
0, RADEON_GEM_DOMAIN_GTT, 0);
case 2:
/* pipe 1 only */
@@ -505,19 +504,19 @@ static void r300_emit_query_finish(struct r300_context *r300,
OUT_CS_REG(R300_SU_REG_DEST,
1 << (caps->high_second_pipe ? 3 : 1));
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
0, RADEON_GEM_DOMAIN_GTT, 0);
case 1:
/* pipe 0 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
0, RADEON_GEM_DOMAIN_GTT, 0);
break;
default:
- debug_printf("r300: Implementation error: Chipset reports %d"
+ fprintf(stderr, "r300: Implementation error: Chipset reports %d"
" pixel pipes!\n", caps->num_frag_pipes);
- assert(0);
+ abort();
}
/* And, finally, reset it to normal... */
@@ -533,7 +532,7 @@ static void rv530_emit_query_single(struct r300_context *r300,
BEGIN_CS(8);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -546,10 +545,10 @@ static void rv530_emit_query_double(struct r300_context *r300,
BEGIN_CS(14);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -675,7 +674,7 @@ void r300_emit_scissor_state(struct r300_context* r300,
maxx = fb->width;
maxy = fb->height;
- if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
+ if (r300->scissor_enabled) {
minx = MAX2(minx, scissor->minx);
miny = MAX2(miny, scissor->miny);
maxx = MIN2(maxx, scissor->maxx);
@@ -747,8 +746,9 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]);
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_CS_RELOC(allstate->textures[i]->buffer, texstate->tile_config,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ OUT_CS_TEX_RELOC((struct r300_texture *)allstate->fragment_sampler_views[i]->texture,
+ texstate->tile_config,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
}
END_CS;
@@ -757,9 +757,9 @@ void r300_emit_textures_state(struct r300_context *r300,
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
int i;
- unsigned size1, size2, aos_count = r300->vertex_element_count;
+ unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
@@ -788,12 +788,36 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
}
for (i = 0; i < aos_count; i++) {
- OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
+ OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
}
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.size);
+ /* Set the pointer to our vertex buffer. The emitted values are this:
+ * PACKET3 [3D_LOAD_VBPNTR]
+ * COUNT [1]
+ * FORMAT [size | stride << 8]
+ * OFFSET [offset into BO]
+ * VBPNTR [relocated BO]
+ */
+ BEGIN_CS(7);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
+ OUT_CS(1);
+ OUT_CS(r300->vertex_info.size |
+ (r300->vertex_info.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_BUF_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state)
{
@@ -867,12 +891,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
CS_LOCALS(r300);
- if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vertex_shader called,"
- " but has_tcl is FALSE!\n");
- return;
- }
-
BEGIN_CS(size);
/* R300_VAP_PVS_CODE_CNTL_0
* R300_VAP_PVS_CONST_CNTL
@@ -902,28 +920,19 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
void r300_emit_vs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants)
{
- int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ unsigned i;
CS_LOCALS(r300);
- if (!r300screen->caps->has_tcl) {
- debug_printf("r300: Implementation error: emit_vertex_shader called,"
- " but has_tcl is FALSE!\n");
- return;
- }
-
- if (constants->Count == 0)
- return;
-
BEGIN_CS(constants->Count * 4 + 3);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4);
for (i = 0; i < constants->Count; i++) {
- const float * data = get_shader_constant(r300,
- &constants->Constants[i],
- &r300->shader_constants[PIPE_SHADER_VERTEX]);
+ const float *data = get_shader_constant(r300,
+ &constants->Constants[i],
+ &r300->shader_constants[PIPE_SHADER_VERTEX]);
OUT_CS_32F(data[0]);
OUT_CS_32F(data[1]);
OUT_CS_32F(data[2]);
@@ -980,21 +989,27 @@ void r300_emit_buffer_validate(struct r300_context *r300,
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture* tex;
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_vertex_element *velem = r300->velems->velem;
struct pipe_buffer *pbuf;
unsigned i;
boolean invalid = FALSE;
+ /* upload buffers first */
+ if (r300->any_user_vbs) {
+ r300_upload_user_buffers(r300);
+ r300->any_user_vbs = false;
+ }
+
/* Clean out BOs. */
- r300->winsys->reset_bos(r300->winsys);
+ r300->rws->reset_bos(r300->rws);
validate:
/* Color buffers... */
for (i = 0; i < fb->nr_cbufs; i++) {
tex = (struct r300_texture*)fb->cbufs[i]->texture;
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM)) {
+ if (!r300_add_texture(r300->rws, tex,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1003,66 +1018,67 @@ validate:
if (fb->zsbuf) {
tex = (struct r300_texture*)fb->zsbuf->texture;
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM)) {
+ if (!r300_add_texture(r300->rws, tex,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
/* ...textures... */
for (i = 0; i < texstate->count; i++) {
- tex = texstate->textures[i];
- if (!tex || !texstate->sampler_states[i])
+ if (!(texstate->tx_enable & (1 << i))) {
continue;
- if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ }
+
+ tex = (struct r300_texture*)texstate->fragment_sampler_views[i]->texture;
+ if (!r300_add_texture(r300->rws, tex,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
/* ...occlusion query buffer... */
if (r300->dirty_state & R300_NEW_QUERY) {
- if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
- 0, RADEON_GEM_DOMAIN_GTT)) {
+ if (!r300_add_buffer(r300->rws, r300->oqbo,
+ 0, RADEON_GEM_DOMAIN_GTT)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
/* ...vertex buffer for SWTCL path... */
if (r300->vbo) {
- if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ if (!r300_add_buffer(r300->rws, r300->vbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
/* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers) {
- for (i = 0; i < r300->vertex_element_count; i++) {
+ for (i = 0; i < r300->velems->count; i++) {
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
- if (!r300->winsys->add_buffer(r300->winsys, pbuf,
- RADEON_GEM_DOMAIN_GTT, 0)) {
- r300->context.flush(&r300->context, 0, NULL);
+ if (!r300_add_buffer(r300->rws, pbuf,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
}
/* ...and index buffer for HWTCL path. */
if (index_buffer) {
- if (!r300->winsys->add_buffer(r300->winsys, index_buffer,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ if (!r300_add_buffer(r300->rws, index_buffer,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
}
-
- if (!r300->winsys->validate(r300->winsys)) {
+ if (!r300->rws->validate(r300->rws)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
/* Well, hell. */
- debug_printf("r300: Stuck in validation loop, gonna quit now.");
- exit(1);
+ fprintf(stderr, "r300: Stuck in validation loop, gonna quit now.\n");
+ abort();
}
invalid = TRUE;
goto validate;
@@ -1127,7 +1143,9 @@ void r300_emit_dirty_state(struct r300_context* r300)
if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) {
struct r300_vertex_shader* vs = r300->vs_state.state;
- r300_emit_vs_constant_buffer(r300, &vs->code.constants);
+ if (vs->code.constants.Count) {
+ r300_emit_vs_constant_buffer(r300, &vs->code.constants);
+ }
r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
}
@@ -1135,8 +1153,10 @@ void r300_emit_dirty_state(struct r300_context* r300)
assert(r300->dirty_state == 0);
*/
- /* Finally, emit the VBO. */
- /* r300_emit_vertex_buffer(r300); */
+ /* Emit the VBO for SWTCL. */
+ if (!r300screen->caps->has_tcl) {
+ r300_emit_vertex_buffer(r300);
+ }
r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 449e640a884..7db2fc6a1a1 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -57,8 +57,7 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state);
-void r300_emit_query_begin(struct r300_context* r300,
- struct r300_query* query);
+void r300_emit_query_start(struct r300_context* r300);
void r300_emit_query_end(struct r300_context* r300);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index e37d3092703..70de152713d 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -61,6 +61,12 @@ static void r300_flush(struct pipe_context* pipe,
atom->dirty = TRUE;
}
}
+
+ /* Unmark HWTCL state for SWTCL. */
+ if (!r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = FALSE;
+ r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS;
+ }
}
/* reset flushed query */
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 3c2625269b8..e23fef8c9f7 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -204,9 +204,9 @@ static void r300_translate_fragment_shader(
r3xx_compile_fragment_program(&compiler);
if (compiler.Base.Error) {
/* XXX failover maybe? */
- DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n",
- compiler.Base.ErrorMsg);
- assert(0);
+ fprintf(stderr, "r300 FP: Compiler Error:\n%s",
+ compiler.Base.ErrorMsg);
+ abort();
}
/* And, finally... */
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index ca00b043c51..f8b52d593d5 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -30,6 +30,8 @@
#include "r300_query.h"
#include "r300_reg.h"
+#include <stdio.h>
+
static struct pipe_query *r300_create_query(struct pipe_context *pipe,
unsigned query_type)
{
@@ -97,8 +99,10 @@ static void r300_end_query(struct pipe_context* pipe,
struct pipe_query* query)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_query* q = (struct r300_query*)query;
r300_emit_query_end(r300);
+ q->begin_emitted = false;
r300->query_current = NULL;
}
@@ -135,8 +139,8 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
if (*map == ~0U) {
/* Looks like our results aren't ready yet. */
if (wait) {
- debug_printf("r300: Despite waiting, OQ results haven't"
- " come in yet.\n");
+ fprintf(stderr, "r300: Despite waiting, OQ results haven't "
+ "come in yet.\n");
}
temp = ~0U;
break;
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index c67cc868713..1c2b2528877 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -1500,6 +1500,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_ANISO_THRESHOLD_MASK (7<<17)
# define R500_MACRO_SWITCH (1<<22)
+# define R500_TX_MAX_ANISO(x) ((x) << 23)
+# define R500_TX_MAX_ANISO_MASK (63 << 23)
+# define R500_TX_ANISO_HIGH_QUALITY (1 << 30)
+
# define R500_BORDER_FIX (1<<31)
#define R300_TX_FORMAT0_0 0x4480
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 6c891029a56..1fb7eac2b34 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -30,18 +30,17 @@
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
#include "util/u_prim.h"
#include "r300_cs.h"
#include "r300_context.h"
+#include "r300_screen_buffer.h"
#include "r300_emit.h"
#include "r300_reg.h"
#include "r300_render.h"
#include "r300_state_derived.h"
-/* r300_render: Vertex and index buffer primitive emission. */
-#define R300_MAX_VBO_SIZE (1024 * 1024)
-
/* XXX The DRM rejects VAP_ALT_NUM_VERTICES.. */
//#define ENABLE_ALT_NUM_VERTS
@@ -123,7 +122,7 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
static boolean r300_reserve_cs_space(struct r300_context *r300,
unsigned dwords)
{
- if (!r300->winsys->check_cs(r300->winsys, dwords)) {
+ if (!r300->rws->check_cs(r300->rws, dwords)) {
r300->context.flush(&r300->context, 0, NULL);
return TRUE;
}
@@ -131,9 +130,36 @@ static boolean r300_reserve_cs_space(struct r300_context *r300,
}
static boolean immd_is_good_idea(struct r300_context *r300,
- unsigned count)
+ unsigned count)
{
- return count <= 4;
+ struct pipe_vertex_element* velem;
+ struct pipe_vertex_buffer* vbuf;
+ boolean checked[PIPE_MAX_ATTRIBS] = {0};
+ unsigned vertex_element_count = r300->velems->count;
+ unsigned i, vbi;
+
+ if (count > 10) {
+ return FALSE;
+ }
+
+ /* We shouldn't map buffers referenced by CS, busy buffers,
+ * and ones placed in VRAM. */
+ /* XXX Check for VRAM buffers. */
+ for (i = 0; i < vertex_element_count; i++) {
+ velem = &r300->velems->velem[i];
+ vbi = velem->vertex_buffer_index;
+
+ if (!checked[vbi]) {
+ vbuf = &r300->vertex_buffer[vbi];
+
+ if (r300_buffer_is_referenced(r300, vbuf->buffer)) {
+ /* It's a very bad idea to map it... */
+ return FALSE;
+ }
+ checked[vbi] = TRUE;
+ }
+ }
+ return TRUE;
}
static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
@@ -143,7 +169,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
{
struct pipe_vertex_element* velem;
struct pipe_vertex_buffer* vbuf;
- unsigned vertex_element_count = r300->vertex_element_count;
+ unsigned vertex_element_count = r300->velems->count;
unsigned i, v, vbi, dw, elem_offset, dwords;
/* Size of the vertex, in dwords. */
@@ -166,7 +192,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Calculate the vertex size, offsets, strides etc. and map the buffers. */
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
offset[i] = velem->src_offset / 4;
size[i] = util_format_get_blocksize(velem->src_format) / 4;
vertex_size += size[i];
@@ -183,18 +209,19 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
}
}
- dwords = 10 + count * vertex_size;
+ dwords = 9 + count * vertex_size;
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
- r300_emit_buffer_validate(r300, FALSE, 0);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
r300_translate_primitive(mode));
@@ -202,7 +229,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Emit vertices. */
for (v = 0; v < count; v++) {
for (i = 0; i < vertex_element_count; i++) {
- velem = &r300->vertex_element[i];
+ velem = &r300->velems->velem[i];
vbi = velem->vertex_buffer_index;
elem_offset = offset[i] + stride[vbi] * (v + start);
@@ -215,7 +242,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
/* Unmap buffers. */
for (i = 0; i < vertex_element_count; i++) {
- vbi = r300->vertex_element[i].vertex_buffer_index;
+ vbi = r300->velems->velem[i].vertex_buffer_index;
if (map[vbi]) {
vbuf = &r300->vertex_buffer[vbi];
@@ -238,15 +265,16 @@ static void r300_emit_draw_arrays(struct r300_context *r300,
if (alt_num_verts) {
assert(count < (1 << 24));
- BEGIN_CS(10);
+ BEGIN_CS(9);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(8);
+ BEGIN_CS(7);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(count - 1);
+ OUT_CS(0);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
r300_translate_primitive(mode) |
@@ -272,24 +300,24 @@ static void r300_emit_draw_elements(struct r300_context *r300,
#endif
CS_LOCALS(r300);
- assert((start * indexSize) % 4 == 0);
assert(count < (1 << 24));
+ maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
+
DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
count, minIndex, maxIndex);
- maxIndex = MIN2(maxIndex, ((1 << 24) - 1));
-
if (alt_num_verts) {
- BEGIN_CS(16);
+ BEGIN_CS(15);
OUT_CS_REG(R500_VAP_ALT_NUM_VERTICES, count);
} else {
- BEGIN_CS(14);
+ BEGIN_CS(13);
}
OUT_CS_REG(R300_GA_COLOR_CONTROL,
r300_provoking_vertex_fixes(r300, mode));
- OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
+ OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+ OUT_CS(maxIndex);
+ OUT_CS(minIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
if (indexSize == 4) {
count_dwords = count;
@@ -313,14 +341,15 @@ static void r300_emit_draw_elements(struct r300_context *r300,
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2) |
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
OUT_CS(offset_dwords << 2);
- OUT_CS_RELOC(indexBuffer, count_dwords,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
+ OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
END_CS;
}
static void r300_shorten_ubyte_elts(struct r300_context* r300,
struct pipe_buffer** elts,
+ unsigned start,
unsigned count)
{
struct pipe_screen* screen = r300->context.screen;
@@ -338,6 +367,8 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300,
in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ);
out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE);
+ in_map += start;
+
for (i = 0; i < count; i++) {
*out_map = (unsigned short)*in_map;
in_map++;
@@ -350,6 +381,32 @@ static void r300_shorten_ubyte_elts(struct r300_context* r300,
*elts = new_elts;
}
+static void r300_align_ushort_elts(struct r300_context *r300,
+ struct pipe_buffer **elts,
+ unsigned start, unsigned count)
+{
+ struct pipe_screen* screen = r300->context.screen;
+ struct pipe_buffer* new_elts;
+ unsigned short *in_map;
+ unsigned short *out_map;
+
+ new_elts = screen->buffer_create(screen, 32,
+ PIPE_BUFFER_USAGE_INDEX |
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_READ,
+ 2 * count);
+
+ in_map = pipe_buffer_map(screen, *elts, PIPE_BUFFER_USAGE_CPU_READ);
+ out_map = pipe_buffer_map(screen, new_elts, PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(out_map, in_map+start, 2 * count);
+
+ pipe_buffer_unmap(screen, *elts);
+ pipe_buffer_unmap(screen, new_elts);
+
+ *elts = new_elts;
+}
+
/* This is the fast-path drawing & emission for HW TCL. */
void r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
@@ -375,18 +432,26 @@ void r300_draw_range_elements(struct pipe_context* pipe,
}
if (indexSize == 1) {
- r300_shorten_ubyte_elts(r300, &indexBuffer, count);
+ r300_shorten_ubyte_elts(r300, &indexBuffer, start, count);
indexSize = 2;
+ start = 0;
+ } else if (indexSize == 2 && start % 2 != 0) {
+ r300_align_ushort_elts(r300, &indexBuffer, start, count);
+ start = 0;
}
r300_update_derived_state(r300);
+ r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count);
+
/* 128 dwords for emit_aos and emit_draw_elements */
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
r300_emit_buffer_validate(r300, TRUE, indexBuffer);
r300_emit_dirty_state(r300);
r300_emit_aos(r300, 0);
+ u_upload_flush(r300->upload_vb);
+ u_upload_flush(r300->upload_ib);
if (alt_num_verts || count <= 65535) {
r300_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
maxIndex, mode, start, count);
@@ -409,7 +474,7 @@ void r300_draw_range_elements(struct pipe_context* pipe,
}
if (indexBuffer != orgIndexBuffer) {
- pipe->screen->buffer_destroy(indexBuffer);
+ pipe_buffer_reference( &indexBuffer, NULL );
}
}
@@ -450,7 +515,7 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Make sure there are at least 128 spare dwords in the command buffer.
* (most of it being consumed by emit_aos) */
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 128);
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
if (alt_num_verts || count <= 65535) {
@@ -468,11 +533,12 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
/* Again, we emit both AOS and draw_arrays so there should be
* at least 128 spare dwords. */
if (count && r300_reserve_cs_space(r300, 128)) {
- r300_emit_buffer_validate(r300, TRUE, 0);
+ r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
}
} while (count);
}
+ u_upload_flush(r300->upload_vb);
}
}
@@ -503,13 +569,6 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
draw_set_mapped_element_buffer(r300->draw, 0, NULL);
- draw_set_mapped_constant_buffer(r300->draw,
- PIPE_SHADER_VERTEX,
- 0,
- r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].count *
- (sizeof(float) * 4));
-
draw_arrays(r300->draw, mode, start, count);
for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -548,13 +607,6 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_element_buffer_range(r300->draw, indexSize,
minIndex, maxIndex, indices);
- draw_set_mapped_constant_buffer(r300->draw,
- PIPE_SHADER_VERTEX,
- 0,
- r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].count *
- (sizeof(float) * 4));
-
draw_arrays(r300->draw, mode, start, count);
for (i = 0; i < r300->vertex_buffer_count; i++) {
@@ -620,9 +672,9 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
r300render->vbo = pipe_buffer_create(screen,
64,
PIPE_BUFFER_USAGE_VERTEX,
- R300_MAX_VBO_SIZE);
+ R300_MAX_DRAW_VBO_SIZE);
r300render->vbo_offset = 0;
- r300render->vbo_size = R300_MAX_VBO_SIZE;
+ r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE;
}
r300render->vertex_size = vertex_size;
@@ -688,6 +740,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -711,6 +764,7 @@ static void r300_render_draw(struct vbuf_render* render,
CS_LOCALS(r300);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
+ r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
BEGIN_CS(dwords);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index d397a8eb2b4..e46f836dd2c 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <[email protected]>
+ * Copyright 2010 Marek Olšák <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,16 +21,12 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
#include "r300_context.h"
-#include "r300_screen.h"
#include "r300_texture.h"
-
-#include "radeon_winsys.h"
+#include "r300_screen_buffer.h"
#include "r300_winsys.h"
/* Return the identifier behind whom the brave coders responsible for this
@@ -167,7 +164,7 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 0;
default:
- debug_printf("r300: Implementation error: Bad param %d\n",
+ fprintf(stderr, "r300: Implementation error: Bad param %d\n",
param);
return 0;
}
@@ -196,7 +193,7 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0f;
default:
- debug_printf("r300: Implementation error: Bad paramf %d\n",
+ fprintf(stderr, "r300: Implementation error: Bad paramf %d\n",
param);
return 0.0f;
}
@@ -215,7 +212,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
- debug_printf("r300: Implementation error: Received bogus texture "
+ fprintf(stderr, "r300: Implementation error: Received bogus texture "
"target %d in %s\n", target, __FUNCTION__);
return FALSE;
}
@@ -231,14 +228,16 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
/* Check colorbuffer format support. */
if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) &&
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) &&
/* 2101010 cannot be rendered to on non-r5xx. */
(is_r500 || !is_color2101010) &&
r300_is_colorbuffer_format_supported(format)) {
retval |= usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY);
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED);
}
/* Check depth-stencil format support. */
@@ -250,82 +249,22 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
return retval == usage;
}
-static struct pipe_transfer*
-r300_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
-{
- struct r300_texture *tex = (struct r300_texture *)texture;
- struct r300_transfer *trans;
- struct r300_screen *rscreen = r300_screen(screen);
- unsigned offset;
-
- offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */
-
- trans = CALLOC_STRUCT(r300_transfer);
- if (trans) {
- pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.x = x;
- trans->transfer.y = y;
- trans->transfer.width = w;
- trans->transfer.height = h;
- trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level);
- trans->transfer.usage = usage;
- trans->transfer.zslice = zslice;
- trans->transfer.face = face;
-
- trans->offset = offset;
- }
- return &trans->transfer;
-}
-
-static void
-r300_tex_transfer_destroy(struct pipe_transfer *trans)
-{
- pipe_texture_reference(&trans->texture, NULL);
- FREE(trans);
-}
-
-static void* r300_transfer_map(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- char* map;
- enum pipe_format format = tex->tex.format;
-
- map = pipe_buffer_map(screen, tex->buffer,
- pipe_transfer_buffer_flags(transfer));
-
- if (!map) {
- return NULL;
- }
-
- return map + r300_transfer(transfer)->offset +
- transfer->y / util_format_get_blockheight(format) * transfer->stride +
- transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
-}
-
-static void r300_transfer_unmap(struct pipe_screen* screen,
- struct pipe_transfer* transfer)
-{
- struct r300_texture* tex = (struct r300_texture*)transfer->texture;
- pipe_buffer_unmap(screen, tex->buffer);
-}
-
static void r300_destroy_screen(struct pipe_screen* pscreen)
{
struct r300_screen* r300screen = r300_screen(pscreen);
+ struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
+
+ if (rws)
+ rws->destroy(rws);
FREE(r300screen->caps);
FREE(r300screen);
}
-struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
+struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
{
- struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen);
- struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities);
+ struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
+ struct r300_capabilities *caps = CALLOC_STRUCT(r300_capabilities);
if (!r300screen || !caps) {
FREE(r300screen);
@@ -333,16 +272,16 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
return NULL;
}
- caps->pci_id = radeon_winsys->pci_id;
- caps->num_frag_pipes = radeon_winsys->gb_pipes;
- caps->num_z_pipes = radeon_winsys->z_pipes;
+ caps->pci_id = rws->get_value(rws, R300_VID_PCI_ID);
+ caps->num_frag_pipes = rws->get_value(rws, R300_VID_GB_PIPES);
+ caps->num_z_pipes = rws->get_value(rws, R300_VID_Z_PIPES);
r300_init_debug(r300screen);
r300_parse_chipset(caps);
r300screen->caps = caps;
- r300screen->radeon_winsys = radeon_winsys;
- r300screen->screen.winsys = (struct pipe_winsys*)radeon_winsys;
+ r300screen->rws = rws;
+ r300screen->screen.winsys = (struct pipe_winsys*)rws;
r300screen->screen.destroy = r300_destroy_screen;
r300screen->screen.get_name = r300_get_name;
r300screen->screen.get_vendor = r300_get_vendor;
@@ -350,13 +289,15 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
r300screen->screen.get_paramf = r300_get_paramf;
r300screen->screen.is_format_supported = r300_is_format_supported;
r300screen->screen.context_create = r300_create_context;
- r300screen->screen.get_tex_transfer = r300_get_tex_transfer;
- r300screen->screen.tex_transfer_destroy = r300_tex_transfer_destroy;
- r300screen->screen.transfer_map = r300_transfer_map;
- r300screen->screen.transfer_unmap = r300_transfer_unmap;
r300_init_screen_texture_functions(&r300screen->screen);
- u_simple_screen_init(&r300screen->screen);
+ r300_screen_init_buffer_functions(r300screen);
return &r300screen->screen;
}
+
+struct r300_winsys_screen *
+r300_winsys_screen(struct pipe_screen *screen)
+{
+ return r300_screen(screen)->rws;
+}
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 502fbfa5a24..1cf8b7452d7 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Corbin Simpson <[email protected]>
+ * Copyright 2010 Marek Olšák <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -27,13 +28,13 @@
#include "r300_chipset.h"
-struct radeon_winsys;
+#include <stdio.h>
struct r300_screen {
/* Parent class */
struct pipe_screen screen;
- struct radeon_winsys* radeon_winsys;
+ struct r300_winsys_screen *rws;
/* Chipset capabilities */
struct r300_capabilities* caps;
@@ -42,26 +43,12 @@ struct r300_screen {
unsigned debug;
};
-struct r300_transfer {
- /* Parent class */
- struct pipe_transfer transfer;
-
- /* Offset from start of buffer. */
- unsigned offset;
-};
/* Convenience cast wrapper. */
static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
return (struct r300_screen*)screen;
}
-/* Convenience cast wrapper. */
-static INLINE struct r300_transfer*
-r300_transfer(struct pipe_transfer* transfer)
-{
- return (struct r300_transfer*)transfer;
-}
-
/* Debug functionality. */
/**
@@ -81,6 +68,7 @@ r300_transfer(struct pipe_transfer* transfer)
#define DBG_DRAW 0x0000010
#define DBG_TEX 0x0000020
#define DBG_FALL 0x0000040
+#define DBG_ANISOHQ 0x0000080
/*@}*/
static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
@@ -94,7 +82,7 @@ static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags,
if (SCREEN_DBG_ON(screen, flags)) {
va_list va;
va_start(va, fmt);
- debug_vprintf(fmt, va);
+ vfprintf(stderr, fmt, va);
va_end(va);
}
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
new file mode 100644
index 00000000000..a1cd48ee730
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ */
+#include <stdio.h>
+
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
+#include "util/u_math.h"
+
+#include "r300_screen_buffer.h"
+
+#include "r300_winsys.h"
+
+boolean r300_buffer_is_referenced(struct r300_context *r300,
+ struct pipe_buffer *buf)
+{
+ struct r300_buffer *rbuf = r300_buffer(buf);
+ if (r300_buffer_is_user_buffer(buf))
+ return FALSE;
+
+ return r300->rws->is_buffer_referenced(r300->rws, rbuf->buf);
+
+}
+int r300_upload_index_buffer(struct r300_context *r300,
+ struct pipe_buffer **index_buffer,
+ unsigned index_size,
+ unsigned start,
+ unsigned count)
+{
+ struct pipe_buffer *upload_buffer = NULL;
+ unsigned index_offset = start * index_size;
+ int ret = 0;
+
+ if (r300_buffer_is_user_buffer(*index_buffer)) {
+ ret = u_upload_buffer(r300->upload_ib,
+ index_offset,
+ count * index_size,
+ *index_buffer,
+ &index_offset,
+ &upload_buffer);
+ if (ret) {
+ goto done;
+ }
+ *index_buffer = upload_buffer;
+ }
+ done:
+ // if (upload_buffer)
+ // pipe_buffer_reference(&upload_buffer, NULL);
+ return ret;
+}
+
+int r300_upload_user_buffers(struct r300_context *r300)
+{
+ enum pipe_error ret = PIPE_OK;
+ int i, nr;
+
+ nr = r300->vertex_buffer_count;
+
+ for (i = 0; i < nr; i++) {
+
+ if (r300_buffer_is_user_buffer(r300->vertex_buffer[i].buffer)) {
+ struct pipe_buffer *upload_buffer = NULL;
+ unsigned offset = 0; /*r300->vertex_buffer[i].buffer_offset * 4;*/
+ unsigned size = r300->vertex_buffer[i].buffer->size;
+ unsigned upload_offset;
+ ret = u_upload_buffer(r300->upload_vb,
+ offset, size,
+ r300->vertex_buffer[i].buffer,
+ &upload_offset, &upload_buffer);
+ if (ret)
+ return ret;
+
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ r300->vertex_buffer[i].buffer = upload_buffer;
+ r300->vertex_buffer[i].buffer_offset = upload_offset;
+ }
+ }
+ return ret;
+}
+
+static struct r300_winsys_buffer *
+r300_winsys_buffer_create(struct r300_screen *r300screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct r300_winsys_screen *rws = r300screen->rws;
+ struct r300_winsys_buffer *buf;
+
+ buf = rws->buffer_create(rws, alignment, usage, size);
+ return buf;
+}
+
+static void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
+ struct r300_buffer *rbuf)
+{
+ struct r300_winsys_screen *rws = r300screen->rws;
+
+ if (rbuf->buf) {
+ rws->buffer_reference(rws, &rbuf->buf, NULL);
+ rbuf->buf = NULL;
+ }
+}
+
+static struct pipe_buffer *r300_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_buffer *rbuf;
+
+ rbuf = CALLOC_STRUCT(r300_buffer);
+ if (!rbuf)
+ goto error1;
+
+ rbuf->magic = R300_BUFFER_MAGIC;
+
+ pipe_reference_init(&rbuf->base.reference, 1);
+ rbuf->base.screen = screen;
+ rbuf->base.alignment = alignment;
+ rbuf->base.usage = usage;
+ rbuf->base.size = size;
+
+ rbuf->buf = r300_winsys_buffer_create(r300screen,
+ alignment,
+ usage,
+ size);
+
+ if (!rbuf->buf)
+ goto error2;
+
+ return &rbuf->base;
+error2:
+ FREE(rbuf);
+error1:
+ return NULL;
+}
+
+
+static struct pipe_buffer *r300_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct r300_buffer *rbuf;
+
+ rbuf = CALLOC_STRUCT(r300_buffer);
+ if (!rbuf)
+ goto no_rbuf;
+
+ rbuf->magic = R300_BUFFER_MAGIC;
+
+ pipe_reference_init(&rbuf->base.reference, 1);
+ rbuf->base.screen = screen;
+ rbuf->base.alignment = 1;
+ rbuf->base.usage = 0;
+ rbuf->base.size = bytes;
+
+ rbuf->user_buffer = ptr;
+ return &rbuf->base;
+
+no_rbuf:
+ return NULL;
+}
+
+static void r300_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct r300_screen *r300screen = r300_screen(buf->screen);
+ struct r300_buffer *rbuf = r300_buffer(buf);
+
+ r300_winsys_buffer_destroy(r300screen, rbuf);
+ FREE(rbuf);
+}
+
+static void *
+r300_buffer_map_range(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset, unsigned length,
+ unsigned usage )
+{
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_winsys_screen *rws = r300screen->rws;
+ struct r300_buffer *rbuf = r300_buffer(buf);
+ void *map;
+ int flush = 0;
+ int i;
+
+ if (rbuf->user_buffer)
+ return rbuf->user_buffer;
+
+ if (rbuf->base.usage & PIPE_BUFFER_USAGE_CONSTANT)
+ goto just_map;
+
+ /* check if the mapping is to a range we already flushed */
+ if (usage & PIPE_BUFFER_USAGE_DISCARD) {
+ for (i = 0; i < rbuf->num_ranges; i++) {
+
+ if ((offset >= rbuf->ranges[i].start) &&
+ (offset < rbuf->ranges[i].end))
+ flush = 1;
+
+ if (flush) {
+ /* unreference this hw buffer and allocate a new one */
+ rws->buffer_reference(rws, &rbuf->buf, NULL);
+
+ rbuf->num_ranges = 0;
+ rbuf->map = NULL;
+ rbuf->buf = r300_winsys_buffer_create(r300screen,
+ rbuf->base.alignment,
+ rbuf->base.usage,
+ rbuf->base.size);
+ break;
+ }
+ }
+ }
+just_map:
+ map = rws->buffer_map(rws, rbuf->buf, usage);
+
+ return map;
+}
+
+static void
+r300_buffer_flush_mapped_range( struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset,
+ unsigned length )
+{
+ struct r300_buffer *rbuf = r300_buffer(buf);
+ int i;
+
+ if (rbuf->user_buffer)
+ return;
+
+ if (rbuf->base.usage & PIPE_BUFFER_USAGE_CONSTANT)
+ return;
+
+ /* mark the range as used */
+ for(i = 0; i < rbuf->num_ranges; ++i) {
+ if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+length)) {
+ rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset);
+ rbuf->ranges[i].end = MAX2(rbuf->ranges[i].end, (offset+length));
+ return;
+ }
+ }
+
+ rbuf->ranges[rbuf->num_ranges].start = offset;
+ rbuf->ranges[rbuf->num_ranges].end = offset+length;
+ rbuf->num_ranges++;
+}
+
+static void *
+r300_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned usage)
+{
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_winsys_screen *rws = r300screen->rws;
+ struct r300_buffer *rbuf = r300_buffer(buf);
+ void *map;
+
+ if (rbuf->user_buffer)
+ return rbuf->user_buffer;
+
+ map = rws->buffer_map(rws, rbuf->buf, usage);
+
+ return map;
+}
+
+static void
+r300_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+ struct r300_screen *r300screen = r300_screen(screen);
+ struct r300_winsys_screen *rws = r300screen->rws;
+ struct r300_buffer *rbuf = r300_buffer(buf);
+
+ if (rbuf->buf) {
+ rws->buffer_unmap(rws, rbuf->buf);
+ }
+}
+
+void r300_screen_init_buffer_functions(struct r300_screen *r300screen)
+{
+ r300screen->screen.buffer_create = r300_buffer_create;
+ r300screen->screen.user_buffer_create = r300_user_buffer_create;
+ r300screen->screen.buffer_map = r300_buffer_map;
+ r300screen->screen.buffer_map_range = r300_buffer_map_range;
+ r300screen->screen.buffer_flush_mapped_range = r300_buffer_flush_mapped_range;
+ r300screen->screen.buffer_unmap = r300_buffer_unmap;
+ r300screen->screen.buffer_destroy = r300_buffer_destroy;
+}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
new file mode 100644
index 00000000000..0cf349c25cd
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -0,0 +1,99 @@
+#ifndef R300_SCREEN_BUFFER_H
+#define R300_SCREEN_BUFFER_H
+#include <stdio.h>
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "r300_screen.h"
+
+#include "r300_winsys.h"
+#include "r300_context.h"
+
+#define R300_BUFFER_MAGIC 0xabcd1234
+
+struct r300_buffer_range {
+ uint32_t start;
+ uint32_t end;
+};
+#define R300_BUFFER_MAX_RANGES 32
+
+struct r300_buffer
+{
+ struct pipe_buffer base;
+
+ uint32_t magic;
+
+ struct r300_winsys_buffer *buf;
+
+ void *user_buffer;
+ struct r300_buffer_range ranges[R300_BUFFER_MAX_RANGES];
+ unsigned num_ranges;
+
+ void *map;
+};
+
+static INLINE struct r300_buffer *
+r300_buffer(struct pipe_buffer *buffer)
+{
+ if (buffer) {
+ assert(((struct r300_buffer *)buffer)->magic == R300_BUFFER_MAGIC);
+ return (struct r300_buffer *)buffer;
+ }
+ return NULL;
+}
+
+static INLINE boolean
+r300_buffer_is_user_buffer(struct pipe_buffer *buffer)
+{
+ return r300_buffer(buffer)->user_buffer ? true : false;
+}
+
+static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws,
+ struct pipe_buffer *buffer,
+ int rd, int wr)
+{
+ struct r300_buffer *buf = r300_buffer(buffer);
+
+ if (!buf->buf)
+ return true;
+
+ return rws->add_buffer(rws, buf->buf, rd, wr);
+}
+
+
+static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws,
+ struct r300_texture *tex,
+ int rd, int wr)
+{
+ return rws->add_buffer(rws, tex->buffer, rd, wr);
+}
+
+void r300_screen_init_buffer_functions(struct r300_screen *r300screen);
+
+static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws,
+ struct r300_buffer *buf,
+ uint32_t rd, uint32_t wd, uint32_t flags)
+{
+ if (!buf->buf)
+ return;
+
+ rws->write_cs_reloc(rws, buf->buf, rd, wd, flags);
+}
+
+static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws,
+ struct r300_texture *texture,
+ uint32_t rd, uint32_t wd, uint32_t flags)
+{
+ rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags);
+}
+
+int r300_upload_user_buffers(struct r300_context *r300);
+
+int r300_upload_index_buffer(struct r300_context *r300,
+ struct pipe_buffer **index_buffer,
+ unsigned index_size,
+ unsigned start,
+ unsigned count);
+
+boolean r300_buffer_is_referenced(struct r300_context *r300,
+ struct pipe_buffer *buf);
+#endif
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 1f6f99d3e52..39e05583dd4 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -34,11 +34,11 @@
#include "r300_context.h"
#include "r300_reg.h"
#include "r300_screen.h"
+#include "r300_screen_buffer.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
#include "r300_vs.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@@ -525,10 +525,10 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
tex = (struct r300_texture*)old_state->cbufs[i]->texture;
if (tex) {
- r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+ r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[0],
- tex->microtile != 0,
- tex->macrotile != 0);
+ tex->microtile,
+ tex->macrotile);
}
}
if (old_state->zsbuf &&
@@ -537,10 +537,10 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
tex = (struct r300_texture*)old_state->zsbuf->texture;
if (tex) {
- r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+ r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[0],
- tex->microtile != 0,
- tex->macrotile != 0);
+ tex->microtile,
+ tex->macrotile);
}
}
@@ -549,19 +549,19 @@ static void r300_fb_update_tiling_flags(struct r300_context *r300,
tex = (struct r300_texture*)new_state->cbufs[i]->texture;
level = new_state->cbufs[i]->level;
- r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+ r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[level],
- tex->microtile != 0,
- tex->mip_macrotile[level] != 0);
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
tex = (struct r300_texture*)new_state->zsbuf->texture;
level = new_state->zsbuf->level;
- r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer,
+ r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
tex->pitch[level],
- tex->microtile != 0,
- tex->mip_macrotile[level] != 0);
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
}
@@ -571,12 +571,12 @@ static void
{
struct r300_context* r300 = r300_context(pipe);
struct r300_screen* r300screen = r300_screen(pipe->screen);
+ struct pipe_framebuffer_state *old_state = r300->fb_state.state;
unsigned max_width, max_height;
uint32_t zbuffer_bpp = 0;
-
if (state->nr_cbufs > 4) {
- debug_printf("r300: Implementation error: Too many MRTs in %s, "
+ fprintf(stderr, "r300: Implementation error: Too many MRTs in %s, "
"refusing to bind framebuffer state!\n", __FUNCTION__);
return;
}
@@ -590,28 +590,35 @@ static void
}
if (state->width > max_width || state->height > max_height) {
- debug_printf("r300: Implementation error: Render targets are too "
+ fprintf(stderr, "r300: Implementation error: Render targets are too "
"big in %s, refusing to bind framebuffer state!\n", __FUNCTION__);
return;
}
-
if (r300->draw) {
draw_flush(r300->draw);
}
- memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+ r300->fb_state.dirty = TRUE;
- r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
- (state->zsbuf ? 10 : 0) + 8;
+ /* If nr_cbufs is changed from zero to non-zero or vice versa... */
+ if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
+ r300->blend_state.dirty = TRUE;
+ }
+ /* If zsbuf is set from NULL to non-NULL or vice versa.. */
+ if (!!old_state->zsbuf != !!state->zsbuf) {
+ r300->dsa_state.dirty = TRUE;
+ }
+ if (!r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
- /* XXX wait what */
- r300->blend_state.dirty = TRUE;
- r300->dsa_state.dirty = TRUE;
- r300->fb_state.dirty = TRUE;
- r300->scissor_state.dirty = TRUE;
+ memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+
+ r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
+ (state->zsbuf ? 10 : 0) + 8;
/* Polygon offset depends on the zbuffer bit depth. */
if (state->zsbuf && r300->polygon_offset_enabled) {
@@ -716,8 +723,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->vap_control_status = R300_VC_32BIT_SWAP;
#endif
- /* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
- * Else, enable HW TCL and force Draw's TCL off. */
+ /* If no TCL engine is present, turn off the HW TCL. */
if (!r300screen->caps->has_tcl) {
rs->vap_control_status |= R300_VAP_TCL_BYPASS;
}
@@ -807,6 +813,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ boolean scissor_was_enabled = r300->scissor_enabled;
if (r300->draw) {
draw_flush(r300->draw);
@@ -815,20 +822,17 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
+ r300->scissor_enabled = rs->rs.scissor;
} else {
r300->polygon_offset_enabled = FALSE;
+ r300->scissor_enabled = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
- /* XXX Why is this still needed, dammit!? */
- r300->scissor_state.dirty = TRUE;
- r300->viewport_state.dirty = TRUE;
-
- /* XXX Clean these up when we move to atom emits */
- if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
- r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ if (scissor_was_enabled != r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
}
}
@@ -844,6 +848,7 @@ static void*
{
struct r300_context* r300 = r300_context(pipe);
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
+ boolean is_r500 = r300_screen(pipe->screen)->caps->is_r500;
int lod_bias;
union util_color uc;
@@ -859,6 +864,8 @@ static void*
state->min_mip_filter,
state->max_anisotropy > 0);
+ sampler->filter0 |= r300_anisotropy(state->max_anisotropy);
+
/* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
/* We must pass these to the merge function to clamp them properly. */
sampler->min_lod = MAX2((unsigned)state->min_lod, 0);
@@ -868,7 +875,13 @@ static void*
sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
- sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
+ /* This is very high quality anisotropic filtering for R5xx.
+ * It's good for benchmarking the performance of texturing but
+ * in practice we don't want to slow down the driver because it's
+ * a pretty good performance killer. Feel free to play with it. */
+ if (DBG_ON(r300, DBG_ANISOHQ) && is_r500) {
+ sampler->filter1 |= r500_anisotropy(state->max_anisotropy);
+ }
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
sampler->border_color = uc.ui;
@@ -918,13 +931,14 @@ static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
FREE(state);
}
-static void r300_set_sampler_textures(struct pipe_context* pipe,
- unsigned count,
- struct pipe_texture** texture)
+static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
+ unsigned count,
+ struct pipe_sampler_view** views)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
+ struct r300_texture *texture;
unsigned i;
boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
boolean dirty_tex = FALSE;
@@ -935,13 +949,20 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
for (i = 0; i < count; i++) {
- if (state->textures[i] != (struct r300_texture*)texture[i]) {
- pipe_texture_reference((struct pipe_texture**)&state->textures[i],
- texture[i]);
+ if (state->fragment_sampler_views[i] != views[i]) {
+ pipe_sampler_view_reference(&state->fragment_sampler_views[i],
+ views[i]);
+
+ if (!views[i]) {
+ continue;
+ }
+
+ /* A new sampler view (= texture)... */
dirty_tex = TRUE;
/* R300-specific - set the texrect factor in the fragment shader */
- if (!is_r500 && state->textures[i]->is_npot) {
+ texture = (struct r300_texture *)views[i]->texture;
+ if (!is_r500 && texture->is_npot) {
/* XXX It would be nice to re-emit just 1 constant,
* XXX not all of them */
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
@@ -950,9 +971,9 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
for (i = count; i < 8; i++) {
- if (state->textures[i]) {
- pipe_texture_reference((struct pipe_texture**)&state->textures[i],
- NULL);
+ if (state->fragment_sampler_views[i]) {
+ pipe_sampler_view_reference(&state->fragment_sampler_views[i],
+ NULL);
}
}
@@ -965,6 +986,32 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,
}
}
+static struct pipe_sampler_view *
+r300_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+static void
+r300_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void r300_set_scissor_state(struct pipe_context* pipe,
const struct pipe_scissor_state* state)
{
@@ -973,7 +1020,9 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
memcpy(r300->scissor_state.state, state,
sizeof(struct pipe_scissor_state));
- r300->scissor_state.dirty = TRUE;
+ if (r300->scissor_enabled) {
+ r300->scissor_state.dirty = TRUE;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,
@@ -1024,63 +1073,171 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- unsigned i, max_index = ~0;
+ struct pipe_vertex_buffer *vbo;
+ unsigned i, max_index = (1 << 24) - 1;
+ boolean any_user_buffer = FALSE;
- memcpy(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count);
+ if (count == r300->vertex_buffer_count &&
+ memcmp(r300->vertex_buffer, buffers,
+ sizeof(struct pipe_vertex_buffer) * count) == 0) {
+ return;
+ }
+
+ /* Check if the stride is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ if (buffers[i].buffer) {
+ if (buffers[i].stride % 4 != 0) {
+ // XXX Shouldn't we align the buffer?
+ fprintf(stderr, "r300_set_vertex_buffers: "
+ "Unaligned buffer stride %i isn't supported.\n",
+ buffers[i].stride);
+ assert(0);
+ abort();
+ }
+ }
+ }
for (i = 0; i < count; i++) {
- max_index = MIN2(buffers[i].max_index, max_index);
+ /* Why, yes, I AM casting away constness. How did you know? */
+ vbo = (struct pipe_vertex_buffer*)&buffers[i];
+
+ /* Reference our buffer. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+
+ /* Skip NULL buffers */
+ if (!buffers[i].buffer) {
+ continue;
+ }
+
+ if (r300_buffer_is_user_buffer(vbo->buffer)) {
+ any_user_buffer = TRUE;
+ }
+
+ if (vbo->max_index == ~0) {
+ /* Bogus value from broken state tracker; hax it. */
+ vbo->max_index =
+ (vbo->buffer->size - vbo->buffer_offset) / vbo->stride;
+ }
+
+ max_index = MIN2(vbo->max_index, max_index);
}
+ for (; i < r300->vertex_buffer_count; i++) {
+ /* Dereference any old buffers. */
+ pipe_buffer_reference(&r300->vertex_buffer[i].buffer, NULL);
+ }
+
+ memcpy(r300->vertex_buffer, buffers,
+ sizeof(struct pipe_vertex_buffer) * count);
+
r300->vertex_buffer_count = count;
r300->vertex_buffer_max_index = max_index;
+ r300->any_user_vbs = any_user_buffer;
if (r300->draw) {
draw_flush(r300->draw);
draw_set_vertex_buffers(r300->draw, count, buffers);
- } else {
- r300->vertex_stream_state.dirty = TRUE;
}
}
-static boolean r300_validate_aos(struct r300_context *r300)
+/* Update the PSC tables. */
+static void r300_vertex_psc(struct r300_vertex_element_state *velems)
{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
- int i;
-
- /* Check if formats and strides are aligned to the size of DWORD. */
- for (i = 0; i < r300->vertex_element_count; i++) {
- if (vbuf[velem[i].vertex_buffer_index].stride % 4 != 0 ||
- util_format_get_blocksize(velem[i].src_format) % 4 != 0) {
- return FALSE;
+ struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
+ uint16_t type, swizzle;
+ enum pipe_format format;
+ unsigned i;
+
+ assert(velems->count <= 16);
+
+ /* Vertex shaders have no semantics on their inputs,
+ * so PSC should just route stuff based on the vertex elements,
+ * and not on attrib information. */
+ for (i = 0; i < velems->count; i++) {
+ format = velems->velem[i].src_format;
+
+ type = r300_translate_vertex_data_type(format) |
+ (i << R300_DST_VEC_LOC_SHIFT);
+ swizzle = r300_translate_vertex_data_swizzle(format);
+
+ if (i & 1) {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+ } else {
+ vstream->vap_prog_stream_cntl[i >> 1] |= type;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
- return TRUE;
+
+ /* Set the last vector in the PSC. */
+ if (i) {
+ i -= 1;
+ }
+ vstream->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+
+ vstream->count = (i >> 1) + 1;
}
-static void r300_set_vertex_elements(struct pipe_context* pipe,
- unsigned count,
- const struct pipe_vertex_element* elements)
+static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
+ unsigned count,
+ const struct pipe_vertex_element* attribs)
{
- struct r300_context* r300 = r300_context(pipe);
+ struct r300_screen* r300screen = r300_screen(pipe->screen);
+ struct r300_vertex_element_state *velems;
+ unsigned i, size;
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = CALLOC_STRUCT(r300_vertex_element_state);
+ if (velems != NULL) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
+
+ if (r300screen->caps->has_tcl) {
+ /* Check if the format is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ size = util_format_get_blocksize(attribs[i].src_format);
+
+ if (size % 4 != 0) {
+ /* XXX Shouldn't we align the format? */
+ fprintf(stderr, "r300_create_vertex_elements_state: "
+ "Unaligned format %s:%i isn't supported\n",
+ util_format_name(attribs[i].src_format), size);
+ assert(0);
+ abort();
+ }
+ }
+
+ r300_vertex_psc(velems);
+ }
+ }
+ return velems;
+}
+
+static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *state)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_vertex_element_state *velems = state;
+
+ if (velems == NULL) {
+ return;
+ }
- memcpy(r300->vertex_element,
- elements,
- sizeof(struct pipe_vertex_element) * count);
- r300->vertex_element_count = count;
+ r300->velems = velems;
if (r300->draw) {
draw_flush(r300->draw);
- draw_set_vertex_elements(r300->draw, count, elements);
+ draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
}
- if (!r300_validate_aos(r300)) {
- /* XXX We should fallback using draw. */
- assert(0);
- abort();
- }
+ UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
+ r300->vertex_stream_state.size = (1 + velems->vertex_stream.count) * 2;
+}
+
+static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
+{
+ FREE(state);
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1088,68 +1245,71 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
- /* Copy state directly into shader. */
- vs->state = *shader;
- vs->state.tokens = tgsi_dup_tokens(shader->tokens);
-
- tgsi_scan_shader(shader->tokens, &vs->info);
+ struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
+ r300_vertex_shader_common_init(vs, shader);
- return (void*)vs;
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300_translate_vertex_shader(r300, vs);
} else {
- return draw_create_vertex_shader(r300->draw, shader);
+ vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
}
+
+ return vs;
}
static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
- if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
+ if (vs == NULL) {
+ r300->vs_state.state = NULL;
+ return;
+ }
+ if (vs == r300->vs_state.state) {
+ return;
+ }
+ r300->vs_state.state = vs;
- if (vs == NULL) {
- r300->vs_state.state = NULL;
- return;
- } else if (!vs->translated) {
- r300_translate_vertex_shader(r300, vs);
- }
+ // VS output mapping for HWTCL or stream mapping for SWTCL to the RS block
+ if (r300->fs) {
+ r300_vertex_shader_setup_wpos(r300);
+ }
+ memcpy(r300->vap_output_state.state, &vs->vap_out,
+ sizeof(struct r300_vap_output_state));
+ r300->vap_output_state.dirty = TRUE;
+
+ /* The majority of the RS block bits is dependent on the vertex shader. */
+ r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
- UPDATE_STATE(shader, r300->vs_state);
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->vs_state.dirty = TRUE;
r300->vs_state.size = vs->code.length + 9;
- r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */
- r300->vap_output_state.dirty = TRUE;
- r300->vertex_stream_state.dirty = TRUE; /* XXX needed for TCL bypass */
r300->pvs_flush.dirty = TRUE;
- if (r300->fs) {
- r300_vertex_shader_setup_wpos(r300);
- }
-
r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
}
static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
if (r300_screen(pipe->screen)->caps->has_tcl) {
- struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
-
rc_constants_destroy(&vs->code.constants);
- FREE((void*)vs->state.tokens);
- FREE(shader);
} else {
draw_delete_vertex_shader(r300->draw,
- (struct draw_vertex_shader*)shader);
+ (struct draw_vertex_shader*)vs->draw_vs);
}
+
+ FREE((void*)vs->state.tokens);
+ FREE(shader);
}
static void r300_set_constant_buffer(struct pipe_context *pipe,
@@ -1191,7 +1351,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
/* XXX Subtract immediates and RC_STATE_* variables. */
if (buf->size > (sizeof(float) * 4 * max_size)) {
- debug_printf("r300: Max size of the constant buffer is "
+ fprintf(stderr, "r300: Max size of the constant buffer is "
"%i*4 floats.\n", max_size);
abort();
}
@@ -1201,11 +1361,17 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
pipe_buffer_unmap(pipe->screen, buf);
if (shader == PIPE_SHADER_VERTEX) {
- r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
- r300->pvs_flush.dirty = TRUE;
- }
- else if (shader == PIPE_SHADER_FRAGMENT)
+ if (r300screen->caps->has_tcl) {
+ r300->dirty_state |= R300_NEW_VERTEX_SHADER_CONSTANTS;
+ r300->pvs_flush.dirty = TRUE;
+ } else if (r300->draw) {
+ draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
+ 0, r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+ buf->size);
+ }
+ } else if (shader == PIPE_SHADER_FRAGMENT) {
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
+ }
}
void r300_init_state_functions(struct r300_context* r300)
@@ -1243,14 +1409,19 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;
r300->context.delete_sampler_state = r300_delete_sampler_state;
- r300->context.set_fragment_sampler_textures = r300_set_sampler_textures;
+ r300->context.set_fragment_sampler_views = r300_set_fragment_sampler_views;
+ r300->context.create_sampler_view = r300_create_sampler_view;
+ r300->context.sampler_view_destroy = r300_sampler_view_destroy;
r300->context.set_scissor_state = r300_set_scissor_state;
r300->context.set_viewport_state = r300_set_viewport_state;
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
- r300->context.set_vertex_elements = r300_set_vertex_elements;
+
+ r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
+ r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
+ r300->context.delete_vertex_elements_state = r300_delete_vertex_elements_state;
r300->context.create_vs_state = r300_create_vs_state;
r300->context.bind_vs_state = r300_bind_vs_state;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 9c8e907fdf7..bc5431c802d 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -103,74 +103,19 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
assert(gen_count <= 8);
}
-/* Update the PSC tables. */
-/* XXX move this function into r300_state.c after TCL-bypass gets removed
- * XXX because this one is dependent only on vertex elements. */
-static void r300_vertex_psc(struct r300_context* r300)
-{
- struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
- uint16_t type, swizzle;
- enum pipe_format format;
- unsigned i;
- int identity[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- int* stream_tab;
-
- memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
-
- stream_tab = identity;
-
- /* Vertex shaders have no semantics on their inputs,
- * so PSC should just route stuff based on the vertex elements,
- * and not on attrib information. */
- DBG(r300, DBG_DRAW, "r300: vs expects %d attribs, routing %d elements"
- " in psc\n",
- vs->info.num_inputs,
- r300->vertex_element_count);
-
- for (i = 0; i < r300->vertex_element_count; i++) {
- format = r300->vertex_element[i].src_format;
-
- type = r300_translate_vertex_data_type(format) |
- (stream_tab[i] << R300_DST_VEC_LOC_SHIFT);
- swizzle = r300_translate_vertex_data_swizzle(format);
-
- if (i & 1) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
- } else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
- }
- }
-
- assert(i <= 15);
-
- /* Set the last vector in the PSC. */
- if (i) {
- i -= 1;
- }
- vformat->vap_prog_stream_cntl[i >> 1] |=
- (R300_LAST_VEC << (i & 1 ? 16 : 0));
-
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
-}
-
/* Update the PSC tables for SW TCL, using Draw. */
-static void r300_swtcl_vertex_psc(struct r300_context* r300)
+static void r300_swtcl_vertex_psc(struct r300_context *r300)
{
+ struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_vertex_stream_state *vformat =
- (struct r300_vertex_stream_state*)r300->vertex_stream_state.state;
struct vertex_info* vinfo = &r300->vertex_info;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i, attrib_count;
int* vs_output_tab = vs->stream_loc_notcl;
- memset(vformat, 0, sizeof(struct r300_vertex_stream_state));
+ /* XXX hax */
+ memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
/* For each Draw attribute, route it to the fragment shader according
* to the vs_output_tab. */
@@ -181,9 +126,7 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300)
" vs_output_tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
vs_output_tab[i]);
- }
- for (i = 0; i < attrib_count; i++) {
/* Make sure we have a proper destination for our attribute. */
assert(vs_output_tab[i] != -1);
@@ -199,11 +142,11 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300)
/* Add the attribute to the PSC table. */
if (i & 1) {
- vformat->vap_prog_stream_cntl[i >> 1] |= type << 16;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
+ vstream->vap_prog_stream_cntl[i >> 1] |= type << 16;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle << 16;
} else {
- vformat->vap_prog_stream_cntl[i >> 1] |= type;
- vformat->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
+ vstream->vap_prog_stream_cntl[i >> 1] |= type;
+ vstream->vap_prog_stream_cntl_ext[i >> 1] |= swizzle;
}
}
@@ -211,11 +154,12 @@ static void r300_swtcl_vertex_psc(struct r300_context* r300)
if (i) {
i -= 1;
}
- vformat->vap_prog_stream_cntl[i >> 1] |=
+ vstream->vap_prog_stream_cntl[i >> 1] |=
(R300_LAST_VEC << (i & 1 ? 16 : 0));
- vformat->count = (i >> 1) + 1;
- r300->vertex_stream_state.size = (1 + vformat->count) * 2;
+ vstream->count = (i >> 1) + 1;
+ r300->vertex_stream_state.dirty = TRUE;
+ r300->vertex_stream_state.size = (1 + vstream->count) * 2;
}
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
@@ -432,23 +376,8 @@ static void r300_update_rs_block(struct r300_context* r300,
static void r300_update_derived_shader_state(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vap_output_state *vap_out =
- (struct r300_vap_output_state*)r300->vap_output_state.state;
-
- /* XXX Mmm, delicious hax */
- memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
- memcpy(vap_out, vs->hwfmt, sizeof(uint)*4);
r300_update_rs_block(r300, &vs->outputs, &r300->fs->inputs);
-
- if (r300screen->caps->has_tcl) {
- r300_vertex_psc(r300);
- } else {
- r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info);
- r300_swtcl_vertex_psc(r300);
- }
}
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@@ -528,20 +457,25 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
(struct r300_textures_state*)r300->textures_state.state;
struct r300_texture_sampler_state *texstate;
struct r300_sampler_state *sampler;
+ struct pipe_sampler_view *view;
struct r300_texture *tex;
unsigned min_level, max_level, i, size;
unsigned count = MIN2(state->texture_count, state->sampler_count);
state->tx_enable = 0;
+ state->count = 0;
size = 2;
for (i = 0; i < count; i++) {
- if (state->textures[i] && state->sampler_states[i]) {
+ if (state->fragment_sampler_views[i] && state->sampler_states[i]) {
state->tx_enable |= 1 << i;
- tex = state->textures[i];
+ view = state->fragment_sampler_views[i];
+ tex = (struct r300_texture *)view->texture;
sampler = state->sampler_states[i];
+ assert(view->format == tex->tex.format);
+
texstate = &state->regs[i];
memcpy(texstate->format, &tex->state, sizeof(uint32_t)*3);
texstate->filter[0] = sampler->filter0;
@@ -563,8 +497,10 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
} else {
/* determine min/max levels */
/* the MAX_MIP level is the largest (finest) one */
- max_level = MIN2(sampler->max_lod, tex->tex.last_level);
- min_level = MIN2(sampler->min_lod, max_level);
+ max_level = MIN3(sampler->max_lod + view->first_level,
+ tex->tex.last_level, view->last_level);
+ min_level = MIN2(sampler->min_lod + view->first_level,
+ max_level);
texstate->format[0] |= R300_TX_NUM_LEVELS(max_level);
texstate->filter[0] |= R300_TX_MAX_MIP_LEVEL(min_level);
}
@@ -581,9 +517,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
void r300_update_derived_state(struct r300_context* r300)
{
- if (r300->rs_block_state.dirty ||
- r300->vertex_stream_state.dirty || /* XXX put updating this state out of this file */
- r300->rs_state.dirty) { /* XXX and remove this one (tcl_bypass dependency) */
+ if (r300->rs_block_state.dirty) {
r300_update_derived_shader_state(r300);
}
@@ -591,5 +525,12 @@ void r300_update_derived_state(struct r300_context* r300)
r300_merge_textures_and_samplers(r300);
}
+ if (r300->draw) {
+ memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+ r300_draw_emit_all_attribs(r300);
+ draw_compute_vertex_size(&r300->vertex_info);
+ r300_swtcl_vertex_psc(r300);
+ }
+
r300_update_ztop(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index af7827820cc..02d09c008c8 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -32,6 +32,8 @@
#include "r300_reg.h"
+#include <stdio.h>
+
/* Some maths. These should probably find their way to u_math, if needed. */
static INLINE int pack_float_16_6x(float f) {
@@ -54,7 +56,7 @@ static INLINE uint32_t r300_translate_blend_function(int blend_func)
case PIPE_BLEND_MAX:
return R300_COMB_FCN_MAX;
default:
- debug_printf("r300: Unknown blend function %d\n", blend_func);
+ fprintf(stderr, "r300: Unknown blend function %d\n", blend_func);
assert(0);
break;
}
@@ -100,13 +102,13 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
case PIPE_BLENDFACTOR_SRC1_ALPHA:
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- debug_printf("r300: Implementation error: "
+ fprintf(stderr, "r300: Implementation error: "
"Bad blend factor %d not supported!\n", blend_fact);
assert(0);
break;
default:
- debug_printf("r300: Unknown blend factor %d\n", blend_fact);
+ fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);
assert(0);
break;
}
@@ -135,7 +137,7 @@ static INLINE uint32_t r300_translate_depth_stencil_function(int zs_func)
case PIPE_FUNC_ALWAYS:
return R300_ZS_ALWAYS;
default:
- debug_printf("r300: Unknown depth/stencil function %d\n",
+ fprintf(stderr, "r300: Unknown depth/stencil function %d\n",
zs_func);
assert(0);
break;
@@ -163,7 +165,7 @@ static INLINE uint32_t r300_translate_stencil_op(int s_op)
case PIPE_STENCIL_OP_INVERT:
return R300_ZS_INVERT;
default:
- debug_printf("r300: Unknown stencil op %d", s_op);
+ fprintf(stderr, "r300: Unknown stencil op %d", s_op);
assert(0);
break;
}
@@ -190,7 +192,7 @@ static INLINE uint32_t r300_translate_alpha_function(int alpha_func)
case PIPE_FUNC_ALWAYS:
return R300_FG_ALPHA_FUNC_ALWAYS;
default:
- debug_printf("r300: Unknown alpha function %d", alpha_func);
+ fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);
assert(0);
break;
}
@@ -209,7 +211,7 @@ r300_translate_polygon_mode_front(unsigned mode) {
return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
default:
- debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+ fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
__FUNCTION__);
return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
}
@@ -227,7 +229,7 @@ r300_translate_polygon_mode_back(unsigned mode) {
return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
default:
- debug_printf("r300: Bad polygon mode %i in %s\n", mode,
+ fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
__FUNCTION__);
return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
}
@@ -255,7 +257,7 @@ static INLINE uint32_t r300_translate_wrap(int wrap)
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
default:
- debug_printf("r300: Unknown texture wrap %d", wrap);
+ fprintf(stderr, "r300: Unknown texture wrap %d", wrap);
assert(0);
return 0;
}
@@ -276,7 +278,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MIN_FILTER_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", min);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", min);
assert(0);
break;
}
@@ -288,7 +290,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MAG_FILTER_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", mag);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", mag);
assert(0);
break;
}
@@ -304,7 +306,7 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
break;
default:
- debug_printf("r300: Unknown texture filter %d\n", mip);
+ fprintf(stderr, "r300: Unknown texture filter %d\n", mip);
assert(0);
break;
}
@@ -327,6 +329,18 @@ static INLINE uint32_t r300_anisotropy(unsigned max_aniso)
}
}
+static INLINE uint32_t r500_anisotropy(unsigned max_aniso)
+{
+ if (!max_aniso) {
+ return 0;
+ }
+ max_aniso -= 1;
+
+ // Map the range [0, 15] to [0, 63].
+ return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |
+ R500_TX_ANISO_HIGH_QUALITY;;
+}
+
/* Non-CSO state. (For now.) */
static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
@@ -348,44 +362,17 @@ static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
return 0;
}
-/* Utility function to count the number of components in RGBAZS formats.
- * XXX should go to util or p_format.h */
-static INLINE unsigned pf_component_count(enum pipe_format format) {
- unsigned count = 0;
-
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0)) {
- count++;
- }
- if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
- count++;
- }
-
- return count;
-}
-
/* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
uint32_t result = 0;
const struct util_format_description *desc;
- unsigned components = pf_component_count(format);
+ unsigned components = util_format_get_nr_components(format);
desc = util_format_description(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format),
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_name(format),
__FUNCTION__, __LINE__);
assert(0);
}
@@ -406,7 +393,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
result = R300_DATA_TYPE_FLOAT_1 + (components - 1);
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@@ -427,15 +414,15 @@ r300_translate_vertex_data_type(enum pipe_format format) {
}
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
- debug_printf("r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
+ fprintf(stderr, "r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n",
util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0));
assert(0);
}
break;
default:
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
assert(0);
}
@@ -457,7 +444,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
assert(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- debug_printf("r300: Bad format %s in %s:%d\n",
+ fprintf(stderr, "r300: Bad format %s in %s:%d\n",
util_format_name(format), __FUNCTION__, __LINE__);
return 0;
}
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 4a2c68269b1..88ae75bb816 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -127,7 +127,7 @@ void r300_emit_invariant_state(struct r300_context* r300,
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
/* XXX */
- OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
+ OUT_CS_REG(R300_SC_CLIP_RULE, 0xFFFF);
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index c0144f64b4a..22ccadfe3dd 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -31,8 +31,7 @@
#include "r300_texture.h"
#include "r300_screen.h"
#include "r300_state_inlines.h"
-
-#include "radeon_winsys.h"
+#include "r300_winsys.h"
#define TILE_WIDTH 0
#define TILE_HEIGHT 1
@@ -46,6 +45,18 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
+/* Return true for non-compressed and non-YUV formats. */
+static boolean r300_format_is_plain(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN;
+}
+
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
@@ -148,7 +159,7 @@ static uint32_t r300_translate_texformat(enum pipe_format format)
}
/* Compressed formats. */
- if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) {
+ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
switch (format) {
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
@@ -302,7 +313,6 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return R300_COLOR_FORMAT_I8;
@@ -311,24 +321,19 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_B5G6R5_UNORM:
return R300_COLOR_FORMAT_RGB565;
case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
return R300_COLOR_FORMAT_ARGB1555;
case PIPE_FORMAT_B4G4R4A4_UNORM:
return R300_COLOR_FORMAT_ARGB4444;
/* 32-bit buffers. */
case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_SRGB:
case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_SRGB:
case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8B8G8R8_SRGB:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
return R300_COLOR_FORMAT_ARGB8888;
case PIPE_FORMAT_R10G10B10A2_UNORM:
@@ -393,12 +398,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
desc = util_format_description(format);
/* Specifies how the shader output is written to the fog unit. */
- if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
- /* The gamma correction causes precision loss so we need
- * higher precision to maintain reasonable quality.
- * It has nothing to do with the colorbuffer format. */
- modifier |= R300_US_OUT_FMT_C4_10_GAMMA;
- } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
+ if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
if (desc->channel[0].size == 32) {
modifier |= R300_US_OUT_FMT_C4_32_FP;
} else {
@@ -428,46 +428,39 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
return modifier | R300_C2_SEL_A;
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_L8_UNORM:
- case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8_SNORM:
return modifier | R300_C2_SEL_R;
- /* ARGB 32-bit outputs. */
+ /* BGRA outputs. */
case PIPE_FORMAT_B5G6R5_UNORM:
case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8A8_SRGB:
case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_SRGB:
return modifier |
R300_C0_SEL_B | R300_C1_SEL_G |
R300_C2_SEL_R | R300_C3_SEL_A;
- /* BGRA 32-bit outputs. */
+ /* ARGB outputs. */
case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_A8R8G8B8_SRGB:
case PIPE_FORMAT_X8R8G8B8_UNORM:
- case PIPE_FORMAT_X8R8G8B8_SRGB:
return modifier |
R300_C0_SEL_A | R300_C1_SEL_R |
R300_C2_SEL_G | R300_C3_SEL_B;
- /* RGBA 32-bit outputs. */
+ /* ABGR outputs. */
case PIPE_FORMAT_A8B8G8R8_UNORM:
- case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_X8B8G8R8_UNORM:
- case PIPE_FORMAT_X8B8G8R8_SRGB:
return modifier |
R300_C0_SEL_A | R300_C1_SEL_B |
R300_C2_SEL_G | R300_C3_SEL_R;
- /* ABGR 32-bit outputs. */
+ /* RGBA outputs. */
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
case PIPE_FORMAT_R10G10B10A2_UNORM:
- /* RGBA high precision outputs (same swizzles as ABGR low precision) */
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
//case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
@@ -617,18 +610,23 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture *tex,
unsigned level,
- boolean rv350_mode)
+ boolean rv350_mode,
+ int dim)
{
- unsigned tile_width, width;
+ unsigned tile, texdim;
- tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
- width = u_minify(tex->tex.width0, level);
+ tile = r300_texture_get_tile_size(tex, dim, TRUE);
+ if (dim == TILE_WIDTH) {
+ texdim = u_minify(tex->tex.width0, level);
+ } else {
+ texdim = u_minify(tex->tex.height0, level);
+ }
/* See TX_FILTER1_n.MACRO_SWITCH. */
if (rv350_mode) {
- return width >= tile_width;
+ return texdim >= tile;
} else {
- return width > tile_width;
+ return texdim > tile;
}
}
@@ -653,7 +651,7 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
width = u_minify(tex->tex.width0, level);
- if (!util_format_is_compressed(tex->tex.format)) {
+ if (r300_format_is_plain(tex->tex.format)) {
tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
tex->mip_macrotile[level]);
width = align(width, tile_width);
@@ -671,7 +669,7 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
height = u_minify(tex->tex.height0, level);
- if (!util_format_is_compressed(tex->tex.format)) {
+ if (r300_format_is_plain(tex->tex.format)) {
tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
tex->mip_macrotile[level]);
height = align(height, tile_height);
@@ -692,9 +690,11 @@ static void r300_setup_miptree(struct r300_screen* screen,
for (i = 0; i <= base->last_level; i++) {
/* Let's see if this miplevel can be macrotiled. */
- tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
- r300_texture_macro_switch(tex, i, rv350_mode)) ?
- R300_BUFFER_TILED : R300_BUFFER_LINEAR;
+ tex->mip_macrotile[i] =
+ (tex->macrotile == R300_BUFFER_TILED &&
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH) &&
+ r300_texture_macro_switch(tex, i, rv350_mode, TILE_HEIGHT)) ?
+ R300_BUFFER_TILED : R300_BUFFER_LINEAR;
stride = r300_texture_get_stride(screen, tex, i);
nblocksy = r300_texture_get_nblocksy(tex, i);
@@ -724,14 +724,51 @@ static void r300_setup_flags(struct r300_texture* tex)
!util_is_power_of_two(tex->tex.height0);
}
+static void r300_setup_tiling(struct pipe_screen *screen,
+ struct r300_texture *tex)
+{
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
+ enum pipe_format format = tex->tex.format;
+ boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350;
+
+ if (!r300_format_is_plain(format)) {
+ return;
+ }
+
+ if (tex->tex.width0 == 1 ||
+ tex->tex.height0 == 1) {
+ return;
+ }
+
+ /* Set microtiling. */
+ switch (util_format_get_blocksize(format)) {
+ case 1:
+ case 4:
+ tex->microtile = R300_BUFFER_TILED;
+ break;
+
+ case 2:
+ case 8:
+ if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
+ tex->microtile = R300_BUFFER_SQUARETILED;
+ }
+ break;
+ }
+
+ /* Set macrotiling. */
+ if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
+ r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
+ tex->macrotile = R300_BUFFER_TILED;
+ }
+}
+
/* Create a new texture. */
-static struct pipe_texture*
- r300_texture_create(struct pipe_screen* screen,
- const struct pipe_texture* template)
+static struct pipe_texture* r300_texture_create(struct pipe_screen* screen,
+ const struct pipe_texture* template)
{
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
struct r300_screen* rscreen = r300_screen(screen);
- struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
if (!tex) {
return NULL;
@@ -742,16 +779,19 @@ static struct pipe_texture*
tex->tex.screen = screen;
r300_setup_flags(tex);
+ if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) {
+ r300_setup_tiling(screen, tex);
+ }
r300_setup_miptree(rscreen, tex);
r300_setup_texture_state(rscreen, tex);
- tex->buffer = screen->buffer_create(screen, 2048,
- PIPE_BUFFER_USAGE_PIXEL,
- tex->size);
- winsys->buffer_set_tiling(winsys, tex->buffer,
- tex->pitch[0],
- tex->microtile != R300_BUFFER_LINEAR,
- tex->macrotile != R300_BUFFER_LINEAR);
+ tex->buffer = rws->buffer_create(rws, 2048,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->size);
+ rws->buffer_set_tiling(rws, tex->buffer,
+ tex->pitch[0],
+ tex->microtile,
+ tex->macrotile);
if (!tex->buffer) {
FREE(tex);
@@ -764,9 +804,9 @@ static struct pipe_texture*
static void r300_texture_destroy(struct pipe_texture* texture)
{
struct r300_texture* tex = (struct r300_texture*)texture;
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
- pipe_buffer_reference(&tex->buffer, NULL);
-
+ rws->buffer_reference(rws, &tex->buffer, NULL);
FREE(tex);
}
@@ -806,14 +846,17 @@ static void r300_tex_surface_destroy(struct pipe_surface* s)
FREE(s);
}
+
static struct pipe_texture*
- r300_texture_blanket(struct pipe_screen* screen,
- const struct pipe_texture* base,
- const unsigned* stride,
- struct pipe_buffer* buffer)
+ r300_texture_from_handle(struct pipe_screen* screen,
+ const struct pipe_texture* base,
+ struct winsys_handle *whandle)
{
- struct r300_texture* tex;
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
struct r300_screen* rscreen = r300_screen(screen);
+ struct r300_winsys_buffer *buffer;
+ struct r300_texture* tex;
+ unsigned stride;
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D ||
@@ -822,6 +865,11 @@ static struct pipe_texture*
return NULL;
}
+ buffer = rws->buffer_from_handle(rws, screen, whandle, &stride);
+ if (!buffer) {
+ return NULL;
+ }
+
tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
return NULL;
@@ -831,17 +879,38 @@ static struct pipe_texture*
pipe_reference_init(&tex->tex.reference, 1);
tex->tex.screen = screen;
- tex->stride_override = *stride;
- tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
+ tex->stride_override = stride;
+ tex->pitch[0] = stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
r300_setup_texture_state(rscreen, tex);
- pipe_buffer_reference(&tex->buffer, buffer);
+ /* one ref already taken */
+ tex->buffer = buffer;
return (struct pipe_texture*)tex;
}
+static boolean
+ r300_texture_get_handle(struct pipe_screen* screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
+ struct r300_texture* tex = (struct r300_texture*)texture;
+ unsigned stride;
+
+ if (!tex) {
+ return FALSE;
+ }
+
+ stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
+
+ rws->buffer_get_handle(rws, tex->buffer, stride, whandle);
+
+ return TRUE;
+}
+
static struct pipe_video_surface *
r300_video_surface_create(struct pipe_screen *screen,
enum pipe_video_chroma_format chroma_format,
@@ -893,10 +962,11 @@ static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
void r300_init_screen_texture_functions(struct pipe_screen* screen)
{
screen->texture_create = r300_texture_create;
+ screen->texture_from_handle = r300_texture_from_handle;
+ screen->texture_get_handle = r300_texture_get_handle;
screen->texture_destroy = r300_texture_destroy;
screen->get_tex_surface = r300_get_tex_surface;
screen->tex_surface_destroy = r300_tex_surface_destroy;
- screen->texture_blanket = r300_texture_blanket;
screen->video_surface_create = r300_video_surface_create;
screen->video_surface_destroy= r300_video_surface_destroy;
@@ -904,19 +974,23 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen)
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
- struct pipe_buffer** buffer,
+ struct r300_winsys_buffer** buffer,
unsigned* stride)
{
struct r300_texture* tex = (struct r300_texture*)texture;
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
+ struct r300_winsys_buffer *buf;
+
if (!tex) {
return FALSE;
}
- pipe_buffer_reference(buffer, tex->buffer);
+ rws->buffer_reference(rws, &buf, tex->buffer);
if (stride) {
*stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
}
+ *buffer = buf;
return TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 46a5fb6188b..60c7fa83420 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -60,13 +60,11 @@ r300_video_surface(struct pipe_video_surface *pvs)
return (struct r300_video_surface *)pvs;
}
-#ifndef R300_WINSYS_H
-
+/* Used internally for texture_is_referenced()
+ */
boolean r300_get_texture_buffer(struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
+ struct pipe_texture *texture,
+ struct r300_winsys_buffer** buffer,
unsigned* stride);
-#endif /* R300_WINSYS_H */
-
#endif /* R300_TEXTURE_H */
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index aff4ddd4e23..3b3802ee2b2 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -25,12 +25,11 @@
#include "radeon_compiler.h"
#include "radeon_program.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_util.h"
-#include "util/u_debug.h"
-
static unsigned translate_opcode(unsigned opcode)
{
switch(opcode) {
@@ -145,7 +144,7 @@ static unsigned translate_opcode(unsigned opcode)
case TGSI_OPCODE_KIL: return RC_OPCODE_KIL;
}
- debug_printf("r300: Unknown TGSI/RC opcode: %i\n", opcode);
+ fprintf(stderr, "r300: Unknown TGSI/RC opcode: %s\n", tgsi_get_opcode_name(opcode));
return RC_OPCODE_ILLEGAL_OPCODE;
}
@@ -272,9 +271,6 @@ static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_inst
struct rc_instruction * dst;
int i;
- if (src->Instruction.Opcode == TGSI_OPCODE_END)
- return;
-
dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev);
dst->U.I.Opcode = translate_opcode(src->Instruction.Opcode);
dst->U.I.SaturateMode = translate_saturate(src->Instruction.Saturate);
@@ -333,6 +329,7 @@ static void handle_immediate(struct tgsi_to_rc * ttr,
void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
const struct tgsi_token * tokens)
{
+ struct tgsi_full_instruction *inst;
struct tgsi_parse_context parser;
unsigned imm_index = 0;
int i;
@@ -367,7 +364,15 @@ void r300_tgsi_to_rc(struct tgsi_to_rc * ttr,
imm_index++;
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
- transform_instruction(ttr, &parser.FullToken.FullInstruction);
+ inst = &parser.FullToken.FullInstruction;
+ /* This hack with the RET opcode woudn't work with
+ * conditionals. */
+ if (inst->Instruction.Opcode == TGSI_OPCODE_END ||
+ inst->Instruction.Opcode == TGSI_OPCODE_RET) {
+ break;
+ }
+
+ transform_instruction(ttr, inst);
break;
}
}
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
new file mode 100644
index 00000000000..987a040698f
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2008 Corbin Simpson <[email protected]>
+ * Copyright 2010 Marek Olšák <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "r300_context.h"
+#include "r300_transfer.h"
+#include "r300_texture.h"
+#include "r300_screen.h"
+
+#include "r300_winsys.h"
+
+#include "util/u_memory.h"
+#include "util/u_format.h"
+
+struct r300_transfer {
+ /* Parent class */
+ struct pipe_transfer transfer;
+
+ /* Pipe context. */
+ struct pipe_context *ctx;
+
+ /* Parameters of get_tex_transfer. */
+ unsigned x, y, level, zslice, face;
+
+ /* Offset from start of buffer. */
+ unsigned offset;
+
+ /* Detiled texture. */
+ struct r300_texture *detiled_texture;
+
+ /* Transfer and format flags. */
+ unsigned buffer_usage, render_target_usage;
+};
+
+/* Convenience cast wrapper. */
+static INLINE struct r300_transfer*
+r300_transfer(struct pipe_transfer* transfer)
+{
+ return (struct r300_transfer*)transfer;
+}
+
+/* Copy from a tiled texture to a detiled one. */
+static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL |
+ r300transfer->buffer_usage);
+
+ ctx->surface_copy(ctx, dst, 0, 0, src, r300transfer->x, r300transfer->y,
+ transfer->width, transfer->height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/* Copy a detiled texture to a tiled one. */
+static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
+ struct r300_transfer *r300transfer)
+{
+ struct pipe_screen *screen = ctx->screen;
+ struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer;
+ struct pipe_texture *tex = transfer->texture;
+ struct pipe_surface *src, *dst;
+
+ src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ dst = screen->get_tex_surface(screen, tex, r300transfer->face,
+ r300transfer->level, r300transfer->zslice,
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_PIXEL);
+
+ /* XXX this flush prevents the following DRM error from occuring:
+ * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation !
+ * Reproducible with perf/copytex. */
+ ctx->flush(ctx, 0, NULL);
+
+ ctx->surface_copy(ctx, dst, r300transfer->x, r300transfer->y, src, 0, 0,
+ transfer->width, transfer->height);
+
+ /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */
+ ctx->flush(ctx, 0, NULL);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+static struct pipe_transfer*
+r300_get_tex_transfer(struct pipe_context *ctx,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
+{
+ struct r300_texture *tex = (struct r300_texture *)texture;
+ struct r300_screen *r300screen = r300_screen(ctx->screen);
+ struct r300_transfer *trans;
+ struct pipe_texture template;
+
+ trans = CALLOC_STRUCT(r300_transfer);
+ if (trans) {
+ /* Initialize the transfer object. */
+ pipe_texture_reference(&trans->transfer.texture, texture);
+ trans->transfer.usage = usage;
+ trans->transfer.width = w;
+ trans->transfer.height = h;
+ trans->ctx = ctx;
+ trans->x = x;
+ trans->y = y;
+ trans->level = level;
+ trans->zslice = zslice;
+ trans->face = face;
+
+ /* If the texture is tiled, we must create a temporary detiled texture
+ * for this transfer. */
+ if (tex->microtile || tex->macrotile) {
+ trans->buffer_usage = pipe_transfer_buffer_flags(&trans->transfer);
+ trans->render_target_usage =
+ util_format_is_depth_or_stencil(texture->format) ?
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ template.target = PIPE_TEXTURE_2D;
+ template.format = texture->format;
+ template.width0 = w;
+ template.height0 = h;
+ template.depth0 = 0;
+ template.last_level = 0;
+ template.nr_samples = 0;
+ template.tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
+ R300_TEXTURE_USAGE_TRANSFER;
+
+ /* For texture reading, the temporary (detiled) texture is used as
+ * a render target when blitting from a tiled texture. */
+ if (usage & PIPE_TRANSFER_READ) {
+ template.tex_usage |= trans->render_target_usage;
+ }
+ /* For texture writing, the temporary texture is used as a sampler
+ * when blitting into a tiled texture. */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SAMPLER;
+ }
+
+ /* Create the temporary texture. */
+ trans->detiled_texture = (struct r300_texture*)
+ ctx->screen->texture_create(ctx->screen,
+ &template);
+
+ assert(!trans->detiled_texture->microtile &&
+ !trans->detiled_texture->macrotile);
+
+ /* Set the stride.
+ * Parameters x, y, level, zslice, and face remain zero. */
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, trans->detiled_texture, 0);
+
+ if (usage & PIPE_TRANSFER_READ) {
+ /* We cannot map a tiled texture directly because the data is
+ * in a different order, therefore we do detiling using a blit. */
+ r300_copy_from_tiled_texture(ctx, trans);
+ }
+ } else {
+ trans->transfer.x = x;
+ trans->transfer.y = y;
+ trans->transfer.stride =
+ r300_texture_get_stride(r300screen, tex, level);
+ trans->transfer.level = level;
+ trans->transfer.zslice = zslice;
+ trans->transfer.face = face;
+ trans->offset = r300_texture_get_offset(tex, level, zslice, face);
+ }
+ }
+ return &trans->transfer;
+}
+
+static void r300_tex_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans)
+{
+ struct r300_transfer *r300transfer = r300_transfer(trans);
+
+ if (r300transfer->detiled_texture) {
+ if (trans->usage & PIPE_TRANSFER_WRITE) {
+ r300_copy_into_tiled_texture(r300transfer->ctx, r300transfer);
+ }
+
+ pipe_texture_reference(
+ (struct pipe_texture**)&r300transfer->detiled_texture, NULL);
+ }
+ pipe_texture_reference(&trans->texture, NULL);
+ FREE(trans);
+}
+
+static void* r300_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer *transfer)
+{
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+ char *map;
+ enum pipe_format format = tex->tex.format;
+
+ if (r300transfer->detiled_texture) {
+ /* The detiled texture is of the same size as the region being mapped
+ * (no offset needed). */
+ return rws->buffer_map(rws,
+ r300transfer->detiled_texture->buffer,
+ pipe_transfer_buffer_flags(transfer));
+ } else {
+ /* Tiling is disabled. */
+ map = rws->buffer_map(rws, tex->buffer,
+ pipe_transfer_buffer_flags(transfer));
+
+ if (!map) {
+ return NULL;
+ }
+
+ return map + r300_transfer(transfer)->offset +
+ transfer->y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ }
+}
+
+static void r300_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer *transfer)
+{
+ struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
+ struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_texture *tex = (struct r300_texture*)transfer->texture;
+
+ if (r300transfer->detiled_texture) {
+ rws->buffer_unmap(rws, r300transfer->detiled_texture->buffer);
+ } else {
+ rws->buffer_unmap(rws, tex->buffer);
+ }
+}
+
+
+void r300_init_transfer_functions( struct r300_context *r300ctx )
+{
+ struct pipe_context *ctx = &r300ctx->context;
+
+ ctx->get_tex_transfer = r300_get_tex_transfer;
+ ctx->tex_transfer_destroy = r300_tex_transfer_destroy;
+ ctx->transfer_map = r300_transfer_map;
+ ctx->transfer_unmap = r300_transfer_unmap;
+}
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
new file mode 100644
index 00000000000..79baf6d0480
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Corbin Simpson <[email protected]>
+ * Copyright 2010 Marek Olšák <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef R300_TRANSFER
+#define R300_TRANSFER
+
+#include "pipe/p_screen.h"
+
+struct r300_context;
+
+void r300_init_transfer_functions(struct r300_context *r300ctx);
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 60a04bbfeda..d5690caa68e 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -34,8 +34,6 @@
#include "radeon_compiler.h"
-#include "util/u_math.h"
-
/* Convert info about VS output semantics into r300_shader_semantics. */
static void r300_shader_read_vs_outputs(
struct tgsi_shader_info* info,
@@ -89,95 +87,41 @@ static void r300_shader_read_vs_outputs(
assert(0);
}
}
+
+ /* WPOS is a straight copy of POSITION and it's always emitted. */
+ vs_outputs->wpos = i;
}
-static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
+/* This function sets up:
+ * - VAP mapping, which maps VS registers to output semantics and
+ * at the same time it indicates which attributes are enabled and should
+ * be rasterized.
+ * - Stream mapping to VS outputs if TCL is not present. */
+static void r300_init_vs_output_mapping(struct r300_vertex_shader* vs)
{
struct r300_shader_semantics* vs_outputs = &vs->outputs;
- uint32_t* hwfmt = vs->hwfmt;
- int i, gen_count;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
+ int *stream_loc = vs->stream_loc_notcl;
+ int i, gen_count, tabi = 0;
boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
vs_outputs->bcolor[1] != ATTR_UNUSED;
- /* Do the actual vertex_info setup.
- *
- * vertex_info has four uints of hardware-specific data in it.
- * vinfo.hwfmt[0] is R300_VAP_VTX_STATE_CNTL
- * vinfo.hwfmt[1] is R300_VAP_VSM_VTX_ASSM
- * vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
- * vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
-
- hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+ vap_out->vap_vtx_state_cntl = 0x5555; /* XXX this is classic Mesa bonghits */
/* Position. */
if (vs_outputs->pos != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_POS;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+
+ stream_loc[tabi++] = 0;
} else {
assert(0);
}
/* Point size. */
if (vs_outputs->psize != ATTR_UNUSED) {
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- }
-
- /* Colors. */
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
- vs_outputs->color[1] != ATTR_UNUSED) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
- }
- }
-
- /* Back-face colors. */
- if (any_bcolor_used) {
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
- }
- }
-
- /* Texture coordinates. */
- gen_count = 0;
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- if (vs_outputs->generic[i] != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
- }
-
- /* Fog coordinates. */
- if (vs_outputs->fog != ATTR_UNUSED) {
- hwfmt[1] |= (R300_INPUT_CNTL_TC0 << gen_count);
- hwfmt[3] |= (4 << (3 * gen_count));
- gen_count++;
- }
-
- /* XXX magic */
- assert(gen_count <= 8);
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
- /* WPOS. */
- vs->wpos_tex_output = gen_count;
-}
-
-/* Sets up stream mapping to equivalent VS outputs if TCL is bypassed
- * or isn't present. */
-static void r300_stream_locations_notcl(
- struct r300_shader_semantics* vs_outputs,
- int* stream_loc)
-{
- int i, tabi = 0, gen_count;
- boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
- vs_outputs->bcolor[1] != ATTR_UNUSED;
-
- /* Position. */
- stream_loc[tabi++] = 0;
-
- /* Point size. */
- if (vs_outputs->psize != ATTR_UNUSED) {
stream_loc[tabi++] = 1;
}
@@ -185,6 +129,9 @@ static void r300_stream_locations_notcl(
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
vs_outputs->color[1] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+
stream_loc[tabi++] = 2 + i;
}
}
@@ -192,6 +139,9 @@ static void r300_stream_locations_notcl(
/* Back-face colors. */
if (any_bcolor_used) {
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ vap_out->vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ vap_out->vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+
stream_loc[tabi++] = 4 + i;
}
}
@@ -200,6 +150,9 @@ static void r300_stream_locations_notcl(
gen_count = 0;
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
if (vs_outputs->generic[i] != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
@@ -208,17 +161,22 @@ static void r300_stream_locations_notcl(
/* Fog coordinates. */
if (vs_outputs->fog != ATTR_UNUSED) {
+ vap_out->vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << gen_count);
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * gen_count));
+
assert(tabi < 16);
stream_loc[tabi++] = 6 + gen_count;
gen_count++;
}
+ /* XXX magic */
+ assert(gen_count <= 8);
+
/* WPOS. */
- if (vs_outputs->wpos != ATTR_UNUSED) {
- assert(tabi < 16);
- stream_loc[tabi++] = 6 + gen_count;
- gen_count++;
- }
+ vs->wpos_tex_output = gen_count;
+
+ assert(tabi < 16);
+ stream_loc[tabi++] = 6 + gen_count;
for (; tabi < 16;) {
stream_loc[tabi++] = -1;
@@ -294,26 +252,16 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
}
}
-static void r300_insert_wpos(struct r300_vertex_program_compiler* c,
- struct r300_shader_semantics* outputs)
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader)
{
- int i, lastOutput = 0;
+ /* Copy state directly into shader. */
+ vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
+ tgsi_scan_shader(shader->tokens, &vs->info);
- /* Find the max output index. */
- lastOutput = MAX2(lastOutput, outputs->psize);
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->color[i]);
- lastOutput = MAX2(lastOutput, outputs->bcolor[i]);
- }
- for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
- lastOutput = MAX2(lastOutput, outputs->generic[i]);
- }
- lastOutput = MAX2(lastOutput, outputs->fog);
-
- /* Set WPOS after the last output. */
- lastOutput++;
- rc_copy_output(&c->Base, 0, lastOutput); /* out[lastOutput] = out[0]; */
- outputs->wpos = lastOutput;
+ r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+ r300_init_vs_output_mapping(vs);
}
void r300_translate_vertex_shader(struct r300_context* r300,
@@ -322,9 +270,6 @@ void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_program_compiler compiler;
struct tgsi_to_rc ttr;
- /* Initialize. */
- r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
-
/* Setup the compiler */
rc_init(&compiler.Base);
@@ -348,45 +293,41 @@ void r300_translate_vertex_shader(struct r300_context* r300,
compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
/* Insert the WPOS output. */
- r300_insert_wpos(&compiler, &vs->outputs);
-
- r300_shader_vap_output_fmt(vs);
- r300_stream_locations_notcl(&vs->outputs, vs->stream_loc_notcl);
+ rc_copy_output(&compiler.Base, 0, vs->outputs.wpos);
/* Invoke the compiler */
r3xx_compile_vertex_program(&compiler);
if (compiler.Base.Error) {
/* XXX We should fallback using Draw. */
- fprintf(stderr, "r300 VP: Compiler error\n");
+ fprintf(stderr, "r300 VP: Compiler error:\n%s", compiler.Base.ErrorMsg);
abort();
}
/* And, finally... */
rc_destroy(&compiler.Base);
- vs->translated = TRUE;
}
boolean r300_vertex_shader_setup_wpos(struct r300_context* r300)
{
struct r300_vertex_shader* vs = r300->vs_state.state;
+ struct r300_vap_output_state *vap_out = &vs->vap_out;
int tex_output = vs->wpos_tex_output;
uint32_t tex_fmt = R300_INPUT_CNTL_TC0 << tex_output;
- uint32_t* hwfmt = vs->hwfmt;
if (r300->fs->inputs.wpos != ATTR_UNUSED) {
/* Enable WPOS in VAP. */
- if (!(hwfmt[1] & tex_fmt)) {
- hwfmt[1] |= tex_fmt;
- hwfmt[3] |= (4 << (3 * tex_output));
+ if (!(vap_out->vap_vsm_vtx_assm & tex_fmt)) {
+ vap_out->vap_vsm_vtx_assm |= tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] |= (4 << (3 * tex_output));
assert(tex_output < 8);
return TRUE;
}
} else {
/* Disable WPOS in VAP. */
- if (hwfmt[1] & tex_fmt) {
- hwfmt[1] &= ~tex_fmt;
- hwfmt[3] &= ~(4 << (3 * tex_output));
+ if (vap_out->vap_vsm_vtx_assm & tex_fmt) {
+ vap_out->vap_vsm_vtx_assm &= ~tex_fmt;
+ vap_out->vap_out_vtx_fmt[1] &= ~(4 << (3 * tex_output));
return TRUE;
}
}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 18cfeee3cd4..f6f0b86b683 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -28,6 +28,7 @@
#include "tgsi/tgsi_scan.h"
#include "radeon_code.h"
+#include "r300_context.h"
#include "r300_shader_semantics.h"
struct r300_context;
@@ -38,7 +39,7 @@ struct r300_vertex_shader {
struct tgsi_shader_info info;
struct r300_shader_semantics outputs;
- uint hwfmt[4];
+ struct r300_vap_output_state vap_out;
/* Stream locations for SWTCL or if TCL is bypassed. */
int stream_loc_notcl[16];
@@ -46,13 +47,17 @@ struct r300_vertex_shader {
/* Output stream location for WPOS. */
int wpos_tex_output;
- /* Has this shader been translated yet? */
- boolean translated;
-
+ /* HWTCL-specific. */
/* Machine code (if translated) */
struct r300_vertex_program_code code;
+
+ /* SWTCL-specific. */
+ void *draw_vs;
};
+void r300_vertex_shader_common_init(struct r300_vertex_shader *vs,
+ const struct pipe_shader_state *shader);
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 40fb8a95ca5..acfa5dbeb9c 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -23,10 +23,6 @@
#ifndef R300_WINSYS_H
#define R300_WINSYS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
/* The public interface header for the r300 pipe driver.
* Any winsys hosting this pipe needs to implement r300_winsys and then
* call r300_create_screen to start things. */
@@ -34,19 +30,147 @@ extern "C" {
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
-struct radeon_winsys;
+#include "r300_defines.h"
+
+struct r300_winsys_screen;
/* Creates a new r300 screen. */
-struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
+struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws);
+
+struct r300_winsys_buffer;
boolean r300_get_texture_buffer(struct pipe_screen* screen,
struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride);
+ struct r300_winsys_buffer** buffer,
+ unsigned *stride);
+
+enum r300_value_id {
+ R300_VID_PCI_ID,
+ R300_VID_GB_PIPES,
+ R300_VID_Z_PIPES,
+ R300_VID_SQUARE_TILING_SUPPORT
+};
+
+struct r300_winsys_screen {
+ void (*destroy)(struct r300_winsys_screen *ws);
+
+ /**
+ * Buffer management. Buffer attributes are mostly fixed over its lifetime.
+ *
+ * Remember that gallium gets to choose the interface it needs, and the
+ * window systems must then implement that interface (rather than the
+ * other way around...).
+ *
+ * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
+ * usage argument is only an optimization hint, not a guarantee, therefore
+ * proper behavior must be observed in all circumstances.
+ *
+ * alignment indicates the client's alignment requirements, eg for
+ * SSE instructions.
+ */
+ struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size);
+
+ /**
+ * Map the entire data store of a buffer object into the client's address.
+ * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags.
+ */
+ void *(*buffer_map)( struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ unsigned usage);
+
+ void (*buffer_unmap)( struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf );
+
+ void (*buffer_destroy)( struct r300_winsys_buffer *buf );
+
+
+ void (*buffer_reference)(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer **pdst,
+ struct r300_winsys_buffer *src);
+
+ boolean (*buffer_references)(struct r300_winsys_buffer *a,
+ struct r300_winsys_buffer *b);
+
+ void (*buffer_flush_range)(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ unsigned offset,
+ unsigned length);
+
+ /* Add a pipe_buffer to the list of buffer objects to validate. */
+ boolean (*add_buffer)(struct r300_winsys_screen *winsys,
+ struct r300_winsys_buffer *buf,
+ uint32_t rd,
+ uint32_t wd);
+
+
+ /* Revalidate all currently setup pipe_buffers.
+ * Returns TRUE if a flush is required. */
+ boolean (*validate)(struct r300_winsys_screen* winsys);
+
+ /* Check to see if there's room for commands. */
+ boolean (*check_cs)(struct r300_winsys_screen* winsys, int size);
+
+ /* Start a command emit. */
+ void (*begin_cs)(struct r300_winsys_screen* winsys,
+ int size,
+ const char* file,
+ const char* function,
+ int line);
+
+ /* Write a dword to the command buffer. */
+ void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword);
+
+ /* Write a relocated dword to the command buffer. */
+ void (*write_cs_reloc)(struct r300_winsys_screen *winsys,
+ struct r300_winsys_buffer *buf,
+ uint32_t rd,
+ uint32_t wd,
+ uint32_t flags);
+
+ /* Finish a command emit. */
+ void (*end_cs)(struct r300_winsys_screen* winsys,
+ const char* file,
+ const char* function,
+ int line);
+
+ /* Flush the CS. */
+ void (*flush_cs)(struct r300_winsys_screen* winsys);
+
+ /* winsys flush - callback from winsys when flush required */
+ void (*set_flush_cb)(struct r300_winsys_screen *winsys,
+ void (*flush_cb)(void *), void *data);
+
+ void (*reset_bos)(struct r300_winsys_screen *winsys);
+
+ void (*buffer_set_tiling)(struct r300_winsys_screen *winsys,
+ struct r300_winsys_buffer *buffer,
+ uint32_t pitch,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled);
+
+ uint32_t (*get_value)(struct r300_winsys_screen *winsys,
+ enum r300_value_id vid);
+
+ struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *winsys,
+ struct pipe_screen *screen,
+ struct winsys_handle *whandle,
+ unsigned *stride);
+ boolean (*buffer_get_handle)(struct r300_winsys_screen *winsys,
+ struct r300_winsys_buffer *buffer,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
+ boolean (*is_buffer_referenced)(struct r300_winsys_screen *winsys,
+ struct r300_winsys_buffer *buffer);
+
+
+};
-#ifdef __cplusplus
-}
-#endif
+struct r300_winsys_screen *
+r300_winsys_screen(struct pipe_screen *screen);
#endif /* R300_WINSYS_H */
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index e4ac49fa85f..239655d628b 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -6,7 +6,9 @@ LIBNAME = softpipe
C_SOURCES = \
sp_fs_exec.c \
sp_fs_sse.c \
+ sp_buffer.c \
sp_clear.c \
+ sp_fence.c \
sp_flush.c \
sp_query.c \
sp_context.c \
@@ -32,7 +34,6 @@ C_SOURCES = \
sp_tex_tile_cache.c \
sp_tile_cache.c \
sp_surface.c \
- sp_video_context.c \
- sp_winsys.c
+ sp_video_context.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index 3042e556c64..9949a53adfd 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -7,9 +7,11 @@ softpipe = env.ConvenienceLibrary(
source = [
'sp_fs_exec.c',
'sp_fs_sse.c',
+ 'sp_buffer.c',
'sp_clear.c',
'sp_context.c',
'sp_draw_arrays.c',
+ 'sp_fence.c',
'sp_flush.c',
'sp_prim_vbuf.c',
'sp_setup.c',
@@ -33,8 +35,7 @@ softpipe = env.ConvenienceLibrary(
'sp_tex_tile_cache.c',
'sp_texture.c',
'sp_tile_cache.c',
- 'sp_video_context.c',
- 'sp_winsys.c'
+ 'sp_video_context.c'
])
Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_buffer.c b/src/gallium/drivers/softpipe/sp_buffer.c
new file mode 100644
index 00000000000..8f390250869
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_buffer.c
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "sp_screen.h"
+#include "sp_buffer.h"
+
+
+static void *
+softpipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf);
+ return softpipe_buf->data;
+}
+
+
+static void
+softpipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+softpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct softpipe_buffer *sbuf = softpipe_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+softpipe_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+softpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct softpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(softpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = softpipe_buffer_create;
+ screen->user_buffer_create = softpipe_user_buffer_create;
+ screen->buffer_map = softpipe_buffer_map;
+ screen->buffer_unmap = softpipe_buffer_unmap;
+ screen->buffer_destroy = softpipe_buffer_destroy;
+}
diff --git a/src/gallium/drivers/softpipe/sp_buffer.h b/src/gallium/drivers/softpipe/sp_buffer.h
new file mode 100644
index 00000000000..9d8e56a176b
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_buffer.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef SP_BUFFER_H
+#define SP_BUFFER_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+struct softpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
+
+
+/** Cast wrapper */
+static INLINE struct softpipe_buffer *
+softpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct softpipe_buffer *)buf;
+}
+
+
+void
+softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_BUFFER_H */
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index ddc35bcd629..937a573092f 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -44,6 +44,7 @@
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_tex_tile_cache.h"
+#include "sp_texture.h"
#include "sp_query.h"
@@ -103,12 +104,12 @@ softpipe_destroy( struct pipe_context *pipe )
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
sp_destroy_tex_tile_cache(softpipe->tex_cache[i]);
- pipe_texture_reference(&softpipe->texture[i], NULL);
+ pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]);
- pipe_texture_reference(&softpipe->vertex_textures[i], NULL);
+ pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL);
}
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
@@ -210,7 +211,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
- softpipe->pipe.winsys = screen->winsys;
+ softpipe->pipe.winsys = NULL;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
softpipe->pipe.priv = priv;
@@ -245,6 +246,10 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
+ softpipe->pipe.create_vertex_elements_state = softpipe_create_vertex_elements_state;
+ softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;
+ softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state;
+
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
@@ -252,12 +257,13 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
- softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures;
- softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures;
+ softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views;
+ softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views;
+ softpipe->pipe.create_sampler_view = softpipe_create_sampler_view;
+ softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
- softpipe->pipe.set_vertex_elements = softpipe_set_vertex_elements;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
@@ -272,6 +278,7 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
softpipe_init_query_funcs( softpipe );
+ softpipe_init_texture_funcs( &softpipe->pipe );
softpipe->pipe.render_condition = softpipe_render_condition;
@@ -280,13 +287,13 @@ softpipe_create_context( struct pipe_screen *screen,
* Must be before quad stage setup!
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
- softpipe->cbuf_cache[i] = sp_create_tile_cache( screen );
- softpipe->zsbuf_cache = sp_create_tile_cache( screen );
+ softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe );
+ softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe );
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen );
+ softpipe->tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache(screen);
+ softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
}
/* setup quad rendering stages */
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 95def72c541..75e03c8ae6b 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -45,6 +45,7 @@ struct softpipe_tile_cache;
struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
+struct sp_velems_state;
struct softpipe_context {
@@ -59,6 +60,7 @@ struct softpipe_context {
struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
+ struct sp_velems_state *velems;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -68,17 +70,15 @@ struct softpipe_context {
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
- unsigned num_textures;
+ unsigned num_sampler_views;
unsigned num_vertex_samplers;
- unsigned num_vertex_textures;
- unsigned num_vertex_elements;
+ unsigned num_vertex_sampler_views;
unsigned num_vertex_buffers;
unsigned dirty; /**< Mask of SP_NEW_x flags */
@@ -93,7 +93,7 @@ struct softpipe_context {
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
- void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
+ const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
/** Vertex format */
struct vertex_info vertex_info;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index b2acc36bf7a..7b77eb239fd 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -33,90 +33,19 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
#include "util/u_prim.h"
#include "sp_context.h"
#include "sp_query.h"
#include "sp_state.h"
+#include "sp_buffer.h"
#include "draw/draw_context.h"
-static void
-softpipe_map_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- sp->mapped_constants[i][j] = ws->buffer_map(ws,
- sp->constants[i][j],
- PIPE_BUFFER_USAGE_CPU_READ);
- }
- }
- }
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- if (sp->constants[PIPE_SHADER_VERTEX][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- sp->mapped_constants[PIPE_SHADER_VERTEX][i],
- sp->constants[PIPE_SHADER_VERTEX][i]->size);
- }
- if (sp->constants[PIPE_SHADER_GEOMETRY][i]) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- sp->mapped_constants[PIPE_SHADER_GEOMETRY][i],
- sp->constants[PIPE_SHADER_GEOMETRY][i]->size);
- }
- }
-}
-
-
-static void
-softpipe_unmap_constant_buffers(struct softpipe_context *sp)
-{
- struct pipe_winsys *ws = sp->pipe.winsys;
- uint i;
- /* really need to flush all prims since the vert/frag shaders const buffers
- * are going away now.
- */
- draw_flush(sp->draw);
-
- for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_VERTEX,
- i,
- NULL,
- 0);
- draw_set_mapped_constant_buffer(sp->draw,
- PIPE_SHADER_GEOMETRY,
- i,
- NULL,
- 0);
- }
-
- for (i = 0; i < PIPE_SHADER_TYPES; i++) {
- uint j;
-
- for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
- if (sp->constants[i][j] && sp->constants[i][j]->size) {
- ws->buffer_unmap(ws, sp->constants[i][j]);
- }
- sp->mapped_constants[i][j] = NULL;
- }
- }
-}
/**
@@ -261,25 +190,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
}
softpipe_map_transfers(sp);
- softpipe_map_constant_buffers(sp);
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
- void *buf;
-
- buf = pipe_buffer_map(pipe->screen,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
- void *mapped_indexes;
-
- mapped_indexes = pipe_buffer_map(pipe->screen,
- indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = softpipe_buffer(indexBuffer)->data;
draw_set_mapped_element_buffer_range(draw,
indexSize,
minIndex,
@@ -300,15 +220,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
/* unmap vertex/index buffers - will cause draw module to flush */
for (i = 0; i < sp->num_vertex_buffers; i++) {
draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
- pipe_buffer_unmap(pipe->screen, indexBuffer);
}
- /* Note: leave drawing surfaces mapped */
- softpipe_unmap_constant_buffers(sp);
+ /*
+ * TODO: Flush only when a user vertex/index buffer is present
+ * (or even better, modify draw module to do this
+ * internally when this condition is seen?)
+ */
+ draw_flush(draw);
+ /* Note: leave drawing surfaces mapped */
sp->dirty_render_cache = TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c
new file mode 100644
index 00000000000..66c52141132
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_fence.c
@@ -0,0 +1,70 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_screen.h"
+#include "util/u_debug.h"
+#include "sp_fence.h"
+
+
+static void
+softpipe_fence_reference(struct pipe_screen *screen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ assert(!*ptr);
+ assert(!fence);
+}
+
+
+static int
+softpipe_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
+{
+ assert(!fence);
+ return 0;
+}
+
+
+static int
+softpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
+{
+ assert(!fence);
+ return 0;
+}
+
+
+void
+softpipe_init_screen_fence_funcs(struct pipe_screen *screen)
+{
+ screen->fence_reference = softpipe_fence_reference;
+ screen->fence_finish = softpipe_fence_finish;
+ screen->fence_signalled = softpipe_fence_signalled;
+}
diff --git a/src/gallium/drivers/softpipe/sp_fence.h b/src/gallium/drivers/softpipe/sp_fence.h
new file mode 100644
index 00000000000..39c33243bd5
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_fence.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef SP_FENCE_H_
+#define SP_FENCE_H_
+
+
+struct pipe_screen;
+
+
+void
+softpipe_init_screen_fence_funcs(struct pipe_screen *screen);
+
+
+#endif /* SP_FENCE_H_ */
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index e8952bf4fb8..508fe8f764d 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -50,10 +50,10 @@ softpipe_flush( struct pipe_context *pipe,
draw_flush(softpipe->draw);
if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
- for (i = 0; i < softpipe->num_textures; i++) {
+ for (i = 0; i < softpipe->num_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->tex_cache[i]);
}
- for (i = 0; i < softpipe->num_vertex_textures; i++) {
+ for (i = 0; i < softpipe->num_vertex_sampler_views; i++) {
sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);
}
}
@@ -93,9 +93,9 @@ softpipe_flush( struct pipe_context *pipe,
static unsigned frame_no = 1;
static char filename[256];
util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no);
- debug_dump_surface_bmp(filename, softpipe->framebuffer.cbufs[0]);
+ debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.cbufs[0]);
util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no);
- debug_dump_surface_bmp(filename, softpipe->framebuffer.zsbuf);
+ debug_dump_surface_bmp(softpipe, filename, softpipe->framebuffer.zsbuf);
++frame_no;
}
#endif
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 27fa126b7c3..67e2c8f8bc4 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -145,8 +145,13 @@ exec_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index acee2136706..daa158df7c4 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -156,8 +156,13 @@ fs_sse_run( const struct sp_fragment_shader *base,
case TGSI_SEMANTIC_COLOR:
{
uint cbuf = sem_index[i];
+
+ assert(sizeof(quad->output.color[cbuf]) ==
+ sizeof(machine->Outputs[i]));
+
+ /* copy float[4][4] result */
memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
+ &machine->Outputs[i],
sizeof(quad->output.color[0]) );
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 98c08eaffaf..6749243ab41 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -264,57 +264,29 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-1], stride),
- get_vert(vertex_buffer, indices[i-3], stride));
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, indices[i-2], stride),
- get_vert(vertex_buffer, indices[i-0], stride),
- get_vert(vertex_buffer, indices[i-3], stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-0], stride) );
- }
}
break;
@@ -448,56 +420,28 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 4) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 4) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- if (softpipe->rasterizer->flatshade_first) {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-1, stride),
- get_vert(vertex_buffer, i-3, stride) );
- sp_setup_tri( setup_ctx,
- get_vert(vertex_buffer, i-2, stride),
- get_vert(vertex_buffer, i-0, stride),
- get_vert(vertex_buffer, i-3, stride) );
- }
- }
- else {
- for (i = 3; i < nr; i += 2) {
- sp_setup_tri( setup_ctx,
+ for (i = 3; i < nr; i += 2) {
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-0, stride) );
- sp_setup_tri( setup_ctx,
+ sp_setup_tri( setup_ctx,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-0, stride) );
- }
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_public.h b/src/gallium/drivers/softpipe/sp_public.h
new file mode 100644
index 00000000000..62d0903d87a
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_public.h
@@ -0,0 +1,10 @@
+#ifndef SP_PUBLIC_H
+#define SP_PUBLIC_H
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct pipe_screen *
+softpipe_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6ec63fe698a..757dc861284 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -27,15 +27,17 @@
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
-#include "util/u_simple_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
+#include "state_tracker/sw_winsys.h"
+
#include "sp_texture.h"
-#include "sp_winsys.h"
#include "sp_screen.h"
#include "sp_context.h"
+#include "sp_buffer.h"
+#include "sp_fence.h"
+#include "sp_public.h"
static const char *
@@ -83,11 +85,11 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 9; /* max 256x256x256 */
+ return SP_MAX_TEXTURE_3D_LEVELS;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 13; /* max 4Kx4K */
+ return SP_MAX_TEXTURE_2D_LEVELS;
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
@@ -145,6 +147,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
assert(target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
@@ -166,15 +170,27 @@ softpipe_is_format_supported( struct pipe_screen *screen,
case PIPE_FORMAT_NONE:
return FALSE;
default:
- return TRUE;
+ break;
}
+
+ if(tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
+ if(!winsys->is_displaytarget_format_supported(winsys, tex_usage, format))
+ return FALSE;
+ }
+
+ /* XXX: this is often a lie. Pull in logic from llvmpipe to fix.
+ */
+ return TRUE;
}
static void
softpipe_destroy_screen( struct pipe_screen *screen )
{
- struct pipe_winsys *winsys = screen->winsys;
+ struct softpipe_screen *sp_screen = softpipe_screen(screen);
+ struct sw_winsys *winsys = sp_screen->winsys;
if(winsys->destroy)
winsys->destroy(winsys);
@@ -183,21 +199,37 @@ softpipe_destroy_screen( struct pipe_screen *screen )
}
+/* This is often overriden by the co-state tracker.
+ */
+static void
+softpipe_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct softpipe_screen *screen = softpipe_screen(_screen);
+ struct sw_winsys *winsys = screen->winsys;
+ struct softpipe_texture *texture = softpipe_texture(surface->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ winsys->displaytarget_display(winsys, texture->dt, context_private);
+}
/**
* Create a new pipe_screen object
* Note: we're not presently subclassing pipe_screen (no softpipe_screen).
*/
struct pipe_screen *
-softpipe_create_screen(struct pipe_winsys *winsys)
+softpipe_create_screen(struct sw_winsys *winsys)
{
struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
if (!screen)
return NULL;
- screen->base.winsys = winsys;
+ screen->winsys = winsys;
+ screen->base.winsys = NULL;
screen->base.destroy = softpipe_destroy_screen;
screen->base.get_name = softpipe_get_name;
@@ -206,9 +238,11 @@ softpipe_create_screen(struct pipe_winsys *winsys)
screen->base.get_paramf = softpipe_get_paramf;
screen->base.is_format_supported = softpipe_is_format_supported;
screen->base.context_create = softpipe_create_context;
+ screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
softpipe_init_screen_texture_funcs(&screen->base);
- u_simple_screen_init(&screen->base);
+ softpipe_init_screen_buffer_funcs(&screen->base);
+ softpipe_init_screen_fence_funcs(&screen->base);
return &screen->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.h b/src/gallium/drivers/softpipe/sp_screen.h
index 3d4bfd3e840..f741454c9e5 100644
--- a/src/gallium/drivers/softpipe/sp_screen.h
+++ b/src/gallium/drivers/softpipe/sp_screen.h
@@ -35,10 +35,13 @@
#include "pipe/p_defines.h"
+struct sw_winsys;
struct softpipe_screen {
struct pipe_screen base;
+ struct sw_winsys *winsys;
+
/* Increments whenever textures are modified. Contexts can track
* this.
*/
@@ -55,4 +58,5 @@ softpipe_screen( struct pipe_screen *pipe )
}
+
#endif /* SP_SCREEN_H */
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 4370bbeaee2..ade96b0fd4c 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -100,6 +100,11 @@ struct sp_geometry_shader {
struct draw_geometry_shader *draw_data;
};
+struct sp_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
void *
softpipe_create_blend_state(struct pipe_context *,
@@ -160,28 +165,39 @@ void *softpipe_create_gs_state(struct pipe_context *,
void softpipe_bind_gs_state(struct pipe_context *, void *);
void softpipe_delete_gs_state(struct pipe_context *, void *);
+void *softpipe_create_vertex_elements_state(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+void softpipe_bind_vertex_elements_state(struct pipe_context *, void *);
+void softpipe_delete_vertex_elements_state(struct pipe_context *, void *);
+
void softpipe_set_polygon_stipple( struct pipe_context *,
- const struct pipe_poly_stipple * );
+ const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
-void softpipe_set_sampler_textures( struct pipe_context *,
- unsigned num,
- struct pipe_texture ** );
+void softpipe_set_sampler_views( struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view ** );
void
-softpipe_set_vertex_sampler_textures(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+softpipe_set_vertex_sampler_views(struct pipe_context *,
+ unsigned num,
+ struct pipe_sampler_view **);
+
+struct pipe_sampler_view *
+softpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ);
+
+void
+softpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
-void softpipe_set_vertex_elements(struct pipe_context *,
- unsigned count,
- const struct pipe_vertex_element *);
-
void softpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index c88e2137510..d6f3229bed7 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -28,6 +28,7 @@
#include "sp_context.h"
#include "sp_state.h"
#include "sp_fs.h"
+#include "sp_buffer.h"
#include "pipe/p_defines.h"
#include "util/u_memory.h"
@@ -163,26 +164,32 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( state );
}
-
-
void
softpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_buffer *constants)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ unsigned size = constants ? constants->size : 0;
+ const void *data = constants ? softpipe_buffer(constants)->data : NULL;
assert(shader < PIPE_SHADER_TYPES);
- assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+ assert(index == 0);
draw_flush(softpipe->draw);
/* note: reference counting */
- pipe_buffer_reference(&softpipe->constants[shader][index], buf);
+ pipe_buffer_reference(&softpipe->constants[shader][index], constants);
+ if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {
+ draw_set_mapped_constant_buffer(softpipe->draw, shader, index, data, size);
+ }
+
+ softpipe->mapped_constants[shader][index] = data;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
+
void *
softpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index ceb4e338f1a..d501952bba9 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -121,9 +121,38 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
}
+struct pipe_sampler_view *
+softpipe_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
void
-softpipe_set_sampler_textures(struct pipe_context *pipe,
- unsigned num, struct pipe_texture **texture)
+softpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+
+void
+softpipe_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
@@ -131,51 +160,51 @@ softpipe_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == softpipe->num_textures &&
- !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+ if (num == softpipe->num_sampler_views &&
+ !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *)))
return;
draw_flush(softpipe->draw);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num ? texture[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&softpipe->texture[i], tex);
- sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex);
+ pipe_sampler_view_reference(&softpipe->sampler_views[i], view);
+ sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view);
}
- softpipe->num_textures = num;
+ softpipe->num_sampler_views = num;
softpipe->dirty |= SP_NEW_TEXTURE;
}
void
-softpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+softpipe_set_vertex_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
- assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
+ assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
- if (num_textures == softpipe->num_vertex_textures &&
- !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
+ if (num == softpipe->num_vertex_sampler_views &&
+ !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
return;
}
draw_flush(softpipe->draw);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
- struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
+ struct pipe_sampler_view *view = i < num ? views[i] : NULL;
- pipe_texture_reference(&softpipe->vertex_textures[i], tex);
- sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex);
+ pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view);
+ sp_tex_tile_cache_set_sampler_view(softpipe->vertex_tex_cache[i], view);
}
- softpipe->num_vertex_textures = num_textures;
+ softpipe->num_vertex_sampler_views = num;
softpipe->dirty |= SP_NEW_TEXTURE;
}
@@ -245,29 +274,41 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
*/
for (i = 0; i <= softpipe->vs->max_sampler; i++) {
if (softpipe->vertex_samplers[i]) {
+ struct pipe_texture *texture = NULL;
+
+ if (softpipe->vertex_sampler_views[i]) {
+ texture = softpipe->vertex_sampler_views[i]->texture;
+ }
+
softpipe->tgsi.vert_samplers_list[i] =
get_sampler_varient( i,
- sp_sampler(softpipe->vertex_samplers[i]),
- softpipe->vertex_textures[i],
+ sp_sampler(softpipe->vertex_samplers[i]),
+ texture,
TGSI_PROCESSOR_VERTEX );
sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i],
- softpipe->vertex_tex_cache[i],
- softpipe->vertex_textures[i] );
+ softpipe->vertex_tex_cache[i],
+ texture );
}
}
for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {
if (softpipe->sampler[i]) {
+ struct pipe_texture *texture = NULL;
+
+ if (softpipe->sampler_views[i]) {
+ texture = softpipe->sampler_views[i]->texture;
+ }
+
softpipe->tgsi.frag_samplers_list[i] =
get_sampler_varient( i,
sp_sampler(softpipe->sampler[i]),
- softpipe->texture[i],
+ texture,
TGSI_PROCESSOR_FRAGMENT );
sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i],
softpipe->tex_cache[i],
- softpipe->texture[i] );
+ texture );
}
}
}
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index b491d92ed15..462f4d2655e 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -32,27 +32,45 @@
#include "sp_context.h"
#include "sp_state.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
+void *
+softpipe_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct sp_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct sp_velems_state *) MALLOC(sizeof(struct sp_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
+
void
-softpipe_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *attribs)
+softpipe_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
+ struct sp_velems_state *sp_velems = (struct sp_velems_state *) velems;
- assert(count <= PIPE_MAX_ATTRIBS);
-
- memcpy(softpipe->vertex_element, attribs,
- count * sizeof(struct pipe_vertex_element));
- softpipe->num_vertex_elements = count;
+ softpipe->velems = sp_velems;
softpipe->dirty |= SP_NEW_VERTEX;
- draw_set_vertex_elements(softpipe->draw, count, attribs);
+ if (sp_velems)
+ draw_set_vertex_elements(softpipe->draw, sp_velems->count, sp_velems->velem);
}
+void
+softpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
+{
+ FREE( velems );
+}
void
softpipe_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index ef7ccf41898..fa9e19b282b 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -1614,7 +1614,6 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
unsigned j;
float ssss[4], tttt[4];
- unsigned face;
/*
major axis
@@ -1628,7 +1627,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
*/
- /* First choose the cube face.
+ /* Choose the cube face and compute new s/t coords for the 2D face.
+ *
* Use the same cube face for all four pixels in the quad.
*
* This isn't ideal, but if we want to use a different cube face
@@ -1647,85 +1647,37 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
if (arx >= ary && arx >= arz) {
- if (rx >= 0.0F) {
- face = PIPE_TEX_FACE_POS_X;
- }
- else {
- face = PIPE_TEX_FACE_NEG_X;
+ float sign = (rx >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5F / fabsf(s[j]);
+ ssss[j] = sign * p[j] * ima + 0.5F;
+ tttt[j] = t[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
else if (ary >= arx && ary >= arz) {
- if (ry >= 0.0F) {
- face = PIPE_TEX_FACE_POS_Y;
- }
- else {
- face = PIPE_TEX_FACE_NEG_Y;
+ float sign = (ry >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5F / fabsf(t[j]);
+ ssss[j] = -s[j] * ima + 0.5F;
+ tttt[j] = sign * -p[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
else {
- if (rz > 0.0F) {
- face = PIPE_TEX_FACE_POS_Z;
- }
- else {
- face = PIPE_TEX_FACE_NEG_Z;
+ float sign = (rz >= 0.0F) ? 1.0F : -1.0F;
+ uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float ima = -0.5 / fabsf(p[j]);
+ ssss[j] = sign * -s[j] * ima + 0.5F;
+ tttt[j] = t[j] * ima + 0.5F;
+ samp->faces[j] = face;
}
}
}
- /* Now compute the 2D _face_ texture coords from the
- * 3D _cube_ texture coords.
- */
- for (j = 0; j < QUAD_SIZE; j++) {
- const float rx = s[j], ry = t[j], rz = p[j];
- const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
- float sc, tc, ma;
-
- switch (face) {
- case PIPE_TEX_FACE_POS_X:
- sc = -rz;
- tc = -ry;
- ma = arx;
- break;
- case PIPE_TEX_FACE_NEG_X:
- sc = rz;
- tc = -ry;
- ma = arx;
- break;
- case PIPE_TEX_FACE_POS_Y:
- sc = rx;
- tc = rz;
- ma = ary;
- break;
- case PIPE_TEX_FACE_NEG_Y:
- sc = rx;
- tc = -rz;
- ma = ary;
- break;
- case PIPE_TEX_FACE_POS_Z:
- sc = rx;
- tc = -ry;
- ma = arz;
- break;
- case PIPE_TEX_FACE_NEG_Z:
- sc = -rx;
- tc = -ry;
- ma = arz;
- break;
- default:
- assert(0 && "bad cube face");
- sc = 0.0F;
- tc = 0.0F;
- ma = 0.0F;
- }
-
- {
- const float ima = 1.0 / ma;
- ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
- tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
- samp->faces[j] = face;
- }
- }
-
/* In our little pipeline, the compare stage is next. If compare
* is not active, this will point somewhere deeper into the
* pipeline, eg. to mip_filter or even img_filter.
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index a0b95c88846..6594514c38f 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -43,14 +43,14 @@
struct softpipe_tex_tile_cache *
-sp_create_tex_tile_cache( struct pipe_screen *screen )
+sp_create_tex_tile_cache( struct pipe_context *pipe )
{
struct softpipe_tex_tile_cache *tc;
uint pos;
tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
if (tc) {
- tc->screen = screen;
+ tc->pipe = pipe;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
tc->entries[pos].addr.bits.invalid = 1;
}
@@ -63,19 +63,16 @@ sp_create_tex_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
{
- struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
if (tc->transfer) {
- screen = tc->transfer->texture->screen;
- screen->tex_transfer_destroy(tc->transfer);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer);
}
if (tc->tex_trans) {
- screen = tc->tex_trans->texture->screen;
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
}
FREE( tc );
@@ -88,7 +85,7 @@ void
sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc)
{
if (tc->tex_trans && !tc->tex_trans_map)
- tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
}
@@ -96,7 +93,7 @@ void
sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc)
{
if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
}
@@ -119,12 +116,13 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)
}
/**
- * Specify the texture to cache.
+ * Specify the sampler view to cache.
*/
void
-sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
- struct pipe_texture *texture)
+sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
+ struct pipe_sampler_view *view)
{
+ struct pipe_texture *texture = view ? view->texture : NULL;
uint i;
assert(!tc->transfer);
@@ -133,17 +131,23 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
pipe_texture_reference(&tc->texture, texture);
if (tc->tex_trans) {
- struct pipe_screen *screen = tc->tex_trans->texture->screen;
-
if (tc->tex_trans_map) {
- screen->transfer_unmap(screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
tc->tex_trans = NULL;
}
+ if (view) {
+ tc->swizzle_r = view->swizzle_r;
+ tc->swizzle_g = view->swizzle_g;
+ tc->swizzle_b = view->swizzle_b;
+ tc->swizzle_a = view->swizzle_a;
+ tc->format = view->format;
+ }
+
/* mark as entries as invalid/empty */
/* XXX we should try to avoid this when the teximage hasn't changed */
for (i = 0; i < NUM_ENTRIES; i++) {
@@ -204,7 +208,6 @@ const struct softpipe_tex_cached_tile *
sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
union tex_tile_address addr )
{
- struct pipe_screen *screen = tc->screen;
struct softpipe_tex_cached_tile *tile;
tile = tc->entries + tex_cache_pos( addr );
@@ -232,16 +235,16 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
if (tc->tex_trans) {
if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->pipe->transfer_unmap(tc->pipe, tc->tex_trans);
tc->tex_trans_map = NULL;
}
- screen->tex_transfer_destroy(tc->tex_trans);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->tex_trans);
tc->tex_trans = NULL;
}
tc->tex_trans =
- screen->get_tex_transfer(screen, tc->texture,
+ tc->pipe->get_tex_transfer(tc->pipe, tc->texture,
addr.bits.face,
addr.bits.level,
addr.bits.z,
@@ -249,7 +252,7 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
u_minify(tc->texture->width0, addr.bits.level),
u_minify(tc->texture->height0, addr.bits.level));
- tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
+ tc->tex_trans_map = tc->pipe->transfer_map(tc->pipe, tc->tex_trans);
tc->tex_face = addr.bits.face;
tc->tex_level = addr.bits.level;
@@ -257,11 +260,18 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
}
/* get tile from the transfer (view into texture) */
- pipe_get_tile_rgba(tc->tex_trans,
- addr.bits.x * TILE_SIZE,
- addr.bits.y * TILE_SIZE,
- TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
+ pipe_get_tile_swizzle(tc->pipe,
+ tc->tex_trans,
+ addr.bits.x * TILE_SIZE,
+ addr.bits.y * TILE_SIZE,
+ TILE_SIZE,
+ TILE_SIZE,
+ tc->swizzle_r,
+ tc->swizzle_g,
+ tc->swizzle_b,
+ tc->swizzle_a,
+ tc->format,
+ (float *) tile->data.color);
tile->addr = addr;
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
index ac6886a3df1..12ae7ba12d6 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -70,7 +70,7 @@ struct softpipe_tex_cached_tile
struct softpipe_tex_tile_cache
{
- struct pipe_screen *screen;
+ struct pipe_context *pipe;
struct pipe_transfer *transfer;
void *transfer_map;
@@ -83,12 +83,18 @@ struct softpipe_tex_tile_cache
void *tex_trans_map;
int tex_face, tex_level, tex_z;
+ unsigned swizzle_r;
+ unsigned swizzle_g;
+ unsigned swizzle_b;
+ unsigned swizzle_a;
+ unsigned format;
+
struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */
};
extern struct softpipe_tex_tile_cache *
-sp_create_tex_tile_cache( struct pipe_screen *screen );
+sp_create_tex_tile_cache( struct pipe_context *pipe );
extern void
sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc);
@@ -101,8 +107,8 @@ extern void
sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc);
extern void
-sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
- struct pipe_texture *texture);
+sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc,
+ struct pipe_sampler_view *view);
void
sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc);
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 32d261b5ffc..f4983b7c8e8 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -40,7 +40,8 @@
#include "sp_context.h"
#include "sp_texture.h"
#include "sp_screen.h"
-#include "sp_winsys.h"
+
+#include "state_tracker/sw_winsys.h"
/**
@@ -72,11 +73,9 @@ softpipe_texture_layout(struct pipe_screen *screen,
depth = u_minify(depth, 1);
}
- spt->buffer = screen->buffer_create(screen, 32,
- PIPE_BUFFER_USAGE_PIXEL,
- buffer_size);
+ spt->data = align_malloc(buffer_size, 16);
- return spt->buffer != NULL;
+ return spt->data != NULL;
}
@@ -87,19 +86,19 @@ static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
{
- unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ_WRITE);
- unsigned tex_usage = spt->base.tex_usage;
-
- spt->buffer = screen->surface_buffer_create( screen,
- spt->base.width0,
- spt->base.height0,
- spt->base.format,
- usage,
- tex_usage,
- &spt->stride[0]);
-
- return spt->buffer != NULL;
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+
+ /* Round up the surface size to a multiple of the tile size?
+ */
+ spt->dt = winsys->displaytarget_create(winsys,
+ spt->base.tex_usage,
+ spt->base.format,
+ spt->base.width0,
+ spt->base.height0,
+ 16,
+ &spt->stride[0] );
+
+ return spt->dt != NULL;
}
@@ -123,7 +122,8 @@ softpipe_texture_create(struct pipe_screen *screen,
util_is_power_of_two(template->depth0));
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
- PIPE_TEXTURE_USAGE_PRIMARY)) {
+ PIPE_TEXTURE_USAGE_SCANOUT |
+ PIPE_TEXTURE_USAGE_SHARED)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@@ -140,47 +140,72 @@ softpipe_texture_create(struct pipe_screen *screen,
}
-/**
- * Create a new pipe_texture which wraps an existing buffer.
- */
-static struct pipe_texture *
-softpipe_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static void
+softpipe_texture_destroy(struct pipe_texture *pt)
{
- struct softpipe_texture *spt;
- assert(screen);
+ struct softpipe_screen *screen = softpipe_screen(pt->screen);
+ struct softpipe_texture *spt = softpipe_texture(pt);
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = screen->winsys;
+ winsys->displaytarget_destroy(winsys, spt->dt);
+ }
+ else {
+ /* regular texture */
+ align_free(spt->data);
}
- spt = CALLOC_STRUCT(softpipe_texture);
+ FREE(spt);
+}
+
+
+static struct pipe_texture *
+softpipe_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *template,
+ struct winsys_handle *whandle)
+{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
+ struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
- spt->base = *base;
+ spt->base = *template;
pipe_reference_init(&spt->base.reference, 1);
spt->base.screen = screen;
- spt->stride[0] = stride[0];
- pipe_buffer_reference(&spt->buffer, buffer);
+ spt->pot = (util_is_power_of_two(template->width0) &&
+ util_is_power_of_two(template->height0) &&
+ util_is_power_of_two(template->depth0));
+
+ spt->dt = winsys->displaytarget_from_handle(winsys,
+ template,
+ whandle,
+ &spt->stride[0]);
+ if (!spt->dt)
+ goto fail;
return &spt->base;
+
+ fail:
+ FREE(spt);
+ return NULL;
}
-static void
-softpipe_texture_destroy(struct pipe_texture *pt)
+static boolean
+softpipe_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ struct winsys_handle *whandle)
{
+ struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
- pipe_buffer_reference(&spt->buffer, NULL);
- FREE(spt);
+ assert(spt->dt);
+ if (!spt->dt)
+ return FALSE;
+
+ return winsys->displaytarget_get_handle(winsys, spt->dt, whandle);
}
@@ -278,7 +303,7 @@ softpipe_tex_surface_destroy(struct pipe_surface *surf)
* \param height height of region to read/write
*/
static struct pipe_transfer *
-softpipe_get_tex_transfer(struct pipe_screen *screen,
+softpipe_get_tex_transfer(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
@@ -332,7 +357,8 @@ softpipe_get_tex_transfer(struct pipe_screen *screen,
* softpipe_get_tex_transfer().
*/
static void
-softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
+softpipe_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
/* Effectively do the texture_update work here - if texture images
* needed post-processing to put them into hardware layout, this is
@@ -348,7 +374,7 @@ softpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
* Create memory mapping for given pipe_transfer object.
*/
static void *
-softpipe_transfer_map( struct pipe_screen *screen,
+softpipe_transfer_map( struct pipe_context *pipe,
struct pipe_transfer *transfer )
{
ubyte *map, *xfer_map;
@@ -359,9 +385,20 @@ softpipe_transfer_map( struct pipe_screen *screen,
spt = softpipe_texture(transfer->texture);
format = transfer->texture->format;
- map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
- if (map == NULL)
- return NULL;
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
+
+ map = winsys->displaytarget_map(winsys, spt->dt,
+ pipe_transfer_buffer_flags(transfer));
+ if (map == NULL)
+ return NULL;
+ }
+ else {
+ map = spt->data;
+ if (map == NULL)
+ return NULL;
+ }
/* May want to different things here depending on read/write nature
* of the map:
@@ -370,7 +407,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
*/
- softpipe_screen(screen)->timestamp++;
+ softpipe_screen(pipe->screen)->timestamp++;
}
xfer_map = map + softpipe_transfer(transfer)->offset +
@@ -385,7 +422,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
* Unmap memory mapping for given pipe_transfer object.
*/
static void
-softpipe_transfer_unmap(struct pipe_screen *screen,
+softpipe_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct softpipe_texture *spt;
@@ -393,7 +430,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
assert(transfer->texture);
spt = softpipe_texture(transfer->texture);
- pipe_buffer_unmap( screen, spt->buffer );
+ if (spt->dt) {
+ /* display target */
+ struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
+ winsys->displaytarget_unmap(winsys, spt->dt);
+ }
if (transfer->usage & PIPE_TRANSFER_WRITE) {
/* Mark the texture as dirty to expire the tile caches. */
@@ -455,43 +496,28 @@ softpipe_video_surface_destroy(struct pipe_video_surface *vsfc)
void
+softpipe_init_texture_funcs(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = softpipe_get_tex_transfer;
+ pipe->tex_transfer_destroy = softpipe_tex_transfer_destroy;
+ pipe->transfer_map = softpipe_transfer_map;
+ pipe->transfer_unmap = softpipe_transfer_unmap;
+}
+
+void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
- screen->texture_blanket = softpipe_texture_blanket;
screen->texture_destroy = softpipe_texture_destroy;
+ screen->texture_from_handle = softpipe_texture_from_handle;
+ screen->texture_get_handle = softpipe_texture_get_handle;
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_destroy = softpipe_tex_surface_destroy;
- screen->get_tex_transfer = softpipe_get_tex_transfer;
- screen->tex_transfer_destroy = softpipe_tex_transfer_destroy;
- screen->transfer_map = softpipe_transfer_map;
- screen->transfer_unmap = softpipe_transfer_unmap;
-
screen->video_surface_create = softpipe_video_surface_create;
screen->video_surface_destroy = softpipe_video_surface_destroy;
}
-/**
- * Return pipe_buffer handle and stride for given texture object.
- * XXX used for???
- */
-boolean
-softpipe_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride )
-{
- struct softpipe_texture *tex = (struct softpipe_texture *) texture;
-
- if (!tex)
- return FALSE;
- pipe_buffer_reference(buf, tex->buffer);
-
- if (stride)
- *stride = tex->stride[0];
-
- return TRUE;
-}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 2ef64e1e7c3..c0e6ba8a869 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -33,6 +33,10 @@
#include "pipe/p_video_state.h"
+#define SP_MAX_TEXTURE_2D_LEVELS 13 /* 4K x 4K */
+#define SP_MAX_TEXTURE_3D_LEVELS 9 /* 512 x 512 x 512 */
+
+
struct pipe_context;
struct pipe_screen;
struct softpipe_context;
@@ -42,12 +46,19 @@ struct softpipe_texture
{
struct pipe_texture base;
- unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long level_offset[SP_MAX_TEXTURE_2D_LEVELS];
+ unsigned stride[SP_MAX_TEXTURE_2D_LEVELS];
- /* The data is held here:
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
*/
- struct pipe_buffer *buffer;
+ struct sw_displaytarget *dt;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
/* True if texture images are power-of-two in all dimensions:
*/
@@ -96,5 +107,8 @@ softpipe_video_surface(struct pipe_video_surface *pvs)
extern void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
+void
+softpipe_init_texture_funcs(struct pipe_context *pipe);
+
#endif /* SP_TEXTURE */
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index aedfdf1b469..1c3c2667d73 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -79,20 +79,20 @@ clear_clear_flag(uint *bitvec, union tile_address addr)
struct softpipe_tile_cache *
-sp_create_tile_cache( struct pipe_screen *screen )
+sp_create_tile_cache( struct pipe_context *pipe )
{
struct softpipe_tile_cache *tc;
uint pos;
int maxLevels, maxTexSize;
/* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
- maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ maxLevels = pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
maxTexSize = 1 << (maxLevels - 1);
assert(MAX_WIDTH >= maxTexSize);
tc = CALLOC_STRUCT( softpipe_tile_cache );
if (tc) {
- tc->screen = screen;
+ tc->pipe = pipe;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
tc->entries[pos].addr.bits.invalid = 1;
}
@@ -115,15 +115,13 @@ sp_create_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
- struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
if (tc->transfer) {
- screen = tc->transfer->texture->screen;
- screen->tex_transfer_destroy(tc->transfer);
+ tc->pipe->tex_transfer_destroy(tc->pipe, tc->transfer);
}
FREE( tc );
@@ -137,27 +135,25 @@ void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct pipe_surface *ps)
{
- if (tc->transfer) {
- struct pipe_screen *screen = tc->transfer->texture->screen;
+ struct pipe_context *pipe = tc->pipe;
+ if (tc->transfer) {
if (ps == tc->surface)
return;
if (tc->transfer_map) {
- screen->transfer_unmap(screen, tc->transfer);
+ pipe->transfer_unmap(pipe, tc->transfer);
tc->transfer_map = NULL;
}
- screen->tex_transfer_destroy(tc->transfer);
+ pipe->tex_transfer_destroy(pipe, tc->transfer);
tc->transfer = NULL;
}
tc->surface = ps;
if (ps) {
- struct pipe_screen *screen = ps->texture->screen;
-
- tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
+ tc->transfer = pipe->get_tex_transfer(pipe, ps->texture, ps->face,
ps->level, ps->zslice,
PIPE_TRANSFER_READ_WRITE,
0, 0, ps->width, ps->height);
@@ -187,7 +183,7 @@ void
sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
{
if (tc->transfer && !tc->transfer_map)
- tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
+ tc->transfer_map = tc->pipe->transfer_map(tc->pipe, tc->transfer);
}
@@ -195,7 +191,7 @@ void
sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
{
if (tc->transfer_map) {
- tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->pipe->transfer_unmap(tc->pipe, tc->transfer);
tc->transfer_map = NULL;
}
}
@@ -295,7 +291,8 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
union tile_address addr = tile_address(x, y);
if (is_clear_flag_set(tc->clear_flags, addr)) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe,
+ pt,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
@@ -329,14 +326,14 @@ sp_flush_tile_cache(struct softpipe_tile_cache *tc)
struct softpipe_cached_tile *tile = tc->entries + pos;
if (!tile->addr.bits.invalid) {
if (tc->depth_stencil) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(pt,
+ pipe_put_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
@@ -379,14 +376,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
if (tile->addr.bits.invalid == 0) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
- pipe_put_tile_raw(pt,
+ pipe_put_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_put_tile_rgba(pt,
+ pipe_put_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
@@ -409,14 +406,14 @@ sp_find_cached_tile(struct softpipe_tile_cache *tc,
else {
/* get new tile data from transfer */
if (tc->depth_stencil) {
- pipe_get_tile_raw(pt,
+ pipe_get_tile_raw(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
- pipe_get_tile_rgba(pt,
+ pipe_get_tile_rgba(tc->pipe, pt,
tile->addr.bits.x * TILE_SIZE,
tile->addr.bits.y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index a12092702a6..753d8c0daac 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -80,7 +80,7 @@ struct softpipe_cached_tile
struct softpipe_tile_cache
{
- struct pipe_screen *screen;
+ struct pipe_context *pipe;
struct pipe_surface *surface; /**< the surface we're caching */
struct pipe_transfer *transfer;
void *transfer_map;
@@ -98,7 +98,7 @@ struct softpipe_tile_cache
extern struct softpipe_tile_cache *
-sp_create_tile_cache( struct pipe_screen *screen );
+sp_create_tile_cache( struct pipe_context *pipe );
extern void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc);
diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c
deleted file mode 100644
index 0a6245ed2cd..00000000000
--- a/src/gallium/drivers/softpipe/sp_winsys.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Malloc softpipe winsys. Uses malloc for all memory allocations.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include "util/u_simple_screen.h"/* port to just p_screen */
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "sp_winsys.h"
-
-
-struct st_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct st_softpipe_buffer *
-st_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct st_softpipe_buffer *)buf;
-}
-
-
-static void *
-st_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = st_softpipe_buf->data;
- return st_softpipe_buf->mapped;
-}
-
-
-static void
-st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-st_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static void
-st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surf,
- void *context_private)
-{
-}
-
-
-
-static const char *
-st_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-st_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct st_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(st_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-st_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-st_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-st_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-st_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-struct pipe_screen *
-softpipe_create_screen_malloc(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = st_softpipe_destroy;
-
- winsys->buffer_create = st_softpipe_buffer_create;
- winsys->user_buffer_create = st_softpipe_user_buffer_create;
- winsys->buffer_map = st_softpipe_buffer_map;
- winsys->buffer_unmap = st_softpipe_buffer_unmap;
- winsys->buffer_destroy = st_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
-
- winsys->fence_reference = st_softpipe_fence_reference;
- winsys->fence_signalled = st_softpipe_fence_signalled;
- winsys->fence_finish = st_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
- winsys->get_name = st_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- st_softpipe_destroy(winsys);
-
- return screen;
-}
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index d499ae6acc9..adb7840182b 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -164,6 +164,8 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
svga_init_constbuffer_functions(svga);
svga_init_query_functions(svga);
+ svga_init_texture_functions(&svga->pipe);
+
/* debug */
svga->debug.no_swtnl = debug_get_bool_option("SVGA_NO_SWTNL", FALSE);
svga->debug.force_swtnl = debug_get_bool_option("SVGA_FORCE_SWTNL", FALSE);
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 03302e2a6ec..1f66437dfe1 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -169,6 +169,11 @@ struct svga_sampler_state {
unsigned view_max_lod;
};
+struct svga_velems_state {
+ unsigned count;
+ struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
+};
+
/* Use to calculate differences between state emitted to hardware and
* current driver-calculated state.
*/
@@ -178,13 +183,13 @@ struct svga_state
const struct svga_depth_stencil_state *depth;
const struct svga_rasterizer_state *rast;
const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+ const struct svga_velems_state *velems;
- struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; /* or texture ID's? */
struct svga_fragment_shader *fs;
struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
- struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
struct pipe_buffer *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
@@ -203,8 +208,7 @@ struct svga_state
struct pipe_viewport_state viewport;
unsigned num_samplers;
- unsigned num_textures;
- unsigned num_vertex_elements;
+ unsigned num_sampler_views;
unsigned num_vertex_buffers;
unsigned reduced_prim;
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index acba2b8f9da..82d525ca33f 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -155,7 +155,7 @@ static void svga_bind_sampler_states(struct pipe_context *pipe,
/* Check for no-op */
if (num == svga->curr.num_samplers &&
!memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
- debug_printf("sampler noop\n");
+ if (0) debug_printf("sampler noop\n");
return;
}
@@ -176,9 +176,36 @@ static void svga_delete_sampler_state(struct pipe_context *pipe,
}
-static void svga_set_sampler_textures(struct pipe_context *pipe,
- unsigned num,
- struct pipe_texture **texture)
+static struct pipe_sampler_view *
+svga_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+svga_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
+static void svga_set_sampler_views(struct pipe_context *pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct svga_context *svga = svga_context(pipe);
unsigned flag_1d = 0;
@@ -188,31 +215,31 @@ static void svga_set_sampler_textures(struct pipe_context *pipe,
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
- if (num == svga->curr.num_textures &&
- !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) {
+ if (num == svga->curr.num_sampler_views &&
+ !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
if (0) debug_printf("texture noop\n");
return;
}
for (i = 0; i < num; i++) {
- pipe_texture_reference(&svga->curr.texture[i],
- texture[i]);
+ pipe_sampler_view_reference(&svga->curr.sampler_views[i],
+ views[i]);
- if (!texture[i])
+ if (!views[i])
continue;
- if (texture[i]->format == PIPE_FORMAT_B8G8R8A8_SRGB)
+ if (views[i]->texture->format == PIPE_FORMAT_B8G8R8A8_SRGB)
flag_srgb |= 1 << i;
- if (texture[i]->target == PIPE_TEXTURE_1D)
+ if (views[i]->texture->target == PIPE_TEXTURE_1D)
flag_1d |= 1 << i;
}
- for (i = num; i < svga->curr.num_textures; i++)
- pipe_texture_reference(&svga->curr.texture[i],
- NULL);
+ for (i = num; i < svga->curr.num_sampler_views; i++)
+ pipe_sampler_view_reference(&svga->curr.sampler_views[i],
+ NULL);
- svga->curr.num_textures = num;
+ svga->curr.num_sampler_views = num;
svga->dirty |= SVGA_NEW_TEXTURE_BINDING;
if (flag_srgb != svga->curr.tex_flags.flag_srgb ||
@@ -231,7 +258,9 @@ void svga_init_sampler_functions( struct svga_context *svga )
svga->pipe.create_sampler_state = svga_create_sampler_state;
svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states;
svga->pipe.delete_sampler_state = svga_delete_sampler_state;
- svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures;
+ svga->pipe.set_fragment_sampler_views = svga_set_sampler_views;
+ svga->pipe.create_sampler_view = svga_create_sampler_view;
+ svga->pipe.sampler_view_destroy = svga_sampler_view_destroy;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 836b8441da2..1715a47fc62 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -26,6 +26,7 @@
#include "util/u_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
+#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
#include "svga_screen.h"
@@ -64,20 +65,37 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
svga->dirty |= SVGA_NEW_VBUFFER;
}
-static void svga_set_vertex_elements(struct pipe_context *pipe,
- unsigned count,
- const struct pipe_vertex_element *elements)
+
+static void *
+svga_create_vertex_elements_state(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
{
- struct svga_context *svga = svga_context(pipe);
- unsigned i;
+ struct svga_velems_state *velems;
+ assert(count <= PIPE_MAX_ATTRIBS);
+ velems = (struct svga_velems_state *) MALLOC(sizeof(struct svga_velems_state));
+ if (velems) {
+ velems->count = count;
+ memcpy(velems->velem, attribs, sizeof(*attribs) * count);
+ }
+ return velems;
+}
- for (i = 0; i < count; i++)
- svga->curr.ve[i] = elements[i];
+static void svga_bind_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ struct svga_context *svga = svga_context(pipe);
+ struct svga_velems_state *svga_velems = (struct svga_velems_state *) velems;
- svga->curr.num_vertex_elements = count;
+ svga->curr.velems = svga_velems;
svga->dirty |= SVGA_NEW_VELEMENT;
}
+static void svga_delete_vertex_elements_state(struct pipe_context *pipe,
+ void *velems)
+{
+ FREE(velems);
+}
void svga_cleanup_vertex_state( struct svga_context *svga )
{
@@ -91,7 +109,9 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
void svga_init_vertex_functions( struct svga_context *svga )
{
svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
- svga->pipe.set_vertex_elements = svga_set_vertex_elements;
+ svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
+ svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
+ svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index e9792e063e0..70d3a8a46ae 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -41,8 +41,6 @@
#include "svga_debug.h"
#include "svga_screen_buffer.h"
-#include <util/u_string.h>
-
/* XXX: This isn't a real hardware flag, but just a hack for kernel to
* know about primary surfaces. Find a better way to accomplish this.
@@ -315,7 +313,11 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.cachable = 0;
}
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
+ tex->key.cachable = 0;
+ }
+
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
tex->key.cachable = 0;
}
@@ -328,7 +330,7 @@ svga_texture_create(struct pipe_screen *screen,
*/
#if 0
if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
- !util_format_is_compressed(templat->format))
+ !util_format_is_s3tc(templat->format))
tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
#endif
@@ -355,80 +357,18 @@ error1:
}
-static struct pipe_texture *
-svga_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
-{
- struct svga_texture *tex;
- struct svga_buffer *sbuf = svga_buffer(buffer);
- struct svga_winsys_screen *sws = svga_winsys_screen(screen);
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- /**
- * We currently can't do texture blanket on
- * SVGA3D_BUFFER. Need to blit to a temporary surface?
- */
-
- assert(sbuf->handle);
- if (!sbuf->handle)
- return NULL;
-
- if (svga_translate_format(base->format) != sbuf->key.format) {
- unsigned f1 = svga_translate_format(base->format);
- unsigned f2 = sbuf->key.format;
-
- /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
- if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
- (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
- (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
- debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
- return NULL;
- }
- }
-
- tex = CALLOC_STRUCT(svga_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
-
-
- if (sbuf->key.format == 1)
- tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM;
- else if (sbuf->key.format == 2)
- tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
- /* We don't own this storage, so don't try to cache it.
- */
- assert(sbuf->key.cachable == 0);
- tex->key.cachable = 0;
- sws->surface_reference(sws, &tex->handle, sbuf->handle);
- return &tex->base;
-}
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf)
+static struct pipe_texture *
+svga_screen_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_texture *base,
+ struct winsys_handle *whandle)
{
+ struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+ struct svga_winsys_surface *srf;
struct svga_texture *tex;
+ enum SVGA3dSurfaceFormat format = 0;
assert(screen);
/* Only supports one type */
@@ -438,6 +378,8 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
return NULL;
}
+ srf = sws->surface_from_handle(sws, whandle, &format);
+
if (!srf)
return NULL;
@@ -478,6 +420,22 @@ svga_screen_texture_wrap_surface(struct pipe_screen *screen,
}
+static boolean
+svga_screen_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ struct winsys_handle *whandle)
+{
+ struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
+ unsigned stride;
+
+ assert(svga_texture(texture)->key.cachable == 0);
+ svga_texture(texture)->key.cachable = 0;
+ stride = util_format_get_nblocksx(texture->format, texture->width0) *
+ util_format_get_blocksize(texture->format);
+ return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
+}
+
+
static void
svga_texture_destroy(struct pipe_texture *pt)
{
@@ -823,15 +781,17 @@ svga_surface_needs_propagation(struct pipe_surface *surf)
return s->dirty && s->handle != tex->handle;
}
-
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static struct pipe_transfer *
-svga_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
+svga_get_tex_transfer(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
{
- struct svga_screen *ss = svga_screen(screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st;
unsigned nblocksx = util_format_get_nblocksx(texture->format, w);
@@ -899,11 +859,14 @@ no_hwbuf:
}
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static void *
-svga_transfer_map( struct pipe_screen *screen,
+svga_transfer_map( 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_transfer *st = svga_transfer(transfer);
@@ -917,11 +880,14 @@ svga_transfer_map( struct pipe_screen *screen,
}
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
static void
-svga_transfer_unmap(struct pipe_screen *screen,
+svga_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_transfer *st = svga_transfer(transfer);
@@ -931,10 +897,11 @@ svga_transfer_unmap(struct pipe_screen *screen,
static void
-svga_tex_transfer_destroy(struct pipe_transfer *transfer)
+svga_tex_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
{
struct svga_texture *tex = svga_texture(transfer->texture);
- struct svga_screen *ss = svga_screen(transfer->texture->screen);
+ struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_winsys_screen *sws = ss->sws;
struct svga_transfer *st = svga_transfer(transfer);
@@ -951,18 +918,26 @@ svga_tex_transfer_destroy(struct pipe_transfer *transfer)
FREE(st);
}
+
+void
+svga_init_texture_functions(struct pipe_context *pipe)
+{
+ pipe->get_tex_transfer = svga_get_tex_transfer;
+ pipe->transfer_map = svga_transfer_map;
+ pipe->transfer_unmap = svga_transfer_unmap;
+ pipe->tex_transfer_destroy = svga_tex_transfer_destroy;
+}
+
+
void
svga_screen_init_texture_functions(struct pipe_screen *screen)
{
screen->texture_create = svga_texture_create;
+ screen->texture_from_handle = svga_screen_texture_from_handle;
+ screen->texture_get_handle = svga_screen_texture_get_handle;
screen->texture_destroy = svga_texture_destroy;
screen->get_tex_surface = svga_get_tex_surface;
screen->tex_surface_destroy = svga_tex_surface_destroy;
- screen->texture_blanket = svga_texture_blanket;
- screen->get_tex_transfer = svga_get_tex_transfer;
- screen->transfer_map = svga_transfer_map;
- screen->transfer_unmap = svga_transfer_unmap;
- screen->tex_transfer_destroy = svga_tex_transfer_destroy;
}
/***********************************************************************
@@ -994,7 +969,7 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
if (min_lod == 0 && max_lod >= pt->last_level)
view = FALSE;
- if (util_format_is_compressed(pt->format) && view) {
+ if (util_format_is_s3tc(pt->format) && view) {
format = svga_translate_format_render(pt->format);
}
@@ -1120,33 +1095,3 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
pipe_texture_reference(&v->texture, NULL);
FREE(v);
}
-
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride)
-{
- struct svga_texture *stex = svga_texture(texture);
-
- *buffer = svga_screen_buffer_wrap_surface
- (texture->screen,
- svga_translate_format(texture->format),
- stex->handle);
-
- *stride = util_format_get_stride(texture->format, texture->width0);
-
- return *buffer != NULL;
-}
-
-
-struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
- struct svga_winsys_surface *vsurf = NULL;
-
- assert(svga_texture(texture)->key.cachable == 0);
- svga_texture(texture)->key.cachable = 0;
- sws->surface_reference(sws, &vsurf, svga_texture(texture)->handle);
- return vsurf;
-}
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h
index 24c1f78ca55..96d035b12d8 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_screen_texture.h
@@ -78,7 +78,7 @@ struct svga_texture
{
struct pipe_texture base;
- boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
+ boolean defined[6][SVGA_MAX_TEXTURE_LEVELS];
struct svga_sampler_view *cached_view;
@@ -186,6 +186,9 @@ svga_surface_needs_propagation(struct pipe_surface *surf);
extern void
svga_screen_init_texture_functions(struct pipe_screen *screen);
+void
+svga_init_texture_functions(struct pipe_context *pipe);
+
enum SVGA3dSurfaceFormat
svga_translate_format(enum pipe_format format);
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index bb92f818eae..493f78a9908 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -137,7 +137,7 @@ static int emit_fs_consts( struct svga_context *svga,
for (i = 0; i < key->num_textures; i++) {
if (key->tex[i].unnormalized) {
- struct pipe_texture *tex = svga->curr.texture[i];
+ struct pipe_texture *tex = svga->curr.sampler_views[i]->texture;
float data[4];
data[0] = 1.0 / (float)tex->width0;
diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index 2973444d0ab..1310fd9825f 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -158,10 +158,11 @@ static int make_fs_key( const struct svga_context *svga,
*
* SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER
*/
- for (i = 0; i < svga->curr.num_textures; i++) {
- if (svga->curr.texture[i]) {
+ for (i = 0; i < svga->curr.num_sampler_views; i++) {
+ if (svga->curr.sampler_views[i]) {
assert(svga->curr.sampler[i]);
- key->tex[i].texture_target = svga->curr.texture[i]->target;
+ assert(svga->curr.sampler_views[i]->texture);
+ key->tex[i].texture_target = svga->curr.sampler_views[i]->texture->target;
if (!svga->curr.sampler[i]->normalized_coords) {
key->tex[i].width_height_idx = idx++;
key->tex[i].unnormalized = TRUE;
@@ -169,7 +170,7 @@ static int make_fs_key( const struct svga_context *svga,
}
}
}
- key->num_textures = svga->curr.num_textures;
+ key->num_textures = svga->curr.num_sampler_views;
idx = 0;
for (i = 0; i < svga->curr.num_samplers; ++i) {
diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c
index d774e3e504d..dfaab53aef4 100644
--- a/src/gallium/drivers/svga/svga_state_need_swtnl.c
+++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c
@@ -76,8 +76,13 @@ static int update_need_swvfetch( struct svga_context *svga,
unsigned i;
boolean need_swvfetch = FALSE;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.ve[i].src_format);
+ if (!svga->curr.velems) {
+ /* No vertex elements bound. */
+ return 0;
+ }
+
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ svga->state.sw.ve_format[i] = svga_translate_vertex_format(svga->curr.velems->velem[i].src_format);
if (svga->state.sw.ve_format[i] == SVGA3D_DECLTYPE_MAX) {
need_swvfetch = TRUE;
break;
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 107cc403b4d..b7195d246bc 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -191,15 +191,24 @@ static int emit_rss( struct svga_context *svga,
EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail );
}
- if (dirty & SVGA_NEW_RAST)
+ if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
{
const struct svga_rasterizer_state *curr = svga->curr.rast;
+ unsigned cullmode = curr->cullmode;
/* Shademode: still need to rearrange index list to move
* flat-shading PV first vertex.
*/
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
- EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
+
+ /* Don't do culling while the software pipeline is active. It
+ * does it for us, and additionally introduces potentially
+ * back-facing triangles.
+ */
+ if (svga->state.sw.need_pipeline)
+ cullmode = SVGA3D_FACE_NONE;
+
+ EMIT_RS( svga, cullmode, CULLMODE, fail );
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index 17b47859781..c08ec7c2e8c 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -37,14 +37,14 @@
void svga_cleanup_tss_binding(struct svga_context *svga)
{
int i;
- unsigned count = MAX2( svga->curr.num_textures,
+ unsigned count = MAX2( svga->curr.num_sampler_views,
svga->state.hw_draw.num_views );
for (i = 0; i < count; i++) {
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
svga_sampler_view_reference(&view->v, NULL);
- pipe_texture_reference( &svga->curr.texture[i], NULL );
+ pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL );
pipe_texture_reference( &view->texture, NULL );
view->dirty = 1;
@@ -57,7 +57,7 @@ update_tss_binding(struct svga_context *svga,
unsigned dirty )
{
unsigned i;
- unsigned count = MAX2( svga->curr.num_textures,
+ unsigned count = MAX2( svga->curr.num_sampler_views,
svga->state.hw_draw.num_views );
unsigned min_lod;
unsigned max_lod;
@@ -77,30 +77,32 @@ update_tss_binding(struct svga_context *svga,
for (i = 0; i < count; i++) {
const struct svga_sampler_state *s = svga->curr.sampler[i];
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
+ struct pipe_texture *texture = NULL;
/* get min max lod */
- if (svga->curr.texture[i]) {
+ if (svga->curr.sampler_views[i]) {
min_lod = MAX2(s->view_min_lod, 0);
- max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level);
+ max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level);
+ texture = svga->curr.sampler_views[i]->texture;
} else {
min_lod = 0;
max_lod = 0;
}
- if (view->texture != svga->curr.texture[i] ||
+ if (view->texture != texture ||
view->min_lod != min_lod ||
view->max_lod != max_lod) {
svga_sampler_view_reference(&view->v, NULL);
- pipe_texture_reference( &view->texture, svga->curr.texture[i] );
+ pipe_texture_reference( &view->texture, texture );
view->dirty = TRUE;
view->min_lod = min_lod;
view->max_lod = max_lod;
- if (svga->curr.texture[i])
+ if (texture)
view->v = svga_get_tex_sampler_view(&svga->pipe,
- svga->curr.texture[i],
+ texture,
min_lod,
max_lod);
}
@@ -115,7 +117,7 @@ update_tss_binding(struct svga_context *svga,
}
}
- svga->state.hw_draw.num_views = svga->curr.num_textures;
+ svga->state.hw_draw.num_views = svga->curr.num_sampler_views;
if (queue.bind_count) {
SVGA3dTextureState *ts;
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index ded903170b5..f531e223048 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -95,17 +95,17 @@ upload_user_buffers( struct svga_context *svga )
static int emit_hw_vs_vdecl( struct svga_context *svga,
unsigned dirty )
{
- const struct pipe_vertex_element *ve = svga->curr.ve;
+ const struct pipe_vertex_element *ve = svga->curr.velems->velem;
SVGA3dVertexDecl decl;
unsigned i;
- assert(svga->curr.num_vertex_elements >=
+ assert(svga->curr.velems->count >=
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
svga_hwtnl_reset_vdecl( svga->hwtnl,
- svga->curr.num_vertex_elements );
+ svga->curr.velems->count );
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
+ for (i = 0; i < svga->curr.velems->count; i++) {
const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
unsigned usage, index;
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index d7999fe53d2..781f7bf5339 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -186,8 +186,8 @@ static int update_zero_stride( struct svga_context *svga,
svga->curr.zero_stride_vertex_elements = 0;
svga->curr.num_zero_stride_vertex_elements = 0;
- for (i = 0; i < svga->curr.num_vertex_elements; i++) {
- const struct pipe_vertex_element *vel = &svga->curr.ve[i];
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
vel->vertex_buffer_index];
if (vbuffer->stride == 0) {
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 35f36a828fd..246d34e649e 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -99,8 +99,8 @@ static int update_swtnl_draw( struct svga_context *svga,
if (dirty & SVGA_NEW_VELEMENT)
draw_set_vertex_elements(svga->swtnl.draw,
- svga->curr.num_vertex_elements,
- svga->curr.ve );
+ svga->curr.velems->count,
+ svga->curr.velems->velem );
if (dirty & SVGA_NEW_CLIP)
draw_set_clip_state(svga->swtnl.draw,
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index b4e3af0eafc..d4bb176f9a8 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -51,6 +51,7 @@ struct pipe_context;
struct pipe_fence_handle;
struct pipe_texture;
struct svga_region;
+struct winsys_handle;
#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
@@ -187,6 +188,25 @@ struct svga_winsys_screen
uint32 numMipLevels);
/**
+ * Creates a surface from a winsys handle.
+ * Used to implement pipe_screen::texture_from_handle.
+ */
+ struct svga_winsys_surface *
+ (*surface_from_handle)(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+
+ /**
+ * Get a winsys_handle from a surface.
+ * Used to implement pipe_screen::texture_get_handle.
+ */
+ boolean
+ (*surface_get_handle)(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
+ /**
* Whether this surface is sitting in a validate list
*/
boolean
@@ -284,19 +304,6 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
struct svga_winsys_surface *srf);
struct svga_winsys_surface *
-svga_screen_texture_get_winsys_surface(struct pipe_texture *texture);
-struct svga_winsys_surface *
svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
-boolean
-svga_screen_buffer_from_texture(struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
-
-struct pipe_texture *
-svga_screen_texture_wrap_surface(struct pipe_screen *screen,
- struct pipe_texture *base,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf);
-
#endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
index 705ca29e8f5..4ee1bf2c353 100644
--- a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
+++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c
@@ -360,7 +360,9 @@ dump_dstreg(struct sh_dstreg dstreg,
union {
struct sh_reg reg;
struct sh_dstreg dstreg;
- } u = { { 0 } };
+ } u;
+
+ memset(&u, 0, sizeof(u));
assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier );
diff --git a/src/gallium/drivers/sw/Makefile b/src/gallium/drivers/sw/Makefile
new file mode 100644
index 00000000000..2713a62ee9f
--- /dev/null
+++ b/src/gallium/drivers/sw/Makefile
@@ -0,0 +1,10 @@
+# Meta-driver which combines whichever software rasterizers have been
+# built into a single convenience library.
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+C_SOURCES = \
+ sw.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/sw/SConscript b/src/gallium/drivers/sw/SConscript
new file mode 100644
index 00000000000..6fbbdf3cc46
--- /dev/null
+++ b/src/gallium/drivers/sw/SConscript
@@ -0,0 +1,42 @@
+#######################################################################
+# SConscript for swrast convenience library
+#
+# This is a meta-driver which consists of any and all of the software
+# rasterizers into a single driver. A software rasterizer is defined
+# as any driver which takes an sw_winsys pointer as the only argument
+# to create_screen.
+#
+# XXX: unfortunately users of this driver still need to link in any
+# extra libraries needed for the particular driver (eg llvm for
+# llvmpipe). Not sure how to get around this.
+
+Import('*')
+
+if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of sw meta-driver'
+ Return()
+
+env = env.Clone()
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+if 'cell' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_CELL')
+ env.Prepend(LIBS = [cell])
+
+sw = env.ConvenienceLibrary(
+ target = 'sw',
+ source = [
+ 'sw.c',
+ ]
+ )
+ Export('sw')
diff --git a/src/gallium/drivers/sw/sw.c b/src/gallium/drivers/sw/sw.c
new file mode 100644
index 00000000000..9f156df45f5
--- /dev/null
+++ b/src/gallium/drivers/sw/sw.c
@@ -0,0 +1,59 @@
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "target-helpers/wrap_screen.h"
+#include "sw_public.h"
+#include "state_tracker/sw_winsys.h"
+
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+ if (screen == NULL && strcmp(driver, "cell") == 0)
+ screen = cell_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/drivers/sw/sw_public.h b/src/gallium/drivers/sw/sw_public.h
new file mode 100644
index 00000000000..7085c5c85a0
--- /dev/null
+++ b/src/gallium/drivers/sw/sw_public.h
@@ -0,0 +1,13 @@
+#ifndef SW_PUBLIC_H
+#define SW_PUBLIC_H
+
+/* A convenience library, primarily to isolate the logic required to
+ * figure out which if any software rasterizers have been built and
+ * select between them.
+ */
+struct sw_winsys;
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys);
+
+#endif
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index df40fbade6c..5c24bd1f7df 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -25,9 +25,12 @@
*
**************************************************************************/
+#include "util/u_inlines.h"
#include "util/u_memory.h"
#include "util/u_simple_list.h"
+#include "util/u_format.h"
+#include "pipe/p_format.h"
#include "pipe/p_screen.h"
#include "tr_dump.h"
@@ -112,7 +115,7 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)
(void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,
(void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,
(void *) tr_ctx->draw_rule.surf, 0,
- (void *) tr_ctx->draw_rule.tex, 0);
+ (void *) tr_ctx->draw_rule.sampler_view, 0);
if (tr_ctx->draw_rule.fs &&
tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
block = TRUE;
@@ -126,12 +129,12 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)
for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
block = TRUE;
- if (tr_ctx->draw_rule.tex) {
- for (k = 0; k < tr_ctx->curr.num_texs; k++)
- if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
+ if (tr_ctx->draw_rule.sampler_view) {
+ for (k = 0; k < tr_ctx->curr.num_sampler_views; k++)
+ if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.sampler_views[k])
block = TRUE;
- for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) {
- if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) {
+ for (k = 0; k < tr_ctx->curr.num_vert_sampler_views; k++) {
+ if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.vert_sampler_views[k]) {
block = TRUE;
}
}
@@ -773,6 +776,70 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,
}
+static INLINE void *
+trace_context_create_vertex_elements_state(struct pipe_context *_pipe,
+ unsigned num_elements,
+ const struct pipe_vertex_element *elements)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ void * result;
+
+ trace_dump_call_begin("pipe_context", "create_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(uint, num_elements);
+
+ trace_dump_arg_begin("elements");
+ trace_dump_struct_array(vertex_element, elements, num_elements);
+ trace_dump_arg_end();
+
+ result = pipe->create_vertex_elements_state(pipe, num_elements, elements);
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ return result;
+}
+
+
+static INLINE void
+trace_context_bind_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "bind_vertex_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->bind_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
+static INLINE void
+trace_context_delete_vertex_elements_state(struct pipe_context *_pipe,
+ void *state)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct pipe_context *pipe = tr_ctx->pipe;
+
+ trace_dump_call_begin("pipe_context", "delete_verte_elements_state");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, state);
+
+ pipe->delete_vertex_elements_state(pipe, state);
+
+ trace_dump_call_end();
+}
+
+
static INLINE void
trace_context_set_blend_color(struct pipe_context *_pipe,
const struct pipe_blend_color *state)
@@ -949,63 +1016,119 @@ trace_context_set_viewport_state(struct pipe_context *_pipe,
}
+static struct pipe_sampler_view *
+trace_create_sampler_view(struct pipe_context *_pipe,
+ struct pipe_texture *_texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ struct trace_sampler_view *result = CALLOC_STRUCT(trace_sampler_view);
+
+ trace_dump_call_begin("pipe_context", "create_sampler_view");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(ptr, templ);
+
+ result->sampler_view = pipe->create_sampler_view(pipe, texture, templ);
+
+ result->base = *templ;
+ result->base.reference.count = 1;
+ result->base.texture = NULL;
+ pipe_texture_reference(&result->base.texture, _texture);
+ result->base.context = _pipe;
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ return &result->base;
+}
+
+
+static void
+trace_sampler_view_destroy(struct pipe_context *_pipe,
+ struct pipe_sampler_view *_view)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_sampler_view *tr_view = trace_sampler_view(_view);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_sampler_view *view = tr_view->sampler_view;
+
+ trace_dump_call_begin("pipe_context", "sampler_view_destroy");
+
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, view);
+
+ pipe->sampler_view_destroy(pipe, view);
+
+ trace_dump_call_end();
+
+ pipe_texture_reference(&_view->texture, NULL);
+ FREE(_view);
+}
+
+
static INLINE void
-trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+trace_context_set_fragment_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_texture *tr_tex;
+ struct trace_sampler_view *tr_view;
struct pipe_context *pipe = tr_ctx->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
unsigned i;
- tr_ctx->curr.num_texs = num_textures;
- for(i = 0; i < num_textures; ++i) {
- tr_tex = trace_texture(textures[i]);
- tr_ctx->curr.tex[i] = tr_tex;
- unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+ tr_ctx->curr.num_sampler_views = num;
+ for(i = 0; i < num; ++i) {
+ tr_view = trace_sampler_view(views[i]);
+ tr_ctx->curr.sampler_views[i] = tr_view;
+ unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;
}
- textures = unwrapped_textures;
+ views = unwrapped_views;
- trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures");
+ trace_dump_call_begin("pipe_context", "set_fragment_sampler_views");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_textures);
- trace_dump_arg_array(ptr, textures, num_textures);
+ trace_dump_arg(uint, num);
+ trace_dump_arg_array(ptr, views, num);
- pipe->set_fragment_sampler_textures(pipe, num_textures, textures);
+ pipe->set_fragment_sampler_views(pipe, num, views);
trace_dump_call_end();
}
static INLINE void
-trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe,
- unsigned num_textures,
- struct pipe_texture **textures)
+trace_context_set_vertex_sampler_views(struct pipe_context *_pipe,
+ unsigned num,
+ struct pipe_sampler_view **views)
{
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_texture *tr_tex;
+ struct trace_sampler_view *tr_view;
struct pipe_context *pipe = tr_ctx->pipe;
- struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned i;
- tr_ctx->curr.num_vert_texs = num_textures;
- for(i = 0; i < num_textures; ++i) {
- tr_tex = trace_texture(textures[i]);
- tr_ctx->curr.vert_tex[i] = tr_tex;
- unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+ tr_ctx->curr.num_vert_sampler_views = num;
+ for(i = 0; i < num; ++i) {
+ tr_view = trace_sampler_view(views[i]);
+ tr_ctx->curr.vert_sampler_views[i] = tr_view;
+ unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;
}
- textures = unwrapped_textures;
+ views = unwrapped_views;
- trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures");
+ trace_dump_call_begin("pipe_context", "set_vertex_sampler_views");
trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_textures);
- trace_dump_arg_array(ptr, textures, num_textures);
+ trace_dump_arg(uint, num);
+ trace_dump_arg_array(ptr, views, num);
- pipe->set_vertex_sampler_textures(pipe, num_textures, textures);
+ pipe->set_vertex_sampler_views(pipe, num, views);
trace_dump_call_end();
}
@@ -1048,29 +1171,6 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
static INLINE void
-trace_context_set_vertex_elements(struct pipe_context *_pipe,
- unsigned num_elements,
- const struct pipe_vertex_element *elements)
-{
- struct trace_context *tr_ctx = trace_context(_pipe);
- struct pipe_context *pipe = tr_ctx->pipe;
-
- trace_dump_call_begin("pipe_context", "set_vertex_elements");
-
- trace_dump_arg(ptr, pipe);
- trace_dump_arg(uint, num_elements);
-
- trace_dump_arg_begin("elements");
- trace_dump_struct_array(vertex_element, elements, num_elements);
- trace_dump_arg_end();
-
- pipe->set_vertex_elements(pipe, num_elements, elements);
-
- trace_dump_call_end();
-}
-
-
-static INLINE void
trace_context_surface_copy(struct pipe_context *_pipe,
struct pipe_surface *dest,
unsigned destx, unsigned desty,
@@ -1242,6 +1342,136 @@ trace_is_buffer_referenced( struct pipe_context *_pipe,
return referenced;
}
+
+/********************************************************************
+ * transfer
+ */
+
+
+static struct pipe_transfer *
+trace_context_get_tex_transfer(struct pipe_context *_context,
+ struct pipe_texture *_texture,
+ unsigned face, unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ struct pipe_transfer *result = NULL;
+
+ assert(texture->screen == context->screen);
+
+ trace_dump_call_begin("pipe_context", "get_tex_transfer");
+
+ trace_dump_arg(ptr, context);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(uint, face);
+ trace_dump_arg(uint, level);
+ trace_dump_arg(uint, zslice);
+ trace_dump_arg(uint, usage);
+
+ trace_dump_arg(uint, x);
+ trace_dump_arg(uint, y);
+ trace_dump_arg(uint, w);
+ trace_dump_arg(uint, h);
+
+ result = context->get_tex_transfer(context, texture, face, level, zslice, usage,
+ x, y, w, h);
+
+ trace_dump_ret(ptr, result);
+
+ trace_dump_call_end();
+
+ if (result)
+ result = trace_transfer_create(tr_context, tr_tex, result);
+
+ return result;
+}
+
+
+static void
+trace_context_tex_transfer_destroy(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+
+ trace_dump_call_begin("pipe_context", "tex_transfer_destroy");
+
+ trace_dump_arg(ptr, context);
+ trace_dump_arg(ptr, transfer);
+
+ trace_dump_call_end();
+
+ trace_transfer_destroy(tr_context, tr_trans);
+}
+
+
+static void *
+trace_context_transfer_map(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_context = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+ void *map;
+
+ map = context->transfer_map(context, transfer);
+ if(map) {
+ if(transfer->usage & PIPE_TRANSFER_WRITE) {
+ assert(!tr_trans->map);
+ tr_trans->map = map;
+ }
+ }
+
+ return map;
+}
+
+
+static void
+trace_context_transfer_unmap(struct pipe_context *_context,
+ struct pipe_transfer *_transfer)
+{
+ struct trace_context *tr_ctx = trace_context(_context);
+ struct trace_transfer *tr_trans = trace_transfer(_transfer);
+ struct pipe_context *context = tr_ctx->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
+
+ if(tr_trans->map) {
+ size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride;
+
+ trace_dump_call_begin("pipe_context", "transfer_write");
+
+ trace_dump_arg(ptr, context);
+
+ trace_dump_arg(ptr, transfer);
+
+ trace_dump_arg_begin("stride");
+ trace_dump_uint(transfer->stride);
+ trace_dump_arg_end();
+
+ trace_dump_arg_begin("data");
+ trace_dump_bytes(tr_trans->map, size);
+ trace_dump_arg_end();
+
+ trace_dump_arg_begin("size");
+ trace_dump_uint(size);
+ trace_dump_arg_end();
+
+ trace_dump_call_end();
+
+ tr_trans->map = NULL;
+ }
+
+ context->transfer_unmap(context, transfer);
+}
+
static const struct debug_named_value rbug_blocker_flags[] = {
{"before", 1},
{"after", 2},
@@ -1303,6 +1533,9 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.create_vs_state = trace_context_create_vs_state;
tr_ctx->base.bind_vs_state = trace_context_bind_vs_state;
tr_ctx->base.delete_vs_state = trace_context_delete_vs_state;
+ tr_ctx->base.create_vertex_elements_state = trace_context_create_vertex_elements_state;
+ tr_ctx->base.bind_vertex_elements_state = trace_context_bind_vertex_elements_state;
+ tr_ctx->base.delete_vertex_elements_state = trace_context_delete_vertex_elements_state;
tr_ctx->base.set_blend_color = trace_context_set_blend_color;
tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref;
tr_ctx->base.set_clip_state = trace_context_set_clip_state;
@@ -1311,10 +1544,11 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;
tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;
tr_ctx->base.set_viewport_state = trace_context_set_viewport_state;
- tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures;
- tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures;
+ tr_ctx->base.set_fragment_sampler_views = trace_context_set_fragment_sampler_views;
+ tr_ctx->base.set_vertex_sampler_views = trace_context_set_vertex_sampler_views;
+ tr_ctx->base.create_sampler_view = trace_create_sampler_view;
+ tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
- tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
if (pipe->surface_copy)
tr_ctx->base.surface_copy = trace_context_surface_copy;
if (pipe->surface_fill)
@@ -1324,6 +1558,11 @@ trace_context_create(struct trace_screen *tr_scr,
tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
+ tr_ctx->base.get_tex_transfer = trace_context_get_tex_transfer;
+ tr_ctx->base.tex_transfer_destroy = trace_context_tex_transfer_destroy;
+ tr_ctx->base.transfer_map = trace_context_transfer_map;
+ tr_ctx->base.transfer_unmap = trace_context_transfer_unmap;
+
tr_ctx->pipe = pipe;
trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h
index 14284232485..feec9b6bbf3 100644
--- a/src/gallium/drivers/trace/tr_context.h
+++ b/src/gallium/drivers/trace/tr_context.h
@@ -53,11 +53,11 @@ struct trace_context
struct trace_shader *fs;
struct trace_shader *vs;
- struct trace_texture *tex[PIPE_MAX_SAMPLERS];
- unsigned num_texs;
+ struct trace_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+ unsigned num_sampler_views;
- struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS];
- unsigned num_vert_texs;
+ struct trace_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+ unsigned num_vert_sampler_views;
unsigned nr_cbufs;
struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS];
@@ -68,7 +68,7 @@ struct trace_context
struct trace_shader *fs;
struct trace_shader *vs;
- struct trace_texture *tex;
+ struct trace_sampler_view *sampler_view;
struct trace_texture *surf;
int blocker;
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 2b4915003e2..eaa47df4066 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -30,9 +30,7 @@
#include "util/u_memory.h"
#include "tr_drm.h"
#include "tr_screen.h"
-#include "tr_context.h"
-#include "tr_buffer.h"
-#include "tr_texture.h"
+#include "tr_public.h"
struct trace_drm_api
{
@@ -62,69 +60,8 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
- return trace_screen_create(screen);
-}
-
-
-static struct pipe_texture *
-trace_drm_texture_from_shared_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct drm_api *api = tr_api->api;
- struct pipe_texture *result;
-
- /* TODO trace call */
-
- result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
-
- result = trace_texture_create(trace_screen(_screen), result);
-
- return result;
-}
-
-static boolean
-trace_drm_shared_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->shared_handle_from_texture(api, screen, texture, stride, handle);
-}
-static boolean
-trace_drm_local_handle_from_texture(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_screen *screen = tr_screen->screen;
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
-
- /* TODO trace call */
-
- return api->local_handle_from_texture(api, screen, texture, stride, handle);
+ return trace_screen_create(screen);
}
static void
@@ -158,9 +95,6 @@ trace_drm_create(struct drm_api *api)
tr_api->base.name = api->name;
tr_api->base.driver_name = api->driver_name;
tr_api->base.create_screen = trace_drm_create_screen;
- tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
- tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
- tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
tr_api->base.destroy = trace_drm_destroy;
tr_api->api = api;
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index f97d963dba6..f82dd01c697 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -479,7 +479,6 @@ void trace_dump_vertex_element(const struct pipe_vertex_element *state)
trace_dump_member(uint, state, src_offset);
trace_dump_member(uint, state, vertex_buffer_index);
- trace_dump_member(uint, state, nr_components);
trace_dump_member(format, state, src_format);
diff --git a/src/gallium/drivers/trace/tr_public.h b/src/gallium/drivers/trace/tr_public.h
new file mode 100644
index 00000000000..62e217097d0
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_public.h
@@ -0,0 +1,45 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+#ifndef TR_PUBLIC_H
+#define TR_PUBLIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_screen;
+struct pipe_context;
+
+struct pipe_screen *
+trace_screen_create(struct pipe_screen *screen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TR_PUBLIC_H */
diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c
index a43adac6940..53ab8c686d8 100644
--- a/src/gallium/drivers/trace/tr_rbug.c
+++ b/src/gallium/drivers/trace/tr_rbug.c
@@ -219,7 +219,7 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
struct trace_texture *tr_tex = NULL;
struct tr_list *ptr;
- struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_context *context = tr_scr->private_context;
struct pipe_texture *tex;
struct pipe_transfer *t;
@@ -239,12 +239,12 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
}
tex = tr_tex->texture;
- t = screen->get_tex_transfer(tr_scr->screen, tex,
- gptr->face, gptr->level, gptr->zslice,
- PIPE_TRANSFER_READ,
- gptr->x, gptr->y, gptr->w, gptr->h);
+ t = context->get_tex_transfer(context, tex,
+ gptr->face, gptr->level, gptr->zslice,
+ PIPE_TRANSFER_READ,
+ gptr->x, gptr->y, gptr->w, gptr->h);
- map = screen->transfer_map(screen, t);
+ map = context->transfer_map(context, t);
rbug_send_texture_read_reply(tr_rbug->con, serial,
t->texture->format,
@@ -256,8 +256,8 @@ trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header,
t->stride,
NULL);
- screen->transfer_unmap(screen, t);
- screen->tex_transfer_destroy(t);
+ context->transfer_unmap(context, t);
+ context->tex_transfer_destroy(context, t);
pipe_mutex_unlock(tr_scr->list_mutex);
@@ -313,12 +313,12 @@ trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header,
for (i = 0; i < tr_ctx->curr.nr_cbufs; i++)
cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]);
- for (i = 0; i < tr_ctx->curr.num_texs; i++)
- texs[i] = VOID2U64(tr_ctx->curr.tex[i]);
+ for (i = 0; i < tr_ctx->curr.num_sampler_views; i++)
+ texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]);
rbug_send_context_info_reply(tr_rbug->con, serial,
VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs),
- texs, tr_ctx->curr.num_texs,
+ texs, tr_ctx->curr.num_sampler_views,
cbufs, tr_ctx->curr.nr_cbufs,
VOID2U64(tr_ctx->curr.zsbuf),
tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL);
@@ -444,7 +444,7 @@ trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *hea
pipe_mutex_lock(tr_ctx->draw_mutex);
tr_ctx->draw_rule.vs = U642VOID(rule->vertex);
tr_ctx->draw_rule.fs = U642VOID(rule->fragment);
- tr_ctx->draw_rule.tex = U642VOID(rule->texture);
+ tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture);
tr_ctx->draw_rule.surf = U642VOID(rule->surface);
tr_ctx->draw_rule.blocker = rule->block;
tr_ctx->draw_blocker |= RBUG_BLOCK_RULE;
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 388d83eb5c2..25990bdac7f 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -35,6 +35,7 @@
#include "tr_texture.h"
#include "tr_context.h"
#include "tr_screen.h"
+#include "tr_public.h"
#include "util/u_inlines.h"
#include "pipe/p_format.h"
@@ -236,39 +237,41 @@ trace_screen_texture_create(struct pipe_screen *_screen,
return result;
}
-
static struct pipe_texture *
-trace_screen_texture_blanket(struct pipe_screen *_screen,
- const struct pipe_texture *templat,
- const unsigned *ppitch,
- struct pipe_buffer *_buffer)
+trace_screen_texture_from_handle(struct pipe_screen *_screen,
+ const struct pipe_texture *templ,
+ struct winsys_handle *handle)
{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(_buffer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_buffer *buffer = tr_buf->buffer;
- unsigned pitch = *ppitch;
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct pipe_screen *screen = tr_screen->screen;
struct pipe_texture *result;
- trace_dump_call_begin("pipe_screen", "texture_blanket");
+ /* TODO trace call */
- trace_dump_arg(ptr, screen);
- trace_dump_arg(template, templat);
- trace_dump_arg(uint, pitch);
- trace_dump_arg(ptr, buffer);
+ result = screen->texture_from_handle(screen, templ, handle);
- result = screen->texture_blanket(screen, templat, ppitch, buffer);
+ result = trace_texture_create(trace_screen(_screen), result);
- trace_dump_ret(ptr, result);
+ return result;
+}
- trace_dump_call_end();
+static boolean
+trace_screen_texture_get_handle(struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ struct winsys_handle *handle)
+{
+ struct trace_screen *tr_screen = trace_screen(_screen);
+ struct trace_texture *tr_texture = trace_texture(_texture);
+ struct pipe_screen *screen = tr_screen->screen;
+ struct pipe_texture *texture = tr_texture->texture;
- result = trace_texture_create(tr_scr, result);
+ /* TODO trace call */
- return result;
+ return screen->texture_get_handle(screen, texture, handle);
}
+
static void
trace_screen_texture_destroy(struct pipe_texture *_texture)
{
@@ -350,133 +353,7 @@ trace_screen_tex_surface_destroy(struct pipe_surface *_surface)
}
-/********************************************************************
- * transfer
- */
-
-
-static struct pipe_transfer *
-trace_screen_get_tex_transfer(struct pipe_screen *_screen,
- struct pipe_texture *_texture,
- unsigned face, unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y, unsigned w, unsigned h)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_texture *tr_tex = trace_texture(_texture);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_texture *texture = tr_tex->texture;
- struct pipe_transfer *result = NULL;
-
- assert(texture->screen == screen);
-
- trace_dump_call_begin("pipe_screen", "get_tex_transfer");
- trace_dump_arg(ptr, screen);
- trace_dump_arg(ptr, texture);
- trace_dump_arg(uint, face);
- trace_dump_arg(uint, level);
- trace_dump_arg(uint, zslice);
- trace_dump_arg(uint, usage);
-
- trace_dump_arg(uint, x);
- trace_dump_arg(uint, y);
- trace_dump_arg(uint, w);
- trace_dump_arg(uint, h);
-
- result = screen->get_tex_transfer(screen, texture, face, level, zslice, usage,
- x, y, w, h);
-
- trace_dump_ret(ptr, result);
-
- trace_dump_call_end();
-
- if (result)
- result = trace_transfer_create(tr_tex, result);
-
- return result;
-}
-
-
-static void
-trace_screen_tex_transfer_destroy(struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_transfer->texture->screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
-
- trace_dump_call_begin("pipe_screen", "tex_transfer_destroy");
-
- trace_dump_arg(ptr, screen);
- trace_dump_arg(ptr, transfer);
-
- trace_dump_call_end();
-
- trace_transfer_destroy(tr_trans);
-}
-
-
-static void *
-trace_screen_transfer_map(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
- void *map;
-
- map = screen->transfer_map(screen, transfer);
- if(map) {
- if(transfer->usage & PIPE_TRANSFER_WRITE) {
- assert(!tr_trans->map);
- tr_trans->map = map;
- }
- }
-
- return map;
-}
-
-
-static void
-trace_screen_transfer_unmap(struct pipe_screen *_screen,
- struct pipe_transfer *_transfer)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_transfer *tr_trans = trace_transfer(_transfer);
- struct pipe_screen *screen = tr_scr->screen;
- struct pipe_transfer *transfer = tr_trans->transfer;
-
- if(tr_trans->map) {
- size_t size = util_format_get_nblocksy(transfer->texture->format, transfer->height) * transfer->stride;
-
- trace_dump_call_begin("pipe_screen", "transfer_write");
-
- trace_dump_arg(ptr, screen);
-
- trace_dump_arg(ptr, transfer);
-
- trace_dump_arg_begin("stride");
- trace_dump_uint(transfer->stride);
- trace_dump_arg_end();
-
- trace_dump_arg_begin("data");
- trace_dump_bytes(tr_trans->map, size);
- trace_dump_arg_end();
-
- trace_dump_arg_begin("size");
- trace_dump_uint(size);
- trace_dump_arg_end();
-
- trace_dump_call_end();
-
- tr_trans->map = NULL;
- }
-
- screen->transfer_unmap(screen, transfer);
-}
/********************************************************************
@@ -484,45 +361,7 @@ trace_screen_transfer_unmap(struct pipe_screen *_screen,
*/
-static struct pipe_buffer *
-trace_screen_surface_buffer_create(struct pipe_screen *_screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *pstride)
-{
- struct trace_screen *tr_scr = trace_screen(_screen);
- struct pipe_screen *screen = tr_scr->screen;
- unsigned stride;
- struct pipe_buffer *result;
-
- trace_dump_call_begin("pipe_screen", "surface_buffer_create");
-
- trace_dump_arg(ptr, screen);
- trace_dump_arg(uint, width);
- trace_dump_arg(uint, height);
- trace_dump_arg(format, format);
- trace_dump_arg(uint, usage);
- trace_dump_arg(uint, tex_usage);
-
- result = screen->surface_buffer_create(screen,
- width, height,
- format,
- usage,
- tex_usage,
- pstride);
-
- stride = *pstride;
-
- trace_dump_arg(uint, stride);
-
- trace_dump_ret(ptr, result);
-
- trace_dump_call_end();
- return trace_buffer_create(tr_scr, result);
-}
static struct pipe_buffer *
@@ -931,17 +770,13 @@ trace_screen_create(struct pipe_screen *screen)
assert(screen->context_create);
tr_scr->base.context_create = trace_screen_context_create;
tr_scr->base.texture_create = trace_screen_texture_create;
- tr_scr->base.texture_blanket = trace_screen_texture_blanket;
+ tr_scr->base.texture_from_handle = trace_screen_texture_from_handle;
+ tr_scr->base.texture_get_handle = trace_screen_texture_get_handle;
tr_scr->base.texture_destroy = trace_screen_texture_destroy;
tr_scr->base.get_tex_surface = trace_screen_get_tex_surface;
tr_scr->base.tex_surface_destroy = trace_screen_tex_surface_destroy;
- tr_scr->base.get_tex_transfer = trace_screen_get_tex_transfer;
- tr_scr->base.tex_transfer_destroy = trace_screen_tex_transfer_destroy;
- tr_scr->base.transfer_map = trace_screen_transfer_map;
- tr_scr->base.transfer_unmap = trace_screen_transfer_unmap;
tr_scr->base.buffer_create = trace_screen_buffer_create;
tr_scr->base.user_buffer_create = trace_screen_user_buffer_create;
- tr_scr->base.surface_buffer_create = trace_screen_surface_buffer_create;
if (screen->buffer_map)
tr_scr->base.buffer_map = trace_screen_buffer_map;
if (screen->buffer_map_range)
@@ -955,7 +790,11 @@ trace_screen_create(struct pipe_screen *screen)
tr_scr->base.fence_signalled = trace_screen_fence_signalled;
tr_scr->base.fence_finish = trace_screen_fence_finish;
tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer;
+
tr_scr->screen = screen;
+ tr_scr->private_context = screen->context_create(screen, NULL);
+ if (tr_scr->private_context == NULL)
+ goto error3;
trace_dump_ret(ptr, screen);
trace_dump_call_end();
@@ -965,10 +804,8 @@ trace_screen_create(struct pipe_screen *screen)
return &tr_scr->base;
-#if 0
error3:
FREE(tr_scr);
-#endif
error2:
trace_dump_ret(ptr, screen);
trace_dump_call_end();
diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h
index fe5a0fa1909..9bfbe72e2c0 100644
--- a/src/gallium/drivers/trace/tr_screen.h
+++ b/src/gallium/drivers/trace/tr_screen.h
@@ -56,6 +56,7 @@ struct trace_screen
struct pipe_screen base;
struct pipe_screen *screen;
+ struct pipe_context *private_context;
/* remote debugger */
struct trace_rbug *rbug;
@@ -99,9 +100,6 @@ trace_enabled(void);
struct trace_screen *
trace_screen(struct pipe_screen *screen);
-struct pipe_screen *
-trace_screen_create(struct pipe_screen *screen);
-
void
trace_screen_user_buffer_update(struct pipe_screen *screen,
struct pipe_buffer *buffer);
diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c
index 5321d68ec0c..d818e21bb82 100644
--- a/src/gallium/drivers/trace/tr_texture.c
+++ b/src/gallium/drivers/trace/tr_texture.c
@@ -31,6 +31,7 @@
#include "util/u_simple_list.h"
#include "tr_screen.h"
+#include "tr_context.h"
#include "tr_texture.h"
@@ -124,8 +125,9 @@ trace_surface_destroy(struct trace_surface *tr_surf)
struct pipe_transfer *
-trace_transfer_create(struct trace_texture *tr_tex,
- struct pipe_transfer *transfer)
+trace_transfer_create(struct trace_context *tr_ctx,
+ struct trace_texture *tr_tex,
+ struct pipe_transfer *transfer)
{
struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_transfer *tr_trans;
@@ -142,8 +144,9 @@ trace_transfer_create(struct trace_texture *tr_tex,
memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer));
tr_trans->base.texture = NULL;
- pipe_texture_reference(&tr_trans->base.texture, &tr_tex->base);
tr_trans->transfer = transfer;
+
+ pipe_texture_reference(&tr_trans->base.texture, &tr_tex->base);
assert(tr_trans->base.texture == &tr_tex->base);
trace_screen_add_to_list(tr_scr, transfers, tr_trans);
@@ -151,21 +154,23 @@ trace_transfer_create(struct trace_texture *tr_tex,
return &tr_trans->base;
error:
- transfer->texture->screen->tex_transfer_destroy(transfer);
+ tr_ctx->pipe->tex_transfer_destroy(tr_ctx->pipe, transfer);
return NULL;
}
void
-trace_transfer_destroy(struct trace_transfer *tr_trans)
+trace_transfer_destroy(struct trace_context *tr_context,
+ struct trace_transfer *tr_trans)
{
- struct trace_screen *tr_scr = trace_screen(tr_trans->base.texture->screen);
- struct pipe_screen *screen = tr_trans->transfer->texture->screen;
+ struct trace_screen *tr_scr = trace_screen(tr_context->base.screen);
+ struct pipe_context *context = tr_context->pipe;
+ struct pipe_transfer *transfer = tr_trans->transfer;
trace_screen_remove_from_list(tr_scr, transfers, tr_trans);
pipe_texture_reference(&tr_trans->base.texture, NULL);
- screen->tex_transfer_destroy(tr_trans->transfer);
+ context->tex_transfer_destroy(context, transfer);
FREE(tr_trans);
}
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index 395e523e73a..66250465e44 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -34,6 +34,7 @@
#include "tr_screen.h"
+struct trace_context;
struct trace_texture
{
@@ -55,11 +56,20 @@ struct trace_surface
};
+struct trace_sampler_view
+{
+ struct pipe_sampler_view base;
+
+ struct pipe_sampler_view *sampler_view;
+};
+
+
struct trace_transfer
{
struct pipe_transfer base;
struct pipe_transfer *transfer;
+ struct pipe_context *pipe;
struct tr_list list;
@@ -87,6 +97,15 @@ trace_surface(struct pipe_surface *surface)
}
+static INLINE struct trace_sampler_view *
+trace_sampler_view(struct pipe_sampler_view *sampler_view)
+{
+ if (!sampler_view)
+ return NULL;
+ return (struct trace_sampler_view *)sampler_view;
+}
+
+
static INLINE struct trace_transfer *
trace_transfer(struct pipe_transfer *transfer)
{
@@ -112,11 +131,13 @@ void
trace_surface_destroy(struct trace_surface *tr_surf);
struct pipe_transfer *
-trace_transfer_create(struct trace_texture *tr_tex,
- struct pipe_transfer *transfer);
+trace_transfer_create(struct trace_context *tr_ctx,
+ struct trace_texture *tr_tex,
+ struct pipe_transfer *transfer);
void
-trace_transfer_destroy(struct trace_transfer *tr_trans);
+trace_transfer_destroy(struct trace_context *tr_ctx,
+ struct trace_transfer *tr_trans);
#endif /* TR_TEXTURE_H_ */
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index b93b38310ac..e2766d15cd1 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -31,13 +31,8 @@
#include "p_config.h"
-#ifndef XFree86Server
#include <stdlib.h>
#include <string.h>
-#else
-#include "xf86_ansic.h"
-#include "xf86_libc.h"
-#endif
#include <stddef.h>
#include <stdarg.h>
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index f82b77903e9..d1b734a9f9a 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -177,6 +177,12 @@ struct pipe_context {
void (*bind_gs_state)(struct pipe_context *, void *);
void (*delete_gs_state)(struct pipe_context *, void *);
+ void * (*create_vertex_elements_state)(struct pipe_context *,
+ unsigned num_elements,
+ const struct pipe_vertex_element *);
+ void (*bind_vertex_elements_state)(struct pipe_context *, void *);
+ void (*delete_vertex_elements_state)(struct pipe_context *, void *);
+
/*@}*/
/**
@@ -208,21 +214,18 @@ struct pipe_context {
void (*set_viewport_state)( struct pipe_context *,
const struct pipe_viewport_state * );
- void (*set_fragment_sampler_textures)(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+ void (*set_fragment_sampler_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **);
- void (*set_vertex_sampler_textures)(struct pipe_context *,
- unsigned num_textures,
- struct pipe_texture **);
+ void (*set_vertex_sampler_views)(struct pipe_context *,
+ unsigned num_views,
+ struct pipe_sampler_view **);
void (*set_vertex_buffers)( struct pipe_context *,
unsigned num_buffers,
const struct pipe_vertex_buffer * );
- void (*set_vertex_elements)( struct pipe_context *,
- unsigned num_elements,
- const struct pipe_vertex_element * );
/*@}*/
@@ -303,6 +306,42 @@ struct pipe_context {
*/
unsigned int (*is_buffer_referenced)(struct pipe_context *pipe,
struct pipe_buffer *buf);
+
+ /**
+ * Create a view on a texture to be used by a shader stage.
+ */
+ struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templat);
+
+ void (*sampler_view_destroy)(struct pipe_context *ctx,
+ struct pipe_sampler_view *view);
+
+
+ /**
+ * Get a transfer object for transferring data to/from a texture.
+ *
+ * Transfers are (by default) context-private and allow uploads to be
+ * interleaved with
+ */
+ struct pipe_transfer *(*get_tex_transfer)(struct pipe_context *,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y,
+ unsigned w, unsigned h);
+
+ void (*tex_transfer_destroy)(struct pipe_context *,
+ struct pipe_transfer *);
+
+ void *(*transfer_map)( struct pipe_context *,
+ struct pipe_transfer *transfer );
+
+ void (*transfer_unmap)( struct pipe_context *,
+ struct pipe_transfer *transfer );
+
+
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 5cebd43ace2..c1e291b9da4 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -176,11 +176,12 @@ enum pipe_texture_target {
#define PIPE_TEX_COMPARE_R_TO_TEXTURE 1
#define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1
-#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */
-#define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */
+#define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* windows presentable buffer, ie a backbuffer */
+#define PIPE_TEXTURE_USAGE_SCANOUT 0x4 /* ie a frontbuffer */
#define PIPE_TEXTURE_USAGE_DEPTH_STENCIL 0x8
#define PIPE_TEXTURE_USAGE_SAMPLER 0x10
#define PIPE_TEXTURE_USAGE_DYNAMIC 0x20
+#define PIPE_TEXTURE_USAGE_SHARED 0x40
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_TEXTURE_USAGE_CUSTOM (1 << 16)
@@ -369,6 +370,17 @@ enum pipe_transfer_usage {
/**
+ * Texture swizzles
+ */
+#define PIPE_SWIZZLE_RED 0
+#define PIPE_SWIZZLE_GREEN 1
+#define PIPE_SWIZZLE_BLUE 2
+#define PIPE_SWIZZLE_ALPHA 3
+#define PIPE_SWIZZLE_ZERO 4
+#define PIPE_SWIZZLE_ONE 5
+
+
+/**
* Implementation capabilities/limits which are queried through
* pipe_screen::get_param() and pipe_screen::get_paramf().
*/
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index cbf3273ec8d..ba2985f4491 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -157,6 +157,7 @@ enum pipe_format {
PIPE_FORMAT_DXT5_SRGBA = 109,
PIPE_FORMAT_A8B8G8R8_UNORM = 110,
+ PIPE_FORMAT_B5G5R5X1_UNORM = 111,
PIPE_FORMAT_COUNT
};
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index e4a92228093..b7cb83abbe5 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -50,6 +50,8 @@ extern "C" {
/** Opaque type */
+struct winsys_handle;
+/** Opaque type */
struct pipe_fence_handle;
struct pipe_winsys;
struct pipe_buffer;
@@ -108,16 +110,23 @@ struct pipe_screen {
const struct pipe_texture *templat);
/**
- * Create a new texture object, using the given template info, but on top of
- * existing memory.
- *
- * It is assumed that the buffer data is layed out according to the expected
- * by the hardware. NULL will be returned if any inconsistency is found.
+ * Create a texture from a winsys_handle. The handle is often created in
+ * another process by first creating a pipe texture and then calling
+ * texture_get_handle.
*/
- struct pipe_texture * (*texture_blanket)(struct pipe_screen *,
- const struct pipe_texture *templat,
- const unsigned *stride,
- struct pipe_buffer *buffer);
+ struct pipe_texture * (*texture_from_handle)(struct pipe_screen *,
+ const struct pipe_texture *templat,
+ struct winsys_handle *handle);
+
+ /**
+ * Get a winsys_handle from a texture. Some platforms/winsys requires
+ * that the texture is created with a special usage flag like
+ * DISPLAYTARGET or PRIMARY.
+ */
+ boolean (*texture_get_handle)(struct pipe_screen *,
+ struct pipe_texture *tex,
+ struct winsys_handle *handle);
+
void (*texture_destroy)(struct pipe_texture *pt);
@@ -133,23 +142,6 @@ struct pipe_screen {
void (*tex_surface_destroy)(struct pipe_surface *);
- /** Get a transfer object for transferring data to/from a texture */
- struct pipe_transfer *(*get_tex_transfer)(struct pipe_screen *,
- struct pipe_texture *texture,
- unsigned face, unsigned level,
- unsigned zslice,
- enum pipe_transfer_usage usage,
- unsigned x, unsigned y,
- unsigned w, unsigned h);
-
- void (*tex_transfer_destroy)(struct pipe_transfer *);
-
- void *(*transfer_map)( struct pipe_screen *,
- struct pipe_transfer *transfer );
-
- void (*transfer_unmap)( struct pipe_screen *,
- struct pipe_transfer *transfer );
-
/**
* Create a new buffer.
@@ -187,23 +179,6 @@ struct pipe_screen {
void *ptr,
unsigned bytes);
- /**
- * Allocate storage for a display target surface.
- *
- * Often surfaces which are meant to be blitted to the front screen (i.e.,
- * display targets) must be allocated with special characteristics, memory
- * pools, or obtained directly from the windowing system.
- *
- * This callback is invoked by the pipe_screenwhen creating a texture marked
- * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
- * buffer storage.
- */
- struct pipe_buffer *(*surface_buffer_create)(struct pipe_screen *screen,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride);
/**
@@ -273,6 +248,7 @@ struct pipe_screen {
/**
* Do any special operations to ensure buffer size is correct
+ * \param context_private the private data of the calling context
*/
void (*update_buffer)( struct pipe_screen *ws,
void *context_private );
@@ -280,10 +256,12 @@ struct pipe_screen {
/**
* Do any special operations to ensure frontbuffer contents are
* displayed, eg copy fake frontbuffer.
+ * \param winsys_drawable_handle an opaque handle that the calling context
+ * gets out-of-band
*/
void (*flush_frontbuffer)( struct pipe_screen *screen,
struct pipe_surface *surf,
- void *context_private );
+ void *winsys_drawable_handle );
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 02558520bfe..11072407d93 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -249,7 +249,7 @@ struct pipe_framebuffer_state
{
unsigned width, height;
- /** multiple colorbuffers for multiple render targets */
+ /** multiple color buffers for multiple render targets */
unsigned nr_cbufs;
struct pipe_surface *cbufs[PIPE_MAX_COLOR_BUFS];
@@ -285,12 +285,12 @@ struct pipe_sampler_state
struct pipe_surface
{
struct pipe_reference reference;
- enum pipe_format format; /**< PIPE_FORMAT_x */
+ enum pipe_format format;
unsigned width; /**< logical width in pixels */
unsigned height; /**< logical height in pixels */
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
- unsigned usage; /**< PIPE_BUFFER_USAGE_* */
+ unsigned usage; /**< bitmask of PIPE_BUFFER_USAGE_x */
unsigned zslice;
struct pipe_texture *texture; /**< texture into which this is a view */
@@ -300,6 +300,24 @@ struct pipe_surface
/**
+ * A view into a texture that can be bound to a shader stage.
+ */
+struct pipe_sampler_view
+{
+ struct pipe_reference reference;
+ enum pipe_format format; /**< typed PIPE_FORMAT_x */
+ struct pipe_texture *texture; /**< texture into which this is a view */
+ struct pipe_context *context; /**< context this view belongs to */
+ unsigned first_level:8; /**< first mipmap level */
+ unsigned last_level:8; /**< last mipmap level */
+ unsigned swizzle_r:3; /**< PIPE_SWIZZLE_x for red component */
+ unsigned swizzle_g:3; /**< PIPE_SWIZZLE_x for green component */
+ unsigned swizzle_b:3; /**< PIPE_SWIZZLE_x for blue component */
+ unsigned swizzle_a:3; /**< PIPE_SWIZZLE_x for alpha component */
+};
+
+
+/**
* Transfer object. For data transfer to/from a texture.
*/
struct pipe_transfer
@@ -336,7 +354,7 @@ struct pipe_texture
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
- unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */
+ unsigned tex_usage; /**< bitmask of PIPE_TEXTURE_USAGE_* */
struct pipe_screen *screen; /**< screen that this texture belongs to */
};
@@ -373,9 +391,8 @@ struct pipe_vertex_element
* this attribute live in?
*/
unsigned vertex_buffer_index:8;
- unsigned nr_components:8;
- enum pipe_format src_format; /**< PIPE_FORMAT_* */
+ enum pipe_format src_format;
};
diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h
index b173ba3683d..bb1cd6d1d82 100644
--- a/src/gallium/include/state_tracker/dri1_api.h
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -7,14 +7,14 @@
#include "state_tracker/drm_api.h"
-#include <drm.h>
-
struct pipe_screen;
struct pipe_winsys;
struct pipe_buffer;
struct pipe_context;
struct pipe_texture;
+struct drm_clip_rect;
+
struct dri1_api_version
{
int major;
@@ -31,8 +31,8 @@ struct dri1_api_lock_funcs
{
void (*lock) (struct pipe_context * pipe);
void (*unlock) (struct pipe_context * locked_pipe);
- boolean(*is_locked) (struct pipe_context * locked_pipe);
- boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
+ boolean(*is_locked) (struct pipe_context * locked_pipe);
+ boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
void (*clear_lost_lock) (struct pipe_context * locked_pipe);
};
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
new file mode 100644
index 00000000000..c6adebb4ec5
--- /dev/null
+++ b/src/gallium/include/state_tracker/drisw_api.h
@@ -0,0 +1,35 @@
+#ifndef _DRISW_API_H_
+#define _DRISW_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_format.h"
+
+#include "state_tracker/drm_api.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_buffer;
+struct pipe_context;
+struct pipe_texture;
+
+struct dri_drawable;
+
+/**
+ * This callback struct is intended for the winsys to call the loader.
+ */
+
+struct drisw_loader_funcs
+{
+ void (*put_image) (struct dri_drawable *dri_drawable,
+ void *data, unsigned width, unsigned height);
+};
+
+struct drisw_create_screen_arg
+{
+ struct drm_create_screen_arg base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+#endif
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index e9fa9b4d2a3..9780cf250b8 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -13,10 +13,37 @@ struct pipe_texture;
enum drm_create_screen_mode {
DRM_CREATE_NORMAL = 0,
DRM_CREATE_DRI1,
+ DRM_CREATE_DRISW,
DRM_CREATE_DRIVER = 1024,
DRM_CREATE_MAX
};
+#define DRM_API_HANDLE_TYPE_SHARED 0
+#define DRM_API_HANDLE_TYPE_KMS 1
+
+/**
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
+ */
+struct winsys_handle
+{
+ /**
+ * Unused for texture_from_handle, always
+ * DRM_API_HANDLE_TYPE_SHARED. Input to texture_get_handle,
+ * use TEXTURE_USAGE to select handle for kms or ipc.
+ */
+ unsigned type;
+ /**
+ * Input to texture_from_handle.
+ * Output for texture_get_handle.
+ */
+ unsigned handle;
+ /**
+ * Input to texture_from_handle.
+ * Output for texture_get_handle.
+ */
+ unsigned stride;
+};
+
/**
* Modes other than DRM_CREATE_NORMAL derive from this struct.
*/
@@ -28,6 +55,8 @@ struct drm_create_screen_arg {
struct drm_api
{
+ void (*destroy)(struct drm_api *api);
+
const char *name;
/**
@@ -36,37 +65,10 @@ struct drm_api
const char *driver_name;
/**
- * Special buffer functions
+ * Create a pipe srcreen.
*/
- /*@{*/
struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd,
struct drm_create_screen_arg *arg);
- /*@}*/
-
- /**
- * Special buffer functions
- */
- /*@{*/
- struct pipe_texture*
- (*texture_from_shared_handle)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle);
- boolean (*shared_handle_from_texture)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle);
- boolean (*local_handle_from_texture)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle);
- /*@}*/
-
- void (*destroy)(struct drm_api *api);
};
extern struct drm_api * drm_api_create(void);
diff --git a/src/gallium/include/state_tracker/graw.h b/src/gallium/include/state_tracker/graw.h
new file mode 100644
index 00000000000..a58e18e4739
--- /dev/null
+++ b/src/gallium/include/state_tracker/graw.h
@@ -0,0 +1,36 @@
+#ifndef GALLIUM_RAW_H
+#define GALLIUM_RAW_H
+
+/* This is an API for exercising gallium functionality in a
+ * platform-neutral fashion. Whatever platform integration is
+ * necessary to implement this interface is orchestrated by the
+ * individual target building this entity.
+ *
+ * For instance, the graw-xlib target includes code to implent these
+ * interfaces on top of the X window system.
+ *
+ * Programs using this interface may additionally benefit from some of
+ * the utilities currently in the libgallium.a library, especially
+ * those for parsing text representations of TGSI shaders.
+ */
+
+#include "pipe/p_format.h"
+
+struct pipe_screen;
+
+struct pipe_screen *graw_init( void );
+
+/* Returns a handle to be used with flush_frontbuffer()/present().
+ *
+ * Query format support with screen::is_format_supported and usage
+ * XXX.
+ */
+void *graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format );
+
+void graw_destroy_window( void *handle );
+
+#endif
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
new file mode 100644
index 00000000000..70ad215bfce
--- /dev/null
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -0,0 +1,407 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef _ST_API_H_
+#define _ST_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+
+/**
+ * \file API for communication between state trackers and state tracker
+ * managers.
+ *
+ * While both are state tackers, we use the term state tracker for rendering
+ * APIs such as OpenGL or OpenVG, and state tracker manager for window system
+ * APIs such as EGL or GLX in this file.
+ *
+ * This file defines an API to be implemented by both state trackers and state
+ * tracker managers.
+ */
+
+/**
+ * The entry points of the state trackers.
+ */
+#define ST_MODULE_OPENGL_SYMBOL "st_module_OpenGL"
+#define ST_MODULE_OPENGL_ES1_SYMBOL "st_module_OpenGL_ES1"
+#define ST_MODULE_OPENGL_ES2_SYMBOL "st_module_OpenGL_ES2"
+#define ST_MODULE_OPENVG_SYMBOL "st_module_OpenVG"
+
+/**
+ * The supported rendering API of a state tracker.
+ */
+enum st_api_type {
+ ST_API_OPENGL,
+ ST_API_OPENGL_ES1,
+ ST_API_OPENGL_ES2,
+ ST_API_OPENVG,
+
+ ST_API_COUNT
+};
+
+/**
+ * Used in st_context_iface->teximage.
+ */
+enum st_texture_type {
+ ST_TEXTURE_1D,
+ ST_TEXTURE_2D,
+ ST_TEXTURE_3D,
+ ST_TEXTURE_RECT,
+};
+
+/**
+ * Available attachments of framebuffer.
+ */
+enum st_attachment_type {
+ ST_ATTACHMENT_FRONT_LEFT,
+ ST_ATTACHMENT_BACK_LEFT,
+ ST_ATTACHMENT_FRONT_RIGHT,
+ ST_ATTACHMENT_BACK_RIGHT,
+ ST_ATTACHMENT_DEPTH_STENCIL,
+ ST_ATTACHMENT_ACCUM,
+ ST_ATTACHMENT_SAMPLE,
+
+ ST_ATTACHMENT_COUNT,
+ ST_ATTACHMENT_INVALID = -1
+};
+
+/* for buffer_mask in st_visual */
+#define ST_ATTACHMENT_FRONT_LEFT_MASK (1 << ST_ATTACHMENT_FRONT_LEFT)
+#define ST_ATTACHMENT_BACK_LEFT_MASK (1 << ST_ATTACHMENT_BACK_LEFT)
+#define ST_ATTACHMENT_FRONT_RIGHT_MASK (1 << ST_ATTACHMENT_FRONT_RIGHT)
+#define ST_ATTACHMENT_BACK_RIGHT_MASK (1 << ST_ATTACHMENT_BACK_RIGHT)
+#define ST_ATTACHMENT_DEPTH_STENCIL_MASK (1 << ST_ATTACHMENT_DEPTH_STENCIL)
+#define ST_ATTACHMENT_ACCUM_MASK (1 << ST_ATTACHMENT_ACCUM)
+#define ST_ATTACHMENT_SAMPLE_MASK (1 << ST_ATTACHMENT_SAMPLE)
+
+/**
+ * Enumerations of state tracker context resources.
+ */
+enum st_context_resource_type {
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER,
+ ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE,
+};
+
+/**
+ * The return type of st_api->get_proc_address.
+ */
+typedef void (*st_proc_t)(void);
+
+struct pipe_context;
+struct pipe_texture;
+struct pipe_fence_handle;
+
+/**
+ * Used in st_context_iface->get_resource_for_egl_image.
+ */
+struct st_context_resource
+{
+ /* these fields are filled by the caller */
+ enum st_context_resource_type type;
+ void *resource;
+
+ /* this is owned by the caller */
+ struct pipe_texture *texture;
+};
+
+/**
+ * Used in st_manager_iface->get_egl_image.
+ */
+struct st_egl_image
+{
+ /* these fields are filled by the caller */
+ struct st_context_iface *stctxi;
+ void *egl_image;
+
+ /* this is owned by the caller */
+ struct pipe_texture *texture;
+
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
+};
+
+/**
+ * Represent the visual of a framebuffer.
+ */
+struct st_visual
+{
+ /**
+ * Available buffers. Tested with ST_FRAMEBUFFER_*_MASK.
+ */
+ unsigned buffer_mask;
+
+ /**
+ * Buffer formats. The formats are always set even when the buffer is
+ * not available.
+ */
+ enum pipe_format color_format;
+ enum pipe_format depth_stencil_format;
+ enum pipe_format accum_format;
+ int samples;
+
+ /**
+ * Desired render buffer.
+ */
+ enum st_attachment_type render_buffer;
+};
+
+/**
+ * Represent a windowing system drawable.
+ *
+ * The framebuffer is implemented by the state tracker manager and
+ * used by the state trackers.
+ *
+ * Instead of the winsys pokeing into the API context to figure
+ * out what buffers that might be needed in the future by the API
+ * context, it calls into the framebuffer to get the textures.
+ *
+ * This structure along with the notify_invalid_framebuffer
+ * allows framebuffers to be shared between different threads
+ * but at the same make the API context free from thread
+ * syncronisation primitves, with the exception of a small
+ * atomic flag used for notification of framebuffer dirty status.
+ *
+ * The thread syncronisation is put inside the framebuffer
+ * and only called once the framebuffer has become dirty.
+ */
+struct st_framebuffer_iface
+{
+ /**
+ * Available for the state tracker manager to use.
+ */
+ void *st_manager_private;
+
+ /**
+ * The visual of a framebuffer.
+ */
+ const struct st_visual *visual;
+
+ /**
+ * Flush the front buffer.
+ *
+ * On some window systems, changes to the front buffers are not immediately
+ * visible. They need to be flushed.
+ *
+ * @att is one of the front buffer attachments.
+ */
+ boolean (*flush_front)(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt);
+
+ /**
+ * The state tracker asks for the textures it needs.
+ *
+ * It should try to only ask for attachments that it currently renders
+ * to, thus allowing the winsys to delay the allocation of textures not
+ * needed. For example front buffer attachments are not needed if you
+ * only do back buffer rendering.
+ *
+ * The implementor of this function needs to also ensure
+ * thread safty as this call might be done from multiple threads.
+ *
+ * The returned textures are owned by the caller. They should be
+ * unreferenced when no longer used. If this function is called multiple
+ * times with different sets of attachments, those buffers not included in
+ * the last call might be destroyed. This behavior might change in the
+ * future.
+ */
+ boolean (*validate)(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out);
+};
+
+/**
+ * Represent a rendering context.
+ *
+ * This entity is created from st_api and used by the state tracker manager.
+ */
+struct st_context_iface
+{
+ /**
+ * Available for the state tracker and the manager to use.
+ */
+ void *st_context_private;
+ void *st_manager_private;
+
+ /**
+ * Destroy the context.
+ */
+ void (*destroy)(struct st_context_iface *stctxi);
+
+ /**
+ * Invalidate the current textures that was taken from a framebuffer.
+ *
+ * The state tracker manager calls this function to let the rendering
+ * context know that it should update the textures it got from
+ * st_framebuffer_iface::validate. It should do so at the latest time possible.
+ * Possible right before sending triangles to the pipe context.
+ *
+ * For certain platforms this function might be called from a thread other
+ * than the thread that the context is currently bound in, and must
+ * therefore be thread safe. But it is the state tracker manager's
+ * responsibility to make sure that the framebuffer is bound to the context
+ * and the API context is current for the duration of this call.
+ *
+ * Thus reducing the sync primitive needed to a single atomic flag.
+ */
+ void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stfbi);
+
+ /**
+ * Flush all drawing from context to the pipe also flushes the pipe.
+ */
+ void (*flush)(struct st_context_iface *stctxi, unsigned flags,
+ struct pipe_fence_handle **fence);
+
+ /**
+ * Replace the texture image of a texture object at the specified level.
+ *
+ * This function is optional.
+ */
+ boolean (*teximage)(struct st_context_iface *stctxi, enum st_texture_type target,
+ int level, enum pipe_format internal_format,
+ struct pipe_texture *tex, boolean mipmap);
+
+ /**
+ * Used to implement glXCopyContext.
+ */
+ void (*copy)(struct st_context_iface *stctxi,
+ struct st_context_iface *stsrci, unsigned mask);
+
+ /**
+ * Look up and return the info of a resource for EGLImage.
+ *
+ * This function is optional.
+ */
+ boolean (*get_resource_for_egl_image)(struct st_context_iface *stctxi,
+ struct st_context_resource *stres);
+};
+
+
+/**
+ * Represent a state tracker manager.
+ *
+ * This interface is implemented by the state tracker manager. It corresponds
+ * to a "display" in the window system.
+ */
+struct st_manager
+{
+ struct pipe_screen *screen;
+
+ /**
+ * Look up and return the info of an EGLImage.
+ *
+ * This function is optional.
+ */
+ boolean (*get_egl_image)(struct st_manager *smapi,
+ struct st_egl_image *stimg);
+};
+
+/**
+ * Represent a rendering API such as OpenGL or OpenVG.
+ *
+ * Implemented by the state tracker and used by the state tracker manager.
+ */
+struct st_api
+{
+ /**
+ * Destroy the API.
+ */
+ void (*destroy)(struct st_api *stapi);
+
+ /**
+ * Return an API entry point.
+ *
+ * For GL this is the same as _glapi_get_proc_address.
+ */
+ st_proc_t (*get_proc_address)(struct st_api *stapi, const char *procname);
+
+ /**
+ * Return true if the visual is supported by the state tracker.
+ */
+ boolean (*is_visual_supported)(struct st_api *stapi,
+ const struct st_visual *visual);
+
+ /**
+ * Create a rendering context.
+ */
+ struct st_context_iface *(*create_context)(struct st_api *stapi,
+ struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *stsharei);
+
+ /**
+ * Bind the context to the calling thread with draw and read as drawables.
+ *
+ * The framebuffers might have different visuals than the context does.
+ */
+ boolean (*make_current)(struct st_api *stapi,
+ struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi);
+
+ /**
+ * Get the currently bound context in the calling thread.
+ */
+ struct st_context_iface *(*get_current)(struct st_api *stapi);
+};
+
+/**
+ * Represent a state tracker.
+ *
+ * This is the entry point of a state tracker.
+ */
+struct st_module
+{
+ enum st_api_type api;
+ struct st_api *(*create_api)(void);
+};
+
+/**
+ * Return true if the visual has the specified buffers.
+ */
+static INLINE boolean
+st_visual_have_buffers(const struct st_visual *visual, unsigned mask)
+{
+ return ((visual->buffer_mask & mask) == mask);
+}
+
+/* these symbols may need to be dynamically lookup up */
+extern PUBLIC const struct st_module st_module_OpenGL;
+extern PUBLIC const struct st_module st_module_OpenGL_ES1;
+extern PUBLIC const struct st_module st_module_OpenGL_ES2;
+extern PUBLIC const struct st_module st_module_OpenVG;
+
+#endif /* _ST_API_H_ */
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/include/state_tracker/sw_winsys.h
index ce11fa93041..a87650dc77d 100644
--- a/src/gallium/drivers/llvmpipe/lp_winsys.h
+++ b/src/gallium/include/state_tracker/sw_winsys.h
@@ -27,12 +27,12 @@
/**
* @file
- * llvmpipe public interface.
+ * Software rasterizer winsys.
*/
-#ifndef LP_WINSYS_H
-#define LP_WINSYS_H
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
#include "pipe/p_compiler.h" /* for boolean */
@@ -44,30 +44,33 @@ extern "C" {
#endif
+struct winsys_handle;
struct pipe_screen;
struct pipe_context;
+struct pipe_texture;
/**
* Opaque pointer.
*/
-struct llvmpipe_displaytarget;
+struct sw_displaytarget;
/**
- * This is the interface that llvmpipe expects any window system
+ * This is the interface that sw expects any window system
* hosting it to implement.
*
- * llvmpipe is for the most part a self sufficient driver. The only thing it
+ * sw is for the most part a self sufficient driver. The only thing it
* does not know is how to display a surface.
*/
-struct llvmpipe_winsys
+struct sw_winsys
{
void
- (*destroy)( struct llvmpipe_winsys *ws );
+ (*destroy)( struct sw_winsys *ws );
boolean
- (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
+ (*is_displaytarget_format_supported)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format );
/**
@@ -81,21 +84,42 @@ struct llvmpipe_winsys
* with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
* storage.
*/
- struct llvmpipe_displaytarget *
- (*displaytarget_create)( struct llvmpipe_winsys *ws,
+ struct sw_displaytarget *
+ (*displaytarget_create)( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride );
+ /**
+ * Used to implement texture_from_handle.
+ */
+ struct sw_displaytarget *
+ (*displaytarget_from_handle)( struct sw_winsys *ws,
+ const struct pipe_texture *templat,
+ struct winsys_handle *whandle,
+ unsigned *stride );
+
+ /**
+ * Used to implement texture_get_handle.
+ */
+ boolean
+ (*displaytarget_get_handle)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle );
+
+ /**
+ * \param flags bitmask of PIPE_BUFFER_USAGE_x flags
+ */
void *
- (*displaytarget_map)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+ (*displaytarget_map)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags );
void
- (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
+ (*displaytarget_unmap)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt );
/**
* @sa pipe_screen:flush_frontbuffer.
@@ -103,23 +127,19 @@ struct llvmpipe_winsys
* This call will likely become asynchronous eventually.
*/
void
- (*displaytarget_display)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+ (*displaytarget_display)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
void *context_private );
void
- (*displaytarget_destroy)( struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt );
+ (*displaytarget_destroy)( struct sw_winsys *ws,
+ struct sw_displaytarget *dt );
};
-struct pipe_screen *
-llvmpipe_create_screen( struct llvmpipe_winsys * );
-
-
#ifdef __cplusplus
}
#endif
-#endif /* LP_WINSYS_H */
+#endif /* SW_WINSYS_H */
diff --git a/src/gallium/include/state_tracker/xlib_sw_winsys.h b/src/gallium/include/state_tracker/xlib_sw_winsys.h
new file mode 100644
index 00000000000..f22c22bb620
--- /dev/null
+++ b/src/gallium/include/state_tracker/xlib_sw_winsys.h
@@ -0,0 +1,29 @@
+#ifndef XLIB_SW_WINSYS_H
+#define XLIB_SW_WINSYS_H
+
+#include "state_tracker/sw_winsys.h"
+#include <X11/Xlib.h>
+
+
+struct pipe_screen;
+struct pipe_surface;
+
+/* This is what the xlib software winsys expects to find in the
+ * "private" field of flush_frontbuffers().
+ *
+ * Xlib-based state trackers somehow need to know this.
+ */
+struct xlib_drawable {
+ Visual *visual;
+ int depth;
+ Drawable drawable;
+};
+
+
+/* This is the public interface to the ws/xlib module. Why isn't it
+ * being defined in that directory?
+ */
+struct sw_winsys *xlib_create_sw_winsys( Display *display );
+
+
+#endif
diff --git a/src/gallium/state_trackers/dri/Makefile b/src/gallium/state_trackers/dri/Makefile
index ef8f19709ab..72e70577b3d 100644
--- a/src/gallium/state_trackers/dri/Makefile
+++ b/src/gallium/state_trackers/dri/Makefile
@@ -1,28 +1,12 @@
+# src/gallium/state_trackers/dri/Makefile
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = dridrm
+SUBDIRS = drm sw
-LIBRARY_INCLUDES = \
- -I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/drivers/dri/common \
- -I$(TOP)/src/mesa/main \
- $(shell pkg-config --cflags-only-I libdrm)
-
-
-C_SOURCES = \
- dri_context.c \
- dri_screen.c \
- dri_drawable.c \
- dri_extensions.c
-
-# $(TOP)/src/mesa/drivers/dri/common/utils.c \
- $(TOP)/src/mesa/drivers/dri/common/vblank.c \
- $(TOP)/src/mesa/drivers/dri/common/dri_util.c \
- $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \
- $(TOP)/src/mesa/drivers/common/driverfuncs.c \
- $(TOP)/src/mesa/drivers/dri/common/texmem.c \
- $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
-
-include ../../Makefile.template
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript
index ce2c2735974..aba60fb8c5b 100644
--- a/src/gallium/state_trackers/dri/SConscript
+++ b/src/gallium/state_trackers/dri/SConscript
@@ -1,23 +1,6 @@
-#######################################################################
-# SConscript for dri state_tracker
-
Import('*')
-if env['dri']:
-
- env = env.Clone()
-
- env.Append(CPPPATH = [
- '#/src/mesa',
- '#/src/mesa/drivers/dri/common',
- ])
-
- st_dri = env.ConvenienceLibrary(
- target = 'st_dri',
- source = [ 'dri_context.c',
- 'dri_drawable.c',
- 'dri_extensions.c',
- 'dri_screen.c',
- ]
- )
- Export('st_dri')
+SConscript([
+ 'sw/SConscript',
+ 'drm/SConscript',
+])
diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.c b/src/gallium/state_trackers/dri/common/dri1_helper.c
new file mode 100644
index 00000000000..7eeb868d422
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri1_helper.c
@@ -0,0 +1,129 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Management of pipe objects (surface / pipe / fences) used by DRI1 and DRISW.
+ *
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri1_helper.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (draw->cur_fences >= draw->desired_fences) {
+ screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
+ screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
+ --draw->cur_fences;
+ draw->tail &= DRI_SWAP_FENCES_MASK;
+ }
+ return fence;
+}
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+
+ if (!fence)
+ return;
+
+ if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
+ draw->cur_fences++;
+ screen->fence_reference(screen, &draw->swap_fences[draw->head++],
+ fence);
+ draw->head &= DRI_SWAP_FENCES_MASK;
+ }
+}
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable)
+{
+ struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence;
+
+ while (drawable->cur_fences) {
+ fence = dri1_swap_fences_pop_front(drawable);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+}
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex)
+{
+ struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_surface *psurf = drawable->dri1_surface;
+
+ if (!psurf || psurf->texture != ptex) {
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+
+ drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen,
+ ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+
+ psurf = drawable->dri1_surface;
+ }
+
+ return psurf;
+}
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable)
+{
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+}
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen)
+{
+ struct pipe_context *pipe = screen->dri1_pipe;
+
+ if (!pipe) {
+ screen->dri1_pipe =
+ screen->pipe_screen->context_create(screen->pipe_screen, NULL);
+ pipe = screen->dri1_pipe;
+ }
+
+ return pipe;
+}
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen)
+{
+ if (screen->dri1_pipe)
+ screen->dri1_pipe->destroy(screen->dri1_pipe);
+}
diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.h b/src/gallium/state_trackers/dri/common/dri1_helper.h
new file mode 100644
index 00000000000..3254b7ff872
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri1_helper.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#ifndef DRI1_HELPER_H
+#define DRI1_HELPER_H
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw);
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence);
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable);
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex);
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable);
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen);
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen);
+
+#endif /* DRI1_HELPER_H */
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index 908cef454e9..f14f4130bf4 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -29,27 +29,36 @@
* Author: Jakob Bornecrantz <[email protected]>
*/
-#include "dri_screen.h"
+#include "utils.h"
+#include "dri_screen.h"
#include "dri_drawable.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
+#include "dri_context.h"
+#include "dri_st_api.h"
+
#include "pipe/p_context.h"
+#include "state_tracker/st_context.h"
-#include "dri_context.h"
+static void
+dri_init_extensions(struct dri_context *ctx)
+{
+ struct st_context *st = (struct st_context *) ctx->st;
-#include "util/u_memory.h"
+ /* New extensions should be added in mesa/state_tracker/st_extensions.c
+ * and not in this file. */
+ driInitExtensions(st->ctx, NULL, GL_FALSE);
+}
GLboolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * cPriv, void *sharedContextPrivate)
{
+ struct st_api *stapi = dri_get_st_api();
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
- struct st_context *st_share = NULL;
+ struct st_context_iface *st_share = NULL;
+ struct st_visual stvis;
if (sharedContextPrivate) {
st_share = ((struct dri_context *)sharedContextPrivate)->st;
@@ -63,21 +72,15 @@ dri_create_context(const __GLcontextModes * visual,
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->lock = screen->drmLock;
- ctx->d_stamp = -1;
- ctx->r_stamp = -1;
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
- ctx );
-
- if (ctx->pipe == NULL)
- goto fail;
-
- ctx->st = st_create_context(ctx->pipe, visual, st_share);
+ dri_fill_st_visual(&stvis, screen, visual);
+ ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
if (ctx->st == NULL)
goto fail;
+ ctx->st->st_manager_private = (void *) ctx;
dri_init_extensions(ctx);
@@ -85,10 +88,7 @@ dri_create_context(const __GLcontextModes * visual,
fail:
if (ctx && ctx->st)
- st_destroy_context(ctx->st);
-
- if (ctx && ctx->pipe)
- ctx->pipe->destroy(ctx->pipe);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
return FALSE;
@@ -110,11 +110,8 @@ dri_destroy_context(__DRIcontext * cPriv)
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
- st_flush(ctx->st, 0, NULL);
-
- /* Also frees ctx->pipe?
- */
- st_destroy_context(ctx->st);
+ ctx->st->flush(ctx->st, 0, NULL);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
}
@@ -122,14 +119,16 @@ dri_destroy_context(__DRIcontext * cPriv)
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
if (--ctx->bind_count == 0) {
- if (ctx->st && ctx->st == st_get_current()) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- st_make_current(NULL, NULL, NULL);
- }
+ if (ctx->st == stapi->get_current(stapi)) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ stapi->make_current(stapi, NULL, NULL, NULL);
+ }
}
}
@@ -141,77 +140,47 @@ dri_make_current(__DRIcontext * cPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
- struct st_context *old_st = st_get_current();
+ struct st_context_iface *old_st;
+ old_st = stapi->get_current(stapi);
if (old_st && old_st != ctx->st)
- st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
++ctx->bind_count;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
- ctx->d_stamp = driDrawPriv->lastStamp - 1;
+ draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
- ctx->r_stamp = driReadPriv->lastStamp - 1;
+ read->texture_stamp = driReadPriv->lastStamp - 1;
}
- st_make_current(ctx->st, draw->stfb, read->stfb);
-
- if (__dri1_api_hooks) {
- dri1_update_drawables(ctx, draw, read);
- } else {
- dri_update_buffer(ctx->pipe->screen,
- ctx->pipe->priv);
- }
- } else {
- st_make_current(NULL, NULL, NULL);
+ stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
+ }
+ else {
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
}
-static void
-st_dri_lock(struct pipe_context *pipe)
+struct dri_context *
+dri_get_current(void)
{
- dri_lock((struct dri_context *)pipe->priv);
-}
+ struct st_api *stapi = dri_get_st_api();
+ struct st_context_iface *st;
-static void
-st_dri_unlock(struct pipe_context *pipe)
-{
- dri_unlock((struct dri_context *)pipe->priv);
-}
+ st = stapi->get_current(stapi);
-static boolean
-st_dri_is_locked(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->isLocked;
+ return (struct dri_context *) (st) ? st->st_manager_private : NULL;
}
-static boolean
-st_dri_lost_lock(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->wsLostLock;
-}
-
-static void
-st_dri_clear_lost_lock(struct pipe_context *pipe)
-{
- ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
-}
-
-struct dri1_api_lock_funcs dri1_lf = {
- .lock = st_dri_lock,
- .unlock = st_dri_unlock,
- .is_locked = st_dri_is_locked,
- .is_lock_lost = st_dri_lost_lock,
- .clear_lost_lock = st_dri_clear_lost_lock
-};
-
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 13f497462f7..594618874a4 100644
--- a/src/gallium/state_trackers/dri/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -33,8 +33,7 @@
#define DRI_CONTEXT_H
#include "pipe/p_compiler.h"
-#include "drm.h"
-#include "dri_util.h"
+#include "dri_wrapper.h"
struct pipe_context;
struct pipe_fence;
@@ -51,9 +50,6 @@ struct dri_context
driOptionCache optionCache;
- unsigned int d_stamp;
- unsigned int r_stamp;
-
drmLock *lock;
boolean isLocked;
boolean stLostLock;
@@ -62,8 +58,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
- struct st_context *st;
- struct pipe_context *pipe;
+ struct st_context_iface *st;
};
static INLINE struct dri_context *
@@ -72,33 +67,9 @@ dri_context(__DRIcontext * driContextPriv)
return (struct dri_context *)driContextPriv->driverPrivate;
}
-static INLINE void
-dri_lock(struct dri_context *ctx)
-{
- drm_context_t hw_context = ctx->cPriv->hHWContext;
- char ret = 0;
-
- DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
- if (ret) {
- drmGetLock(ctx->sPriv->fd, hw_context, 0);
- ctx->stLostLock = TRUE;
- ctx->wsLostLock = TRUE;
- }
- ctx->isLocked = TRUE;
-}
-
-static INLINE void
-dri_unlock(struct dri_context *ctx)
-{
- ctx->isLocked = FALSE;
- DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
-}
-
/***********************************************************************
* dri_context.c
*/
-extern struct dri1_api_lock_funcs dri1_lf;
-
void dri_destroy_context(__DRIcontext * driContextPriv);
boolean dri_unbind_context(__DRIcontext * driContextPriv);
@@ -108,16 +79,14 @@ dri_make_current(__DRIcontext * driContextPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv);
+struct dri_context *
+dri_get_current(void);
+
boolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * driContextPriv,
void *sharedContextPrivate);
-/***********************************************************************
- * dri_extensions.c
- */
-void dri_init_extensions(struct dri_context *ctx);
-
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
new file mode 100644
index 00000000000..75b4cc56289
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -0,0 +1,94 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+boolean
+dri_create_buffer(__DRIscreen * sPriv,
+ __DRIdrawable * dPriv,
+ const __GLcontextModes * visual, boolean isPixmap)
+{
+ struct dri_screen *screen = sPriv->private;
+ struct dri_drawable *drawable = NULL;
+
+ if (isPixmap)
+ goto fail; /* not implemented */
+
+ drawable = CALLOC_STRUCT(dri_drawable);
+ if (drawable == NULL)
+ goto fail;
+
+ dri_fill_st_visual(&drawable->stvis, screen, visual);
+ drawable->stfb = dri_create_st_framebuffer(drawable);
+ if (drawable->stfb == NULL)
+ goto fail;
+
+ drawable->sPriv = sPriv;
+ drawable->dPriv = dPriv;
+ dPriv->driverPrivate = (void *)drawable;
+
+ drawable->desired_fences = 2;
+
+ return GL_TRUE;
+fail:
+ FREE(drawable);
+ return GL_FALSE;
+}
+
+void
+dri_destroy_buffer(__DRIdrawable * dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+
+ dri1_swap_fences_clear(drawable);
+
+ dri1_destroy_pipe_surface(drawable);
+
+ dri_destroy_st_framebuffer(drawable->stfb);
+
+ drawable->desired_fences = 0;
+
+ FREE(drawable);
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 8bc59cb4c3d..98abeb9ec05 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -29,6 +29,8 @@
#define DRI_DRAWABLE_H
#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "state_tracker/st_api.h"
struct pipe_surface;
struct pipe_fence_handle;
@@ -44,26 +46,26 @@ struct dri_drawable
__DRIdrawable *dPriv;
__DRIscreen *sPriv;
- unsigned attachments[8];
- unsigned num_attachments;
-
- boolean is_pixmap;
+ /* gallium */
+ struct st_framebuffer_iface *stfb;
+ struct st_visual stvis;
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
unsigned old_h;
- /* gallium */
- struct st_framebuffer *stfb;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+ unsigned int texture_mask, texture_stamp;
+
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
unsigned int cur_fences;
- enum pipe_format color_format;
- enum pipe_format depth_stencil_format;
+ /* used only by DRI1 */
+ struct pipe_surface *dri1_surface;
};
static INLINE struct dri_drawable *
@@ -80,35 +82,8 @@ dri_create_buffer(__DRIscreen * sPriv,
__DRIdrawable * dPriv,
const __GLcontextModes * visual, boolean isPixmap);
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private);
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
-
-void dri_swap_buffers(__DRIdrawable * dPriv);
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
-
-void dri_get_buffers(__DRIdrawable * dPriv);
-
void dri_destroy_buffer(__DRIdrawable * dPriv);
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint glx_texture_format, __DRIdrawable *dPriv);
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv);
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read);
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 7ccad8f5dd6..821c1dea626 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -30,17 +30,26 @@
*/
#include "utils.h"
+#ifndef __NOT_HAVE_DRM_H
#include "vblank.h"
+#endif
#include "xmlpool.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
-
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_format.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
#include "util/u_debug.h"
@@ -49,41 +58,11 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
- /*DRI_CONF_FORCE_S3TC_ENABLE(false) */
+/* DRI_CONF_FORCE_S3TC_ENABLE(false) */
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
- const uint __driNConfigOptions = 3;
-
-static const __DRItexBufferExtension dri2TexBufferExtension = {
- { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
- dri2_set_tex_buffer,
- dri2_set_tex_buffer2,
-};
-
-static void
-dri2_flush_drawable(__DRIdrawable *draw)
-{
-}
-
-static const __DRI2flushExtension dri2FlushExtension = {
- { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
- dri2_flush_drawable,
- dri2InvalidateDrawable,
-};
-
- static const __DRIextension *dri_screen_extensions[] = {
- &driReadDrawableExtension,
- &driCopySubBufferExtension.base,
- &driSwapControlExtension.base,
- &driFrameTrackingExtension.base,
- &driMediaStreamCounterExtension.base,
- &dri2TexBufferExtension.base,
- &dri2FlushExtension.base,
- NULL
- };
-
-struct dri1_api *__dri1_api_hooks = NULL;
+static const uint __driNConfigOptions = 3;
static const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen,
@@ -135,9 +114,7 @@ dri_fill_in_modes(struct dri_screen *screen,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
- if (screen->sPriv->dri2.loader &&
- (screen->sPriv->dri2.loader->base.version > 2) &&
- (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+ if (dri_with_format(screen->sPriv)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
@@ -229,6 +206,70 @@ dri_fill_in_modes(struct dri_screen *screen,
}
/**
+ * Roughly the converse of dri_fill_in_modes.
+ */
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode)
+{
+ memset(stvis, 0, sizeof(*stvis));
+
+ stvis->samples = mode->samples;
+ stvis->render_buffer = ST_ATTACHMENT_INVALID;
+
+ if (mode->redBits == 8) {
+ if (mode->alphaBits == 8)
+ stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ else
+ stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ } else {
+ stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
+ }
+
+ switch (mode->depthBits) {
+ default:
+ case 0:
+ stvis->depth_stencil_format = PIPE_FORMAT_NONE;
+ break;
+ case 16:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
+ break;
+ case 24:
+ if (mode->stencilBits == 0) {
+ stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
+ PIPE_FORMAT_Z24X8_UNORM:
+ PIPE_FORMAT_X8Z24_UNORM;
+ } else {
+ stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
+ PIPE_FORMAT_Z24S8_UNORM:
+ PIPE_FORMAT_S8Z24_UNORM;
+ }
+ break;
+ case 32:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
+ break;
+ }
+
+ stvis->accum_format = (mode->haveAccumBuffer) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ if (mode->haveDepthBuffer || mode->haveStencilBuffer)
+ stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
+ /* let the state tracker allocate the accum buffer */
+}
+
+#ifndef __NOT_HAVE_DRM_H
+
+/**
* Get information about previous buffer swaps.
*/
static int
@@ -240,164 +281,101 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
return 0;
}
-static INLINE void
-dri_copy_version(struct dri1_api_version *dst,
- const struct __DRIversionRec *src)
-{
- dst->major = src->major;
- dst->minor = src->minor;
- dst->patch_level = src->patch;
-}
+#endif
-static const __DRIconfig **
-dri_init_screen(__DRIscreen * sPriv)
+static void
+dri_destroy_option_cache(struct dri_screen * screen)
{
- struct dri_screen *screen;
- const __DRIconfig **configs;
- struct dri1_create_screen_arg arg;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- return NULL;
+ int i;
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
-
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
-
- arg.base.mode = DRM_CREATE_DRI1;
- arg.lf = &dri1_lf;
- arg.ddx_info = sPriv->pDevPriv;
- arg.ddx_info_size = sPriv->devPrivSize;
- arg.sarea = sPriv->pSAREA;
- dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
- dri_copy_version(&arg.dri_version, &sPriv->dri_version);
- dri_copy_version(&arg.drm_version, &sPriv->drm_version);
- arg.api = NULL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
-
- if (!screen->pipe_screen || !arg.api) {
- debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
- goto out_no_screen;
+ for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
+ FREE(screen->optionCache.info[i].name);
+ FREE(screen->optionCache.info[i].ranges);
}
- __dri1_api_hooks = arg.api;
-
- screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
-
- /**
- * FIXME: If the driver supports format conversion swapbuffer blits, we might
- * want to support other color bit depths than the server is currently
- * using.
- */
-
- configs = dri_fill_in_modes(screen, sPriv->fbBPP);
- if (!configs)
- goto out_no_configs;
-
- return configs;
- out_no_configs:
- screen->pipe_screen->destroy(screen->pipe_screen);
- out_no_screen:
- FREE(screen);
- return NULL;
+ FREE(screen->optionCache.info);
+ FREE(screen->optionCache.values);
}
-/**
- * This is the driver specific part of the createNewScreen entry point.
- *
- * Returns the __GLcontextModes supported by this driver.
- */
-static const __DRIconfig **
-dri_init_screen2(__DRIscreen * sPriv)
+void
+dri_destroy_screen_helper(struct dri_screen * screen)
{
- struct dri_screen *screen;
- struct drm_create_screen_arg arg;
- const __DRIdri2LoaderExtension *dri2_ext =
- sPriv->dri2.loader;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- goto fail;
-
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
- arg.mode = DRM_CREATE_NORMAL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg);
- if (!screen->pipe_screen) {
- debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
- goto fail;
- }
+ dri1_destroy_pipe_context(screen);
- /* We need to hook in here */
- screen->pipe_screen->update_buffer = dri_update_buffer;
- screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
-
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
+ if (screen->smapi)
+ dri_destroy_st_manager(screen->smapi);
- screen->auto_fake_front = dri2_ext->base.version >= 3 &&
- dri2_ext->getBuffersWithFormat != NULL;
+ if (screen->pipe_screen)
+ screen->pipe_screen->destroy(screen->pipe_screen);
- return dri_fill_in_modes(screen, 32);
- fail:
- return NULL;
+ dri_destroy_option_cache(screen);
}
static void
dri_destroy_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
- int i;
-
- screen->pipe_screen->destroy(screen->pipe_screen);
-
- for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
- FREE(screen->optionCache.info[i].name);
- FREE(screen->optionCache.info[i].ranges);
- }
- FREE(screen->optionCache.info);
- FREE(screen->optionCache.values);
+ dri_destroy_screen_helper(screen);
FREE(screen);
sPriv->private = NULL;
+ sPriv->extensions = NULL;
}
-PUBLIC const struct __DriverAPIRec driDriverAPI = {
- .InitScreen = dri_init_screen,
+const __DRIconfig **
+dri_init_screen_helper(struct dri_screen *screen,
+ struct drm_create_screen_arg *arg,
+ unsigned pixel_bits)
+{
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, arg);
+ if (!screen->pipe_screen) {
+ debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
+ return NULL;
+ }
+
+ screen->smapi = dri_create_st_manager(screen);
+ if (!screen->smapi)
+ return NULL;
+
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ return dri_fill_in_modes(screen, pixel_bits);
+}
+
+/**
+ * DRI driver virtual function table.
+ *
+ * DRI versions differ in their implementation of init_screen and swap_buffers.
+ */
+const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
- .SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+
+#ifndef __NOT_HAVE_DRM_H
+
.GetSwapInfo = dri_get_swap_info,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
- .CopySubBuffer = dri_copy_sub_buffer,
- .InitScreen = dri_init_screen,
- .InitScreen2 = dri_init_screen2,
-};
+ .InitScreen2 = dri2_init_screen,
+
+ .InitScreen = dri1_init_screen,
+ .SwapBuffers = dri1_swap_buffers,
+ .CopySubBuffer = dri1_copy_sub_buffer,
+
+#else
+
+ .InitScreen = drisw_init_screen,
+ .SwapBuffers = drisw_swap_buffers,
+
+#endif
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
- &driCoreExtension.base,
- &driLegacyExtension.base,
- &driDRI2Extension.base,
- NULL
};
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 75a0ee4250e..e77bce17ae9 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -32,12 +32,14 @@
#ifndef DRI_SCREEN_H
#define DRI_SCREEN_H
-#include "dri_util.h"
+#include "dri_wrapper.h"
#include "xmlconfig.h"
#include "pipe/p_compiler.h"
-
-#include "state_tracker/dri1_api.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/st_api.h"
+#include "state_tracker/drm_api.h"
struct dri_screen
{
@@ -60,6 +62,11 @@ struct dri_screen
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
boolean auto_fake_front;
+
+ struct st_manager *smapi;
+
+ /* used only by DRI1 */
+ struct pipe_context *dri1_pipe;
};
/** cast wrapper */
@@ -69,11 +76,39 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->private;
}
-/***********************************************************************
- * dri_screen.c
- */
+#ifndef __NOT_HAVE_DRM_H
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ const __DRIdri2LoaderExtension *loader = sPriv->dri2.loader;
+
+ return loader
+ && (loader->base.version >= 3)
+ && (loader->getBuffersWithFormat != NULL);
+}
+
+#else
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ return TRUE;
+}
+
+#endif
+
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode);
+
+const __DRIconfig **
+dri_init_screen_helper(struct dri_screen *screen,
+ struct drm_create_screen_arg *arg,
+ unsigned pixel_bits);
-extern struct dri1_api *__dri1_api_hooks;
+void
+dri_destroy_screen_helper(struct dri_screen * screen);
#endif
diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.c b/src/gallium/state_trackers/dri/common/dri_st_api.c
new file mode 100644
index 00000000000..7ba7ec383d8
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_st_api.c
@@ -0,0 +1,263 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/st_manager.h" /* for st_manager_create_api */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+static boolean
+dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ unsigned statt_mask, new_mask;
+ boolean new_stamp;
+ int i;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= (1 << statts[i]);
+
+ /* record newly allocated textures */
+ new_mask = (statt_mask & ~drawable->texture_mask);
+
+ /*
+ * dPriv->pStamp is the server stamp. It should be accessed with a lock, at
+ * least for DRI1. dPriv->lastStamp is the client stamp. It has the value
+ * of the server stamp when last checked.
+ */
+ new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp);
+
+ if (new_stamp || new_mask) {
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_allocate_textures(drawable, statt_mask);
+ }
+ else {
+ dri2_allocate_textures(drawable, statts, count);
+ }
+#else
+ if (new_stamp)
+ drisw_update_drawable_info(drawable);
+
+ drisw_allocate_textures(drawable, statt_mask);
+#endif
+
+ /* add existing textures */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->textures[i])
+ statt_mask |= (1 << i);
+ }
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp;
+ drawable->texture_mask = statt_mask;
+ }
+
+ if (!out)
+ return TRUE;
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], drawable->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_flush_frontbuffer(drawable, statt);
+ }
+ else {
+ dri2_flush_frontbuffer(drawable, statt);
+ }
+#else
+ drisw_flush_frontbuffer(drawable, statt);
+#endif
+
+ return TRUE;
+}
+
+/**
+ * Create a framebuffer from the given drawable.
+ */
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable)
+{
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (stfbi) {
+ stfbi->visual = &drawable->stvis;
+ stfbi->flush_front = dri_st_framebuffer_flush_front;
+ stfbi->validate = dri_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) drawable;
+ }
+
+ return stfbi;
+}
+
+/**
+ * Destroy a framebuffer.
+ */
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ int i;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ FREE(stfbi);
+}
+
+/**
+ * Validate the texture at an attachment. Allocate the texture if it does not
+ * exist.
+ */
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
+ unsigned i, count = 0;
+
+ /* check if buffer already exists */
+ if (drawable->texture_mask & (1 << statt))
+ return;
+
+ /* make sure DRI2 does not destroy existing buffers */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->texture_mask & (1 << i)) {
+ statts[count++] = i;
+ }
+ }
+ statts[count++] = statt;
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
+
+ stfbi->validate(stfbi, statts, count, NULL);
+}
+
+/**
+ * Reference counted st_api.
+ */
+static struct {
+ int32_t refcnt;
+ struct st_api *stapi;
+} dri_st_api;
+
+/**
+ * Add a reference to the st_api of the state tracker.
+ */
+static void
+_dri_get_st_api(void)
+{
+ p_atomic_inc(&dri_st_api.refcnt);
+ if (p_atomic_read(&dri_st_api.refcnt) == 1)
+ dri_st_api.stapi = st_manager_create_api();
+}
+
+/**
+ * Remove a reference to the st_api of the state tracker.
+ */
+static void
+_dri_put_st_api(void)
+{
+ struct st_api *stapi = dri_st_api.stapi;
+
+ if (p_atomic_dec_zero(&dri_st_api.refcnt)) {
+ stapi->destroy(dri_st_api.stapi);
+ dri_st_api.stapi = NULL;
+ }
+}
+
+/**
+ * Create a state tracker manager from the given screen.
+ */
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen)
+{
+ struct st_manager *smapi;
+
+ smapi = CALLOC_STRUCT(st_manager);
+ if (smapi) {
+ smapi->screen = screen->pipe_screen;
+ _dri_get_st_api();
+ }
+
+ return smapi;
+}
+
+/**
+ * Destroy a state tracker manager.
+ */
+void
+dri_destroy_st_manager(struct st_manager *smapi)
+{
+ _dri_put_st_api();
+ FREE(smapi);
+}
+
+/**
+ * Return the st_api of OpenGL state tracker.
+ */
+struct st_api *
+dri_get_st_api(void)
+{
+ assert(dri_st_api.stapi);
+ return dri_st_api.stapi;
+}
diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.h b/src/gallium/state_trackers/dri/common/dri_st_api.h
new file mode 100644
index 00000000000..99a217bfa79
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_st_api.h
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef _DRI_ST_API_H_
+#define _DRI_ST_API_H_
+
+#include "state_tracker/st_api.h"
+
+struct dri_screen;
+struct dri_drawable;
+
+struct st_api *
+dri_get_st_api(void);
+
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen);
+
+void
+dri_destroy_st_manager(struct st_manager *smapi);
+
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable);
+
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt);
+
+#endif /* _DRI_ST_API_H_ */
diff --git a/src/gallium/state_trackers/dri/common/dri_wrapper.h b/src/gallium/state_trackers/dri/common/dri_wrapper.h
new file mode 100644
index 00000000000..141ba02706a
--- /dev/null
+++ b/src/gallium/state_trackers/dri/common/dri_wrapper.h
@@ -0,0 +1,10 @@
+#ifndef DRI_WRAPPER_H
+#define DRI_WRAPPER_H
+
+#ifndef __NOT_HAVE_DRM_H
+#include "dri_util.h"
+#else
+#include "drisw_util.h"
+#endif
+
+#endif
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
deleted file mode 100644
index 173f4041c8c..00000000000
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009, VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-/*
- * Author: Keith Whitwell <[email protected]>
- * Author: Jakob Bornecrantz <[email protected]>
- */
-
-#include "dri_screen.h"
-#include "dri_context.h"
-#include "dri_drawable.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "main/mtypes.h"
-#include "main/renderbuffer.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_rect.h"
-#include "util/u_inlines.h"
-
-static struct pipe_surface *
-dri_surface_from_handle(struct drm_api *api,
- struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width, unsigned height, unsigned pitch)
-{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth0 = 1;
- templat.format = format;
- templat.width0 = width;
- templat.height0 = height;
-
- texture = api->texture_from_shared_handle(api, screen, &templat,
- "dri2 buffer", pitch, handle);
-
- if (!texture) {
- debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
- return NULL;
- }
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
-}
-
-/**
- * Pixmaps have will have the same name of fake front and front.
- */
-static boolean
-dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
-{
- boolean found = FALSE;
- boolean is_pixmap = FALSE;
- unsigned name;
- int i;
-
- for (i = 0; i < count; i++) {
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- if (found) {
- is_pixmap = buffers[i].name == name;
- } else {
- name = buffers[i].name;
- found = TRUE;
- }
- default:
- continue;
- }
- }
-
- return is_pixmap;
-}
-
-/**
- * This will be called a drawable is known to have been resized.
- */
-void
-dri_get_buffers(__DRIdrawable * dPriv)
-{
-
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *surface = NULL;
- struct dri_screen *st_screen = dri_screen(drawable->sPriv);
- struct pipe_screen *screen = st_screen->pipe_screen;
- __DRIbuffer *buffers = NULL;
- __DRIscreen *dri_screen = drawable->sPriv;
- __DRIdrawable *dri_drawable = drawable->dPriv;
- struct drm_api *api = st_screen->api;
- boolean have_depth = FALSE;
- int i, count;
-
- if ((dri_screen->dri2.loader
- && (dri_screen->dri2.loader->base.version > 2)
- && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) {
- buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
- (dri_drawable, &dri_drawable->w, &dri_drawable->h,
- drawable->attachments, drawable->num_attachments,
- &count, dri_drawable->loaderPrivate);
- } else {
- assert(dri_screen->dri2.loader);
- buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
- &dri_drawable->w,
- &dri_drawable->h,
- drawable->attachments,
- drawable->
- num_attachments, &count,
- dri_drawable->
- loaderPrivate);
- }
-
- if (buffers == NULL) {
- return;
- }
-
- /* set one cliprect to cover the whole dri_drawable */
- dri_drawable->x = 0;
- dri_drawable->y = 0;
- dri_drawable->backX = 0;
- dri_drawable->backY = 0;
- dri_drawable->numClipRects = 1;
- dri_drawable->pClipRects[0].x1 = 0;
- dri_drawable->pClipRects[0].y1 = 0;
- dri_drawable->pClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pClipRects[0].y2 = dri_drawable->h;
- dri_drawable->numBackClipRects = 1;
- dri_drawable->pBackClipRects[0].x1 = 0;
- dri_drawable->pBackClipRects[0].y1 = 0;
- dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
-
- if (drawable->old_num == count &&
- drawable->old_w == dri_drawable->w &&
- drawable->old_h == dri_drawable->h &&
- memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
- return;
- } else {
- drawable->old_num = count;
- drawable->old_w = dri_drawable->w;
- drawable->old_h = dri_drawable->h;
- memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
- }
-
- drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
-
- for (i = 0; i < count; i++) {
- enum pipe_format format = 0;
- int index = 0;
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- if (!st_screen->auto_fake_front)
- continue;
- /* fallthrough */
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_BACK_LEFT:
- index = ST_SURFACE_BACK_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- index = ST_SURFACE_DEPTH;
- format = drawable->depth_stencil_format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- if (index == ST_SURFACE_DEPTH) {
- if (have_depth)
- continue;
- else
- have_depth = TRUE;
- }
-
- surface = dri_surface_from_handle(api,
- screen,
- buffers[i].name,
- format,
- dri_drawable->w,
- dri_drawable->h, buffers[i].pitch);
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- case __DRI_BUFFER_BACK_LEFT:
- drawable->color_format = surface->format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- drawable->depth_stencil_format = surface->format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- st_set_framebuffer_surface(drawable->stfb, index, surface);
- pipe_surface_reference(&surface, NULL);
- }
- /* this needed, or else the state tracker fails to pick the new buffers */
- st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
-}
-
-/**
- * These are used for GLX_EXT_texture_from_pixmap
- */
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint format, __DRIdrawable *dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *ps;
-
- if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
- struct gl_renderbuffer *rb =
- st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
- _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
- }
-
- dri_get_buffers(drawable->dPriv);
- st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
-
- if (!ps)
- return;
-
- st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
- ST_TEXTURE_RECT, 0, drawable->color_format);
-}
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv)
-{
- dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
-}
-
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
-
- if (ctx->d_stamp == *ctx->dPriv->pStamp &&
- ctx->r_stamp == *ctx->rPriv->pStamp)
- return;
-
- ctx->d_stamp = *ctx->dPriv->pStamp;
- ctx->r_stamp = *ctx->rPriv->pStamp;
-
- /* Ask the X server for new renderbuffers. */
- dri_get_buffers(ctx->dPriv);
- if (ctx->dPriv != ctx->rPriv)
- dri_get_buffers(ctx->rPriv);
-
-}
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
- __DRIdrawable *dri_drawable = ctx->dPriv;
- __DRIscreen *dri_screen = ctx->sPriv;
-
- /* XXX Does this function get called with DRI1? */
-
- if (ctx->dPriv == NULL) {
- debug_printf("%s: no drawable bound to context\n", __func__);
- return;
- }
-
-#if 0
- /* TODO if rendering to pixmaps is slow enable this code. */
- if (drawable->is_pixmap)
- return;
-#else
- (void)drawable;
-#endif
-
- (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
- dri_drawable->loaderPrivate);
-}
-
-/**
- * This is called when we need to set up GL rendering to a new X window.
- */
-boolean
-dri_create_buffer(__DRIscreen * sPriv,
- __DRIdrawable * dPriv,
- const __GLcontextModes * visual, boolean isPixmap)
-{
- struct dri_screen *screen = sPriv->private;
- struct dri_drawable *drawable = NULL;
- int i;
-
- if (isPixmap)
- goto fail; /* not implemented */
-
- drawable = CALLOC_STRUCT(dri_drawable);
- if (drawable == NULL)
- goto fail;
-
- if (visual->redBits == 8) {
- if (visual->alphaBits == 8)
- drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- else
- drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
- } else {
- drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM;
- }
-
- switch(visual->depthBits) {
- default:
- case 0:
- drawable->depth_stencil_format = PIPE_FORMAT_NONE;
- break;
- case 16:
- drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
- break;
- case 24:
- if (visual->stencilBits == 0) {
- drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
- PIPE_FORMAT_Z24X8_UNORM:
- PIPE_FORMAT_X8Z24_UNORM;
- } else {
- drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
- PIPE_FORMAT_Z24S8_UNORM:
- PIPE_FORMAT_S8Z24_UNORM;
- }
- break;
- case 32:
- drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- break;
- }
-
- drawable->stfb = st_create_framebuffer(visual,
- drawable->color_format,
- drawable->depth_stencil_format,
- drawable->depth_stencil_format,
- dPriv->w,
- dPriv->h, (void *)drawable);
- if (drawable->stfb == NULL)
- goto fail;
-
- drawable->sPriv = sPriv;
- drawable->dPriv = dPriv;
- dPriv->driverPrivate = (void *)drawable;
-
- /* setup dri2 buffers information */
- /* TODO incase of double buffer visual, delay fake creation */
- i = 0;
- if (sPriv->dri2.loader
- && (sPriv->dri2.loader->base.version > 2)
- && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- if (!screen->auto_fake_front) {
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->doubleBufferMode) {
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->depthBits && visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
- } else if (visual->depthBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- drawable->attachments[i++] = visual->depthBits;
- } else if (visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->attachments[i++] = visual->stencilBits;
- }
- drawable->num_attachments = i / 2;
- } else {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- if (!screen->auto_fake_front)
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- if (visual->doubleBufferMode)
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (visual->depthBits && visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- else if (visual->depthBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- else if (visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->num_attachments = i;
- }
-
- drawable->desired_fences = 2;
-
- return GL_TRUE;
-fail:
- FREE(drawable);
- return GL_FALSE;
-}
-
-static struct pipe_fence_handle *
-dri_swap_fences_pop_front(struct dri_drawable *draw)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence = NULL;
-
- if (draw->cur_fences >= draw->desired_fences) {
- screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
- screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
- --draw->cur_fences;
- draw->tail &= DRI_SWAP_FENCES_MASK;
- }
- return fence;
-}
-
-static void
-dri_swap_fences_push_back(struct dri_drawable *draw,
- struct pipe_fence_handle *fence)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
-
- if (!fence)
- return;
-
- if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
- draw->cur_fences++;
- screen->fence_reference(screen, &draw->swap_fences[draw->head++],
- fence);
- draw->head &= DRI_SWAP_FENCES_MASK;
- }
-}
-
-void
-dri_destroy_buffer(__DRIdrawable * dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_fence_handle *fence;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
-
- st_unreference_framebuffer(drawable->stfb);
- drawable->desired_fences = 0;
- while (drawable->cur_fences) {
- fence = dri_swap_fences_pop_front(drawable);
- screen->fence_reference(screen, &fence, NULL);
- }
-
- FREE(drawable);
-}
-
-static void
-dri1_update_drawables_locked(struct dri_context *ctx,
- __DRIdrawable * driDrawPriv,
- __DRIdrawable * driReadPriv)
-{
- if (ctx->stLostLock) {
- ctx->stLostLock = FALSE;
- if (driDrawPriv == driReadPriv)
- DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
- else
- DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
- driReadPriv);
- }
-}
-
-/**
- * This ensures all contexts which bind to a drawable pick up the
- * drawable change and signal new buffer state.
- * Calling st_resize_framebuffer for each context may seem like overkill,
- * but no new buffers will actually be allocated if the dimensions don't
- * change.
- */
-
-static void
-dri1_propagate_drawable_change(struct dri_context *ctx)
-{
- __DRIdrawable *dPriv = ctx->dPriv;
- __DRIdrawable *rPriv = ctx->rPriv;
- boolean flushed = FALSE;
-
- if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- flushed = TRUE;
- ctx->d_stamp = dPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h);
-
- }
-
- if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) {
-
- if (!flushed)
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->r_stamp = rPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h);
-
- } else if (rPriv && dPriv == rPriv) {
-
- ctx->r_stamp = ctx->d_stamp;
-
- }
-}
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read)
-{
- dri_lock(ctx);
- dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv);
- dri_unlock(ctx);
-
- dri1_propagate_drawable_change(ctx);
-}
-
-static INLINE boolean
-dri1_intersect_src_bbox(struct drm_clip_rect *dst,
- int dst_x,
- int dst_y,
- const struct drm_clip_rect *src,
- const struct drm_clip_rect *bbox)
-{
- int xy1;
- int xy2;
-
- xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
- (int)bbox->x1 + dst_x;
- xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
- (int)bbox->x2 + dst_x;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->x1 = xy1;
- dst->x2 = xy2;
-
- xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
- (int)bbox->y1 + dst_y;
- xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
- (int)bbox->y2 + dst_y;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->y1 = xy1;
- dst->y2 = xy2;
- return TRUE;
-}
-
-static void
-dri1_swap_copy(struct dri_context *ctx,
- struct pipe_surface *dst,
- struct pipe_surface *src,
- __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct drm_clip_rect clip;
- struct drm_clip_rect *cur;
- int i;
-
- cur = dPriv->pClipRects;
-
- for (i = 0; i < dPriv->numClipRects; ++i) {
- if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
- if (pipe->surface_copy) {
- pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- } else {
- util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- }
- }
- }
-}
-
-static void
-dri1_copy_to_front(struct dri_context *ctx,
- struct pipe_surface *surf,
- __DRIdrawable * dPriv,
- const struct drm_clip_rect *sub_box,
- struct pipe_fence_handle **fence)
-{
- struct pipe_context *pipe = ctx->pipe;
- boolean save_lost_lock;
- uint cur_w;
- uint cur_h;
- struct drm_clip_rect bbox;
- boolean visible = TRUE;
-
- *fence = NULL;
-
- dri_lock(ctx);
- save_lost_lock = ctx->stLostLock;
- dri1_update_drawables_locked(ctx, dPriv, dPriv);
- st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h);
-
- bbox.x1 = 0;
- bbox.x2 = cur_w;
- bbox.y1 = 0;
- bbox.y2 = cur_h;
-
- if (sub_box)
- visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
-
- if (visible && __dri1_api_hooks->present_locked) {
-
- __dri1_api_hooks->present_locked(pipe,
- surf,
- dPriv->pClipRects,
- dPriv->numClipRects,
- dPriv->x, dPriv->y, &bbox, fence);
-
- } else if (visible && __dri1_api_hooks->front_srf_locked) {
-
- struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
-
- if (front)
- dri1_swap_copy(ctx, front, surf, dPriv, &bbox);
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
- }
-
- ctx->stLostLock = save_lost_lock;
-
- /**
- * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
- */
-
- if (!sub_box)
- dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
-
- dri_unlock(ctx);
- dri1_propagate_drawable_change(ctx);
-}
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct pipe_fence_handle *dummy_fence;
-
- dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
-
- /**
- * FIXME: Do we need swap throttling here?
- */
-}
-
-void
-dri_swap_buffers(__DRIdrawable * dPriv)
-{
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return; /* For now */
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_notify_swapbuffers(draw->stfb);
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- fence = dri_swap_fences_pop_front(draw);
- if (fence) {
- (void)screen->fence_finish(screen, fence, 0);
- screen->fence_reference(screen, &fence, NULL);
- }
- dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence);
- dri_swap_fences_push_back(draw, fence);
- screen->fence_reference(screen, &fence, NULL);
- }
-}
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
-{
- struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
- struct drm_clip_rect sub_bbox;
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_fence_handle *dummy_fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return;
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- sub_bbox.x1 = x;
- sub_bbox.x2 = x + w;
- sub_bbox.y1 = y;
- sub_bbox.y2 = y + h;
-
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
- }
-}
-
-/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
deleted file mode 100644
index 1259813a412..00000000000
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009, VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-/*
- * Author: Keith Whitwell <[email protected]>
- * Author: Jakob Bornecrantz <[email protected]>
- */
-
-#include "dri_screen.h"
-#include "dri_context.h"
-#include "state_tracker/st_context.h"
-
-#define need_GL_ARB_map_buffer_range
-#define need_GL_ARB_multisample
-#define need_GL_ARB_occlusion_query
-#define need_GL_ARB_point_parameters
-#define need_GL_ARB_provoking_vertex
-#define need_GL_ARB_shader_objects
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_array_object
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_vertex_program
-#define need_GL_ARB_vertex_shader
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_blend_color
-#define need_GL_EXT_blend_equation_separate
-#define need_GL_EXT_blend_func_separate
-#define need_GL_EXT_blend_minmax
-#define need_GL_EXT_cull_vertex
-#define need_GL_EXT_draw_buffers2
-#define need_GL_EXT_fog_coord
-#define need_GL_EXT_framebuffer_object
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_provoking_vertex
-#define need_GL_EXT_secondary_color
-#define need_GL_EXT_stencil_two_side
-#define need_GL_APPLE_vertex_array_object
-#define need_GL_NV_vertex_program
-#define need_GL_VERSION_2_0
-#define need_GL_VERSION_2_1
-#include "main/remap_helper.h"
-#include "utils.h"
-
-/**
- * Extension strings exported by the driver.
- */
-static const struct dri_extension card_extensions[] = {
- {"GL_ARB_fragment_shader", NULL},
- {"GL_ARB_map_buffer_range", GL_ARB_map_buffer_range_functions},
- {"GL_ARB_multisample", GL_ARB_multisample_functions},
- {"GL_ARB_multitexture", NULL},
- {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
- {"GL_ARB_pixel_buffer_object", NULL},
- {"GL_ARB_provoking_vertex", GL_ARB_provoking_vertex_functions},
- {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
- {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
- {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
- {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions},
- {"GL_ARB_texture_border_clamp", NULL},
- {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
- {"GL_ARB_texture_cube_map", NULL},
- {"GL_ARB_texture_env_add", NULL},
- {"GL_ARB_texture_env_combine", NULL},
- {"GL_ARB_texture_env_dot3", NULL},
- {"GL_ARB_texture_mirrored_repeat", NULL},
- {"GL_ARB_texture_non_power_of_two", NULL},
- {"GL_ARB_texture_rectangle", NULL},
- {"GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions},
- {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
- {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
- {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
- {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
- {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
- {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
- {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
- {"GL_EXT_blend_subtract", NULL},
- {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
- {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions},
- {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
- {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
- {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
- {"GL_EXT_packed_depth_stencil", NULL},
- {"GL_EXT_pixel_buffer_object", NULL},
- {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions},
- {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
- {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
- {"GL_EXT_stencil_wrap", NULL},
- {"GL_EXT_texture_edge_clamp", NULL},
- {"GL_EXT_texture_env_combine", NULL},
- {"GL_EXT_texture_env_dot3", NULL},
- {"GL_EXT_texture_filter_anisotropic", NULL},
- {"GL_EXT_texture_lod_bias", NULL},
- {"GL_3DFX_texture_compression_FXT1", NULL},
- {"GL_APPLE_client_storage", NULL},
- {"GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions},
- {"GL_MESA_pack_invert", NULL},
- {"GL_MESA_ycbcr_texture", NULL},
- {"GL_NV_blend_square", NULL},
- {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
- {"GL_NV_vertex_program1_1", NULL},
- {"GL_SGIS_generate_mipmap", NULL},
- {NULL, NULL}
-};
-
-void
-dri_init_extensions(struct dri_context *ctx)
-{
- /* The card_extensions list should be pruned according to the
- * capabilities of the pipe_screen. This is actually something
- * that can/should be done inside st_create_context().
- * XXX Not pruning is very bogus. Always all these extensions above
- * will be advertized, regardless what st_init_extensions
- * (which depends on the pipe cap bits) does.
- */
- driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE);
-}
-
-/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/drm/Makefile b/src/gallium/state_trackers/dri/drm/Makefile
new file mode 100644
index 00000000000..7a236da0c0f
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/Makefile
@@ -0,0 +1,32 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = dridrm
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/gallium/state_trackers/dri/common \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa/main \
+ $(shell pkg-config --cflags-only-I libdrm)
+
+
+C_SOURCES = \
+ dri_context.c \
+ dri_screen.c \
+ dri_drawable.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ dri1.c \
+ dri2.c
+
+# $(TOP)/src/mesa/drivers/dri/common/utils.c \
+ $(TOP)/src/mesa/drivers/dri/common/vblank.c \
+ $(TOP)/src/mesa/drivers/dri/common/dri_util.c \
+ $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \
+ $(TOP)/src/mesa/drivers/common/driverfuncs.c \
+ $(TOP)/src/mesa/drivers/dri/common/texmem.c \
+ $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript
new file mode 100644
index 00000000000..b9726ee3113
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/SConscript
@@ -0,0 +1,27 @@
+#######################################################################
+# SConscript for dri state_tracker
+
+Import('*')
+
+if env['dri']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/gallium/state_trackers/dri/common',
+ '#/src/mesa/drivers/dri/common',
+ ])
+
+ st_dri = env.ConvenienceLibrary(
+ target = 'st_dri',
+ source = [ 'dri_context.c',
+ 'dri_drawable.c',
+ 'dri_screen.c',
+ 'dri_st_api.c',
+ 'dri1_helper.c',
+ 'dri1.c',
+ 'dri2.c',
+ ]
+ )
+ Export('st_dri')
diff --git a/src/gallium/state_trackers/dri/drm/dri1.c b/src/gallium/state_trackers/dri/drm/dri1.c
new file mode 100644
index 00000000000..cca7cd8f0c3
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1.c
@@ -0,0 +1,522 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+/* XXX DRI1 is untested after the switch to st_api.h */
+
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/dri1_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#include "dri1.h"
+
+static INLINE void
+dri1_lock(struct dri_context *ctx)
+{
+ drm_context_t hw_context = ctx->cPriv->hHWContext;
+ char ret = 0;
+
+ DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
+ if (ret) {
+ drmGetLock(ctx->sPriv->fd, hw_context, 0);
+ ctx->stLostLock = TRUE;
+ ctx->wsLostLock = TRUE;
+ }
+ ctx->isLocked = TRUE;
+}
+
+static INLINE void
+dri1_unlock(struct dri_context *ctx)
+{
+ ctx->isLocked = FALSE;
+ DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
+}
+
+static void
+dri1_update_drawables_locked(struct dri_context *ctx,
+ __DRIdrawable * driDrawPriv,
+ __DRIdrawable * driReadPriv)
+{
+ if (ctx->stLostLock) {
+ ctx->stLostLock = FALSE;
+ if (driDrawPriv == driReadPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
+ else
+ DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
+ driReadPriv);
+ }
+}
+
+/**
+ * This ensures all contexts which bind to a drawable pick up the
+ * drawable change and signal new buffer state.
+ */
+static void
+dri1_propagate_drawable_change(struct dri_context *ctx)
+{
+ __DRIdrawable *dPriv = ctx->dPriv;
+ __DRIdrawable *rPriv = ctx->rPriv;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_drawable *read = dri_drawable(rPriv);
+ boolean flushed = FALSE;
+
+ if (dPriv && draw->texture_stamp != dPriv->lastStamp) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ flushed = TRUE;
+ ctx->st->notify_invalid_framebuffer(ctx->st, draw->stfb);
+ }
+
+ if (rPriv && dPriv != rPriv && read->texture_stamp != rPriv->lastStamp) {
+ if (!flushed)
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->notify_invalid_framebuffer(ctx->st, read->stfb);
+ }
+}
+
+static INLINE boolean
+dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+static void
+dri1_swap_copy(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
+{
+ struct drm_clip_rect clip;
+ struct drm_clip_rect *cur;
+ int i;
+
+ cur = dPriv->pClipRects;
+
+ for (i = 0; i < dPriv->numClipRects; ++i) {
+ if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
+ if (pipe->surface_copy) {
+ pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ } else {
+ util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ }
+ }
+ }
+}
+
+static void
+dri1_present_texture_locked(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_context *pipe;
+ struct pipe_surface *psurf;
+ struct drm_clip_rect bbox;
+ boolean visible = TRUE;
+
+ *fence = NULL;
+
+ bbox.x1 = 0;
+ bbox.x2 = ptex->width0;
+ bbox.y1 = 0;
+ bbox.y2 = ptex->height0;
+
+ if (sub_box)
+ visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
+ if (!visible)
+ return;
+
+ pipe = dri1_get_pipe_context(screen);
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!pipe || !psurf)
+ return;
+
+ if (__dri1_api_hooks->present_locked) {
+ __dri1_api_hooks->present_locked(pipe, psurf,
+ dPriv->pClipRects, dPriv->numClipRects,
+ dPriv->x, dPriv->y, &bbox, fence);
+ } else if (__dri1_api_hooks->front_srf_locked) {
+ struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
+
+ if (front)
+ dri1_swap_copy(pipe, front, psurf, dPriv, &bbox);
+
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, fence);
+ }
+}
+
+static void
+dri1_copy_to_front(struct dri_context *ctx,
+ struct pipe_texture *ptex,
+ __DRIdrawable * dPriv,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ boolean save_lost_lock;
+
+ dri1_lock(ctx);
+ save_lost_lock = ctx->stLostLock;
+ dri1_update_drawables_locked(ctx, dPriv, dPriv);
+
+ dri1_present_texture_locked(dPriv, ptex, sub_box, fence);
+
+ ctx->stLostLock = save_lost_lock;
+
+ /**
+ * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
+ */
+
+ if (!sub_box)
+ dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
+
+ dri1_unlock(ctx);
+ dri1_propagate_drawable_change(ctx);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *draw,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[statt];
+ if (ptex) {
+ dri1_copy_to_front(ctx, ptex, ctx->dPriv, NULL, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+
+ /**
+ * FIXME: Do we need swap throttling here?
+ */
+}
+
+void
+dri1_swap_buffers(__DRIdrawable * dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ fence = dri1_swap_fences_pop_front(draw);
+ if (fence) {
+ (void)pipe_screen->fence_finish(pipe_screen, fence, 0);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+ dri1_copy_to_front(ctx, ptex, dPriv, NULL, &fence);
+ dri1_swap_fences_push_back(draw, fence);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+}
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct drm_clip_rect sub_bbox;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return;
+
+ sub_bbox.x1 = x;
+ sub_bbox.x2 = x + w;
+ sub_bbox.y1 = y;
+ sub_bbox.y2 = y + h;
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ dri1_copy_to_front(ctx, ptex, dPriv, &sub_bbox, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ */
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *dri1_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
+
+static void
+st_dri_lock(struct pipe_context *pipe)
+{
+ dri1_lock((struct dri_context *)pipe->priv);
+}
+
+static void
+st_dri_unlock(struct pipe_context *pipe)
+{
+ dri1_unlock((struct dri_context *)pipe->priv);
+}
+
+static boolean
+st_dri_is_locked(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->isLocked;
+}
+
+static boolean
+st_dri_lost_lock(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->wsLostLock;
+}
+
+static void
+st_dri_clear_lost_lock(struct pipe_context *pipe)
+{
+ ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
+}
+
+static struct dri1_api_lock_funcs dri1_lf = {
+ .lock = st_dri_lock,
+ .unlock = st_dri_unlock,
+ .is_locked = st_dri_is_locked,
+ .is_lock_lost = st_dri_lost_lock,
+ .clear_lost_lock = st_dri_clear_lost_lock
+};
+
+static INLINE void
+dri1_copy_version(struct dri1_api_version *dst,
+ const struct __DRIversionRec *src)
+{
+ dst->major = src->major;
+ dst->minor = src->minor;
+ dst->patch_level = src->patch;
+}
+
+struct dri1_api *__dri1_api_hooks = NULL;
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct dri1_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+ screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri1_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRI1;
+ arg.lf = &dri1_lf;
+ arg.ddx_info = sPriv->pDevPriv;
+ arg.ddx_info_size = sPriv->devPrivSize;
+ arg.sarea = sPriv->pSAREA;
+ dri1_copy_version(&arg.ddx_version, &sPriv->ddx_version);
+ dri1_copy_version(&arg.dri_version, &sPriv->dri_version);
+ dri1_copy_version(&arg.drm_version, &sPriv->drm_version);
+ arg.api = NULL;
+
+ /**
+ * FIXME: If the driver supports format conversion swapbuffer blits, we might
+ * want to support other color bit depths than the server is currently
+ * using.
+ */
+
+ configs = dri_init_screen_helper(screen, &arg.base, sPriv->fbBPP);
+ if (!configs)
+ goto fail;
+
+ if (!arg.api) {
+ debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
+ goto fail;
+ }
+
+ __dri1_api_hooks = arg.api;
+
+ return configs;
+fail:
+ if (configs)
+ FREE(configs);
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
diff --git a/src/gallium/state_trackers/dri/drm/dri1.h b/src/gallium/state_trackers/dri/drm/dri1.h
new file mode 100644
index 00000000000..f7441f98abc
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ */
+
+#ifndef DRI1_H
+#define DRI1_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+extern struct dri1_api *__dri1_api_hooks;
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv);
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void dri1_swap_buffers(__DRIdrawable * dPriv);
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
+
+#endif /* DRI1_H */
diff --git a/src/gallium/state_trackers/dri/drm/dri1_helper.c b/src/gallium/state_trackers/dri/drm/dri1_helper.c
new file mode 120000
index 00000000000..c45ebf5c102
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri1_helper.c
@@ -0,0 +1 @@
+../common/dri1_helper.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
new file mode 100644
index 00000000000..c632f0fe4f3
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -0,0 +1,416 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ * Jakob Bornecrantz <[email protected]>
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri2.h"
+
+/**
+ * DRI2 flush extension.
+ */
+static void
+dri2_flush_drawable(__DRIdrawable *draw)
+{
+}
+
+static void
+dri2_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_context *ctx = dri_context(dPriv->driContextPriv);
+
+ dri2InvalidateDrawable(dPriv);
+ drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
+
+ if (ctx)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static const __DRI2flushExtension dri2FlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ dri2_flush_drawable,
+ dri2_invalidate_drawable,
+};
+
+/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+static void
+dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_context(pDRICtx);
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *pt;
+
+ dri_st_framebuffer_validate_att(drawable->stfb, ST_ATTACHMENT_FRONT_LEFT);
+
+ pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
+
+ if (pt) {
+ ctx->st->teximage(ctx->st,
+ (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
+ 0, drawable->stvis.color_format, pt, FALSE);
+ }
+}
+
+static void
+dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension dri2TexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri2_set_tex_buffer,
+ dri2_set_tex_buffer2,
+};
+
+/**
+ * Get the format of an attachment.
+ */
+static INLINE enum pipe_format
+dri2_drawable_get_format(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ enum pipe_format format;
+
+ switch (statt) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return format;
+}
+
+/**
+ * Retrieve __DRIbuffer from the DRI loader.
+ */
+static __DRIbuffer *
+dri2_drawable_get_buffers(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned *count)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+ boolean with_format;
+ __DRIbuffer *buffers;
+ int num_buffers;
+ unsigned attachments[10];
+ unsigned num_attachments, i;
+
+ assert(loader);
+ with_format = dri_with_format(drawable->sPriv);
+
+ num_attachments = 0;
+
+ /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
+ if (!with_format)
+ attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
+
+ for (i = 0; i < *count; i++) {
+ enum pipe_format format;
+ int att, bpp;
+
+ format = dri2_drawable_get_format(drawable, statts[i]);
+ if (format == PIPE_FORMAT_NONE)
+ continue;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ /* already added */
+ if (!with_format)
+ continue;
+ att = __DRI_BUFFER_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ att = __DRI_BUFFER_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ att = __DRI_BUFFER_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ att = __DRI_BUFFER_BACK_RIGHT;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ att = __DRI_BUFFER_DEPTH_STENCIL;
+ break;
+ default:
+ att = -1;
+ break;
+ }
+
+ bpp = util_format_get_blocksizebits(format);
+
+ if (att >= 0) {
+ attachments[num_attachments++] = att;
+ if (with_format) {
+ attachments[num_attachments++] = bpp;
+ }
+ }
+ }
+
+ if (with_format) {
+ num_attachments /= 2;
+ buffers = loader->getBuffersWithFormat(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+ else {
+ buffers = loader->getBuffers(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+
+ if (buffers) {
+ /* set one cliprect to cover the whole dri_drawable */
+ dri_drawable->x = 0;
+ dri_drawable->y = 0;
+ dri_drawable->backX = 0;
+ dri_drawable->backY = 0;
+ dri_drawable->numClipRects = 1;
+ dri_drawable->pClipRects[0].x1 = 0;
+ dri_drawable->pClipRects[0].y1 = 0;
+ dri_drawable->pClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pClipRects[0].y2 = dri_drawable->h;
+ dri_drawable->numBackClipRects = 1;
+ dri_drawable->pBackClipRects[0].x1 = 0;
+ dri_drawable->pBackClipRects[0].y1 = 0;
+ dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+
+ *count = num_buffers;
+ }
+
+ return buffers;
+}
+
+/**
+ * Process __DRIbuffer and convert them into pipe_textures.
+ */
+static void
+dri2_drawable_process_buffers(struct dri_drawable *drawable,
+ __DRIbuffer *buffers, unsigned count)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct pipe_texture templ;
+ struct winsys_handle whandle;
+ boolean have_depth = FALSE;
+ unsigned i;
+
+ if (drawable->old_num == count &&
+ drawable->old_w == dri_drawable->w &&
+ drawable->old_h == dri_drawable->h &&
+ memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0)
+ return;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ memset(&templ, 0, sizeof(templ));
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = dri_drawable->w;
+ templ.height0 = dri_drawable->h;
+ templ.depth0 = 1;
+
+ memset(&whandle, 0, sizeof(whandle));
+
+ for (i = 0; i < count; i++) {
+ __DRIbuffer *buf = &buffers[i];
+ enum st_attachment_type statt;
+ enum pipe_format format;
+
+ switch (buf->attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ if (!screen->auto_fake_front) {
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+ /* fallthrough */
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case __DRI_BUFFER_BACK_LEFT:
+ statt = ST_ATTACHMENT_BACK_LEFT;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_STENCIL:
+ /* use only the first depth/stencil buffer */
+ if (!have_depth) {
+ have_depth = TRUE;
+ statt = ST_ATTACHMENT_DEPTH_STENCIL;
+ }
+ else {
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ break;
+ default:
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+
+ format = dri2_drawable_get_format(drawable, statt);
+ if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE)
+ continue;
+
+ templ.format = format;
+ whandle.handle = buf->name;
+ whandle.stride = buf->pitch;
+
+ drawable->textures[statt] =
+ screen->pipe_screen->texture_from_handle(screen->pipe_screen,
+ &templ, &whandle);
+ }
+
+ drawable->old_num = count;
+ drawable->old_w = dri_drawable->w;
+ drawable->old_h = dri_drawable->h;
+ memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
+}
+
+/*
+ * Backend functions for st_framebuffer interface.
+ */
+
+void
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count)
+{
+ __DRIbuffer *buffers;
+ unsigned num_buffers = count;
+
+ buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
+ dri2_drawable_process_buffers(drawable, buffers, num_buffers);
+}
+
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+
+ if (loader->flushFrontBuffer == NULL)
+ return;
+
+ if (statt == ST_ATTACHMENT_FRONT_LEFT) {
+ loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
+ }
+}
+
+/*
+ * Backend function init_screen.
+ */
+
+static const __DRIextension *dri_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ &dri2TexBufferExtension.base,
+ &dri2FlushExtension.base,
+ NULL
+};
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * Returns the __GLcontextModes supported by this driver.
+ */
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct drm_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri_screen_extensions;
+
+ arg.mode = DRM_CREATE_NORMAL;
+
+ configs = dri_init_screen_helper(screen, &arg, 32);
+ if (!configs)
+ goto fail;
+
+ screen->auto_fake_front = dri_with_format(sPriv);
+
+ return configs;
+fail:
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driLegacyExtension.base,
+ &driDRI2Extension.base,
+ NULL
+};
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/drm/dri2.h b/src/gallium/state_trackers/dri/drm/dri2.h
new file mode 100644
index 00000000000..379963431fb
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri2.h
@@ -0,0 +1,46 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef DRI2_H
+#define DRI2_H
+
+#include "dri_drawable.h"
+#include "dri_wrapper.h"
+
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv);
+
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count);
+
+#endif /* DRI2_H */
diff --git a/src/gallium/state_trackers/dri/drm/dri_context.c b/src/gallium/state_trackers/dri/drm/dri_context.c
new file mode 120000
index 00000000000..5cfbbaeb068
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_context.c
@@ -0,0 +1 @@
+../common/dri_context.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_drawable.c b/src/gallium/state_trackers/dri/drm/dri_drawable.c
new file mode 120000
index 00000000000..0fc19be6ea6
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_drawable.c
@@ -0,0 +1 @@
+../common/dri_drawable.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_screen.c b/src/gallium/state_trackers/dri/drm/dri_screen.c
new file mode 120000
index 00000000000..847f6515f25
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_screen.c
@@ -0,0 +1 @@
+../common/dri_screen.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/drm/dri_st_api.c b/src/gallium/state_trackers/dri/drm/dri_st_api.c
new file mode 120000
index 00000000000..a8f6bd06b09
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri_st_api.c
@@ -0,0 +1 @@
+../common/dri_st_api.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/Makefile b/src/gallium/state_trackers/dri/sw/Makefile
new file mode 100644
index 00000000000..18d7aabd9f0
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/Makefile
@@ -0,0 +1,26 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = drisw
+
+LIBRARY_DEFINES = -D__NOT_HAVE_DRM_H
+
+LIBRARY_INCLUDES = \
+ -I../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/gallium/state_trackers/dri/common \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa/main \
+ -D__NOT_HAVE_DRM_H
+
+
+C_SOURCES = \
+ dri_context.c \
+ dri_screen.c \
+ dri_drawable.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ drisw.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript
new file mode 100644
index 00000000000..c97124c8310
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/SConscript
@@ -0,0 +1,28 @@
+#######################################################################
+# SConscript for dri state_tracker
+
+Import('*')
+
+if env['dri']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/gallium/state_trackers/dri/common',
+ '#/src/mesa/drivers/dri/common',
+ ])
+
+ env.Append(CPPDEFINES = [('__NOT_HAVE_DRM_H', '1')])
+
+ st_drisw = env.ConvenienceLibrary(
+ target = 'st_drisw',
+ source = [ 'dri_context.c',
+ 'dri_drawable.c',
+ 'dri_screen.c',
+ 'dri_st_api.c',
+ 'dri1_helper.c',
+ 'drisw.c',
+ ]
+ )
+ Export('st_drisw')
diff --git a/src/gallium/state_trackers/dri/sw/dri1_helper.c b/src/gallium/state_trackers/dri/sw/dri1_helper.c
new file mode 120000
index 00000000000..c45ebf5c102
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri1_helper.c
@@ -0,0 +1 @@
+../common/dri1_helper.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_context.c b/src/gallium/state_trackers/dri/sw/dri_context.c
new file mode 120000
index 00000000000..5cfbbaeb068
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_context.c
@@ -0,0 +1 @@
+../common/dri_context.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_drawable.c b/src/gallium/state_trackers/dri/sw/dri_drawable.c
new file mode 120000
index 00000000000..0fc19be6ea6
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_drawable.c
@@ -0,0 +1 @@
+../common/dri_drawable.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_screen.c b/src/gallium/state_trackers/dri/sw/dri_screen.c
new file mode 120000
index 00000000000..847f6515f25
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_screen.c
@@ -0,0 +1 @@
+../common/dri_screen.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/dri_st_api.c b/src/gallium/state_trackers/dri/sw/dri_st_api.c
new file mode 120000
index 00000000000..a8f6bd06b09
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/dri_st_api.c
@@ -0,0 +1 @@
+../common/dri_st_api.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
new file mode 100644
index 00000000000..42fa789aaf7
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -0,0 +1,298 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* TODO:
+ *
+ * xshm / texture_from_pixmap / EGLImage:
+ *
+ * Allow the loaders to use the XSHM extension. It probably requires callbacks
+ * for createImage/destroyImage similar to DRI2 getBuffers.
+ */
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/drisw_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri1_helper.h"
+#include "drisw.h"
+
+
+static INLINE void
+get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+ int x, y;
+
+ loader->getDrawableInfo(dPriv,
+ &x, &y, w, h,
+ dPriv->loaderPrivate);
+}
+
+static INLINE void
+put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+ 0, 0, width, height,
+ data, dPriv->loaderPrivate);
+}
+
+void
+drisw_update_drawable_info(struct dri_drawable *drawable)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
+}
+
+static void
+drisw_put_image(struct dri_drawable *drawable,
+ void *data, unsigned width, unsigned height)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ put_image(dPriv, data, width, height);
+}
+
+static INLINE void
+drisw_present_texture(__DRIdrawable *dPriv,
+ struct pipe_texture *ptex)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_surface *psurf;
+
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!psurf)
+ return;
+
+ screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable);
+}
+
+static INLINE void
+drisw_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+
+ drawable->texture_stamp = dPriv->lastStamp - 1;
+
+ /* check if swapping currently bound buffer */
+ if (ctx && ctx->dPriv == dPriv)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static INLINE void
+drisw_copy_to_front(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex)
+{
+ drisw_present_texture(dPriv, ptex);
+
+ drisw_invalidate_drawable(dPriv);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+drisw_swap_buffers(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ drisw_copy_to_front(dPriv, ptex);
+ }
+}
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[statt];
+
+ if (ptex) {
+ drisw_copy_to_front(ctx->dPriv, ptex);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ *
+ * It should be possible for DRI1 and DRISW to share this function, but it
+ * seems a better seperation and safer for each DRI version to provide its own
+ * function.
+ */
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *drisw_screen_extensions[] = {
+ NULL
+};
+
+static struct drisw_loader_funcs drisw_lf = {
+ .put_image = drisw_put_image
+};
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv)
+{
+ const __DRIconfig **configs;
+ struct dri_screen *screen;
+ struct drisw_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = -1;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = drisw_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRISW;
+ arg.lf = &drisw_lf;
+
+ configs = dri_init_screen_helper(screen, &arg.base, 32);
+ if (!configs)
+ goto fail;
+
+ return configs;
+fail:
+ dri_destroy_screen_helper(screen);
+ FREE(screen);
+ return NULL;
+}
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driSWRastExtension.base,
+ NULL
+};
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h
new file mode 100644
index 00000000000..c0c874f7326
--- /dev/null
+++ b/src/gallium/state_trackers/dri/sw/drisw.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef DRISW_H
+#define DRISW_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv);
+
+void
+drisw_update_drawable_info(struct dri_drawable *drawable);
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void drisw_swap_buffers(__DRIdrawable * dPriv);
+
+#endif /* DRISW_H */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 50774b03f35..5eabe10558a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -36,234 +36,27 @@
#include "native.h"
#include "egl_g3d.h"
+#include "egl_g3d_st.h"
#include "egl_g3d_image.h"
-#include "egl_st.h"
-
-/**
- * Validate the draw/read surfaces of the context.
- */
-static void
-egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct pipe_screen *screen = gdpy->native->screen;
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
- ST_SURFACE_FRONT_LEFT,
- ST_SURFACE_BACK_LEFT,
- ST_SURFACE_FRONT_RIGHT,
- ST_SURFACE_BACK_RIGHT,
- };
- EGLint num_surfaces, s;
-
- /* validate draw and/or read buffers */
- num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
- for (s = 0; s < num_surfaces; s++) {
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
- EGLint att;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- if (!gctx->force_validate) {
- unsigned int seq_num;
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &seq_num, NULL, NULL, NULL);
- /* skip validation */
- if (gsurf->sequence_number == seq_num)
- continue;
- }
-
- pipe_surface_reference(&gsurf->render_surface, NULL);
- memset(textures, 0, sizeof(textures));
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &gsurf->sequence_number, textures,
- &gsurf->base.Width, &gsurf->base.Height);
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- struct pipe_texture *pt = textures[att];
- struct pipe_surface *ps;
-
- if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
- ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
- gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
- st_att_map[att], ps);
-
- if (gsurf->render_att == att)
- pipe_surface_reference(&gsurf->render_surface, ps);
-
- pipe_surface_reference(&ps, NULL);
- pipe_texture_reference(&pt, NULL);
- }
- }
-
- gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
- gsurf->base.Width, gsurf->base.Height);
- }
-
- gctx->force_validate = EGL_FALSE;
-
-}
-
-/**
- * Create a st_framebuffer.
- */
-static struct st_framebuffer *
-create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
-
- return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
- gconf->native->color_format, gconf->native->depth_format,
- gconf->native->stencil_format,
- gsurf->base.Width, gsurf->base.Height, &gsurf->base);
-}
-
-/**
- * Update the attachments of draw/read surfaces.
- */
-static void
-egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- EGLint s;
-
- /* route draw and read buffers' attachments */
- for (s = 0; s < 2; s++) {
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- gbuf->attachment_mask = (1 << gsurf->render_att);
-
- /* FIXME OpenGL defaults to draw the front or back buffer when the
- * context is single-buffered or double-buffered respectively. In EGL,
- * however, the buffer to be drawn is determined by the surface, instead
- * of the context. As a result, rendering to a pixmap surface with a
- * double-buffered context does not work as expected.
- *
- * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
- * NATIVE_ATTACHMENT_FRONT_LEFT);
- */
-
- /*
- * FIXME If the back buffer is asked for here, and the front buffer is
- * later needed by the client API (e.g. glDrawBuffer is called to draw
- * the front buffer), it will create a new pipe texture and draw there.
- * One fix is to ask for both buffers here, but it would be a waste if
- * the front buffer is never used. A better fix is to add a callback to
- * the pipe screen with context private (just like flush_frontbuffer).
- */
- }
-}
-
-/**
- * Reallocate the context's framebuffers after draw/read surfaces change.
- */
-static EGLBoolean
-egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
- struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
-
- /* unreference the old framebuffers */
- if (gctx->draw.st_fb) {
- EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
- void *priv;
-
- priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
- if (!gdraw || priv != (void *) &gdraw->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
-
- if (is_equal) {
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- else {
- priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
- if (!gread || priv != (void *) &gread->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- }
- }
-
- if (!gdraw)
- return EGL_TRUE;
-
- /* create the draw fb */
- if (!gctx->draw.st_fb) {
- gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
- if (!gctx->draw.st_fb)
- return EGL_FALSE;
- }
-
- /* create the read fb */
- if (!gctx->read.st_fb) {
- if (gread != gdraw) {
- gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
- if (!gctx->read.st_fb) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- return EGL_FALSE;
- }
- }
- else {
- /* there is no st_reference_framebuffer... */
- gctx->read.st_fb = gctx->draw.st_fb;
- }
- }
-
- egl_g3d_route_context(dpy, &gctx->base);
- gctx->force_validate = EGL_TRUE;
-
- return EGL_TRUE;
-}
/**
* Return the state tracker for the given context.
*/
-static const struct egl_g3d_st *
+static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- const struct egl_g3d_st *stapi;
+ struct st_api *stapi;
EGLint idx = -1;
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientVersion) {
case 1:
- idx = EGL_G3D_ST_OPENGL_ES;
+ idx = ST_API_OPENGL_ES1;
break;
case 2:
- idx = EGL_G3D_ST_OPENGL_ES2;
+ idx = ST_API_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client version %d",
@@ -272,10 +65,10 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
break;
case EGL_OPENVG_API:
- idx = EGL_G3D_ST_OPENVG;
+ idx = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
- idx = EGL_G3D_ST_OPENGL;
+ idx = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
@@ -299,10 +92,10 @@ egl_g3d_init_st(_EGLDriver *drv)
if (gdrv->api_mask)
return;
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- gdrv->stapis[i] = egl_g3d_get_st(i);
+ for (i = 0; i < ST_API_COUNT; i++) {
+ gdrv->stapis[i] = egl_g3d_create_st_api(i);
if (gdrv->stapis[i])
- gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+ gdrv->api_mask |= egl_g3d_st_api_bit(i);
}
if (gdrv->api_mask)
@@ -351,35 +144,6 @@ egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
}
}
-/**
- * Return an API mask that consists of the state trackers that supports the
- * given mode.
- *
- * FIXME add st_is_mode_supported()?
- */
-static EGLint
-get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
-{
- EGLint check;
-
- /* OpenGL ES 1.x and 2.x are checked together */
- check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
- if (api_mask & check) {
- /* this is required by EGL, not by OpenGL ES */
- if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
- api_mask &= ~check;
- }
-
- check = EGL_OPENVG_BIT;
- if (api_mask & check) {
- /* vega st needs the depth/stencil rb */
- if (!mode->depthBits && !mode->stencilBits)
- api_mask &= ~check;
- }
-
- return api_mask;
-}
-
#ifdef EGL_MESA_screen_surface
static void
@@ -444,18 +208,88 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
#endif /* EGL_MESA_screen_surface */
/**
+ * Initialize an EGL config from the native config.
+ */
+static EGLBoolean
+egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const struct native_config *nconf)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ const __GLcontextModes *mode = &nconf->mode;
+ EGLint buffer_mask, api_mask;
+ EGLBoolean valid;
+ EGLint i;
+
+ buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ gconf->stvis.buffer_mask = buffer_mask;
+ gconf->stvis.color_format = nconf->color_format;
+ gconf->stvis.depth_stencil_format = nconf->depth_format;
+ gconf->stvis.accum_format = PIPE_FORMAT_NONE;
+ gconf->stvis.samples = 0;
+
+ gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT) ?
+ ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
+
+ api_mask = 0;
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
+ if (stapi) {
+ if (stapi->is_visual_supported(stapi, &gconf->stvis))
+ api_mask |= egl_g3d_st_api_bit(i);
+ }
+ }
+ /* this is required by EGL, not by OpenGL ES */
+ if ((mode->drawableType & GLX_WINDOW_BIT) && !mode->doubleBufferMode)
+ api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
+
+ if (!api_mask) {
+ _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+ mode->visualID);
+ }
+
+ valid = _eglConfigFromContextModesRec(&gconf->base,
+ mode, api_mask, api_mask);
+ if (valid) {
+#ifdef EGL_MESA_screen_surface
+ /* check if scanout surface bit is set */
+ if (nconf->scanout_bit) {
+ EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
+ val |= EGL_SCREEN_BIT_MESA;
+ SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ }
+#endif
+ valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
+ }
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", mode->visualID);
+ return EGL_FALSE;
+ }
+
+ gconf->native = nconf;
+
+ return EGL_TRUE;
+}
+
+/**
* Add configs to display and return the next config ID.
*/
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_config **native_configs;
int num_configs, i;
- native_configs = gdpy->native->get_configs(gdpy->native,
- &num_configs);
+ native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
if (!num_configs) {
if (native_configs)
free(native_configs);
@@ -463,75 +297,25 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
for (i = 0; i < num_configs; i++) {
- EGLint api_mask;
struct egl_g3d_config *gconf;
- EGLBoolean valid;
gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
-
- _eglInitConfig(&gconf->base, dpy, id);
-
- api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
- if (!api_mask) {
- _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
- native_configs[i]->mode.visualID);
- }
-
- valid = _eglConfigFromContextModesRec(&gconf->base,
- &native_configs[i]->mode, api_mask, api_mask);
- if (valid) {
-#ifdef EGL_MESA_screen_surface
- /* check if scanout surface bit is set */
- if (native_configs[i]->scanout_bit) {
- EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
- val |= EGL_SCREEN_BIT_MESA;
- SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ if (gconf) {
+ _eglInitConfig(&gconf->base, dpy, id);
+ if (!egl_g3d_init_config(drv, dpy, &gconf->base, native_configs[i])) {
+ free(gconf);
+ continue;
}
-#endif
- valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
- }
- if (!valid) {
- _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
- native_configs[i]->mode.visualID);
- free(gconf);
- continue;
- }
- gconf->native = native_configs[i];
- _eglAddConfig(dpy, &gconf->base);
- id++;
+ _eglAddConfig(dpy, &gconf->base);
+ id++;
+ }
}
free(native_configs);
return id;
}
-/**
- * Flush the front buffer of the context's draw surface.
- */
-static void
-egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
-
- if (gsurf)
- gsurf->native->flush_frontbuffer(gsurf->native);
-}
-
-/**
- * Re-validate the context.
- */
-static void
-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
-}
-
static void
egl_g3d_invalid_surface(struct native_display *ndpy,
struct native_surface *nsurf,
@@ -539,11 +323,15 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
-
- /* set force_validate to skip an unnecessary check */
+ struct egl_g3d_context *gctx;
+
+ /*
+ * Some functions such as egl_g3d_copy_buffers create a temporary native
+ * surface. There is no gsurf associated with it.
+ */
+ gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
if (gctx)
- gctx->force_validate = TRUE;
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
}
static struct native_event_handler egl_g3d_native_event_handler = {
@@ -559,6 +347,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);
+ if (gdpy->pipe)
+ gdpy->pipe->destroy(gdpy->pipe);
+
if (dpy->Screens) {
for (i = 0; i < dpy->NumScreens; i++) {
struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
@@ -568,6 +359,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
free(dpy->Screens);
}
+ if (gdpy->smapi)
+ egl_g3d_destroy_st_manager(gdpy->smapi);
+
if (gdpy->native)
gdpy->native->destroy(gdpy->native);
@@ -602,12 +396,17 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
gdpy->native->user_data = (void *) dpy;
- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
- gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;
+ gdpy->smapi = egl_g3d_create_st_manager(dpy);
+ if (!gdpy->smapi) {
+ _eglError(EGL_NOT_INITIALIZED,
+ "eglInitialize(failed to create st manager)");
+ goto fail;
+ }
+
#ifdef EGL_MESA_screen_surface
/* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
@@ -644,7 +443,6 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
struct egl_g3d_context *gshare = egl_g3d_context(share);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_context *gctx;
- const __GLcontextModes *mode;
gctx = CALLOC_STRUCT(egl_g3d_context);
if (!gctx) {
@@ -663,24 +461,14 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
- mode = &gconf->native->mode;
-
- gctx->pipe = gdpy->native->screen->context_create(
- gdpy->native->screen,
- (void *) &gctx->base);
-
- if (!gctx->pipe) {
+ gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
+ &gconf->stvis, (gshare) ? gshare->stctxi : NULL);
+ if (!gctx->stctxi) {
free(gctx);
return NULL;
}
- gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
- (gshare) ? gshare->st_ctx : NULL);
- if (!gctx->st_ctx) {
- gctx->pipe->destroy(gctx->pipe);
- free(gctx);
- return NULL;
- }
+ gctx->stctxi->st_manager_private = (void *) &gctx->base;
return &gctx->base;
}
@@ -697,9 +485,7 @@ destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
- egl_g3d_realloc_context(dpy, &gctx->base);
- /* it will destroy the associated pipe context */
- gctx->stapi->st_destroy_context(gctx->st_ctx);
+ gctx->stctxi->destroy(gctx->stctxi);
free(gctx);
}
@@ -801,14 +587,20 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
+ gsurf->stvis = gconf->stvis;
+ if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER)
+ gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
+
+ gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
+ if (!gsurf->stfbi) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
nsurf->user_data = &gsurf->base;
gsurf->native = nsurf;
- gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
- if (!gconf->native->mode.doubleBufferMode)
- gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
-
return &gsurf->base;
}
@@ -864,7 +656,8 @@ destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
- pipe_surface_reference(&gsurf->render_surface, NULL);
+ pipe_texture_reference(&gsurf->render_texture, NULL);
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
gsurf->native->destroy(gsurf->native);
free(gsurf);
}
@@ -883,6 +676,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
+ struct egl_g3d_surface *gread = egl_g3d_surface(read);
struct egl_g3d_context *old_gctx;
EGLBoolean ok = EGL_TRUE;
@@ -893,34 +687,29 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
if (old_gctx) {
/* flush old context */
- old_gctx->stapi->st_flush(old_gctx->st_ctx,
+ old_gctx->stctxi->flush(old_gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
-
- /*
- * The old context is no longer current, and egl_g3d_realloc_context()
- * should be called to destroy the framebuffers. However, it is possible
- * that it will be made current again with the same draw/read surfaces.
- * It might be better to keep it around.
- */
}
if (gctx) {
- ok = egl_g3d_realloc_context(dpy, &gctx->base);
+ ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
+ (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
- ok = gctx->stapi->st_make_current(gctx->st_ctx,
- gctx->draw.st_fb, gctx->read.st_fb);
- if (ok) {
- egl_g3d_validate_context(dpy, &gctx->base);
- if (gdraw->base.Type == EGL_WINDOW_BIT) {
- gctx->base.WindowRenderBuffer =
- (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
- EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
- }
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gdraw->stfbi);
+ if (gread != gdraw) {
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
+ gread->stfbi);
+ }
+
+ if (gdraw->base.Type == EGL_WINDOW_BIT) {
+ gctx->base.WindowRenderBuffer =
+ (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
+ EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
}
else if (old_gctx) {
- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
+ ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
@@ -947,15 +736,17 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;
/* or when the surface is single-buffered */
- if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
+ if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
return EGL_TRUE;
if (ctx && ctx->DrawSurface == surf)
gctx = egl_g3d_context(ctx);
/* flush if the surface is current */
- if (gctx)
- gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
+ if (gctx) {
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
return gsurf->native->swap_buffers(gsurf->native);
}
@@ -995,7 +786,7 @@ get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
return NULL;
psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
pipe_texture_reference(&textures[natt], NULL);
return psurf;
@@ -1013,7 +804,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_surface *psurf;
- if (!gsurf->render_surface)
+ if (!gsurf->render_texture)
return EGL_TRUE;
gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
@@ -1028,26 +819,33 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
/* flush if the surface is current */
if (ctx && ctx->DrawSurface == &gsurf->base) {
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_flush(gctx->st_ctx,
+ gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
+ /* create a pipe context to copy surfaces */
+ if (!gdpy->pipe) {
+ gdpy->pipe =
+ gdpy->native->screen->context_create(gdpy->native->screen, NULL);
+ if (!gdpy->pipe)
+ return EGL_FALSE;
+ }
+
psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (psurf) {
- struct pipe_context pipe;
+ struct pipe_surface *psrc;
- /**
- * XXX This is hacky. If we might allow the EGLDisplay to create a pipe
- * context of its own and use the blitter context for this.
- */
- memset(&pipe, 0, sizeof(pipe));
- pipe.screen = screen;
+ psrc = screen->get_tex_surface(screen, gsurf->render_texture,
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ if (psrc) {
+ gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0,
+ psrc, 0, 0, psurf->width, psurf->height);
+ pipe_surface_reference(&psrc, NULL);
- util_surface_copy(&pipe, FALSE, psurf, 0, 0,
- gsurf->render_surface, 0, 0, psurf->width, psurf->height);
+ nsurf->flush_frontbuffer(nsurf);
+ }
pipe_surface_reference(&psurf, NULL);
- nsurf->flush_frontbuffer(nsurf);
}
nsurf->destroy(nsurf);
@@ -1058,8 +856,16 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
static EGLBoolean
egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_finish(gctx->st_ctx);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ screen->fence_finish(screen, fence, 0);
+ screen->fence_reference(screen, &fence, NULL);
+
return EGL_TRUE;
}
@@ -1089,10 +895,10 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
/* in case this is called before a display is initialized */
egl_g3d_init_st(&gdrv->base);
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- const struct egl_g3d_st *stapi = gdrv->stapis[i];
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
if (stapi) {
- proc = (_EGLProc) stapi->st_get_proc_address(procname);
+ proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
if (proc)
return proc;
}
@@ -1108,8 +914,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx;
- enum pipe_format target_format;
- int target;
+ enum pipe_format internal_format;
+ enum st_texture_type target;
if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
@@ -1120,10 +926,10 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
switch (gsurf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
- target_format = PIPE_FORMAT_R8G8B8_UNORM;
+ internal_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
- target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
@@ -1139,21 +945,24 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (!es1)
return EGL_TRUE;
- if (!gsurf->render_surface)
+ if (!gsurf->render_texture)
return EGL_FALSE;
/* flush properly if the surface is bound */
if (gsurf->base.CurrentContext) {
gctx = egl_g3d_context(gsurf->base.CurrentContext);
- gctx->stapi->st_flush(gctx->st_ctx,
+ gctx->stctxi->flush(gctx->stctxi,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
gctx = egl_g3d_context(es1);
- gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
- target, gsurf->base.MipmapLevel, target_format);
-
- gsurf->base.BoundToTexture = EGL_TRUE;
+ if (gctx->stctxi->teximage) {
+ if (!gctx->stctxi->teximage(gctx->stctxi, target,
+ gsurf->base.MipmapLevel, internal_format,
+ gsurf->render_texture, gsurf->base.MipmapTexture))
+ return EGL_FALSE;
+ gsurf->base.BoundToTexture = EGL_TRUE;
+ }
return EGL_TRUE;
}
@@ -1170,14 +979,15 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
- if (gsurf->render_surface) {
+ if (gsurf->render_texture) {
_EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
/* what if the context the surface binds to is no longer current? */
- if (gctx)
- gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
- ST_TEXTURE_2D, gsurf->base.MipmapLevel);
+ if (gctx) {
+ gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
+ gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
+ }
}
gsurf->base.BoundToTexture = EGL_FALSE;
@@ -1289,6 +1099,12 @@ static void
egl_g3d_unload(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ EGLint i;
+
+ for (i = 0; i < ST_API_COUNT; i++) {
+ if (gdrv->stapis[i])
+ gdrv->stapis[i]->destroy(gdrv->stapis[i]);
+ }
egl_g3d_destroy_probe(drv, NULL);
free(gdrv);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index e3e55e46d3b..2788f1bf4ac 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -39,11 +39,11 @@
#include "eglmode.h"
#include "native.h"
-#include "egl_st.h"
+#include "egl_g3d_st.h"
struct egl_g3d_driver {
_EGLDriver base;
- const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
+ struct st_api *stapis[ST_API_COUNT];
EGLint api_mask;
EGLint probe_key;
@@ -51,35 +51,34 @@ struct egl_g3d_driver {
struct egl_g3d_display {
struct native_display *native;
-};
-struct egl_g3d_buffer {
- struct st_framebuffer *st_fb;
- uint attachment_mask;
+ struct st_manager *smapi;
+ struct pipe_context *pipe;
};
struct egl_g3d_context {
_EGLContext base;
- const struct egl_g3d_st *stapi;
- struct pipe_context *pipe;
+ struct st_api *stapi;
- struct st_context *st_ctx;
- EGLBoolean force_validate;
- struct egl_g3d_buffer draw, read;
+ struct st_context_iface *stctxi;
};
struct egl_g3d_surface {
_EGLSurface base;
+
+ struct st_visual stvis;
+ struct st_framebuffer_iface *stfbi;
+
struct native_surface *native;
- enum native_attachment render_att;
- struct pipe_surface *render_surface;
+ struct pipe_texture *render_texture;
unsigned int sequence_number;
};
struct egl_g3d_config {
_EGLConfig base;
const struct native_config *native;
+ struct st_visual stvis;
};
struct egl_g3d_image {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
new file mode 100644
index 00000000000..36094096d36
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -0,0 +1,227 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_dl.h"
+#include "eglimage.h"
+#include "eglmutex.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_st.h"
+
+struct egl_g3d_st_manager {
+ struct st_manager base;
+ _EGLDisplay *display;
+};
+
+static INLINE struct egl_g3d_st_manager *
+egl_g3d_st_manager(struct st_manager *smapi)
+{
+ return (struct egl_g3d_st_manager *) smapi;
+}
+
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api)
+{
+ const char *stmod_name;
+ struct util_dl_library *lib;
+ const struct st_module *mod;
+
+ switch (api) {
+ case ST_API_OPENGL:
+ stmod_name = ST_MODULE_OPENGL_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES1:
+ stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES2:
+ stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL;
+ break;
+ case ST_API_OPENVG:
+ stmod_name = ST_MODULE_OPENVG_SYMBOL;
+ break;
+ default:
+ stmod_name = NULL;
+ break;
+ }
+ if (!stmod_name)
+ return NULL;
+
+ mod = NULL;
+ lib = util_dl_open(NULL);
+ if (lib) {
+ mod = (const struct st_module *)
+ util_dl_get_proc_address(lib, stmod_name);
+ util_dl_close(lib);
+ }
+ if (!mod || mod->api != api)
+ return NULL;
+
+ return mod->create_api();
+}
+
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_st_manager *gsmapi;
+
+ gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
+ if (gsmapi) {
+ gsmapi->display = dpy;
+
+ gsmapi->base.screen = gdpy->native->screen;
+ }
+
+ return &gsmapi->base;;
+}
+
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi)
+{
+ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
+ free(gsmapi);
+}
+
+static boolean
+egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ return gsurf->native->flush_frontbuffer(gsurf->native);
+}
+
+static boolean
+egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ uint attachment_mask = 0;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0)
+ attachment_mask |= 1 << natt;
+ }
+
+ if (!gsurf->native->validate(gsurf->native, attachment_mask,
+ &gsurf->sequence_number, textures, &gsurf->base.Width,
+ &gsurf->base.Height))
+ return FALSE;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_texture *tex;
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ break;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0) {
+ tex = textures[natt];
+
+ if (statts[i] == stfbi->visual->render_buffer)
+ pipe_texture_reference(&gsurf->render_texture, tex);
+
+ if (attachment_mask & (1 << natt)) {
+ /* transfer the ownership to the caller */
+ out[i] = tex;
+ attachment_mask &= ~(1 << natt);
+ }
+ else {
+ /* the attachment is listed more than once */
+ pipe_texture_reference(&out[i], tex);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (!stfbi)
+ return NULL;
+
+ stfbi->visual = &gsurf->stvis;
+ stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
+ stfbi->validate = egl_g3d_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) &gsurf->base;
+
+ return stfbi;
+}
+
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ free(stfbi);
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
index 8fb464bd3d7..ea8b4068cd8 100644
--- a/src/gallium/state_trackers/egl/common/egl_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 7.8
+ * Version: 7.9
*
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ * Copyright (C) 2010 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,54 +20,60 @@
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
*/
-#ifndef _EGL_ST_H_
-#define _EGL_ST_H_
-
-#include "GL/gl.h" /* for GL types */
-#include "GL/internal/glcore.h" /* for __GLcontextModes */
+#ifndef _EGL_G3D_ST_H_
+#define _EGL_G3D_ST_H_
#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
+#include "state_tracker/st_api.h"
+#include "egltypedefs.h"
-/* avoid calling st functions directly */
-#if 1
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api);
-#define ST_SURFACE_FRONT_LEFT 0
-#define ST_SURFACE_BACK_LEFT 1
-#define ST_SURFACE_FRONT_RIGHT 2
-#define ST_SURFACE_BACK_RIGHT 3
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy);
-#define ST_TEXTURE_2D 0x2
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi);
-struct st_context;
-struct st_framebuffer;
-typedef void (*st_proc)();
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf);
-#else
-#include "state_tracker/st_public.h"
-#endif
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
-/* remember to update egl_g3d_get_st() when update the enums */
-enum egl_g3d_st_api {
- EGL_G3D_ST_OPENGL_ES = 0,
- EGL_G3D_ST_OPENVG,
- EGL_G3D_ST_OPENGL_ES2,
- EGL_G3D_ST_OPENGL,
-
- NUM_EGL_G3D_STS
-};
+/**
+ * Return the EGL_<api>_BIT of the st api.
+ */
+static INLINE int
+egl_g3d_st_api_bit(enum st_api_type api)
+{
+ int bit;
-struct egl_g3d_st {
-#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
-#include "st_public_tmp.h"
- /* fields must be added here */
- EGLint api_bit;
-};
+ switch (api) {
+ case ST_API_OPENGL:
+ bit = EGL_OPENGL_BIT;
+ break;
+ case ST_API_OPENGL_ES1:
+ bit = EGL_OPENGL_ES_BIT;
+ break;
+ case ST_API_OPENGL_ES2:
+ bit = EGL_OPENGL_ES2_BIT;
+ break;
+ case ST_API_OPENVG:
+ bit = EGL_OPENVG_BIT;
+ break;
+ default:
+ bit = 0;
+ break;
+ }
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api);
+ return bit;
+}
-#endif /* _EGL_ST_H_ */
+#endif /* _EGL_G3D_ST_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c
deleted file mode 100644
index a88ff911cd5..00000000000
--- a/src/gallium/state_trackers/egl/common/egl_st.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.8
- *
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dlfcn.h>
-#include "pipe/p_compiler.h"
-#include "util/u_memory.h"
-#include "egllog.h"
-#include "EGL/egl.h" /* for EGL_api_BIT */
-
-#include "egl_st.h"
-
-#ifndef HAVE_DLADDR
-#define HAVE_DLADDR 1
-#endif
-
-#if HAVE_DLADDR
-
-static const char *
-egl_g3d_st_names[] = {
-#define ST_PUBLIC(name, ...) #name,
-#include "st_public_tmp.h"
- NULL
-};
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
- st_proc *procs = (st_proc *) stapi;
- void *handle;
- Dl_info info;
- const char **name;
-
- if (!dladdr(sym, &info))
- return FALSE;
- handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
- if (!handle)
- return FALSE;
-
- for (name = egl_g3d_st_names; *name; name++) {
- st_proc proc = (st_proc) dlsym(handle, *name);
- if (!proc) {
- _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
- memset(stapi, 0, sizeof(*stapi));
- dlclose(handle);
- return FALSE;
- }
- *procs++ = proc;
- }
-
- dlclose(handle);
- return TRUE;
-}
-
-#else /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
-#define ST_PUBLIC(name, ...) stapi->name = name;
-#include "st_public_tmp.h"
- return TRUE;
-}
-
-#endif /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
-{
- void *handle, *sym;
- boolean res = FALSE;
-
- /* already initialized */
- if (stapi->st_notify_swapbuffers != NULL)
- return TRUE;
-
- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
- if (!handle)
- return FALSE;
-
- sym = dlsym(handle, api);
- if (sym && egl_g3d_fill_st(stapi, sym))
- res = TRUE;
-
- dlclose(handle);
- return res;
-}
-
-static struct {
- const char *symbol;
- EGLint api_bit;
-} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
- { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
- { "st_api_OpenVG", EGL_OPENVG_BIT },
- { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
- { "st_api_OpenGL", EGL_OPENGL_BIT },
-};
-
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api)
-{
- static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
-
- if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
- all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
- return &all_trackers[api];
- }
- else {
- return NULL;
- }
-}
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 9c22ff3e432..93c81b26e10 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -140,9 +140,6 @@ struct native_config {
struct native_display {
/**
* The pipe screen of the native display.
- *
- * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be
- * overridden.
*/
struct pipe_screen *screen;
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
deleted file mode 100644
index 507a0ec4027..00000000000
--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h
+++ /dev/null
@@ -1,20 +0,0 @@
-ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
-ST_PUBLIC(st_destroy_context, void, struct st_context *st)
-ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask)
-ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
-ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height)
-ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
-ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height)
-ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
-ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
-ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
-ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read)
-ST_PUBLIC(st_get_current, struct st_context *, void)
-ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
-ST_PUBLIC(st_finish, void, struct st_context *st)
-ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format)
-ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level)
-ST_PUBLIC(st_get_proc_address, st_proc, const char *procname)
-#undef ST_PUBLIC
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index 94588bfa743..73222408565 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
templ.format = ksurf->color_format;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
- templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
}
/* create textures */
@@ -100,7 +100,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
for (i = 0; i < num_framebuffers; i++) {
struct kms_framebuffer *fb;
enum native_attachment natt;
- unsigned int handle, stride;
+ struct winsys_handle whandle;
uint block_bits;
if (i == 0) {
@@ -128,13 +128,17 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
/* TODO detect the real value */
fb->is_passive = TRUE;
- if (!kdpy->api->local_handle_from_texture(kdpy->api,
- kdpy->base.screen, fb->texture, &stride, &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!kdpy->base.screen->texture_get_handle(kdpy->base.screen,
+ fb->texture, &whandle))
return FALSE;
block_bits = util_format_get_blocksizebits(ksurf->color_format);
err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
- block_bits, block_bits, stride, handle, &fb->buffer_id);
+ block_bits, block_bits, whandle.stride, whandle.handle,
+ &fb->buffer_id);
if (err) {
fb->buffer_id = 0;
return FALSE;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 8d2a8b1dffe..98399792311 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -114,6 +114,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
struct pipe_texture templ;
+ struct winsys_handle whandle;
uint valid_mask;
int i;
@@ -171,9 +172,11 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
continue;
}
- dri2surf->textures[natt] =
- dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
- dri2dpy->base.screen, &templ, desc, xbuf->pitch, xbuf->name);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = xbuf->pitch;
+ whandle.handle = xbuf->name;
+ dri2surf->textures[natt] = dri2dpy->base.screen->texture_from_handle(
+ dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 7b4fe63fa07..c6eb17ab1ac 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -142,16 +142,9 @@ native_create_display(EGLNativeDisplayType dpy,
if (!ndpy) {
EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
- boolean use_shm;
-
- /*
- * XXX st/mesa calls pipe_screen::update_buffer in st_validate_state.
- * When SHM is used, there is a good chance that the shared memory
- * segment is detached before the softpipe tile cache is flushed.
- */
- use_shm = FALSE;
- _eglLog(level, "use software%s fallback", (use_shm) ? " (SHM)" : "");
- ndpy = x11_create_ximage_display(dpy, event_handler, use_shm);
+
+ _eglLog(level, "use software fallback");
+ ndpy = x11_create_ximage_display(dpy, event_handler);
}
return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 8c6a7d93497..1566524926a 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -30,8 +30,7 @@
struct native_display *
x11_create_ximage_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
- boolean use_xshm);
+ struct native_event_handler *event_handler);
struct native_display *
x11_create_dri2_display(EGLNativeDisplayType dpy,
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 3421c1951aa..c6b16354f9b 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -28,17 +28,19 @@
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
-#include "softpipe/sp_winsys.h"
+#include "state_tracker/xlib_sw_winsys.h"
+#include "target-helpers/wrap_screen.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "cell/ppu/cell_public.h"
#include "egllog.h"
-#include "sw_winsys.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -53,24 +55,18 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
- struct x11_screen *xscr;
- int xscr_number;
-
struct native_event_handler *event_handler;
- boolean use_xshm;
+ struct x11_screen *xscr;
+ int xscr_number;
- struct pipe_winsys *winsys;
struct ximage_config *configs;
int num_configs;
};
struct ximage_buffer {
- XImage *ximage;
-
struct pipe_texture *texture;
- XShmSegmentInfo *shm_info;
- boolean xshm_attached;
+ struct xlib_drawable xdraw;
};
struct ximage_surface {
@@ -81,13 +77,13 @@ struct ximage_surface {
XVisualInfo visual;
struct ximage_display *xdpy;
- GC gc;
-
unsigned int server_stamp;
unsigned int client_stamp;
int width, height;
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
uint valid_mask;
+
+ struct pipe_surface *draw_surface;
};
struct ximage_config {
@@ -121,18 +117,6 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
struct ximage_buffer *xbuf = &xsurf->buffers[which];
pipe_texture_reference(&xbuf->texture, NULL);
-
- if (xbuf->shm_info) {
- if (xbuf->xshm_attached)
- XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
- if (xbuf->shm_info->shmaddr != (void *) -1)
- shmdt(xbuf->shm_info->shmaddr);
- if (xbuf->shm_info->shmid != -1)
- shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
-
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->shmid = -1;
- }
}
static boolean
@@ -156,40 +140,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- if (xbuf->shm_info) {
- struct pipe_buffer *pbuf;
- unsigned stride, size;
- void *addr = NULL;
-
- stride = util_format_get_stride(xsurf->color_format, xsurf->width);
- /* alignment should depend on visual? */
- stride = align(stride, 4);
- size = stride * xsurf->height;
-
- /* create and attach shm object */
- xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
- if (xbuf->shm_info->shmid != -1) {
- xbuf->shm_info->shmaddr =
- shmat(xbuf->shm_info->shmid, NULL, 0);
- if (xbuf->shm_info->shmaddr != (void *) -1) {
- if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
- addr = xbuf->shm_info->shmaddr;
- xbuf->xshm_attached = TRUE;
- }
- }
- }
-
- if (addr) {
- pbuf = screen->user_buffer_create(screen, addr, size);
- if (pbuf) {
- xbuf->texture =
- screen->texture_blanket(screen, &templ, &stride, pbuf);
- pipe_buffer_reference(&pbuf, NULL);
- }
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+ switch (which) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ break;
+ default:
+ break;
}
}
- else {
- xbuf->texture = screen->texture_create(screen, &templ);
+ xbuf->texture = screen->texture_create(screen, &templ);
+ if (xbuf->texture) {
+ xbuf->xdraw.visual = xsurf->visual.visual;
+ xbuf->xdraw.depth = xsurf->visual.depth;
+ xbuf->xdraw.drawable = xsurf->drawable;
}
/* clean up the buffer if allocation failed */
@@ -269,18 +238,10 @@ ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
new_valid = 0x0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
/* reallocate the texture */
if (!ximage_surface_alloc_buffer(&xsurf->base, att))
break;
- /* update ximage */
- if (xbuf->ximage) {
- xbuf->ximage->width = xsurf->width;
- xbuf->ximage->height = xsurf->height;
- }
-
new_valid |= (1 << att);
if (buffer_mask == new_valid)
break;
@@ -300,43 +261,26 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xbuf = &xsurf->buffers[which];
struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_transfer *transfer;
+ struct pipe_surface *psurf;
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return TRUE;
- assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+ assert(xsurf->drawable && xbuf->texture);
- transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!transfer)
- return FALSE;
+ psurf = xsurf->draw_surface;
+ if (!psurf || psurf->texture != xbuf->texture) {
+ pipe_surface_reference(&xsurf->draw_surface, NULL);
- xbuf->ximage->bytes_per_line = transfer->stride;
- xbuf->ximage->data = screen->transfer_map(screen, transfer);
- if (!xbuf->ximage->data) {
- screen->tex_transfer_destroy(transfer);
- return FALSE;
- }
-
-
- if (xbuf->shm_info)
- XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
- else
- XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
-
- xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, transfer);
+ psurf = screen->get_tex_surface(screen,
+ xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
+ return FALSE;
- /*
- * softpipe allows the pipe transfer to be re-used, but we don't want to
- * rely on that behavior.
- */
- screen->tex_transfer_destroy(transfer);
+ xsurf->draw_surface = psurf;
+ }
- XSync(xsurf->xdpy->dpy, FALSE);
+ screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
return TRUE;
}
@@ -364,7 +308,8 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
boolean ret;
/* display the back buffer first */
- ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
+ ret = ximage_surface_draw_buffer(&xsurf->base,
+ NATIVE_ATTACHMENT_BACK_LEFT);
/* force buffers to be updated in next validation call */
xsurf->server_stamp++;
ximage_surface_notify_invalid(&xsurf->base);
@@ -372,13 +317,12 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
- /* skip swapping so that the front buffer is allocated only when needed */
- if (!xfront->texture)
- return ret;
-
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
+ /* skip swapping unless there is a front buffer */
+ if (xfront->texture) {
+ xtmp = *xfront;
+ *xfront = *xback;
+ *xback = xtmp;
+ }
return ret;
}
@@ -433,18 +377,11 @@ ximage_surface_destroy(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
int i;
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
+ pipe_surface_reference(&xsurf->draw_surface, NULL);
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
ximage_surface_free_buffer(&xsurf->base, i);
- /* xbuf->shm_info is owned by xbuf->ximage? */
- if (xbuf->ximage) {
- XDestroyImage(xbuf->ximage);
- xbuf->ximage = NULL;
- }
- }
- if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
- XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
free(xsurf);
}
@@ -457,7 +394,6 @@ ximage_display_create_surface(struct native_display *ndpy,
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
- int i;
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
@@ -471,52 +407,8 @@ ximage_display_create_surface(struct native_display *ndpy,
if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
-
- xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
- if (!xsurf->gc) {
- free(xsurf);
- return NULL;
- }
-
/* initialize the geometry */
ximage_surface_update_buffers(&xsurf->base, 0x0);
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
-
- if (xdpy->use_xshm) {
- xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
- if (xbuf->shm_info) {
- /* initialize shm info */
- xbuf->shm_info->shmid = -1;
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->readOnly = TRUE;
-
- xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, NULL,
- xbuf->shm_info,
- 0, 0);
- }
- }
- else {
- xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 8, /* bitmap_pad */
- 0); /* bytes_per_line */
- }
-
- if (!xbuf->ximage) {
- XFreeGC(xdpy->dpy, xsurf->gc);
- free(xsurf);
- return NULL;
- }
- }
}
xsurf->base.destroy = ximage_surface_destroy;
@@ -727,7 +619,6 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
- free(xdpy->winsys);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
@@ -735,10 +626,63 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy);
}
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try.
+ *
+ * Long term, want to avoid having global #defines for things like
+ * GALLIUM_LLVMPIPE, GALLIUM_CELL, etc. Scons already eliminates
+ * those #defines, so things that are painful for it now are likely to
+ * be painful for other build systems in the future.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( display );
+ if (winsys == NULL)
+ return NULL;
+
+ /* Create a software rasterizer on top of that winsys. Use
+ * llvmpipe if it is available.
+ */
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+
struct native_display *
x11_create_ximage_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
- boolean use_xshm)
+ struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
@@ -756,6 +700,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
xdpy->own_dpy = TRUE;
}
+ xdpy->event_handler = event_handler;
+
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
@@ -763,13 +709,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
return NULL;
}
- xdpy->event_handler = event_handler;
-
- xdpy->use_xshm =
- (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
-
- xdpy->winsys = create_sw_winsys();
- xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+ xdpy->base.screen = swrast_xlib_create_screen(xdpy->dpy);
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
deleted file mode 100644
index 33328aadf26..00000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * Totally software-based winsys layer.
- * Note that the one winsys function that we can't implement here
- * is flush_frontbuffer().
- * Whoever uses this code will have to provide that.
- *
- * Authors: Brian Paul
- */
-
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "sw_winsys.h"
-
-
-
-/** Subclass of pipe_winsys */
-struct sw_pipe_winsys
-{
- struct pipe_winsys Base;
- /* no extra fields for now */
-};
-
-
-/** subclass of pipe_buffer */
-struct sw_pipe_buffer
-{
- struct pipe_buffer Base;
- boolean UserBuffer; /** Is this a user-space buffer? */
- void *Data;
- void *Mapped;
-};
-
-
-/** cast wrapper */
-static INLINE struct sw_pipe_buffer *
-sw_pipe_buffer(struct pipe_buffer *b)
-{
- return (struct sw_pipe_buffer *) b;
-}
-
-
-static const char *
-get_name(struct pipe_winsys *pws)
-{
- return "software";
-}
-
-
-/** Create new pipe_buffer and allocate storage of given size */
-static struct pipe_buffer *
-buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.alignment = alignment;
- buffer->Base.usage = usage;
- buffer->Base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->Data = align_malloc(size, MAX2(alignment, 16));
-
- return &buffer->Base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.size = bytes;
- buffer->UserBuffer = TRUE;
- buffer->Data = ptr;
-
- return &buffer->Base;
-}
-
-
-static void *
-buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = buffer->Data;
- return buffer->Mapped;
-}
-
-
-static void
-buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = NULL;
-}
-
-
-static void
-buffer_destroy(struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
-
- if (buffer->Data && !buffer->UserBuffer) {
- align_free(buffer->Data);
- buffer->Data = NULL;
- }
-
- free(buffer);
-}
-
-
-static struct pipe_buffer *
-surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- /* no-op */
-}
-
-
-static int
-fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-static int
-fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-/**
- * Create/return a new pipe_winsys object.
- */
-struct pipe_winsys *
-create_sw_winsys(void)
-{
- struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
- if (!ws)
- return NULL;
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->Base.buffer_create = buffer_create;
- ws->Base.user_buffer_create = user_buffer_create;
- ws->Base.buffer_map = buffer_map;
- ws->Base.buffer_unmap = buffer_unmap;
- ws->Base.buffer_destroy = buffer_destroy;
-
- ws->Base.surface_buffer_create = surface_buffer_create;
-
- ws->Base.fence_reference = fence_reference;
- ws->Base.fence_signalled = fence_signalled;
- ws->Base.fence_finish = fence_finish;
-
- ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
-
- ws->Base.get_name = get_name;
-
- return &ws->Base;
-}
diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile
index b0365512719..089d4411675 100644
--- a/src/gallium/state_trackers/es/Makefile
+++ b/src/gallium/state_trackers/es/Makefile
@@ -38,6 +38,8 @@ SYS_LIBS = -lm -pthread
INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
-I$(TOP)/src/gallium/include
.c.o:
diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c
index 25bc53b21eb..4e89e06b34c 100644
--- a/src/gallium/state_trackers/es/st_es1.c
+++ b/src/gallium/state_trackers/es/st_es1.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES1 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES1 = {
+ .api = ST_API_OPENGL_ES1,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c
index 171ea62b97f..82e88b176ac 100644
--- a/src/gallium/state_trackers/es/st_es2.c
+++ b/src/gallium/state_trackers/es/st_es2.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES2 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES2 = {
+ .api = ST_API_OPENGL_ES2,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 7b2adc62c34..35509fd708b 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -5,12 +5,14 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
- -I$(TOP)/src/mesa
+ -I$(TOP)/src/mesa \
+ $(X11_CFLAGS)
C_SOURCES = \
glx_api.c \
glx_getproc.c \
glx_usefont.c \
- xm_api.c
+ xm_api.c \
+ xm_st.c
include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index fa96df357d5..d6c16ad2f52 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -13,8 +13,6 @@ if env['platform'] == 'linux' \
'#/src/mesa/main',
])
- env.Append(CPPDEFINES = ['USE_XSHM'])
-
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
source = [
@@ -22,6 +20,7 @@ if env['platform'] == 'linux' \
'glx_getproc.c',
'glx_usefont.c',
'xm_api.c',
+ 'xm_st.c',
]
)
Export('st_xlib')
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 08bf624b5c1..eb8d6a19333 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -35,12 +35,9 @@
#include "xm_api.h"
#include "main/context.h"
-#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/version.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
/* This indicates the client-side GLX API and GLX encoder version. */
@@ -689,7 +686,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
int desiredVisualID = -1;
int numAux = 0;
- xmesa_init();
+ xmesa_init( dpy );
parselist = list;
@@ -1304,7 +1301,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
}
- st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
+ XMesaCopyContext(xm_src, xm_dst, mask);
}
@@ -1761,6 +1758,10 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
}
for (i = 0; i < *nelements; i++) {
results[i] = create_glx_visual(dpy, visuals + i);
+ if (!results[i]) {
+ *nelements = i;
+ break;
+ }
}
return (GLXFBConfig *) results;
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index e8524a21c21..fd03d3c46a4 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -35,10 +35,6 @@
* corner of the window. Therefore, most drawing functions in this
* file have to flip Y coordinates.
*
- * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
- * in support for the MIT Shared Memory extension. If enabled, when you
- * use an Ximage for the back buffer in double buffered mode, the "swap"
- * operation will be faster. You must also link with -lXext.
*
* Byte swapping: If the Mesa host and the X display use a different
* byte order then there's some trickiness to be aware of when using
@@ -58,20 +54,14 @@
#endif
#include "xm_api.h"
-#include "main/context.h"
-#include "main/framebuffer.h"
+#include "xm_st.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
+#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#include "trace/tr_texture.h"
-
-#include "xm_winsys.h"
+#include "xm_public.h"
#include <GL/glx.h>
@@ -80,20 +70,78 @@
* global.
*/
static struct xm_driver driver;
+static struct st_api *stapi;
void xmesa_set_driver( const struct xm_driver *templ )
{
driver = *templ;
+ stapi = driver.create_st_api();
}
-/**
- * Global X driver lock
+
+/*
+ * XXX replace this with a linked list, or better yet, try to attach the
+ * gallium/mesa extra bits to the X Display object with XAddExtension().
*/
-pipe_mutex _xmesa_lock;
+#define MAX_DISPLAYS 10
+static struct xmesa_display Displays[MAX_DISPLAYS];
+static int NumDisplays = 0;
+
-static struct pipe_screen *_screen = NULL;
-static struct pipe_screen *screen = NULL;
+static XMesaDisplay
+xmesa_init_display( Display *display )
+{
+ pipe_static_mutex(init_mutex);
+ XMesaDisplay xmdpy;
+ int i;
+
+ pipe_mutex_lock(init_mutex);
+
+ /* Look for XMesaDisplay which corresponds to 'display' */
+ for (i = 0; i < NumDisplays; i++) {
+ if (Displays[i].display == display) {
+ /* Found it */
+ pipe_mutex_unlock(init_mutex);
+ return &Displays[i];
+ }
+ }
+
+ /* Create new XMesaDisplay */
+ assert(NumDisplays < MAX_DISPLAYS);
+ xmdpy = &Displays[NumDisplays];
+ NumDisplays++;
+
+ if (!xmdpy->display && display) {
+ xmdpy->display = display;
+ xmdpy->screen = driver.create_pipe_screen(display);
+ xmdpy->smapi = CALLOC_STRUCT(st_manager);
+ if (xmdpy->smapi)
+ xmdpy->smapi->screen = xmdpy->screen;
+
+ if (xmdpy->screen && xmdpy->smapi) {
+ pipe_mutex_init(xmdpy->mutex);
+ }
+ else {
+ if (xmdpy->screen) {
+ xmdpy->screen->destroy(xmdpy->screen);
+ xmdpy->screen = NULL;
+ }
+ if (xmdpy->smapi) {
+ FREE(xmdpy->smapi);
+ xmdpy->smapi = NULL;
+ }
+
+ xmdpy->display = NULL;
+ }
+ }
+ if (!xmdpy->display || xmdpy->display != display)
+ xmdpy = NULL;
+
+ pipe_mutex_unlock(init_mutex);
+
+ return xmdpy;
+}
/**********************************************************************/
/***** X Utility Functions *****/
@@ -111,41 +159,6 @@ static int host_byte_order( void )
}
-/**
- * Check if the X Shared Memory extension is available.
- * Return: 0 = not available
- * 1 = shared XImage support available
- * 2 = shared Pixmap support available also
- */
-int xmesa_check_for_xshm( Display *display )
-{
-#if defined(USE_XSHM)
- int major, minor, ignore;
- Bool pixmaps;
-
- if (getenv("SP_NO_RAST"))
- return 0;
-
- if (getenv("MESA_NOSHM")) {
- return 0;
- }
-
- if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
- if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
- return (pixmaps==True) ? 2 : 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
- }
-#else
- /* No XSHM support */
- return 0;
-#endif
-}
/**
@@ -238,12 +251,13 @@ void
xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height)
{
+ XMesaDisplay xmdpy = xmesa_init_display(dpy);
Status stat;
- pipe_mutex_lock(_xmesa_lock);
+ pipe_mutex_lock(xmdpy->mutex);
XSync(b->xm_visual->display, 0); /* added for Chromium */
- stat = get_drawable_size(dpy, b->drawable, width, height);
- pipe_mutex_unlock(_xmesa_lock);
+ stat = get_drawable_size(dpy, b->ws.drawable, width, height);
+ pipe_mutex_unlock(xmdpy->mutex);
if (!stat) {
/* probably querying a window that's recently been destroyed */
@@ -313,26 +327,22 @@ choose_pixel_format(XMesaVisual v)
return PIPE_FORMAT_B5G6R5_UNORM;
}
- assert(0);
- return 0;
+ return PIPE_FORMAT_NONE;
}
-
/**
- * Query the default gallium screen for a Z/Stencil format that
- * at least matches the given depthBits and stencilBits.
+ * Choose a depth/stencil format that satisfies the given depth and
+ * stencil sizes.
*/
-static void
-xmesa_choose_z_stencil_format(int depth, int stencil,
- enum pipe_format *depthFormat,
- enum pipe_format *stencilFormat)
+static enum pipe_format
+choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
- enum pipe_format formats[8];
+ enum pipe_format formats[8], fmt;
int count, i;
count = 0;
@@ -352,21 +362,16 @@ xmesa_choose_z_stencil_format(int depth, int stencil,
formats[count++] = PIPE_FORMAT_Z32_UNORM;
}
- *depthFormat = PIPE_FORMAT_NONE;
+ fmt = PIPE_FORMAT_NONE;
for (i = 0; i < count; i++) {
- if (screen->is_format_supported(screen, formats[i],
+ if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
target, tex_usage, geom_flags)) {
- *depthFormat = formats[i];
+ fmt = formats[i];
break;
}
}
- if (stencil) {
- *stencilFormat = *depthFormat;
- }
- else {
- *stencilFormat = PIPE_FORMAT_NONE;
- }
+ return fmt;
}
@@ -375,7 +380,7 @@ xmesa_choose_z_stencil_format(int depth, int stencil,
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/
-XMesaBuffer XMesaBufferList = NULL;
+static XMesaBuffer XMesaBufferList = NULL;
/**
@@ -393,53 +398,33 @@ static XMesaBuffer
create_xmesa_buffer(Drawable d, BufferType type,
XMesaVisual vis, Colormap cmap)
{
+ XMesaDisplay xmdpy = xmesa_init_display(vis->display);
XMesaBuffer b;
- GLframebuffer *fb;
- enum pipe_format colorFormat, depthFormat, stencilFormat;
uint width, height;
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
+ if (!xmdpy)
+ return NULL;
+
b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
- b->drawable = d;
+ b->ws.drawable = d;
+ b->ws.visual = vis->visinfo->visual;
+ b->ws.depth = vis->visinfo->depth;
b->xm_visual = vis;
b->type = type;
b->cmap = cmap;
- /* determine PIPE_FORMATs for buffers */
- colorFormat = choose_pixel_format(vis);
-
- xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
- vis->mesa_visual.stencilBits,
- &depthFormat, &stencilFormat);
-
-
get_drawable_size(vis->display, d, &width, &height);
/*
* Create framebuffer, but we'll plug in our own renderbuffers below.
*/
- b->stfb = st_create_framebuffer(&vis->mesa_visual,
- colorFormat, depthFormat, stencilFormat,
- width, height,
- (void *) b);
- fb = &b->stfb->Base;
-
- /*
- * Create scratch XImage for xmesa_display_surface()
- */
- b->tempImage = XCreateImage(vis->display,
- vis->visinfo->visual,
- vis->visinfo->depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 32, /* bitmap_pad */
- 0); /* bytes_per_line */
+ b->stfb = xmesa_create_st_framebuffer(xmdpy, b);
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
@@ -483,29 +468,21 @@ xmesa_free_buffer(XMesaBuffer buffer)
for (b = XMesaBufferList; b; b = b->Next) {
if (b == buffer) {
- struct gl_framebuffer *fb = &buffer->stfb->Base;
-
/* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;
- /* mark as delete pending */
- fb->DeletePending = GL_TRUE;
-
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
- b->drawable = 0;
-
- buffer->tempImage->data = NULL;
- XDestroyImage(buffer->tempImage);
+ b->ws.drawable = 0;
- /* Unreference. If count = zero we'll really delete the buffer */
- _mesa_reference_framebuffer(&fb, NULL);
-
- XFreeGC(b->xm_visual->display, b->gc);
+ /* XXX we should move the buffer to a delete-pending list and destroy
+ * the buffer until it is no longer current.
+ */
+ xmesa_destroy_st_framebuffer(buffer->stfb);
free(buffer);
@@ -583,21 +560,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
}
- if (b && window) {
- /* these should have been set in create_xmesa_buffer */
- ASSERT(b->drawable == window);
-
- /* Setup for single/double buffering */
- if (v->mesa_visual.doubleBufferMode) {
- /* Double buffered */
- b->shm = xmesa_check_for_xshm( v->display );
- }
-
- /* X11 graphics context */
- b->gc = XCreateGC( v->display, window, 0, NULL );
- XSetFunction( v->display, b->gc, GXcopy );
- }
-
return GL_TRUE;
}
@@ -677,10 +639,12 @@ XMesaVisual XMesaCreateVisual( Display *display,
GLint level,
GLint visualCaveat )
{
+ XMesaDisplay xmdpy = xmesa_init_display(display);
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
- xmesa_init();
+ if (!xmdpy)
+ return NULL;
/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
@@ -762,6 +726,32 @@ XMesaVisual XMesaCreateVisual( Display *display,
accum_blue_size, accum_alpha_size,
0 );
+ v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (stereo_flag) {
+ v->stvis.buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ v->stvis.color_format = choose_pixel_format(v);
+ if (v->stvis.color_format == PIPE_FORMAT_NONE) {
+ FREE(v->visinfo);
+ FREE(v);
+ return NULL;
+ }
+
+ v->stvis.depth_stencil_format =
+ choose_depth_stencil_format(xmdpy, depth_size, stencil_size);
+
+ v->stvis.accum_format = (accum_red_size +
+ accum_green_size + accum_blue_size + accum_alpha_size) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+ v->stvis.samples = num_samples;
+ v->stvis.render_buffer = ST_ATTACHMENT_INVALID;
+
/* XXX minor hack */
v->mesa_visual.level = level;
return v;
@@ -777,18 +767,12 @@ void XMesaDestroyVisual( XMesaVisual v )
/**
- * Do one-time initializations.
+ * Do per-display initializations.
*/
void
-xmesa_init(void)
+xmesa_init( Display *display )
{
- static GLboolean firstTime = GL_TRUE;
- if (firstTime) {
- pipe_mutex_init(_xmesa_lock);
- _screen = driver.create_pipe_screen();
- screen = trace_screen_create( _screen );
- firstTime = GL_FALSE;
- }
+ xmesa_init_display(display);
}
@@ -802,51 +786,33 @@ xmesa_init(void)
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
- struct pipe_context *pipe = NULL;
+ XMesaDisplay xmdpy = xmesa_init_display(v->display);
XMesaContext c;
- GLcontext *mesaCtx;
- uint pf;
- xmesa_init();
+ if (!xmdpy)
+ return NULL;
/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
if (!c)
return NULL;
- pf = choose_pixel_format(v);
- assert(pf);
-
c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
- if (screen == NULL)
- goto fail;
-
- /* Trace screen knows how to properly wrap context creation in the
- * wrapped screen, so nothing special to do here:
- */
- pipe = screen->context_create(screen, (void *) c);
- if (pipe == NULL)
- goto fail;
-
- c->st = st_create_context(pipe,
- &v->mesa_visual,
- share_list ? share_list->st : NULL);
+ c->st = stapi->create_context(stapi, xmdpy->smapi,
+ &v->stvis, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
- mesaCtx = c->st->ctx;
- c->st->ctx->DriverCtx = c;
+ c->st->st_manager_private = (void *) c;
return c;
fail:
if (c->st)
- st_destroy_context(c->st);
- else if (pipe)
- pipe->destroy(pipe);
+ c->st->destroy(c->st);
free(c);
return NULL;
@@ -857,7 +823,7 @@ fail:
PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
- st_destroy_context(c->st);
+ c->st->destroy(c->st);
/* FIXME: We should destroy the screen here, but if we do so, surfaces may
* outlive it, causing segfaults
@@ -963,7 +929,6 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
{
GET_CURRENT_CONTEXT(ctx);
XMesaBuffer b;
- GLuint width, height;
assert(v);
@@ -971,19 +936,18 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
if (!b)
return NULL;
- /* get pixmap size, update framebuffer/renderbuffer dims */
- xmesa_get_window_size(v->display, b, &width, &height);
- _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
+ /* get pixmap size */
+ xmesa_get_window_size(v->display, b, &b->width, &b->height);
if (target == 0) {
/* examine dims */
if (ctx->Extensions.ARB_texture_non_power_of_two) {
target = GLX_TEXTURE_2D_EXT;
}
- else if ( _mesa_bitcount(width) == 1
- && _mesa_bitcount(height) == 1) {
+ else if ( _mesa_bitcount(b->width) == 1
+ && _mesa_bitcount(b->height) == 1) {
/* power of two size */
- if (height == 1) {
+ if (b->height == 1) {
target = GLX_TEXTURE_1D_EXT;
}
else {
@@ -1056,23 +1020,20 @@ XMesaDestroyBuffer(XMesaBuffer b)
/**
- * Query the current window size and update the corresponding GLframebuffer
- * and all attached renderbuffers.
- * Called when:
- * 1. the first time a buffer is bound to a context.
- * 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
- * Note: it's possible (and legal) for xmctx to be NULL. That can happen
- * when resizing a buffer when no rendering context is bound.
+ * Query the current drawable size and notify the binding context.
*/
void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+xmesa_check_buffer_size(XMesaBuffer b)
{
- GLuint width, height;
- xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
- st_resize_framebuffer(drawBuffer->stfb, width, height);
-}
+ XMesaContext xmctx = XMesaGetCurrentContext();
+ if (b->type == PBUFFER)
+ return;
+ xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
+ if (xmctx && xmctx->xm_buffer == b)
+ xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
+}
/*
@@ -1099,21 +1060,21 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_read_buffer == readBuffer)
return GL_TRUE;
+ xmesa_check_buffer_size(drawBuffer);
+ if (readBuffer != drawBuffer)
+ xmesa_check_buffer_size(readBuffer);
+
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
- st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
-
- xmesa_check_and_update_buffer_size(c, drawBuffer);
- if (readBuffer != drawBuffer)
- xmesa_check_and_update_buffer_size(c, readBuffer);
+ stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb);
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
- st_make_current( NULL, NULL, NULL );
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
@@ -1132,14 +1093,8 @@ GLboolean XMesaUnbindContext( XMesaContext c )
XMesaContext XMesaGetCurrentContext( void )
{
- GET_CURRENT_CONTEXT(ctx);
- if (ctx) {
- XMesaContext xmesa = xmesa_context(ctx);
- return xmesa;
- }
- else {
- return 0;
- }
+ struct st_context_iface *st = stapi->get_current(stapi);
+ return (XMesaContext) (st) ? st->st_manager_private : NULL;
}
@@ -1151,21 +1106,17 @@ XMesaContext XMesaGetCurrentContext( void )
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
- struct pipe_surface *frontLeftSurf;
-
- st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
-
- if (frontLeftSurf) {
- if (_screen != screen) {
- struct trace_surface *tr_surf = trace_surface( frontLeftSurf );
- struct pipe_surface *surf = tr_surf->surface;
- frontLeftSurf = surf;
- }
-
- driver.display_surface(b, frontLeftSurf);
+ XMesaContext xmctx = XMesaGetCurrentContext();
+
+ if (xmctx && xmctx->xm_buffer == b) {
+ xmctx->st->flush( xmctx->st,
+ PIPE_FLUSH_RENDER_CACHE |
+ PIPE_FLUSH_SWAPBUFFERS |
+ PIPE_FLUSH_FRAME,
+ NULL);
}
- xmesa_check_and_update_buffer_size(NULL, b);
+ xmesa_swap_st_framebuffer(b->stfb);
}
@@ -1175,21 +1126,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
*/
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
- struct pipe_surface *surf_front;
- struct pipe_surface *surf_back;
- struct pipe_context *pipe = NULL; /* XXX fix */
-
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back);
-
- if (!surf_front || !surf_back)
- return;
-
- assert(pipe);
- pipe->surface_copy(pipe,
- surf_front, x, y, /* dest */
- surf_back, x, y, /* src */
- width, height);
+ xmesa_copy_st_framebuffer(b->stfb,
+ ST_ATTACHMENT_BACK_LEFT, ST_ATTACHMENT_FRONT_LEFT,
+ x, y, width, height);
}
@@ -1197,7 +1136,14 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
void XMesaFlush( XMesaContext c )
{
if (c && c->xm_visual->display) {
- st_finish(c->st);
+ XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
+ struct pipe_fence_handle *fence = NULL;
+
+ c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ if (fence) {
+ xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
+ xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
+ }
XSync( c->xm_visual->display, False );
}
}
@@ -1210,7 +1156,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
for (b = XMesaBufferList; b; b = b->Next) {
- if (b->drawable == d && b->xm_visual->display == dpy) {
+ if (b->ws.drawable == d && b->xm_visual->display == dpy) {
return b;
}
}
@@ -1244,10 +1190,10 @@ void XMesaGarbageCollect( void )
next = b->Next;
if (b->xm_visual &&
b->xm_visual->display &&
- b->drawable &&
+ b->ws.drawable &&
b->type == WINDOW) {
XSync(b->xm_visual->display, False);
- if (!window_exists( b->xm_visual->display, b->drawable )) {
+ if (!window_exists( b->xm_visual->display, b->ws.drawable )) {
/* found a dead window, free the ancillary info */
XMesaDestroyBuffer( b );
}
@@ -1271,3 +1217,10 @@ XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
{
}
+
+void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask)
+{
+ if (dst->st->copy)
+ dst->st->copy(dst->st, src->st, mask);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 004cb260dcd..4f2c8a6e6a9 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -58,25 +58,31 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "main/mtypes.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
+#include "state_tracker/st_api.h"
#include "os/os_thread.h"
+#include "state_tracker/xlib_sw_winsys.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
-# ifdef USE_XSHM /* was SHM */
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-# endif
+typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;
+struct xmesa_display {
+ pipe_mutex mutex;
+
+ Display *display;
+ struct pipe_screen *screen;
+ struct st_manager *smapi;
+
+ struct pipe_context *pipe;
+};
+
/*
* Create a new X/Mesa visual.
@@ -262,16 +268,13 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
int format, int target, int mipmap);
+extern void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
/***********************************************************************
*/
-extern pipe_mutex _xmesa_lock;
-
-extern struct xmesa_buffer *XMesaBufferList;
-
-
/**
* Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
@@ -284,6 +287,8 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
+
+ struct st_visual stvis;
};
@@ -292,7 +297,7 @@ struct xmesa_visual {
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
- struct st_context *st;
+ struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
@@ -315,7 +320,8 @@ typedef enum {
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
- struct st_framebuffer *stfb;
+ struct st_framebuffer_iface *stfb;
+ struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
@@ -329,13 +335,6 @@ struct xmesa_buffer {
XImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
- GLuint shm; /* X Shared Memory extension status: */
- /* 0 = not available */
- /* 1 = XImage support available */
- /* 2 = Pixmap support available too */
-#if defined(USE_XSHM)
- XShmSegmentInfo shminfo;
-#endif
GC gc; /* scratch GC for span, line, tri drawing */
@@ -345,32 +344,14 @@ struct xmesa_buffer {
GLint TextureMipmap; /** 0 or 1 */
struct xmesa_buffer *Next; /* Linked list pointer: */
-};
+ unsigned width, height;
+};
-/** cast wrapper */
-static INLINE XMesaContext
-xmesa_context(GLcontext *ctx)
-{
- return (XMesaContext) ctx->DriverCtx;
-}
-
-
-/** cast wrapper */
-static INLINE XMesaBuffer
-xmesa_buffer(GLframebuffer *fb)
-{
- struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
- return (XMesaBuffer) st_framebuffer_private(stfb);
-}
-
-
-extern void
-xmesa_init(void);
extern void
-xmesa_delete_framebuffer(struct gl_framebuffer *fb);
+xmesa_init(Display *dpy);
extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);
@@ -380,7 +361,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
+xmesa_check_buffer_size(XMesaBuffer b);
extern void
xmesa_destroy_buffers_on_display(Display *dpy);
@@ -388,17 +369,15 @@ xmesa_destroy_buffers_on_display(Display *dpy);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
{
- return b->stfb->Base.Width;
+ return b->width;
}
static INLINE GLuint
xmesa_buffer_height(XMesaBuffer b)
{
- return b->stfb->Base.Height;
+ return b->height;
}
-extern int
-xmesa_check_for_xshm(Display *display);
#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_public.h
index 4bd5b5c8d3b..950eb21521f 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_public.h
@@ -26,27 +26,23 @@
*
**************************************************************************/
-#ifndef XM_WINSYS_H
-#define XM_WINSYS_H
+#ifndef XM_PUBLIC_H
+#define XM_PUBLIC_H
-struct pipe_context;
-struct pipe_screen;
-struct pipe_surface;
-struct xmesa_buffer;
+#include <X11/Xlib.h>
+struct pipe_screen;
+struct st_api;
+/* This is the driver interface required by the glx/xlib state tracker.
+ */
struct xm_driver {
-
- struct pipe_screen *(*create_pipe_screen)( void );
-
- void (*display_surface)( struct xmesa_buffer *,
- struct pipe_surface * );
-
+ struct pipe_screen *(*create_pipe_screen)( Display *display );
+ struct st_api *(*create_st_api)( void );
};
-
extern void
xmesa_set_driver( const struct xm_driver *driver );
-#endif
+#endif /* XM_PUBLIC_H */
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
new file mode 100644
index 00000000000..b6ed7e8e1e8
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -0,0 +1,332 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "xm_api.h"
+#include "xm_st.h"
+
+struct xmesa_st_framebuffer {
+ XMesaDisplay display;
+ XMesaBuffer buffer;
+ struct pipe_screen *screen;
+
+ struct st_visual stvis;
+
+ unsigned texture_width, texture_height, texture_mask;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+
+ struct pipe_surface *display_surface;
+};
+
+static INLINE struct xmesa_st_framebuffer *
+xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
+}
+
+/**
+ * Display an attachment to the xlib_drawable of the framebuffer.
+ */
+static boolean
+xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *ptex = xstfb->textures[statt];
+ struct pipe_surface *psurf;
+
+ if (!ptex)
+ return TRUE;
+
+ psurf = xstfb->display_surface;
+ /* (re)allocate the surface for the texture to be displayed */
+ if (!psurf || psurf->texture != ptex) {
+ pipe_surface_reference(&xstfb->display_surface, NULL);
+
+ psurf = xstfb->screen->get_tex_surface(xstfb->screen,
+ ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
+ return FALSE;
+
+ xstfb->display_surface = psurf;
+ }
+
+ xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+
+ return TRUE;
+}
+
+/**
+ * Copy the contents between the attachments.
+ */
+static void
+xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src_statt,
+ enum st_attachment_type dst_statt,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *src_ptex = xstfb->textures[src_statt];
+ struct pipe_texture *dst_ptex = xstfb->textures[dst_statt];
+ struct pipe_surface *src, *dst;
+ struct pipe_context *pipe;
+
+ if (!src_ptex || !dst_ptex)
+ return;
+
+ pipe = xstfb->display->pipe;
+ if (!pipe) {
+ pipe = xstfb->screen->context_create(xstfb->screen, NULL);
+ if (!pipe)
+ return;
+ xstfb->display->pipe = pipe;
+ }
+
+ src = xstfb->screen->get_tex_surface(xstfb->screen,
+ src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ dst = xstfb->screen->get_tex_surface(xstfb->screen,
+ dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ if (src && dst)
+ pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/**
+ * Remove outdated textures and create the requested ones.
+ */
+static void
+xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
+ unsigned width, unsigned height,
+ unsigned mask)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture templ;
+ unsigned i;
+
+ /* remove outdated textures */
+ if (xstfb->texture_width != width || xstfb->texture_height != height) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (xstfb->textures[i] || !(mask & (1 << i))) {
+ /* remember the texture */
+ if (xstfb->textures[i])
+ mask |= (1 << i);
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = xstfb->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = xstfb->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ xstfb->textures[i] =
+ xstfb->screen->texture_create(xstfb->screen, &templ);
+ }
+ }
+
+ xstfb->texture_width = width;
+ xstfb->texture_height = height;
+ xstfb->texture_mask = mask;
+}
+
+static boolean
+xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ unsigned statt_mask, new_mask, i;
+ boolean resized;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= 1 << statts[i];
+ /* record newly allocated textures */
+ new_mask = statt_mask & ~xstfb->texture_mask;
+
+ resized = (xstfb->buffer->width != xstfb->texture_width ||
+ xstfb->buffer->height != xstfb->texture_height);
+
+ /* revalidate textures */
+ if (resized || new_mask) {
+ xmesa_st_framebuffer_validate_textures(stfbi,
+ xstfb->buffer->width, xstfb->buffer->height, statt_mask);
+
+ if (!resized) {
+ enum st_attachment_type back, front;
+
+ back = ST_ATTACHMENT_BACK_LEFT;
+ front = ST_ATTACHMENT_FRONT_LEFT;
+ /* copy the contents if front is newly allocated and back is not */
+ if ((statt_mask & (1 << back)) &&
+ (new_mask & (1 << front)) &&
+ !(new_mask & (1 << back))) {
+ xmesa_st_framebuffer_copy_textures(stfbi, back, front,
+ 0, 0, xstfb->texture_width, xstfb->texture_height);
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], xstfb->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, statt);
+ if (ret)
+ xmesa_check_buffer_size(xstfb->buffer);
+
+ return ret;
+}
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
+{
+ struct st_framebuffer_iface *stfbi;
+ struct xmesa_st_framebuffer *xstfb;
+
+ assert(xmdpy->display == b->xm_visual->display);
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
+ if (!stfbi || !xstfb) {
+ if (stfbi)
+ FREE(stfbi);
+ if (xstfb)
+ FREE(xstfb);
+ return NULL;
+ }
+
+ xstfb->display = xmdpy;
+ xstfb->buffer = b;
+ xstfb->screen = xmdpy->screen;
+ xstfb->stvis = b->xm_visual->stvis;
+
+ stfbi->visual = &xstfb->stvis;
+ stfbi->flush_front = xmesa_st_framebuffer_flush_front;
+ stfbi->validate = xmesa_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) xstfb;
+
+ return stfbi;
+}
+
+void
+xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ int i;
+
+ pipe_surface_reference(&xstfb->display_surface, NULL);
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+
+ FREE(xstfb);
+ FREE(stfbi);
+}
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT);
+ if (ret) {
+ struct pipe_texture **front, **back, *tmp;
+
+ front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
+ back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
+ /* swap textures only if the front texture has been allocated */
+ if (*front) {
+ tmp = *front;
+ *front = *back;
+ *back = tmp;
+ }
+
+ xmesa_check_buffer_size(xstfb->buffer);
+ }
+}
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h)
+{
+ xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
+ if (dst == ST_ATTACHMENT_FRONT_LEFT)
+ xmesa_st_framebuffer_display(stfbi, dst);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.h b/src/gallium/state_trackers/glx/xlib/xm_st.h
new file mode 100644
index 00000000000..396495c1893
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.h
@@ -0,0 +1,51 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef _XM_ST_H_
+#define _XM_ST_H_
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/st_api.h"
+
+#include "xm_api.h"
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b);
+
+void
+xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h);
+
+#endif /* _XM_ST_H_ */
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 527e065cd91..781f54bf2b9 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -24,6 +24,7 @@ if 'python' in env['statetrackers']:
'ws2_32',
])
else:
+ env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY'])
env.Append(LIBS = [
'GL',
'X11',
@@ -33,31 +34,27 @@ if 'python' in env['statetrackers']:
'gallium.i',
'st_device.c',
'st_sample.c',
+ 'st_hardpipe_winsys.c',
+ 'st_softpipe_winsys.c',
]
- drivers = [
- trace
- ]
+ env.Prepend(LIBS = [
+ ws_null,
+ trace,
+ gallium,
+ ])
if 'llvmpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_LLVMPIPE'])
env.Tool('llvm')
- sources += ['st_llvmpipe_winsys.c']
- drivers += [llvmpipe]
- else:
- sources += ['st_softpipe_winsys.c']
- drivers += [softpipe]
-
- pyst = env.ConvenienceLibrary(
- target = 'pyst',
- source = sources,
- )
+ env.Prepend(LIBS = [llvmpipe])
+ if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_SOFTPIPE'])
+ env.Prepend(LIBS = [softpipe])
env['no_import_lib'] = 1
env.SharedLibrary(
target = '_gallium',
- source = [
- 'st_hardpipe_winsys.c',
- ],
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
+ source = sources,
)
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index ffb084e358b..632d71ccbee 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -49,6 +49,7 @@
#include "util/u_format.h"
#include "util/u_dump.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
#include "tgsi/tgsi_text.h"
#include "tgsi/tgsi_dump.h"
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 3f36ccb6217..bccaeead015 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -51,7 +51,7 @@ struct st_context {
void set_blend( const struct pipe_blend_state *state ) {
cso_set_blend($self->cso, state);
}
-
+
void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) {
cso_single_sampler($self->cso, index, state);
cso_single_sampler_done($self->cso);
@@ -169,22 +169,39 @@ struct st_context {
void set_fragment_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->fragment_sampler_textures[index], texture);
- $self->pipe->set_fragment_sampler_textures($self->pipe,
- PIPE_MAX_SAMPLERS,
- $self->fragment_sampler_textures);
+ pipe_sampler_view_reference(&$self->fragment_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->fragment_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+ $self->pipe->set_fragment_sampler_views($self->pipe,
+ PIPE_MAX_SAMPLERS,
+ $self->fragment_sampler_views);
}
void set_vertex_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->vertex_sampler_textures[index], texture);
- $self->pipe->set_vertex_sampler_textures($self->pipe,
- PIPE_MAX_VERTEX_SAMPLERS,
- $self->vertex_sampler_textures);
+ pipe_sampler_view_reference(&$self->vertex_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->vertex_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+
+ $self->pipe->set_vertex_sampler_views($self->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ $self->vertex_sampler_views);
}
void set_vertex_buffer(unsigned index,
@@ -222,9 +239,9 @@ struct st_context {
void set_vertex_elements(unsigned num)
{
$self->num_vertex_elements = num;
- $self->pipe->set_vertex_elements($self->pipe,
- $self->num_vertex_elements,
- $self->vertex_elements);
+ cso_set_vertex_elements($self->cso,
+ $self->num_vertex_elements,
+ $self->vertex_elements);
}
/*
@@ -263,8 +280,11 @@ struct st_context {
struct pipe_context *pipe = $self->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_buffer *vbuf;
+ struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_buffer vbuffer;
float *map;
unsigned size;
+ unsigned i;
size = num_verts * num_attribs * 4 * sizeof(float);
@@ -280,9 +300,31 @@ struct st_context {
goto error2;
memcpy(map, vertices, size);
pipe_buffer_unmap(screen, vbuf);
-
- util_draw_vertex_buffer(pipe, vbuf, 0, prim, num_verts, num_attribs);
-
+
+ cso_save_vertex_elements($self->cso);
+
+ /* tell pipe about the vertex attributes */
+ for (i = 0; i < num_attribs; i++) {
+ velements[i].src_offset = i * 4 * sizeof(float);
+ velements[i].instance_divisor = 0;
+ velements[i].vertex_buffer_index = 0;
+ velements[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+ cso_set_vertex_elements($self->cso, num_attribs, velements);
+
+ /* tell pipe about the vertex buffer */
+ memset(&vbuffer, 0, sizeof(vbuffer));
+ vbuffer.buffer = vbuf;
+ vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
+ vbuffer.buffer_offset = 0;
+ vbuffer.max_index = num_verts - 1;
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+
+ /* draw */
+ pipe->draw_arrays(pipe, prim, 0, num_verts);
+
+ cso_restore_vertex_elements($self->cso);
+
error2:
pipe_buffer_reference(&vbuf, NULL);
error1:
@@ -290,6 +332,13 @@ error1:
}
void
+ clear(unsigned buffers, const float *rgba, double depth = 0.0f,
+ unsigned stencil = 0)
+ {
+ $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil);
+ }
+
+ void
flush(unsigned flags = 0) {
struct pipe_fence_handle *fence = NULL;
$self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence);
@@ -345,10 +394,253 @@ error1:
pipe_surface_reference(&_dst, NULL);
}
- void clear(unsigned buffers, const float *rgba, double depth = 0.0f,
- unsigned stencil = 0)
+ %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
+ void
+ surface_read_raw(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ char **STRING, int *LENGTH)
{
- $self->pipe->clear($self->pipe, buffers, rgba, depth, stencil);
+ struct pipe_texture *texture = surface->texture;
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ unsigned stride;
+
+ stride = util_format_get_stride(texture->format, w);
+ *LENGTH = util_format_get_nblocksy(texture->format, h) * stride;
+ *STRING = (char *) malloc(*LENGTH);
+ if(!*STRING)
+ return;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_raw(pipe, transfer, 0, 0, w, h, *STRING, stride);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ %cstring_input_binary(const char *STRING, unsigned LENGTH);
+ void
+ surface_write_raw(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const char *STRING, unsigned LENGTH, unsigned stride = 0)
+ {
+ struct pipe_texture *texture = surface->texture;
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+
+ if(stride == 0)
+ stride = util_format_get_stride(texture->format, w);
+
+ if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride)
+ SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size");
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(!transfer)
+ SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer");
+
+ pipe_put_tile_raw(pipe, transfer, 0, 0, w, h, STRING, stride);
+ pipe->tex_transfer_destroy(pipe, transfer);
+
+ fail:
+ return;
+ }
+
+ void
+ surface_read_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ float *rgba)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_write_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const float *rgba)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(transfer) {
+ pipe_put_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
+ void
+ surface_read_rgba8(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ char **STRING, int *LENGTH)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ float *rgba;
+ unsigned char *rgba8;
+ unsigned i, j, k;
+
+ *LENGTH = 0;
+ *STRING = NULL;
+
+ if (!surface)
+ return;
+
+ *LENGTH = h*w*4;
+ *STRING = (char *) malloc(*LENGTH);
+ if(!*STRING)
+ return;
+
+ rgba = malloc(h*w*4*sizeof(float));
+ if(!rgba)
+ return;
+
+ rgba8 = (unsigned char *) *STRING;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y,
+ w, h);
+ if(transfer) {
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba);
+ for(j = 0; j < h; ++j) {
+ for(i = 0; i < w; ++i)
+ for(k = 0; k <4; ++k)
+ rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]);
+ }
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+
+ free(rgba);
+ }
+
+ void
+ surface_read_z(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ unsigned *z)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(transfer) {
+ pipe_get_tile_z(pipe, transfer, 0, 0, w, h, z);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_write_z(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const unsigned *z)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ x, y, w, h);
+ if(transfer) {
+ pipe_put_tile_z(pipe, transfer, 0, 0, w, h, z);
+ pipe->tex_transfer_destroy(pipe, transfer);
+ }
+ }
+
+ void
+ surface_sample_rgba(struct st_surface *surface,
+ float *rgba)
+ {
+ st_sample_surface($self->pipe, surface, rgba);
+ }
+
+ unsigned
+ surface_compare_rgba(struct st_surface *surface,
+ unsigned x, unsigned y, unsigned w, unsigned h,
+ const float *rgba, float tol = 0.0)
+ {
+ struct pipe_context *pipe = $self->pipe;
+ struct pipe_transfer *transfer;
+ float *rgba2;
+ const float *p1;
+ const float *p2;
+ unsigned i, j, n;
+
+ rgba2 = MALLOC(h*w*4*sizeof(float));
+ if(!rgba2)
+ return ~0;
+
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_READ,
+ x, y, w, h);
+ if(!transfer) {
+ FREE(rgba2);
+ return ~0;
+ }
+
+ pipe_get_tile_rgba(pipe, transfer, 0, 0, w, h, rgba2);
+ pipe->tex_transfer_destroy(pipe, transfer);
+
+ p1 = rgba;
+ p2 = rgba2;
+ n = 0;
+ for(i = h*w; i; --i) {
+ unsigned differs = 0;
+ for(j = 4; j; --j) {
+ float delta = *p2++ - *p1++;
+ if (delta < -tol || delta > tol)
+ differs = 1;
+ }
+ n += differs;
+ }
+
+ FREE(rgba2);
+
+ return n;
}
};
diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i
index 761587dc533..923a6285289 100644
--- a/src/gallium/state_trackers/python/p_texture.i
+++ b/src/gallium/state_trackers/python/p_texture.i
@@ -124,234 +124,6 @@ struct st_surface
FREE($self);
}
- %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
- void get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH)
- {
- struct pipe_texture *texture = $self->texture;
- struct pipe_screen *screen = texture->screen;
- struct pipe_transfer *transfer;
- unsigned stride;
-
- stride = util_format_get_stride(texture->format, w);
- *LENGTH = util_format_get_nblocksy(texture->format, h) * stride;
- *STRING = (char *) malloc(*LENGTH);
- if(!*STRING)
- return;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_raw(transfer, 0, 0, w, h, *STRING, stride);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- %cstring_input_binary(const char *STRING, unsigned LENGTH);
- void put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *STRING, unsigned LENGTH, unsigned stride = 0)
- {
- struct pipe_texture *texture = $self->texture;
- struct pipe_screen *screen = texture->screen;
- struct pipe_transfer *transfer;
-
- if(stride == 0)
- stride = util_format_get_stride(texture->format, w);
-
- if(LENGTH < util_format_get_nblocksy(texture->format, h) * stride)
- SWIG_exception(SWIG_ValueError, "offset must be smaller than buffer size");
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(!transfer)
- SWIG_exception(SWIG_MemoryError, "couldn't initiate transfer");
-
- pipe_put_tile_raw(transfer, 0, 0, w, h, STRING, stride);
- screen->tex_transfer_destroy(transfer);
-
- fail:
- return;
- }
-
- void
- get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(transfer) {
- pipe_put_tile_rgba(transfer, 0, 0, w, h, rgba);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1));
- void
- get_tile_rgba8(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- float *rgba;
- unsigned char *rgba8;
- unsigned i, j, k;
-
- *LENGTH = 0;
- *STRING = NULL;
-
- if (!$self)
- return;
-
- *LENGTH = h*w*4;
- *STRING = (char *) malloc(*LENGTH);
- if(!*STRING)
- return;
-
- rgba = malloc(h*w*4*sizeof(float));
- if(!rgba)
- return;
-
- rgba8 = (unsigned char *) *STRING;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y,
- w, h);
- if(transfer) {
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba);
- for(j = 0; j < h; ++j) {
- for(i = 0; i < w; ++i)
- for(k = 0; k <4; ++k)
- rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[j*w*4 + i*4 + k]);
- }
- screen->tex_transfer_destroy(transfer);
- }
-
- free(rgba);
- }
-
- void
- get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(transfer) {
- pipe_get_tile_z(transfer, 0, 0, w, h, z);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_WRITE,
- x, y, w, h);
- if(transfer) {
- pipe_put_tile_z(transfer, 0, 0, w, h, z);
- screen->tex_transfer_destroy(transfer);
- }
- }
-
- void
- sample_rgba(float *rgba) {
- st_sample_surface($self, rgba);
- }
-
- unsigned
- compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0)
- {
- struct pipe_screen *screen = $self->texture->screen;
- struct pipe_transfer *transfer;
- float *rgba2;
- const float *p1;
- const float *p2;
- unsigned i, j, n;
-
- rgba2 = MALLOC(h*w*4*sizeof(float));
- if(!rgba2)
- return ~0;
-
- transfer = screen->get_tex_transfer(screen,
- $self->texture,
- $self->face,
- $self->level,
- $self->zslice,
- PIPE_TRANSFER_READ,
- x, y, w, h);
- if(!transfer) {
- FREE(rgba2);
- return ~0;
- }
-
- pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba2);
- screen->tex_transfer_destroy(transfer);
-
- p1 = rgba;
- p2 = rgba2;
- n = 0;
- for(i = h*w; i; --i) {
- unsigned differs = 0;
- for(j = 4; j; --j) {
- float delta = *p2++ - *p1++;
- if (delta < -tol || delta > tol)
- differs = 1;
- }
- n += differs;
- }
-
- FREE(rgba2);
-
- return n;
- }
};
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 45e78417500..44d65e3fc1e 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -31,11 +31,12 @@
#include "pipe/p_shader_tokens.h"
#include "util/u_inlines.h"
#include "cso_cache/cso_context.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
+#include "trace/tr_public.h"
#include "st_device.h"
#include "st_winsys.h"
@@ -75,43 +76,34 @@ st_device_destroy(struct st_device *st_dev)
}
-static struct st_device *
-st_device_create_from_st_winsys(const struct st_winsys *st_ws)
+struct st_device *
+st_device_create(boolean hardware)
{
+ struct pipe_screen *screen;
struct st_device *st_dev;
-
- if(!st_ws->screen_create)
- return NULL;
-
+
+ if (hardware)
+ screen = st_hardware_screen_create();
+ else
+ screen = st_software_screen_create();
+
+ screen = trace_screen_create(screen);
+ if (!screen)
+ goto no_screen;
+
st_dev = CALLOC_STRUCT(st_device);
- if(!st_dev)
- return NULL;
+ if (!st_dev)
+ goto no_device;
pipe_reference_init(&st_dev->reference, 1);
- st_dev->st_ws = st_ws;
-
- st_dev->real_screen = st_ws->screen_create();
- if(!st_dev->real_screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
-
- st_dev->screen = trace_screen_create(st_dev->real_screen);
- if(!st_dev->screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
+ st_dev->screen = screen;
return st_dev;
-}
-
-struct st_device *
-st_device_create(boolean hardware) {
- if(hardware)
- return st_device_create_from_st_winsys(&st_hardpipe_winsys);
- else
- return st_device_create_from_st_winsys(&st_softpipe_winsys);
+no_device:
+ screen->destroy(screen);
+no_screen:
+ return NULL;
}
@@ -134,9 +126,9 @@ st_context_destroy(struct st_context *st_ctx)
st_ctx->pipe->destroy(st_ctx->pipe);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], NULL);
for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], NULL);
pipe_texture_reference(&st_ctx->default_texture, NULL);
FREE(st_ctx);
@@ -237,9 +229,12 @@ st_context_create(struct st_device *st_dev)
/* default textures */
{
+ struct pipe_context *pipe = st_ctx->pipe;
struct pipe_screen *screen = st_dev->screen;
struct pipe_texture templat;
struct pipe_transfer *transfer;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
unsigned i;
memset( &templat, 0, sizeof( templat ) );
@@ -252,31 +247,44 @@ st_context_create(struct st_device *st_dev)
st_ctx->default_texture = screen->texture_create( screen, &templat );
if(st_ctx->default_texture) {
- transfer = screen->get_tex_transfer(screen,
- st_ctx->default_texture,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0,
- st_ctx->default_texture->width0,
- st_ctx->default_texture->height0);
+ transfer = pipe->get_tex_transfer(pipe,
+ st_ctx->default_texture,
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0,
+ st_ctx->default_texture->width0,
+ st_ctx->default_texture->height0);
if (transfer) {
uint32_t *map;
- map = (uint32_t *) screen->transfer_map(screen, transfer);
+ map = (uint32_t *) pipe->transfer_map(pipe, transfer);
if(map) {
*map = 0x00000000;
- screen->transfer_unmap(screen, transfer);
+ pipe->transfer_unmap(pipe, transfer);
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
-
+
+ u_sampler_view_default_template(&view_templ,
+ st_ctx->default_texture,
+ st_ctx->default_texture->format);
+ view = st_ctx->pipe->create_sampler_view(st_ctx->pipe,
+ st_ctx->default_texture,
+ &view_templ);
+
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], view);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture);
-
- cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures);
- cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], view);
+
+ st_ctx->pipe->set_fragment_sampler_views(st_ctx->pipe,
+ PIPE_MAX_SAMPLERS,
+ st_ctx->fragment_sampler_views);
+ st_ctx->pipe->set_vertex_sampler_views(st_ctx->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ st_ctx->vertex_sampler_views);
+
+ pipe_sampler_view_reference(&view, NULL);
}
/* vertex shader */
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index de9e0215d8e..dcd0dc6e273 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -47,7 +47,8 @@ struct st_surface
};
-struct st_context {
+struct st_context
+{
struct st_device *st_dev;
struct pipe_context *pipe;
@@ -59,8 +60,8 @@ struct st_context {
void *gs;
struct pipe_texture *default_texture;
- struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_sampler_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned num_vertex_buffers;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
@@ -72,13 +73,11 @@ struct st_context {
};
-struct st_device {
+struct st_device
+{
/* FIXME: we also need to refcount for textures and surfaces... */
struct pipe_reference reference;
- const struct st_winsys *st_ws;
-
- struct pipe_screen *real_screen;
struct pipe_screen *screen;
};
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index a3110a19d5d..b141177b793 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -54,11 +54,6 @@ static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
#ifdef PIPE_OS_WINDOWS
static INLINE boolean
@@ -207,16 +202,11 @@ st_hardpipe_load(void)
#endif
-static struct pipe_screen *
-st_hardpipe_screen_create(void)
+struct pipe_screen *
+st_hardware_screen_create(void)
{
if(st_hardpipe_load())
return pfnGetGalliumScreenMESA();
else
- return st_softpipe_winsys.screen_create();
+ return st_software_screen_create();
}
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &st_hardpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
deleted file mode 100644
index 5d83b5a9e15..00000000000
--- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Llvmpipe support.
- *
- * @author Jose Fonseca
- */
-
-
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "st_winsys.h"
-
-
-static boolean
-llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
- enum pipe_format format )
-{
- return FALSE;
-}
-
-
-static void *
-llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags )
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
-{
- assert(0);
-}
-
-
-static struct llvmpipe_displaytarget *
-llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride)
-{
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-st_llvmpipe_screen_create(void)
-{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if (!winsys)
- goto no_winsys;
-
- winsys->destroy = llvmpipe_ws_destroy;
- winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported;
- winsys->displaytarget_create = llvmpipe_ws_displaytarget_create;
- winsys->displaytarget_map = llvmpipe_ws_displaytarget_map;
- winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap;
- winsys->displaytarget_display = llvmpipe_ws_displaytarget_display;
- winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy;
-
- screen = llvmpipe_create_screen(winsys);
- if (!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
-}
-
-
-
-const struct st_winsys st_softpipe_winsys = {
- &st_llvmpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index e1808153461..e2c1e060174 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -523,29 +523,30 @@ st_sample_pixel_block(enum pipe_format format,
void
-st_sample_surface(struct st_surface *surface, float *rgba)
+st_sample_surface(struct pipe_context *pipe,
+ struct st_surface *surface,
+ float *rgba)
{
struct pipe_texture *texture = surface->texture;
- struct pipe_screen *screen = texture->screen;
unsigned width = u_minify(texture->width0, surface->level);
unsigned height = u_minify(texture->height0, surface->level);
uint rgba_stride = width * 4;
struct pipe_transfer *transfer;
void *raw;
- transfer = screen->get_tex_transfer(screen,
- surface->texture,
- surface->face,
- surface->level,
- surface->zslice,
- PIPE_TRANSFER_WRITE,
- 0, 0,
- width,
- height);
+ transfer = pipe->get_tex_transfer(pipe,
+ surface->texture,
+ surface->face,
+ surface->level,
+ surface->zslice,
+ PIPE_TRANSFER_WRITE,
+ 0, 0,
+ width,
+ height);
if (!transfer)
return;
- raw = screen->transfer_map(screen, transfer);
+ raw = pipe->transfer_map(pipe, transfer);
if (raw) {
enum pipe_format format = texture->format;
uint x, y;
@@ -567,8 +568,8 @@ st_sample_surface(struct st_surface *surface, float *rgba)
}
}
- screen->transfer_unmap(screen, transfer);
+ pipe->transfer_unmap(pipe, transfer);
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h
index 888114d3021..6fb8417add8 100644
--- a/src/gallium/state_trackers/python/st_sample.h
+++ b/src/gallium/state_trackers/python/st_sample.h
@@ -32,6 +32,9 @@
#include "pipe/p_format.h"
+struct pipe_context;
+struct st_surface;
+
void
st_sample_pixel_block(enum pipe_format format,
@@ -40,7 +43,9 @@ st_sample_pixel_block(enum pipe_format format,
unsigned w, unsigned h);
void
-st_sample_surface(struct st_surface *surface, float *rgba);
+st_sample_surface(struct pipe_context *pipe,
+ struct st_surface *surface,
+ float *rgba);
#endif /* ST_SAMPLE_H_ */
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 81676bc3a4f..0a332aaa9f1 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -26,18 +26,47 @@
*
**************************************************************************/
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-#include "softpipe/sp_winsys.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "state_tracker/sw_winsys.h"
+#include "sw/null/null_sw_winsys.h"
#include "st_winsys.h"
-const struct st_winsys st_softpipe_winsys = {
- &softpipe_create_screen_malloc
-};
+
+struct pipe_screen *
+st_software_screen_create(void)
+{
+ struct sw_winsys *ws;
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(HAVE_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(HAVE_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ ws = null_sw_create();
+ if(!ws)
+ return NULL;
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#ifdef HAVE_LLVMPIPE
+ if (strcmp(driver, "llvmpipe") == 0) {
+ screen = llvmpipe_create_screen(ws);
+ }
+#endif
+
+#ifdef HAVE_SOFTPIPE
+ if (strcmp(driver, "softpipe") == 0) {
+ screen = softpipe_create_screen(ws);
+ }
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index 0c7b6a200e1..e1a99383a41 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -31,19 +31,13 @@
struct pipe_screen;
-struct pipe_context;
-struct st_winsys
-{
- struct pipe_screen *
- (*screen_create)(void);
-};
+struct pipe_screen *
+st_hardware_screen_create(void);
-
-extern const struct st_winsys st_softpipe_winsys;
-
-extern const struct st_winsys st_hardpipe_winsys;
+struct pipe_screen *
+st_software_screen_create(void);
#endif /* ST_WINSYS_H_ */
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 037d8dc911a..7c315de8271 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -25,6 +25,7 @@ VG_SOURCES = \
api_transform.c \
vgu.c \
vg_context.c \
+ vg_manager.c \
vg_state.c \
vg_tracker.c \
vg_translate.c \
@@ -53,7 +54,7 @@ INCLUDE_DIRS = \
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c
index 47db102dd2d..eb2fbe26e7f 100644
--- a/src/gallium/state_trackers/vega/api_context.c
+++ b/src/gallium/state_trackers/vega/api_context.c
@@ -26,6 +26,7 @@
#include "VG/openvg.h"
+#include "vg_manager.h"
#include "vg_context.h"
#include "pipe/p_context.h"
@@ -55,6 +56,8 @@ void vgFlush(void)
pipe = ctx->pipe;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ vg_manager_flush_frontbuffer(ctx);
}
void vgFinish(void)
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 02248ad4337..a643f38624f 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "asm_filters.h"
@@ -53,7 +54,7 @@ struct filter_info {
const void *const_buffer;
VGint const_buffer_len;
VGTilingMode tiling_mode;
- struct pipe_texture *extra_texture;
+ struct pipe_sampler_view *extra_texture_view;
};
static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
@@ -78,26 +79,48 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
{ /* upload color_data */
struct pipe_transfer *transfer =
- screen->get_tex_transfer(screen, tex,
- 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE ,
- 0, 0, tex->width0, tex->height0);
- void *map = screen->transfer_map(screen, transfer);
+ pipe->get_tex_transfer(pipe, tex,
+ 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE ,
+ 0, 0, tex->width0, tex->height0);
+ void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, color_data, sizeof(VGint)*color_data_len);
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
return tex;
}
+static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context *ctx,
+ const VGuint *color_data,
+ const VGint color_data_len)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_texture_1d(ctx, color_data, color_data_len);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
static INLINE struct pipe_surface * setup_framebuffer(struct vg_image *dst)
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb;
struct pipe_surface *dst_surf = pipe->screen->get_tex_surface(
- pipe->screen, dst->texture, 0, 0, 0,
+ pipe->screen, dst->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* drawing dest */
@@ -168,7 +191,7 @@ static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state sampler[3];
int num_samplers = 0;
int num_textures = 0;
@@ -177,10 +200,10 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
+ sampler_views[2] = NULL;
+ sampler_views[3] = NULL;
memset(&sampler[0], 0, sizeof(struct pipe_sampler_state));
sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -215,21 +238,21 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
}
samplers[0] = &sampler[0];
- textures[0] = info->src->texture;
+ sampler_views[0] = info->src->sampler_view;
++num_samplers;
++num_textures;
- if (info->extra_texture) {
+ if (info->extra_texture_view) {
memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
samplers[1] = &sampler[1];
- textures[1] = info->extra_texture;
+ sampler_views[1] = info->extra_texture_view;
++num_samplers;
++num_textures;
}
cso_set_samplers(ctx->cso_context, num_samplers, (const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, num_textures, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, num_textures, sampler_views);
}
static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
@@ -308,7 +331,7 @@ static void execute_filter(struct vg_context *ctx,
cso_save_viewport(ctx->cso_context);
cso_save_blend(ctx->cso_context);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
+ cso_save_fragment_sampler_views(ctx->cso_context);
dst_surf = setup_framebuffer(info->dst);
setup_viewport(info->dst);
@@ -318,7 +341,7 @@ static void execute_filter(struct vg_context *ctx,
setup_samplers(ctx, info);
renderer_draw_texture(ctx->renderer,
- info->src->texture,
+ info->src->sampler_view->texture,
info->dst->x, info->dst->y,
info->dst->x + info->dst->width,
info->dst->y + info->dst->height,
@@ -331,7 +354,7 @@ static void execute_filter(struct vg_context *ctx,
cso_restore_viewport(ctx->cso_context);
cso_restore_blend(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
vg_shader_destroy(ctx, shader);
@@ -369,7 +392,7 @@ void vgColorMatrix(VGImage dst, VGImage src,
info.const_buffer = matrix;
info.const_buffer_len = 20 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
}
@@ -479,7 +502,7 @@ void vgConvolve(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -669,7 +692,7 @@ void vgGaussianBlur(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -688,7 +711,7 @@ void vgLookup(VGImage dst, VGImage src,
struct vg_image *d, *s;
VGuint color_data[256];
VGint i;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
@@ -714,7 +737,7 @@ void vgLookup(VGImage dst, VGImage src,
color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 |
redLUT[i] << 8 | alphaLUT[i];
}
- lut_texture = create_texture_1d(ctx, color_data, 255);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 255);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -728,11 +751,11 @@ void vgLookup(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
void vgLookupSingle(VGImage dst, VGImage src,
@@ -743,7 +766,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
VGuint color_data[256];
@@ -783,7 +806,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
color_data[i] = blue << 24 | green << 16 |
red << 8 | alpha;
}
- lut_texture = create_texture_1d(ctx, color_data, 256);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 256);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -797,9 +820,9 @@ void vgLookupSingle(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c
index 015241498ed..fec473d9d23 100644
--- a/src/gallium/state_trackers/vega/api_images.c
+++ b/src/gallium/state_trackers/vega/api_images.c
@@ -397,7 +397,6 @@ void vgReadPixels(void * data, VGint dataStride,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
@@ -442,7 +441,7 @@ void vgReadPixels(void * data, VGint dataStride,
{
struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,
+ transfer = pipe->get_tex_transfer(pipe, strb->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0, width, height);
@@ -451,14 +450,14 @@ void vgReadPixels(void * data, VGint dataStride,
#if 0
debug_printf("%d-%d == %d\n", sy, height, y);
#endif
- pipe_get_tile_rgba(transfer, sx, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, transfer, sx, y, width, 1, df);
y += yStep;
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
dst + yoffset + xoffset);
dst += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 9c123a4cf95..2f2d925252d 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st,
/* draw */
if (buf) {
+ cso_set_vertex_elements(st->cso_context, 2, st->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -115,10 +117,6 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/
- if (st->pipe->screen && st->pipe->screen->update_buffer)
- st->pipe->screen->update_buffer( st->pipe->screen,
- st->pipe->priv );
-
cso_save_blend(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_fragment_shader(st->cso_context);
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 41c979bfecf..c3268a84a60 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -43,6 +43,7 @@
#include "util/u_tile.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
static enum pipe_format vg_format_to_pipe(VGImageFormat format)
{
@@ -81,7 +82,7 @@ static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
static void vg_copy_texture(struct vg_context *ctx,
struct pipe_texture *dst, VGint dx, VGint dy,
- struct pipe_texture *src, VGint sx, VGint sy,
+ struct pipe_sampler_view *src, VGint sx, VGint sy,
VGint width, VGint height)
{
VGfloat dst_loc[4], src_loc[4];
@@ -103,8 +104,8 @@ static void vg_copy_texture(struct vg_context *ctx,
src_loc[3] = height;
src_bounds[0] = 0.f;
src_bounds[1] = 0.f;
- src_bounds[2] = src->width0;
- src_bounds[3] = src->height0;
+ src_bounds[2] = src->texture->width0;
+ src_bounds[3] = src->texture->height0;
vg_bound_rect(src_loc, src_bounds, src_shift);
vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -218,7 +219,7 @@ void vg_copy_surface(struct vg_context *ctx,
static struct pipe_texture *image_texture(struct vg_image *img)
{
- struct pipe_texture *tex = img->texture;
+ struct pipe_texture *tex = img->sampler_view->texture;
return tex;
}
@@ -247,9 +248,12 @@ struct vg_image * image_create(VGImageFormat format,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_context *pipe = ctx->pipe;
struct vg_image *image = CALLOC_STRUCT(vg_image);
enum pipe_format pformat = vg_format_to_pipe(format);
struct pipe_texture pt, *newtex;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_screen *screen = ctx->pipe->screen;
vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
@@ -281,7 +285,12 @@ struct vg_image * image_create(VGImageFormat format,
debug_assert(newtex);
- image->texture = newtex;
+ u_sampler_view_default_template(&view_templ, newtex, newtex->format);
+ view = pipe->create_sampler_view(pipe, newtex, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&newtex, NULL);
+
+ image->sampler_view = view;
vg_context_add_object(ctx, VG_OBJECT_IMAGE, image);
@@ -345,7 +354,7 @@ void image_destroy(struct vg_image *img)
array_destroy(img->children_array);
}
- pipe_texture_reference(&img->texture, NULL);
+ pipe_sampler_view_reference(&img->sampler_view, NULL);
free(img);
}
@@ -378,7 +387,7 @@ void image_sub_data(struct vg_image *image,
VGfloat *df = (VGfloat*)temp;
VGint i;
struct vg_context *ctx = vg_current_context();
- struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_context *pipe = ctx->pipe;
struct pipe_texture *texture = image_texture(image);
VGint xoffset = 0, yoffset = 0;
@@ -412,17 +421,17 @@ void image_sub_data(struct vg_image *image,
}
{ /* upload color_data */
- struct pipe_transfer *transfer = screen->get_tex_transfer(
- screen, texture, 0, 0, 0,
+ struct pipe_transfer *transfer = pipe->get_tex_transfer(
+ pipe, texture, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
src += (dataStride * yoffset);
for (i = 0; i < height; i++) {
_vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp);
- pipe_put_tile_rgba(transfer, x+image->x, y+image->y, width, 1, df);
+ pipe_put_tile_rgba(pipe, transfer, x+image->x, y+image->y, width, 1, df);
y += yStep;
src += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
@@ -435,7 +444,6 @@ void image_get_sub_data(struct vg_image * image,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
VGfloat *df = (VGfloat*)temp;
VGint y = 0, yStep = 1;
@@ -444,8 +452,8 @@ void image_get_sub_data(struct vg_image * image,
{
struct pipe_transfer *transfer =
- screen->get_tex_transfer(screen,
- image->texture, 0, 0, 0,
+ pipe->get_tex_transfer(pipe,
+ image->sampler_view->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0,
image->x + image->width,
@@ -455,13 +463,13 @@ void image_get_sub_data(struct vg_image * image,
#if 0
debug_printf("%d-%d == %d\n", sy, height, y);
#endif
- pipe_get_tile_rgba(transfer, sx+image->x, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, transfer, sx+image->x, y, width, 1, df);
y += yStep;
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst);
dst += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
@@ -479,9 +487,9 @@ struct vg_image * image_child_image(struct vg_image *parent,
image->width = width;
image->height = height;
image->parent = parent;
- image->texture = 0;
- pipe_texture_reference(&image->texture,
- parent->texture);
+ image->sampler_view = NULL;
+ pipe_sampler_view_reference(&image->sampler_view,
+ parent->sampler_view);
image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -515,8 +523,8 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
}
/* make sure rendering has completed */
ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- vg_copy_texture(ctx, dst->texture, dst->x + dx, dst->y + dy,
- src->texture, src->x + sx, src->y + sy, width, height);
+ vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
+ src->sampler_view, src->x + sx, src->y + sy, width, height);
}
void image_draw(struct vg_image *img)
@@ -625,12 +633,12 @@ VGboolean vg_image_overlaps(struct vg_image *dst,
}
VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
img->sampler.min_img_filter = image_sampler_filter(img->base.ctx);
img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx);
samplers[3] = &img->sampler;
- textures[3] = img->texture;
+ sampler_views[3] = img->sampler_view;
return 1;
}
diff --git a/src/gallium/state_trackers/vega/image.h b/src/gallium/state_trackers/vega/image.h
index 78e17cffa64..805b35fab9f 100644
--- a/src/gallium/state_trackers/vega/image.h
+++ b/src/gallium/state_trackers/vega/image.h
@@ -43,7 +43,7 @@ struct vg_image {
struct vg_image *parent;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
struct array *children_array;
@@ -89,7 +89,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
VGint width, VGint height);
VGint image_bind_samplers(struct vg_image *dst, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGboolean vg_image_overlaps(struct vg_image *dst,
struct vg_image *src);
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 839dc19a3b8..316ea7a9c95 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -45,7 +45,7 @@ struct vg_mask_layer {
VGint width;
VGint height;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
};
static INLINE struct pipe_surface *
@@ -54,7 +54,7 @@ alpha_mask_surface(struct vg_context *ctx, int usage)
struct pipe_screen *screen = ctx->pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
return screen->get_tex_surface(screen,
- stfb->alpha_mask,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
usage);
}
@@ -284,35 +284,33 @@ static void setup_mask_operation(VGMaskOperation operation)
cso_set_fragment_shader_handle(ctx->cso_context, shader);
}
-static void setup_mask_samplers(struct pipe_texture *umask)
+static void setup_mask_samplers(struct pipe_sampler_view *umask)
{
struct vg_context *ctx = vg_current_context();
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
- struct pipe_texture *uprev = NULL;
+ struct pipe_sampler_view *uprev = NULL;
struct pipe_sampler_state sampler;
- uprev = fb_buffers->blend_texture;
+ uprev = fb_buffers->blend_texture_view;
sampler = ctx->mask.sampler;
sampler.normalized_coords = 1;
samplers[0] = NULL;
samplers[1] = NULL;
- samplers[2] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
samplers[0] = &sampler;
samplers[1] = &ctx->mask.sampler;
- textures[0] = umask;
- textures[1] = uprev;
+ sampler_views[0] = umask;
+ sampler_views[1] = uprev;
cso_set_samplers(ctx->cso_context, 2,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, 2, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 2, sampler_views);
}
@@ -411,12 +409,13 @@ static void surface_fill(struct pipe_surface *surf,
}
-static void mask_using_texture(struct pipe_texture *texture,
+static void mask_using_texture(struct pipe_sampler_view *sampler_view,
VGMaskOperation operation,
VGint x, VGint y,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_texture *texture = sampler_view->texture;
struct pipe_surface *surface =
alpha_mask_surface(ctx, PIPE_BUFFER_USAGE_GPU_WRITE);
VGint offsets[4], loc[4];
@@ -439,13 +438,13 @@ static void mask_using_texture(struct pipe_texture *texture,
vg_prepare_blend_surface_from_mask(ctx);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
+ cso_save_fragment_sampler_views(ctx->cso_context);
cso_save_framebuffer(ctx->cso_context);
cso_save_blend(ctx->cso_context);
cso_save_fragment_shader(ctx->cso_context);
cso_save_viewport(ctx->cso_context);
- setup_mask_samplers(texture);
+ setup_mask_samplers(sampler_view);
setup_mask_blend();
setup_mask_operation(operation);
setup_mask_framebuffer(surface, surface->width, surface->height);
@@ -463,7 +462,7 @@ static void mask_using_texture(struct pipe_texture *texture,
cso_restore_framebuffer(ctx->cso_context);
cso_restore_fragment_shader(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
cso_restore_viewport(ctx->cso_context);
pipe_surface_reference(&surface, NULL);
@@ -484,7 +483,11 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
{
struct pipe_texture pt;
+ struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view = NULL;
+ struct pipe_texture *texture;
memset(&pt, 0, sizeof(pt));
pt.target = PIPE_TEXTURE_2D;
@@ -496,7 +499,14 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
pt.compressed = 0;
- mask->texture = screen->texture_create(screen, &pt);
+ texture = screen->texture_create(screen, &pt);
+
+ if (texture) {
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ }
+ pipe_texture_reference(&texture, NULL);
+ mask->sampler_view = view;
}
vg_context_add_object(ctx, VG_OBJECT_MASK, mask);
@@ -525,7 +535,7 @@ void mask_layer_fill(struct vg_mask_layer *layer,
alpha_color[3] = value;
surface = ctx->pipe->screen->get_tex_surface(
- ctx->pipe->screen, layer->texture,
+ ctx->pipe->screen, layer->sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -545,10 +555,10 @@ void mask_copy(struct vg_mask_layer *layer,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
renderer_copy_texture(ctx->renderer,
- layer->texture,
+ layer->sampler_view,
sx, sy,
sx + width, sy + height,
- fb_buffers->alpha_mask,
+ fb_buffers->alpha_mask_view->texture,
dx, dy,
dx + width, dy + height);
}
@@ -562,7 +572,7 @@ static void mask_layer_render_to(struct vg_mask_layer *layer,
struct pipe_screen *screen = ctx->pipe->screen;
struct pipe_surface *surface;
- surface = screen->get_tex_surface(screen, layer->texture, 0, 0, 0,
+ surface = screen->get_tex_surface(screen, layer->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
cso_save_framebuffer(ctx->cso_context);
@@ -604,8 +614,8 @@ void mask_render_to(struct path *path,
struct vg_mask_layer *temp_layer;
VGint width, height;
- width = fb_buffers->alpha_mask->width0;
- height = fb_buffers->alpha_mask->width0;
+ width = fb_buffers->alpha_mask_view->texture->width0;
+ height = fb_buffers->alpha_mask_view->texture->width0;
temp_layer = mask_layer_create(width, height);
@@ -622,7 +632,7 @@ void mask_using_layer(struct vg_mask_layer *layer,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(layer->texture, operation,
+ mask_using_texture(layer->sampler_view, operation,
x, y, width, height);
}
@@ -644,7 +654,7 @@ void mask_using_image(struct vg_image *image,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(image->texture, operation,
+ mask_using_texture(image->sampler_view, operation,
x, y, width, height);
}
@@ -672,7 +682,7 @@ void mask_fill(VGint x, VGint y, VGint width, VGint height,
}
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
@@ -680,7 +690,7 @@ VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
samplers[1] = &ctx->mask.sampler;
- textures[1] = fb_buffers->alpha_mask;
+ sampler_views[1] = fb_buffers->alpha_mask_view;
return 1;
} else
return 0;
diff --git a/src/gallium/state_trackers/vega/mask.h b/src/gallium/state_trackers/vega/mask.h
index 5eaaede0e3a..4feacbefda8 100644
--- a/src/gallium/state_trackers/vega/mask.h
+++ b/src/gallium/state_trackers/vega/mask.h
@@ -63,6 +63,6 @@ void mask_fill(VGint x, VGint y,
VGfloat value);
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
#endif
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index cdb87d3bf68..508e1863a57 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -37,6 +37,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -61,7 +62,7 @@ struct vg_paint {
VGfloat vals[5];
VGint valsi[5];
} radial;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
VGfloat *ramp_stops;
@@ -72,7 +73,7 @@ struct vg_paint {
} gradient;
struct {
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
VGTilingMode tiling_mode;
struct pipe_sampler_state sampler;
} pattern;
@@ -164,15 +165,35 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p)
struct pipe_transfer *transfer =
st_no_flush_get_tex_transfer(p->base.ctx, tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
- void *map = screen->transfer_map(screen, transfer);
+ void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
return tex;
}
+static INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p)
+{
+ struct pipe_context *pipe = p->base.ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_gradient_texture(p);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
struct vg_paint * paint_create(struct vg_context *ctx)
{
struct vg_paint *paint = CALLOC_STRUCT(vg_paint);
@@ -207,8 +228,9 @@ struct vg_paint * paint_create(struct vg_context *ctx)
void paint_destroy(struct vg_paint *paint)
{
struct vg_context *ctx = paint->base.ctx;
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
if (ctx)
vg_context_remove_object(ctx, VG_OBJECT_PAINT, paint);
@@ -329,8 +351,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
map[4] = 0.f;
map[5] = 1.f;
- map[6] = paint->pattern.texture->width0;
- map[7] = paint->pattern.texture->height0;
+ map[6] = paint->pattern.sampler_view->texture->width0;
+ map[7] = paint->pattern.sampler_view->texture->height0;
{
struct matrix mat;
memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
@@ -394,12 +416,12 @@ void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
create_gradient_data(stops, num / 5, paint->gradient.color_data,
1024);
- if (paint->gradient.texture) {
- pipe_texture_reference(&paint->gradient.texture, NULL);
- paint->gradient.texture = 0;
+ if (paint->gradient.sampler_view) {
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ paint->gradient.sampler_view = NULL;
}
- paint->gradient.texture = create_gradient_texture(paint);
+ paint->gradient.sampler_view = create_gradient_sampler_view(paint);
}
void paint_set_colori(struct vg_paint *p,
@@ -459,12 +481,12 @@ void paint_set_radial_gradient(struct vg_paint *paint,
void paint_set_pattern(struct vg_paint *paint,
struct vg_image *img)
{
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
- paint->pattern.texture = 0;
- pipe_texture_reference(&paint->pattern.texture,
- img->texture);
+ paint->pattern.sampler_view = NULL;
+ pipe_sampler_view_reference(&paint->pattern.sampler_view,
+ img->sampler_view);
}
void paint_set_pattern_tiling(struct vg_paint *paint,
@@ -611,18 +633,18 @@ VGTilingMode paint_pattern_tiling(struct vg_paint *paint)
}
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
switch(paint->type) {
case VG_PAINT_TYPE_LINEAR_GRADIENT:
case VG_PAINT_TYPE_RADIAL_GRADIENT: {
- if (paint->gradient.texture) {
+ if (paint->gradient.sampler_view) {
paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx);
paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->gradient.sampler;
- textures[0] = paint->gradient.texture;
+ sampler_views[0] = paint->gradient.sampler_view;
return 1;
}
}
@@ -634,7 +656,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx);
paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->pattern.sampler;
- textures[0] = paint->pattern.texture;
+ sampler_views[0] = paint->pattern.sampler_view;
return 1;
}
break;
@@ -647,7 +669,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
void paint_resolve_type(struct vg_paint *paint)
{
if (paint->type == VG_PAINT_TYPE_PATTERN &&
- !paint->pattern.texture) {
+ !paint->pattern.sampler_view) {
paint->type = VG_PAINT_TYPE_COLOR;
}
}
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 999b5c167ca..9ea67c4b1e6 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -108,7 +108,7 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGint paint_constant_buffer_size(struct vg_paint *paint);
void paint_fill_constant_buffer(struct vg_paint *paint,
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index c06dbf52069..eef2c1eb876 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx,
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
velement.src_offset = 0;
velement.instance_divisor = 0;
velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
- velement.nr_components = COMPONENTS;
- pipe->set_vertex_elements(pipe, 1, &velement);
+ cso_set_vertex_elements(ctx->cso_context, 1, &velement);
/* draw */
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 05620efa9c0..2bb4c8bc756 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -39,6 +39,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -210,6 +211,7 @@ void renderer_draw_quad(struct renderer *r,
buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -248,6 +250,7 @@ void renderer_draw_texture(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -261,7 +264,7 @@ void renderer_draw_texture(struct renderer *r,
}
void renderer_copy_texture(struct renderer *ctx,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
@@ -270,6 +273,7 @@ void renderer_copy_texture(struct renderer *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
+ struct pipe_texture *tex = src->texture;
struct pipe_buffer *buf;
struct pipe_surface *dst_surf = screen->get_tex_surface(
screen, dst, 0, 0, 0,
@@ -277,8 +281,8 @@ void renderer_copy_texture(struct renderer *ctx,
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
- assert(src->width0 != 0);
- assert(src->height0 != 0);
+ assert(tex->width0 != 0);
+ assert(tex->height0 != 0);
assert(dst->width0 != 0);
assert(dst->height0 != 0);
@@ -288,10 +292,10 @@ void renderer_copy_texture(struct renderer *ctx,
#endif
#if 1
- s0 = sx1 / src->width0;
- s1 = sx2 / src->width0;
- t0 = sy1 / src->height0;
- t1 = sy2 / src->height0;
+ s0 = sx1 / tex->width0;
+ s1 = sx2 / tex->width0;
+ t0 = sy1 / tex->height0;
+ t1 = sy2 / tex->height0;
#else
s0 = 0;
s1 = 1;
@@ -305,7 +309,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
@@ -343,7 +347,7 @@ void renderer_copy_texture(struct renderer *ctx,
vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &src);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &src);
/* shaders */
cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
@@ -370,6 +374,7 @@ void renderer_copy_texture(struct renderer *ctx,
0.0f);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -382,7 +387,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
@@ -403,6 +408,8 @@ void renderer_copy_surface(struct renderer *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_buffer *buf;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_texture texTemp, *tex;
struct pipe_surface *texSurf;
struct pipe_framebuffer_state fb;
@@ -454,6 +461,12 @@ void renderer_copy_surface(struct renderer *ctx,
if (!tex)
return;
+ u_sampler_view_default_template(&view_templ, tex, tex->format);
+ view = pipe->create_sampler_view(pipe, tex, &view_templ);
+
+ if (!view)
+ return;
+
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -476,7 +489,7 @@ void renderer_copy_surface(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
@@ -512,7 +525,7 @@ void renderer_copy_surface(struct renderer *ctx,
}
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &view);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
@@ -535,6 +548,7 @@ void renderer_copy_surface(struct renderer *ctx,
(float) dstX1, (float) dstY1, z);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -548,13 +562,14 @@ void renderer_copy_surface(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
pipe_texture_reference(&tex, NULL);
+ pipe_sampler_view_reference(&view, NULL);
}
void renderer_texture_quad(struct renderer *r,
@@ -587,6 +602,7 @@ void renderer_texture_quad(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h
index 990cd32c313..03366f13614 100644
--- a/src/gallium/state_trackers/vega/renderer.h
+++ b/src/gallium/state_trackers/vega/renderer.h
@@ -33,6 +33,7 @@ struct renderer;
struct vg_context;
struct pipe_texture;
+struct pipe_sampler_view;
struct pipe_surface;
struct renderer *renderer_create(struct vg_context *owner);
@@ -57,7 +58,7 @@ void renderer_texture_quad(struct renderer *,
VGfloat x3, VGfloat y3,
VGfloat x4, VGfloat y4);
void renderer_copy_texture(struct renderer *r,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 0e71a507bff..f2ec24c57ff 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -119,7 +119,7 @@ static void setup_constant_buffer(struct shader *shader)
static VGint blend_bind_samplers(struct vg_context *ctx,
struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
VGBlendMode bmode = ctx->state.vg.blend_mode;
@@ -132,15 +132,15 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
vg_prepare_blend_surface(ctx);
samplers[2] = &ctx->blend_sampler;
- textures[2] = stfb->blend_texture;
+ sampler_views[2] = stfb->blend_texture_view;
- if (!samplers[0] || !textures[0]) {
+ if (!samplers[0] || !sampler_views[0]) {
samplers[0] = samplers[2];
- textures[0] = textures[2];
+ sampler_views[0] = sampler_views[2];
}
- if (!samplers[1] || !textures[1]) {
+ if (!samplers[1] || !sampler_views[1]) {
samplers[1] = samplers[0];
- textures[1] = textures[0];
+ sampler_views[1] = sampler_views[0];
}
return 1;
@@ -151,7 +151,7 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
static void setup_samplers(struct shader *shader)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct vg_context *ctx = shader->context;
/* a little wonky: we use the num as a boolean that just says
* whether any sampler/textures have been set. the actual numbering
@@ -167,20 +167,20 @@ static void setup_samplers(struct shader *shader)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
-
- num += paint_bind_samplers(shader->paint, samplers, textures);
- num += mask_bind_samplers(samplers, textures);
- num += blend_bind_samplers(ctx, samplers, textures);
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
+ sampler_views[2] = NULL;
+ sampler_views[3] = NULL;
+
+ num += paint_bind_samplers(shader->paint, samplers, sampler_views);
+ num += mask_bind_samplers(samplers, sampler_views);
+ num += blend_bind_samplers(ctx, samplers, sampler_views);
if (shader->drawing_image && shader->image)
- num += image_bind_samplers(shader->image, samplers, textures);
+ num += image_bind_samplers(shader->image, samplers, sampler_views);
if (num) {
cso_set_samplers(ctx->cso_context, 4, (const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, 4, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 4, sampler_views);
}
}
diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h
index 419151c3aee..4d12a4efdd6 100644
--- a/src/gallium/state_trackers/vega/st_inlines.h
+++ b/src/gallium/state_trackers/vega/st_inlines.h
@@ -51,7 +51,6 @@ st_cond_flush_get_tex_transfer(struct vg_context *st,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
- struct pipe_screen *screen = st->pipe->screen;
struct pipe_context *pipe = st->pipe;
unsigned referenced =
pipe->is_texture_referenced(pipe, pt, face, level);
@@ -60,7 +59,7 @@ st_cond_flush_get_tex_transfer(struct vg_context *st,
(usage & PIPE_TRANSFER_WRITE)))
vgFlush();
- return screen->get_tex_transfer(screen, pt, face, level, zslice, usage,
+ return pipe->get_tex_transfer(pipe, pt, face, level, zslice, usage,
x, y, w, h);
}
@@ -74,10 +73,10 @@ st_no_flush_get_tex_transfer(struct vg_context *st,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
- struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_context *pipe = st->pipe;
- return screen->get_tex_transfer(screen, pt, face, level,
- zslice, usage, x, y, w, h);
+ return pipe->get_tex_transfer(pipe, pt, face, level,
+ zslice, usage, x, y, w, h);
}
static INLINE void *
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 426bf9bc62b..11ebbbe5444 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -32,6 +32,7 @@
#include "shader.h"
#include "asm_util.h"
#include "st_inlines.h"
+#include "vg_manager.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
@@ -42,6 +43,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_blit.h"
+#include "util/u_sampler.h"
struct vg_context *_vg_context = 0;
@@ -72,6 +74,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share)
{
struct vg_context *ctx;
+ unsigned i;
ctx = CALLOC_STRUCT(vg_context);
@@ -103,6 +106,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0;
+ for (i = 0; i < 2; i++) {
+ ctx->velems[i].src_offset = i * 4 * sizeof(float);
+ ctx->velems[i].instance_divisor = 0;
+ ctx->velems[i].vertex_buffer_index = 0;
+ ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
@@ -297,6 +307,8 @@ static void update_clip_state(struct vg_context *ctx)
void vg_validate_state(struct vg_context *ctx)
{
+ vg_manager_validate_framebuffer(ctx);
+
if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));
@@ -425,19 +437,24 @@ void vg_prepare_blend_surface(struct vg_context *ctx)
{
struct pipe_surface *dest_surface = NULL;
struct pipe_context *pipe = ctx->pipe;
+ struct pipe_sampler_view *view;
+ struct pipe_sampler_view view_templ;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
/* first finish all pending rendering */
vgFinish();
+ u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
+ view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
+
dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- strb->texture,
+ view,
0, strb->height,
strb->width, 0,
dest_surface,
@@ -450,6 +467,8 @@ void vg_prepare_blend_surface(struct vg_context *ctx)
/* make sure it's complete */
vgFinish();
+
+ pipe_sampler_view_reference(&view, NULL);
}
@@ -466,13 +485,13 @@ void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
vgFinish();
dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- stfb->alpha_mask,
+ stfb->alpha_mask_view,
0, strb->height,
strb->width, 0,
dest_surface,
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index bc88c8d139d..c9e36d7d767 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -33,6 +33,7 @@
#include "pipe/p_state.h"
#include "util/u_pointer.h"
#include "util/u_math.h"
+#include "state_tracker/st_api.h"
#include "cso_cache/cso_hash.h"
#include "cso_cache/cso_context.h"
@@ -54,9 +55,13 @@ struct st_framebuffer {
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
- struct pipe_texture *alpha_mask;
+ struct pipe_sampler_view *alpha_mask_view;
- struct pipe_texture *blend_texture;
+ struct pipe_sampler_view *blend_texture_view;
+
+
+ struct st_framebuffer_iface *iface;
+ enum st_attachment_type strb_att;
void *privateData;
};
@@ -84,6 +89,8 @@ enum dirty_state {
struct vg_context
{
+ struct st_context_iface iface;
+
struct pipe_context *pipe;
struct {
@@ -101,6 +108,7 @@ struct vg_context
VGErrorCode _error;
struct st_framebuffer *draw_buffer;
+ int32_t draw_buffer_invalid;
struct cso_hash *owned_objects[VG_OBJECT_LAST];
@@ -146,6 +154,7 @@ struct vg_context
struct vg_shader *clear_vs;
struct vg_shader *texture_vs;
struct pipe_buffer *vs_const_buffer;
+ struct pipe_vertex_element velems[2];
};
struct vg_object {
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
new file mode 100644
index 00000000000..25c2e853f2a
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -0,0 +1,373 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include "state_tracker/st_api.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "vg_manager.h"
+#include "vg_context.h"
+#include "vg_tracker.h" /* for st_resize_framebuffer */
+#include "image.h"
+
+/**
+ * Flush the front buffer if the current context renders to the front buffer.
+ */
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->flush_frontbuffer) {
+ screen->flush_frontbuffer(screen,
+ stfb->strb->surface, ctx->pipe->priv);
+ }
+ return;
+ }
+
+ switch (stfb->strb_att) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ stfb->iface->flush_front(stfb->iface, stfb->strb_att);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Re-validate the framebuffer.
+ */
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx)
+{
+ struct pipe_screen *screen = ctx->pipe->screen;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct st_renderbuffer *rb;
+ struct pipe_texture *pt;
+
+ /* no binding surface */
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->update_buffer)
+ screen->update_buffer(screen, ctx->pipe->priv);
+ return;
+ }
+
+ if (!p_atomic_read(&ctx->draw_buffer_invalid))
+ return;
+
+ /* validate the fb */
+ if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
+ return;
+
+ rb = stfb->strb;
+ if (rb->texture == pt) {
+ pipe_texture_reference(&pt, NULL);
+ return;
+ }
+
+ /* unreference existing ones */
+ pipe_surface_reference(&rb->surface, NULL);
+ pipe_texture_reference(&rb->texture, NULL);
+
+ rb->texture = pt;
+ rb->surface = screen->get_tex_surface(screen, rb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ rb->width = rb->surface->width;
+ rb->height = rb->surface->height;
+
+ st_resize_framebuffer(stfb, rb->width, rb->height);
+
+ p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
+}
+
+
+static void
+vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stfbi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+}
+
+static void
+vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ ctx->pipe->flush(ctx->pipe, flags, fence);
+ if (flags & PIPE_FLUSH_RENDER_CACHE)
+ vg_manager_flush_frontbuffer(ctx);
+}
+
+static void
+vg_context_destroy(struct st_context_iface *stctxi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ vg_destroy_context(ctx);
+}
+
+static struct st_context_iface *
+vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
+ struct vg_context *ctx;
+ struct pipe_context *pipe;
+
+ pipe = smapi->screen->context_create(smapi->screen, NULL);
+ if (!pipe)
+ return NULL;
+ ctx = vg_create_context(pipe, NULL, shared_ctx);
+ if (!ctx) {
+ pipe->destroy(pipe);
+ return NULL;
+ }
+
+ ctx->iface.destroy = vg_context_destroy;
+
+ ctx->iface.notify_invalid_framebuffer =
+ vg_context_notify_invalid_framebuffer;
+ ctx->iface.flush = vg_context_flush;
+
+ ctx->iface.teximage = NULL;
+ ctx->iface.copy = NULL;
+
+ ctx->iface.st_context_private = (void *) smapi;
+
+ return &ctx->iface;
+}
+
+static struct st_renderbuffer *
+create_renderbuffer(enum pipe_format format)
+{
+ struct st_renderbuffer *strb;
+
+ strb = CALLOC_STRUCT(st_renderbuffer);
+ if (strb)
+ strb->format = format;
+
+ return strb;
+}
+
+static void
+destroy_renderbuffer(struct st_renderbuffer *strb)
+{
+ pipe_surface_reference(&strb->surface, NULL);
+ pipe_texture_reference(&strb->texture, NULL);
+ free(strb);
+}
+
+/**
+ * Decide the buffer to render to.
+ */
+static enum st_attachment_type
+choose_attachment(struct st_framebuffer_iface *stfbi)
+{
+ enum st_attachment_type statt;
+
+ statt = stfbi->visual->render_buffer;
+ if (statt != ST_ATTACHMENT_INVALID) {
+ /* use the buffer given by the visual, unless it is unavailable */
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
+ switch (statt) {
+ case ST_ATTACHMENT_BACK_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ statt = ST_ATTACHMENT_FRONT_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ }
+
+ return statt;
+}
+
+/**
+ * Bind the context to the given framebuffers.
+ */
+static boolean
+vg_context_bind_framebuffers(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ struct st_framebuffer *stfb;
+ enum st_attachment_type strb_att;
+
+ /* the draw and read framebuffers must be the same */
+ if (stdrawi != streadi)
+ return FALSE;
+
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+
+ strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
+
+ if (ctx->draw_buffer) {
+ stfb = ctx->draw_buffer;
+
+ /* free the existing fb */
+ if (!stdrawi ||
+ stfb->strb_att != strb_att ||
+ stfb->strb->format != stdrawi->visual->color_format ||
+ stfb->dsrb->format != stdrawi->visual->depth_stencil_format) {
+ destroy_renderbuffer(stfb->strb);
+ destroy_renderbuffer(stfb->dsrb);
+ free(stfb);
+
+ ctx->draw_buffer = NULL;
+ }
+ }
+
+ if (!stdrawi)
+ return TRUE;
+
+ if (strb_att == ST_ATTACHMENT_INVALID)
+ return FALSE;
+
+ /* create a new fb */
+ if (!ctx->draw_buffer) {
+ stfb = CALLOC_STRUCT(st_framebuffer);
+ if (!stfb)
+ return FALSE;
+
+ stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
+ if (!stfb->strb) {
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format);
+ if (!stfb->dsrb) {
+ free(stfb->strb);
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->width = 0;
+ stfb->height = 0;
+ stfb->strb_att = strb_att;
+
+ ctx->draw_buffer = stfb;
+ }
+
+ ctx->draw_buffer->iface = stdrawi;
+
+ return TRUE;
+}
+
+static boolean
+vg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+
+ if (stctxi)
+ vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
+ vg_set_current_context(ctx);
+
+ return TRUE;
+}
+
+static struct st_context_iface *
+vg_api_get_current(struct st_api *stapi)
+{
+ struct vg_context *ctx = vg_current_context();
+
+ return (ctx) ? &ctx->iface : NULL;
+}
+
+static boolean
+vg_api_is_visual_supported(struct st_api *stapi,
+ const struct st_visual *visual)
+{
+ /* the impl requires a depth/stencil buffer */
+ if (visual->depth_stencil_format == PIPE_FORMAT_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static st_proc_t
+vg_api_get_proc_address(struct st_api *stapi, const char *procname)
+{
+ /* TODO */
+ return (st_proc_t) NULL;
+}
+
+static void
+vg_api_destroy(struct st_api *stapi)
+{
+ free(stapi);
+}
+
+static struct st_api *
+vg_module_create_api(void)
+{
+ struct st_api *stapi;
+
+ stapi = CALLOC_STRUCT(st_api);
+ if (stapi) {
+ stapi->destroy = vg_api_destroy;
+ stapi->get_proc_address = vg_api_get_proc_address;
+ stapi->is_visual_supported = vg_api_is_visual_supported;
+
+ stapi->create_context = vg_api_create_context;
+ stapi->make_current = vg_api_make_current;
+ stapi->get_current = vg_api_get_current;
+ }
+
+ return stapi;
+}
+
+PUBLIC const struct st_module st_module_OpenVG = {
+ .api = ST_API_OPENVG,
+ .create_api = vg_module_create_api,
+};
diff --git a/src/gallium/state_trackers/vega/vg_manager.h b/src/gallium/state_trackers/vega/vg_manager.h
new file mode 100644
index 00000000000..1a276c0f35e
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.h
@@ -0,0 +1,40 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef VG_MANAGER_H
+#define VG_MANAGER_H
+
+#include "state_tracker/st_api.h"
+#include "vg_context.h"
+
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx);
+
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx);
+
+#endif /* VG_MANAGER_H */
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index 57d3baad7fb..f438e34087e 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -32,6 +32,7 @@
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/u_format.h"
+#include "util/u_sampler.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_rect.h"
@@ -41,7 +42,7 @@ PUBLIC const int st_api_OpenVG = 1;
static struct pipe_texture *
create_texture(struct pipe_context *pipe, enum pipe_format format,
- VGint width, VGint height)
+ VGint width, VGint height)
{
struct pipe_texture templ;
@@ -71,6 +72,27 @@ create_texture(struct pipe_context *pipe, enum pipe_format format,
return pipe->screen->texture_create(pipe->screen, &templ);
}
+static struct pipe_sampler_view *
+create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
+ VGint width, VGint height)
+{
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_texture(pipe, format, width, height);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
/**
* Allocate a renderbuffer for a an on-screen window (not a user-created
* renderbuffer). The window system code determines the format.
@@ -115,8 +137,8 @@ st_renderbuffer_alloc_storage(struct vg_context * ctx,
surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
- strb->texture = create_texture(pipe, strb->format,
- width, height);
+ strb->texture = create_texture(pipe, strb->format, width, height);
+
if (!strb->texture)
return FALSE;
@@ -191,7 +213,7 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
/*### currently we always allocate it but it's possible it's
not necessary if EGL_ALPHA_MASK_SIZE was 0
*/
- stfb->alpha_mask = 0;
+ stfb->alpha_mask_view = NULL;
stfb->width = width;
stfb->height = height;
@@ -206,19 +228,19 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
uint width, uint height)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_texture *old_texture = stfb->alpha_mask;
+ struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
/*
we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
this texture and use it as a sampler, so while this wastes some
space it makes both of those a lot simpler
*/
- stfb->alpha_mask =
- create_texture(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+ stfb->alpha_mask_view =
+ create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
- if (!stfb->alpha_mask) {
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (!stfb->alpha_mask_view) {
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
return;
}
@@ -228,15 +250,15 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
mask_fill(0, 0, width, height, 1.f);
/* if we had an old surface copy it over */
- if (old_texture) {
+ if (old_sampler_view) {
struct pipe_surface *surface = pipe->screen->get_tex_surface(
pipe->screen,
- stfb->alpha_mask,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
struct pipe_surface *old_surface = pipe->screen->get_tex_surface(
pipe->screen,
- old_texture,
+ old_sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ);
if (pipe->surface_copy) {
@@ -264,8 +286,8 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
/* Free the old texture
*/
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
}
void st_resize_framebuffer(struct st_framebuffer *stfb,
@@ -326,9 +348,9 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
setup_new_alpha_mask(ctx, stfb, width, height);
- pipe_texture_reference( &stfb->blend_texture, NULL );
- stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
- width, height);
+ pipe_sampler_view_reference( &stfb->blend_texture_view, NULL );
+ stfb->blend_texture_view = create_tex_and_view(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
+ width, height);
}
void st_set_framebuffer_surface(struct st_framebuffer *stfb,
@@ -376,12 +398,12 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb)
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read)
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle)
{
vg_set_current_context(st);
- if (st) {
+ if (st)
st->draw_buffer = draw;
- }
return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index c1196954a76..165a6b7a332 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -101,7 +101,8 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb);
PUBLIC
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read);
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle);
PUBLIC
struct vg_context *st_get_current(void);
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 05ccd5febcf..1f11b649c3e 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -226,7 +226,7 @@ DrvDeleteContext(
/* Unbind current if deleting current context. */
if (curctx == ctx)
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
st_destroy_context(ctx->st);
FREE(ctx);
@@ -317,7 +317,7 @@ stw_make_current(
}
if (hdc == NULL || dhglrc == 0) {
- return st_make_current( NULL, NULL, NULL );
+ return st_make_current( NULL, NULL, NULL, NULL );
}
pipe_mutex_lock( stw_dev->ctx_mutex );
@@ -352,7 +352,7 @@ stw_make_current(
/* pass to stw_flush_frontbuffer as context_private */
ctx->st->pipe->priv = hdc;
- if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc ))
goto fail;
success:
@@ -367,7 +367,7 @@ success:
fail:
if(fb)
stw_framebuffer_release(fb);
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 472a2a5379a..ea300f27cb5 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -33,11 +33,6 @@
#include "pipe/p_screen.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_device.h"
#include "stw_winsys.h"
#include "stw_pixelformat.h"
@@ -107,13 +102,10 @@ stw_init(const struct stw_winsys *stw_winsys)
if(stw_winsys->get_adapter_luid)
stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
-#ifdef DEBUG
- stw_dev->screen = trace_screen_create(screen);
- stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
-#else
stw_dev->screen = screen;
-#endif
-
+
+ /* XXX
+ */
stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->ctx_mutex );
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index a83841f6b7d..2e9ba197dfa 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -48,10 +48,6 @@ struct stw_device
struct pipe_screen *screen;
-#ifdef DEBUG
- boolean trace_running;
-#endif
-
LUID AdapterLuid;
struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index 8dd63f124ad..5ecbd8048de 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -31,11 +31,6 @@
#include "stw_winsys.h"
#include "stw_ext_gallium.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
struct pipe_screen * APIENTRY
wglGetGalliumScreenMESA(void)
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 02de21ccb2b..4f1629de2f2 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -34,11 +34,6 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_icd.h"
#include "stw_framebuffer.h"
#include "stw_device.h"
@@ -495,13 +490,6 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
surface = (struct pipe_surface *)data->pPrivateData;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
if(data->hSharedSurface != fb->hSharedSurface) {
if(fb->shared_surface) {
stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
@@ -563,13 +551,6 @@ stw_framebuffer_present_locked(HDC hdc,
else {
struct pipe_screen *screen = stw_dev->screen;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
stw_dev->stw_winsys->present( screen, surface, hdc );
stw_framebuffer_update(fb);
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index c50873c1508..4ff48026e50 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -4,6 +4,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
/*XXX also in Xrender.h but the including it here breaks compilition */
@@ -356,17 +357,12 @@ bind_samplers(struct exa_context *exa, int op,
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state src_sampler, mask_sampler;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *src_view;
+ struct pipe_context *pipe = exa->pipe;
exa->num_bound_samplers = 0;
-#if 0
- if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)) ||
- (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)))
- xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#endif
-
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
@@ -374,7 +370,7 @@ bind_samplers(struct exa_context *exa, int op,
if (exa->has_solid_color) {
debug_assert(!"solid color with textures");
samplers[0] = NULL;
- exa->bound_textures[0] = NULL;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
} else {
unsigned src_wrap = render_repeat_to_gallium(
pSrcPicture->repeatType);
@@ -389,8 +385,13 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.normalized_coords = 1;
samplers[0] = &src_sampler;
- exa->bound_textures[0] = pSrc->tex;
exa->num_bound_samplers = 1;
+ u_sampler_view_default_template(&view_templ,
+ pSrc->tex,
+ pSrc->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ exa->bound_sampler_views[0] = src_view;
}
}
@@ -408,14 +409,19 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.normalized_coords = 1;
samplers[1] = &mask_sampler;
- exa->bound_textures[1] = pMask->tex;
exa->num_bound_samplers = 2;
+ u_sampler_view_default_template(&view_templ,
+ pMask->tex,
+ pMask->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+ exa->bound_sampler_views[1] = src_view;
}
cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
- exa->bound_textures);
+ cso_set_fragment_sampler_views(exa->renderer->cso, exa->num_bound_samplers,
+ exa->bound_sampler_views);
}
@@ -484,7 +490,6 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
renderer_begin_solid(exa->renderer);
} else {
renderer_begin_textures(exa->renderer,
- exa->bound_textures,
exa->num_bound_samplers);
}
@@ -514,7 +519,7 @@ void xorg_composite(struct exa_context *exa,
renderer_texture(exa->renderer,
pos, width, height,
- exa->bound_textures,
+ exa->bound_sampler_views,
exa->num_bound_samplers,
src_matrix, mask_matrix);
}
@@ -546,7 +551,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
pixmap->width, pixmap->height);
bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
cso_set_samplers(exa->renderer->cso, 0, NULL);
- cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
+ cso_set_fragment_sampler_views(exa->renderer->cso, 0, NULL);
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index a428fa8d948..eef428232b0 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -198,11 +198,11 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
if (!crtcp->cursor_tex) {
struct pipe_texture templat;
- unsigned pitch;
+ struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
@@ -210,25 +210,26 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
templat.width0 = 64;
templat.height0 = 64;
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
- ms->api->local_handle_from_texture(ms->api,
- ms->screen,
- crtcp->cursor_tex,
- &pitch,
- &crtcp->cursor_handle);
+ ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
+
+ crtcp->cursor_handle = whandle.handle;
}
- transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, 64, 64);
- ptr = ms->screen->transfer_map(ms->screen, transfer);
+ transfer = ms->ctx->get_tex_transfer(ms->ctx, crtcp->cursor_tex,
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, 64, 64);
+ ptr = ms->ctx->transfer_map(ms->ctx, transfer);
util_copy_rect(ptr, crtcp->cursor_tex->format,
transfer->stride, 0, 0,
64, 64, (void*)image, 64 * 4, 0, 0);
- ms->screen->transfer_unmap(ms->screen, transfer);
- ms->screen->tex_transfer_destroy(transfer);
+ ms->ctx->transfer_unmap(ms->ctx, transfer);
+ ms->ctx->tex_transfer_destroy(ms->ctx, transfer);
}
#if HAVE_LIBKMS
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 5fc85c0e98c..f23e4c6cc7c 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
- unsigned stride, handle;
+ struct winsys_handle whandle;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
@@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
+
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
@@ -128,7 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ PIPE_TEXTURE_USAGE_SHARED;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
@@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
- ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+
+ ms->screen->texture_get_handle(ms->screen, tex, &whandle);
- buffer->name = handle;
- buffer->pitch = stride;
+ buffer->name = whandle.handle;
+ buffer->pitch = whandle.stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index d7c67463d21..8ac5179545a 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -994,8 +994,9 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride, fb_id;
struct pipe_texture *tex;
+ struct winsys_handle whandle;
+ unsigned fb_id;
int ret;
ms->noEvict = TRUE;
@@ -1006,10 +1007,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
if (!tex)
return FALSE;
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle))
goto err_destroy;
ret = drmModeAddFB(ms->fd,
@@ -1017,8 +1018,8 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- stride,
- handle,
+ whandle.stride,
+ whandle.handle,
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)\n",
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a242e02ee77..76e6411bb8c 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -188,11 +188,7 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
if (!priv || !priv->tex)
return FALSE;
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- exa->pipe->flush(exa->pipe, 0, NULL);
-
- transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ transfer = exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
PIPE_TRANSFER_READ, x, y, w, h);
if (!transfer)
return FALSE;
@@ -203,11 +199,11 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
#endif
util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
- w, h, exa->scrn->transfer_map(exa->scrn, transfer),
+ w, h, exa->pipe->transfer_map(exa->pipe, transfer),
transfer->stride, 0, 0);
- exa->scrn->transfer_unmap(exa->scrn, transfer);
- exa->scrn->tex_transfer_destroy(transfer);
+ exa->pipe->transfer_unmap(exa->pipe, transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, transfer);
return TRUE;
}
@@ -226,12 +222,7 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
if (!priv || !priv->tex)
return FALSE;
- /* make sure that any pending operations are flushed to hardware */
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- (PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
- xorg_exa_flush(exa, 0, NULL);
-
- transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ transfer = exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
return FALSE;
@@ -241,12 +232,12 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
x, y, w, h, src_pitch);
#endif
- util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+ util_copy_rect(exa->pipe->transfer_map(exa->pipe, transfer),
priv->tex->format, transfer->stride, 0, 0, w, h,
(unsigned char*)src, src_pitch, 0, 0);
- exa->scrn->transfer_unmap(exa->scrn, transfer);
- exa->scrn->tex_transfer_destroy(transfer);
+ exa->pipe->transfer_unmap(exa->pipe, transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, transfer);
return TRUE;
}
@@ -270,15 +261,11 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
if (priv->map_count == 0)
{
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- exa->pipe->flush(exa->pipe, 0, NULL);
-
assert(pPix->drawable.width <= priv->tex->width0);
assert(pPix->drawable.height <= priv->tex->height0);
priv->map_transfer =
- exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
@@ -294,7 +281,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
#endif
pPix->devPrivate.ptr =
- exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
+ exa->pipe->transfer_map(exa->pipe, priv->map_transfer);
pPix->devKind = priv->map_transfer->stride;
}
@@ -321,8 +308,8 @@ ExaFinishAccess(PixmapPtr pPix, int index)
if (--priv->map_count == 0) {
assert(priv->map_transfer);
- exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
- exa->scrn->tex_transfer_destroy(priv->map_transfer);
+ exa->pipe->transfer_unmap(exa->pipe, priv->map_transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, priv->map_transfer);
priv->map_transfer = NULL;
pPix->devPrivate.ptr = NULL;
}
@@ -789,7 +776,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+ priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT;
return 0;
}
@@ -805,7 +792,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ priv->flags |= PIPE_TEXTURE_USAGE_SHARED;
return 0;
}
@@ -943,7 +930,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
{
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT;
if (!priv)
return FALSE;
@@ -976,8 +963,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED;
return exa->scrn->texture_create(exa->scrn, &template);
}
@@ -988,6 +975,9 @@ xorg_exa_close(ScrnInfoPtr pScrn)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+
renderer_destroy(exa->renderer);
if (exa->pipe)
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index f2cefe23b99..41b19061599 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -18,7 +18,7 @@ struct exa_context
struct pipe_screen *scrn;
struct xorg_renderer *renderer;
- struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
+ struct pipe_sampler_view *bound_sampler_views[MAX_EXA_SAMPLERS];
int num_bound_samplers;
float solid_color[4];
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 83b0d31e38d..81b0dcf656f 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -8,6 +8,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_inlines.h"
@@ -68,6 +69,8 @@ renderer_draw(struct xorg_renderer *r)
if (buf) {
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
num_verts, /* verts */
@@ -92,6 +95,7 @@ renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state raster;
+ unsigned i;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
@@ -103,6 +107,14 @@ renderer_init_state(struct xorg_renderer *r)
raster.gl_rasterization_rules = 1;
cso_set_rasterizer(r->cso, &raster);
+ /* vertex elements state */
+ memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
+ for (i = 0; i < 3; i++) {
+ r->velems[i].src_offset = i * 4 * sizeof(float);
+ r->velems[i].instance_divisor = 0;
+ r->velems[i].vertex_buffer_index = 0;
+ r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
}
@@ -471,8 +483,17 @@ void renderer_copy_prepare(struct xorg_renderer *r,
dst_surface->width,
dst_surface->height);
- /* texture */
- cso_set_sampler_textures(r->cso, 1, &src_texture);
+ /* texture/sampler view */
+ {
+ struct pipe_sampler_view templ;
+ struct pipe_sampler_view *src_view;
+ u_sampler_view_default_template(&templ,
+ src_texture,
+ src_texture->format);
+ src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
+ cso_set_fragment_sampler_views(r->cso, 1, &src_view);
+ pipe_sampler_view_reference(&src_view, NULL);
+ }
/* shaders */
shader = xorg_shaders_get(r->shaders,
@@ -600,6 +621,8 @@ void renderer_draw_yuv(struct xorg_renderer *r,
if (buf) {
const int num_attribs = 2; /*pos + tex coord*/
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
@@ -642,7 +665,6 @@ void renderer_draw_flush(struct xorg_renderer *r)
}
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures)
{
r->attrs_per_vertex = 1 + num_textures;
@@ -652,7 +674,7 @@ void renderer_begin_textures(struct xorg_renderer *r,
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **sampler_view,
int num_textures,
float *src_matrix,
float *mask_matrix)
@@ -680,7 +702,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[0], pos[1], /* src */
pos[4], pos[5], /* dst */
width, height,
- textures[0], src_matrix);
+ sampler_view[0]->texture, src_matrix);
break;
case 3:
renderer_draw_conditional(r, 4 * 12);
@@ -689,7 +711,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[2], pos[3], /* mask */
pos[4], pos[5], /* dst */
width, height,
- textures[0], textures[1],
+ sampler_view[0]->texture, sampler_view[1]->texture,
src_matrix, mask_matrix);
break;
default:
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index af6aa0567d6..cc5802e79b2 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -28,6 +28,7 @@ struct xorg_renderer {
float buffer[BUF_SIZE];
int buffer_size;
+ struct pipe_vertex_element velems[3];
/* number of attributes per vertex for the current
* draw operation */
@@ -64,12 +65,12 @@ void renderer_solid(struct xorg_renderer *r,
float *color);
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures);
+
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **textures,
int num_textures,
float *src_matrix,
float *mask_matrix);
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index e37a1c39596..5efda6837de 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -9,6 +9,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
#include "pipe/p_screen.h"
@@ -91,6 +92,7 @@ struct xorg_xv_port_priv {
/* juggle two sets of seperate Y, U and V
* textures */
struct pipe_texture *yuv[2][3];
+ struct pipe_sampler_view *yuv_views[2][3];
};
@@ -180,32 +182,60 @@ static int
check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
{
struct pipe_texture **dst = priv->yuv[priv->current_set];
+ struct pipe_sampler_view **dst_view = priv->yuv_views[priv->current_set];
+ struct pipe_sampler_view view_templ;
+ struct pipe_context *pipe = priv->r->pipe;
+
if (!dst[0] ||
dst[0]->width0 != width ||
dst[0]->height0 != height) {
pipe_texture_reference(&dst[0], NULL);
+ pipe_sampler_view_reference(&dst_view[0], NULL);
}
if (!dst[1] ||
dst[1]->width0 != width ||
dst[1]->height0 != height) {
pipe_texture_reference(&dst[1], NULL);
+ pipe_sampler_view_reference(&dst_view[1], NULL);
}
if (!dst[2] ||
dst[2]->width0 != width ||
dst[2]->height0 != height) {
pipe_texture_reference(&dst[2], NULL);
+ pipe_sampler_view_reference(&dst_view[2], NULL);
}
- if (!dst[0])
+ if (!dst[0]) {
dst[0] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[0]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[0],
+ dst[0]->format);
+ dst_view[0] = pipe->create_sampler_view(pipe, dst[0], &view_templ);
+ }
+ }
- if (!dst[1])
+ if (!dst[1]) {
dst[1] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[1]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[1],
+ dst[1]->format);
+ dst_view[1] = pipe->create_sampler_view(pipe, dst[1], &view_templ);
+ }
+ }
- if (!dst[2])
+ if (!dst[2]) {
dst[2] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[2]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[2],
+ dst[2]->format);
+ dst_view[2] = pipe->create_sampler_view(pipe, dst[2], &view_templ);
+ }
+ }
- if (!dst[0] || !dst[1] || !dst[2])
+ if (!dst[0] || !dst[1] || !dst[2] || !dst_view[0] || !dst_view[1] || !dst_view[2] )
return BadAlloc;
return Success;
@@ -275,28 +305,28 @@ copy_packed_data(ScrnInfoPtr pScrn,
int i, j;
struct pipe_texture **dst = port->yuv[port->current_set];
struct pipe_transfer *ytrans, *utrans, *vtrans;
- struct pipe_screen *screen = port->r->pipe->screen;
+ struct pipe_context *pipe = port->r->pipe;
char *ymap, *vmap, *umap;
unsigned char y1, y2, u, v;
int yidx, uidx, vidx;
int y_array_size = w * h;
- ytrans = screen->get_tex_transfer(screen, dst[0],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
- utrans = screen->get_tex_transfer(screen, dst[1],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
- vtrans = screen->get_tex_transfer(screen, dst[2],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
-
- ymap = (char*)screen->transfer_map(screen, ytrans);
- umap = (char*)screen->transfer_map(screen, utrans);
- vmap = (char*)screen->transfer_map(screen, vtrans);
+ ytrans = pipe->get_tex_transfer(pipe, dst[0],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+ utrans = pipe->get_tex_transfer(pipe, dst[1],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+ vtrans = pipe->get_tex_transfer(pipe, dst[2],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+
+ ymap = (char*)pipe->transfer_map(pipe, ytrans);
+ umap = (char*)pipe->transfer_map(pipe, utrans);
+ vmap = (char*)pipe->transfer_map(pipe, vtrans);
yidx = uidx = vidx = 0;
@@ -362,12 +392,12 @@ copy_packed_data(ScrnInfoPtr pScrn,
break;
}
- screen->transfer_unmap(screen, ytrans);
- screen->transfer_unmap(screen, utrans);
- screen->transfer_unmap(screen, vtrans);
- screen->tex_transfer_destroy(ytrans);
- screen->tex_transfer_destroy(utrans);
- screen->tex_transfer_destroy(vtrans);
+ pipe->transfer_unmap(pipe, ytrans);
+ pipe->transfer_unmap(pipe, utrans);
+ pipe->transfer_unmap(pipe, vtrans);
+ pipe->tex_transfer_destroy(pipe, ytrans);
+ pipe->tex_transfer_destroy(pipe, utrans);
+ pipe->tex_transfer_destroy(pipe, vtrans);
}
@@ -450,6 +480,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state sampler;
struct pipe_texture **dst = port->yuv[port->current_set];
+ struct pipe_sampler_view **dst_views = port->yuv_views[port->current_set];
memset(&sampler, 0, sizeof(struct pipe_sampler_state));
@@ -469,8 +500,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
cso_set_samplers(port->r->cso, 3,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(port->r->cso, 3,
- dst);
+ cso_set_fragment_sampler_views(port->r->cso, 3, dst_views);
}
static int
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 87d1dfaace2..12d94e0c5ca 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -106,7 +106,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
- template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_SHARED;
tex = vpipe->screen->texture_create(vpipe->screen, &template);
if (!tex)
diff --git a/src/gallium/winsys/drm/Makefile b/src/gallium/targets/Makefile
index fee01916432..a0bc5eb14fa 100644
--- a/src/gallium/winsys/drm/Makefile
+++ b/src/gallium/targets/Makefile
@@ -1,8 +1,8 @@
# src/gallium/winsys/Makefile
-TOP = ../../../..
+TOP = ../../..
include $(TOP)/configs/current
-SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS)
+SUBDIRS = $(GALLIUM_TARGET_DIRS)
default install clean:
@for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/targets/Makefile.dri
index f4cc0def471..6d9b81aa249 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/targets/Makefile.dri
@@ -64,11 +64,14 @@ SHARED_INCLUDES = \
default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) Makefile \
- $(TOP)/src/mesa/drivers/dri/Makefile.template
- $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ $(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/src/mesa/drivers/dri/common/dri_test.o
+ $(MKLIB) -o [email protected] -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
$(OBJECTS) $(PIPE_DRIVERS) \
-Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
$(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
+ $(CC) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS)
$(TOP)/$(LIB_DIR)/gallium:
mkdir -p $@
diff --git a/src/gallium/winsys/drm/Makefile.egl b/src/gallium/targets/Makefile.egl
index 8363de6e975..9265e2eb7bc 100644
--- a/src/gallium/winsys/drm/Makefile.egl
+++ b/src/gallium/targets/Makefile.egl
@@ -13,7 +13,14 @@ EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
common_LIBS = -ldrm -lm -ldl
-x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a
+# ximage backend calls gallium_wrap_screen, which requires libidentity.a and
+# libtrace.a
+x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a \
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a
+
x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
@@ -38,8 +45,10 @@ $(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/%.so: %.so
define mklib-egl
$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) $($(1)_ST) \
- $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS)
+ $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \
+ -Wl,--start-group $($(1)_ST) $(EGL_DRIVER_PIPES) \
+ $(GALLIUM_AUXILIARIES) -Wl,--end-group \
+ $($(1)_LIBS) $(EGL_DRIVER_LIBS)
endef
egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript
new file mode 100644
index 00000000000..1292d4f6193
--- /dev/null
+++ b/src/gallium/targets/SConscript
@@ -0,0 +1,27 @@
+Import('*')
+
+if 'xlib' in env['winsys']:
+ SConscript([
+ 'libgl-xlib/SConscript',
+ ])
+
+if 'gdi' in env['winsys']:
+ SConscript([
+ 'libgl-gdi/SConscript',
+ ])
+
+if 'graw-xlib' in env['winsys']:
+ SConscript([
+ 'graw-xlib/SConscript',
+ ])
+
+if env['dri']:
+ SConscript([
+ 'SConscript.dri'
+ ])
+
+if 'xorg' in env['statetrackers']:
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'xorg-vmwgfx/SConscript',
+ ])
diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri
new file mode 100644
index 00000000000..210af13720a
--- /dev/null
+++ b/src/gallium/targets/SConscript.dri
@@ -0,0 +1,96 @@
+###################################
+# SConcscript file for dri targets
+
+Import('*')
+
+drienv = env.Clone()
+
+drienv.Replace(CPPPATH = [
+ '#src/mesa/drivers/dri/common',
+ '#include',
+ '#include/GL/internal',
+ '#src/gallium/include',
+ '#src/gallium/auxiliary',
+ '#src/gallium/drivers',
+ '#src/mesa',
+ '#src/mesa/main',
+ '#src/mesa/glapi',
+ '#src/mesa/math',
+ '#src/mesa/transform',
+ '#src/mesa/shader',
+ '#src/mesa/swrast',
+ '#src/mesa/swrast_setup',
+ '#src/egl/main',
+ '#src/egl/drivers/dri',
+])
+
+drienv.ParseConfig('pkg-config --cflags --libs libdrm')
+
+dri_common_utils = drienv.SharedObject(
+ target = 'utils.o',
+ source = '#src/mesa/drivers/dri/common/utils.c'
+)
+
+dri_common_xmlconfig = drienv.SharedObject(
+ target = 'xmlconfig.o',
+ source = '#src/mesa/drivers/dri/common/xmlconfig.c'
+)
+
+dri_common_vblank = drienv.SharedObject(
+ target = 'vblank.o',
+ source = '#src/mesa/drivers/dri/common/vblank.c'
+)
+
+dri_common_dri_util = drienv.SharedObject(
+ target = 'dri_util.o',
+ source = '#src/mesa/drivers/dri/common/dri_util.c'
+)
+
+dri_common_drisw_util = drienv.SharedObject(
+ target = 'drisw_util.o',
+ source = '#src/mesa/drivers/dri/common/drisw_util.c'
+)
+
+
+COMMON_DRI_SW_OBJECTS = [
+ dri_common_utils,
+ dri_common_xmlconfig,
+ dri_common_drisw_util,
+]
+
+COMMON_DRI_DRM_OBJECTS = [
+ dri_common_utils,
+ dri_common_xmlconfig,
+ dri_common_vblank,
+ dri_common_dri_util,
+]
+
+Export([
+ 'drienv',
+ 'COMMON_DRI_SW_OBJECTS',
+ 'COMMON_DRI_DRM_OBJECTS',
+])
+
+SConscript([
+ 'dri-swrast/SConscript',
+])
+
+if 'vmware' in env['winsys']:
+ SConscript([
+ 'dri-vmwgfx/SConscript',
+ ])
+
+if 'i915' in env['winsys']:
+ SConscript([
+ 'dri-i915/SConscript',
+ ])
+
+if 'i965' in env['winsys']:
+ SConscript([
+ 'dri-i965/SConscript',
+ ])
+
+if 'radeon' in env['winsys']:
+ SConscript([
+ 'dri-radeong/SConscript',
+ ])
diff --git a/src/gallium/winsys/drm/intel/dri/Makefile b/src/gallium/targets/dri-i915/Makefile
index 26aae4122eb..50a8e11e17c 100644
--- a/src/gallium/winsys/drm/intel/dri/Makefile
+++ b/src/gallium/targets/dri-i915/Makefile
@@ -1,26 +1,22 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i915_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i915/libi915.a
-
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_intel
-symlinks: $(TOP)/$(LIB_DIR)/gallium
- @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
+symlinks:
diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript
new file mode 100644
index 00000000000..2fcc8028f12
--- /dev/null
+++ b/src/gallium/targets/dri-i915/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'i915' in env['drivers']:
+ print 'warning: i915 pipe driver not built skipping i915_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+env.Prepend(LIBS = [
+ st_dri,
+ i915drm,
+ i915,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'i915_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-i915/dummy.c b/src/gallium/targets/dri-i915/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-i915/dummy.c
diff --git a/src/gallium/winsys/drm/i965/dri/Makefile b/src/gallium/targets/dri-i965/Makefile
index f7e81eed87b..e267ba3a023 100644
--- a/src/gallium/winsys/drm/i965/dri/Makefile
+++ b/src/gallium/targets/dri-i965/Makefile
@@ -1,26 +1,24 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = i965_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/gallium/drivers/i965/libi965.a
-
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_intel
-symlinks: $(TOP)/$(LIB_DIR)/gallium
- @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
+symlinks:
diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript
new file mode 100644
index 00000000000..eb9e6cd172a
--- /dev/null
+++ b/src/gallium/targets/dri-i965/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'i965' in env['drivers']:
+ print 'warning: i965 pipe driver not built skipping i965_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
+env.Prepend(LIBS = [
+ st_dri,
+ i965drm,
+ i965,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'i965_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-i965/dummy.c b/src/gallium/targets/dri-i965/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-i965/dummy.c
diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/targets/dri-nouveau/Makefile
index 7e95f79d03c..74d352c6a70 100644
--- a/src/gallium/winsys/drm/nouveau/dri/Makefile
+++ b/src/gallium/targets/dri-nouveau/Makefile
@@ -1,23 +1,20 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = nouveau_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
- $(TOP)/src/gallium/drivers/nv30/libnv30.a \
- $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a
-DRIVER_SOURCES =
-
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
diff --git a/src/gallium/winsys/drm/radeon/dri/Makefile b/src/gallium/targets/dri-radeong/Makefile
index d75f7dd6da7..66dd392b68b 100644
--- a/src/gallium/winsys/drm/radeon/dri/Makefile
+++ b/src/gallium/targets/dri-radeong/Makefile
@@ -1,12 +1,11 @@
-
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = radeong_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
@@ -15,9 +14,7 @@ C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-ASM_SOURCES =
-
-include ../../Makefile.template
+include ../Makefile.dri
DRI_LIB_DEPS += -ldrm_radeon
diff --git a/src/gallium/targets/dri-radeong/SConscript b/src/gallium/targets/dri-radeong/SConscript
new file mode 100644
index 00000000000..d926c272889
--- /dev/null
+++ b/src/gallium/targets/dri-radeong/SConscript
@@ -0,0 +1,26 @@
+Import('*')
+
+if not 'r300' in env['drivers']:
+ print 'warning: r300 pipe driver not built skipping radeong_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
+
+env.Prepend(LIBS = [
+ st_dri,
+ radeonwinsys,
+ r300,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.SharedLibrary(
+ target ='radeon_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-radeong/dummy.c b/src/gallium/targets/dri-radeong/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-radeong/dummy.c
diff --git a/src/gallium/targets/dri-swrast/Makefile b/src/gallium/targets/dri-swrast/Makefile
new file mode 100644
index 00000000000..fcfd690e438
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/Makefile
@@ -0,0 +1,30 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swrastg_dri.so
+
+DRIVER_DEFINES = -D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/sw/libdrisw.a \
+ $(TOP)/src/gallium/winsys/sw/dri/libswdri.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+SWRAST_COMMON_GALLIUM_SOURCES = \
+ $(TOP)/src/mesa/drivers/dri/common/utils.c \
+ $(TOP)/src/mesa/drivers/dri/common/drisw_util.c \
+ $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c
+
+C_SOURCES = \
+ swrast_drm_api.c \
+ $(SWRAST_COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+include ../Makefile.dri
+
+INCLUDES += \
+ -I$(TOP)/src/gallium/winsys/sw/dri
+
+symlinks:
diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript
new file mode 100644
index 00000000000..94ff99a0a90
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/SConscript
@@ -0,0 +1,42 @@
+Import('*')
+
+if not set(('softpipe', 'llvmpipe')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of swrastg_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/winsys/sw/dri',
+])
+
+env.Prepend(LIBS = [
+ st_drisw,
+ ws_dri,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_SW_OBJECTS
+])
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+swrastg_sources = [
+ 'swrast_drm_api.c'
+]
+
+env.LoadableModule(
+ target ='swrastg_dri.so',
+ source = swrastg_sources,
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-swrast/swrast_drm_api.c b/src/gallium/targets/dri-swrast/swrast_drm_api.c
new file mode 100644
index 00000000000..99c25543a76
--- /dev/null
+++ b/src/gallium/targets/dri-swrast/swrast_drm_api.c
@@ -0,0 +1,147 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "state_tracker/drm_api.h"
+#include "state_tracker/sw_winsys.h"
+#include "dri_sw_winsys.h"
+
+/* Copied from targets/libgl-xlib */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+static struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+ if (screen == NULL && strcmp(driver, "cell") == 0)
+ screen = cell_create_screen( winsys );
+#elif defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#elif defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ (void) driver;
+#else
+ (void) driver;
+#endif
+
+ return screen;
+}
+
+static struct pipe_screen *
+swrast_drm_create_screen(struct drm_api *api,
+ int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct sw_winsys *winsys = NULL;
+ struct pipe_screen *screen = NULL;
+ struct drisw_create_screen_arg *drisw;
+
+ (void) drmFD;
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_DRISW:
+ drisw = (struct drisw_create_screen_arg *)arg;
+ break;
+ default:
+ return NULL;
+ }
+ }
+ else {
+ return NULL;
+ }
+
+ winsys = dri_create_sw_winsys(drisw->lf);
+ if (winsys == NULL)
+ return NULL;
+
+ screen = swrast_create_screen(winsys);
+ if (!screen)
+ goto fail;
+
+ return screen;
+
+fail:
+ if (winsys)
+ winsys->destroy(winsys);
+
+ return NULL;
+}
+
+static void
+swrast_drm_api_destroy(struct drm_api *api)
+{
+ return;
+}
+
+static struct drm_api swrast_drm_api =
+{
+ .name = "swrast",
+ .driver_name = "swrast",
+ .create_screen = swrast_drm_create_screen,
+ .destroy = swrast_drm_api_destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return &swrast_drm_api;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/winsys/drm/vmware/dri/Makefile b/src/gallium/targets/dri-vmwgfx/Makefile
index 8a39e23da6d..4b002e828fa 100644
--- a/src/gallium/winsys/drm/vmware/dri/Makefile
+++ b/src/gallium/targets/dri-vmwgfx/Makefile
@@ -1,18 +1,17 @@
-
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
LIBNAME = vmwgfx_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES)
-include ../../Makefile.template
+include ../Makefile.dri
symlinks:
diff --git a/src/gallium/targets/dri-vmwgfx/SConscript b/src/gallium/targets/dri-vmwgfx/SConscript
new file mode 100644
index 00000000000..6a1f8827bc3
--- /dev/null
+++ b/src/gallium/targets/dri-vmwgfx/SConscript
@@ -0,0 +1,24 @@
+Import('*')
+
+if not 'svga' in env['drivers']:
+ print 'warning: svga pipe driver not built skipping vmwgfx_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.Prepend(LIBS = [
+ st_dri,
+ svgadrm,
+ svga,
+ trace,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.LoadableModule(
+ target = 'vmwgfx_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-vmwgfx/dummy.c b/src/gallium/targets/dri-vmwgfx/dummy.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/targets/dri-vmwgfx/dummy.c
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/targets/egl-i915/Makefile
index 60d675ca73d..02258fb69a4 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/targets/egl-i915/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = i915
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS = -ldrm_intel
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915/libi915.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/i965/egl/dummy.c b/src/gallium/targets/egl-i915/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/i965/egl/dummy.c
+++ b/src/gallium/targets/egl-i915/dummy.c
diff --git a/src/gallium/targets/egl-i965/Makefile b/src/gallium/targets/egl-i965/Makefile
new file mode 100644
index 00000000000..fad56ef5554
--- /dev/null
+++ b/src/gallium/targets/egl-i965/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = i965
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
+
+EGL_DRIVER_PIPES = \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/intel/egl/dummy.c b/src/gallium/targets/egl-i965/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/intel/egl/dummy.c
+++ b/src/gallium/targets/egl-i965/dummy.c
diff --git a/src/gallium/targets/egl-nouveau/Makefile b/src/gallium/targets/egl-nouveau/Makefile
new file mode 100644
index 00000000000..e3fa8937e83
--- /dev/null
+++ b/src/gallium/targets/egl-nouveau/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER_NAME = nouveau
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_nouveau
+
+EGL_DRIVER_PIPES = \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
+
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/nouveau/egl/dummy.c b/src/gallium/targets/egl-nouveau/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/nouveau/egl/dummy.c
+++ b/src/gallium/targets/egl-nouveau/dummy.c
diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/targets/egl-radeon/Makefile
index cd4f9b20f06..8daadb59791 100644
--- a/src/gallium/winsys/drm/radeon/egl/Makefile
+++ b/src/gallium/targets/egl-radeon/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = radeon
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS = -ldrm_radeon
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/radeon/egl/dummy.c b/src/gallium/targets/egl-radeon/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/radeon/egl/dummy.c
+++ b/src/gallium/targets/egl-radeon/dummy.c
diff --git a/src/gallium/targets/egl-swrast/Makefile b/src/gallium/targets/egl-swrast/Makefile
new file mode 100644
index 00000000000..7d4f5054983
--- /dev/null
+++ b/src/gallium/targets/egl-swrast/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+# Do propperly
+CFLAGS+="-I$(TOP)/src/gallium/include"
+
+EGL_DRIVER_NAME = swrast
+EGL_DRIVER_SOURCES = swrast_glue.c
+EGL_DRIVER_LIBS =
+EGL_DRIVER_PIPES =
+
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c b/src/gallium/targets/egl-swrast/swrast_glue.c
index 8c9f80e2c15..9db8089a666 100644
--- a/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c
+++ b/src/gallium/targets/egl-swrast/swrast_glue.c
@@ -11,3 +11,7 @@ drm_api_create()
(void) swrast_drm_api;
return NULL;
}
+
+/* A poor man's --whole-archive for EGL drivers */
+void *_eglMain(void *);
+void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/targets/egl-vmwgfx/Makefile
index a3e73131c35..5f9385f42b0 100644
--- a/src/gallium/winsys/drm/vmware/egl/Makefile
+++ b/src/gallium/targets/egl-vmwgfx/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER_NAME = vmwgfx
@@ -6,9 +6,8 @@ EGL_DRIVER_SOURCES = dummy.c
EGL_DRIVER_LIBS =
EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a
-include ../../Makefile.egl
+include ../Makefile.egl
diff --git a/src/gallium/winsys/drm/swrast/egl/dummy.c b/src/gallium/targets/egl-vmwgfx/dummy.c
index 3181d0ba7e8..3181d0ba7e8 100644
--- a/src/gallium/winsys/drm/swrast/egl/dummy.c
+++ b/src/gallium/targets/egl-vmwgfx/dummy.c
diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript
new file mode 100644
index 00000000000..24cea92f907
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/SConscript
@@ -0,0 +1,57 @@
+#######################################################################
+# SConscript for xlib winsys
+
+Import('*')
+
+if env['platform'] != 'linux':
+ Return()
+
+if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']):
+ print 'warning: no supported pipe driver: skipping build of xlib libGL.so'
+ Return()
+
+env = env.Clone()
+
+env.Prepend(LIBS = [
+ ws_xlib,
+ trace,
+ identity,
+# gallium,
+])
+
+env.Append(CPPPATH = [
+ '#src/gallium/drivers',
+])
+
+
+sources = [
+ 'graw_xlib.c',
+]
+
+if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+ env.Prepend(LIBS = [softpipe])
+
+if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ env.Prepend(LIBS = [llvmpipe])
+
+# Need this for trace, identity drivers referenced by
+# gallium_wrap_screen().
+#
+env.Prepend(LIBS = [gallium])
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+graw = env.SharedLibrary(
+ target ='graw',
+ source = sources,
+)
+
+env.InstallSharedLibrary(graw, version=(1, 0))
+
+graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+
+Export('graw')
diff --git a/src/gallium/targets/graw-xlib/graw.h b/src/gallium/targets/graw-xlib/graw.h
new file mode 100644
index 00000000000..a58e18e4739
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/graw.h
@@ -0,0 +1,36 @@
+#ifndef GALLIUM_RAW_H
+#define GALLIUM_RAW_H
+
+/* This is an API for exercising gallium functionality in a
+ * platform-neutral fashion. Whatever platform integration is
+ * necessary to implement this interface is orchestrated by the
+ * individual target building this entity.
+ *
+ * For instance, the graw-xlib target includes code to implent these
+ * interfaces on top of the X window system.
+ *
+ * Programs using this interface may additionally benefit from some of
+ * the utilities currently in the libgallium.a library, especially
+ * those for parsing text representations of TGSI shaders.
+ */
+
+#include "pipe/p_format.h"
+
+struct pipe_screen;
+
+struct pipe_screen *graw_init( void );
+
+/* Returns a handle to be used with flush_frontbuffer()/present().
+ *
+ * Query format support with screen::is_format_supported and usage
+ * XXX.
+ */
+void *graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format );
+
+void graw_destroy_window( void *handle );
+
+#endif
diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c
new file mode 100644
index 00000000000..fb8ef9d78b6
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/graw_xlib.c
@@ -0,0 +1,181 @@
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "target-helpers/wrap_screen.h"
+#include "state_tracker/xlib_sw_winsys.h"
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+/* Haven't figured out a decent way to build the helper code yet -
+ * #include it here temporarily.
+ */
+#include "sw/sw_public.h"
+#include "sw/sw.c"
+
+#include "graw.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+
+static struct {
+ Display *display;
+} graw;
+
+
+struct pipe_screen *
+graw_init( void )
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+ struct sw_winsys *winsys = NULL;
+
+ graw.display = XOpenDisplay(NULL);
+ if (graw.display == NULL)
+ return NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( graw.display );
+ if (winsys == NULL)
+ return NULL;
+
+#if defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+#endif
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+}
+
+
+
+
+
+void *
+graw_create_window( int x,
+ int y,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format )
+{
+ struct xlib_drawable *handle = NULL;
+ XSetWindowAttributes attr;
+ Window root;
+ Window win = 0;
+ XVisualInfo templat, *visinfo = NULL;
+ unsigned mask;
+ int n;
+ int scrnum;
+
+
+ scrnum = DefaultScreen( graw.display );
+ root = RootWindow( graw.display, scrnum );
+
+
+ if (format != PIPE_FORMAT_R8G8B8A8_UNORM)
+ goto fail;
+
+ if (graw.display == NULL)
+ goto fail;
+
+ handle = CALLOC_STRUCT(xlib_drawable);
+ if (handle == NULL)
+ goto fail;
+
+
+ mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
+ templat.screen = DefaultScreen(graw.display);
+ templat.depth = 32;
+ templat.class = TrueColor;
+
+ visinfo = XGetVisualInfo(graw.display, mask, &templat, &n);
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ /* XXX this is a bad way to get a borderless window! */
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( graw.display, root, x, y, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+
+ /* set hints and properties */
+ {
+ char *name = NULL;
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(graw.display, win, &sizehints);
+ XSetStandardProperties(graw.display, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ XFree(visinfo);
+ XMapWindow(graw.display, win);
+ while (1) {
+ XEvent e;
+ XNextEvent( graw.display, &e );
+ if (e.type == MapNotify && e.xmap.window == win) {
+ break;
+ }
+ }
+
+ handle->visual = visinfo->visual;
+ handle->drawable = (Drawable)win;
+ handle->depth = visinfo->depth;
+ return (void *)handle;
+
+fail:
+ FREE(handle);
+ XFree(visinfo);
+
+ if (win)
+ XDestroyWindow(graw.display, win);
+
+ return NULL;
+}
+
+
+void
+graw_destroy_window( void *xlib_drawable )
+{
+}
+
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript
index 4cbc86f3311..21b4eb2abee 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/targets/libgl-gdi/SConscript
@@ -9,6 +9,7 @@ if env['platform'] == 'windows':
env.Append(CPPPATH = [
'#src/gallium/state_trackers/wgl',
+ '#src/gallium/winsys/sw',
])
env.Append(LIBS = [
@@ -47,5 +48,5 @@ if env['platform'] == 'windows':
env.SharedLibrary(
target ='opengl32',
source = sources,
- LIBS = wgl + glapi + mesa + drivers + gallium + glsl + env['LIBS'],
+ LIBS = wgl + ws_gdi + glapi + mesa + drivers + gallium + glsl + env['LIBS'],
)
diff --git a/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c b/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c
new file mode 100644
index 00000000000..29316a1ce28
--- /dev/null
+++ b/src/gallium/targets/libgl-gdi/gdi_llvmpipe_winsys.c
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#include <windows.h>
+
+#include "stw_winsys.h"
+#include "gdi/gdi_sw_winsys.h"
+#include "llvmpipe/lp_texture.h"
+#include "llvmpipe/lp_screen.h"
+#include "llvmpipe/lp_public.h"
+
+
+static struct pipe_screen *
+gdi_llvmpipe_screen_create(void)
+{
+ static struct sw_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = gdi_create_sw_winsys();
+ if(!winsys)
+ goto no_winsys;
+
+ screen = llvmpipe_create_screen(winsys);
+ if(!screen)
+ goto no_screen;
+
+ return screen;
+
+no_screen:
+ winsys->destroy(winsys);
+no_winsys:
+ return NULL;
+}
+
+
+
+
+static void
+gdi_llvmpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
+{
+ /* This will fail if any interposing layer (trace, debug, etc) has
+ * been introduced between the state-trackers and llvmpipe.
+ *
+ * Ideally this would get replaced with a call to
+ * pipe_screen::flush_frontbuffer().
+ *
+ * Failing that, it may be necessary for intervening layers to wrap
+ * other structs such as this stw_winsys as well...
+ */
+ gdi_sw_display(llvmpipe_screen(screen)->winsys,
+ llvmpipe_texture(surface->texture)->dt,
+ hDC);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+ &gdi_llvmpipe_screen_create,
+ &gdi_llvmpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ stw_init(&stw_winsys);
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_DETACH:
+ stw_cleanup_thread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ stw_cleanup_thread();
+ stw_cleanup();
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c b/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c
new file mode 100644
index 00000000000..dfe60195d94
--- /dev/null
+++ b/src/gallium/targets/libgl-gdi/gdi_softpipe_winsys.c
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#include <windows.h>
+
+#include "stw_winsys.h"
+#include "gdi/gdi_sw_winsys.h"
+#include "softpipe/sp_texture.h"
+#include "softpipe/sp_screen.h"
+#include "softpipe/sp_public.h"
+
+
+static struct pipe_screen *
+gdi_softpipe_screen_create(void)
+{
+ static struct sw_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = gdi_create_sw_winsys();
+ if(!winsys)
+ goto no_winsys;
+
+ screen = softpipe_create_screen(winsys);
+ if(!screen)
+ goto no_screen;
+
+ return screen;
+
+no_screen:
+ winsys->destroy(winsys);
+no_winsys:
+ return NULL;
+}
+
+
+
+
+static void
+gdi_softpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
+{
+ /* This will fail if any interposing layer (trace, debug, etc) has
+ * been introduced between the state-trackers and softpipe.
+ *
+ * Ideally this would get replaced with a call to
+ * pipe_screen::flush_frontbuffer().
+ *
+ * Failing that, it may be necessary for intervening layers to wrap
+ * other structs such as this stw_winsys as well...
+ */
+ gdi_sw_display(softpipe_screen(screen)->winsys,
+ softpipe_texture(surface->texture)->dt,
+ hDC);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+ &gdi_softpipe_screen_create,
+ &gdi_softpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ stw_init(&stw_winsys);
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_ATTACH:
+ stw_init_thread();
+ break;
+
+ case DLL_THREAD_DETACH:
+ stw_cleanup_thread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ stw_cleanup_thread();
+ stw_cleanup();
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/targets/libgl-xlib/Makefile
index 824c666ae30..6cd00cad458 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/targets/libgl-xlib/Makefile
@@ -1,4 +1,4 @@
-# src/gallium/winsys/xlib/Makefile
+# src/gallium/targets/libgl-xlib/Makefile
# This makefile produces a "stand-alone" libGL.so which is based on
# Xlib (no DRI HW acceleration)
@@ -26,14 +26,11 @@ DEFINES += \
-DGALLIUM_SOFTPIPE
#-DGALLIUM_CELL will be defined by the config */
-XLIB_WINSYS_SOURCES = \
- xlib.c \
- xlib_cell.c \
- xlib_llvmpipe.c \
- xlib_softpipe.c
+XLIB_TARGET_SOURCES = \
+ xlib.c
-XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
+XLIB_TARGET_OBJECTS = $(XLIB_TARGET_SOURCES:.c=.o)
# Note: CELL_SPU_LIB is only defined for cell configs
@@ -41,6 +38,9 @@ XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
LIBS = \
$(GALLIUM_DRIVERS) \
$(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
$(TOP)/src/mesa/libglapi.a \
$(TOP)/src/mesa/libmesagallium.a \
$(GALLIUM_AUXILIARIES) \
@@ -63,20 +63,20 @@ $(TOP)/$(LIB_DIR)/gallium:
@ mkdir -p $(TOP)/$(LIB_DIR)/gallium
# Make the libGL.so library
-$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile
+$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_TARGET_OBJECTS) $(LIBS) Makefile
$(TOP)/bin/mklib -o $(GL_LIB) \
-linker "$(CC)" \
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
-install $(TOP)/$(LIB_DIR)/gallium \
- $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
+ $(MKLIB_OPTIONS) $(XLIB_TARGET_OBJECTS) \
-Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
-depend: $(XLIB_WINSYS_SOURCES)
+depend: $(XLIB_TARGET_SOURCES)
@ echo "running $(MKDEP)"
@ rm -f depend # workaround oops on gutsy?!?
@ touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_TARGET_SOURCES) \
> /dev/null 2>/dev/null
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript
index 8c9d318af2b..efa7e797d1f 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/targets/libgl-xlib/SConscript
@@ -28,35 +28,40 @@ env.Append(CPPPATH = [
env.Append(CPPDEFINES = ['USE_XSHM'])
+env.Prepend(LIBS = [
+ st_xlib,
+ ws_xlib,
+ trace,
+ identity,
+ glapi,
+ mesa,
+ glsl,
+ gallium,
+])
+
sources = [
'xlib.c',
]
-drivers = [trace]
-
if 'softpipe' in env['drivers']:
env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
- sources += ['xlib_softpipe.c']
- drivers += [softpipe]
+ env.Prepend(LIBS = [softpipe])
if 'llvmpipe' in env['drivers']:
env.Tool('llvm')
if 'LLVM_VERSION' in env:
env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
env.Tool('udis86')
- sources += ['xlib_llvmpipe.c']
- drivers += [llvmpipe]
+ env.Prepend(LIBS = [llvmpipe])
if 'cell' in env['drivers']:
env.Append(CPPDEFINES = 'GALLIUM_CELL')
- sources += ['xlib_cell.c']
- drivers += [cell]
+ env.Prepend(LIBS = [cell])
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
libgl = env.SharedLibrary(
target ='GL',
source = sources,
- LIBS = st_xlib + glapi + mesa + glsl + drivers + gallium + env['LIBS'],
)
if not env['dri']:
diff --git a/src/gallium/targets/libgl-xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c
new file mode 100644
index 00000000000..48e5bdff429
--- /dev/null
+++ b/src/gallium/targets/libgl-xlib/xlib.c
@@ -0,0 +1,211 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ */
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "target-helpers/wrap_screen.h"
+#include "state_tracker/xlib_sw_winsys.h"
+#include "xm_public.h"
+
+#include "state_tracker/st_manager.h"
+
+/* advertise OpenGL support */
+PUBLIC const int st_api_OpenGL = 1;
+
+PUBLIC const struct st_module st_module_OpenGL = {
+ .api = ST_API_OPENGL,
+ .create_api = st_manager_create_api
+};
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try. Long term, want
+ * to avoid having global #defines for things like GALLIUM_LLVMPIPE,
+ * GALLIUM_CELL, etc. Scons already eliminates those #defines, so
+ * things that are painful for it now are likely to be painful for
+ * other build systems in the future.
+ *
+ * Copies (full or partial):
+ * targets/libgl-xlib
+ * targets/graw-xlib
+ * targets/dri-swrast
+ * winsys/sw/drm
+ * drivers/sw
+ *
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+static struct pipe_screen *
+swrast_create_screen(struct sw_winsys *winsys)
+{
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+ default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+ if (screen == NULL && strcmp(driver, "cell") == 0)
+ screen = cell_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+#endif
+
+ return screen;
+}
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( display );
+ if (winsys == NULL)
+ return NULL;
+
+ /* Create a software rasterizer on top of that winsys:
+ */
+ screen = swrast_create_screen( winsys );
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+static struct xm_driver xlib_driver =
+{
+ .create_pipe_screen = swrast_xlib_create_screen,
+ .create_st_api = st_manager_create_api,
+};
+
+
+/* Build the rendering stack.
+ */
+static void _init( void ) __attribute__((constructor));
+static void _init( void )
+{
+ /* Initialize the xlib libgl code, pass in the winsys:
+ */
+ xmesa_set_driver( &xlib_driver );
+}
+
+
+/***********************************************************************
+ *
+ * Butt-ugly hack to convince the linker not to throw away public GL
+ * symbols (they are all referenced from getprocaddress, I guess).
+ */
+extern void (*linker_foo(const unsigned char *procName))();
+extern void (*glXGetProcAddress(const unsigned char *procName))();
+
+extern void (*linker_foo(const unsigned char *procName))()
+{
+ return glXGetProcAddress(procName);
+}
+
+
+/**
+ * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
+ * libglapi.a. We need to define them here.
+ */
+#ifdef GLX_INDIRECT_RENDERING
+
+#define GL_GLEXT_PROTOTYPES
+#include "GL/gl.h"
+#include "glapi/glapi.h"
+#include "glapi/glapitable.h"
+#include "glapi/glapidispatch.h"
+
+#if defined(USE_MGL_NAMESPACE)
+#define NAME(func) mgl##func
+#else
+#define NAME(func) gl##func
+#endif
+
+#define DISPATCH(FUNC, ARGS, MESSAGE) \
+ CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \
+ return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
+
+/* skip normal ones */
+#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
+#include "glapi/glapitemp.h"
+
+#endif /* GLX_INDIRECT_RENDERING */
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/targets/xorg-i915/Makefile
index 14c2462524b..52a9e97b409 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/targets/xorg-i915/Makefile
@@ -1,13 +1,13 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
TARGET = modesetting_drv.so
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
-TOP = ../../../../../..
-
-include $(TOP)/configs/current
INCLUDES = \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I../gem \
+ -I$(TOP)/src/gallium/winsys/drm/intel/gem \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
@@ -17,7 +17,7 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
$(TOP)/src/gallium/drivers/i915/libi915.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/targets/xorg-i915/intel_xorg.c
index 369dc356cf8..08f3b088636 100644
--- a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
+++ b/src/gallium/targets/xorg-i915/intel_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void intel_xorg_identify(int flags);
static Bool intel_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/targets/xorg-i965/Makefile
index c25726b0bb1..104a1434a84 100644
--- a/src/gallium/winsys/drm/i965/xorg/Makefile
+++ b/src/gallium/targets/xorg-i965/Makefile
@@ -1,29 +1,23 @@
-TOP = ../../../../../..
-
-
-GALLIUMDIR = $(TOP)/src/gallium
+TOP = ../../../..
+include $(TOP)/configs/current
TARGET = i965g_drv.so
-
CFILES = $(wildcard ./*.c)
-
-include ${TOP}/configs/current
-
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
CFLAGS = -DHAVE_CONFIG_H \
-g -Wall -Wimplicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/drivers \
- -I${GALLIUMDIR}/auxiliary \
- -I${TOP}/src/mesa \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
$(TOP)/src/gallium/drivers/i965/libi965.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
@@ -34,7 +28,7 @@ TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
all default: $(TARGET) $(TARGET_STAGING)
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
diff --git a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c b/src/gallium/targets/xorg-i965/intel_xorg.c
index ac691cb76b3..f4608f0eb41 100644
--- a/src/gallium/winsys/drm/i965/xorg/intel_xorg.c
+++ b/src/gallium/targets/xorg-i965/intel_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void intel_xorg_identify(int flags);
static Bool intel_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/targets/xorg-nouveau/Makefile
index 179b50230b5..b514b570007 100644
--- a/src/gallium/winsys/drm/nouveau/xorg/Makefile
+++ b/src/gallium/targets/xorg-nouveau/Makefile
@@ -1,13 +1,12 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
TARGET = modesetting_drv.so
CFILES = $(wildcard ./*.c)
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
-TOP = ../../../../../..
-
-include $(TOP)/configs/current
INCLUDES = \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I../gem \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary \
@@ -17,9 +16,8 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
- $(TOP)/src/gallium/drivers/nv30/libnv30.a \
- $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
index a669b3080aa..699af09029f 100644
--- a/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
+++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
@@ -28,7 +28,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void nouveau_xorg_identify(int flags);
static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/targets/xorg-radeon/Makefile
index 0eb1b3988f3..cd32914c0d3 100644
--- a/src/gallium/winsys/drm/radeon/xorg/Makefile
+++ b/src/gallium/targets/xorg-radeon/Makefile
@@ -1,29 +1,23 @@
-TOP = ../../../../../..
-
-
-GALLIUMDIR = $(TOP)/src/gallium
+TOP = ../../../..
+include $(TOP)/configs/current
TARGET = radeong_drv.so
-
CFILES = $(wildcard ./*.c)
-
-include ${TOP}/configs/current
-
OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
CFLAGS = -DHAVE_CONFIG_H \
-g -Wall -Wimplicit-function-declaration -fPIC \
$(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/drivers \
- -I${GALLIUMDIR}/auxiliary \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
-I${TOP}/src/mesa \
-I$(TOP)/include \
-I$(TOP)/src/egl/main
LIBS = \
- $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \
- $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \
+ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/r300/libr300.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
@@ -34,7 +28,7 @@ TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
all default: $(TARGET) $(TARGET_STAGING)
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_radeon
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/targets/xorg-radeon/radeon_xorg.c
index bb76cc03499..0d6aa567229 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/targets/xorg-radeon/radeon_xorg.c
@@ -29,7 +29,7 @@
*
*/
-#include "../../../../state_trackers/xorg/xorg_winsys.h"
+#include "../../state_trackers/xorg/xorg_winsys.h"
static void radeon_xorg_identify(int flags);
static Bool radeon_xorg_pci_probe(DriverPtr driver,
diff --git a/src/gallium/winsys/drm/vmware/xorg/Makefile b/src/gallium/targets/xorg-vmwgfx/Makefile
index 49e28ae17f5..12bc307ef9b 100644
--- a/src/gallium/winsys/drm/vmware/xorg/Makefile
+++ b/src/gallium/targets/xorg-vmwgfx/Makefile
@@ -1,5 +1,4 @@
-TOP = ../../../../../..
-
+TOP = ../../../..
include $(TOP)/configs/current
TARGET = vmwgfx_drv.so
@@ -21,7 +20,7 @@ INCLUDES = \
LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
- $(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/vmware/xorg/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript
index 1e5d8ff7fed..b63ab99e050 100644
--- a/src/gallium/winsys/drm/vmware/xorg/SConscript
+++ b/src/gallium/targets/xorg-vmwgfx/SConscript
@@ -2,6 +2,10 @@ import os.path
Import('*')
+if not 'svga' in env['drivers']:
+ print 'warning: svga pipe driver not built skipping vmwgfx_drv.so'
+ Return()
+
if env['platform'] == 'linux':
env = env.Clone()
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h b/src/gallium/targets/xorg-vmwgfx/vmw_driver.h
index ba754b51e47..ba754b51e47 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_driver.h
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_driver.h
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h b/src/gallium/targets/xorg-vmwgfx/vmw_hook.h
index 224a2d92996..224a2d92996 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_hook.h
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_hook.h
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c b/src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c
index 521578ab35d..96ee4ff82b4 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_ioctl.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_ioctl.c
@@ -42,7 +42,7 @@
#include <sys/mman.h>
#include "xf86drm.h"
-#include "../core/vmwgfx_drm.h"
+#include "../../winsys/svga/drm/vmwgfx_drm.h"
#include "vmw_driver.h"
#include "util/u_debug.h"
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
index f43f91e5c0d..f43f91e5c0d 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_screen.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/targets/xorg-vmwgfx/vmw_video.c
index de28f06a475..eced60d0ec1 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_video.c
@@ -62,7 +62,7 @@ typedef uint8_t uint8;
#include <X11/extensions/Xv.h>
#include "xf86drm.h"
-#include "../core/vmwgfx_drm.h"
+#include "../../winsys/svga/drm/vmwgfx_drm.h"
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/targets/xorg-vmwgfx/vmw_xorg.c
index 87aad25b24f..87aad25b24f 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_xorg.c
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
index 30c3378dfff..2013ee97c1c 100644
--- a/src/gallium/winsys/SConscript
+++ b/src/gallium/winsys/SConscript
@@ -1,16 +1,36 @@
Import('*')
-if env['dri']:
- SConscript([
- 'drm/SConscript',
- ])
-
if 'xlib' in env['winsys']:
SConscript([
- 'xlib/SConscript',
+ 'sw/xlib/SConscript',
])
if 'gdi' in env['winsys']:
SConscript([
- 'gdi/SConscript',
+ 'sw/gdi/SConscript',
])
+
+if env['dri']:
+ SConscript([
+ 'sw/dri/SConscript',
+ ])
+
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'svga/drm/SConscript',
+ ])
+
+ if 'i915' in env['winsys']:
+ SConscript([
+ 'i915/drm/SConscript',
+ ])
+
+ if 'i965' in env['winsys']:
+ SConscript([
+ 'i965/drm/SConscript',
+ ])
+
+ if 'radeon' in env['winsys']:
+ SConscript([
+ 'radeon/drm/SConscript',
+ ])
diff --git a/src/gallium/winsys/drm/SConscript b/src/gallium/winsys/drm/SConscript
deleted file mode 100644
index 66b73a8bf93..00000000000
--- a/src/gallium/winsys/drm/SConscript
+++ /dev/null
@@ -1,69 +0,0 @@
-Import('*')
-
-if env['dri']:
-
- drienv = env.Clone()
-
- drienv.Replace(CPPPATH = [
- '#src/mesa/drivers/dri/common',
- '#include',
- '#include/GL/internal',
- '#src/gallium/include',
- '#src/gallium/auxiliary',
- '#src/gallium/drivers',
- '#src/mesa',
- '#src/mesa/main',
- '#src/mesa/glapi',
- '#src/mesa/math',
- '#src/mesa/transform',
- '#src/mesa/shader',
- '#src/mesa/swrast',
- '#src/mesa/swrast_setup',
- '#src/egl/main',
- '#src/egl/drivers/dri',
- ])
-
- drienv.ParseConfig('pkg-config --cflags --libs libdrm')
-
- COMMON_GALLIUM_SOURCES = [
- '#src/mesa/drivers/dri/common/utils.c',
- '#src/mesa/drivers/dri/common/vblank.c',
- '#src/mesa/drivers/dri/common/dri_util.c',
- '#src/mesa/drivers/dri/common/xmlconfig.c',
- ]
-
- COMMON_BM_SOURCES = [
- '#src/mesa/drivers/dri/common/dri_bufmgr.c',
- '#src/mesa/drivers/dri/common/dri_drmpool.c',
- ]
-
- Export([
- 'drienv',
- 'COMMON_GALLIUM_SOURCES',
- 'COMMON_BM_SOURCES',
- ])
-
- # TODO: Installation
- #install: $(LIBNAME)
- # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
- # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
-
- if 'vmware' in env['winsys']:
- SConscript([
- 'vmware/SConscript',
- ])
-
- if 'intel' in env['winsys']:
- SConscript([
- 'intel/SConscript',
- ])
-
- if 'i965' in env['winsys']:
- SConscript([
- 'i965/SConscript',
- ])
-
- if 'radeon' in env['winsys']:
- SConscript([
- 'radeon/SConscript',
- ])
diff --git a/src/gallium/winsys/drm/i965/Makefile b/src/gallium/winsys/drm/i965/Makefile
deleted file mode 100644
index d8feef6824a..00000000000
--- a/src/gallium/winsys/drm/i965/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/intel/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/i965/SConscript b/src/gallium/winsys/drm/i965/SConscript
deleted file mode 100644
index 50d7b75ed68..00000000000
--- a/src/gallium/winsys/drm/i965/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['gem/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/i965/dri/SConscript b/src/gallium/winsys/drm/i965/dri/SConscript
deleted file mode 100644
index a99533fd245..00000000000
--- a/src/gallium/winsys/drm/i965/dri/SConscript
+++ /dev/null
@@ -1,19 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
-
-drivers = [
- st_dri,
- i965drm,
- i965,
- trace,
-]
-
-env.LoadableModule(
- target ='i965_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- LIBS = drivers + mesa + gallium + env['LIBS'],
- SHLIBPREFIX = '',
-)
diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile
deleted file mode 100644
index 1c132582005..00000000000
--- a/src/gallium/winsys/drm/i965/egl/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = i965
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_intel
-
-EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/i965/gem/libi965drm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
- $(TOP)/src/gallium/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/i965/libi965.a
-
-include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c b/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
deleted file mode 100644
index a061eef0beb..00000000000
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_api.c
+++ /dev/null
@@ -1,238 +0,0 @@
-
-#include <stdio.h>
-#include "state_tracker/drm_api.h"
-
-#include "i965_drm_winsys.h"
-#include "util/u_memory.h"
-
-#include "i965/brw_context.h" /* XXX: shouldn't be doing this */
-#include "i965/brw_screen.h" /* XXX: shouldn't be doing this */
-
-#include "trace/tr_drm.h"
-
-/*
- * Helper functions
- */
-
-
-static void
-i965_libdrm_get_device_id(unsigned int *device_id)
-{
- char path[512];
- FILE *file;
- void *shutup_gcc;
-
- /*
- * FIXME: Fix this up to use a drm ioctl or whatever.
- */
-
- snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
- file = fopen(path, "r");
- if (!file) {
- return;
- }
-
- shutup_gcc = fgets(path, sizeof(path), file);
- sscanf(path, "%x", device_id);
- fclose(file);
-}
-
-static struct i965_libdrm_buffer *
-i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
- const char* name, unsigned handle)
-{
- struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
- uint32_t swizzle = 0;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!buf)
- return NULL;
- pipe_reference_init(&buf->base.reference, 1);
- buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
- buf->base.size = buf->bo->size;
- buf->base.sws = &idws->base;
- buf->flinked = TRUE;
- buf->flink = handle;
-
-
- if (!buf->bo)
- goto err;
-
- drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
- if (buf->tiling != 0)
- buf->map_gtt = TRUE;
-
- return buf;
-
-err:
- FREE(buf);
- return NULL;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_texture *
-i965_libdrm_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *template,
- const char* name,
- unsigned pitch,
- unsigned handle)
-{
- /* XXX: this is silly -- there should be a way to get directly from
- * the "drm_api" struct to ourselves, without peering into
- * unrelated code:
- */
- struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
- struct i965_libdrm_buffer *buffer;
-
- if (BRW_DUMP)
- debug_printf("%s %s pitch %d handle 0x%x\n", __FUNCTION__,
- name, pitch, handle);
-
- buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
- if (!buffer)
- return NULL;
-
- return brw_texture_blanket_winsys_buffer(screen, template, pitch,
- buffer->tiling,
- &buffer->base);
-}
-
-
-static boolean
-i965_libdrm_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct i965_libdrm_buffer *buf = NULL;
- struct brw_winsys_buffer *buffer = NULL;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
- return FALSE;
-
- buf = i965_libdrm_buffer(buffer);
- if (!buf->flinked) {
- if (drm_intel_bo_flink(buf->bo, &buf->flink))
- return FALSE;
- buf->flinked = TRUE;
- }
-
- *handle = buf->flink;
-
- if (BRW_DUMP)
- debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
-
- return TRUE;
-}
-
-static boolean
-i965_libdrm_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct brw_winsys_buffer *buffer = NULL;
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
- return FALSE;
-
- *handle = i965_libdrm_buffer(buffer)->bo->handle;
-
- if (BRW_DUMP)
- debug_printf(" -> pitch %d handle 0x%x\n", *pitch, *handle);
-
- return TRUE;
-}
-
-static void
-i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
-{
- struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
-
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
- drm_intel_bufmgr_destroy(idws->gem);
-
- FREE(idws);
-}
-
-static struct pipe_screen *
-i965_libdrm_create_screen(struct drm_api *api, int drmFD,
- struct drm_create_screen_arg *arg)
-{
- struct i965_libdrm_winsys *idws;
- unsigned int deviceID;
-
- debug_printf("%s\n", __FUNCTION__);
-
- if (arg != NULL) {
- switch(arg->mode) {
- case DRM_CREATE_NORMAL:
- break;
- default:
- return NULL;
- }
- }
-
- idws = CALLOC_STRUCT(i965_libdrm_winsys);
- if (!idws)
- return NULL;
-
- i965_libdrm_get_device_id(&deviceID);
-
- i965_libdrm_winsys_init_buffer_functions(idws);
-
- idws->fd = drmFD;
- idws->id = deviceID;
-
- idws->base.destroy = i965_libdrm_winsys_destroy;
-
- idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
- drm_intel_bufmgr_gem_enable_reuse(idws->gem);
-
- idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
-
- return brw_create_screen(&idws->base, deviceID);
-}
-
-
-static void
-destroy(struct drm_api *api)
-{
- if (BRW_DUMP)
- debug_printf("%s\n", __FUNCTION__);
-
-}
-
-struct drm_api i965_libdrm_api =
-{
- .name = "i965",
- .create_screen = i965_libdrm_create_screen,
- .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
- .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
- .local_handle_from_texture = i965_libdrm_local_handle_from_texture,
- .destroy = destroy,
-};
-
-struct drm_api *
-drm_api_create()
-{
- return trace_drm_create(&i965_libdrm_api);
-}
diff --git a/src/gallium/winsys/drm/intel/SConscript b/src/gallium/winsys/drm/intel/SConscript
deleted file mode 100644
index 50d7b75ed68..00000000000
--- a/src/gallium/winsys/drm/intel/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['gem/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
deleted file mode 100644
index 0df841d8798..00000000000
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ /dev/null
@@ -1,21 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
-
-env.Prepend(LIBS = [
- st_dri,
- inteldrm,
- i915,
- trace,
- mesa,
- glsl,
- gallium
-])
-
-env.LoadableModule(
- target ='i915_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- SHLIBPREFIX = '',
-)
diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript
deleted file mode 100644
index 26717f391fa..00000000000
--- a/src/gallium/winsys/drm/intel/gem/SConscript
+++ /dev/null
@@ -1,17 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-inteldrm_sources = [
- 'intel_drm_api.c',
- 'intel_drm_batchbuffer.c',
- 'intel_drm_buffer.c',
- 'intel_drm_fence.c',
-]
-
-inteldrm = env.ConvenienceLibrary(
- target ='inteldrm',
- source = inteldrm_sources,
-)
-
-Export('inteldrm')
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
deleted file mode 100644
index 377ed255131..00000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ /dev/null
@@ -1,205 +0,0 @@
-#include <stdio.h>
-
-#include "state_tracker/drm_api.h"
-
-#include "intel_drm_winsys.h"
-#include "util/u_memory.h"
-
-#include "i915/i915_context.h"
-#include "i915/i915_screen.h"
-
-#include "trace/tr_drm.h"
-
-/*
- * Helper functions
- */
-
-
-static void
-intel_drm_get_device_id(unsigned int *device_id)
-{
- char path[512];
- FILE *file;
- void *shutup_gcc;
-
- /*
- * FIXME: Fix this up to use a drm ioctl or whatever.
- */
-
- snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
- file = fopen(path, "r");
- if (!file) {
- return;
- }
-
- shutup_gcc = fgets(path, sizeof(path), file);
- (void) shutup_gcc;
- sscanf(path, "%x", device_id);
- fclose(file);
-}
-
-static struct intel_buffer *
-intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
- const char* name, unsigned handle)
-{
- struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
- uint32_t tile = 0, swizzle = 0;
-
- if (!buf)
- return NULL;
-
- buf->magic = 0xDEAD1337;
- buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
- buf->flinked = TRUE;
- buf->flink = handle;
-
- if (!buf->bo)
- goto err;
-
- drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
- if (tile != INTEL_TILE_NONE)
- buf->map_gtt = TRUE;
-
- return (struct intel_buffer *)buf;
-
-err:
- FREE(buf);
- return NULL;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_texture *
-intel_drm_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char* name,
- unsigned pitch,
- unsigned handle)
-{
- struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
- struct intel_buffer *buffer;
-
- buffer = intel_drm_buffer_from_handle(idws, name, handle);
- if (!buffer)
- return NULL;
-
- return i915_texture_blanket_intel(screen, templ, pitch, buffer);
-}
-
-static boolean
-intel_drm_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct intel_drm_buffer *buf = NULL;
- struct intel_buffer *buffer = NULL;
- if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
- return FALSE;
-
- buf = intel_drm_buffer(buffer);
- if (!buf->flinked) {
- if (drm_intel_bo_flink(buf->bo, &buf->flink))
- return FALSE;
- buf->flinked = TRUE;
- }
-
- *handle = buf->flink;
-
- return TRUE;
-}
-
-static boolean
-intel_drm_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *pitch,
- unsigned *handle)
-{
- struct intel_buffer *buffer = NULL;
- if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
- return FALSE;
-
- *handle = intel_drm_buffer(buffer)->bo->handle;
-
- return TRUE;
-}
-
-static void
-intel_drm_winsys_destroy(struct intel_winsys *iws)
-{
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
-
- drm_intel_bufmgr_destroy(idws->pools.gem);
-
- FREE(idws);
-}
-
-static struct pipe_screen *
-intel_drm_create_screen(struct drm_api *api, int drmFD,
- struct drm_create_screen_arg *arg)
-{
- struct intel_drm_winsys *idws;
- unsigned int deviceID;
-
- if (arg != NULL) {
- switch(arg->mode) {
- case DRM_CREATE_NORMAL:
- break;
- default:
- return NULL;
- }
- }
-
- idws = CALLOC_STRUCT(intel_drm_winsys);
- if (!idws)
- return NULL;
-
- intel_drm_get_device_id(&deviceID);
-
- intel_drm_winsys_init_batchbuffer_functions(idws);
- intel_drm_winsys_init_buffer_functions(idws);
- intel_drm_winsys_init_fence_functions(idws);
-
- idws->fd = drmFD;
- idws->id = deviceID;
- idws->max_batch_size = 16 * 4096;
-
- idws->base.destroy = intel_drm_winsys_destroy;
-
- idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
- drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem);
-
- idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
-
- return i915_create_screen(&idws->base, deviceID);
-}
-
-static void
-destroy(struct drm_api *api)
-{
-
-}
-
-struct drm_api intel_drm_api =
-{
- .name = "i915",
- .driver_name = "i915",
- .create_screen = intel_drm_create_screen,
- .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
- .shared_handle_from_texture = intel_drm_shared_handle_from_texture,
- .local_handle_from_texture = intel_drm_local_handle_from_texture,
- .destroy = destroy,
-};
-
-struct drm_api *
-drm_api_create()
-{
- return trace_drm_create(&intel_drm_api);
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
deleted file mode 100644
index ac4dd6e00e9..00000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
+++ /dev/null
@@ -1,154 +0,0 @@
-
-#include "intel_drm_winsys.h"
-#include "util/u_memory.h"
-
-#include "i915_drm.h"
-
-static struct intel_buffer *
-intel_drm_buffer_create(struct intel_winsys *iws,
- unsigned size, unsigned alignment,
- enum intel_buffer_type type)
-{
- struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
- drm_intel_bufmgr *pool;
- char *name;
-
- if (!buf)
- return NULL;
-
- buf->magic = 0xDEAD1337;
- buf->flinked = FALSE;
- buf->flink = 0;
- buf->map_gtt = FALSE;
-
- if (type == INTEL_NEW_TEXTURE) {
- name = "gallium3d_texture";
- pool = idws->pools.gem;
- } else if (type == INTEL_NEW_VERTEX) {
- name = "gallium3d_vertex";
- pool = idws->pools.gem;
- buf->map_gtt = TRUE;
- } else if (type == INTEL_NEW_SCANOUT) {
- name = "gallium3d_scanout";
- pool = idws->pools.gem;
- buf->map_gtt = TRUE;
- } else {
- assert(0);
- name = "gallium3d_unknown";
- pool = idws->pools.gem;
- }
-
- buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
-
- if (!buf->bo)
- goto err;
-
- return (struct intel_buffer *)buf;
-
-err:
- assert(0);
- FREE(buf);
- return NULL;
-}
-
-static int
-intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
- struct intel_buffer *buffer,
- unsigned stride,
- enum intel_buffer_tile tile)
-{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
- assert(I915_TILING_NONE == INTEL_TILE_NONE);
- assert(I915_TILING_X == INTEL_TILE_X);
- assert(I915_TILING_Y == INTEL_TILE_Y);
-
- if (tile != INTEL_TILE_NONE) {
- assert(buf->map_count == 0);
- buf->map_gtt = TRUE;
- }
-
- return drm_intel_bo_set_tiling(buf->bo, &tile, stride);
-}
-
-static void *
-intel_drm_buffer_map(struct intel_winsys *iws,
- struct intel_buffer *buffer,
- boolean write)
-{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
- drm_intel_bo *bo = intel_bo(buffer);
- int ret = 0;
-
- assert(bo);
-
- if (buf->map_count)
- goto out;
-
- if (buf->map_gtt)
- ret = drm_intel_gem_bo_map_gtt(bo);
- else
- ret = drm_intel_bo_map(bo, write);
-
- buf->ptr = bo->virtual;
-
- assert(ret == 0);
-out:
- if (ret)
- return NULL;
-
- buf->map_count++;
- return buf->ptr;
-}
-
-static void
-intel_drm_buffer_unmap(struct intel_winsys *iws,
- struct intel_buffer *buffer)
-{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
-
- if (--buf->map_count)
- return;
-
- if (buf->map_gtt)
- drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
- else
- drm_intel_bo_unmap(intel_bo(buffer));
-}
-
-static int
-intel_drm_buffer_write(struct intel_winsys *iws,
- struct intel_buffer *buffer,
- size_t offset,
- size_t size,
- const void *data)
-{
- struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
-
- return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
-}
-
-static void
-intel_drm_buffer_destroy(struct intel_winsys *iws,
- struct intel_buffer *buffer)
-{
- drm_intel_bo_unreference(intel_bo(buffer));
-
-#ifdef DEBUG
- intel_drm_buffer(buffer)->magic = 0;
- intel_drm_buffer(buffer)->bo = NULL;
-#endif
-
- FREE(buffer);
-}
-
-void
-intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
-{
- idws->base.buffer_create = intel_drm_buffer_create;
- idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
- idws->base.buffer_map = intel_drm_buffer_map;
- idws->base.buffer_unmap = intel_drm_buffer_unmap;
- idws->base.buffer_write = intel_drm_buffer_write;
- idws->base.buffer_destroy = intel_drm_buffer_destroy;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
deleted file mode 100644
index 9786ee93650..00000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
+++ /dev/null
@@ -1,77 +0,0 @@
-
-#ifndef INTEL_DRM_WINSYS_H
-#define INTEL_DRM_WINSYS_H
-
-#include "i915/intel_batchbuffer.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-
-/*
- * Winsys
- */
-
-
-struct intel_drm_winsys
-{
- struct intel_winsys base;
-
- boolean dump_cmd;
-
- int fd; /**< Drm file discriptor */
-
- unsigned id;
-
- size_t max_batch_size;
-
- struct {
- drm_intel_bufmgr *gem;
- } pools;
-};
-
-static INLINE struct intel_drm_winsys *
-intel_drm_winsys(struct intel_winsys *iws)
-{
- return (struct intel_drm_winsys *)iws;
-}
-
-struct intel_drm_winsys * intel_drm_winsys_create(int fd, unsigned pci_id);
-struct pipe_fence_handle * intel_drm_fence_create(drm_intel_bo *bo);
-
-void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws);
-void intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws);
-void intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws);
-
-
-/*
- * Buffer
- */
-
-
-struct intel_drm_buffer {
- unsigned magic;
-
- drm_intel_bo *bo;
-
- void *ptr;
- unsigned map_count;
- boolean map_gtt;
-
- boolean flinked;
- unsigned flink;
-};
-
-static INLINE struct intel_drm_buffer *
-intel_drm_buffer(struct intel_buffer *buffer)
-{
- return (struct intel_drm_buffer *)buffer;
-}
-
-static INLINE drm_intel_bo *
-intel_bo(struct intel_buffer *buffer)
-{
- return intel_drm_buffer(buffer)->bo;
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile
deleted file mode 100644
index 6c9cbef26df..00000000000
--- a/src/gallium/winsys/drm/nouveau/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/nouveau/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/nouveau/egl/Makefile b/src/gallium/winsys/drm/nouveau/egl/Makefile
deleted file mode 100644
index 2c352603320..00000000000
--- a/src/gallium/winsys/drm/nouveau/egl/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = nouveau
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_nouveau
-
-EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
- $(TOP)/src/gallium/drivers/nv30/libnv30.a \
- $(TOP)/src/gallium/drivers/nv40/libnv40.a \
- $(TOP)/src/gallium/drivers/nv50/libnv50.a \
- $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-
-include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/radeon/Makefile b/src/gallium/winsys/drm/radeon/Makefile
deleted file mode 100644
index bacdf3de28a..00000000000
--- a/src/gallium/winsys/drm/radeon/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/radeon/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/radeon/SConscript b/src/gallium/winsys/drm/radeon/SConscript
deleted file mode 100644
index b2dfd504d42..00000000000
--- a/src/gallium/winsys/drm/radeon/SConscript
+++ /dev/null
@@ -1,7 +0,0 @@
-Import('*')
-
-SConscript(['core/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
deleted file mode 100644
index e5c69199330..00000000000
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright © 2008 Jérôme Glisse
- * 2009 Corbin Simpson
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
- * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- * Jérôme Glisse <[email protected]>
- * Corbin Simpson <[email protected]>
- */
-
-#include "radeon_buffer.h"
-#include "radeon_drm.h"
-
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "radeon_bo_gem.h"
-#include <X11/Xutil.h>
-
-struct radeon_vl_context
-{
- Display *display;
- int screen;
- Drawable drawable;
-};
-
-static const char *radeon_get_name(struct pipe_winsys *ws)
-{
- return "Radeon/GEM+KMS";
-}
-
-static uint32_t radeon_domain_from_usage(unsigned usage)
-{
- uint32_t domain = 0;
-
- if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BUFFER_USAGE_PIXEL) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BUFFER_USAGE_VERTEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
- if (usage & PIPE_BUFFER_USAGE_INDEX) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
-
- return domain;
-}
-
-static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct radeon_winsys *radeon_ws = (struct radeon_winsys *)ws;
- struct radeon_pipe_buffer *radeon_buffer;
- struct pb_desc desc;
- uint32_t domain;
-
- radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
- if (radeon_buffer == NULL) {
- return NULL;
- }
-
- pipe_reference_init(&radeon_buffer->base.reference, 1);
- radeon_buffer->base.alignment = alignment;
- radeon_buffer->base.usage = usage;
- radeon_buffer->base.size = size;
-
- if (usage & PIPE_BUFFER_USAGE_CONSTANT && is_r3xx(radeon_ws->pci_id)) {
- /* Don't bother allocating a BO, as it'll never get to the card. */
- desc.alignment = alignment;
- desc.usage = usage;
- radeon_buffer->pb = pb_malloc_buffer_create(size, &desc);
- return &radeon_buffer->base;
- }
-
- domain = radeon_domain_from_usage(usage);
-
- radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size,
- alignment, domain, 0);
- if (radeon_buffer->bo == NULL) {
- FREE(radeon_buffer);
- return NULL;
- }
- return &radeon_buffer->base;
-}
-
-static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
- void *ptr,
- unsigned bytes)
-{
- struct radeon_pipe_buffer *radeon_buffer;
-
- radeon_buffer =
- (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes);
- if (radeon_buffer == NULL) {
- return NULL;
- }
- radeon_bo_map(radeon_buffer->bo, 1);
- memcpy(radeon_buffer->bo->ptr, ptr, bytes);
- radeon_bo_unmap(radeon_buffer->bo);
- return &radeon_buffer->base;
-}
-
-static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
- unsigned width,
- unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- /* Radeons enjoy things in multiples of 32. */
- /* XXX this can be 32 when POT */
- const unsigned alignment = 64;
- unsigned nblocksy, size;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
- size = *stride * nblocksy;
-
- return radeon_buffer_create(ws, 64, usage, size);
-}
-
-static void radeon_buffer_del(struct pipe_buffer *buffer)
-{
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
-
- if (radeon_buffer->pb) {
- pipe_reference_init(&radeon_buffer->pb->base.reference, 0);
- pb_destroy(radeon_buffer->pb);
- }
-
- if (radeon_buffer->bo) {
- radeon_bo_unref(radeon_buffer->bo);
- }
-
- FREE(radeon_buffer);
-}
-
-static void *radeon_buffer_map(struct pipe_winsys *ws,
- struct pipe_buffer *buffer,
- unsigned flags)
-{
- struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- int write = 0;
-
- if (radeon_buffer->pb) {
- return pb_map(radeon_buffer->pb, flags);
- }
-
- if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- uint32_t domain;
-
- if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
- return NULL;
- }
-
- if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
- priv->flush_cb(priv->flush_data);
- }
-
- if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
- write = 1;
- }
-
- if (radeon_bo_map(radeon_buffer->bo, write)) {
- return NULL;
- }
-
- return radeon_buffer->bo->ptr;
-}
-
-static void radeon_buffer_unmap(struct pipe_winsys *ws,
- struct pipe_buffer *buffer)
-{
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
-
- if (radeon_buffer->pb) {
- pb_unmap(radeon_buffer->pb);
- } else {
- radeon_bo_unmap(radeon_buffer->bo);
- }
-}
-
-static void radeon_buffer_set_tiling(struct radeon_winsys *ws,
- struct pipe_buffer *buffer,
- uint32_t pitch,
- boolean microtiled,
- boolean macrotiled)
-{
- struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv;
- struct radeon_pipe_buffer *radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- uint32_t flags = 0, old_flags, old_pitch;
-
- if (microtiled) {
- flags |= RADEON_BO_FLAGS_MICRO_TILE;
- }
- if (macrotiled) {
- flags |= RADEON_BO_FLAGS_MACRO_TILE;
- }
-
- radeon_bo_get_tiling(radeon_buffer->bo, &old_flags, &old_pitch);
-
- if (flags != old_flags || pitch != old_pitch) {
- /* Tiling determines how DRM treats the buffer data.
- * We must flush CS when changing it if the buffer is referenced. */
- if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) {
- priv->flush_cb(priv->flush_data);
- }
-
- radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch);
- }
-}
-
-static void radeon_fence_reference(struct pipe_winsys *ws,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *pfence)
-{
-}
-
-static int radeon_fence_signalled(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence,
- unsigned flag)
-{
- return 1;
-}
-
-static int radeon_fence_finish(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence,
- unsigned flag)
-{
- return 0;
-}
-
-struct radeon_winsys* radeon_pipe_winsys(int fd)
-{
- struct radeon_winsys* radeon_ws;
-
- radeon_ws = CALLOC_STRUCT(radeon_winsys);
- if (radeon_ws == NULL) {
- return NULL;
- }
-
- radeon_ws->priv = CALLOC_STRUCT(radeon_winsys_priv);
- if (radeon_ws->priv == NULL) {
- FREE(radeon_ws);
- return NULL;
- }
-
- radeon_ws->priv->fd = fd;
- radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd);
-
- radeon_ws->base.flush_frontbuffer = NULL; /* overriden by co-state tracker */
-
- radeon_ws->base.buffer_create = radeon_buffer_create;
- radeon_ws->base.user_buffer_create = radeon_buffer_user_create;
- radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;
- radeon_ws->base.buffer_map = radeon_buffer_map;
- radeon_ws->base.buffer_unmap = radeon_buffer_unmap;
- radeon_ws->base.buffer_destroy = radeon_buffer_del;
-
- radeon_ws->base.fence_reference = radeon_fence_reference;
- radeon_ws->base.fence_signalled = radeon_fence_signalled;
- radeon_ws->base.fence_finish = radeon_fence_finish;
-
- radeon_ws->base.get_name = radeon_get_name;
-
- radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling;
-
- return radeon_ws;
-}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
deleted file mode 100644
index 122bd213543..00000000000
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "radeon_r300.h"
-#include "radeon_buffer.h"
-
-#include "radeon_cs_gem.h"
-
-static void radeon_set_flush_cb(struct radeon_winsys *winsys,
- void (*flush_cb)(void *),
- void *data)
-{
- winsys->priv->flush_cb = flush_cb;
- winsys->priv->flush_data = data;
- radeon_cs_space_set_flush(winsys->priv->cs, flush_cb, data);
-}
-
-static boolean radeon_add_buffer(struct radeon_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd)
-{
- struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
-
- radeon_cs_space_add_persistent_bo(winsys->priv->cs, bo, rd, wd);
- return TRUE;
-}
-
-static boolean radeon_validate(struct radeon_winsys* winsys)
-{
- if (radeon_cs_space_check(winsys->priv->cs) < 0) {
- return FALSE;
- }
-
- /* Things are fine, we can proceed as normal. */
- return TRUE;
-}
-
-static boolean radeon_check_cs(struct radeon_winsys* winsys, int size)
-{
- struct radeon_cs* cs = winsys->priv->cs;
-
- return radeon_validate(winsys) && cs->cdw + size <= cs->ndw;
-}
-
-static void radeon_begin_cs(struct radeon_winsys* winsys,
- int size,
- const char* file,
- const char* function,
- int line)
-{
- radeon_cs_begin(winsys->priv->cs, size, file, function, line);
-}
-
-static void radeon_write_cs_dword(struct radeon_winsys* winsys,
- uint32_t dword)
-{
- radeon_cs_write_dword(winsys->priv->cs, dword);
-}
-
-static void radeon_write_cs_reloc(struct radeon_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags)
-{
- int retval = 0;
- struct radeon_pipe_buffer* radeon_buffer =
- (struct radeon_pipe_buffer*)pbuffer;
-
- assert(!radeon_buffer->pb);
-
- retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo,
- rd, wd, flags);
-
- if (retval) {
- debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
- pbuffer, rd, wd, flags);
- }
-}
-
-static void radeon_reset_bos(struct radeon_winsys *winsys)
-{
- radeon_cs_space_reset_bos(winsys->priv->cs);
-}
-
-static void radeon_end_cs(struct radeon_winsys* winsys,
- const char* file,
- const char* function,
- int line)
-{
- radeon_cs_end(winsys->priv->cs, file, function, line);
-}
-
-static void radeon_flush_cs(struct radeon_winsys* winsys)
-{
- int retval;
-
- /* Don't flush a zero-sized CS. */
- if (!winsys->priv->cs->cdw) {
- return;
- }
-
- /* Emit the CS. */
- retval = radeon_cs_emit(winsys->priv->cs);
- if (retval) {
- debug_printf("radeon: Bad CS, dumping...\n");
- radeon_cs_print(winsys->priv->cs, stderr);
- }
-
- /* Reset CS.
- * Someday, when we care about performance, we should really find a way
- * to rotate between two or three CS objects so that the GPU can be
- * spinning through one CS while another one is being filled. */
- radeon_cs_erase(winsys->priv->cs);
-}
-
-void
-radeon_setup_winsys(int fd, struct radeon_winsys* winsys)
-{
- struct radeon_winsys_priv* priv = winsys->priv;
-
- priv->csm = radeon_cs_manager_gem_ctor(fd);
-
- /* Size limit on IBs is 64 kibibytes. */
- priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4);
- radeon_cs_set_limit(priv->cs,
- RADEON_GEM_DOMAIN_GTT, winsys->gart_size);
- radeon_cs_set_limit(priv->cs,
- RADEON_GEM_DOMAIN_VRAM, winsys->vram_size);
-
- winsys->add_buffer = radeon_add_buffer;
- winsys->validate = radeon_validate;
-
- winsys->check_cs = radeon_check_cs;
- winsys->begin_cs = radeon_begin_cs;
- winsys->write_cs_dword = radeon_write_cs_dword;
- winsys->write_cs_reloc = radeon_write_cs_reloc;
- winsys->end_cs = radeon_end_cs;
- winsys->flush_cs = radeon_flush_cs;
- winsys->reset_bos = radeon_reset_bos;
- winsys->set_flush_cb = radeon_set_flush_cb;
-}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
deleted file mode 100644
index 4901080ca7b..00000000000
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright © 2009 Corbin Simpson
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
- * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- */
-/*
- * Authors:
- * Corbin Simpson <[email protected]>
- */
-#ifndef RADEON_WINSYS_H
-#define RADEON_WINSYS_H
-
-#include "util/u_simple_screen.h"
-
-struct radeon_winsys_priv;
-
-struct radeon_winsys {
- /* Parent class. */
- struct pipe_winsys base;
-
- /* Winsys private */
- struct radeon_winsys_priv* priv;
-
- /* PCI ID */
- uint32_t pci_id;
-
- /* GB pipe count */
- uint32_t gb_pipes;
-
- /* Z pipe count (rv530 only) */
- uint32_t z_pipes;
-
- /* GART size. */
- uint32_t gart_size;
-
- /* VRAM size. */
- uint32_t vram_size;
-
- /* Add a pipe_buffer to the list of buffer objects to validate. */
- boolean (*add_buffer)(struct radeon_winsys* winsys,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd);
-
- /* Revalidate all currently setup pipe_buffers.
- * Returns TRUE if a flush is required. */
- boolean (*validate)(struct radeon_winsys* winsys);
-
- /* Check to see if there's room for commands. */
- boolean (*check_cs)(struct radeon_winsys* winsys, int size);
-
- /* Start a command emit. */
- void (*begin_cs)(struct radeon_winsys* winsys,
- int size,
- const char* file,
- const char* function,
- int line);
-
- /* Write a dword to the command buffer. */
- void (*write_cs_dword)(struct radeon_winsys* winsys, uint32_t dword);
-
- /* Write a relocated dword to the command buffer. */
- void (*write_cs_reloc)(struct radeon_winsys* winsys,
- struct pipe_buffer* bo,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags);
-
- /* Finish a command emit. */
- void (*end_cs)(struct radeon_winsys* winsys,
- const char* file,
- const char* function,
- int line);
-
- /* Flush the CS. */
- void (*flush_cs)(struct radeon_winsys* winsys);
-
- /* winsys flush - callback from winsys when flush required */
- void (*set_flush_cb)(struct radeon_winsys *winsys,
- void (*flush_cb)(void *), void *data);
-
- void (*reset_bos)(struct radeon_winsys *winsys);
-
- void (*buffer_set_tiling)(struct radeon_winsys* winsys,
- struct pipe_buffer* buffer,
- uint32_t pitch,
- boolean microtiled,
- boolean macrotiled);
-};
-
-#endif
diff --git a/src/gallium/winsys/drm/radeon/dri/SConscript b/src/gallium/winsys/drm/radeon/dri/SConscript
deleted file mode 100644
index c4989d1b595..00000000000
--- a/src/gallium/winsys/drm/radeon/dri/SConscript
+++ /dev/null
@@ -1,17 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
-
-drivers = [
- trace,
- softpipe,
- r300
-]
-
-env.SharedLibrary(
- target ='radeon_dri.so',
- source = COMMON_GALLIUM_SOURCES,
- LIBS = st_dri + radeonwinsys + mesa + drivers + gallium + env['LIBS'],
-)
diff --git a/src/gallium/winsys/drm/radeon/python/README b/src/gallium/winsys/drm/radeon/python/README
deleted file mode 100644
index 339836a592b..00000000000
--- a/src/gallium/winsys/drm/radeon/python/README
+++ /dev/null
@@ -1,15 +0,0 @@
-Python bindings for the radeon gallium driver.
-
-
-See gallium/src/gallium/state_trackers/python/README for more information.
-
-
-Build as:
-
- scons debug=1 statetrackers=python winsys=drm/radeon/python
-
-Run as:
-
- export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/winsys/drm/radeon/python:$PWD/build/linux-x86-debug/gallium/state_trackers/python
-
- python progs/gallium/python/samples/tri.py
diff --git a/src/gallium/winsys/drm/radeon/python/SConscript b/src/gallium/winsys/drm/radeon/python/SConscript
deleted file mode 100644
index 91cae986975..00000000000
--- a/src/gallium/winsys/drm/radeon/python/SConscript
+++ /dev/null
@@ -1,33 +0,0 @@
-import os.path
-
-Import('*')
-
-if env['platform'] == 'linux':
-
- env = env.Clone()
-
- env.Tool('python')
-
- env.ParseConfig('pkg-config --cflags --libs libdrm')
-
- env.Prepend(CPPPATH = [
- '#src/gallium/state_trackers/python',
- '../core',
- ])
-
- drivers = [
- softpipe,
- radeon,
- trace,
- ]
-
- sources = [
- 'radeon_hardpipe_winsys.c',
- 'xf86dri.c',
- ]
-
- env.SharedLibrary(
- target ='_gallium',
- source = sources,
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
- )
diff --git a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c b/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c
deleted file mode 100644
index fc63081a4cc..00000000000
--- a/src/gallium/winsys/drm/radeon/python/radeon_hardpipe_winsys.c
+++ /dev/null
@@ -1,132 +0,0 @@
- /**************************************************************************
- *
- * Copyright 2009 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <drm/drm.h>
-
-#include "pipe/p_screen.h"
-#include "pipe/p_context.h"
-
-#include "st_winsys.h"
-
-#include "radeon_winsys.h"
-
-#include "xf86dri.h"
-
-
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
-static struct pipe_screen *
-radeon_hardpipe_screen_create(void)
-{
- Display *dpy;
- Window rootWin;
- XWindowAttributes winAttr;
- int isCapable;
- int screen;
- char *driverName;
- char *curBusID;
- unsigned magic;
- int ddxDriverMajor;
- int ddxDriverMinor;
- int ddxDriverPatch;
- drm_handle_t sAreaOffset;
- int ret;
- int drmFD;
- drm_context_t hHWContext;
- XID id;
-
- dpy = XOpenDisplay(":0");
- if (!dpy) {
- fprintf(stderr, "Open Display Failed\n");
- return NULL;
- }
-
- screen = DefaultScreen(dpy);
- rootWin = RootWindow(dpy, screen);
- XGetWindowAttributes(dpy, rootWin, &winAttr);
-
- ret = uniDRIQueryDirectRenderingCapable(dpy, screen, &isCapable);
- if (!ret || !isCapable) {
- fprintf(stderr, "No DRI on this display:sceen\n");
- goto error;
- }
-
- if (!uniDRIOpenConnection(dpy, screen, &sAreaOffset,
- &curBusID)) {
- fprintf(stderr, "Could not open DRI connection.\n");
- goto error;
- }
-
- if (!uniDRIGetClientDriverName(dpy, screen, &ddxDriverMajor,
- &ddxDriverMinor, &ddxDriverPatch,
- &driverName)) {
- fprintf(stderr, "Could not get DRI driver name.\n");
- goto error;
- }
-
- if ((drmFD = drmOpen(NULL, curBusID)) < 0) {
- perror("DRM Device could not be opened");
- goto error;
- }
-
- drmGetMagic(drmFD, &magic);
- if (!uniDRIAuthConnection(dpy, screen, magic)) {
- fprintf(stderr, "Could not get X server to authenticate us.\n");
- goto error;
- }
-
- if (!uniDRICreateContext(dpy, screen, winAttr.visual,
- &id, &hHWContext)) {
- fprintf(stderr, "Could not create DRI context.\n");
- goto error;
- }
-
- /* FIXME: create a radeon pipe_screen from drmFD and hHWContext */
-
- return NULL;
-
-error:
- return NULL;
-}
-
-
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &radeon_hardpipe_screen_create,
-};
-
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.c b/src/gallium/winsys/drm/radeon/python/xf86dri.c
deleted file mode 100644
index 1736f1e54f8..00000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dri.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <[email protected]>
- * Jens Owen <[email protected]>
- * Rickard E. (Rik) Faith <[email protected]>
- *
- */
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#define NEED_REPLIES
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include "xf86dristr.h"
-
-static XExtensionInfo _xf86dri_info_data;
-static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
-static char xf86dri_extension_name[] = XF86DRINAME;
-
-#define uniDRICheckExtension(dpy,i,val) \
- XextCheckExtension (dpy, i, xf86dri_extension_name, val)
-
-/*****************************************************************************
- * *
- * private utility routines *
- * *
- *****************************************************************************/
-
-static int close_display(Display * dpy, XExtCodes * extCodes);
-static /* const */ XExtensionHooks xf86dri_extension_hooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- close_display, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- NULL, /* error_string */
-};
-
-static
-XEXT_GENERATE_FIND_DISPLAY(find_display, xf86dri_info,
- xf86dri_extension_name, &xf86dri_extension_hooks,
- 0, NULL)
-
- static XEXT_GENERATE_CLOSE_DISPLAY(close_display, xf86dri_info)
-
-/*****************************************************************************
- * *
- * public XFree86-DRI Extension routines *
- * *
- *****************************************************************************/
-#if 0
-#include <stdio.h>
-#define TRACE(msg) fprintf(stderr,"uniDRI%s\n", msg);
-#else
-#define TRACE(msg)
-#endif
- Bool uniDRIQueryExtension(dpy, event_basep, error_basep)
- Display *dpy;
- int *event_basep, *error_basep;
-{
- XExtDisplayInfo *info = find_display(dpy);
-
- TRACE("QueryExtension...");
- if (XextHasExtension(info)) {
- *event_basep = info->codes->first_event;
- *error_basep = info->codes->first_error;
- TRACE("QueryExtension... return True");
- return True;
- } else {
- TRACE("QueryExtension... return False");
- return False;
- }
-}
-
-Bool
-uniDRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
- Display *dpy;
- int *majorVersion;
- int *minorVersion;
- int *patchVersion;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIQueryVersionReply rep;
- xXF86DRIQueryVersionReq *req;
-
- TRACE("QueryVersion...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryVersion, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryVersion;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return False");
- return False;
- }
- *majorVersion = rep.majorVersion;
- *minorVersion = rep.minorVersion;
- *patchVersion = rep.patchVersion;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return True");
- return True;
-}
-
-Bool
-uniDRIQueryDirectRenderingCapable(dpy, screen, isCapable)
- Display *dpy;
- int screen;
- Bool *isCapable;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIQueryDirectRenderingCapableReply rep;
- xXF86DRIQueryDirectRenderingCapableReq *req;
-
- TRACE("QueryDirectRenderingCapable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryDirectRenderingCapable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return False");
- return False;
- }
- *isCapable = rep.isCapable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return True");
- return True;
-}
-
-Bool
-uniDRIOpenConnection(dpy, screen, hSAREA, busIdString)
- Display *dpy;
- int screen;
- drm_handle_t *hSAREA;
- char **busIdString;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIOpenConnectionReply rep;
- xXF86DRIOpenConnectionReq *req;
-
- TRACE("OpenConnection...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIOpenConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIOpenConnection;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
-
- *hSAREA = rep.hSAREALow;
-#ifdef LONG64
- if (sizeof(drm_handle_t) == 8) {
- *hSAREA |= ((unsigned long)rep.hSAREAHigh) << 32;
- }
-#endif
- if (rep.length) {
- if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
- _XEatData(dpy, ((rep.busIdStringLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
- _XReadPad(dpy, *busIdString, rep.busIdStringLength);
- } else {
- *busIdString = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return True");
- return True;
-}
-
-Bool
-uniDRIAuthConnection(dpy, screen, magic)
- Display *dpy;
- int screen;
- drm_magic_t magic;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIAuthConnectionReq *req;
- xXF86DRIAuthConnectionReply rep;
-
- TRACE("AuthConnection...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIAuthConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIAuthConnection;
- req->screen = screen;
- req->magic = magic;
- rep.authenticated = 0;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse) || !rep.authenticated) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return False");
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return True");
- return True;
-}
-
-Bool
-uniDRICloseConnection(dpy, screen)
- Display *dpy;
- int screen;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICloseConnectionReq *req;
-
- TRACE("CloseConnection...");
-
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICloseConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICloseConnection;
- req->screen = screen;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CloseConnection... return True");
- return True;
-}
-
-Bool
-uniDRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
- ddxDriverMinorVersion, ddxDriverPatchVersion,
- clientDriverName)
- Display *dpy;
- int screen;
- int *ddxDriverMajorVersion;
- int *ddxDriverMinorVersion;
- int *ddxDriverPatchVersion;
- char **clientDriverName;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetClientDriverNameReply rep;
- xXF86DRIGetClientDriverNameReq *req;
-
- TRACE("GetClientDriverName...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetClientDriverName, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetClientDriverName;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
-
- *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
- *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
- *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
-
- if (rep.length) {
- if (!(*clientDriverName =
- (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
- _XEatData(dpy, ((rep.clientDriverNameLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
- _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
- } else {
- *clientDriverName = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return True");
- return True;
-}
-
-Bool
-uniDRICreateContextWithConfig(dpy, screen, configID, context, hHWContext)
- Display *dpy;
- int screen;
- int configID;
- XID *context;
- drm_context_t *hHWContext;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICreateContextReply rep;
- xXF86DRICreateContextReq *req;
-
- TRACE("CreateContext...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateContext;
- req->visual = configID;
- req->screen = screen;
- *context = XAllocID(dpy);
- req->context = *context;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return False");
- return False;
- }
- *hHWContext = rep.hHWContext;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return True");
- return True;
-}
-
-Bool
-uniDRICreateContext(dpy, screen, visual, context, hHWContext)
- Display *dpy;
- int screen;
- Visual *visual;
- XID *context;
- drm_context_t *hHWContext;
-{
- return uniDRICreateContextWithConfig(dpy, screen, visual->visualid,
- context, hHWContext);
-}
-
-Bool
-uniDRIDestroyContext(Display * ndpy, int screen, XID context)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIDestroyContextReq *req;
-
- TRACE("DestroyContext...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyContext;
- req->screen = screen;
- req->context = context;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyContext... return True");
- return True;
-}
-
-Bool
-uniDRICreateDrawable(Display * ndpy, int screen,
- Drawable drawable, drm_drawable_t * hHWDrawable)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRICreateDrawableReply rep;
- xXF86DRICreateDrawableReq *req;
-
- TRACE("CreateDrawable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateDrawable;
- req->screen = screen;
- req->drawable = drawable;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return False");
- return False;
- }
- *hHWDrawable = rep.hHWDrawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return True");
- return True;
-}
-
-Bool
-uniDRIDestroyDrawable(Display * ndpy, int screen, Drawable drawable)
-{
- Display *const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIDestroyDrawableReq *req;
-
- TRACE("DestroyDrawable...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyDrawable;
- req->screen = screen;
- req->drawable = drawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyDrawable... return True");
- return True;
-}
-
-Bool
-uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects,
- drm_clip_rect_t ** pBackClipRects)
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetDrawableInfoReply rep;
- xXF86DRIGetDrawableInfoReq *req;
- int total_rects;
-
- TRACE("GetDrawableInfo...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDrawableInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDrawableInfo;
- req->screen = screen;
- req->drawable = drawable;
-
- if (!_XReply(dpy, (xReply *) & rep, 1, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
- *index = rep.drawableTableIndex;
- *stamp = rep.drawableTableStamp;
- *X = (int)rep.drawableX;
- *Y = (int)rep.drawableY;
- *W = (int)rep.drawableWidth;
- *H = (int)rep.drawableHeight;
- *numClipRects = rep.numClipRects;
- total_rects = *numClipRects;
-
- *backX = rep.backX;
- *backY = rep.backY;
- *numBackClipRects = rep.numBackClipRects;
- total_rects += *numBackClipRects;
-
-#if 0
- /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
- * backwards compatibility (Because of the >> 2 shift) but the fix
- * enables multi-threaded apps to work.
- */
- if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply) +
- total_rects * sizeof(drm_clip_rect_t)) +
- 3) & ~3) >> 2)) {
- _XEatData(dpy, rep.length);
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
-#endif
-
- if (*numClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numClipRects);
-
- *pClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
- if (*pClipRects)
- _XRead(dpy, (char *)*pClipRects, len);
- } else {
- *pClipRects = NULL;
- }
-
- if (*numBackClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
-
- *pBackClipRects = (drm_clip_rect_t *) Xcalloc(len, 1);
- if (*pBackClipRects)
- _XRead(dpy, (char *)*pBackClipRects, len);
- } else {
- *pBackClipRects = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return True");
- return True;
-}
-
-Bool
-uniDRIGetDeviceInfo(dpy, screen, hFrameBuffer,
- fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
- Display *dpy;
- int screen;
- drm_handle_t *hFrameBuffer;
- int *fbOrigin;
- int *fbSize;
- int *fbStride;
- int *devPrivateSize;
- void **pDevPrivate;
-{
- XExtDisplayInfo *info = find_display(dpy);
- xXF86DRIGetDeviceInfoReply rep;
- xXF86DRIGetDeviceInfoReq *req;
-
- TRACE("GetDeviceInfo...");
- uniDRICheckExtension(dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDeviceInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDeviceInfo;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
-
- *hFrameBuffer = rep.hFrameBufferLow;
-#ifdef LONG64
- if (sizeof(drm_handle_t) == 8) {
- *hFrameBuffer |= ((unsigned long)rep.hFrameBufferHigh) << 32;
- }
-#endif
-
- *fbOrigin = rep.framebufferOrigin;
- *fbSize = rep.framebufferSize;
- *fbStride = rep.framebufferStride;
- *devPrivateSize = rep.devPrivateSize;
-
- if (rep.length) {
- if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
- _XEatData(dpy, ((rep.devPrivateSize + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
- _XRead(dpy, (char *)*pDevPrivate, rep.devPrivateSize);
- } else {
- *pDevPrivate = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return True");
- return True;
-}
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dri.h b/src/gallium/winsys/drm/radeon/python/xf86dri.h
deleted file mode 100644
index bf6de37d9dd..00000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dri.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/**
- * \file xf86dri.h
- * Protocol numbers and function prototypes for DRI X protocol.
- *
- * \author Kevin E. Martin <[email protected]>
- * \author Jens Owen <[email protected]>
- * \author Rickard E. (Rik) Faith <[email protected]>
- */
-
-#ifndef _XF86DRI_H_
-#define _XF86DRI_H_
-
-#include <stdint.h>
-#include <X11/Xfuncproto.h>
-#include <drm/drm.h>
-
-#define X_XF86DRIQueryVersion 0
-#define X_XF86DRIQueryDirectRenderingCapable 1
-#define X_XF86DRIOpenConnection 2
-#define X_XF86DRICloseConnection 3
-#define X_XF86DRIGetClientDriverName 4
-#define X_XF86DRICreateContext 5
-#define X_XF86DRIDestroyContext 6
-#define X_XF86DRICreateDrawable 7
-#define X_XF86DRIDestroyDrawable 8
-#define X_XF86DRIGetDrawableInfo 9
-#define X_XF86DRIGetDeviceInfo 10
-#define X_XF86DRIAuthConnection 11
-#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
-#define X_XF86DRICloseFullScreen 13 /* Deprecated */
-
-#define XF86DRINumberEvents 0
-
-#define XF86DRIClientNotLocal 0
-#define XF86DRIOperationNotSupported 1
-#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
-
-#ifndef _XF86DRI_SERVER_
-
-_XFUNCPROTOBEGIN
- Bool uniDRIQueryExtension(Display * dpy, int *event_base,
- int *error_base);
-
-Bool uniDRIQueryVersion(Display * dpy, int *majorVersion, int *minorVersion,
- int *patchVersion);
-
-Bool uniDRIQueryDirectRenderingCapable(Display * dpy, int screen,
- Bool * isCapable);
-
-Bool uniDRIOpenConnection(Display * dpy, int screen, drm_handle_t * hSAREA,
- char **busIDString);
-
-Bool uniDRIAuthConnection(Display * dpy, int screen, drm_magic_t magic);
-
-Bool uniDRICloseConnection(Display * dpy, int screen);
-
-Bool uniDRIGetClientDriverName(Display * dpy, int screen,
- int *ddxDriverMajorVersion,
- int *ddxDriverMinorVersion,
- int *ddxDriverPatchVersion,
- char **clientDriverName);
-
-Bool uniDRICreateContext(Display * dpy, int screen, Visual * visual,
- XID * ptr_to_returned_context_id,
- drm_context_t * hHWContext);
-
-Bool uniDRICreateContextWithConfig(Display * dpy, int screen, int configID,
- XID * ptr_to_returned_context_id,
- drm_context_t * hHWContext);
-
-extern Bool uniDRIDestroyContext(Display * dpy, int screen, XID context_id);
-
-extern Bool uniDRICreateDrawable(Display * dpy, int screen,
- Drawable drawable,
- drm_drawable_t * hHWDrawable);
-
-extern Bool uniDRIDestroyDrawable(Display * dpy, int screen,
- Drawable drawable);
-
-Bool uniDRIGetDrawableInfo(Display * dpy, int screen, Drawable drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects,
- drm_clip_rect_t ** pBackClipRects);
-
-Bool uniDRIGetDeviceInfo(Display * dpy, int screen,
- drm_handle_t * hFrameBuffer, int *fbOrigin,
- int *fbSize, int *fbStride, int *devPrivateSize,
- void **pDevPrivate);
-
-_XFUNCPROTOEND
-#endif /* _XF86DRI_SERVER_ */
-#endif /* _XF86DRI_H_ */
diff --git a/src/gallium/winsys/drm/radeon/python/xf86dristr.h b/src/gallium/winsys/drm/radeon/python/xf86dristr.h
deleted file mode 100644
index d8989963609..00000000000
--- a/src/gallium/winsys/drm/radeon/python/xf86dristr.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <[email protected]>
- * Jens Owen <[email protected]>
- * Rickard E. (Rik) Fiath <[email protected]>
- *
- */
-
-#ifndef _XF86DRISTR_H_
-#define _XF86DRISTR_H_
-
-#include "xf86dri.h"
-
-#define XF86DRINAME "XFree86-DRI"
-
-/* The DRI version number. This was originally set to be the same of the
- * XFree86 version number. However, this version is really indepedent of
- * the XFree86 version.
- *
- * Version History:
- * 4.0.0: Original
- * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
- * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
- */
-#define XF86DRI_MAJOR_VERSION 4
-#define XF86DRI_MINOR_VERSION 1
-#define XF86DRI_PATCH_VERSION 0
-
-typedef struct _XF86DRIQueryVersion
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIQueryVersion */
- CARD16 length B16;
-} xXF86DRIQueryVersionReq;
-
-#define sz_xXF86DRIQueryVersionReq 4
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD16 majorVersion B16; /* major version of DRI protocol */
- CARD16 minorVersion B16; /* minor version of DRI protocol */
- CARD32 patchVersion B32; /* patch version of DRI protocol */
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIQueryVersionReply;
-
-#define sz_xXF86DRIQueryVersionReply 32
-
-typedef struct _XF86DRIQueryDirectRenderingCapable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIQueryDirectRenderingCapableReq;
-
-#define sz_xXF86DRIQueryDirectRenderingCapableReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- BOOL isCapable;
- BOOL pad2;
- BOOL pad3;
- BOOL pad4;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
- CARD32 pad9 B32;
-} xXF86DRIQueryDirectRenderingCapableReply;
-
-#define sz_xXF86DRIQueryDirectRenderingCapableReply 32
-
-typedef struct _XF86DRIOpenConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIOpenConnectionReq;
-
-#define sz_xXF86DRIOpenConnectionReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hSAREALow B32;
- CARD32 hSAREAHigh B32;
- CARD32 busIdStringLength B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
-} xXF86DRIOpenConnectionReply;
-
-#define sz_xXF86DRIOpenConnectionReply 32
-
-typedef struct _XF86DRIAuthConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 magic B32;
-} xXF86DRIAuthConnectionReq;
-
-#define sz_xXF86DRIAuthConnectionReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 authenticated B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIAuthConnectionReply;
-
-#define zx_xXF86DRIAuthConnectionReply 32
-
-typedef struct _XF86DRICloseConnection
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRICloseConnectionReq;
-
-#define sz_xXF86DRICloseConnectionReq 8
-
-typedef struct _XF86DRIGetClientDriverName
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetClientDriverName */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetClientDriverNameReq;
-
-#define sz_xXF86DRIGetClientDriverNameReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 ddxDriverMajorVersion B32;
- CARD32 ddxDriverMinorVersion B32;
- CARD32 ddxDriverPatchVersion B32;
- CARD32 clientDriverNameLength B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIGetClientDriverNameReply;
-
-#define sz_xXF86DRIGetClientDriverNameReply 32
-
-typedef struct _XF86DRICreateContext
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 visual B32;
- CARD32 context B32;
-} xXF86DRICreateContextReq;
-
-#define sz_xXF86DRICreateContextReq 16
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWContext B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateContextReply;
-
-#define sz_xXF86DRICreateContextReply 32
-
-typedef struct _XF86DRIDestroyContext
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 context B32;
-} xXF86DRIDestroyContextReq;
-
-#define sz_xXF86DRIDestroyContextReq 12
-
-typedef struct _XF86DRICreateDrawable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICreateDrawableReq;
-
-#define sz_xXF86DRICreateDrawableReq 12
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWDrawable B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateDrawableReply;
-
-#define sz_xXF86DRICreateDrawableReply 32
-
-typedef struct _XF86DRIDestroyDrawable
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIDestroyDrawableReq;
-
-#define sz_xXF86DRIDestroyDrawableReq 12
-
-typedef struct _XF86DRIGetDrawableInfo
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDrawableInfo */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIGetDrawableInfoReq;
-
-#define sz_xXF86DRIGetDrawableInfoReq 12
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 drawableTableIndex B32;
- CARD32 drawableTableStamp B32;
- INT16 drawableX B16;
- INT16 drawableY B16;
- INT16 drawableWidth B16;
- INT16 drawableHeight B16;
- CARD32 numClipRects B32;
- INT16 backX B16;
- INT16 backY B16;
- CARD32 numBackClipRects B32;
-} xXF86DRIGetDrawableInfoReply;
-
-#define sz_xXF86DRIGetDrawableInfoReply 36
-
-typedef struct _XF86DRIGetDeviceInfo
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDeviceInfo */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetDeviceInfoReq;
-
-#define sz_xXF86DRIGetDeviceInfoReq 8
-
-typedef struct
-{
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hFrameBufferLow B32;
- CARD32 hFrameBufferHigh B32;
- CARD32 framebufferOrigin B32;
- CARD32 framebufferSize B32;
- CARD32 framebufferStride B32;
- CARD32 devPrivateSize B32;
-} xXF86DRIGetDeviceInfoReply;
-
-#define sz_xXF86DRIGetDeviceInfoReply 32
-
-typedef struct _XF86DRIOpenFullScreen
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIOpenFullScreenReq;
-
-#define sz_xXF86DRIOpenFullScreenReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 isFullScreen B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIOpenFullScreenReply;
-
-#define sz_xXF86DRIOpenFullScreenReply 32
-
-typedef struct _XF86DRICloseFullScreen
-{
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICloseFullScreenReq;
-
-#define sz_xXF86DRICloseFullScreenReq 12
-
-typedef struct
-{
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
-} xXF86DRICloseFullScreenReply;
-
-#define sz_xXF86DRICloseFullScreenReply 32
-
-#endif /* _XF86DRISTR_H_ */
diff --git a/src/gallium/winsys/drm/swrast/Makefile b/src/gallium/winsys/drm/swrast/Makefile
deleted file mode 100644
index 363b89584f2..00000000000
--- a/src/gallium/winsys/drm/swrast/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/swrast/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/swrast/core/Makefile b/src/gallium/winsys/drm/swrast/core/Makefile
deleted file mode 100644
index 93931ae22b9..00000000000
--- a/src/gallium/winsys/drm/swrast/core/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# src/gallium/winsys/drm/swrast/core/Makefile
-
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = swrastdrm
-
-C_SOURCES = swrast_drm_api.c
-
-include ../../../../Makefile.template
diff --git a/src/gallium/winsys/drm/swrast/egl/Makefile b/src/gallium/winsys/drm/swrast/egl/Makefile
deleted file mode 100644
index 26fe2d2805a..00000000000
--- a/src/gallium/winsys/drm/swrast/egl/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = swrast
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS =
-
-EGL_DRIVER_PIPES = \
- $(TOP)/src/gallium/winsys/drm/swrast/core/libswrastdrm.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-
-include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/vmware/Makefile b/src/gallium/winsys/drm/vmware/Makefile
deleted file mode 100644
index 2ae6dead5c1..00000000000
--- a/src/gallium/winsys/drm/vmware/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# src/gallium/winsys/drm/vmware/Makefile
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-SUBDIRS = core $(GALLIUM_STATE_TRACKERS_DIRS)
-
-default install clean:
- @for dir in $(SUBDIRS) ; do \
- if [ -d $$dir ] ; then \
- (cd $$dir && $(MAKE) $@) || exit 1; \
- fi \
- done
diff --git a/src/gallium/winsys/drm/vmware/SConscript b/src/gallium/winsys/drm/vmware/SConscript
deleted file mode 100644
index 06e6d5be9ca..00000000000
--- a/src/gallium/winsys/drm/vmware/SConscript
+++ /dev/null
@@ -1,11 +0,0 @@
-Import('*')
-
-SConscript(['core/SConscript',])
-
-if 'mesa' in env['statetrackers']:
-
- SConscript(['dri/SConscript'])
-
-if 'xorg' in env['statetrackers']:
-
- SConscript(['xorg/SConscript'])
diff --git a/src/gallium/winsys/drm/vmware/dri/SConscript b/src/gallium/winsys/drm/vmware/dri/SConscript
deleted file mode 100644
index d26d0cd7483..00000000000
--- a/src/gallium/winsys/drm/vmware/dri/SConscript
+++ /dev/null
@@ -1,63 +0,0 @@
-import os
-import os.path
-
-Import('*')
-
-if env['platform'] == 'linux':
-
- if env['dri']:
- env = env.Clone()
-
- sources = [
- '#/src/mesa/drivers/dri/common/utils.c',
- '#/src/mesa/drivers/dri/common/vblank.c',
- '#/src/mesa/drivers/dri/common/dri_util.c',
- '#/src/mesa/drivers/dri/common/xmlconfig.c',
- ]
-
-
- env.ParseConfig('pkg-config --cflags --libs libdrm')
-
- env.Prepend(CPPPATH = [
- '#/src/mesa/state_tracker',
- '#/src/mesa/drivers/dri/common',
- '#/src/mesa/main',
- '#/src/mesa/glapi',
- '#/src/mesa',
- '#/include',
- '#/src/gallium/drivers/svga',
- '#/src/gallium/drivers/svga/include',
- ])
-
- env.Append(CPPDEFINES = [
- 'HAVE_STDINT_H',
- 'HAVE_SYS_TYPES_H',
- ])
-
- env.Append(CFLAGS = [
- '-std=gnu99',
- '-D_FILE_OFFSET_BITS=64',
- ])
-
- env.Prepend(LIBPATH = [
- ])
-
- env.Prepend(LIBS = [
- trace,
- st_dri,
- svgadrm,
- svga,
- mesa,
- glsl,
- gallium,
- ])
-
- # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
- env.LoadableModule(
- target ='vmwgfx_dri.so',
- source = sources,
- LIBS = env['LIBS'],
- SHLIBPREFIX = '',
- )
-
-
diff --git a/src/gallium/winsys/drm/vmware/egl/dummy.c b/src/gallium/winsys/drm/vmware/egl/dummy.c
deleted file mode 100644
index 3181d0ba7e8..00000000000
--- a/src/gallium/winsys/drm/vmware/egl/dummy.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
deleted file mode 100644
index 71360e55aac..00000000000
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-
-#include <windows.h>
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
-#include "stw_winsys.h"
-
-
-struct gdi_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct gdi_softpipe_buffer *
-gdi_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct gdi_softpipe_buffer *)buf;
-}
-
-
-static void *
-gdi_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
- gdi_softpipe_buf->mapped = gdi_softpipe_buf->data;
- return gdi_softpipe_buf->mapped;
-}
-
-
-static void
-gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
- gdi_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-gdi_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static const char *
-gdi_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct gdi_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surface,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-gdi_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-gdi_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-gdi_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-gdi_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-gdi_softpipe_screen_create(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = gdi_softpipe_destroy;
-
- winsys->buffer_create = gdi_softpipe_buffer_create;
- winsys->user_buffer_create = gdi_softpipe_user_buffer_create;
- winsys->buffer_map = gdi_softpipe_buffer_map;
- winsys->buffer_unmap = gdi_softpipe_buffer_unmap;
- winsys->buffer_destroy = gdi_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create;
-
- winsys->fence_reference = gdi_softpipe_fence_reference;
- winsys->fence_signalled = gdi_softpipe_fence_signalled;
- winsys->fence_finish = gdi_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer;
- winsys->get_name = gdi_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- gdi_softpipe_destroy(winsys);
-
- return screen;
-}
-
-
-static void
-gdi_softpipe_present(struct pipe_screen *screen,
- struct pipe_surface *surface,
- HDC hDC)
-{
- struct softpipe_texture *texture;
- struct gdi_softpipe_buffer *buffer;
- BITMAPINFO bmi;
-
- texture = softpipe_texture(surface->texture);
-
- buffer = gdi_softpipe_buffer(texture->buffer);
-
- memset(&bmi, 0, sizeof(BITMAPINFO));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = texture->stride[surface->level] / util_format_get_blocksize(surface->format);
- bmi.bmiHeader.biHeight= -(long)surface->height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = util_format_get_blocksizebits(surface->format);
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = 0;
- bmi.bmiHeader.biXPelsPerMeter = 0;
- bmi.bmiHeader.biYPelsPerMeter = 0;
- bmi.bmiHeader.biClrUsed = 0;
- bmi.bmiHeader.biClrImportant = 0;
-
- StretchDIBits(hDC,
- 0, 0, surface->width, surface->height,
- 0, 0, surface->width, surface->height,
- buffer->data, &bmi, 0, SRCCOPY);
-}
-
-
-static const struct stw_winsys stw_winsys = {
- &gdi_softpipe_screen_create,
- &gdi_softpipe_present,
- NULL, /* get_adapter_luid */
- NULL, /* shared_surface_open */
- NULL, /* shared_surface_close */
- NULL /* compose */
-};
-
-
-BOOL WINAPI
-DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
-{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- stw_init(&stw_winsys);
- stw_init_thread();
- break;
-
- case DLL_THREAD_ATTACH:
- stw_init_thread();
- break;
-
- case DLL_THREAD_DETACH:
- stw_cleanup_thread();
- break;
-
- case DLL_PROCESS_DETACH:
- stw_cleanup_thread();
- stw_cleanup();
- break;
- }
- return TRUE;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/i915/drm/Makefile
index 0d6d4e37dbd..a67b9e8a528 100644
--- a/src/gallium/winsys/drm/intel/gem/Makefile
+++ b/src/gallium/winsys/i915/drm/Makefile
@@ -1,16 +1,16 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
-LIBNAME = inteldrm
+LIBNAME = i915drm
C_SOURCES = \
- intel_drm_batchbuffer.c \
- intel_drm_buffer.c \
- intel_drm_fence.c \
- intel_drm_api.c
+ i915_drm_batchbuffer.c \
+ i915_drm_buffer.c \
+ i915_drm_fence.c \
+ i915_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i915/drm/SConscript b/src/gallium/winsys/i915/drm/SConscript
new file mode 100644
index 00000000000..ba29ac72fe7
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+i915drm_sources = [
+ 'i915_drm_api.c',
+ 'i915_drm_batchbuffer.c',
+ 'i915_drm_buffer.c',
+ 'i915_drm_fence.c',
+]
+
+i915drm = env.ConvenienceLibrary(
+ target ='i915drm',
+ source = i915drm_sources,
+)
+
+Export('i915drm')
diff --git a/src/gallium/winsys/i915/drm/i915_drm_api.c b/src/gallium/winsys/i915/drm/i915_drm_api.c
new file mode 100644
index 00000000000..6bb0aec1a67
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_api.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+
+#include "state_tracker/drm_api.h"
+
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915/i915_context.h"
+#include "i915/i915_screen.h"
+
+#include "trace/tr_drm.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i915_drm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ (void) shutup_gcc;
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static void
+i915_drm_winsys_destroy(struct i915_winsys *iws)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+
+ drm_intel_bufmgr_destroy(idws->pools.gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+i915_drm_create_screen(struct drm_api *api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct i915_drm_winsys *idws;
+ unsigned int deviceID;
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ idws = CALLOC_STRUCT(i915_drm_winsys);
+ if (!idws)
+ return NULL;
+
+ i915_drm_get_device_id(&deviceID);
+
+ i915_drm_winsys_init_batchbuffer_functions(idws);
+ i915_drm_winsys_init_buffer_functions(idws);
+ i915_drm_winsys_init_fence_functions(idws);
+
+ idws->fd = drmFD;
+ idws->id = deviceID;
+ idws->max_batch_size = 16 * 4096;
+
+ idws->base.destroy = i915_drm_winsys_destroy;
+
+ idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
+ drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem);
+
+ idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+ return i915_create_screen(&idws->base, deviceID);
+}
+
+static void
+destroy(struct drm_api *api)
+{
+
+}
+
+struct drm_api intel_drm_api =
+{
+ .name = "i915",
+ .driver_name = "i915",
+ .create_screen = i915_drm_create_screen,
+ .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return trace_drm_create(&intel_drm_api);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
index 5b4dafc8e41..102f59dc541 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
@@ -1,5 +1,5 @@
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "i915_drm.h"
@@ -17,25 +17,25 @@
#undef INTEL_MAP_GTT
#define INTEL_ALWAYS_FLUSH
-struct intel_drm_batchbuffer
+struct i915_drm_batchbuffer
{
- struct intel_batchbuffer base;
+ struct i915_winsys_batchbuffer base;
size_t actual_size;
drm_intel_bo *bo;
};
-static INLINE struct intel_drm_batchbuffer *
-intel_drm_batchbuffer(struct intel_batchbuffer *batch)
+static INLINE struct i915_drm_batchbuffer *
+i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
{
- return (struct intel_drm_batchbuffer *)batch;
+ return (struct i915_drm_batchbuffer *)batch;
}
static void
-intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
+i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws);
+ struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
int ret;
if (batch->bo)
@@ -63,11 +63,11 @@ intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
batch->base.relocs = 0;
}
-static struct intel_batchbuffer *
-intel_drm_batchbuffer_create(struct intel_winsys *iws)
+static struct i915_winsys_batchbuffer *
+i915_drm_batchbuffer_create(struct i915_winsys *iws)
{
- struct intel_drm_winsys *idws = intel_drm_winsys(iws);
- struct intel_drm_batchbuffer *batch = CALLOC_STRUCT(intel_drm_batchbuffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
batch->actual_size = idws->max_batch_size;
@@ -84,18 +84,18 @@ intel_drm_batchbuffer_create(struct intel_winsys *iws)
batch->base.iws = iws;
- intel_drm_batchbuffer_reset(batch);
+ i915_drm_batchbuffer_reset(batch);
return &batch->base;
}
static int
-intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
- struct intel_buffer *buffer,
- enum intel_buffer_usage usage,
+i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
unsigned pre_add)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
unsigned write_domain = 0;
unsigned read_domain = 0;
unsigned offset;
@@ -103,23 +103,23 @@ intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
assert(batch->base.relocs < batch->base.max_relocs);
- if (usage == INTEL_USAGE_SAMPLER) {
+ if (usage == I915_USAGE_SAMPLER) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_SAMPLER;
- } else if (usage == INTEL_USAGE_RENDER) {
+ } else if (usage == I915_USAGE_RENDER) {
write_domain = I915_GEM_DOMAIN_RENDER;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_2D_TARGET) {
+ } else if (usage == I915_USAGE_2D_TARGET) {
write_domain = I915_GEM_DOMAIN_RENDER;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_2D_SOURCE) {
+ } else if (usage == I915_USAGE_2D_SOURCE) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_RENDER;
- } else if (usage == INTEL_USAGE_VERTEX) {
+ } else if (usage == I915_USAGE_VERTEX) {
write_domain = 0;
read_domain = I915_GEM_DOMAIN_VERTEX;
@@ -145,15 +145,15 @@ intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
}
static void
-intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
+i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
struct pipe_fence_handle **fence)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
unsigned used = 0;
int ret = 0;
int i;
- assert(intel_batchbuffer_space(ibatch) >= 0);
+ assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
used = batch->base.ptr - batch->base.map;
assert((used & 3) == 0);
@@ -161,16 +161,16 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
#ifdef INTEL_ALWAYS_FLUSH
/* MI_FLUSH | FLUSH_MAP_CACHE */
- intel_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
+ i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
used += 4;
#endif
if ((used & 4) == 0) {
/* MI_NOOP */
- intel_batchbuffer_dword(ibatch, 0);
+ i915_winsys_batchbuffer_dword(ibatch, 0);
}
/* MI_BATCH_BUFFER_END */
- intel_batchbuffer_dword(ibatch, (0xA<<23));
+ i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
used = batch->base.ptr - batch->base.map;
assert((used & 4) == 0);
@@ -189,7 +189,7 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
assert(ret == 0);
- if (intel_drm_winsys(ibatch->iws)->dump_cmd) {
+ if (i915_drm_winsys(ibatch->iws)->dump_cmd) {
unsigned *ptr;
drm_intel_bo_map(batch->bo, FALSE);
ptr = (unsigned*)batch->bo->virtual;
@@ -212,19 +212,19 @@ intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
#ifdef INTEL_RUN_SYNC
/* we run synced to GPU so just pass null */
- (*fence) = intel_drm_fence_create(NULL);
+ (*fence) = i915_drm_fence_create(NULL);
#else
- (*fence) = intel_drm_fence_create(batch->bo);
+ (*fence) = i915_drm_fence_create(batch->bo);
#endif
}
- intel_drm_batchbuffer_reset(batch);
+ i915_drm_batchbuffer_reset(batch);
}
static void
-intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
+i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
{
- struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
@@ -235,10 +235,10 @@ intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
FREE(batch);
}
-void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws)
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
{
- idws->base.batchbuffer_create = intel_drm_batchbuffer_create;
- idws->base.batchbuffer_reloc = intel_drm_batchbuffer_reloc;
- idws->base.batchbuffer_flush = intel_drm_batchbuffer_flush;
- idws->base.batchbuffer_destroy = intel_drm_batchbuffer_destroy;
+ idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
+ idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
+ idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
+ idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
new file mode 100644
index 00000000000..3bd85026b21
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -0,0 +1,217 @@
+
+#include "state_tracker/drm_api.h"
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_create(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type)
+{
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ drm_intel_bufmgr *pool;
+ char *name;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->flinked = FALSE;
+ buf->flink = 0;
+ buf->map_gtt = FALSE;
+
+ if (type == I915_NEW_TEXTURE) {
+ name = "gallium3d_texture";
+ pool = idws->pools.gem;
+ } else if (type == I915_NEW_VERTEX) {
+ name = "gallium3d_vertex";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else if (type == I915_NEW_SCANOUT) {
+ name = "gallium3d_scanout";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else {
+ assert(0);
+ name = "gallium3d_unknown";
+ pool = idws->pools.gem;
+ }
+
+ buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+ if (!buf->bo)
+ goto err;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ assert(0);
+ FREE(buf);
+ return NULL;
+}
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_from_handle(struct i915_winsys *iws,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+ uint32_t tile = 0, swizzle = 0;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, "gallium3d_from_handle", whandle->handle);
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
+ if (tile != I915_TILE_NONE)
+ buf->map_gtt = TRUE;
+
+ *stride = whandle->stride;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+static boolean
+i915_drm_buffer_get_handle(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return FALSE;
+ }
+
+ whandle->stride = stride;
+ return TRUE;
+}
+
+static int
+i915_drm_buffer_set_fence_reg(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ unsigned stride,
+ enum i915_winsys_buffer_tile tile)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+ assert(I915_TILING_NONE == I915_TILE_NONE);
+ assert(I915_TILING_X == I915_TILE_X);
+ assert(I915_TILING_Y == I915_TILE_Y);
+
+ if (tile != I915_TILE_NONE) {
+ assert(buf->map_count == 0);
+ buf->map_gtt = TRUE;
+ }
+
+ return drm_intel_bo_set_tiling(buf->bo, &tile, stride);
+}
+
+static void *
+i915_drm_buffer_map(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ boolean write)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+ drm_intel_bo *bo = intel_bo(buffer);
+ int ret = 0;
+
+ assert(bo);
+
+ if (buf->map_count)
+ goto out;
+
+ if (buf->map_gtt)
+ ret = drm_intel_gem_bo_map_gtt(bo);
+ else
+ ret = drm_intel_bo_map(bo, write);
+
+ buf->ptr = bo->virtual;
+
+ assert(ret == 0);
+out:
+ if (ret)
+ return NULL;
+
+ buf->map_count++;
+ return buf->ptr;
+}
+
+static void
+i915_drm_buffer_unmap(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ if (--buf->map_count)
+ return;
+
+ if (buf->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
+ else
+ drm_intel_bo_unmap(intel_bo(buffer));
+}
+
+static int
+i915_drm_buffer_write(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ size_t offset,
+ size_t size,
+ const void *data)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+}
+
+static void
+i915_drm_buffer_destroy(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ drm_intel_bo_unreference(intel_bo(buffer));
+
+#ifdef DEBUG
+ i915_drm_buffer(buffer)->magic = 0;
+ i915_drm_buffer(buffer)->bo = NULL;
+#endif
+
+ FREE(buffer);
+}
+
+void
+i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
+{
+ idws->base.buffer_create = i915_drm_buffer_create;
+ idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
+ idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
+ idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg;
+ idws->base.buffer_map = i915_drm_buffer_map;
+ idws->base.buffer_unmap = i915_drm_buffer_unmap;
+ idws->base.buffer_write = i915_drm_buffer_write;
+ idws->base.buffer_destroy = i915_drm_buffer_destroy;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/i915/drm/i915_drm_fence.c
index 102faedfeae..30ebf4835ea 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_fence.c
@@ -1,5 +1,5 @@
-#include "intel_drm_winsys.h"
+#include "i915_drm_winsys.h"
#include "util/u_memory.h"
#include "util/u_atomic.h"
#include "util/u_inlines.h"
@@ -10,7 +10,7 @@
* They work by keeping the batchbuffer around and checking if that has
* been idled. If bo is NULL fence has expired.
*/
-struct intel_drm_fence
+struct i915_drm_fence
{
struct pipe_reference reference;
drm_intel_bo *bo;
@@ -18,9 +18,9 @@ struct intel_drm_fence
struct pipe_fence_handle *
-intel_drm_fence_create(drm_intel_bo *bo)
+i915_drm_fence_create(drm_intel_bo *bo)
{
- struct intel_drm_fence *fence = CALLOC_STRUCT(intel_drm_fence);
+ struct i915_drm_fence *fence = CALLOC_STRUCT(i915_drm_fence);
pipe_reference_init(&fence->reference, 1);
/* bo is null if fence already expired */
@@ -33,14 +33,14 @@ intel_drm_fence_create(drm_intel_bo *bo)
}
static void
-intel_drm_fence_reference(struct intel_winsys *iws,
+i915_drm_fence_reference(struct i915_winsys *iws,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
- struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr;
- struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+ struct i915_drm_fence *old = (struct i915_drm_fence *)*ptr;
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
- if (pipe_reference(&((struct intel_drm_fence *)(*ptr))->reference, &f->reference)) {
+ if (pipe_reference(&((struct i915_drm_fence *)(*ptr))->reference, &f->reference)) {
if (old->bo)
drm_intel_bo_unreference(old->bo);
FREE(old);
@@ -49,7 +49,7 @@ intel_drm_fence_reference(struct intel_winsys *iws,
}
static int
-intel_drm_fence_signalled(struct intel_winsys *iws,
+i915_drm_fence_signalled(struct i915_winsys *iws,
struct pipe_fence_handle *fence)
{
assert(0);
@@ -58,10 +58,10 @@ intel_drm_fence_signalled(struct intel_winsys *iws,
}
static int
-intel_drm_fence_finish(struct intel_winsys *iws,
+i915_drm_fence_finish(struct i915_winsys *iws,
struct pipe_fence_handle *fence)
{
- struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
/* fence already expired */
if (!f->bo)
@@ -75,9 +75,9 @@ intel_drm_fence_finish(struct intel_winsys *iws,
}
void
-intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws)
+i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws)
{
- idws->base.fence_reference = intel_drm_fence_reference;
- idws->base.fence_signalled = intel_drm_fence_signalled;
- idws->base.fence_finish = intel_drm_fence_finish;
+ idws->base.fence_reference = i915_drm_fence_reference;
+ idws->base.fence_signalled = i915_drm_fence_signalled;
+ idws->base.fence_finish = i915_drm_fence_finish;
}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
new file mode 100644
index 00000000000..217c4a7eafb
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
@@ -0,0 +1,77 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i915/i915_batchbuffer.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct i915_drm_winsys
+{
+ struct i915_winsys base;
+
+ boolean dump_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ unsigned id;
+
+ size_t max_batch_size;
+
+ struct {
+ drm_intel_bufmgr *gem;
+ } pools;
+};
+
+static INLINE struct i915_drm_winsys *
+i915_drm_winsys(struct i915_winsys *iws)
+{
+ return (struct i915_drm_winsys *)iws;
+}
+
+struct i915_drm_winsys * i915_drm_winsys_create(int fd, unsigned pci_id);
+struct pipe_fence_handle * i915_drm_fence_create(drm_intel_bo *bo);
+
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct i915_drm_buffer {
+ unsigned magic;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct i915_drm_buffer *
+i915_drm_buffer(struct i915_winsys_buffer *buffer)
+{
+ return (struct i915_drm_buffer *)buffer;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct i915_winsys_buffer *buffer)
+{
+ return i915_drm_buffer(buffer)->bo;
+}
+
+#endif
diff --git a/src/gallium/winsys/drm/i965/gem/Makefile b/src/gallium/winsys/i965/drm/Makefile
index 6a7497b6be3..bbb71e25d84 100644
--- a/src/gallium/winsys/drm/i965/gem/Makefile
+++ b/src/gallium/winsys/i965/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = i965drm
@@ -11,4 +11,4 @@ LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/i965/gem/SConscript b/src/gallium/winsys/i965/drm/SConscript
index 6256ec6eaf0..150ab19a33e 100644
--- a/src/gallium/winsys/drm/i965/gem/SConscript
+++ b/src/gallium/winsys/i965/drm/SConscript
@@ -1,6 +1,6 @@
Import('*')
-env = drienv.Clone()
+env = env.Clone()
i965drm_sources = [
'i965_drm_api.c',
diff --git a/src/gallium/winsys/i965/drm/i965_drm_api.c b/src/gallium/winsys/i965/drm/i965_drm_api.c
new file mode 100644
index 00000000000..9072a186384
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_api.c
@@ -0,0 +1,122 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_api.h"
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i965/brw_context.h" /* XXX: shouldn't be doing this */
+#include "i965/brw_screen.h" /* XXX: shouldn't be doing this */
+
+#include "trace/tr_drm.h"
+
+#include "../../sw/drm/sw_drm_api.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ drm_intel_bufmgr_destroy(idws->gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+i965_libdrm_create_screen(struct drm_api *api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct i965_libdrm_winsys *idws;
+ unsigned int deviceID;
+
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ idws = CALLOC_STRUCT(i965_libdrm_winsys);
+ if (!idws)
+ return NULL;
+
+ i965_libdrm_get_device_id(&deviceID);
+
+ i965_libdrm_winsys_init_buffer_functions(idws);
+
+ idws->fd = drmFD;
+ idws->id = deviceID;
+
+ idws->base.destroy = i965_libdrm_winsys_destroy;
+
+ idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+ drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+ idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+ return brw_create_screen(&idws->base, deviceID);
+}
+
+
+static void
+destroy(struct drm_api *api)
+{
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+}
+
+struct drm_api i965_libdrm_api =
+{
+ .name = "i965",
+ .create_screen = i965_libdrm_create_screen,
+ .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ struct drm_api *api = NULL;
+
+ if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+ api = sw_drm_api_create(&i965_libdrm_api);
+
+ if (api == NULL)
+ api = &i965_libdrm_api;
+
+ return trace_drm_create(api);
+}
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
index 07be1df87f0..33a17496b2b 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_buffer.c
+++ b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
@@ -1,4 +1,5 @@
+#include "state_tracker/drm_api.h"
#include "i965_drm_winsys.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
@@ -122,6 +123,78 @@ err:
return PIPE_ERROR_OUT_OF_MEMORY;
}
+static enum pipe_error
+i965_libdrm_bo_from_handle(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tile,
+ struct brw_winsys_buffer **bo_out)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+ struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ uint32_t swizzle = 0;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, "FROM_HANDLE", whandle->handle);
+ buf->base.size = buf->bo->size;
+ buf->base.sws = &idws->base;
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
+ if (buf->tiling != 0)
+ buf->map_gtt = TRUE;
+
+ *tile = buf->tiling;
+ *stride = whandle->stride;
+
+ *bo_out = &buf->base;
+ return PIPE_OK;
+
+err:
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static enum pipe_error
+i965_libdrm_bo_get_handle(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return PIPE_ERROR_BAD_INPUT;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return PIPE_ERROR_BAD_INPUT;
+ }
+
+ whandle->stride = stride;
+ return PIPE_OK;
+}
+
static void
i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
{
@@ -415,6 +488,8 @@ void
i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
{
idws->base.bo_alloc = i965_libdrm_bo_alloc;
+ idws->base.bo_from_handle = i965_libdrm_bo_from_handle;
+ idws->base.bo_get_handle = i965_libdrm_bo_get_handle;
idws->base.bo_destroy = i965_libdrm_bo_destroy;
idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
idws->base.bo_exec = i965_libdrm_bo_exec;
diff --git a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
index c6a7d4a8c51..c6a7d4a8c51 100644
--- a/src/gallium/winsys/drm/i965/gem/i965_drm_winsys.h
+++ b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
diff --git a/src/gallium/winsys/drm/i965/xlib/Makefile b/src/gallium/winsys/i965/xlib/Makefile
index 0efa0ca6f9a..3730db6997e 100644
--- a/src/gallium/winsys/drm/i965/xlib/Makefile
+++ b/src/gallium/winsys/i965/xlib/Makefile
@@ -1,10 +1,10 @@
-# src/gallium/winsys/xlib/Makefile
+# src/gallium/winsys/i965/xlib/Makefile
# This makefile produces a "stand-alone" libGL.so which is based on
# Xlib (no DRI HW acceleration)
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
diff --git a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c b/src/gallium/winsys/i965/xlib/xlib_i965.c
index 74501eeb16f..063e9f600b9 100644
--- a/src/gallium/winsys/drm/i965/xlib/xlib_i965.c
+++ b/src/gallium/winsys/i965/xlib/xlib_i965.c
@@ -38,7 +38,7 @@
#include "pipe/p_error.h"
#include "pipe/p_context.h"
-#include "xm_winsys.h"
+#include "xm_public.h"
#include "i965/brw_winsys.h"
#include "i965/brw_screen.h"
diff --git a/src/gallium/winsys/drm/nouveau/drm/Makefile b/src/gallium/winsys/nouveau/drm/Makefile
index 54c3b26c755..71029858f75 100644
--- a/src/gallium/winsys/drm/nouveau/drm/Makefile
+++ b/src/gallium/winsys/nouveau/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = nouveaudrm
@@ -8,4 +8,4 @@ C_SOURCES = nouveau_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
index 1207c2d609c..1207c2d609c 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h
+++ b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
index 0d05f316c42..716d4bacd3b 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
@@ -21,9 +21,10 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
struct pipe_surface *ps = NULL;
struct pipe_texture *pt = NULL;
struct pipe_texture tmpl;
+ struct winsys_handle whandle;
memset(&tmpl, 0, sizeof(tmpl));
- tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY;
+ tmpl.tex_usage = PIPE_TEXTURE_USAGE_SCANOUT;
tmpl.target = PIPE_TEXTURE_2D;
tmpl.last_level = 0;
tmpl.depth0 = 1;
@@ -31,8 +32,11 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
tmpl.width0 = width;
tmpl.height0 = height;
- pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
- "front buffer", pitch, handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = pitch;
+ whandle.handle = handle;
+
+ pt = pscreen->texture_from_handle(pscreen, &tmpl, &whandle);
if (!pt)
return NULL;
@@ -82,11 +86,9 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
switch (dev->chipset & 0xf0) {
case 0x30:
- init = nv30_screen_create;
- break;
case 0x40:
case 0x60:
- init = nv40_screen_create;
+ init = nvfx_screen_create;
break;
case 0x50:
case 0x80:
@@ -142,74 +144,10 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return nvws->pscreen;
}
-static struct pipe_texture *
-nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *templ, const char *name,
- unsigned stride, unsigned handle)
-{
- struct nouveau_device *dev = nouveau_screen(pscreen)->device;
- struct pipe_texture *pt;
- struct pipe_buffer *pb;
- int ret;
-
- pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
- if (!pb)
- return NULL;
-
- ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1));
- if (ret) {
- debug_printf("%s: ref name 0x%08x failed with %d\n",
- __func__, handle, ret);
- FREE(pb);
- return NULL;
- }
-
- pipe_reference_init(&pb->reference, 1);
- pb->screen = pscreen;
- pb->alignment = 0;
- pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ_WRITE;
- pb->size = nouveau_bo(pb)->size;
- pt = pscreen->texture_blanket(pscreen, templ, &stride, pb);
- pipe_buffer_reference(&pb, NULL);
- return pt;
-}
-
-static boolean
-nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *pt, unsigned *stride,
- unsigned *handle)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- if (!mt || !mt->bo)
- return false;
-
- return nouveau_bo_handle_get(mt->bo, handle) == 0;
-}
-
-static boolean
-nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_texture *pt, unsigned *stride,
- unsigned *handle)
-{
- struct nouveau_miptree *mt = nouveau_miptree(pt);
-
- if (!mt || !mt->bo)
- return false;
-
- *handle = mt->bo->handle;
- *stride = util_format_get_stride(mt->base.format, mt->base.width0);
- return true;
-}
-
struct drm_api drm_api_hooks = {
.name = "nouveau",
.driver_name = "nouveau",
.create_screen = nouveau_drm_create_screen,
- .texture_from_shared_handle = nouveau_drm_pt_from_name,
- .shared_handle_from_texture = nouveau_drm_name_from_pt,
- .local_handle_from_texture = nouveau_drm_handle_from_pt,
};
struct drm_api *
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
index a91aad7df8e..a91aad7df8e 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
diff --git a/src/gallium/winsys/drm/radeon/core/Makefile b/src/gallium/winsys/radeon/drm/Makefile
index 860cbb6dbf8..7f69e392735 100644
--- a/src/gallium/winsys/drm/radeon/core/Makefile
+++ b/src/gallium/winsys/radeon/drm/Makefile
@@ -1,17 +1,17 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = radeonwinsys
C_SOURCES = \
- radeon_buffer.c \
+ radeon_drm_buffer.c \
radeon_drm.c \
radeon_r300.c
LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \
$(shell pkg-config libdrm --cflags-only-I)
-include ../../../../Makefile.template
+include ../../../Makefile.template
symlinks:
diff --git a/src/gallium/winsys/drm/radeon/core/SConscript b/src/gallium/winsys/radeon/drm/SConscript
index f4e9c397bdf..fab42929514 100644
--- a/src/gallium/winsys/drm/radeon/core/SConscript
+++ b/src/gallium/winsys/radeon/drm/SConscript
@@ -1,9 +1,9 @@
Import('*')
-env = drienv.Clone()
+env = env.Clone()
radeon_sources = [
- 'radeon_buffer.c',
+ 'radeon_drm_buffer.c',
'radeon_drm.c',
'radeon_r300.c',
]
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
new file mode 100644
index 00000000000..218a3763018
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <[email protected]>
+ */
+#ifndef RADEON_BUFFER_H
+#define RADEON_BUFFER_H
+
+#include <stdio.h>
+
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+
+#include "radeon_winsys.h"
+
+
+#define RADEON_MAX_BOS 24
+
+static INLINE struct pb_buffer *
+radeon_pb_buffer(struct r300_winsys_buffer *buffer)
+{
+ return (struct pb_buffer *)buffer;
+}
+
+static INLINE struct r300_winsys_buffer *
+radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
+{
+ return (struct r300_winsys_buffer *)buffer;
+}
+
+struct pb_manager *
+radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
+
+boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
+ uint32_t rd, uint32_t wd);
+
+
+void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+ uint32_t rd, uint32_t wd,
+ uint32_t flags);
+
+struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
+ uint32_t handle);
+
+void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled,
+ uint32_t pitch);
+
+void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
+
+boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
+ struct winsys_handle *whandle);
+
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf);
+#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c
index e817a26da6d..3dfcc5aef07 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.c
@@ -41,8 +41,22 @@
#include "xf86drm.h"
#include <sys/ioctl.h>
+static struct radeon_libdrm_winsys *
+radeon_winsys_create(int fd)
+{
+ struct radeon_libdrm_winsys *rws;
+
+ rws = CALLOC_STRUCT(radeon_libdrm_winsys);
+ if (rws == NULL) {
+ return NULL;
+ }
+
+ rws->fd = fd;
+ return rws;
+}
+
/* Helper function to do the ioctls needed for setup and init. */
-static void do_ioctls(int fd, struct radeon_winsys* winsys)
+static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
{
struct drm_radeon_gem_info gem_info = {0};
struct drm_radeon_info info = {0};
@@ -79,6 +93,13 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys)
exit(1);
}
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+ // Supported since 2.1.0.
+ winsys->squaretiling = version->version_major > 2 ||
+ version->version_minor >= 1;
+#endif
+
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
@@ -133,137 +154,28 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg)
{
- struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB);
- do_ioctls(drmFB, rwinsys);
+ struct radeon_libdrm_winsys* rws;
+ boolean ret;
+
+ rws = radeon_winsys_create(drmFB);
+ if (!rws)
+ return NULL;
+
+ do_ioctls(drmFB, rws);
/* The state tracker can organize a softpipe fallback if no hw
* driver is found.
*/
- if (is_r3xx(rwinsys->pci_id)) {
- radeon_setup_winsys(drmFB, rwinsys);
- return r300_create_screen(rwinsys);
- } else {
- FREE(rwinsys);
- return NULL;
- }
-}
-
-
-boolean radeon_buffer_from_texture(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_texture* texture,
- struct pipe_buffer** buffer,
- unsigned* stride)
-{
- /* XXX fix this */
- return r300_get_texture_buffer(screen, texture, buffer, stride);
-}
-
-/* Create a buffer from a handle. */
-/* XXX what's up with name? */
-struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
- struct pipe_screen* screen,
- const char* name,
- unsigned handle)
-{
- struct radeon_bo_manager* bom =
- ((struct radeon_winsys*)screen->winsys)->priv->bom;
- struct radeon_pipe_buffer* radeon_buffer;
- struct radeon_bo* bo = NULL;
-
- bo = radeon_bo_open(bom, handle, 0, 0, 0, 0);
- if (bo == NULL) {
- return NULL;
- }
-
- radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
- if (radeon_buffer == NULL) {
- radeon_bo_unref(bo);
- return NULL;
- }
-
- pipe_reference_init(&radeon_buffer->base.reference, 1);
- radeon_buffer->base.screen = screen;
- radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
- radeon_buffer->bo = bo;
- return &radeon_buffer->base;
-}
-
-static struct pipe_texture*
-radeon_texture_from_shared_handle(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *templ,
- const char *name,
- unsigned stride,
- unsigned handle)
-{
- struct pipe_buffer *buffer;
- struct pipe_texture *blanket;
-
- buffer = radeon_buffer_from_handle(api, screen, name, handle);
- if (!buffer) {
- return NULL;
- }
-
- blanket = screen->texture_blanket(screen, templ, &stride, buffer);
-
- pipe_buffer_reference(&buffer, NULL);
-
- return blanket;
-}
-
-static boolean radeon_shared_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
-{
- int retval, fd;
- struct drm_gem_flink flink;
- struct radeon_pipe_buffer* radeon_buffer;
- struct pipe_buffer *buffer = NULL;
-
- if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
- return FALSE;
+ if (is_r3xx(rws->pci_id)) {
+ ret = radeon_setup_winsys(drmFB, rws);
+ if (ret == FALSE)
+ goto fail;
+ return r300_create_screen(&rws->base);
}
- radeon_buffer = (struct radeon_pipe_buffer*)buffer;
- if (!radeon_buffer->flinked) {
- fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
-
- flink.handle = radeon_buffer->bo->handle;
-
- retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- if (retval) {
- debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
- retval);
- return FALSE;
- }
-
- radeon_buffer->flink = flink.name;
- radeon_buffer->flinked = TRUE;
- }
-
- *handle = radeon_buffer->flink;
- return TRUE;
-}
-
-static boolean radeon_local_handle_from_texture(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct pipe_buffer *buffer = NULL;
- if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
- return FALSE;
- }
-
- *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
-
- pipe_buffer_reference(&buffer, NULL);
-
- return TRUE;
+fail:
+ FREE(rws);
+ return NULL;
}
static void radeon_drm_api_destroy(struct drm_api *api)
@@ -275,9 +187,6 @@ struct drm_api drm_api_hooks = {
.name = "radeon",
.driver_name = "radeon",
.create_screen = radeon_create_screen,
- .texture_from_shared_handle = radeon_texture_from_shared_handle,
- .shared_handle_from_texture = radeon_shared_handle_from_texture,
- .local_handle_from_texture = radeon_local_handle_from_texture,
.destroy = radeon_drm_api_destroy,
};
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/radeon/drm/radeon_drm.h
index f62a9b80485..2dc077c0521 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.h
@@ -37,18 +37,12 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
-
boolean radeon_buffer_from_texture(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
-struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
- struct pipe_screen* screen,
- const char* name,
- unsigned handle);
-
boolean radeon_handle_from_buffer(struct drm_api* api,
struct pipe_screen* screen,
struct pipe_buffer* buffer,
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
new file mode 100644
index 00000000000..66f61322457
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -0,0 +1,385 @@
+
+#include <sys/ioctl.h>
+#include "radeon_drm.h"
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
+#include "radeon_buffer.h"
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "radeon_winsys.h"
+struct radeon_drm_bufmgr;
+
+struct radeon_drm_buffer {
+ struct pb_buffer base;
+ struct radeon_drm_bufmgr *mgr;
+
+ struct radeon_bo *bo;
+
+ boolean flinked;
+ uint32_t flink;
+
+ struct radeon_drm_buffer *next, *prev;
+};
+
+extern const struct pb_vtbl radeon_drm_buffer_vtbl;
+
+
+static INLINE struct radeon_drm_buffer *
+radeon_drm_buffer(struct pb_buffer *buf)
+{
+ assert(buf);
+ assert(buf->vtbl == &radeon_drm_buffer_vtbl);
+ return (struct radeon_drm_buffer *)buf;
+}
+
+struct radeon_drm_bufmgr {
+ struct pb_manager base;
+ struct radeon_libdrm_winsys *rws;
+ struct radeon_drm_buffer buffer_map_list;
+};
+
+static INLINE struct radeon_drm_bufmgr *
+radeon_drm_bufmgr(struct pb_manager *mgr)
+{
+ assert(mgr);
+ return (struct radeon_drm_bufmgr *)mgr;
+}
+
+static void
+radeon_drm_buffer_destroy(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+
+ if (buf->bo->ptr != NULL) {
+ remove_from_list(buf);
+ radeon_bo_unmap(buf->bo);
+ buf->bo->ptr = NULL;
+ }
+ radeon_bo_unref(buf->bo);
+
+ FREE(buf);
+}
+
+static void *
+radeon_drm_buffer_map(struct pb_buffer *_buf,
+ unsigned flags)
+{
+ struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+ int write = 0;
+
+ if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
+ if ((_buf->base.usage & PIPE_BUFFER_USAGE_VERTEX) ||
+ (_buf->base.usage & PIPE_BUFFER_USAGE_INDEX))
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+ return NULL;
+ }
+
+ if (buf->bo->ptr != NULL)
+ return buf->bo->ptr;
+
+ if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
+ uint32_t domain;
+ if (radeon_bo_is_busy(buf->bo, &domain))
+ return NULL;
+ }
+
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ }
+
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
+ write = 1;
+ }
+
+ if (radeon_bo_map(buf->bo, write)) {
+ return NULL;
+ }
+ insert_at_tail(&buf->mgr->buffer_map_list, buf);
+ return buf->bo->ptr;
+}
+
+static void
+radeon_drm_buffer_unmap(struct pb_buffer *_buf)
+{
+ (void)_buf;
+}
+
+static void
+radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset)
+{
+ *base_buf = buf;
+ *offset = 0;
+}
+
+
+static enum pipe_error
+radeon_drm_buffer_validate(struct pb_buffer *_buf,
+ struct pb_validate *vl,
+ unsigned flags)
+{
+ /* Always pinned */
+ return PIPE_OK;
+}
+
+static void
+radeon_drm_buffer_fence(struct pb_buffer *buf,
+ struct pipe_fence_handle *fence)
+{
+}
+
+const struct pb_vtbl radeon_drm_buffer_vtbl = {
+ radeon_drm_buffer_destroy,
+ radeon_drm_buffer_map,
+ radeon_drm_buffer_unmap,
+ radeon_drm_buffer_validate,
+ radeon_drm_buffer_fence,
+ radeon_drm_buffer_get_base_buffer,
+};
+
+
+static uint32_t radeon_domain_from_usage(unsigned usage)
+{
+ uint32_t domain = 0;
+
+ if (usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ if (usage & PIPE_BUFFER_USAGE_PIXEL) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ if (usage & PIPE_BUFFER_USAGE_VERTEX) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
+ }
+ if (usage & PIPE_BUFFER_USAGE_INDEX) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
+ }
+
+ return domain;
+}
+
+struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
+ uint32_t handle)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_libdrm_winsys *rws = mgr->rws;
+ struct radeon_drm_buffer *buf;
+ struct radeon_bo *bo;
+
+ bo = radeon_bo_open(rws->bom, handle, 0,
+ 0, 0, 0);
+ if (bo == NULL)
+ return NULL;
+
+ buf = CALLOC_STRUCT(radeon_drm_buffer);
+ if (!buf) {
+ radeon_bo_unref(bo);
+ return NULL;
+ }
+
+ make_empty_list(buf);
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = 0;
+ buf->base.base.usage = PIPE_BUFFER_USAGE_PIXEL;
+ buf->base.base.size = 0;
+ buf->base.vtbl = &radeon_drm_buffer_vtbl;
+ buf->mgr = mgr;
+
+ buf->bo = bo;
+
+ return &buf->base;
+}
+
+static struct pb_buffer *
+radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
+ pb_size size,
+ const struct pb_desc *desc)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_libdrm_winsys *rws = mgr->rws;
+ struct radeon_drm_buffer *buf;
+ uint32_t domain;
+
+ buf = CALLOC_STRUCT(radeon_drm_buffer);
+ if (!buf)
+ goto error1;
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+ buf->base.vtbl = &radeon_drm_buffer_vtbl;
+ buf->mgr = mgr;
+
+ make_empty_list(buf);
+ domain = radeon_domain_from_usage(desc->usage);
+ buf->bo = radeon_bo_open(rws->bom, 0, size,
+ desc->alignment, domain, 0);
+ if (buf->bo == NULL)
+ goto error2;
+
+ return &buf->base;
+
+ error2:
+ FREE(buf);
+ error1:
+ return NULL;
+}
+
+static void
+radeon_drm_bufmgr_flush(struct pb_manager *mgr)
+{
+ /* NOP */
+}
+
+static void
+radeon_drm_bufmgr_destroy(struct pb_manager *_mgr)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ FREE(mgr);
+}
+
+struct pb_manager *
+radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
+{
+ struct radeon_drm_bufmgr *mgr;
+
+ mgr = CALLOC_STRUCT(radeon_drm_bufmgr);
+ if (!mgr)
+ return NULL;
+
+ mgr->base.destroy = radeon_drm_bufmgr_destroy;
+ mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer;
+ mgr->base.flush = radeon_drm_bufmgr_flush;
+
+ mgr->rws = rws;
+ make_empty_list(&mgr->buffer_map_list);
+ return &mgr->base;
+}
+
+static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf;
+ if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
+ buf = radeon_drm_buffer(_buf);
+ } else {
+ struct pb_buffer *base_buf;
+ pb_size offset;
+ pb_get_base_buffer(_buf, &base_buf, &offset);
+
+ buf = radeon_drm_buffer(base_buf);
+ }
+ return buf;
+}
+
+boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
+ struct winsys_handle *whandle)
+{
+ int retval, fd;
+ struct drm_gem_flink flink;
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ fd = buf->mgr->rws->fd;
+ flink.handle = buf->bo->handle;
+
+ retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
+ if (retval) {
+ return FALSE;
+ }
+
+ buf->flinked = TRUE;
+ buf->flink = flink.name;
+ }
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ }
+ return TRUE;
+}
+
+
+void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled,
+ uint32_t pitch)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t flags = 0, old_flags, old_pitch;
+ if (microtiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE;
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+ else if (microtiled == R300_BUFFER_SQUARETILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
+#endif
+ if (macrotiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MACRO_TILE;
+
+ radeon_bo_get_tiling(buf->bo, &old_flags, &old_pitch);
+
+ if (flags != old_flags || pitch != old_pitch) {
+ /* Tiling determines how DRM treats the buffer data.
+ * We must flush CS when changing it if the buffer is referenced. */
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ }
+ }
+ radeon_bo_set_tiling(buf->bo, flags, pitch);
+
+}
+
+boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
+ uint32_t rd, uint32_t wd)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
+ rd, wd);
+ return TRUE;
+}
+
+void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+ uint32_t rd, uint32_t wd,
+ uint32_t flags)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ int retval;
+
+ retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
+ buf->bo, rd, wd, flags);
+ if (retval) {
+ debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
+ buf, rd, wd, flags);
+ }
+}
+
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t domain;
+
+ return (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs) ||
+ radeon_bo_is_busy(buf->bo, &domain));
+}
+
+
+void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_drm_buffer *rpb, *t_rpb;
+
+ foreach_s(rpb, t_rpb, &mgr->buffer_map_list) {
+ radeon_bo_unmap(rpb->bo);
+ rpb->bo->ptr = NULL;
+ remove_from_list(rpb);
+ }
+
+ make_empty_list(&mgr->buffer_map_list);
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
new file mode 100644
index 00000000000..38fcf889c8b
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -0,0 +1,348 @@
+/*
+ * Copyright 2008 Corbin Simpson <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "radeon_r300.h"
+#include "radeon_buffer.h"
+
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
+#include "state_tracker/drm_api.h"
+
+static struct r300_winsys_buffer *
+radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct pb_desc desc;
+ struct pb_manager *provider;
+ struct pb_buffer *buffer;
+
+ memset(&desc, 0, sizeof(desc));
+ desc.alignment = alignment;
+ desc.usage = usage;
+
+ if (usage & PIPE_BUFFER_USAGE_CONSTANT)
+ provider = ws->mman;
+ else if ((usage & PIPE_BUFFER_USAGE_VERTEX) ||
+ (usage & PIPE_BUFFER_USAGE_INDEX))
+ provider = ws->cman;
+ else
+ provider = ws->kman;
+ buffer = provider->create_buffer(provider, size, &desc);
+ if (!buffer)
+ return NULL;
+
+ return radeon_libdrm_winsys_buffer(buffer);
+}
+
+static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_destroy(_buf);
+}
+static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ uint32_t pitch,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
+}
+
+static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ unsigned usage)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return pb_map(_buf, usage);
+}
+
+static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_unmap(_buf);
+}
+
+static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer **pdst,
+ struct r300_winsys_buffer *src)
+{
+ struct pb_buffer *_src = radeon_pb_buffer(src);
+ struct pb_buffer *_dst = radeon_pb_buffer(*pdst);
+
+ pb_reference(&_dst, _src);
+
+ *pdst = radeon_libdrm_winsys_buffer(_dst);
+}
+
+static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return radeon_drm_bufmgr_is_buffer_referenced(_buf);
+}
+
+static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
+ struct pipe_screen *screen,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct pb_buffer *_buf;
+
+ _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
+ *stride = whandle->stride;
+ return radeon_libdrm_winsys_buffer(_buf);
+}
+
+static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buffer,
+ unsigned stride,
+ struct winsys_handle *whandle)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buffer);
+ boolean ret;
+ ret = radeon_drm_bufmgr_get_handle(_buf, whandle);
+ if (ret)
+ whandle->stride = stride;
+ return ret;
+}
+
+static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
+ void (*flush_cb)(void *),
+ void *data)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ ws->flush_cb = flush_cb;
+ ws->flush_data = data;
+ radeon_cs_space_set_flush(ws->cs, flush_cb, data);
+}
+
+static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ uint32_t rd,
+ uint32_t wd)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
+}
+
+static boolean radeon_validate(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ if (radeon_cs_space_check(ws->cs) < 0) {
+ return FALSE;
+ }
+
+ /* Things are fine, we can proceed as normal. */
+ return TRUE;
+}
+
+static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_cs *cs = ws->cs;
+
+ return radeon_validate(rws) && cs->cdw + size <= cs->ndw;
+}
+
+static void radeon_begin_cs(struct r300_winsys_screen *rws,
+ int size,
+ const char* file,
+ const char* function,
+ int line)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_begin(ws->cs, size, file, function, line);
+}
+
+static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
+ uint32_t dword)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_write_dword(ws->cs, dword);
+}
+
+static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ uint32_t rd,
+ uint32_t wd,
+ uint32_t flags)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
+}
+
+static void radeon_reset_bos(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_space_reset_bos(ws->cs);
+}
+
+static void radeon_end_cs(struct r300_winsys_screen *rws,
+ const char* file,
+ const char* function,
+ int line)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_end(ws->cs, file, function, line);
+}
+
+static void radeon_flush_cs(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ int retval;
+
+ /* Don't flush a zero-sized CS. */
+ if (!ws->cs->cdw) {
+ return;
+ }
+
+ radeon_drm_bufmgr_flush_maps(ws->kman);
+ /* Emit the CS. */
+ retval = radeon_cs_emit(ws->cs);
+ if (retval) {
+ debug_printf("radeon: Bad CS, dumping...\n");
+ radeon_cs_print(ws->cs, stderr);
+ }
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
+ radeon_cs_erase(ws->cs);
+}
+
+static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
+ enum r300_value_id id)
+{
+ struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
+
+ switch(id) {
+ case R300_VID_PCI_ID:
+ return ws->pci_id;
+ case R300_VID_GB_PIPES:
+ return ws->gb_pipes;
+ case R300_VID_Z_PIPES:
+ return ws->z_pipes;
+ case R300_VID_SQUARE_TILING_SUPPORT:
+ return ws->squaretiling;
+ }
+ return 0;
+}
+
+static void
+radeon_winsys_destroy(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
+ radeon_cs_destroy(ws->cs);
+
+ ws->cman->destroy(ws->cman);
+ ws->kman->destroy(ws->kman);
+ ws->mman->destroy(ws->mman);
+
+ radeon_bo_manager_gem_dtor(ws->bom);
+ radeon_cs_manager_gem_dtor(ws->csm);
+}
+
+boolean
+radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
+{
+
+ ws->csm = radeon_cs_manager_gem_ctor(fd);
+ if (!ws->csm)
+ goto fail;
+ ws->bom = radeon_bo_manager_gem_ctor(fd);
+ if (!ws->bom)
+ goto fail;
+ ws->kman = radeon_drm_bufmgr_create(ws);
+ if (!ws->kman)
+ goto fail;
+
+ ws->cman = pb_cache_manager_create(ws->kman, 100000);
+ if (!ws->cman)
+ goto fail;
+
+ ws->mman = pb_malloc_bufmgr_create();
+ if (!ws->mman)
+ goto fail;
+
+ /* Size limit on IBs is 64 kibibytes. */
+ ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
+ if (!ws->cs)
+ goto fail;
+ radeon_cs_set_limit(ws->cs,
+ RADEON_GEM_DOMAIN_GTT, ws->gart_size);
+ radeon_cs_set_limit(ws->cs,
+ RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
+
+ ws->base.add_buffer = radeon_add_buffer;
+ ws->base.validate = radeon_validate;
+ ws->base.destroy = radeon_winsys_destroy;
+ ws->base.check_cs = radeon_check_cs;
+ ws->base.begin_cs = radeon_begin_cs;
+ ws->base.write_cs_dword = radeon_write_cs_dword;
+ ws->base.write_cs_reloc = radeon_write_cs_reloc;
+ ws->base.end_cs = radeon_end_cs;
+ ws->base.flush_cs = radeon_flush_cs;
+ ws->base.reset_bos = radeon_reset_bos;
+ ws->base.set_flush_cb = radeon_set_flush_cb;
+ ws->base.get_value = radeon_get_value;
+
+ ws->base.buffer_create = radeon_r300_winsys_buffer_create;
+ ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy;
+ ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling;
+ ws->base.buffer_map = radeon_r300_winsys_buffer_map;
+ ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
+ ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
+ ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
+ ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
+ ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced;
+ return TRUE;
+
+fail:
+ if (ws->csm)
+ radeon_cs_manager_gem_dtor(ws->csm);
+
+ if (ws->bom)
+ radeon_bo_manager_gem_dtor(ws->bom);
+
+ if (ws->cman)
+ ws->cman->destroy(ws->cman);
+ if (ws->kman)
+ ws->kman->destroy(ws->kman);
+ if (ws->mman)
+ ws->mman->destroy(ws->mman);
+
+ if (ws->cs)
+ radeon_cs_destroy(ws->cs);
+ return FALSE;
+}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/radeon/drm/radeon_r300.h
index e655dc32c85..2703464ad8f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.h
@@ -25,6 +25,6 @@
#include "radeon_winsys.h"
-void radeon_setup_winsys(int fd, struct radeon_winsys* winsys);
+boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys);
#endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index f776e2d9008..4260dbaad72 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -1,5 +1,5 @@
/*
- * Copyright © 2008 Jérôme Glisse
+ * Copyright © 2009 Corbin Simpson
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
@@ -25,53 +25,62 @@
*/
/*
* Authors:
- * Jérôme Glisse <[email protected]>
+ * Corbin Simpson <[email protected]>
*/
-#ifndef RADEON_BUFFER_H
-#define RADEON_BUFFER_H
+#ifndef RADEON_WINSYS_H
+#define RADEON_WINSYS_H
-#include "pipebuffer/pb_buffer.h"
+#include "r300_winsys.h"
-#include "radeon_bo.h"
-#include "radeon_cs.h"
+struct radeon_libdrm_winsys {
+ /* Parent class. */
+ struct r300_winsys_screen base;
-#include "radeon_winsys.h"
+ struct pb_manager *kman;
-struct radeon_pipe_buffer {
- struct pipe_buffer base;
- /* Pointer to GPU-backed BO. */
- struct radeon_bo *bo;
- /* Pointer to fallback PB buffer. */
- struct pb_buffer *pb;
- boolean flinked;
- uint32_t flink;
-};
+ struct pb_manager *cman;
+
+ struct pb_manager *mman;
+
+ /* PCI ID */
+ uint32_t pci_id;
+
+ /* GB pipe count */
+ uint32_t gb_pipes;
+
+ /* Z pipe count (rv530 only) */
+ uint32_t z_pipes;
-#define RADEON_MAX_BOS 24
+ /* GART size. */
+ uint32_t gart_size;
+
+ /* VRAM size. */
+ uint32_t vram_size;
+
+ /* Square tiling support. */
+ boolean squaretiling;
-struct radeon_winsys_priv {
/* DRM FD */
int fd;
/* Radeon BO manager. */
- struct radeon_bo_manager* bom;
+ struct radeon_bo_manager *bom;
/* Radeon CS manager. */
- struct radeon_cs_manager* csm;
+ struct radeon_cs_manager *csm;
/* Current CS. */
- struct radeon_cs* cs;
+ struct radeon_cs *cs;
/* Flush CB */
void (*flush_cb)(void *);
void *flush_data;
};
-struct radeon_winsys* radeon_pipe_winsys(int fb);
-#if 0
-struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context,
- uint32_t handle,
- enum pipe_format format,
- int w, int h, int pitch);
-#endif
+static INLINE struct radeon_libdrm_winsys *
+radeon_winsys_screen(struct r300_winsys_screen *base)
+{
+ return (struct radeon_libdrm_winsys *)base;
+}
+
#endif
diff --git a/src/gallium/winsys/drm/vmware/core/Makefile b/src/gallium/winsys/svga/drm/Makefile
index a52957c1a5b..c2f59e01b0d 100644
--- a/src/gallium/winsys/drm/vmware/core/Makefile
+++ b/src/gallium/winsys/svga/drm/Makefile
@@ -1,4 +1,4 @@
-TOP = ../../../../../..
+TOP = ../../../../..
include $(TOP)/configs/current
LIBNAME = svgadrm
@@ -17,14 +17,6 @@ C_SOURCES = \
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/svga \
-I$(TOP)/src/gallium/drivers/svga/include \
- -I$(GALLIUM)/src/mesa/drivers/dri/common \
- -I$(GALLIUM)/include \
- -I$(GALLIUM)/include/GL/internal \
- -I$(GALLIUM)/src/mesa \
- -I$(GALLIUM)/src/mesa/main \
- -I$(GALLIUM)/src/mesa/glapi \
- -I$(GALLIUM)/src/egl/main \
- -I$(GALLIUM)/src/egl/drivers/dri \
$(shell pkg-config libdrm --cflags-only-I)
LIBRARY_DEFINES = \
@@ -32,4 +24,4 @@ LIBRARY_DEFINES = \
-DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
$(shell pkg-config libdrm --cflags-only-other)
-include ../../../../Makefile.template
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/drm/vmware/core/SConscript b/src/gallium/winsys/svga/drm/SConscript
index edaf9458bee..edaf9458bee 100644
--- a/src/gallium/winsys/drm/vmware/core/SConscript
+++ b/src/gallium/winsys/svga/drm/SConscript
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c
index eca174a6c56..eca174a6c56 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.c
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h b/src/gallium/winsys/svga/drm/vmw_buffer.h
index 41fb4476da5..41fb4476da5 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_buffer.h
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
index 90ffc4868f7..90ffc4868f7 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.h b/src/gallium/winsys/svga/drm/vmw_context.h
index d4884d24e99..d4884d24e99 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_context.h
+++ b/src/gallium/winsys/svga/drm/vmw_context.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.c b/src/gallium/winsys/svga/drm/vmw_fence.c
index 873dd51166c..873dd51166c 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_fence.c
+++ b/src/gallium/winsys/svga/drm/vmw_fence.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_fence.h b/src/gallium/winsys/svga/drm/vmw_fence.h
index 5357b4f61de..5357b4f61de 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_fence.h
+++ b/src/gallium/winsys/svga/drm/vmw_fence.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 6cc9b382932..6cc9b382932 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index d3f2c2c7f56..d3f2c2c7f56 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
index a7c6e88b9eb..e8ebe9ac893 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
@@ -39,11 +39,21 @@
#include <state_tracker/dri1_api.h>
#include <state_tracker/drm_api.h>
-#include <vmwgfx_drm.h>
+#include "vmwgfx_drm.h"
#include <xf86drm.h>
#include <stdio.h>
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+static boolean
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
static struct dri1_api dri1_api_hooks;
static struct dri1_api_version ddx_required = { 0, 1, 0 };
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
@@ -129,7 +139,12 @@ vmw_drm_create_screen(struct drm_api *drm_api,
&drm_compat, "use old scanout field (not a error)"))
use_old_scanout_flag = TRUE;
dri1->api = &dri1_api_hooks;
+#if 0
break;
+#else
+ assert(!"No dri 1 support for now\n");
+ return NULL;
+#endif
default:
return NULL;
}
@@ -139,6 +154,10 @@ vmw_drm_create_screen(struct drm_api *drm_api,
if (!vws)
goto out_no_vws;
+ /* XXX do this properly */
+ vws->base.surface_from_handle = vmw_drm_surface_from_handle;
+ vws->base.surface_get_handle = vmw_drm_surface_get_handle;
+
screen = svga_screen_create( &vws->base );
if (!screen)
goto out_no_screen;
@@ -200,6 +219,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
const struct drm_clip_rect *bbox,
struct pipe_fence_handle **p_fence)
{
+#if 0
struct svga_winsys_surface *srf =
svga_screen_texture_get_winsys_surface(surf->texture);
struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf);
@@ -246,21 +266,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
*p_fence = (visible) ? vmw_pipe_fence(fence_seq) : NULL;
vmw_svga_winsys_surface_reference(&vsrf, NULL);
+#else
+ assert(!"No dri 1 support for now\n");
+#endif
}
-static struct pipe_texture *
-vmw_drm_texture_from_handle(struct drm_api *drm_api,
- struct pipe_screen *screen,
- struct pipe_texture *templat,
- const char *name,
- unsigned stride,
- unsigned handle)
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format)
{
struct vmw_svga_winsys_surface *vsrf;
struct svga_winsys_surface *ssrf;
- struct vmw_winsys_screen *vws =
- vmw_winsys_screen(svga_winsys_screen(screen));
- struct pipe_texture *tex;
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
union drm_vmw_surface_reference_arg arg;
struct drm_vmw_surface_arg *req = &arg.req;
struct drm_vmw_surface_create_req *rep = &arg.rep;
@@ -273,7 +291,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
*/
memset(&arg, 0, sizeof(arg));
- req->sid = handle;
+ req->sid = whandle->handle;
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
&arg, sizeof(arg));
@@ -281,14 +299,14 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (ret) {
fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
"Error %d (%s).\n",
- handle, ret, strerror(-ret));
+ whandle->handle, ret, strerror(-ret));
return NULL;
}
if (rep->mip_levels[0] != 1) {
fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
" SID %d, levels %d\n",
- handle, rep->mip_levels[0]);
+ whandle->handle, rep->mip_levels[0]);
goto out_mip;
}
@@ -296,7 +314,7 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
if (rep->mip_levels[i] != 0) {
fprintf(stderr, "Incorrect number of faces levels on shared surface."
" SID %d, face %d present.\n",
- handle, i);
+ whandle->handle, i);
goto out_mip;
}
}
@@ -308,38 +326,32 @@ vmw_drm_texture_from_handle(struct drm_api *drm_api,
pipe_reference_init(&vsrf->refcnt, 1);
p_atomic_set(&vsrf->validated, 0);
vsrf->screen = vws;
- vsrf->sid = handle;
+ vsrf->sid = whandle->handle;
ssrf = svga_winsys_surface(vsrf);
- tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
- if (!tex)
- vmw_svga_winsys_surface_reference(&vsrf, NULL);
+ *format = rep->format;
+
+ return ssrf;
- return tex;
- out_mip:
- vmw_ioctl_surface_destroy(vws, handle);
+out_mip:
+ vmw_ioctl_surface_destroy(vws, whandle->handle);
return NULL;
}
static boolean
-vmw_drm_handle_from_texture(struct drm_api *drm_api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle)
{
- struct svga_winsys_surface *surface =
- svga_screen_texture_get_winsys_surface(texture);
struct vmw_svga_winsys_surface *vsrf;
if (!surface)
return FALSE;
vsrf = vmw_svga_winsys_surface(surface);
- *handle = vsrf->sid;
- *stride = util_format_get_nblocksx(texture->format, texture->width0) *
- util_format_get_blocksize(texture->format);
+ whandle->handle = vsrf->sid;
+ whandle->stride = stride;
- vmw_svga_winsys_surface_reference(&vsrf, NULL);
return TRUE;
}
@@ -353,9 +365,6 @@ static struct drm_api vmw_drm_api_hooks = {
.name = "vmwgfx",
.driver_name = "vmwgfx",
.create_screen = vmw_drm_create_screen,
- .texture_from_shared_handle = vmw_drm_texture_from_handle,
- .shared_handle_from_texture = vmw_drm_handle_from_texture,
- .local_handle_from_texture = vmw_drm_handle_from_texture,
};
struct drm_api* drm_api_create()
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 5d81fa8c4a6..5d81fa8c4a6 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
index b9823d78575..b9823d78575 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
index 2b4e80f0039..2b4e80f0039 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_svga.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c
index 5f1b9ad5770..5f1b9ad5770 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.c
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h
index 3d61595c288..3d61595c288 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_surface.h
+++ b/src/gallium/winsys/svga/drm/vmw_surface.h
diff --git a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
index 47914bdb711..47914bdb711 100644
--- a/src/gallium/winsys/drm/vmware/core/vmwgfx_drm.h
+++ b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/sw/Makefile
index d8feef6824a..e9182ea5b1b 100644
--- a/src/gallium/winsys/drm/intel/Makefile
+++ b/src/gallium/winsys/sw/Makefile
@@ -1,8 +1,8 @@
-# src/gallium/winsys/drm/intel/Makefile
-TOP = ../../../../..
+# src/gallium/winsys/sw/Makefile
+TOP = ../../../..
include $(TOP)/configs/current
-SUBDIRS = gem $(GALLIUM_STATE_TRACKERS_DIRS)
+SUBDIRS = null wrapper
default install clean:
@for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/sw/dri/Makefile b/src/gallium/winsys/sw/dri/Makefile
new file mode 100644
index 00000000000..a3fca6be885
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/Makefile
@@ -0,0 +1,13 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdri
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+C_SOURCES = \
+ dri_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript
new file mode 100644
index 00000000000..b255d725f95
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_dri = env.ConvenienceLibrary(
+ target = 'ws_dri',
+ source = [
+ 'dri_sw_winsys.c',
+ ]
+ )
+ Export('ws_dri')
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
new file mode 100644
index 00000000000..870c6afc124
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -0,0 +1,225 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/sw_winsys.h"
+#include "dri_sw_winsys.h"
+
+
+struct dri_sw_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+};
+
+struct dri_sw_winsys
+{
+ struct sw_winsys base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+static INLINE struct dri_sw_displaytarget *
+dri_sw_displaytarget( struct sw_displaytarget *dt )
+{
+ return (struct dri_sw_displaytarget *)dt;
+}
+
+static INLINE struct dri_sw_winsys *
+dri_sw_winsys( struct sw_winsys *ws )
+{
+ return (struct dri_sw_winsys *)ws;
+}
+
+
+static boolean
+dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct dri_sw_displaytarget *dri_sw_dt;
+ unsigned nblocksy, size, format_stride;
+
+ dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
+ if(!dri_sw_dt)
+ goto no_dt;
+
+ dri_sw_dt->format = format;
+ dri_sw_dt->width = width;
+ dri_sw_dt->height = height;
+
+ format_stride = util_format_get_stride(format, width);
+ dri_sw_dt->stride = align(format_stride, alignment);
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ size = dri_sw_dt->stride * nblocksy;
+
+ dri_sw_dt->data = align_malloc(size, alignment);
+ if(!dri_sw_dt->data)
+ goto no_data;
+
+ *stride = dri_sw_dt->stride;
+ return (struct sw_displaytarget *)dri_sw_dt;
+
+no_data:
+ FREE(dri_sw_dt);
+no_dt:
+ return NULL;
+}
+
+static void
+dri_sw_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+
+ if (dri_sw_dt->data) {
+ FREE(dri_sw_dt->data);
+ }
+
+ FREE(dri_sw_dt);
+}
+
+static void *
+dri_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = dri_sw_dt->data;
+ return dri_sw_dt->mapped;
+}
+
+static void
+dri_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = NULL;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+static boolean
+dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+static void
+dri_sw_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
+ unsigned width, height;
+
+ /* Set the width to 'stride / cpp'.
+ *
+ * PutImage correctly clips to the width of the dst drawable.
+ */
+ width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
+
+ height = dri_sw_dt->height;
+
+ dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
+}
+
+
+static void
+dri_destroy_sw_winsys(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+struct sw_winsys *
+dri_create_sw_winsys(struct drisw_loader_funcs *lf)
+{
+ struct dri_sw_winsys *ws;
+
+ ws = CALLOC_STRUCT(dri_sw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->lf = lf;
+ ws->base.destroy = dri_destroy_sw_winsys;
+
+ ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
+
+ /* screen texture functions */
+ ws->base.displaytarget_create = dri_sw_displaytarget_create;
+ ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy;
+ ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle;
+
+ /* texture functions */
+ ws->base.displaytarget_map = dri_sw_displaytarget_map;
+ ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap;
+
+ ws->base.displaytarget_display = dri_sw_displaytarget_display;
+
+ return &ws->base;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
index f96c5a14b0a..329ac06a05b 100644
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.h
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
@@ -1,8 +1,9 @@
/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2009, VMware, Inc.
* All Rights Reserved.
- *
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,31 +11,28 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
+#ifndef DRI_SW_WINSYS
+#define DRI_SW_WINSYS
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
+#include "state_tracker/drisw_api.h"
+struct sw_winsys;
-struct pipe_winsys;
+struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
-
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
+#endif
diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile
new file mode 100644
index 00000000000..79664536aa0
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdrm
+
+C_SOURCES = sw_drm_api.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c
new file mode 100644
index 00000000000..eb81d26a593
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.c
@@ -0,0 +1,97 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "util/u_memory.h"
+#include "softpipe/sp_public.h"
+#include "state_tracker/drm_api.h"
+#include "../../sw/wrapper/wrapper_sw_winsys.h"
+#include "sw_drm_api.h"
+
+
+/*
+ * Defines
+ */
+
+
+struct sw_drm_api
+{
+ struct drm_api base;
+ struct drm_api *api;
+ struct sw_winsys *sw;
+};
+
+static INLINE struct sw_drm_api *
+sw_drm_api(struct drm_api *api)
+{
+ return (struct sw_drm_api *)api;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_screen *
+sw_drm_create_screen(struct drm_api *_api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct sw_drm_api *swapi = sw_drm_api(_api);
+ struct drm_api *api = swapi->api;
+ struct sw_winsys *sww;
+ struct pipe_screen *screen;
+
+ screen = api->create_screen(api, drmFD, arg);
+
+ sww = wrapper_sw_winsys_warp_pipe_screen(screen);
+
+ return softpipe_create_screen(sww);
+}
+
+static void
+sw_drm_destroy(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = sw_drm_api(api);
+ if (swapi->api->destroy)
+ swapi->api->destroy(swapi->api);
+
+ FREE(swapi);
+}
+
+struct drm_api *
+sw_drm_api_create(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
+
+ swapi->base.name = "sw";
+ swapi->base.driver_name = api->driver_name;
+ swapi->base.create_screen = sw_drm_create_screen;
+ swapi->base.destroy = sw_drm_destroy;
+
+ swapi->api = api;
+
+ return &swapi->base;
+}
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/winsys/sw/drm/sw_drm_api.h
new file mode 100644
index 00000000000..ce90a04ae0c
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.h
@@ -0,0 +1,34 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef SW_DRM_API_H
+#define SW_DRM_API_H
+
+struct drm_api;
+
+struct drm_api * sw_drm_api_create(struct drm_api *api);
+
+#endif
diff --git a/src/gallium/winsys/sw/gdi/SConscript b/src/gallium/winsys/sw/gdi/SConscript
new file mode 100644
index 00000000000..1267fc6eea4
--- /dev/null
+++ b/src/gallium/winsys/sw/gdi/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_gdi = env.ConvenienceLibrary(
+ target = 'ws_gdi',
+ source = [
+ 'gdi_sw_winsys.c',
+ ]
+ )
+ Export('ws_gdi')
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
index a9fa03b8e57..4dba4b577b8 100644
--- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
@@ -28,7 +28,7 @@
/**
* @file
- * LLVMpipe support.
+ * GDI software rasterizer support.
*
* @author Jose Fonseca <[email protected]>
*/
@@ -42,12 +42,11 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
-#include "stw_winsys.h"
+#include "state_tracker/sw_winsys.h"
+#include "gdi_sw_winsys.h"
-struct gdi_llvmpipe_displaytarget
+struct gdi_sw_displaytarget
{
enum pipe_format format;
unsigned width;
@@ -63,15 +62,16 @@ struct gdi_llvmpipe_displaytarget
/** Cast wrapper */
-static INLINE struct gdi_llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf )
+static INLINE struct gdi_sw_displaytarget *
+gdi_sw_displaytarget( struct sw_displaytarget *buf )
{
- return (struct gdi_llvmpipe_displaytarget *)buf;
+ return (struct gdi_sw_displaytarget *)buf;
}
static boolean
-gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
switch(format) {
@@ -89,47 +89,48 @@ gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
static void *
-gdi_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+gdi_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags )
{
- struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
return gdt->data;
}
static void
-gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
+gdi_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
{
}
static void
-gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
+gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
{
- struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
align_free(gdt->data);
FREE(gdt);
}
-static struct llvmpipe_displaytarget *
-gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
+static struct sw_displaytarget *
+gdi_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride)
{
- struct gdi_llvmpipe_displaytarget *gdt;
+ struct gdi_sw_displaytarget *gdt;
unsigned cpp;
unsigned bpp;
- gdt = CALLOC_STRUCT(gdi_llvmpipe_displaytarget);
+ gdt = CALLOC_STRUCT(gdi_sw_displaytarget);
if(!gdt)
goto no_gdt;
@@ -160,7 +161,7 @@ gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
gdt->bmi.bmiHeader.biClrImportant = 0;
*stride = gdt->stride;
- return (struct llvmpipe_displaytarget *)gdt;
+ return (struct sw_displaytarget *)gdt;
no_data:
FREE(gdt);
@@ -169,65 +170,33 @@ no_gdt:
}
-static void
-gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
+static struct sw_displaytarget *
+gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
{
assert(0);
+ return NULL;
}
-static void
-gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys)
+static boolean
+gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
{
- FREE(winsys);
+ assert(0);
+ return FALSE;
}
-static struct pipe_screen *
-gdi_llvmpipe_screen_create(void)
+void
+gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC )
{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if(!winsys)
- goto no_winsys;
-
- winsys->destroy = gdi_llvmpipe_destroy;
- winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported;
- winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create;
- winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map;
- winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap;
- winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display;
- winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy;
-
- screen = llvmpipe_create_screen(winsys);
- if(!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
-}
-
-
-
-
-static void
-gdi_llvmpipe_present(struct pipe_screen *screen,
- struct pipe_surface *surface,
- HDC hDC)
-{
- struct llvmpipe_texture *texture;
- struct gdi_llvmpipe_displaytarget *gdt;
-
- texture = llvmpipe_texture(surface->texture);
- gdt = gdi_llvmpipe_displaytarget(texture->dt);
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
StretchDIBits(hDC,
0, 0, gdt->width, gdt->height,
@@ -235,38 +204,44 @@ gdi_llvmpipe_present(struct pipe_screen *screen,
gdt->data, &gdt->bmi, 0, SRCCOPY);
}
+static void
+gdi_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ /* nasty:
+ */
+ HDC hDC = (HDC)context_private;
-static const struct stw_winsys stw_winsys = {
- &gdi_llvmpipe_screen_create,
- &gdi_llvmpipe_present,
- NULL, /* get_adapter_luid */
- NULL, /* shared_surface_open */
- NULL, /* shared_surface_close */
- NULL /* compose */
-};
+ gdi_sw_display(winsys, dt, hDC);
+}
-BOOL WINAPI
-DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+static void
+gdi_sw_destroy(struct sw_winsys *winsys)
{
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- stw_init(&stw_winsys);
- stw_init_thread();
- break;
-
- case DLL_THREAD_ATTACH:
- stw_init_thread();
- break;
-
- case DLL_THREAD_DETACH:
- stw_cleanup_thread();
- break;
-
- case DLL_PROCESS_DETACH:
- stw_cleanup_thread();
- stw_cleanup();
- break;
- }
- return TRUE;
+ FREE(winsys);
+}
+
+struct sw_winsys *
+gdi_create_sw_winsys(void)
+{
+ static struct sw_winsys *winsys;
+
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if(!winsys)
+ return NULL;
+
+ winsys->destroy = gdi_sw_destroy;
+ winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
+ winsys->displaytarget_create = gdi_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
+ winsys->displaytarget_map = gdi_sw_displaytarget_map;
+ winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
+ winsys->displaytarget_display = gdi_sw_displaytarget_display;
+ winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy;
+
+ return winsys;
}
+
diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
new file mode 100644
index 00000000000..4bbcb47848b
--- /dev/null
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
@@ -0,0 +1,16 @@
+#ifndef GDI_SW_WINSYS_H
+#define GDI_SW_WINSYS_H
+
+#include <windows.h>
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/sw_winsys.h"
+
+void gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC );
+
+struct sw_winsys *
+gdi_create_sw_winsys(void);
+
+#endif
diff --git a/src/gallium/winsys/sw/null/Makefile b/src/gallium/winsys/sw/null/Makefile
new file mode 100644
index 00000000000..b1882b582e9
--- /dev/null
+++ b/src/gallium/winsys/sw/null/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = ws_null
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary
+
+C_SOURCES = \
+ null_sw_winsys.c
+
+include ../../../Makefile.template
+
+
diff --git a/src/gallium/winsys/sw/null/SConscript b/src/gallium/winsys/sw/null/SConscript
new file mode 100644
index 00000000000..21837dc60c2
--- /dev/null
+++ b/src/gallium/winsys/sw/null/SConscript
@@ -0,0 +1,21 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+])
+
+ws_null = env.ConvenienceLibrary(
+ target = 'ws_null',
+ source = [
+ 'null_sw_winsys.c',
+ ]
+)
+Export('ws_null')
diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c
new file mode 100644
index 00000000000..5027e57b303
--- /dev/null
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.c
@@ -0,0 +1,148 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Null software rasterizer winsys.
+ *
+ * There is no present support. Framebuffer data needs to be obtained via
+ * transfers.
+ *
+ * @author Jose Fonseca
+ */
+
+
+#include "pipe/p_format.h"
+#include "util/u_memory.h"
+#include "state_tracker/sw_winsys.h"
+#include "null_sw_winsys.h"
+
+
+static boolean
+null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ return FALSE;
+}
+
+
+static void *
+null_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags )
+{
+ assert(0);
+ return NULL;
+}
+
+
+static void
+null_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
+{
+ assert(0);
+}
+
+
+static void
+null_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
+{
+ assert(0);
+}
+
+
+static struct sw_displaytarget *
+null_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static struct sw_displaytarget *
+null_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static boolean
+null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
+static void
+null_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ assert(0);
+}
+
+
+static void
+null_sw_destroy(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+
+struct sw_winsys *
+null_sw_create(void)
+{
+ static struct sw_winsys *winsys;
+
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if (!winsys)
+ return NULL;
+
+ winsys->destroy = null_sw_destroy;
+ winsys->is_displaytarget_format_supported = null_sw_is_displaytarget_format_supported;
+ winsys->displaytarget_create = null_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = null_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = null_sw_displaytarget_get_handle;
+ winsys->displaytarget_map = null_sw_displaytarget_map;
+ winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
+ winsys->displaytarget_display = null_sw_displaytarget_display;
+ winsys->displaytarget_destroy = null_sw_displaytarget_destroy;
+
+ return winsys;
+}
diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.h b/src/gallium/winsys/sw/null/null_sw_winsys.h
new file mode 100644
index 00000000000..1986186febe
--- /dev/null
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef NULL_SW_WINSYS_H_
+#define NULL_SW_WINSYS_H_
+
+
+struct sw_winsys;
+
+
+struct sw_winsys *
+null_sw_create(void);
+
+
+#endif /* NULL_SW_WINSYS_H_ */
diff --git a/src/gallium/winsys/sw/wrapper/Makefile b/src/gallium/winsys/sw/wrapper/Makefile
new file mode 100644
index 00000000000..4771fbcf700
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = wsw
+
+C_SOURCES = wrapper_sw_winsys.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
new file mode 100644
index 00000000000..459b1c1e2a3
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -0,0 +1,282 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "wrapper_sw_winsys.h"
+
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/*
+ * This code wraps a pipe_screen and exposes a sw_winsys interface for use
+ * with software resterizers. This code is used by the DRM based winsys to
+ * allow access to the drm driver.
+ *
+ * We must borrow the whole stack because only the pipe screen knows how
+ * to decode the content of a buffer. Or how to create a buffer that
+ * can still be used by drivers using real hardware (as the case is
+ * with software st/xorg but hw st/dri).
+ *
+ * We also need a pipe context for the transfers.
+ */
+
+struct wrapper_sw_winsys
+{
+ struct sw_winsys base;
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+};
+
+struct wrapper_sw_displaytarget
+{
+ struct wrapper_sw_winsys *winsys;
+ struct pipe_texture *tex;
+ struct pipe_transfer *transfer;
+
+ unsigned width;
+ unsigned height;
+ unsigned map_count;
+ unsigned stride; /**< because we give stride at create */
+ void *ptr;
+};
+
+static INLINE struct wrapper_sw_winsys *
+wrapper_sw_winsys(struct sw_winsys *ws)
+{
+ return (struct wrapper_sw_winsys *)ws;
+}
+
+static INLINE struct wrapper_sw_displaytarget *
+wrapper_sw_displaytarget(struct sw_displaytarget *dt)
+{
+ return (struct wrapper_sw_displaytarget *)dt;
+}
+
+
+/*
+ * Functions
+ */
+
+
+static boolean
+wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
+{
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return FALSE;
+
+ *stride = tr->stride;
+ wdt->stride = tr->stride;
+
+ pipe->tex_transfer_destroy(pipe, tr);
+
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,
+ struct pipe_texture *tex, unsigned *stride)
+{
+ struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);
+ if (!wdt)
+ goto err_unref;
+
+ wdt->tex = tex;
+ wdt->winsys = wsw;
+
+ if (!wsw_dt_get_stride(wdt, stride))
+ goto err_free;
+
+ return (struct sw_displaytarget *)wdt;
+
+err_free:
+ FREE(wdt);
+err_unref:
+ pipe_texture_reference(&tex, NULL);
+ return NULL;
+}
+
+static struct sw_displaytarget *
+wsw_dt_create(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture templ;
+ struct pipe_texture *tex;
+
+ /*
+ * XXX Why don't we just get the template.
+ */
+ memset(&templ, 0, sizeof(templ));
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ /* XXX alignment: we can't do anything about this */
+
+ tex = wsw->screen->texture_create(wsw->screen, &templ);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static struct sw_displaytarget *
+wsw_dt_from_handle(struct sw_winsys *ws,
+ const struct pipe_texture *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_texture *tex;
+
+ tex = wsw->screen->texture_from_handle(wsw->screen, templ, whandle);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static void *
+wsw_dt_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_texture *tex = wdt->tex;
+ struct pipe_transfer *tr;
+ void *ptr;
+
+ if (!wdt->map_count) {
+
+ assert(!wdt->transfer);
+
+ tr = pipe->get_tex_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return NULL;
+
+ ptr = pipe->transfer_map(pipe, tr);
+ if (!ptr)
+ goto err;
+
+ wdt->transfer = tr;
+ wdt->ptr = ptr;
+
+ /* XXX Handle this case */
+ assert(tr->stride == wdt->stride);
+ }
+
+ wdt->map_count++;
+
+ return wdt->ptr;
+
+err:
+ pipe->tex_transfer_destroy(pipe, tr);
+ return NULL;
+}
+
+static void
+wsw_dt_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+
+ assert(wdt->transfer);
+
+ wdt->map_count--;
+
+ if (wdt->map_count)
+ return;
+
+ pipe->transfer_unmap(pipe, wdt->transfer);
+ pipe->tex_transfer_destroy(pipe, wdt->transfer);
+ wdt->transfer = NULL;
+}
+
+static void
+wsw_dt_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+
+ pipe_texture_reference(&wdt->tex, NULL);
+
+ FREE(wdt);
+}
+
+static void
+wsw_destroy(struct sw_winsys *ws)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+
+ wsw->pipe->destroy(wsw->pipe);
+ wsw->screen->destroy(wsw->screen);
+
+ FREE(wsw);
+}
+
+struct sw_winsys *
+wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
+{
+ struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);
+
+ wsw->base.displaytarget_create = wsw_dt_create;
+ wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
+ wsw->base.displaytarget_map = wsw_dt_map;
+ wsw->base.displaytarget_unmap = wsw_dt_unmap;
+ wsw->base.displaytarget_destroy = wsw_dt_destroy;
+ wsw->base.destroy = wsw_destroy;
+
+ wsw->screen = screen;
+ wsw->pipe = screen->context_create(screen, NULL);
+ if (!wsw->pipe)
+ goto err;
+
+ return &wsw->base;
+
+err:
+ FREE(wsw);
+ return NULL;
+}
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
new file mode 100644
index 00000000000..b5c25a3c50f
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
@@ -0,0 +1,35 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef WRAPPER_SW_WINSYS
+#define WRAPPER_SW_WINSYS
+
+struct sw_winsys;
+struct pipe_screen;
+
+struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/winsys/sw/xlib/Makefile b/src/gallium/winsys/sw/xlib/Makefile
new file mode 100644
index 00000000000..c6693899281
--- /dev/null
+++ b/src/gallium/winsys/sw/xlib/Makefile
@@ -0,0 +1,17 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = ws_xlib
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ $(X11_CFLAGS)
+
+C_SOURCES = \
+ xlib_sw_winsys.c
+
+include ../../../Makefile.template
+
+
diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript
new file mode 100644
index 00000000000..2af6153b4c7
--- /dev/null
+++ b/src/gallium/winsys/sw/xlib/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_xlib = env.ConvenienceLibrary(
+ target = 'ws_xlib',
+ source = [
+ 'xlib_sw_winsys.c',
+ ]
+ )
+ Export('ws_xlib')
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
index 6cebd4c2012..ad843b7def6 100644
--- a/src/gallium/winsys/xlib/xlib_llvmpipe.c
+++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
@@ -32,25 +32,21 @@
* Brian Paul
*/
-
-#if defined(GALLIUM_LLVMPIPE)
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "llvmpipe/lp_texture.h"
-#include "xlib.h"
+#include "state_tracker/xlib_sw_winsys.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
/**
* Subclass of pipe_buffer for Xlib winsys.
@@ -66,28 +62,38 @@ struct xm_displaytarget
void *data;
void *mapped;
+ Display *display;
+ Visual *visual;
XImage *tempImage;
-#ifdef USE_XSHM
- int shm;
+ GC gc;
+
+ /* This is the last drawable that this display target was presented
+ * against. May need to recreate gc, tempImage when this changes??
+ */
+ Drawable drawable;
+
XShmSegmentInfo shminfo;
-#endif
+ int shm;
};
/**
- * Subclass of llvmpipe_winsys for Xlib winsys
+ * Subclass of sw_winsys for Xlib winsys
*/
-struct xmesa_llvmpipe_winsys
+struct xlib_sw_winsys
{
- struct llvmpipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
+ struct sw_winsys base;
+
+
+
+ Display *display;
};
/** Cast wrapper */
static INLINE struct xm_displaytarget *
-xm_displaytarget( struct llvmpipe_displaytarget *dt )
+xm_displaytarget( struct sw_displaytarget *dt )
{
return (struct xm_displaytarget *)dt;
}
@@ -97,8 +103,6 @@ xm_displaytarget( struct llvmpipe_displaytarget *dt )
* X Shared Memory Image extension code
*/
-#ifdef USE_XSHM
-
static volatile int mesaXErrorFlag = 0;
/**
@@ -138,8 +142,8 @@ static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
*/
static void
-alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
- struct xmesa_buffer *xmb,
+alloc_shm_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
unsigned width, unsigned height)
{
/*
@@ -150,15 +154,15 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
*/
int (*old_handler)(Display *, XErrorEvent *);
- xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &xm_buffer->shminfo,
- width, height);
- if (xm_buffer->tempImage == NULL) {
- xm_buffer->shm = 0;
+ xm_dt->tempImage = XShmCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap,
+ NULL,
+ &xm_dt->shminfo,
+ width, height);
+ if (xm_dt->tempImage == NULL) {
+ xm_dt->shm = 0;
return;
}
@@ -166,27 +170,45 @@ alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
mesaXErrorFlag = 0;
old_handler = XSetErrorHandler(mesaHandleXError);
/* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
- XSync(xmb->xm_visual->display, False);
+ XShmAttach(xm_dt->display, &xm_dt->shminfo);
+ XSync(xm_dt->display, False);
if (mesaXErrorFlag) {
/* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
+ XFlush(xm_dt->display);
mesaXErrorFlag = 0;
- XDestroyImage(xm_buffer->tempImage);
- xm_buffer->tempImage = NULL;
- xm_buffer->shm = 0;
+ XDestroyImage(xm_dt->tempImage);
+ xm_dt->tempImage = NULL;
+ xm_dt->shm = 0;
(void) XSetErrorHandler(old_handler);
return;
}
- xm_buffer->shm = 1;
+ xm_dt->shm = 1;
}
-#endif /* USE_XSHM */
+
+static void
+alloc_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
+ unsigned width, unsigned height)
+{
+ if (xm_dt->shm) {
+ alloc_shm_ximage(xm_dt, xmb, width, height);
+ return;
+ }
+
+ xm_dt->tempImage = XCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap, 0,
+ NULL, width, height,
+ 8, 0);
+}
static boolean
-xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
enum pipe_format format )
{
/* TODO: check visuals or other sensible thing here */
@@ -195,8 +217,8 @@ xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
static void *
-xm_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+xm_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
unsigned flags)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
@@ -205,21 +227,20 @@ xm_displaytarget_map(struct llvmpipe_winsys *ws,
}
static void
-xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
+xm_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
xm_dt->mapped = NULL;
}
static void
-xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt)
+xm_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
{
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
if (xm_dt->data) {
-#ifdef USE_XSHM
if (xm_dt->shminfo.shmid >= 0) {
shmdt(xm_dt->shminfo.shmaddr);
shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
@@ -227,11 +248,17 @@ xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
xm_dt->shminfo.shmid = -1;
xm_dt->shminfo.shmaddr = (char *) -1;
}
- else
-#endif
+ else {
FREE(xm_dt->data);
+ }
}
+ if (xm_dt->tempImage)
+ XDestroyImage(xm_dt->tempImage);
+
+ if (xm_dt->gc)
+ XFreeGC(xm_dt->display, xm_dt->gc);
+
FREE(xm_dt);
}
@@ -241,13 +268,14 @@ xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
* by the XMesaBuffer.
*/
static void
-xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
- struct llvmpipe_displaytarget *dt)
+xlib_sw_display(struct xlib_drawable *xlib_drawable,
+ struct sw_displaytarget *dt)
{
- XImage *ximage;
- struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
static boolean no_swap = 0;
static boolean firsttime = 1;
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ Display *display = xm_dt->display;
+ XImage *ximage;
if (firsttime) {
no_swap = getenv("SP_NO_RAST") != NULL;
@@ -257,28 +285,45 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
if (no_swap)
return;
-#ifdef USE_XSHM
- if (xm_dt->shm)
- {
- if (xm_dt->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(xm_dt->format) == 1);
- assert(util_format_get_blockheight(xm_dt->format) == 1);
- alloc_shm_ximage(xm_dt, xm_buffer,
- xm_dt->stride / util_format_get_blocksize(xm_dt->format),
- xm_dt->height);
+ if (xm_dt->drawable != xlib_drawable->drawable) {
+ if (xm_dt->gc) {
+ XFreeGC( display, xm_dt->gc );
+ xm_dt->gc = NULL;
+ }
+
+ if (xm_dt->tempImage) {
+ XDestroyImage( xm_dt->tempImage );
+ xm_dt->tempImage = NULL;
}
+ xm_dt->drawable = xlib_drawable->drawable;
+ }
+
+ if (xm_dt->tempImage == NULL) {
+ assert(util_format_get_blockwidth(xm_dt->format) == 1);
+ assert(util_format_get_blockheight(xm_dt->format) == 1);
+ alloc_ximage(xm_dt, xlib_drawable,
+ xm_dt->stride / util_format_get_blocksize(xm_dt->format),
+ xm_dt->height);
+ if (!xm_dt->tempImage)
+ return;
+ }
+
+ if (xm_dt->gc == NULL) {
+ xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL );
+ XSetFunction( display, xm_dt->gc, GXcopy );
+ }
+
+ if (xm_dt->shm)
+ {
ximage = xm_dt->tempImage;
ximage->data = xm_dt->data;
/* _debug_printf("XSHM\n"); */
- XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
}
- else
-#endif
- {
+ else {
/* display image in Window */
ximage = xm_dt->tempImage;
ximage->data = xm_dt->data;
@@ -293,9 +338,11 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
ximage->bytes_per_line = xm_dt->stride;
/* _debug_printf("XPUT\n"); */
- XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
}
+
+ XFlush(xm_dt->display);
}
/**
@@ -303,30 +350,31 @@ xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
* by the XMesaBuffer.
*/
static void
-xm_displaytarget_display(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
+xm_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
void *context_private)
{
- XMesaContext xmctx = (XMesaContext) context_private;
- struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
- xm_llvmpipe_display(xm_buffer, dt);
+ struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
+ xlib_sw_display(xlib_drawable, dt);
}
-static struct llvmpipe_displaytarget *
-xm_displaytarget_create(struct llvmpipe_winsys *winsys,
+static struct sw_displaytarget *
+xm_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
enum pipe_format format,
unsigned width, unsigned height,
unsigned alignment,
unsigned *stride)
{
- struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ struct xm_displaytarget *xm_dt;
unsigned nblocksy, size;
xm_dt = CALLOC_STRUCT(xm_displaytarget);
if(!xm_dt)
goto no_xm_dt;
+ xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display;
xm_dt->format = format;
xm_dt->width = width;
xm_dt->height = height;
@@ -335,7 +383,6 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
xm_dt->stride = align(util_format_get_stride(format, width), alignment);
size = xm_dt->stride * nblocksy;
-#ifdef USE_XSHM
if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
{
xm_dt->shminfo.shmid = -1;
@@ -346,7 +393,6 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
if(!xm_dt->data)
goto no_data;
}
-#endif
if(!xm_dt->data) {
xm_dt->data = align_malloc(size, alignment);
@@ -355,7 +401,7 @@ xm_displaytarget_create(struct llvmpipe_winsys *winsys,
}
*stride = xm_dt->stride;
- return (struct llvmpipe_displaytarget *)xm_dt;
+ return (struct sw_displaytarget *)xm_dt;
no_data:
FREE(xm_dt);
@@ -364,27 +410,51 @@ no_xm_dt:
}
+static struct sw_displaytarget *
+xm_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_texture *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+xm_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
static void
-xm_destroy( struct llvmpipe_winsys *ws )
+xm_destroy( struct sw_winsys *ws )
{
FREE(ws);
}
-static struct llvmpipe_winsys *
-xlib_create_llvmpipe_winsys( void )
+struct sw_winsys *
+xlib_create_sw_winsys( Display *display )
{
- struct xmesa_llvmpipe_winsys *ws;
+ struct xlib_sw_winsys *ws;
- ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
+ ws = CALLOC_STRUCT(xlib_sw_winsys);
if (!ws)
return NULL;
+ ws->display = display;
ws->base.destroy = xm_destroy;
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
ws->base.displaytarget_map = xm_displaytarget_map;
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
ws->base.displaytarget_destroy = xm_displaytarget_destroy;
@@ -394,49 +464,3 @@ xlib_create_llvmpipe_winsys( void )
return &ws->base;
}
-
-static struct pipe_screen *
-xlib_create_llvmpipe_screen( void )
-{
- struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_llvmpipe_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = llvmpipe_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-static void
-xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
- struct pipe_surface *surf)
-{
- struct llvmpipe_texture *texture = llvmpipe_texture(surf->texture);
-
- assert(texture->dt);
- if (texture->dt)
- xm_llvmpipe_display(xm_buffer, texture->dt);
-}
-
-
-struct xm_driver xlib_llvmpipe_driver =
-{
- .create_pipe_screen = xlib_create_llvmpipe_screen,
- .display_surface = xlib_llvmpipe_display_surface
-};
-
-
-
-#endif /* GALLIUM_LLVMPIPE */
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c
deleted file mode 100644
index 67617a470d6..00000000000
--- a/src/gallium/winsys/xlib/xlib.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- */
-
-#include "xlib.h"
-#include "xm_winsys.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-/* Todo, replace all this with callback-structs provided by the
- * individual implementations.
- */
-
-enum mode {
- MODE_CELL,
- MODE_LLVMPIPE,
- MODE_SOFTPIPE
-};
-
-/* advertise OpenGL support */
-PUBLIC const int st_api_OpenGL = 1;
-
-static enum mode get_mode()
-{
-#ifdef GALLIUM_CELL
- if (!getenv("GALLIUM_NOCELL"))
- return MODE_CELL;
-#endif
-
-#if defined(GALLIUM_LLVMPIPE)
- return MODE_LLVMPIPE;
-#else
- return MODE_SOFTPIPE;
-#endif
-}
-
-static void _init( void ) __attribute__((constructor));
-
-static void _init( void )
-{
- enum mode xlib_mode = get_mode();
-
- switch (xlib_mode) {
- case MODE_CELL:
-#if defined(GALLIUM_CELL)
- xmesa_set_driver( &xlib_cell_driver );
-#endif
- break;
- case MODE_LLVMPIPE:
-#if defined(GALLIUM_LLVMPIPE)
- xmesa_set_driver( &xlib_llvmpipe_driver );
-#endif
- break;
- case MODE_SOFTPIPE:
-#if defined(GALLIUM_SOFTPIPE)
- xmesa_set_driver( &xlib_softpipe_driver );
-#endif
- break;
- default:
- assert(0);
- break;
- }
-}
-
-
-/***********************************************************************
- *
- * Butt-ugly hack to convince the linker not to throw away public GL
- * symbols (they are all referenced from getprocaddress, I guess).
- */
-extern void (*linker_foo(const unsigned char *procName))();
-extern void (*glXGetProcAddress(const unsigned char *procName))();
-
-extern void (*linker_foo(const unsigned char *procName))()
-{
- return glXGetProcAddress(procName);
-}
-
-
-/**
- * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
- * libglapi.a. We need to define them here.
- */
-#ifdef GLX_INDIRECT_RENDERING
-
-#define GL_GLEXT_PROTOTYPES
-#include "GL/gl.h"
-#include "glapi/glapi.h"
-#include "glapi/glapitable.h"
-#include "glapi/glapidispatch.h"
-
-#if defined(USE_MGL_NAMESPACE)
-#define NAME(func) mgl##func
-#else
-#define NAME(func) gl##func
-#endif
-
-#define DISPATCH(FUNC, ARGS, MESSAGE) \
- CALL_ ## FUNC(GET_DISPATCH(), ARGS);
-
-#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \
- return CALL_ ## FUNC(GET_DISPATCH(), ARGS);
-
-/* skip normal ones */
-#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
-#include "glapi/glapitemp.h"
-
-#endif /* GLX_INDIRECT_RENDERING */
diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h
deleted file mode 100644
index 8e091d0c084..00000000000
--- a/src/gallium/winsys/xlib/xlib.h
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#ifndef XLIB_H
-#define XLIB_H
-
-#include "pipe/p_compiler.h"
-#include "xm_winsys.h"
-
-extern struct xm_driver xlib_softpipe_driver;
-extern struct xm_driver xlib_llvmpipe_driver;
-extern struct xm_driver xlib_cell_driver;
-
-
-#endif
diff --git a/src/gallium/winsys/xlib/xlib_brw_context.c b/src/gallium/winsys/xlib/xlib_brw_context.c
deleted file mode 100644
index 22bf41a46f7..00000000000
--- a/src/gallium/winsys/xlib/xlib_brw_context.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-
-/* #include "glxheader.h" */
-/* #include "xmesaP.h" */
-
-#include "util/u_simple_screen.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "i965simple/brw_winsys.h"
-#include "xlib_brw_aub.h"
-#include "xlib_brw.h"
-
-
-
-
-#define XBCWS_BATCHBUFFER_SIZE 1024
-
-
-/* The backend to the brw driver (ie struct brw_winsys) is actually a
- * per-context entity.
- */
-struct xlib_brw_context_winsys {
- struct brw_winsys brw_context_winsys; /**< batch buffer funcs */
- struct aub_context *aub;
-
- struct pipe_winsys *pipe_winsys;
-
- unsigned batch_data[XBCWS_BATCHBUFFER_SIZE];
- unsigned batch_nr;
- unsigned batch_size;
- unsigned batch_alloc;
-};
-
-
-/* Turn a brw_winsys into an xlib_brw_context_winsys:
- */
-static inline struct xlib_brw_context_winsys *
-xlib_brw_context_winsys( struct brw_winsys *sws )
-{
- return (struct xlib_brw_context_winsys *)sws;
-}
-
-
-/* Simple batchbuffer interface:
- */
-
-static unsigned *xbcws_batch_start( struct brw_winsys *sws,
- unsigned dwords,
- unsigned relocs )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- if (xbcws->batch_size < xbcws->batch_nr + dwords)
- return NULL;
-
- xbcws->batch_alloc = xbcws->batch_nr + dwords;
- return (void *)1; /* not a valid pointer! */
-}
-
-static void xbcws_batch_dword( struct brw_winsys *sws,
- unsigned dword )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr < xbcws->batch_alloc);
- xbcws->batch_data[xbcws->batch_nr++] = dword;
-}
-
-static void xbcws_batch_reloc( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags,
- unsigned delta )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr < xbcws->batch_alloc);
- xbcws->batch_data[xbcws->batch_nr++] =
- ( xlib_brw_get_buffer_offset( NULL, buf, access_flags ) +
- delta );
-}
-
-static void xbcws_batch_end( struct brw_winsys *sws )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- assert(xbcws->batch_nr <= xbcws->batch_alloc);
- xbcws->batch_alloc = 0;
-}
-
-static void xbcws_batch_flush( struct brw_winsys *sws,
- struct pipe_fence_handle **fence )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
- assert(xbcws->batch_nr <= xbcws->batch_size);
-
- if (xbcws->batch_nr) {
- xlib_brw_commands_aub( xbcws->pipe_winsys,
- xbcws->batch_data,
- xbcws->batch_nr );
- }
-
- xbcws->batch_nr = 0;
-}
-
-
-
-/* Really a per-device function, just pass through:
- */
-static unsigned xbcws_get_buffer_offset( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- return xlib_brw_get_buffer_offset( xbcws->pipe_winsys,
- buf,
- access_flags );
-}
-
-
-/* Really a per-device function, just pass through:
- */
-static void xbcws_buffer_subdata_typed( struct brw_winsys *sws,
- struct pipe_buffer *buf,
- unsigned long offset,
- unsigned long size,
- const void *data,
- unsigned data_type )
-{
- struct xlib_brw_context_winsys *xbcws = xlib_brw_context_winsys(sws);
-
- xlib_brw_buffer_subdata_typed( xbcws->pipe_winsys,
- buf,
- offset,
- size,
- data,
- data_type );
-}
-
-
-/**
- * Create i965 hardware rendering context, but plugged into a
- * dump-to-aubfile backend.
- */
-struct pipe_context *
-xlib_create_brw_context( struct pipe_screen *screen,
- void *unused )
-{
- struct xlib_brw_context_winsys *xbcws = CALLOC_STRUCT( xlib_brw_context_winsys );
-
- /* Fill in this struct with callbacks that i965simple will need to
- * communicate with the window system, buffer manager, etc.
- */
- xbcws->brw_context_winsys.batch_start = xbcws_batch_start;
- xbcws->brw_context_winsys.batch_dword = xbcws_batch_dword;
- xbcws->brw_context_winsys.batch_reloc = xbcws_batch_reloc;
- xbcws->brw_context_winsys.batch_end = xbcws_batch_end;
- xbcws->brw_context_winsys.batch_flush = xbcws_batch_flush;
- xbcws->brw_context_winsys.buffer_subdata_typed = xbcws_buffer_subdata_typed;
- xbcws->brw_context_winsys.get_buffer_offset = xbcws_get_buffer_offset;
-
- xbcws->pipe_winsys = screen->winsys; /* redundant */
-
- xbcws->batch_size = XBCWS_BATCHBUFFER_SIZE;
-
- /* Create the i965simple context:
- */
-#ifdef GALLIUM_CELL
- return NULL;
-#else
- return brw_create( screen,
- &xbcws->brw_context_winsys,
- 0 );
-#endif
-}
diff --git a/src/gallium/winsys/xlib/xlib_cell.c b/src/gallium/winsys/xlib/xlib_cell.c
deleted file mode 100644
index 1dc9e8fa11f..00000000000
--- a/src/gallium/winsys/xlib/xlib_cell.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-#include "xlib.h"
-
-#ifdef GALLIUM_CELL
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "cell/ppu/cell_context.h"
-#include "cell/ppu/cell_screen.h"
-#include "cell/ppu/cell_winsys.h"
-#include "cell/ppu/cell_texture.h"
-
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-
- XImage *tempImage;
- int shm;
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
- struct pipe_winsys base;
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
- return (struct xm_buffer *)buf;
-}
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = xm_buf->data;
- return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(/*struct pipe_winsys *pws,*/
- struct pipe_buffer *buf)
-{
- struct xm_buffer *oldBuf = xm_buffer(buf);
-
- if (oldBuf) {
- if (oldBuf->data) {
- if (!oldBuf->userBuffer) {
- align_free(oldBuf->data);
- }
-
- oldBuf->data = NULL;
- }
- free(oldBuf);
- }
-}
-
-
-/**
- * For Cell. Basically, rearrange the pixels/quads from this layout:
- * +--+--+--+--+
- * |p0|p1|p2|p3|....
- * +--+--+--+--+
- *
- * to this layout:
- * +--+--+
- * |p0|p1|....
- * +--+--+
- * |p2|p3|
- * +--+--+
- */
-static void
-twiddle_tile(const uint *tileIn, uint *tileOut)
-{
- int y, x;
-
- for (y = 0; y < TILE_SIZE; y+=2) {
- for (x = 0; x < TILE_SIZE; x+=2) {
- int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
- tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
- tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
- tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
- tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
- }
- }
-}
-
-
-
-/**
- * Display a surface that's in a tiled configuration. That is, all the
- * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory.
- */
-static void
-xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf)
-{
- XImage *ximage;
- struct xm_buffer *xm_buf = xm_buffer(
- cell_texture(surf->texture)->buffer);
- const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
- uint x, y;
-
- ximage = b->tempImage;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = TILE_SIZE;
- ximage->height = TILE_SIZE;
- ximage->bytes_per_line = TILE_SIZE * 4;
-
- for (y = 0; y < surf->height; y += TILE_SIZE) {
- for (x = 0; x < surf->width; x += TILE_SIZE) {
- uint tmpTile[TILE_SIZE * TILE_SIZE];
- int tx = x / TILE_SIZE;
- int ty = y / TILE_SIZE;
- int offset = ty * tilesPerRow + tx;
- int w = TILE_SIZE;
- int h = TILE_SIZE;
-
- if (y + h > surf->height)
- h = surf->height - y;
- if (x + w > surf->width)
- w = surf->width - x;
-
- /* offset in pixels */
- offset *= TILE_SIZE * TILE_SIZE;
-
- /* twiddle from ximage buffer to temp tile */
- twiddle_tile((uint *) xm_buf->data + offset, tmpTile);
- /* display temp tile data */
- ximage->data = (char *) tmpTile;
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, x, y, w, h);
- }
- }
-}
-
-
-
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *surf,
- void *context_private)
-{
- /*
- * The front color buffer is actually just another XImage buffer.
- * This function copies that XImage to the actual X Window.
- */
- XMesaContext xmctx = (XMesaContext) context_private;
- if (xmctx)
- xlib_cell_display_surface(xmctx->xm_buffer, surf);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
- return "Xlib/Cell";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
-
- if (buffer->data == NULL) {
- buffer->shm = 0;
-
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
- }
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
- buffer->shm = 0;
-
- return &buffer->base;
-}
-
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- /* XXX a bit of a hack */
- *stride * align(nblocksy, TILE_SIZE));
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_cell_winsys( void )
-{
- static struct xmesa_pipe_winsys *ws = NULL;
-
- if (!ws) {
- ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->base.buffer_create = xm_buffer_create;
- ws->base.user_buffer_create = xm_user_buffer_create;
- ws->base.buffer_map = xm_buffer_map;
- ws->base.buffer_unmap = xm_buffer_unmap;
- ws->base.buffer_destroy = xm_buffer_destroy;
-
- ws->base.surface_buffer_create = xm_surface_buffer_create;
-
- ws->base.fence_reference = xm_fence_reference;
- ws->base.fence_signalled = xm_fence_signalled;
- ws->base.fence_finish = xm_fence_finish;
-
- ws->base.flush_frontbuffer = xm_flush_frontbuffer;
- ws->base.get_name = xm_get_name;
- }
-
- return &ws->base;
-}
-
-
-static struct pipe_screen *
-xlib_create_cell_screen( void )
-{
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_cell_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = cell_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-
-struct xm_driver xlib_cell_driver =
-{
- .create_pipe_screen = xlib_create_cell_screen,
- .display_surface = xlib_cell_display_surface,
-};
-
-#else
-
-struct xm_driver xlib_cell_driver =
-{
- .create_pipe_screen = NULL,
- .display_surface = NULL,
-};
-
-#endif
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
deleted file mode 100644
index 716338aef47..00000000000
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/*
- * Authors:
- * Keith Whitwell
- * Brian Paul
- */
-
-
-#include "xm_api.h"
-
-#undef ASSERT
-#undef Elements
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
-
-#include "xlib.h"
-
-/**
- * Subclass of pipe_buffer for Xlib winsys.
- * Low-level OS/window system memory buffer
- */
-struct xm_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-
- XImage *tempImage;
-#ifdef USE_XSHM
- boolean shm; /** Is this a shared memory buffer? */
- XShmSegmentInfo shminfo;
-#endif
-};
-
-
-/**
- * Subclass of pipe_winsys for Xlib winsys
- */
-struct xmesa_pipe_winsys
-{
- struct pipe_winsys base;
-/* struct xmesa_visual *xm_visual; */
-};
-
-
-
-/** Cast wrapper */
-static INLINE struct xm_buffer *
-xm_buffer( struct pipe_buffer *buf )
-{
- return (struct xm_buffer *)buf;
-}
-
-
-/**
- * X Shared Memory Image extension code
- */
-
-#ifdef USE_XSHM
-
-static volatile int mesaXErrorFlag = 0;
-
-/**
- * Catches potential Xlib errors.
- */
-static int
-mesaHandleXError(Display *dpy, XErrorEvent *event)
-{
- (void) dpy;
- (void) event;
- mesaXErrorFlag = 1;
- return 0;
-}
-
-
-static char *alloc_shm(struct xm_buffer *buf, unsigned size)
-{
- XShmSegmentInfo *const shminfo = & buf->shminfo;
-
- shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
- if (shminfo->shmid < 0) {
- return NULL;
- }
-
- shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
- if (shminfo->shmaddr == (char *) -1) {
- shmctl(shminfo->shmid, IPC_RMID, 0);
- return NULL;
- }
-
- shminfo->readOnly = False;
- return shminfo->shmaddr;
-}
-
-
-/**
- * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
- */
-static void
-alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
- unsigned width, unsigned height)
-{
- /*
- * We have to do a _lot_ of error checking here to be sure we can
- * really use the XSHM extension. It seems different servers trigger
- * errors at different points if the extension won't work. Therefore
- * we have to be very careful...
- */
- int (*old_handler)(Display *, XErrorEvent *);
-
- b->tempImage = XShmCreateImage(xmb->xm_visual->display,
- xmb->xm_visual->visinfo->visual,
- xmb->xm_visual->visinfo->depth,
- ZPixmap,
- NULL,
- &b->shminfo,
- width, height);
- if (b->tempImage == NULL) {
- b->shm = FALSE;
- return;
- }
-
-
- mesaXErrorFlag = 0;
- old_handler = XSetErrorHandler(mesaHandleXError);
- /* This may trigger the X protocol error we're ready to catch: */
- XShmAttach(xmb->xm_visual->display, &b->shminfo);
- XSync(xmb->xm_visual->display, False);
-
- if (mesaXErrorFlag) {
- /* we are on a remote display, this error is normal, don't print it */
- XFlush(xmb->xm_visual->display);
- mesaXErrorFlag = 0;
- XDestroyImage(b->tempImage);
- b->tempImage = NULL;
- b->shm = FALSE;
- (void) XSetErrorHandler(old_handler);
- return;
- }
-
- b->shm = TRUE;
-}
-
-#endif /* USE_XSHM */
-
-
-
-/* Most callbacks map direcly onto dri_bufmgr operations:
- */
-static void *
-xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = xm_buf->data;
- return xm_buf->mapped;
-}
-
-static void
-xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct xm_buffer *xm_buf = xm_buffer(buf);
- xm_buf->mapped = NULL;
-}
-
-static void
-xm_buffer_destroy(struct pipe_buffer *buf)
-{
- struct xm_buffer *oldBuf = xm_buffer(buf);
-
- /*
- * Note oldBuf->data may point to one of three things:
- * 1. XShm shared memory image data
- * 2. User-provided (wrapped) memory, see xm_user_buffer_create()
- * 3. Regular, malloc'd memory
- * We need to be careful with freeing that data now.
- */
-
- if (oldBuf->data) {
-#ifdef USE_XSHM
- if (oldBuf->shminfo.shmid >= 0) {
- shmdt(oldBuf->shminfo.shmaddr);
- shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
-
- oldBuf->shminfo.shmid = -1;
- oldBuf->shminfo.shmaddr = (char *) -1;
- }
-
- if (oldBuf->shm) {
- oldBuf->data = NULL;
- }
-
- if (oldBuf->tempImage) {
- XDestroyImage(oldBuf->tempImage);
- oldBuf->tempImage = NULL;
- }
-#endif
-
- if (oldBuf->data && !oldBuf->userBuffer) {
- /* this was regular malloc'd memory */
- align_free(oldBuf->data);
- }
-
- oldBuf->data = NULL;
- }
-
- free(oldBuf);
-}
-
-
-/**
- * Display/copy the image in the surface into the X window specified
- * by the XMesaBuffer.
- */
-static void
-xlib_softpipe_display_surface(struct xmesa_buffer *b,
- struct pipe_surface *surf)
-{
- XImage *ximage;
- struct softpipe_texture *spt = softpipe_texture(surf->texture);
- struct xm_buffer *xm_buf = xm_buffer(spt->buffer);
- static boolean no_swap = 0;
- static boolean firsttime = 1;
-
- if (firsttime) {
- no_swap = getenv("SP_NO_RAST") != NULL;
- firsttime = 0;
- }
-
- if (no_swap)
- return;
-
-#ifdef USE_XSHM
- if (xm_buf->shm)
- {
- if (xm_buf->tempImage == NULL)
- {
- assert(util_format_get_blockwidth(surf->texture->format) == 1);
- assert(util_format_get_blockheight(surf->texture->format) == 1);
- alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
- util_format_get_blocksize(surf->texture->format), surf->height);
- }
-
- ximage = xm_buf->tempImage;
- ximage->data = xm_buf->data;
-
- /* _debug_printf("XSHM\n"); */
- XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height, False);
- }
- else
-#endif
- {
- /* display image in Window */
- ximage = b->tempImage;
- ximage->data = xm_buf->data;
-
- /* check that the XImage has been previously initialized */
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- /* update XImage's fields */
- ximage->width = surf->width;
- ximage->height = surf->height;
- ximage->bytes_per_line = spt->stride[surf->level];
-
- /* _debug_printf("XPUT\n"); */
- XPutImage(b->xm_visual->display, b->drawable, b->gc,
- ximage, 0, 0, 0, 0, surf->width, surf->height);
- }
-}
-
-
-static void
-xm_flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *surf,
- void *context_private)
-{
- /*
- * The front color buffer is actually just another XImage buffer.
- * This function copies that XImage to the actual X Window.
- */
- XMesaContext xmctx = (XMesaContext) context_private;
- xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
- xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
-}
-
-
-
-static const char *
-xm_get_name(struct pipe_winsys *pws)
-{
- return "Xlib";
-}
-
-
-static struct pipe_buffer *
-xm_buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-xm_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy, size;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
- size = *stride * nblocksy;
-
-#ifdef USE_XSHM
- if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
- {
- struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
- buffer->userBuffer = FALSE;
- buffer->shminfo.shmid = -1;
- buffer->shminfo.shmaddr = (char *) -1;
- buffer->shm = TRUE;
-
- buffer->data = alloc_shm(buffer, size);
- if (!buffer->data)
- goto out;
-
- return &buffer->base;
-
- out:
- if (buffer)
- FREE(buffer);
- }
-#endif
-
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- size);
-}
-
-
-/*
- * Fence functions - basically nothing to do, as we don't create any actual
- * fence objects.
- */
-
-static void
-xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-
-static struct pipe_winsys *
-xlib_create_softpipe_winsys( void )
-{
- static struct xmesa_pipe_winsys *ws = NULL;
-
- if (!ws) {
- ws = CALLOC_STRUCT(xmesa_pipe_winsys);
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->base.buffer_create = xm_buffer_create;
- ws->base.user_buffer_create = xm_user_buffer_create;
- ws->base.buffer_map = xm_buffer_map;
- ws->base.buffer_unmap = xm_buffer_unmap;
- ws->base.buffer_destroy = xm_buffer_destroy;
-
- ws->base.surface_buffer_create = xm_surface_buffer_create;
-
- ws->base.fence_reference = xm_fence_reference;
- ws->base.fence_signalled = xm_fence_signalled;
- ws->base.fence_finish = xm_fence_finish;
-
- ws->base.flush_frontbuffer = xm_flush_frontbuffer;
- ws->base.get_name = xm_get_name;
- }
-
- return &ws->base;
-}
-
-
-static struct pipe_screen *
-xlib_create_softpipe_screen( void )
-{
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = xlib_create_softpipe_winsys();
- if (winsys == NULL)
- return NULL;
-
- screen = softpipe_create_screen(winsys);
- if (screen == NULL)
- goto fail;
-
- return screen;
-
-fail:
- if (winsys)
- winsys->destroy( winsys );
-
- return NULL;
-}
-
-
-struct xm_driver xlib_softpipe_driver =
-{
- .create_pipe_screen = xlib_create_softpipe_screen,
- .display_surface = xlib_softpipe_display_surface
-};
-
-
-
diff --git a/src/gallium/winsys/xlib/xmesa.h b/src/gallium/winsys/xlib/xmesa.h
deleted file mode 100644
index 98139af8336..00000000000
--- a/src/gallium/winsys/xlib/xmesa.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * Mesa/X11 interface. This header file serves as the documentation for
- * the Mesa/X11 interface functions.
- *
- * Note: this interface isn't intended for user programs. It's primarily
- * just for implementing the pseudo-GLX interface.
- */
-
-
-/* Sample Usage:
-
-In addition to the usual X calls to select a visual, create a colormap
-and create a window, you must do the following to use the X/Mesa interface:
-
-1. Call XMesaCreateVisual() to make an XMesaVisual from an XVisualInfo.
-
-2. Call XMesaCreateContext() to create an X/Mesa rendering context, given
- the XMesaVisual.
-
-3. Call XMesaCreateWindowBuffer() to create an XMesaBuffer from an X window
- and XMesaVisual.
-
-4. Call XMesaMakeCurrent() to bind the XMesaBuffer to an XMesaContext and
- to make the context the current one.
-
-5. Make gl* calls to render your graphics.
-
-6. Use XMesaSwapBuffers() when double buffering to swap front/back buffers.
-
-7. Before the X window is destroyed, call XMesaDestroyBuffer().
-
-8. Before exiting, call XMesaDestroyVisual and XMesaDestroyContext.
-
-*/
-
-
-
-
-#ifndef XMESA_H
-#define XMESA_H
-
-#ifdef __VMS
-#include <GL/vms_x_fix.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef XFree86Server
-#include "xmesa_xf86.h"
-#else
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include "xmesa_x.h"
-#endif
-#include "GL/gl.h"
-
-#ifdef AMIWIN
-#include <pragmas/xlib_pragmas.h>
-extern struct Library *XLibBase;
-#endif
-
-
-#define XMESA_MAJOR_VERSION 6
-#define XMESA_MINOR_VERSION 3
-
-
-
-/*
- * Values passed to XMesaGetString:
- */
-#define XMESA_VERSION 1
-#define XMESA_EXTENSIONS 2
-
-
-/*
- * Values passed to XMesaSetFXmode:
- */
-#define XMESA_FX_WINDOW 1
-#define XMESA_FX_FULLSCREEN 2
-
-
-
-typedef struct xmesa_context *XMesaContext;
-
-typedef struct xmesa_visual *XMesaVisual;
-
-typedef struct xmesa_buffer *XMesaBuffer;
-
-
-
-/*
- * Create a new X/Mesa visual.
- * Input: display - X11 display
- * visinfo - an XVisualInfo pointer
- * rgb_flag - GL_TRUE = RGB mode,
- * GL_FALSE = color index mode
- * alpha_flag - alpha buffer requested?
- * db_flag - GL_TRUE = double-buffered,
- * GL_FALSE = single buffered
- * stereo_flag - stereo visual?
- * ximage_flag - GL_TRUE = use an XImage for back buffer,
- * GL_FALSE = use an off-screen pixmap for back buffer
- * depth_size - requested bits/depth values, or zero
- * stencil_size - requested bits/stencil values, or zero
- * accum_red_size - requested bits/red accum values, or zero
- * accum_green_size - requested bits/green accum values, or zero
- * accum_blue_size - requested bits/blue accum values, or zero
- * accum_alpha_size - requested bits/alpha accum values, or zero
- * num_samples - number of samples/pixel if multisampling, or zero
- * level - visual level, usually 0
- * visualCaveat - ala the GLX extension, usually GLX_NONE_EXT
- * Return; a new XMesaVisual or 0 if error.
- */
-extern XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
- XMesaVisualInfo visinfo,
- GLboolean rgb_flag,
- GLboolean alpha_flag,
- GLboolean db_flag,
- GLboolean stereo_flag,
- GLboolean ximage_flag,
- GLint depth_size,
- GLint stencil_size,
- GLint accum_red_size,
- GLint accum_green_size,
- GLint accum_blue_size,
- GLint accum_alpha_size,
- GLint num_samples,
- GLint level,
- GLint visualCaveat );
-
-/*
- * Destroy an XMesaVisual, but not the associated XVisualInfo.
- */
-extern void XMesaDestroyVisual( XMesaVisual v );
-
-
-
-/*
- * Create a new XMesaContext for rendering into an X11 window.
- *
- * Input: visual - an XMesaVisual
- * share_list - another XMesaContext with which to share display
- * lists or NULL if no sharing is wanted.
- * Return: an XMesaContext or NULL if error.
- */
-extern XMesaContext XMesaCreateContext( XMesaVisual v,
- XMesaContext share_list );
-
-
-/*
- * Destroy a rendering context as returned by XMesaCreateContext()
- */
-extern void XMesaDestroyContext( XMesaContext c );
-
-
-#ifdef XFree86Server
-/*
- * These are the extra routines required for integration with XFree86.
- * None of these routines should be user visible. -KEM
- */
-extern GLboolean XMesaForceCurrent( XMesaContext c );
-
-extern GLboolean XMesaLoseCurrent( XMesaContext c );
-
-extern GLboolean XMesaCopyContext( XMesaContext src,
- XMesaContext dst,
- GLuint mask );
-#endif /* XFree86Server */
-
-
-/*
- * Create an XMesaBuffer from an X window.
- */
-extern XMesaBuffer XMesaCreateWindowBuffer( XMesaVisual v, XMesaWindow w );
-
-
-/*
- * Create an XMesaBuffer from an X pixmap.
- */
-extern XMesaBuffer XMesaCreatePixmapBuffer( XMesaVisual v,
- XMesaPixmap p,
- XMesaColormap cmap );
-
-
-/*
- * Destroy an XMesaBuffer, but not the corresponding window or pixmap.
- */
-extern void XMesaDestroyBuffer( XMesaBuffer b );
-
-
-/*
- * Return the XMesaBuffer handle which corresponds to an X drawable, if any.
- *
- * New in Mesa 2.3.
- */
-extern XMesaBuffer XMesaFindBuffer( XMesaDisplay *dpy,
- XMesaDrawable d );
-
-
-
-/*
- * Bind a buffer to a context and make the context the current one.
- */
-extern GLboolean XMesaMakeCurrent( XMesaContext c,
- XMesaBuffer b );
-
-
-/*
- * Bind two buffers (read and draw) to a context and make the
- * context the current one.
- * New in Mesa 3.3
- */
-extern GLboolean XMesaMakeCurrent2( XMesaContext c,
- XMesaBuffer drawBuffer,
- XMesaBuffer readBuffer );
-
-
-/*
- * Unbind the current context from its buffer.
- */
-extern GLboolean XMesaUnbindContext( XMesaContext c );
-
-
-/*
- * Return a handle to the current context.
- */
-extern XMesaContext XMesaGetCurrentContext( void );
-
-
-/*
- * Return handle to the current (draw) buffer.
- */
-extern XMesaBuffer XMesaGetCurrentBuffer( void );
-
-
-/*
- * Return handle to the current read buffer.
- * New in Mesa 3.3
- */
-extern XMesaBuffer XMesaGetCurrentReadBuffer( void );
-
-
-/*
- * Swap the front and back buffers for the given buffer. No action is
- * taken if the buffer is not double buffered.
- */
-extern void XMesaSwapBuffers( XMesaBuffer b );
-
-
-/*
- * Copy a sub-region of the back buffer to the front buffer.
- *
- * New in Mesa 2.6
- */
-extern void XMesaCopySubBuffer( XMesaBuffer b,
- int x,
- int y,
- int width,
- int height );
-
-
-/*
- * Return a pointer to the the Pixmap or XImage being used as the back
- * color buffer of an XMesaBuffer. This function is a way to get "under
- * the hood" of X/Mesa so one can manipulate the back buffer directly.
- * Input: b - the XMesaBuffer
- * Output: pixmap - pointer to back buffer's Pixmap, or 0
- * ximage - pointer to back buffer's XImage, or NULL
- * Return: GL_TRUE = context is double buffered
- * GL_FALSE = context is single buffered
- */
-extern GLboolean XMesaGetBackBuffer( XMesaBuffer b,
- XMesaPixmap *pixmap,
- XMesaImage **ximage );
-
-
-
-/*
- * Return the depth buffer associated with an XMesaBuffer.
- * Input: b - the XMesa buffer handle
- * Output: width, height - size of buffer in pixels
- * bytesPerValue - bytes per depth value (2 or 4)
- * buffer - pointer to depth buffer values
- * Return: GL_TRUE or GL_FALSE to indicate success or failure.
- *
- * New in Mesa 2.4.
- */
-extern GLboolean XMesaGetDepthBuffer( XMesaBuffer b,
- GLint *width,
- GLint *height,
- GLint *bytesPerValue,
- void **buffer );
-
-
-
-/*
- * Flush/sync a context
- */
-extern void XMesaFlush( XMesaContext c );
-
-
-
-/*
- * Get an X/Mesa-specific string.
- * Input: name - either XMESA_VERSION or XMESA_EXTENSIONS
- */
-extern const char *XMesaGetString( XMesaContext c, int name );
-
-
-
-/*
- * Scan for XMesaBuffers whose window/pixmap has been destroyed, then free
- * any memory used by that buffer.
- *
- * New in Mesa 2.3.
- */
-extern void XMesaGarbageCollect( void );
-
-
-
-/*
- * Return a dithered pixel value.
- * Input: c - XMesaContext
- * x, y - window coordinate
- * red, green, blue, alpha - color components in [0,1]
- * Return: pixel value
- *
- * New in Mesa 2.3.
- */
-extern unsigned long XMesaDitherColor( XMesaContext xmesa,
- GLint x,
- GLint y,
- GLfloat red,
- GLfloat green,
- GLfloat blue,
- GLfloat alpha );
-
-
-
-/*
- * 3Dfx Glide driver only!
- * Set 3Dfx/Glide full-screen or window rendering mode.
- * Input: mode - either XMESA_FX_WINDOW (window rendering mode) or
- * XMESA_FX_FULLSCREEN (full-screen rendering mode)
- * Return: GL_TRUE if success
- * GL_FALSE if invalid mode or if not using 3Dfx driver
- *
- * New in Mesa 2.6.
- */
-extern GLboolean XMesaSetFXmode( GLint mode );
-
-
-
-/*
- * Reallocate the back/depth/stencil/accum/etc/ buffers associated with
- * buffer <b> if its size has changed.
- *
- * New in Mesa 4.0.2
- */
-extern void XMesaResizeBuffers( XMesaBuffer b );
-
-
-
-/*
- * Create a pbuffer.
- * New in Mesa 4.1
- */
-extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap,
- unsigned int width, unsigned int height);
-
-
-
-/*
- * Texture from Pixmap
- * New in Mesa 7.1
- */
-extern void
-XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer,
- const int *attrib_list);
-
-extern void
-XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer);
-
-
-extern XMesaBuffer
-XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
- XMesaColormap cmap,
- int format, int target, int mipmap);
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/src/gallium/winsys/xlib/xmesa_x.h b/src/gallium/winsys/xlib/xmesa_x.h
deleted file mode 100644
index 865bab4313b..00000000000
--- a/src/gallium/winsys/xlib/xmesa_x.h
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <[email protected]>
- *
- * When we're building the XMesa driver for stand-alone Mesa we
- * include this file when building the xm_*.c files.
- * We need to define some types and macros differently when building
- * in the Xserver vs. stand-alone Mesa.
- */
-
-#ifndef _XMESA_X_H_
-#define _XMESA_X_H_
-
-typedef Display XMesaDisplay;
-typedef Pixmap XMesaPixmap;
-typedef Colormap XMesaColormap;
-typedef Drawable XMesaDrawable;
-typedef Window XMesaWindow;
-typedef GC XMesaGC;
-typedef XVisualInfo *XMesaVisualInfo;
-typedef XImage XMesaImage;
-typedef XPoint XMesaPoint;
-typedef XColor XMesaColor;
-
-#define XMesaDestroyImage XDestroyImage
-
-#define XMesaPutPixel XPutPixel
-#define XMesaGetPixel XGetPixel
-
-#define XMesaSetForeground XSetForeground
-#define XMesaSetBackground XSetBackground
-#define XMesaSetPlaneMask XSetPlaneMask
-#define XMesaSetFunction XSetFunction
-#define XMesaSetFillStyle XSetFillStyle
-#define XMesaSetTile XSetTile
-
-#define XMesaDrawPoint XDrawPoint
-#define XMesaDrawPoints XDrawPoints
-#define XMesaDrawLine XDrawLine
-#define XMesaFillRectangle XFillRectangle
-#define XMesaGetImage XGetImage
-#define XMesaPutImage XPutImage
-#define XMesaCopyArea XCopyArea
-
-#define XMesaCreatePixmap XCreatePixmap
-#define XMesaFreePixmap XFreePixmap
-#define XMesaFreeGC XFreeGC
-
-#define GET_COLORMAP_SIZE(__v) __v->visinfo->colormap_size
-#define GET_REDMASK(__v) __v->mesa_visual.redMask
-#define GET_GREENMASK(__v) __v->mesa_visual.greenMask
-#define GET_BLUEMASK(__v) __v->mesa_visual.blueMask
-#define GET_VISUAL_DEPTH(__v) __v->visinfo->depth
-#define GET_BLACK_PIXEL(__v) BlackPixel(__v->display, __v->mesa_visual.screen)
-#define CHECK_BYTE_ORDER(__v) host_byte_order()==ImageByteOrder(__v->display)
-#define CHECK_FOR_HPCR(__v) XInternAtom(__v->display, "_HP_RGB_SMOOTH_MAP_LIST", True)
-
-#endif