summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2010-01-31 05:36:33 +0000
committerJosé Fonseca <[email protected]>2010-01-31 05:36:33 +0000
commitbee9964b29b2428ee75e2d1efc0e1d2c2518a417 (patch)
treefd733f886743b31f2ac2727e57f05d1a0918a977 /src/gallium
parent36a0819ff4ede1af91dcf909106cf20659856384 (diff)
parent12eb32e34244db9923cacaaed9ba951b7ac274a4 (diff)
Merge remote branch 'origin/master' into lp-binning
Conflicts: Makefile src/gallium/auxiliary/util/u_surface.c src/gallium/drivers/llvmpipe/lp_flush.c src/gallium/drivers/llvmpipe/lp_setup.c src/gallium/drivers/llvmpipe/lp_state_derived.c src/gallium/drivers/llvmpipe/lp_state_fs.c src/gallium/drivers/llvmpipe/lp_state_surface.c src/gallium/drivers/llvmpipe/lp_tex_cache.c src/gallium/drivers/llvmpipe/lp_texture.c src/gallium/drivers/llvmpipe/lp_tile_cache.c src/mesa/state_tracker/st_cb_condrender.c
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/SConscript7
-rw-r--r--src/gallium/auxiliary/Makefile3
-rw-r--r--src/gallium/auxiliary/SConscript1
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.c23
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_cache.h2
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.c75
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h4
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h10
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_gs.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c44
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_cull.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_validate.c16
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h28
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c13
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_post_vs.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c40
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h8
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.c10
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_machine.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_ppc.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_varient.c5
-rw-r--r--src/gallium/auxiliary/pipebuffer/Makefile18
-rw-r--r--src/gallium/auxiliary/pipebuffer/SConscript18
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c1067
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h37
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr.h4
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c3
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c152
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_validate.c1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c46
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h9
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c79
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c266
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c12
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.c10
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c100
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c268
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h64
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_util.c1
-rw-r--r--src/gallium/auxiliary/util/u_blit.c10
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c2
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c6
-rw-r--r--src/gallium/auxiliary/util/u_surface.c1
-rw-r--r--src/gallium/auxiliary/util/u_tile.c2
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c4
-rw-r--r--src/gallium/docs/source/context.rst53
-rw-r--r--src/gallium/docs/source/cso/blend.rst45
-rw-r--r--src/gallium/docs/source/cso/rasterizer.rst101
-rw-r--r--src/gallium/docs/source/cso/sampler.rst10
-rw-r--r--src/gallium/docs/source/distro.rst27
-rw-r--r--src/gallium/docs/source/glossary.rst13
-rw-r--r--src/gallium/docs/source/screen.rst221
-rw-r--r--src/gallium/docs/source/tgsi.rst187
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fragment.c20
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c6
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c48
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h25
-rw-r--r--src/gallium/drivers/i915/i915_clear.c1
-rw-r--r--src/gallium/drivers/i915/i915_context.c5
-rw-r--r--src/gallium/drivers/i915/i915_debug.c1
-rw-r--r--src/gallium/drivers/i915/i915_debug_fp.c1
-rw-r--r--src/gallium/drivers/i915/i915_screen.c6
-rw-r--r--src/gallium/drivers/i915/i915_state.c30
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c1
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c1
-rw-r--r--src/gallium/drivers/i915/i915_surface.c6
-rw-r--r--src/gallium/drivers/i915/i915_texture.c2
-rw-r--r--src/gallium/drivers/i965/brw_batchbuffer.c2
-rw-r--r--src/gallium/drivers/i965/brw_batchbuffer.h4
-rw-r--r--src/gallium/drivers/i965/brw_cc.c1
-rw-r--r--src/gallium/drivers/i965/brw_clip.c1
-rw-r--r--src/gallium/drivers/i965/brw_clip_line.c1
-rw-r--r--src/gallium/drivers/i965/brw_clip_point.c1
-rw-r--r--src/gallium/drivers/i965/brw_clip_tri.c1
-rw-r--r--src/gallium/drivers/i965/brw_clip_util.c1
-rw-r--r--src/gallium/drivers/i965/brw_context.c1
-rw-r--r--src/gallium/drivers/i965/brw_curbe.c2
-rw-r--r--src/gallium/drivers/i965/brw_draw.c1
-rw-r--r--src/gallium/drivers/i965/brw_gs.c1
-rw-r--r--src/gallium/drivers/i965/brw_gs_emit.c1
-rw-r--r--src/gallium/drivers/i965/brw_pipe_blend.c22
-rw-r--r--src/gallium/drivers/i965/brw_pipe_fb.c1
-rw-r--r--src/gallium/drivers/i965/brw_pipe_sampler.c1
-rw-r--r--src/gallium/drivers/i965/brw_screen.c9
-rw-r--r--src/gallium/drivers/i965/brw_sf.c1
-rw-r--r--src/gallium/drivers/i965/brw_sf_emit.c1
-rw-r--r--src/gallium/drivers/i965/brw_state_cache.c1
-rw-r--r--src/gallium/drivers/i965/brw_util.c2
-rw-r--r--src/gallium/drivers/i965/brw_vs.c2
-rw-r--r--src/gallium/drivers/i965/brw_vs_surface_state.c1
-rw-r--r--src/gallium/drivers/i965/brw_wm_fp.c1
-rw-r--r--src/gallium/drivers/i965/brw_wm_surface_state.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_conv.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format_aos.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c27
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_surface.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_blend.c73
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c1
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c2
-rw-r--r--src/gallium/drivers/nv04/nv04_screen.c10
-rw-r--r--src/gallium/drivers/nv04/nv04_state.c10
-rw-r--r--src/gallium/drivers/nv04/nv04_vbo.c2
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.c10
-rw-r--r--src/gallium/drivers/nv10/nv10_state.c20
-rw-r--r--src/gallium/drivers/nv10/nv10_vbo.c1
-rw-r--r--src/gallium/drivers/nv20/nv20_screen.c10
-rw-r--r--src/gallium/drivers/nv20/nv20_state.c20
-rw-r--r--src/gallium/drivers/nv20/nv20_vbo.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c10
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c20
-rw-r--r--src/gallium/drivers/nv40/nv40_draw.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c10
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c22
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h16
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c58
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c40
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c26
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c68
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c473
-rw-r--r--src/gallium/drivers/r300/r300_blit.c14
-rw-r--r--src/gallium/drivers/r300/r300_context.c40
-rw-r--r--src/gallium/drivers/r300/r300_context.h69
-rw-r--r--src/gallium/drivers/r300/r300_debug.c10
-rw-r--r--src/gallium/drivers/r300/r300_emit.c231
-rw-r--r--src/gallium/drivers/r300/r300_emit.h10
-rw-r--r--src/gallium/drivers/r300/r300_flush.c2
-rw-r--r--src/gallium/drivers/r300/r300_render.c163
-rw-r--r--src/gallium/drivers/r300/r300_screen.c89
-rw-r--r--src/gallium/drivers/r300/r300_screen.h43
-rw-r--r--src/gallium/drivers/r300/r300_state.c117
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c116
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h53
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c9
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.h2
-rw-r--r--src/gallium/drivers/r300/r300_texture.c64
-rw-r--r--src/gallium/drivers/r300/r300_texture.h7
-rw-r--r--src/gallium/drivers/r300/r300_vs.c9
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h3
-rw-r--r--src/gallium/drivers/softpipe/Makefile3
-rw-r--r--src/gallium/drivers/softpipe/SConscript1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c71
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c56
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c9
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c13
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h3
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c12
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c3
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_video_context.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.c244
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.h13
-rw-r--r--src/gallium/drivers/svga/svga_draw_arrays.c1
-rw-r--r--src/gallium/drivers/svga/svga_draw_elements.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_blend.c19
-rw-r--r--src/gallium/drivers/svga/svga_pipe_constants.c4
-rw-r--r--src/gallium/drivers/svga/svga_pipe_depthstencil.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_flush.c5
-rw-r--r--src/gallium/drivers/svga/svga_pipe_fs.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_misc.c6
-rw-r--r--src/gallium/drivers/svga/svga_pipe_query.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_rasterizer.c1
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c3
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c5
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vs.c1
-rw-r--r--src/gallium/drivers/svga/svga_screen.c11
-rw-r--r--src/gallium/drivers/svga/svga_screen.h6
-rw-r--r--src/gallium/drivers/svga/svga_screen_buffer.c104
-rw-r--r--src/gallium/drivers/svga/svga_screen_buffer.h8
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c68
-rw-r--r--src/gallium/drivers/svga/svga_state_framebuffer.c2
-rw-r--r--src/gallium/drivers/svga/svga_state_rss.c3
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c2
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_backend.c15
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c3
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_state.c1
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_decl_sm20.c3
-rw-r--r--src/gallium/drivers/svga/svga_tgsi_decl_sm30.c1
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h6
-rw-r--r--src/gallium/drivers/trace/tr_drm.c1
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c32
-rw-r--r--src/gallium/include/pipe/p_compiler.h14
-rw-r--r--src/gallium/include/pipe/p_context.h37
-rw-r--r--src/gallium/include/pipe/p_defines.h10
-rw-r--r--src/gallium/include/pipe/p_inlines.h41
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h19
-rw-r--r--src/gallium/include/pipe/p_state.h15
-rw-r--r--src/gallium/include/state_tracker/drm_api.h5
-rw-r--r--src/gallium/state_trackers/Makefile6
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c6
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c14
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c5
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c32
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h1
-rw-r--r--src/gallium/state_trackers/egl/Makefile72
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c (renamed from src/gallium/state_trackers/egl_g3d/common/egl_g3d.c)373
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h (renamed from src/gallium/state_trackers/egl_g3d/common/egl_g3d.h)6
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c (renamed from src/gallium/state_trackers/egl_g3d/common/egl_st.c)0
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.h (renamed from src/gallium/state_trackers/egl_g3d/common/egl_st.h)0
-rw-r--r--src/gallium/state_trackers/egl/common/native.h (renamed from src/gallium/state_trackers/egl_g3d/common/native.h)77
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h (renamed from src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h)0
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c105
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c443
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.c274
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.h195
-rw-r--r--src/gallium/state_trackers/egl/egl_visual.c85
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c (renamed from src/gallium/state_trackers/egl_g3d/kms/native_kms.c)41
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h (renamed from src/gallium/state_trackers/egl_g3d/kms/native_kms.h)0
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c (renamed from src/gallium/state_trackers/egl_g3d/x11/native_dri2.c)105
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c (renamed from src/gallium/state_trackers/egl_g3d/x11/native_x11.c)77
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h (renamed from src/gallium/state_trackers/egl_g3d/x11/native_x11.h)0
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c (renamed from src/gallium/state_trackers/egl_g3d/x11/native_ximage.c)112
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c (renamed from src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c)0
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.h (renamed from src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h)0
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c (renamed from src/gallium/state_trackers/egl_g3d/x11/x11_screen.c)69
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.h (renamed from src/gallium/state_trackers/egl_g3d/x11/x11_screen.h)6
-rw-r--r--src/gallium/state_trackers/egl_g3d/Makefile72
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/glxinit.c573
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/glxinit.h14
-rw-r--r--src/gallium/state_trackers/es/Makefile84
-rw-r--r--src/gallium/state_trackers/es/st_es1.c3
-rw-r--r--src/gallium/state_trackers/es/st_es2.c3
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_getproc.c2
-rw-r--r--src/gallium/state_trackers/python/SConscript1
-rw-r--r--src/gallium/state_trackers/python/samples/gs.py10
-rw-r--r--src/gallium/state_trackers/python/samples/tri.py10
-rw-r--r--src/gallium/state_trackers/python/st_device.c10
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c219
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh13
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh9
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh2
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py49
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh16
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh12
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py50
-rwxr-xr-xsrc/gallium/state_trackers/python/tests/texture_render.py10
-rwxr-xr-xsrc/gallium/state_trackers/python/tests/texture_sample.py20
-rw-r--r--src/gallium/state_trackers/vega/Makefile80
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c18
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c18
-rw-r--r--src/gallium/state_trackers/vega/mask.c15
-rw-r--r--src/gallium/state_trackers/vega/polygon.c10
-rw-r--r--src/gallium/state_trackers/vega/renderer.c20
-rw-r--r--src/gallium/state_trackers/vega/shader.c4
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c68
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h2
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c11
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c50
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c100
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c11
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_winsys.h1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c15
-rw-r--r--src/gallium/winsys/drm/Makefile.egl (renamed from src/gallium/winsys/drm/Makefile.egl_g3d)24
-rw-r--r--src/gallium/winsys/drm/Makefile.template9
-rw-r--r--src/gallium/winsys/drm/i965/egl/Makefile27
-rw-r--r--src/gallium/winsys/drm/i965/egl/dummy.c (renamed from src/gallium/winsys/drm/i965/egl_g3d/dummy.c)0
-rw-r--r--src/gallium/winsys/drm/i965/egl_g3d/Makefile14
-rw-r--r--src/gallium/winsys/drm/i965/xorg/Makefile2
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile27
-rw-r--r--src/gallium/winsys/drm/intel/egl/dummy.c (renamed from src/gallium/winsys/drm/intel/egl_g3d/dummy.c)0
-rw-r--r--src/gallium/winsys/drm/intel/egl_g3d/Makefile14
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c1
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c12
-rw-r--r--src/gallium/winsys/drm/nouveau/egl/Makefile (renamed from src/gallium/winsys/drm/nouveau/egl_g3d/Makefile)2
-rw-r--r--src/gallium/winsys/drm/nouveau/egl/dummy.c (renamed from src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c)0
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c83
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h5
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c50
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h10
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c13
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_winsys.h6
-rw-r--r--src/gallium/winsys/drm/radeon/egl/Makefile24
-rw-r--r--src/gallium/winsys/drm/radeon/egl/dummy.c (renamed from src/gallium/winsys/drm/radeon/egl_g3d/dummy.c)0
-rw-r--r--src/gallium/winsys/drm/radeon/egl_g3d/Makefile14
-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/core/swrast_drm_api.c13
-rw-r--r--src/gallium/winsys/drm/swrast/egl/Makefile12
-rw-r--r--src/gallium/winsys/drm/swrast/egl/dummy.c (renamed from src/gallium/winsys/drm/vmware/egl_g3d/dummy.c)0
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_context.c114
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen.h4
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c86
-rw-r--r--src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c22
-rw-r--r--src/gallium/winsys/drm/vmware/egl/Makefile16
-rw-r--r--src/gallium/winsys/drm/vmware/egl/dummy.c1
-rw-r--r--src/gallium/winsys/drm/vmware/egl_g3d/Makefile14
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_video.c3
-rw-r--r--src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c10
-rw-r--r--src/gallium/winsys/egl_xlib/Makefile89
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c853
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c231
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.h40
-rw-r--r--src/gallium/winsys/xlib/xlib.c31
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c40
338 files changed, 6069 insertions, 6069 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index eea32b1314b..d56c5c84617 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -8,9 +8,10 @@ for driver in env['drivers']:
SConscript(os.path.join('drivers', driver, 'SConscript'))
SConscript('state_trackers/python/SConscript')
-SConscript('state_trackers/glx/xlib/SConscript')
-SConscript('state_trackers/dri/SConscript')
-SConscript('state_trackers/xorg/SConscript')
+if platform != 'embedded':
+ SConscript('state_trackers/glx/xlib/SConscript')
+ SConscript('state_trackers/dri/SConscript')
+ SConscript('state_trackers/xorg/SConscript')
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 8f937e3b4e9..da1fb6b299f 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -48,12 +48,10 @@ C_SOURCES = \
draw/draw_vs_sse.c \
indices/u_indices_gen.c \
indices/u_unfilled_gen.c \
- pipebuffer/pb_buffer_fenced.c \
pipebuffer/pb_buffer_malloc.c \
pipebuffer/pb_bufmgr_alt.c \
pipebuffer/pb_bufmgr_cache.c \
pipebuffer/pb_bufmgr_debug.c \
- pipebuffer/pb_bufmgr_fenced.c \
pipebuffer/pb_bufmgr_mm.c \
pipebuffer/pb_bufmgr_ondemand.c \
pipebuffer/pb_bufmgr_pool.c \
@@ -92,6 +90,7 @@ C_SOURCES = \
util/u_debug_dump.c \
util/u_debug_symbol.c \
util/u_debug_stack.c \
+ util/u_bitmask.c \
util/u_blit.c \
util/u_blitter.c \
util/u_cache.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index f957090b5fb..3aa782f81e6 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -87,7 +87,6 @@ source = [
'pipebuffer/pb_bufmgr_alt.c',
'pipebuffer/pb_bufmgr_cache.c',
'pipebuffer/pb_bufmgr_debug.c',
- 'pipebuffer/pb_bufmgr_fenced.c',
'pipebuffer/pb_bufmgr_mm.c',
'pipebuffer/pb_bufmgr_ondemand.c',
'pipebuffer/pb_bufmgr_pool.c',
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.c b/src/gallium/auxiliary/cso_cache/cso_cache.c
index e6dce3f0e5b..a6a07e72c2f 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.c
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.c
@@ -113,26 +113,6 @@ static struct cso_hash *_cso_hash_for_type(struct cso_cache *sc, enum cso_cache_
return hash;
}
-static int _cso_size_for_type(enum cso_cache_type type)
-{
- switch(type) {
- case CSO_BLEND:
- return sizeof(struct pipe_blend_state);
- case CSO_SAMPLER:
- return sizeof(struct pipe_sampler_state);
- case CSO_DEPTH_STENCIL_ALPHA:
- return sizeof(struct pipe_depth_stencil_alpha_state);
- case CSO_RASTERIZER:
- return sizeof(struct pipe_rasterizer_state);
- case CSO_FRAGMENT_SHADER:
- return sizeof(struct pipe_shader_state);
- case CSO_VERTEX_SHADER:
- return sizeof(struct pipe_shader_state);
- }
- return 0;
-}
-
-
static void delete_blend_state(void *state, void *data)
{
struct cso_blend *cso = (struct cso_blend *)state;
@@ -282,10 +262,9 @@ void *cso_hash_find_data_from_template( struct cso_hash *hash,
struct cso_hash_iter cso_find_state_template(struct cso_cache *sc,
unsigned hash_key, enum cso_cache_type type,
- void *templ)
+ void *templ, unsigned size)
{
struct cso_hash_iter iter = cso_find_state(sc, hash_key, type);
- int size = _cso_size_for_type(type);
while (!cso_hash_iter_is_null(iter)) {
void *iter_data = cso_hash_iter_data(iter);
if (!memcmp(iter_data, templ, size))
diff --git a/src/gallium/auxiliary/cso_cache/cso_cache.h b/src/gallium/auxiliary/cso_cache/cso_cache.h
index 6b5c230e8f2..eea60b940bb 100644
--- a/src/gallium/auxiliary/cso_cache/cso_cache.h
+++ b/src/gallium/auxiliary/cso_cache/cso_cache.h
@@ -160,7 +160,7 @@ struct cso_hash_iter cso_find_state(struct cso_cache *sc,
unsigned hash_key, enum cso_cache_type type);
struct cso_hash_iter cso_find_state_template(struct cso_cache *sc,
unsigned hash_key, enum cso_cache_type type,
- void *templ);
+ void *templ, unsigned size);
void cso_for_each_state(struct cso_cache *sc, enum cso_cache_type type,
cso_state_callback func, void *user_data);
void * cso_take_state(struct cso_cache *sc, unsigned hash_key,
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index 2b16332e143..dec830ba93e 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -310,18 +310,21 @@ void cso_destroy_context( struct cso_context *ctx )
enum pipe_error cso_set_blend(struct cso_context *ctx,
const struct pipe_blend_state *templ)
{
- unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state));
- struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
- hash_key, CSO_BLEND,
- (void*)templ);
+ unsigned key_size, hash_key;
+ struct cso_hash_iter iter;
void *handle;
+ key_size = templ->independent_blend_enable ? sizeof(struct pipe_blend_state) :
+ (char *)&(templ->rt[1]) - (char *)templ;
+ hash_key = cso_construct_key((void*)templ, key_size);
+ iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND, (void*)templ, key_size);
+
if (cso_hash_iter_is_null(iter)) {
struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
if (!cso)
return PIPE_ERROR_OUT_OF_MEMORY;
- memcpy(&cso->state, templ, sizeof(*templ));
+ memcpy(&cso->state, templ, key_size);
cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
cso->context = ctx->pipe;
@@ -369,10 +372,11 @@ enum pipe_error cso_single_sampler(struct cso_context *ctx,
void *handle = NULL;
if (templ != NULL) {
- unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state));
+ unsigned key_size = sizeof(struct pipe_sampler_state);
+ unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key, CSO_SAMPLER,
- (void*)templ);
+ (void*)templ, key_size);
if (cso_hash_iter_is_null(iter)) {
struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
@@ -409,10 +413,11 @@ cso_single_vertex_sampler(struct cso_context *ctx,
void *handle = NULL;
if (templ != NULL) {
- unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_sampler_state));
+ unsigned key_size = sizeof(struct pipe_sampler_state);
+ unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key, CSO_SAMPLER,
- (void*)templ);
+ (void*)templ, key_size);
if (cso_hash_iter_is_null(iter)) {
struct cso_sampler *cso = MALLOC(sizeof(struct cso_sampler));
@@ -539,6 +544,38 @@ void cso_restore_samplers(struct cso_context *ctx)
cso_single_sampler_done( ctx );
}
+/*
+ * If the function encouters any errors it will return the
+ * last one. Done to always try to set as many samplers
+ * as possible.
+ */
+enum pipe_error cso_set_vertex_samplers(struct cso_context *ctx,
+ unsigned nr,
+ const struct pipe_sampler_state **templates)
+{
+ unsigned i;
+ enum pipe_error temp, error = PIPE_OK;
+
+ /* TODO: fastpath
+ */
+
+ for (i = 0; i < nr; i++) {
+ temp = cso_single_vertex_sampler( ctx, i, templates[i] );
+ if (temp != PIPE_OK)
+ error = temp;
+ }
+
+ for ( ; i < ctx->nr_samplers; i++) {
+ temp = cso_single_vertex_sampler( ctx, i, NULL );
+ if (temp != PIPE_OK)
+ error = temp;
+ }
+
+ cso_single_vertex_sampler_done( ctx );
+
+ return error;
+}
+
void
cso_save_vertex_samplers(struct cso_context *ctx)
{
@@ -666,12 +703,12 @@ cso_restore_vertex_sampler_textures(struct cso_context *ctx)
enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
const struct pipe_depth_stencil_alpha_state *templ)
{
- unsigned hash_key = cso_construct_key((void*)templ,
- sizeof(struct pipe_depth_stencil_alpha_state));
+ unsigned key_size = sizeof(struct pipe_depth_stencil_alpha_state);
+ unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key,
- CSO_DEPTH_STENCIL_ALPHA,
- (void*)templ);
+ CSO_DEPTH_STENCIL_ALPHA,
+ (void*)templ, key_size);
void *handle;
if (cso_hash_iter_is_null(iter)) {
@@ -723,11 +760,11 @@ void cso_restore_depth_stencil_alpha(struct cso_context *ctx)
enum pipe_error cso_set_rasterizer(struct cso_context *ctx,
const struct pipe_rasterizer_state *templ)
{
- unsigned hash_key = cso_construct_key((void*)templ,
- sizeof(struct pipe_rasterizer_state));
+ unsigned key_size = sizeof(struct pipe_rasterizer_state);
+ unsigned hash_key = cso_construct_key((void*)templ, key_size);
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key, CSO_RASTERIZER,
- (void*)templ);
+ (void*)templ, key_size);
void *handle = NULL;
if (cso_hash_iter_is_null(iter)) {
@@ -809,7 +846,8 @@ enum pipe_error cso_set_fragment_shader(struct cso_context *ctx,
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key,
CSO_FRAGMENT_SHADER,
- (void*)tokens);
+ (void*)tokens,
+ sizeof(*templ)); /* XXX correct? tokens_size? */
void *handle = NULL;
if (cso_hash_iter_is_null(iter)) {
@@ -888,7 +926,8 @@ enum pipe_error cso_set_vertex_shader(struct cso_context *ctx,
sizeof(struct pipe_shader_state));
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
hash_key, CSO_VERTEX_SHADER,
- (void*)templ);
+ (void*)templ,
+ sizeof(*templ));
void *handle = NULL;
if (cso_hash_iter_is_null(iter)) {
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index b9e313e32d6..d2089b1c883 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -84,6 +84,10 @@ enum pipe_error cso_single_sampler( struct cso_context *cso,
void cso_single_sampler_done( struct cso_context *cso );
+enum pipe_error cso_set_vertex_samplers(struct cso_context *cso,
+ unsigned count,
+ const struct pipe_sampler_state **states);
+
void
cso_save_vertex_samplers(struct cso_context *cso);
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index e90dfc5aec4..d3084fd4283 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -34,11 +34,8 @@
#include "util/u_memory.h"
#include "util/u_math.h"
#include "draw_context.h"
-#include "draw_vbuf.h"
#include "draw_vs.h"
#include "draw_gs.h"
-#include "draw_pt.h"
-#include "draw_pipe.h"
struct draw_context *draw_create( void )
@@ -237,17 +234,20 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw,
void
draw_set_mapped_constant_buffer(struct draw_context *draw,
unsigned shader_type,
+ unsigned slot,
const void *buffer,
unsigned size )
{
debug_assert(shader_type == PIPE_SHADER_VERTEX ||
shader_type == PIPE_SHADER_GEOMETRY);
+ debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS);
+
if (shader_type == PIPE_SHADER_VERTEX) {
- draw->pt.user.vs_constants = buffer;
- draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
+ draw->pt.user.vs_constants[slot] = buffer;
+ draw_vs_set_constants(draw, slot, buffer, size);
} else if (shader_type == PIPE_SHADER_GEOMETRY) {
- draw->pt.user.gs_constants = buffer;
- draw_gs_set_constants( draw, (const float (*)[4])buffer, size );
+ draw->pt.user.gs_constants[slot] = buffer;
+ draw_gs_set_constants(draw, slot, buffer, size);
}
}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 8a64c06efcd..acd81b9712d 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -151,10 +151,12 @@ void draw_set_mapped_element_buffer( struct draw_context *draw,
void draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer);
-void draw_set_mapped_constant_buffer(struct draw_context *draw,
- unsigned shader_type,
- const void *buffer,
- unsigned size );
+void
+draw_set_mapped_constant_buffer(struct draw_context *draw,
+ unsigned shader_type,
+ unsigned slot,
+ const void *buffer,
+ unsigned size);
/***********************************************************************
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index daf8d071f12..7069aa6b181 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -69,9 +69,11 @@ void draw_gs_destroy( struct draw_context *draw )
tgsi_exec_machine_destroy(draw->gs.machine);
}
-void draw_gs_set_constants( struct draw_context *draw,
- const float (*constants)[4],
- unsigned size )
+void
+draw_gs_set_constants(struct draw_context *draw,
+ unsigned slot,
+ const void *constants,
+ unsigned size)
{
}
@@ -291,7 +293,7 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
void draw_geometry_shader_run(struct draw_geometry_shader *shader,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned vertex_size)
@@ -302,7 +304,9 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
unsigned num_primitives = count/num_vertices;
unsigned inputs_from_vs = 0;
- machine->Consts = constants;
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ machine->Consts[i] = constants[i];
+ }
for (i = 0; i < shader->info.num_inputs; ++i) {
if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
index d6a97d9c4ef..d8eb2103433 100644
--- a/src/gallium/auxiliary/draw/draw_gs.h
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -62,7 +62,7 @@ struct draw_geometry_shader {
void draw_geometry_shader_run(struct draw_geometry_shader *shader,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride);
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 1c6d657297c..11d6485dcf0 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -106,10 +106,9 @@ void draw_pipeline_destroy( struct draw_context *draw )
-
-
-
-
+/**
+ * Build primitive to render a point with vertex at v0.
+ */
static void do_point( struct draw_context *draw,
const char *v0 )
{
@@ -123,6 +122,10 @@ static void do_point( struct draw_context *draw,
}
+/**
+ * Build primitive to render a line with vertices at v0, v1.
+ * \param flags bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE
+ */
static void do_line( struct draw_context *draw,
ushort flags,
const char *v0,
@@ -139,6 +142,10 @@ static void do_line( struct draw_context *draw,
}
+/**
+ * Build primitive to render a triangle with vertices at v0, v1, v2.
+ * \param flags bitmask of DRAW_PIPE_EDGE_x, DRAW_PIPE_RESET_STIPPLE
+ */
static void do_triangle( struct draw_context *draw,
ushort flags,
char *v0,
@@ -157,7 +164,10 @@ static void do_triangle( struct draw_context *draw,
}
-
+/*
+ * Set up macros for draw_pt_decompose.h template code.
+ * This code uses vertex indexes / elements.
+ */
#define QUAD(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
@@ -175,16 +185,16 @@ static void do_triangle( struct draw_context *draw,
#define TRIANGLE(flags,i0,i1,i2) \
do_triangle( draw, \
- elts[i0], /* flags */ \
+ elts[i0], /* flags */ \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * elts[i1], \
- verts + stride * elts[i2])
+ verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) );
#define LINE(flags,i0,i1) \
do_line( draw, \
- elts[i0], \
+ elts[i0], \
verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
- verts + stride * elts[i1])
+ verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) );
#define POINT(i0) \
do_point( draw, \
@@ -213,7 +223,9 @@ static void do_triangle( struct draw_context *draw,
-/* Code to run the pipeline on a fairly arbitary collection of vertices.
+/**
+ * Code to run the pipeline on a fairly arbitary collection of vertices.
+ * For drawing indexed primitives.
*
* Vertex headers must be pre-initialized with the
* UNDEFINED_VERTEX_ID, this code will cause that id to become
@@ -243,6 +255,12 @@ void draw_pipeline_run( struct draw_context *draw,
draw->pipeline.vertex_count = 0;
}
+
+
+/*
+ * Set up macros for draw_pt_decompose.h template code.
+ * This code is for non-indexed rendering (no elts).
+ */
#define QUAD(i0,i1,i2,i3) \
do_triangle( draw, \
( DRAW_PIPE_RESET_STIPPLE | \
@@ -293,6 +311,10 @@ void draw_pipeline_run( struct draw_context *draw,
#include "draw_pt_decompose.h"
+
+/*
+ * For drawing non-indexed primitives.
+ */
void draw_pipeline_run_linear( struct draw_context *draw,
unsigned prim,
struct vertex_header *vertices,
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
index 11b39db5990..dc66c65a56c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -50,8 +50,6 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
}
-
-
static void cull_tri( struct draw_stage *stage,
struct prim_header *header )
{
@@ -62,7 +60,7 @@ static void cull_tri( struct draw_stage *stage,
const float *v1 = header->v[1]->data[pos];
const float *v2 = header->v[2]->data[pos];
- /* edge vectors e = v0 - v2, f = v1 - v2 */
+ /* edge vectors: e = v0 - v2, f = v1 - v2 */
const float ex = v0[0] - v2[0];
const float ey = v0[1] - v2[1];
const float fx = v1[0] - v2[0];
@@ -72,7 +70,7 @@ static void cull_tri( struct draw_stage *stage,
header->det = ex * fy - ey * fx;
if (header->det != 0) {
- /* if (det < 0 then Z points toward camera and triangle is
+ /* if det < 0 then Z points toward the camera and the triangle is
* counter-clockwise winding.
*/
unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
@@ -84,6 +82,7 @@ static void cull_tri( struct draw_stage *stage,
}
}
+
static void cull_first_tri( struct draw_stage *stage,
struct prim_header *header )
{
@@ -96,13 +95,13 @@ static void cull_first_tri( struct draw_stage *stage,
}
-
static void cull_flush( struct draw_stage *stage, unsigned flags )
{
stage->tri = cull_first_tri;
stage->next->flush( stage->next, flags );
}
+
static void cull_reset_stipple_counter( struct draw_stage *stage )
{
stage->next->reset_stipple_counter( stage->next );
@@ -140,7 +139,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
return &cull->stage;
- fail:
+fail:
if (cull)
cull->stage.destroy( &cull->stage );
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
index bea90e50d30..a69e2633bec 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_validate.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c
@@ -151,8 +151,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
{
struct draw_context *draw = stage->draw;
struct draw_stage *next = draw->pipeline.rasterize;
- int need_det = 0;
- int precalc_flat = 0;
+ boolean need_det = FALSE;
+ boolean precalc_flat = FALSE;
boolean wide_lines, wide_points;
/* Set the validate's next stage to the rasterize stage, so that it
@@ -194,7 +194,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
if (wide_lines) {
draw->pipeline.wide_line->next = next;
next = draw->pipeline.wide_line;
- precalc_flat = 1;
+ precalc_flat = TRUE;
}
if (wide_points || draw->rasterizer->point_sprite) {
@@ -205,7 +205,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) {
draw->pipeline.stipple->next = next;
next = draw->pipeline.stipple;
- precalc_flat = 1; /* only needed for lines really */
+ precalc_flat = TRUE; /* only needed for lines really */
}
if (draw->rasterizer->poly_stipple_enable
@@ -218,8 +218,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
draw->pipeline.unfilled->next = next;
next = draw->pipeline.unfilled;
- precalc_flat = 1; /* only needed for triangles really */
- need_det = 1;
+ precalc_flat = TRUE; /* only needed for triangles really */
+ need_det = TRUE;
}
if (draw->rasterizer->flatshade && precalc_flat) {
@@ -231,13 +231,13 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
draw->rasterizer->offset_ccw) {
draw->pipeline.offset->next = next;
next = draw->pipeline.offset;
- need_det = 1;
+ need_det = TRUE;
}
if (draw->rasterizer->light_twoside) {
draw->pipeline.twoside->next = next;
next = draw->pipeline.twoside;
- need_det = 1;
+ need_det = TRUE;
}
/* Always run the cull stage as we calculate determinant there
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index ef49e575366..6a7190e9750 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -153,8 +153,8 @@ struct draw_context
const void *vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffer (for vertex/geometry shader) */
- const void *vs_constants;
- const void *gs_constants;
+ const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS];
+ const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS];
} user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */
@@ -202,10 +202,10 @@ struct draw_context
struct aos_machine *aos_machine;
- const float (*aligned_constants)[4];
+ const void *aligned_constants[PIPE_MAX_CONSTANT_BUFFERS];
- const float (*aligned_constant_storage)[4];
- unsigned const_storage_size;
+ const void *aligned_constant_storage[PIPE_MAX_CONSTANT_BUFFERS];
+ unsigned const_storage_size[PIPE_MAX_CONSTANT_BUFFERS];
struct translate *fetch;
@@ -256,9 +256,11 @@ void draw_vs_destroy( struct draw_context *draw );
void draw_vs_set_viewport( struct draw_context *,
const struct pipe_viewport_state * );
-void draw_vs_set_constants( struct draw_context *,
- const float (*constants)[4],
- unsigned size );
+void
+draw_vs_set_constants(struct draw_context *,
+ unsigned slot,
+ const void *constants,
+ unsigned size);
@@ -266,9 +268,13 @@ void draw_vs_set_constants( struct draw_context *,
* Geometry shading code:
*/
boolean draw_gs_init( struct draw_context *draw );
-void draw_gs_set_constants( struct draw_context *,
- const float (*constants)[4],
- unsigned size );
+
+void
+draw_gs_set_constants(struct draw_context *,
+ unsigned slot,
+ const void *constants,
+ unsigned size);
+
void draw_gs_destroy( struct draw_context *draw );
/*******************************************************************************
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index a5ddec52863..f5ed32d0b05 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -33,7 +33,6 @@
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_pt.h"
-#include "draw/draw_vs.h"
#include "tgsi/tgsi_dump.h"
#include "util/u_math.h"
#include "util/u_prim.h"
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch.c b/src/gallium/auxiliary/draw/draw_pt_fetch.c
index 55e7a7b81ad..252be5053e4 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -30,7 +30,6 @@
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_vbuf.h"
-#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
#include "translate/translate.h"
#include "translate/translate_cache.h"
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 734c05f0688..c5dfbcfa3cb 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -40,7 +40,6 @@
#include "draw/draw_pt.h"
#include "draw/draw_vs.h"
-#include "translate/translate.h"
struct fetch_shade_emit;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 23da556f797..56b69354b21 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -33,7 +33,6 @@
#include "draw/draw_pt.h"
#include "draw/draw_vs.h"
#include "draw/draw_gs.h"
-#include "translate/translate.h"
struct fetch_pipeline_middle_end {
@@ -164,7 +163,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
vshader->run_linear(vshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.vs_constants,
+ draw->pt.user.vs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
@@ -172,7 +171,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
draw_geometry_shader_run(gshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.gs_constants,
+ draw->pt.user.gs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
@@ -249,7 +248,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.vs_constants,
+ draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
@@ -258,7 +257,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
draw_geometry_shader_run(geometry_shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.gs_constants,
+ draw->pt.user.gs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
@@ -329,7 +328,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.vs_constants,
+ draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
@@ -338,7 +337,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
draw_geometry_shader_run(geometry_shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
- (const float (*)[4])draw->pt.user.gs_constants,
+ draw->pt.user.gs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 55151823a14..9728d5c2bdf 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -30,7 +30,6 @@
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_vbuf.h"
-#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
struct pt_post_vs {
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index e03ac8c2291..6bdd612e6f4 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -48,24 +48,27 @@
-void draw_vs_set_constants( struct draw_context *draw,
- const float (*constants)[4],
- unsigned size )
+void
+draw_vs_set_constants(struct draw_context *draw,
+ unsigned slot,
+ const void *constants,
+ unsigned size)
{
if (((uintptr_t)constants) & 0xf) {
- if (size > draw->vs.const_storage_size) {
- if (draw->vs.aligned_constant_storage)
- align_free((void *)draw->vs.aligned_constant_storage);
- draw->vs.aligned_constant_storage = align_malloc( size, 16 );
+ if (size > draw->vs.const_storage_size[slot]) {
+ if (draw->vs.aligned_constant_storage[slot]) {
+ align_free((void *)draw->vs.aligned_constant_storage[slot]);
+ }
+ draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16);
}
- memcpy( (void*)draw->vs.aligned_constant_storage,
- constants,
- size );
- constants = draw->vs.aligned_constant_storage;
+ memcpy((void *)draw->vs.aligned_constant_storage[slot],
+ constants,
+ size);
+ constants = draw->vs.aligned_constant_storage[slot];
}
-
- draw->vs.aligned_constants = constants;
- draw_vs_aos_machine_constants( draw->vs.aos_machine, constants );
+
+ draw->vs.aligned_constants[slot] = constants;
+ draw_vs_aos_machine_constants(draw->vs.aos_machine, slot, constants);
}
@@ -182,6 +185,8 @@ draw_vs_init( struct draw_context *draw )
void
draw_vs_destroy( struct draw_context *draw )
{
+ uint i;
+
if (draw->vs.fetch_cache)
translate_cache_destroy(draw->vs.fetch_cache);
@@ -191,8 +196,11 @@ draw_vs_destroy( struct draw_context *draw )
if (draw->vs.aos_machine)
draw_vs_aos_machine_destroy(draw->vs.aos_machine);
- if (draw->vs.aligned_constant_storage)
- align_free((void*)draw->vs.aligned_constant_storage);
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ if (draw->vs.aligned_constant_storage[i]) {
+ align_free((void *)draw->vs.aligned_constant_storage[i]);
+ }
+ }
tgsi_exec_machine_destroy(draw->vs.machine);
}
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index 00036cfe68b..d095c9bad1d 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -132,7 +132,7 @@ struct draw_vertex_shader {
void (*run_linear)( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride );
@@ -212,8 +212,10 @@ static INLINE int draw_vs_varient_key_compare( const struct draw_vs_varient_key
struct aos_machine *draw_vs_aos_machine( void );
void draw_vs_aos_machine_destroy( struct aos_machine *machine );
-void draw_vs_aos_machine_constants( struct aos_machine *machine,
- const float (*constants)[4] );
+void
+draw_vs_aos_machine_constants(struct aos_machine *machine,
+ unsigned slot,
+ const void *constants);
void draw_vs_aos_machine_viewport( struct aos_machine *machine,
const struct pipe_viewport_state *viewport );
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 1aaae4ab7a4..e7121f36541 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.c
@@ -2114,11 +2114,14 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient,
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct aos_machine *machine = vaos->draw->vs.aos_machine;
+ unsigned i;
if (0) debug_printf("%s %d\n", __FUNCTION__, count);
machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
- machine->constants = vaos->draw->vs.aligned_constants;
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ machine->constants[i] = vaos->draw->vs.aligned_constants[i];
+ }
machine->immediates = vaos->base.vs->immediates;
machine->buffer = vaos->buffer;
@@ -2135,12 +2138,15 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient,
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct aos_machine *machine = vaos->draw->vs.aos_machine;
+ unsigned i;
if (0) debug_printf("%s %d %d const: %x\n", __FUNCTION__, start, count,
vaos->base.key.const_vbuffers);
machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
- machine->constants = vaos->draw->vs.aligned_constants;
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ machine->constants[i] = vaos->draw->vs.aligned_constants[i];
+ }
machine->immediates = vaos->base.vs->immediates;
machine->buffer = vaos->buffer;
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.h b/src/gallium/auxiliary/draw/draw_vs_aos.h
index 2cf72ddf7b1..1911242f825 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.h
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.h
@@ -122,7 +122,7 @@ struct aos_machine {
ushort fpucntl; /* one of FPU_* above */
const float (*immediates)[4]; /* points to shader data */
- const float (*constants)[4]; /* points to draw data */
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS]; /* points to draw data */
const struct aos_buffer *buffer; /* points to ? */
};
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
index 3240e3745dd..0eda414ee6a 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
@@ -219,10 +219,12 @@ static void PIPE_CDECL populate_lut( struct aos_machine *machine,
}
-void draw_vs_aos_machine_constants( struct aos_machine *machine,
- const float (*constants)[4] )
+void
+draw_vs_aos_machine_constants(struct aos_machine *machine,
+ unsigned slot,
+ const void *constants)
{
- machine->constants = constants;
+ machine->constants[slot] = constants;
{
unsigned i;
@@ -307,8 +309,10 @@ void draw_vs_aos_machine_viewport( struct aos_machine *machine,
{
}
-void draw_vs_aos_machine_constants( struct aos_machine *machine,
- const float (*constants)[4] )
+void
+draw_vs_aos_machine_constants(struct aos_machine *machine,
+ unsigned slot,
+ const void *constants)
{
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 41cc8026131..7deca2b69d9 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -85,7 +85,7 @@ static void
vs_exec_run_linear( struct draw_vertex_shader *shader,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@@ -95,7 +95,9 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
unsigned int i, j;
unsigned slot;
- machine->Consts = constants;
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ machine->Consts[i] = constants[i];
+ }
for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index b3535c0e48e..fd9166fda58 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -64,7 +64,7 @@ static void
vs_llvm_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@@ -74,7 +74,8 @@ vs_llvm_run_linear( struct draw_vertex_shader *base,
gallivm_cpu_vs_exec(shader->llvm_prog, shader->machine,
input, base->info.num_inputs, output, base->info.num_outputs,
- constants, count, input_stride, output_stride);
+ (const float (*)[4])constants[0],
+ count, input_stride, output_stride);
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_ppc.c b/src/gallium/auxiliary/draw/draw_vs_ppc.c
index da9f3e3d35c..d869eecec5e 100644
--- a/src/gallium/auxiliary/draw/draw_vs_ppc.c
+++ b/src/gallium/auxiliary/draw/draw_vs_ppc.c
@@ -85,7 +85,7 @@ static void
vs_ppc_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@@ -125,7 +125,7 @@ vs_ppc_run_linear( struct draw_vertex_shader *base,
*/
shader->func(inputs_soa, outputs_soa, temps_soa,
(float (*)[4]) shader->base.immediates,
- (float (*)[4]) constants,
+ (const float (*)[4])constants[0],
ppc_builtin_constants);
/* convert (up to) four output verts from SoA back to AoS format */
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index 702051387ac..54e6423388f 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -83,7 +83,7 @@ static void
vs_sse_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
- const float (*constants)[4],
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
unsigned count,
unsigned input_stride,
unsigned output_stride )
@@ -112,7 +112,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base,
/* run compiled shader
*/
shader->func(machine,
- constants,
+ (const float (*)[4])constants[0],
shader->base.immediates,
input,
base->info.num_inputs,
diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c
index 9f40030f39f..5ed706cb4ff 100644
--- a/src/gallium/auxiliary/draw/draw_vs_varient.c
+++ b/src/gallium/auxiliary/draw/draw_vs_varient.c
@@ -38,7 +38,6 @@
#include "draw/draw_vertex.h"
#include "draw/draw_vs.h"
#include "translate/translate.h"
-#include "translate/translate_cache.h"
/* A first pass at incorporating vertex fetch/emit functionality into
*/
@@ -148,7 +147,7 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);
@@ -211,7 +210,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
- (const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
+ vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);
diff --git a/src/gallium/auxiliary/pipebuffer/Makefile b/src/gallium/auxiliary/pipebuffer/Makefile
new file mode 100644
index 00000000000..21d25d24748
--- /dev/null
+++ b/src/gallium/auxiliary/pipebuffer/Makefile
@@ -0,0 +1,18 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = pipebuffer
+
+C_SOURCES = \
+ pb_buffer_fenced.c \
+ pb_buffer_malloc.c \
+ pb_bufmgr_alt.c \
+ pb_bufmgr_cache.c \
+ pb_bufmgr_debug.c \
+ pb_bufmgr_mm.c \
+ pb_bufmgr_ondemand.c \
+ pb_bufmgr_pool.c \
+ pb_bufmgr_slab.c \
+ pb_validate.c
+
+include ../../Makefile.template
diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript
new file mode 100644
index 00000000000..a074a554717
--- /dev/null
+++ b/src/gallium/auxiliary/pipebuffer/SConscript
@@ -0,0 +1,18 @@
+Import('*')
+
+pipebuffer = env.ConvenienceLibrary(
+ target = 'pipebuffer',
+ source = [
+ 'pb_buffer_fenced.c',
+ 'pb_buffer_malloc.c',
+ 'pb_bufmgr_alt.c',
+ 'pb_bufmgr_cache.c',
+ 'pb_bufmgr_debug.c',
+ 'pb_bufmgr_mm.c',
+ 'pb_bufmgr_ondemand.c',
+ 'pb_bufmgr_pool.c',
+ 'pb_bufmgr_slab.c',
+ 'pb_validate.c',
+ ])
+
+auxiliaries.insert(0, pipebuffer)
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index a4b78f14943..ba087ac0f34 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2007-2009 VMware, Inc.
+ * Copyright 2007-2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,9 +28,9 @@
/**
* \file
* Implementation of fenced buffers.
- *
- * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com>
- * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ *
+ * \author Jose Fonseca <jfonseca-at-vmware-dot-com>
+ * \author Thomas Hellström <thellstrom-at-vmware-dot-com>
*/
@@ -50,6 +50,7 @@
#include "pb_buffer.h"
#include "pb_buffer_fenced.h"
+#include "pb_bufmgr.h"
@@ -59,32 +60,79 @@
#define SUPER(__derived) (&(__derived)->base)
-struct fenced_buffer_list
+struct fenced_manager
{
- pipe_mutex mutex;
-
+ struct pb_manager base;
+ struct pb_manager *provider;
struct pb_fence_ops *ops;
-
- pb_size numDelayed;
- struct list_head delayed;
-
-#ifdef DEBUG
- pb_size numUnfenced;
+
+ /**
+ * Maximum buffer size that can be safely allocated.
+ */
+ pb_size max_buffer_size;
+
+ /**
+ * Maximum cpu memory we can allocate before we start waiting for the
+ * GPU to idle.
+ */
+ pb_size max_cpu_total_size;
+
+ /**
+ * Following members are mutable and protected by this mutex.
+ */
+ pipe_mutex mutex;
+
+ /**
+ * Fenced buffer list.
+ *
+ * All fenced buffers are placed in this listed, ordered from the oldest
+ * fence to the newest fence.
+ */
+ struct list_head fenced;
+ pb_size num_fenced;
+
struct list_head unfenced;
-#endif
+ pb_size num_unfenced;
+
+ /**
+ * How much temporary CPU memory is being used to hold unvalidated buffers.
+ */
+ pb_size cpu_total_size;
};
/**
+ * Fenced buffer.
+ *
* Wrapper around a pipe buffer which adds fencing and reference counting.
*/
struct fenced_buffer
{
+ /*
+ * Immutable members.
+ */
+
struct pb_buffer base;
-
+ struct fenced_manager *mgr;
+
+ /*
+ * Following members are mutable and protected by fenced_manager::mutex.
+ */
+
+ struct list_head head;
+
+ /**
+ * Buffer with storage.
+ */
struct pb_buffer *buffer;
+ pb_size size;
+ struct pb_desc desc;
- /* FIXME: protect access with mutex */
+ /**
+ * Temporary CPU storage data. Used when there isn't enough GPU memory to
+ * store the buffer.
+ */
+ void *data;
/**
* A bitmask of PIPE_BUFFER_USAGE_CPU/GPU_READ/WRITE describing the current
@@ -93,15 +141,22 @@ struct fenced_buffer
unsigned flags;
unsigned mapcount;
+
struct pb_validate *vl;
unsigned validation_flags;
- struct pipe_fence_handle *fence;
- struct list_head head;
- struct fenced_buffer_list *list;
+ struct pipe_fence_handle *fence;
};
+static INLINE struct fenced_manager *
+fenced_manager(struct pb_manager *mgr)
+{
+ assert(mgr);
+ return (struct fenced_manager *)mgr;
+}
+
+
static INLINE struct fenced_buffer *
fenced_buffer(struct pb_buffer *buf)
{
@@ -110,221 +165,568 @@ fenced_buffer(struct pb_buffer *buf)
}
-static INLINE void
-_fenced_buffer_add(struct fenced_buffer *fenced_buf)
-{
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
+static void
+fenced_buffer_destroy_cpu_storage_locked(struct fenced_buffer *fenced_buf);
- assert(pipe_is_referenced(&fenced_buf->base.base.reference));
- assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
- assert(fenced_buf->fence);
+static enum pipe_error
+fenced_buffer_create_cpu_storage_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf);
+static void
+fenced_buffer_destroy_gpu_storage_locked(struct fenced_buffer *fenced_buf);
+
+static enum pipe_error
+fenced_buffer_create_gpu_storage_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf,
+ boolean wait);
+
+static enum pipe_error
+fenced_buffer_copy_storage_to_gpu_locked(struct fenced_buffer *fenced_buf);
+
+static enum pipe_error
+fenced_buffer_copy_storage_to_cpu_locked(struct fenced_buffer *fenced_buf);
+
+
+/**
+ * Dump the fenced buffer list.
+ *
+ * Useful to understand failures to allocate buffers.
+ */
+static void
+fenced_manager_dump_locked(struct fenced_manager *fenced_mgr)
+{
#ifdef DEBUG
- LIST_DEL(&fenced_buf->head);
- assert(fenced_list->numUnfenced);
- --fenced_list->numUnfenced;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
+ struct list_head *curr, *next;
+ struct fenced_buffer *fenced_buf;
+
+ debug_printf("%10s %7s %8s %7s %10s %s\n",
+ "buffer", "size", "refcount", "storage", "fence", "signalled");
+
+ curr = fenced_mgr->unfenced.next;
+ next = curr->next;
+ while(curr != &fenced_mgr->unfenced) {
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+ assert(!fenced_buf->fence);
+ debug_printf("%10p %7u %8u %7s\n",
+ (void *) fenced_buf,
+ fenced_buf->base.base.size,
+ p_atomic_read(&fenced_buf->base.base.reference.count),
+ fenced_buf->buffer ? "gpu" : (fenced_buf->data ? "cpu" : "none"));
+ curr = next;
+ next = curr->next;
+ }
+
+ curr = fenced_mgr->fenced.next;
+ next = curr->next;
+ while(curr != &fenced_mgr->fenced) {
+ int signaled;
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+ assert(fenced_buf->buffer);
+ signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
+ debug_printf("%10p %7u %8u %7s %10p %s\n",
+ (void *) fenced_buf,
+ fenced_buf->base.base.size,
+ p_atomic_read(&fenced_buf->base.base.reference.count),
+ "gpu",
+ (void *) fenced_buf->fence,
+ signaled == 0 ? "y" : "n");
+ curr = next;
+ next = curr->next;
+ }
+#else
+ (void)fenced_mgr;
#endif
- LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
- ++fenced_list->numDelayed;
}
-/**
- * Actually destroy the buffer.
- */
static INLINE void
-_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
+fenced_buffer_destroy_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
{
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
-
assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
+
assert(!fenced_buf->fence);
-#ifdef DEBUG
assert(fenced_buf->head.prev);
assert(fenced_buf->head.next);
LIST_DEL(&fenced_buf->head);
- assert(fenced_list->numUnfenced);
- --fenced_list->numUnfenced;
-#else
- (void)fenced_list;
-#endif
- pb_reference(&fenced_buf->buffer, NULL);
+ assert(fenced_mgr->num_unfenced);
+ --fenced_mgr->num_unfenced;
+
+ fenced_buffer_destroy_gpu_storage_locked(fenced_buf);
+ fenced_buffer_destroy_cpu_storage_locked(fenced_buf);
+
FREE(fenced_buf);
}
+/**
+ * Add the buffer to the fenced list.
+ *
+ * Reference count should be incremented before calling this function.
+ */
static INLINE void
-_fenced_buffer_remove(struct fenced_buffer_list *fenced_list,
- struct fenced_buffer *fenced_buf)
+fenced_buffer_add_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
+{
+ assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+ assert(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
+ assert(fenced_buf->fence);
+
+ p_atomic_inc(&fenced_buf->base.base.reference.count);
+
+ LIST_DEL(&fenced_buf->head);
+ assert(fenced_mgr->num_unfenced);
+ --fenced_mgr->num_unfenced;
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->fenced);
+ ++fenced_mgr->num_fenced;
+}
+
+
+/**
+ * Remove the buffer from the fenced list, and potentially destroy the buffer
+ * if the reference count reaches zero.
+ *
+ * Returns TRUE if the buffer was detroyed.
+ */
+static INLINE boolean
+fenced_buffer_remove_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
{
- struct pb_fence_ops *ops = fenced_list->ops;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
assert(fenced_buf->fence);
- assert(fenced_buf->list == fenced_list);
-
+ assert(fenced_buf->mgr == fenced_mgr);
+
ops->fence_reference(ops, &fenced_buf->fence, NULL);
fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
-
+
assert(fenced_buf->head.prev);
assert(fenced_buf->head.next);
-
+
LIST_DEL(&fenced_buf->head);
- assert(fenced_list->numDelayed);
- --fenced_list->numDelayed;
-
-#ifdef DEBUG
- LIST_ADDTAIL(&fenced_buf->head, &fenced_list->unfenced);
- ++fenced_list->numUnfenced;
-#endif
-
- /**
- * FIXME!!!
- */
+ assert(fenced_mgr->num_fenced);
+ --fenced_mgr->num_fenced;
+
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->unfenced);
+ ++fenced_mgr->num_unfenced;
+
+ if (p_atomic_dec_zero(&fenced_buf->base.base.reference.count)) {
+ fenced_buffer_destroy_locked(fenced_mgr, fenced_buf);
+ return TRUE;
+ }
- if(!pipe_is_referenced(&fenced_buf->base.base.reference))
- _fenced_buffer_destroy(fenced_buf);
+ return FALSE;
}
+/**
+ * Wait for the fence to expire, and remove it from the fenced list.
+ *
+ * This function will release and re-aquire the mutex, so any copy of mutable
+ * state must be discarded after calling it.
+ */
static INLINE enum pipe_error
-_fenced_buffer_finish(struct fenced_buffer *fenced_buf)
+fenced_buffer_finish_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
{
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- struct pb_fence_ops *ops = fenced_list->ops;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
+ enum pipe_error ret = PIPE_ERROR;
#if 0
debug_warning("waiting for GPU");
#endif
+ assert(pipe_is_referenced(&fenced_buf->base.base.reference));
assert(fenced_buf->fence);
+
if(fenced_buf->fence) {
- if(ops->fence_finish(ops, fenced_buf->fence, 0) != 0) {
- return PIPE_ERROR;
+ struct pipe_fence_handle *fence = NULL;
+ int finished;
+ boolean proceed;
+
+ ops->fence_reference(ops, &fence, fenced_buf->fence);
+
+ pipe_mutex_unlock(fenced_mgr->mutex);
+
+ finished = ops->fence_finish(ops, fenced_buf->fence, 0);
+
+ pipe_mutex_lock(fenced_mgr->mutex);
+
+ assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+
+ /*
+ * Only proceed if the fence object didn't change in the meanwhile.
+ * Otherwise assume the work has been already carried out by another
+ * thread that re-aquired the lock before us.
+ */
+ proceed = fence == fenced_buf->fence ? TRUE : FALSE;
+
+ ops->fence_reference(ops, &fence, NULL);
+
+ if(proceed && finished == 0) {
+ /*
+ * Remove from the fenced list
+ */
+
+ boolean destroyed;
+
+ destroyed = fenced_buffer_remove_locked(fenced_mgr, fenced_buf);
+
+ /* TODO: remove consequents buffers with the same fence? */
+
+ assert(!destroyed);
+
+ fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
+
+ ret = PIPE_OK;
}
- /* Remove from the fenced list */
- /* TODO: remove consequents */
- _fenced_buffer_remove(fenced_list, fenced_buf);
}
- fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE;
- return PIPE_OK;
+ return ret;
}
/**
- * Free as many fenced buffers from the list head as possible.
+ * Remove as many fenced buffers from the fenced list as possible.
+ *
+ * Returns TRUE if at least one buffer was removed.
*/
-static void
-_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
- int wait)
+static boolean
+fenced_manager_check_signalled_locked(struct fenced_manager *fenced_mgr,
+ boolean wait)
{
- struct pb_fence_ops *ops = fenced_list->ops;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
struct list_head *curr, *next;
struct fenced_buffer *fenced_buf;
- struct pb_buffer *pb_buf;
struct pipe_fence_handle *prev_fence = NULL;
+ boolean ret = FALSE;
- curr = fenced_list->delayed.next;
+ curr = fenced_mgr->fenced.next;
next = curr->next;
- while(curr != &fenced_list->delayed) {
+ while(curr != &fenced_mgr->fenced) {
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
if(fenced_buf->fence != prev_fence) {
int signaled;
- if (wait)
+
+ if (wait) {
signaled = ops->fence_finish(ops, fenced_buf->fence, 0);
- else
+
+ /*
+ * Don't return just now. Instead preemptively check if the
+ * following buffers' fences already expired, without further waits.
+ */
+ wait = FALSE;
+ }
+ else {
signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
- if (signaled != 0)
- break;
+ }
+
+ if (signaled != 0) {
+ return ret;
+ }
+
prev_fence = fenced_buf->fence;
}
else {
+ /* This buffer's fence object is identical to the previous buffer's
+ * fence object, so no need to check the fence again.
+ */
assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
}
- _fenced_buffer_remove(fenced_list, fenced_buf);
+ fenced_buffer_remove_locked(fenced_mgr, fenced_buf);
+
+ ret = TRUE;
+
+ curr = next;
+ next = curr->next;
+ }
+
+ return ret;
+}
+
+
+/**
+ * Try to free some GPU memory by backing it up into CPU memory.
+ *
+ * Returns TRUE if at least one buffer was freed.
+ */
+static boolean
+fenced_manager_free_gpu_storage_locked(struct fenced_manager *fenced_mgr)
+{
+ struct list_head *curr, *next;
+ struct fenced_buffer *fenced_buf;
- curr = next;
+ curr = fenced_mgr->unfenced.next;
+ next = curr->next;
+ while(curr != &fenced_mgr->unfenced) {
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+
+ /*
+ * We can only move storage if the buffer is not mapped and not
+ * validated.
+ */
+ if(fenced_buf->buffer &&
+ !fenced_buf->mapcount &&
+ !fenced_buf->vl) {
+ enum pipe_error ret;
+
+ ret = fenced_buffer_create_cpu_storage_locked(fenced_mgr, fenced_buf);
+ if(ret == PIPE_OK) {
+ ret = fenced_buffer_copy_storage_to_cpu_locked(fenced_buf);
+ if(ret == PIPE_OK) {
+ fenced_buffer_destroy_gpu_storage_locked(fenced_buf);
+ return TRUE;
+ }
+ fenced_buffer_destroy_cpu_storage_locked(fenced_buf);
+ }
+ }
+
+ curr = next;
next = curr->next;
}
+
+ return FALSE;
}
+/**
+ * Destroy CPU storage for this buffer.
+ */
static void
-fenced_buffer_destroy(struct pb_buffer *buf)
+fenced_buffer_destroy_cpu_storage_locked(struct fenced_buffer *fenced_buf)
{
- struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ if(fenced_buf->data) {
+ align_free(fenced_buf->data);
+ fenced_buf->data = NULL;
+ assert(fenced_buf->mgr->cpu_total_size >= fenced_buf->size);
+ fenced_buf->mgr->cpu_total_size -= fenced_buf->size;
+ }
+}
- pipe_mutex_lock(fenced_list->mutex);
- assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
- if (fenced_buf->fence) {
- struct pb_fence_ops *ops = fenced_list->ops;
- if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
- struct list_head *curr, *prev;
- curr = &fenced_buf->head;
- prev = curr->prev;
- do {
- fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0);
- _fenced_buffer_remove(fenced_list, fenced_buf);
- curr = prev;
- prev = curr->prev;
- } while (curr != &fenced_list->delayed);
- }
- else {
- /* delay destruction */
+
+/**
+ * Create CPU storage for this buffer.
+ */
+static enum pipe_error
+fenced_buffer_create_cpu_storage_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
+{
+ assert(!fenced_buf->data);
+ if(fenced_buf->data)
+ return PIPE_OK;
+
+ if (fenced_mgr->cpu_total_size + fenced_buf->size > fenced_mgr->max_cpu_total_size)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ fenced_buf->data = align_malloc(fenced_buf->size, fenced_buf->desc.alignment);
+ if(!fenced_buf->data)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ fenced_mgr->cpu_total_size += fenced_buf->size;
+
+ return PIPE_OK;
+}
+
+
+/**
+ * Destroy the GPU storage.
+ */
+static void
+fenced_buffer_destroy_gpu_storage_locked(struct fenced_buffer *fenced_buf)
+{
+ if(fenced_buf->buffer) {
+ pb_reference(&fenced_buf->buffer, NULL);
+ }
+}
+
+
+/**
+ * Try to create GPU storage for this buffer.
+ *
+ * This function is a shorthand around pb_manager::create_buffer for
+ * fenced_buffer_create_gpu_storage_locked()'s benefit.
+ */
+static INLINE boolean
+fenced_buffer_try_create_gpu_storage_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf)
+{
+ struct pb_manager *provider = fenced_mgr->provider;
+
+ assert(!fenced_buf->buffer);
+
+ fenced_buf->buffer = provider->create_buffer(fenced_mgr->provider,
+ fenced_buf->size,
+ &fenced_buf->desc);
+ return fenced_buf->buffer ? TRUE : FALSE;
+}
+
+
+/**
+ * Create GPU storage for this buffer.
+ */
+static enum pipe_error
+fenced_buffer_create_gpu_storage_locked(struct fenced_manager *fenced_mgr,
+ struct fenced_buffer *fenced_buf,
+ boolean wait)
+{
+ assert(!fenced_buf->buffer);
+
+ /*
+ * Check for signaled buffers before trying to allocate.
+ */
+ fenced_manager_check_signalled_locked(fenced_mgr, FALSE);
+
+ fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf);
+
+ /*
+ * Keep trying while there is some sort of progress:
+ * - fences are expiring,
+ * - or buffers are being being swapped out from GPU memory into CPU memory.
+ */
+ while(!fenced_buf->buffer &&
+ (fenced_manager_check_signalled_locked(fenced_mgr, FALSE) ||
+ fenced_manager_free_gpu_storage_locked(fenced_mgr))) {
+ fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf);
+ }
+
+ if(!fenced_buf->buffer && wait) {
+ /*
+ * Same as before, but this time around, wait to free buffers if
+ * necessary.
+ */
+ while(!fenced_buf->buffer &&
+ (fenced_manager_check_signalled_locked(fenced_mgr, TRUE) ||
+ fenced_manager_free_gpu_storage_locked(fenced_mgr))) {
+ fenced_buffer_try_create_gpu_storage_locked(fenced_mgr, fenced_buf);
}
}
- else {
- _fenced_buffer_destroy(fenced_buf);
+
+ if(!fenced_buf->buffer) {
+ if(0)
+ fenced_manager_dump_locked(fenced_mgr);
+
+ /* give up */
+ return PIPE_ERROR_OUT_OF_MEMORY;
}
- pipe_mutex_unlock(fenced_list->mutex);
+
+ return PIPE_OK;
+}
+
+
+static enum pipe_error
+fenced_buffer_copy_storage_to_gpu_locked(struct fenced_buffer *fenced_buf)
+{
+ uint8_t *map;
+
+ assert(fenced_buf->data);
+ assert(fenced_buf->buffer);
+
+ map = pb_map(fenced_buf->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+ if(!map)
+ return PIPE_ERROR;
+
+ memcpy(map, fenced_buf->data, fenced_buf->size);
+
+ pb_unmap(fenced_buf->buffer);
+
+ return PIPE_OK;
+}
+
+
+static enum pipe_error
+fenced_buffer_copy_storage_to_cpu_locked(struct fenced_buffer *fenced_buf)
+{
+ const uint8_t *map;
+
+ assert(fenced_buf->data);
+ assert(fenced_buf->buffer);
+
+ map = pb_map(fenced_buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ if(!map)
+ return PIPE_ERROR;
+
+ memcpy(fenced_buf->data, map, fenced_buf->size);
+
+ pb_unmap(fenced_buf->buffer);
+
+ return PIPE_OK;
+}
+
+
+static void
+fenced_buffer_destroy(struct pb_buffer *buf)
+{
+ struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
+
+ assert(!pipe_is_referenced(&fenced_buf->base.base.reference));
+
+ pipe_mutex_lock(fenced_mgr->mutex);
+
+ fenced_buffer_destroy_locked(fenced_mgr, fenced_buf);
+
+ pipe_mutex_unlock(fenced_mgr->mutex);
}
static void *
-fenced_buffer_map(struct pb_buffer *buf,
+fenced_buffer_map(struct pb_buffer *buf,
unsigned flags)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- struct fenced_buffer_list *fenced_list = fenced_buf->list;
- struct pb_fence_ops *ops = fenced_list->ops;
- void *map;
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
+ void *map = NULL;
+
+ pipe_mutex_lock(fenced_mgr->mutex);
assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
-
- /* Serialize writes */
- if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) ||
- ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) {
- if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- /* Don't wait for the GPU to finish writing */
- if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0)
- _fenced_buffer_remove(fenced_list, fenced_buf);
- else
- return NULL;
+
+ /*
+ * Serialize writes.
+ */
+ while((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) ||
+ ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) &&
+ (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) {
+
+ /*
+ * Don't wait for the GPU to finish accessing it, if blocking is forbidden.
+ */
+ if((flags & PIPE_BUFFER_USAGE_DONTBLOCK) &&
+ ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) {
+ goto done;
}
- else {
- /* Wait for the GPU to finish writing */
- _fenced_buffer_finish(fenced_buf);
+
+ if (flags & PIPE_BUFFER_USAGE_UNSYNCHRONIZED) {
+ break;
}
+
+ /*
+ * Wait for the GPU to finish accessing. This will release and re-acquire
+ * the mutex, so all copies of mutable state must be discarded.
+ */
+ fenced_buffer_finish_locked(fenced_mgr, fenced_buf);
}
-#if 0
- /* Check for CPU write access (read is OK) */
- if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
- /* this is legal -- just for debugging */
- debug_warning("concurrent CPU writes");
+ if(fenced_buf->buffer) {
+ map = pb_map(fenced_buf->buffer, flags);
}
-#endif
-
- map = pb_map(fenced_buf->buffer, flags);
+ else {
+ assert(fenced_buf->data);
+ map = fenced_buf->data;
+ }
+
if(map) {
++fenced_buf->mapcount;
fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;
}
+done:
+ pipe_mutex_unlock(fenced_mgr->mutex);
+
return map;
}
@@ -333,13 +735,20 @@ static void
fenced_buffer_unmap(struct pb_buffer *buf)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
+
+ pipe_mutex_lock(fenced_mgr->mutex);
+
assert(fenced_buf->mapcount);
if(fenced_buf->mapcount) {
- pb_unmap(fenced_buf->buffer);
+ if (fenced_buf->buffer)
+ pb_unmap(fenced_buf->buffer);
--fenced_buf->mapcount;
if(!fenced_buf->mapcount)
fenced_buf->flags &= ~PIPE_BUFFER_USAGE_CPU_READ_WRITE;
}
+
+ pipe_mutex_unlock(fenced_mgr->mutex);
}
@@ -349,48 +758,72 @@ fenced_buffer_validate(struct pb_buffer *buf,
unsigned flags)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
enum pipe_error ret;
-
+
+ pipe_mutex_lock(fenced_mgr->mutex);
+
if(!vl) {
/* invalidate */
fenced_buf->vl = NULL;
fenced_buf->validation_flags = 0;
- return PIPE_OK;
+ ret = PIPE_OK;
+ goto done;
}
-
+
assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE);
assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE));
flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE;
- /* Buffer cannot be validated in two different lists */
- if(fenced_buf->vl && fenced_buf->vl != vl)
- return PIPE_ERROR_RETRY;
-
-#if 0
- /* Do not validate if buffer is still mapped */
- if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
- /* TODO: wait for the thread that mapped the buffer to unmap it */
- return PIPE_ERROR_RETRY;
+ /* Buffer cannot be validated in two different lists */
+ if(fenced_buf->vl && fenced_buf->vl != vl) {
+ ret = PIPE_ERROR_RETRY;
+ goto done;
}
- /* Final sanity checking */
- assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
- assert(!fenced_buf->mapcount);
-#endif
if(fenced_buf->vl == vl &&
(fenced_buf->validation_flags & flags) == flags) {
/* Nothing to do -- buffer already validated */
- return PIPE_OK;
+ ret = PIPE_OK;
+ goto done;
+ }
+
+ /*
+ * Create and update GPU storage.
+ */
+ if(!fenced_buf->buffer) {
+ assert(!fenced_buf->mapcount);
+
+ ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, TRUE);
+ if(ret != PIPE_OK) {
+ goto done;
+ }
+
+ ret = fenced_buffer_copy_storage_to_gpu_locked(fenced_buf);
+ if(ret != PIPE_OK) {
+ fenced_buffer_destroy_gpu_storage_locked(fenced_buf);
+ goto done;
+ }
+
+ if(fenced_buf->mapcount) {
+ debug_printf("warning: validating a buffer while it is still mapped\n");
+ }
+ else {
+ fenced_buffer_destroy_cpu_storage_locked(fenced_buf);
+ }
}
-
+
ret = pb_validate(fenced_buf->buffer, vl, flags);
if (ret != PIPE_OK)
- return ret;
-
+ goto done;
+
fenced_buf->vl = vl;
fenced_buf->validation_flags |= flags;
-
- return PIPE_OK;
+
+done:
+ pipe_mutex_unlock(fenced_mgr->mutex);
+
+ return ret;
}
@@ -398,36 +831,37 @@ static void
fenced_buffer_fence(struct pb_buffer *buf,
struct pipe_fence_handle *fence)
{
- struct fenced_buffer *fenced_buf;
- struct fenced_buffer_list *fenced_list;
- struct pb_fence_ops *ops;
+ struct fenced_buffer *fenced_buf = fenced_buffer(buf);
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
+ struct pb_fence_ops *ops = fenced_mgr->ops;
- fenced_buf = fenced_buffer(buf);
- fenced_list = fenced_buf->list;
- ops = fenced_list->ops;
-
- if(fence == fenced_buf->fence) {
- /* Nothing to do */
- return;
- }
+ pipe_mutex_lock(fenced_mgr->mutex);
- assert(fenced_buf->vl);
- assert(fenced_buf->validation_flags);
-
- pipe_mutex_lock(fenced_list->mutex);
- if (fenced_buf->fence)
- _fenced_buffer_remove(fenced_list, fenced_buf);
- if (fence) {
- ops->fence_reference(ops, &fenced_buf->fence, fence);
- fenced_buf->flags |= fenced_buf->validation_flags;
- _fenced_buffer_add(fenced_buf);
+ assert(pipe_is_referenced(&fenced_buf->base.base.reference));
+ assert(fenced_buf->buffer);
+
+ if(fence != fenced_buf->fence) {
+ assert(fenced_buf->vl);
+ assert(fenced_buf->validation_flags);
+
+ if (fenced_buf->fence) {
+ boolean destroyed;
+ destroyed = fenced_buffer_remove_locked(fenced_mgr, fenced_buf);
+ assert(!destroyed);
+ }
+ if (fence) {
+ ops->fence_reference(ops, &fenced_buf->fence, fence);
+ fenced_buf->flags |= fenced_buf->validation_flags;
+ fenced_buffer_add_locked(fenced_mgr, fenced_buf);
+ }
+
+ pb_fence(fenced_buf->buffer, fence);
+
+ fenced_buf->vl = NULL;
+ fenced_buf->validation_flags = 0;
}
- pipe_mutex_unlock(fenced_list->mutex);
-
- pb_fence(fenced_buf->buffer, fence);
- fenced_buf->vl = NULL;
- fenced_buf->validation_flags = 0;
+ pipe_mutex_unlock(fenced_mgr->mutex);
}
@@ -437,11 +871,29 @@ fenced_buffer_get_base_buffer(struct pb_buffer *buf,
pb_size *offset)
{
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
- pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
+ struct fenced_manager *fenced_mgr = fenced_buf->mgr;
+
+ pipe_mutex_lock(fenced_mgr->mutex);
+
+ /*
+ * This should only be called when the buffer is validated. Typically
+ * when processing relocations.
+ */
+ assert(fenced_buf->vl);
+ assert(fenced_buf->buffer);
+
+ if(fenced_buf->buffer)
+ pb_get_base_buffer(fenced_buf->buffer, base_buf, offset);
+ else {
+ *base_buf = buf;
+ *offset = 0;
+ }
+
+ pipe_mutex_unlock(fenced_mgr->mutex);
}
-static const struct pb_vtbl
+static const struct pb_vtbl
fenced_buffer_vtbl = {
fenced_buffer_destroy,
fenced_buffer_map,
@@ -452,147 +904,166 @@ fenced_buffer_vtbl = {
};
-struct pb_buffer *
-fenced_buffer_create(struct fenced_buffer_list *fenced_list,
- struct pb_buffer *buffer)
+/**
+ * Wrap a buffer in a fenced buffer.
+ */
+static struct pb_buffer *
+fenced_bufmgr_create_buffer(struct pb_manager *mgr,
+ pb_size size,
+ const struct pb_desc *desc)
{
- struct fenced_buffer *buf;
-
- if(!buffer)
- return NULL;
-
- buf = CALLOC_STRUCT(fenced_buffer);
- if(!buf) {
- pb_reference(&buffer, NULL);
- return NULL;
+ struct fenced_manager *fenced_mgr = fenced_manager(mgr);
+ struct fenced_buffer *fenced_buf;
+ enum pipe_error ret;
+
+ /*
+ * Don't stall the GPU, waste time evicting buffers, or waste memory
+ * trying to create a buffer that will most likely never fit into the
+ * graphics aperture.
+ */
+ if(size > fenced_mgr->max_buffer_size) {
+ goto no_buffer;
}
-
- pipe_reference_init(&buf->base.base.reference, 1);
- buf->base.base.alignment = buffer->base.alignment;
- buf->base.base.usage = buffer->base.usage;
- buf->base.base.size = buffer->base.size;
-
- buf->base.vtbl = &fenced_buffer_vtbl;
- buf->buffer = buffer;
- buf->list = fenced_list;
-
-#ifdef DEBUG
- pipe_mutex_lock(fenced_list->mutex);
- LIST_ADDTAIL(&buf->head, &fenced_list->unfenced);
- ++fenced_list->numUnfenced;
- pipe_mutex_unlock(fenced_list->mutex);
-#endif
- return &buf->base;
-}
+ fenced_buf = CALLOC_STRUCT(fenced_buffer);
+ if(!fenced_buf)
+ goto no_buffer;
+ pipe_reference_init(&fenced_buf->base.base.reference, 1);
+ fenced_buf->base.base.alignment = desc->alignment;
+ fenced_buf->base.base.usage = desc->usage;
+ fenced_buf->base.base.size = size;
+ fenced_buf->size = size;
+ fenced_buf->desc = *desc;
-struct fenced_buffer_list *
-fenced_buffer_list_create(struct pb_fence_ops *ops)
-{
- struct fenced_buffer_list *fenced_list;
+ fenced_buf->base.vtbl = &fenced_buffer_vtbl;
+ fenced_buf->mgr = fenced_mgr;
- fenced_list = CALLOC_STRUCT(fenced_buffer_list);
- if (!fenced_list)
- return NULL;
+ pipe_mutex_lock(fenced_mgr->mutex);
+
+ /*
+ * Try to create GPU storage without stalling,
+ */
+ ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, FALSE);
- fenced_list->ops = ops;
+ /*
+ * Attempt to use CPU memory to avoid stalling the GPU.
+ */
+ if(ret != PIPE_OK) {
+ ret = fenced_buffer_create_cpu_storage_locked(fenced_mgr, fenced_buf);
+ }
- LIST_INITHEAD(&fenced_list->delayed);
- fenced_list->numDelayed = 0;
-
-#ifdef DEBUG
- LIST_INITHEAD(&fenced_list->unfenced);
- fenced_list->numUnfenced = 0;
-#endif
+ /*
+ * Create GPU storage, waiting for some to be available.
+ */
+ if(ret != PIPE_OK) {
+ ret = fenced_buffer_create_gpu_storage_locked(fenced_mgr, fenced_buf, TRUE);
+ }
+
+ /*
+ * Give up.
+ */
+ if(ret != PIPE_OK) {
+ goto no_storage;
+ }
- pipe_mutex_init(fenced_list->mutex);
+ assert(fenced_buf->buffer || fenced_buf->data);
- return fenced_list;
-}
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_mgr->unfenced);
+ ++fenced_mgr->num_unfenced;
+ pipe_mutex_unlock(fenced_mgr->mutex);
+ return &fenced_buf->base;
-void
-fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
- int wait)
-{
- pipe_mutex_lock(fenced_list->mutex);
- _fenced_buffer_list_check_free(fenced_list, wait);
- pipe_mutex_unlock(fenced_list->mutex);
+no_storage:
+ pipe_mutex_unlock(fenced_mgr->mutex);
+ FREE(fenced_buf);
+no_buffer:
+ return NULL;
}
-#ifdef DEBUG
-void
-fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
+static void
+fenced_bufmgr_flush(struct pb_manager *mgr)
{
- struct pb_fence_ops *ops = fenced_list->ops;
- struct list_head *curr, *next;
- struct fenced_buffer *fenced_buf;
+ struct fenced_manager *fenced_mgr = fenced_manager(mgr);
- pipe_mutex_lock(fenced_list->mutex);
+ pipe_mutex_lock(fenced_mgr->mutex);
+ while(fenced_manager_check_signalled_locked(fenced_mgr, TRUE))
+ ;
+ pipe_mutex_unlock(fenced_mgr->mutex);
- debug_printf("%10s %7s %7s %10s %s\n",
- "buffer", "size", "refcount", "fence", "signalled");
-
- curr = fenced_list->unfenced.next;
- next = curr->next;
- while(curr != &fenced_list->unfenced) {
- fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- assert(!fenced_buf->fence);
- debug_printf("%10p %7u %7u\n",
- (void *) fenced_buf,
- fenced_buf->base.base.size,
- p_atomic_read(&fenced_buf->base.base.reference.count));
- curr = next;
- next = curr->next;
- }
-
- curr = fenced_list->delayed.next;
- next = curr->next;
- while(curr != &fenced_list->delayed) {
- int signaled;
- fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
- signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
- debug_printf("%10p %7u %7u %10p %s\n",
- (void *) fenced_buf,
- fenced_buf->base.base.size,
- p_atomic_read(&fenced_buf->base.base.reference.count),
- (void *) fenced_buf->fence,
- signaled == 0 ? "y" : "n");
- curr = next;
- next = curr->next;
- }
-
- pipe_mutex_unlock(fenced_list->mutex);
+ assert(fenced_mgr->provider->flush);
+ if(fenced_mgr->provider->flush)
+ fenced_mgr->provider->flush(fenced_mgr->provider);
}
-#endif
-void
-fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list)
+static void
+fenced_bufmgr_destroy(struct pb_manager *mgr)
{
- pipe_mutex_lock(fenced_list->mutex);
+ struct fenced_manager *fenced_mgr = fenced_manager(mgr);
+
+ pipe_mutex_lock(fenced_mgr->mutex);
/* Wait on outstanding fences */
- while (fenced_list->numDelayed) {
- pipe_mutex_unlock(fenced_list->mutex);
+ while (fenced_mgr->num_fenced) {
+ pipe_mutex_unlock(fenced_mgr->mutex);
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
sched_yield();
#endif
- _fenced_buffer_list_check_free(fenced_list, 1);
- pipe_mutex_lock(fenced_list->mutex);
+ pipe_mutex_lock(fenced_mgr->mutex);
+ while(fenced_manager_check_signalled_locked(fenced_mgr, TRUE))
+ ;
}
#ifdef DEBUG
- /*assert(!fenced_list->numUnfenced);*/
+ /*assert(!fenced_mgr->num_unfenced);*/
#endif
-
- pipe_mutex_unlock(fenced_list->mutex);
-
- fenced_list->ops->destroy(fenced_list->ops);
-
- FREE(fenced_list);
+
+ pipe_mutex_unlock(fenced_mgr->mutex);
+ pipe_mutex_destroy(fenced_mgr->mutex);
+
+ if(fenced_mgr->provider)
+ fenced_mgr->provider->destroy(fenced_mgr->provider);
+
+ fenced_mgr->ops->destroy(fenced_mgr->ops);
+
+ FREE(fenced_mgr);
}
+struct pb_manager *
+fenced_bufmgr_create(struct pb_manager *provider,
+ struct pb_fence_ops *ops,
+ pb_size max_buffer_size,
+ pb_size max_cpu_total_size)
+{
+ struct fenced_manager *fenced_mgr;
+
+ if(!provider)
+ return NULL;
+
+ fenced_mgr = CALLOC_STRUCT(fenced_manager);
+ if (!fenced_mgr)
+ return NULL;
+
+ fenced_mgr->base.destroy = fenced_bufmgr_destroy;
+ fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer;
+ fenced_mgr->base.flush = fenced_bufmgr_flush;
+
+ fenced_mgr->provider = provider;
+ fenced_mgr->ops = ops;
+ fenced_mgr->max_buffer_size = max_buffer_size;
+ fenced_mgr->max_cpu_total_size = max_cpu_total_size;
+
+ LIST_INITHEAD(&fenced_mgr->fenced);
+ fenced_mgr->num_fenced = 0;
+
+ LIST_INITHEAD(&fenced_mgr->unfenced);
+ fenced_mgr->num_unfenced = 0;
+
+ pipe_mutex_init(fenced_mgr->mutex);
+
+ return &fenced_mgr->base;
+}
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h
index 034ca1e024a..0372f81d0a1 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h
@@ -98,43 +98,6 @@ struct pb_fence_ops
};
-/**
- * Create a fenced buffer list.
- *
- * See also fenced_bufmgr_create for a more convenient way to use this.
- */
-struct fenced_buffer_list *
-fenced_buffer_list_create(struct pb_fence_ops *ops);
-
-
-/**
- * Walk the fenced buffer list to check and free signalled buffers.
- */
-void
-fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
- int wait);
-
-
-#ifdef DEBUG
-void
-fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list);
-#endif
-
-
-void
-fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list);
-
-
-/**
- * Wrap a buffer in a fenced buffer.
- *
- * NOTE: this will not increase the buffer reference count.
- */
-struct pb_buffer *
-fenced_buffer_create(struct fenced_buffer_list *fenced,
- struct pb_buffer *buffer);
-
-
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
index 8c8d7130781..06669917ff6 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
@@ -175,7 +175,9 @@ struct pb_fence_ops;
*/
struct pb_manager *
fenced_bufmgr_create(struct pb_manager *provider,
- struct pb_fence_ops *ops);
+ struct pb_fence_ops *ops,
+ pb_size max_buffer_size,
+ pb_size max_cpu_total_size);
struct pb_manager *
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
index 6e3214ca9c9..8f74180a111 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
@@ -371,6 +371,9 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
struct pb_desc real_desc;
pb_size real_size;
+ assert(size);
+ assert(desc->alignment);
+
buf = CALLOC_STRUCT(pb_debug_buffer);
if(!buf)
return NULL;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c
deleted file mode 100644
index 97dd1427fda..00000000000
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006 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
- * A buffer manager that wraps buffers in fenced buffers.
- *
- * \author Jose Fonseca <[email protected]>
- */
-
-
-#include "util/u_debug.h"
-#include "util/u_memory.h"
-
-#include "pb_buffer.h"
-#include "pb_buffer_fenced.h"
-#include "pb_bufmgr.h"
-
-
-struct fenced_pb_manager
-{
- struct pb_manager base;
-
- struct pb_manager *provider;
-
- struct fenced_buffer_list *fenced_list;
-};
-
-
-static INLINE struct fenced_pb_manager *
-fenced_pb_manager(struct pb_manager *mgr)
-{
- assert(mgr);
- return (struct fenced_pb_manager *)mgr;
-}
-
-
-static struct pb_buffer *
-fenced_bufmgr_create_buffer(struct pb_manager *mgr,
- pb_size size,
- const struct pb_desc *desc)
-{
- struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
- struct pb_buffer *buf;
- struct pb_buffer *fenced_buf;
-
- /* check for free buffers before allocating new ones */
- fenced_buffer_list_check_free(fenced_mgr->fenced_list, 0);
-
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
- if(!buf) {
- /* try harder to get a buffer */
- fenced_buffer_list_check_free(fenced_mgr->fenced_list, 1);
-
- buf = fenced_mgr->provider->create_buffer(fenced_mgr->provider, size, desc);
- if(!buf) {
-#if 0
- fenced_buffer_list_dump(fenced_mgr->fenced_list);
-#endif
-
- /* give up */
- return NULL;
- }
- }
-
- fenced_buf = fenced_buffer_create(fenced_mgr->fenced_list, buf);
- if(!fenced_buf) {
- pb_reference(&buf, NULL);
- }
-
- return fenced_buf;
-}
-
-
-static void
-fenced_bufmgr_flush(struct pb_manager *mgr)
-{
- struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
-
- fenced_buffer_list_check_free(fenced_mgr->fenced_list, TRUE);
-
- assert(fenced_mgr->provider->flush);
- if(fenced_mgr->provider->flush)
- fenced_mgr->provider->flush(fenced_mgr->provider);
-}
-
-
-static void
-fenced_bufmgr_destroy(struct pb_manager *mgr)
-{
- struct fenced_pb_manager *fenced_mgr = fenced_pb_manager(mgr);
-
- fenced_buffer_list_destroy(fenced_mgr->fenced_list);
-
- if(fenced_mgr->provider)
- fenced_mgr->provider->destroy(fenced_mgr->provider);
-
- FREE(fenced_mgr);
-}
-
-
-struct pb_manager *
-fenced_bufmgr_create(struct pb_manager *provider,
- struct pb_fence_ops *ops)
-{
- struct fenced_pb_manager *fenced_mgr;
-
- if(!provider)
- return NULL;
-
- fenced_mgr = CALLOC_STRUCT(fenced_pb_manager);
- if (!fenced_mgr)
- return NULL;
-
- fenced_mgr->base.destroy = fenced_bufmgr_destroy;
- fenced_mgr->base.create_buffer = fenced_bufmgr_create_buffer;
- fenced_mgr->base.flush = fenced_bufmgr_flush;
-
- fenced_mgr->provider = provider;
- fenced_mgr->fenced_list = fenced_buffer_list_create(ops);
- if(!fenced_mgr->fenced_list) {
- FREE(fenced_mgr);
- return NULL;
- }
-
- return &fenced_mgr->base;
-}
diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c
index ce40c0cf0e6..903afc749d3 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_validate.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c
@@ -39,7 +39,6 @@
#include "util/u_debug.h"
#include "pb_buffer.h"
-#include "pb_buffer_fenced.h"
#include "pb_validate.h"
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index de9cbc86305..e38b0be7ab5 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -103,6 +103,7 @@ tgsi_default_declaration( void )
declaration.File = TGSI_FILE_NULL;
declaration.UsageMask = TGSI_WRITEMASK_XYZW;
declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+ declaration.Dimension = 0;
declaration.Semantic = 0;
declaration.Centroid = 0;
declaration.Invariant = 0;
@@ -116,6 +117,7 @@ tgsi_build_declaration(
unsigned file,
unsigned usage_mask,
unsigned interpolate,
+ unsigned dimension,
unsigned semantic,
unsigned centroid,
unsigned invariant,
@@ -130,6 +132,7 @@ tgsi_build_declaration(
declaration.File = file;
declaration.UsageMask = usage_mask;
declaration.Interpolate = interpolate;
+ declaration.Dimension = dimension;
declaration.Semantic = semantic;
declaration.Centroid = centroid;
declaration.Invariant = invariant;
@@ -183,6 +186,7 @@ tgsi_build_full_declaration(
full_decl->Declaration.File,
full_decl->Declaration.UsageMask,
full_decl->Declaration.Interpolate,
+ full_decl->Declaration.Dimension,
full_decl->Declaration.Semantic,
full_decl->Declaration.Centroid,
full_decl->Declaration.Invariant,
@@ -199,6 +203,20 @@ tgsi_build_full_declaration(
declaration,
header );
+ if (full_decl->Declaration.Dimension) {
+ struct tgsi_declaration_dimension *dd;
+
+ if (maxsize <= size) {
+ return 0;
+ }
+ dd = (struct tgsi_declaration_dimension *)&tokens[size];
+ size++;
+
+ *dd = tgsi_build_declaration_dimension(full_decl->Dim.Index2D,
+ declaration,
+ header);
+ }
+
if( full_decl->Declaration.Semantic ) {
struct tgsi_declaration_semantic *ds;
@@ -249,6 +267,34 @@ tgsi_build_declaration_range(
return declaration_range;
}
+struct tgsi_declaration_dimension
+tgsi_default_declaration_dimension(void)
+{
+ struct tgsi_declaration_dimension dd;
+
+ dd.Index2D = 0;
+ dd.Padding = 0;
+
+ return dd;
+}
+
+struct tgsi_declaration_dimension
+tgsi_build_declaration_dimension(unsigned index_2d,
+ struct tgsi_declaration *declaration,
+ struct tgsi_header *header)
+{
+ struct tgsi_declaration_dimension dd;
+
+ assert(index_2d <= 0xFFFF);
+
+ dd = tgsi_default_declaration_dimension();
+ dd.Index2D = index_2d;
+
+ declaration_grow(declaration, header);
+
+ return dd;
+}
+
struct tgsi_declaration_semantic
tgsi_default_declaration_semantic( void )
{
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 9de2757fe40..ebee4ce5f6a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -64,6 +64,7 @@ tgsi_build_declaration(
unsigned file,
unsigned usage_mask,
unsigned interpolate,
+ unsigned dimension,
unsigned semantic,
unsigned centroid,
unsigned invariant,
@@ -89,6 +90,14 @@ tgsi_build_declaration_range(
struct tgsi_declaration *declaration,
struct tgsi_header *header );
+struct tgsi_declaration_dimension
+tgsi_default_declaration_dimension(void);
+
+struct tgsi_declaration_dimension
+tgsi_build_declaration_dimension(unsigned index_2d,
+ struct tgsi_declaration *declaration,
+ struct tgsi_header *header);
+
struct tgsi_declaration_semantic
tgsi_default_declaration_semantic( void );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index d7ff262f30a..dd365558755 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -159,7 +159,9 @@ static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
- "GS_MAX_OUTPUT_VERTICES"
+ "GS_MAX_OUTPUT_VERTICES",
+ "FS_COORD_ORIGIN",
+ "FS_COORD_PIXEL_CENTER"
};
static const char *primitive_names[] =
@@ -176,29 +178,18 @@ static const char *primitive_names[] =
"POLYGON"
};
-
-static void
-_dump_register_decl(
- struct dump_ctx *ctx,
- uint file,
- int first,
- int last )
+static const char *fs_coord_origin_names[] =
{
- ENM( file, file_names );
+ "UPPER_LEFT",
+ "LOWER_LEFT"
+};
- /* all geometry shader inputs are two dimensional */
- if (file == TGSI_FILE_INPUT &&
- ctx->iter.processor.Processor == TGSI_PROCESSOR_GEOMETRY)
- TXT("[]");
+static const char *fs_coord_pixel_center_names[] =
+{
+ "HALF_INTEGER",
+ "INTEGER"
+};
- CHR( '[' );
- SID( first );
- if (first != last) {
- TXT( ".." );
- SID( last );
- }
- CHR( ']' );
-}
static void
_dump_register_dst(
@@ -219,8 +210,13 @@ _dump_register_src(
struct dump_ctx *ctx,
const struct tgsi_full_src_register *src )
{
+ ENM(src->Register.File, file_names);
+ if (src->Register.Dimension) {
+ CHR('[');
+ SID(src->Dimension.Index);
+ CHR(']');
+ }
if (src->Register.Indirect) {
- ENM( src->Register.File, file_names );
CHR( '[' );
ENM( src->Indirect.File, file_names );
CHR( '[' );
@@ -234,16 +230,10 @@ _dump_register_src(
}
CHR( ']' );
} else {
- ENM( src->Register.File, file_names );
CHR( '[' );
SID( src->Register.Index );
CHR( ']' );
}
- if (src->Register.Dimension) {
- CHR( '[' );
- SID( src->Dimension.Index );
- CHR( ']' );
- }
}
static void
@@ -300,11 +290,28 @@ iter_declaration(
TXT( "DCL " );
- _dump_register_decl(
- ctx,
- decl->Declaration.File,
- decl->Range.First,
- decl->Range.Last );
+ ENM(decl->Declaration.File, file_names);
+
+ /* all geometry shader inputs are two dimensional */
+ if (decl->Declaration.File == TGSI_FILE_INPUT &&
+ iter->processor.Processor == TGSI_PROCESSOR_GEOMETRY) {
+ TXT("[]");
+ }
+
+ if (decl->Declaration.Dimension) {
+ CHR('[');
+ SID(decl->Dim.Index2D);
+ CHR(']');
+ }
+
+ CHR('[');
+ SID(decl->Range.First);
+ if (decl->Range.First != decl->Range.Last) {
+ TXT("..");
+ SID(decl->Range.Last);
+ }
+ CHR(']');
+
_dump_writemask(
ctx,
decl->Declaration.UsageMask );
@@ -373,6 +380,12 @@ iter_property(
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
ENM(prop->u[i].Data, primitive_names);
break;
+ case TGSI_PROPERTY_FS_COORD_ORIGIN:
+ ENM(prop->u[i].Data, fs_coord_origin_names);
+ break;
+ case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
+ ENM(prop->u[i].Data, fs_coord_pixel_center_names);
+ break;
default:
SID( prop->u[i].Data );
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 118a638ab48..fbb9aa0e63a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -953,107 +953,90 @@ micro_sub(
}
static void
-fetch_src_file_channel(
- const struct tgsi_exec_machine *mach,
- const uint file,
- const uint swizzle,
- const union tgsi_exec_channel *index,
- union tgsi_exec_channel *chan )
-{
- switch( swizzle ) {
- case TGSI_SWIZZLE_X:
- case TGSI_SWIZZLE_Y:
- case TGSI_SWIZZLE_Z:
- case TGSI_SWIZZLE_W:
- switch( file ) {
- case TGSI_FILE_CONSTANT:
- assert(mach->Consts);
- if (index->i[0] < 0)
- chan->f[0] = 0.0f;
- else
- chan->f[0] = mach->Consts[index->i[0]][swizzle];
- if (index->i[1] < 0)
- chan->f[1] = 0.0f;
- else
- chan->f[1] = mach->Consts[index->i[1]][swizzle];
- if (index->i[2] < 0)
- chan->f[2] = 0.0f;
- else
- chan->f[2] = mach->Consts[index->i[2]][swizzle];
- if (index->i[3] < 0)
- chan->f[3] = 0.0f;
- else
- chan->f[3] = mach->Consts[index->i[3]][swizzle];
- break;
+fetch_src_file_channel(const struct tgsi_exec_machine *mach,
+ const uint file,
+ const uint swizzle,
+ const union tgsi_exec_channel *index,
+ const union tgsi_exec_channel *index2D,
+ union tgsi_exec_channel *chan)
+{
+ uint i;
- case TGSI_FILE_INPUT:
- case TGSI_FILE_SYSTEM_VALUE:
- chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
- chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
- chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
- chan->u[3] = mach->Inputs[index->i[3]].xyzw[swizzle].u[3];
- break;
+ switch (file) {
+ case TGSI_FILE_CONSTANT:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index2D->i[i] >= 0 && index2D->i[i] < PIPE_MAX_CONSTANT_BUFFERS);
+ assert(mach->Consts[index2D->i[i]]);
- case TGSI_FILE_TEMPORARY:
- assert(index->i[0] < TGSI_EXEC_NUM_TEMPS);
- chan->u[0] = mach->Temps[index->i[0]].xyzw[swizzle].u[0];
- chan->u[1] = mach->Temps[index->i[1]].xyzw[swizzle].u[1];
- chan->u[2] = mach->Temps[index->i[2]].xyzw[swizzle].u[2];
- chan->u[3] = mach->Temps[index->i[3]].xyzw[swizzle].u[3];
- break;
+ if (index->i[i] < 0) {
+ chan->u[i] = 0;
+ } else {
+ const uint *p = (const uint *)mach->Consts[index2D->i[i]];
- case TGSI_FILE_IMMEDIATE:
- assert( index->i[0] < (int) mach->ImmLimit );
- chan->f[0] = mach->Imms[index->i[0]][swizzle];
- assert( index->i[1] < (int) mach->ImmLimit );
- chan->f[1] = mach->Imms[index->i[1]][swizzle];
- assert( index->i[2] < (int) mach->ImmLimit );
- chan->f[2] = mach->Imms[index->i[2]][swizzle];
- assert( index->i[3] < (int) mach->ImmLimit );
- chan->f[3] = mach->Imms[index->i[3]][swizzle];
- break;
+ chan->u[i] = p[index->i[i] * 4 + swizzle];
+ }
+ }
+ break;
- case TGSI_FILE_ADDRESS:
- chan->u[0] = mach->Addrs[index->i[0]].xyzw[swizzle].u[0];
- chan->u[1] = mach->Addrs[index->i[1]].xyzw[swizzle].u[1];
- chan->u[2] = mach->Addrs[index->i[2]].xyzw[swizzle].u[2];
- chan->u[3] = mach->Addrs[index->i[3]].xyzw[swizzle].u[3];
- break;
+ case TGSI_FILE_INPUT:
+ case TGSI_FILE_SYSTEM_VALUE:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ /* XXX: 2D indexing */
+ chan->u[i] = mach->Inputs[index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]].xyzw[swizzle].u[i];
+ }
+ break;
- case TGSI_FILE_PREDICATE:
- assert(index->i[0] < TGSI_EXEC_NUM_PREDS);
- assert(index->i[1] < TGSI_EXEC_NUM_PREDS);
- assert(index->i[2] < TGSI_EXEC_NUM_PREDS);
- assert(index->i[3] < TGSI_EXEC_NUM_PREDS);
- chan->u[0] = mach->Predicates[0].xyzw[swizzle].u[0];
- chan->u[1] = mach->Predicates[0].xyzw[swizzle].u[1];
- chan->u[2] = mach->Predicates[0].xyzw[swizzle].u[2];
- chan->u[3] = mach->Predicates[0].xyzw[swizzle].u[3];
- break;
+ case TGSI_FILE_TEMPORARY:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] < TGSI_EXEC_NUM_TEMPS);
+ assert(index2D->i[i] == 0);
- case TGSI_FILE_OUTPUT:
- /* vertex/fragment output vars can be read too */
- chan->u[0] = mach->Outputs[index->i[0]].xyzw[swizzle].u[0];
- chan->u[1] = mach->Outputs[index->i[1]].xyzw[swizzle].u[1];
- chan->u[2] = mach->Outputs[index->i[2]].xyzw[swizzle].u[2];
- chan->u[3] = mach->Outputs[index->i[3]].xyzw[swizzle].u[3];
- break;
+ chan->u[i] = mach->Temps[index->i[i]].xyzw[swizzle].u[i];
+ }
+ break;
- default:
- assert( 0 );
- chan->u[0] = 0;
- chan->u[1] = 0;
- chan->u[2] = 0;
- chan->u[3] = 0;
+ case TGSI_FILE_IMMEDIATE:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] >= 0 && index->i[i] < (int)mach->ImmLimit);
+ assert(index2D->i[i] == 0);
+
+ chan->f[i] = mach->Imms[index->i[i]][swizzle];
+ }
+ break;
+
+ case TGSI_FILE_ADDRESS:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] >= 0);
+ assert(index2D->i[i] == 0);
+
+ chan->u[i] = mach->Addrs[index->i[i]].xyzw[swizzle].u[i];
+ }
+ break;
+
+ case TGSI_FILE_PREDICATE:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] >= 0 && index->i[i] < TGSI_EXEC_NUM_PREDS);
+ assert(index2D->i[i] == 0);
+
+ chan->u[i] = mach->Predicates[0].xyzw[swizzle].u[i];
+ }
+ break;
+
+ case TGSI_FILE_OUTPUT:
+ /* vertex/fragment output vars can be read too */
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] >= 0);
+ assert(index2D->i[i] == 0);
+
+ chan->u[i] = mach->Outputs[index->i[i]].xyzw[swizzle].u[i];
}
break;
default:
- assert( 0 );
- chan->u[0] = 0;
- chan->u[1] = 0;
- chan->u[2] = 0;
- chan->u[3] = 0;
+ assert(0);
+ for (i = 0; i < QUAD_SIZE; i++) {
+ chan->u[i] = 0;
+ }
}
}
@@ -1065,6 +1048,7 @@ fetch_source(const struct tgsi_exec_machine *mach,
enum tgsi_exec_datatype src_datatype)
{
union tgsi_exec_channel index;
+ union tgsi_exec_channel index2D;
uint swizzle;
/* We start with a direct index into a register file.
@@ -1103,12 +1087,12 @@ fetch_source(const struct tgsi_exec_machine *mach,
/* get current value of address register[swizzle] */
swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
- fetch_src_file_channel(
- mach,
- reg->Indirect.File,
- swizzle,
- &index2,
- &indir_index );
+ fetch_src_file_channel(mach,
+ reg->Indirect.File,
+ swizzle,
+ &index2,
+ &ZeroVec,
+ &indir_index);
/* add value of address register to the offset */
index.i[0] += indir_index.i[0];
@@ -1129,44 +1113,22 @@ fetch_source(const struct tgsi_exec_machine *mach,
* subscript to a register file. Effectively it means that
* the register file is actually a 2D array of registers.
*
- * file[1][3] == file[1*sizeof(file[1])+3],
+ * file[3][1],
* where:
* [3] = Dimension.Index
*/
if (reg->Register.Dimension) {
- /* The size of the first-order array depends on the register file type.
- * We need to multiply the index to the first array to get an effective,
- * "flat" index that points to the beginning of the second-order array.
- */
- switch (reg->Register.File) {
- case TGSI_FILE_INPUT:
- case TGSI_FILE_SYSTEM_VALUE:
- index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
- index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
- index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
- index.i[3] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
- break;
- case TGSI_FILE_CONSTANT:
- index.i[0] *= TGSI_EXEC_MAX_CONST_BUFFER;
- index.i[1] *= TGSI_EXEC_MAX_CONST_BUFFER;
- index.i[2] *= TGSI_EXEC_MAX_CONST_BUFFER;
- index.i[3] *= TGSI_EXEC_MAX_CONST_BUFFER;
- break;
- default:
- assert( 0 );
- }
-
- index.i[0] += reg->Dimension.Index;
- index.i[1] += reg->Dimension.Index;
- index.i[2] += reg->Dimension.Index;
- index.i[3] += reg->Dimension.Index;
+ index2D.i[0] =
+ index2D.i[1] =
+ index2D.i[2] =
+ index2D.i[3] = reg->Dimension.Index;
/* Again, the second subscript index can be addressed indirectly
* identically to the first one.
* Nothing stops us from indirectly addressing the indirect register,
* but there is no need for that, so we won't exercise it.
*
- * file[1][ind[4].y+3],
+ * file[ind[4].y+3][1],
* where:
* ind = DimIndirect.File
* [4] = DimIndirect.Index
@@ -1184,24 +1146,25 @@ fetch_source(const struct tgsi_exec_machine *mach,
index2.i[3] = reg->DimIndirect.Index;
swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect, CHAN_X );
- fetch_src_file_channel(
- mach,
- reg->DimIndirect.File,
- swizzle,
- &index2,
- &indir_index );
-
- index.i[0] += indir_index.i[0];
- index.i[1] += indir_index.i[1];
- index.i[2] += indir_index.i[2];
- index.i[3] += indir_index.i[3];
+ fetch_src_file_channel(mach,
+ reg->DimIndirect.File,
+ swizzle,
+ &index2,
+ &ZeroVec,
+ &indir_index);
+
+ index2D.i[0] += indir_index.i[0];
+ index2D.i[1] += indir_index.i[1];
+ index2D.i[2] += indir_index.i[2];
+ index2D.i[3] += indir_index.i[3];
/* for disabled execution channels, zero-out the index to
* avoid using a potential garbage value.
*/
for (i = 0; i < QUAD_SIZE; i++) {
- if ((execmask & (1 << i)) == 0)
- index.i[i] = 0;
+ if ((execmask & (1 << i)) == 0) {
+ index2D.i[i] = 0;
+ }
}
}
@@ -1209,15 +1172,20 @@ fetch_source(const struct tgsi_exec_machine *mach,
* files, we would have to check whether Dimension is followed
* by a dimension register and continue the saga.
*/
+ } else {
+ index2D.i[0] =
+ index2D.i[1] =
+ index2D.i[2] =
+ index2D.i[3] = 0;
}
swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
- fetch_src_file_channel(
- mach,
- reg->Register.File,
- swizzle,
- &index,
- chan );
+ fetch_src_file_channel(mach,
+ reg->Register.File,
+ swizzle,
+ &index,
+ &index2D,
+ chan);
if (reg->Register.Absolute) {
if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
@@ -1280,12 +1248,12 @@ store_dest(struct tgsi_exec_machine *mach,
swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, CHAN_X );
/* fetch values from the address/indirection register */
- fetch_src_file_channel(
- mach,
- reg->Indirect.File,
- swizzle,
- &index,
- &indir_index );
+ fetch_src_file_channel(mach,
+ reg->Indirect.File,
+ swizzle,
+ &index,
+ &ZeroVec,
+ &indir_index);
/* save indirection offset */
offset = indir_index.i[0];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 59e3b445cc3..a22873e4c2b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -260,7 +260,7 @@ struct tgsi_exec_machine
struct tgsi_sampler **Samplers;
unsigned ImmLimit;
- const float (*Consts)[4];
+ const void *Consts[PIPE_MAX_CONSTANT_BUFFERS];
const struct tgsi_token *Tokens; /**< Declarations, instructions */
unsigned Processor; /**< TGSI_PROCESSOR_x */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 8c7062d850c..fd37fc3079b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -109,6 +109,10 @@ tgsi_parse_token(
next_token( ctx, &decl->Range );
+ if (decl->Declaration.Dimension) {
+ next_token(ctx, &decl->Dim);
+ }
+
if( decl->Declaration.Semantic ) {
next_token( ctx, &decl->Semantic );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 439a57269b7..8150e3cd29d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -58,6 +58,7 @@ struct tgsi_full_declaration
{
struct tgsi_declaration Declaration;
struct tgsi_declaration_range Range;
+ struct tgsi_declaration_dimension Dim;
struct tgsi_declaration_semantic Semantic;
};
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index e1e4f97967d..91e1b27da12 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -335,10 +335,6 @@ iter_instruction(
fill_scan_register1d(ind_reg,
inst->Src[i].Indirect.File,
inst->Src[i].Indirect.Index);
- if (!(ind_reg->file == TGSI_FILE_ADDRESS || ind_reg->file == TGSI_FILE_LOOP) ||
- ind_reg->indices[0] != 0) {
- report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
- }
check_register_usage(
ctx,
ind_reg,
@@ -412,12 +408,16 @@ iter_declaration(
uint vert;
for (vert = 0; vert < ctx->implied_array_size; ++vert) {
scan_register *reg = MALLOC(sizeof(scan_register));
- fill_scan_register2d(reg, file, vert, i);
+ fill_scan_register2d(reg, file, i, vert);
check_and_declare(ctx, reg);
}
} else {
scan_register *reg = MALLOC(sizeof(scan_register));
- fill_scan_register1d(reg, file, i);
+ if (decl->Declaration.Dimension) {
+ fill_scan_register2d(reg, file, i, decl->Dim.Index2D);
+ } else {
+ fill_scan_register1d(reg, file, i);
+ }
check_and_declare(ctx, reg);
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index a6cc773003a..b9be8dc0a31 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -101,12 +101,10 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
const int ind = src->Register.Index;
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
- if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
- info->uses_fogcoord = TRUE;
- }
- else if (src->Register.SwizzleX == TGSI_SWIZZLE_Y) {
- info->uses_frontfacing = TRUE;
- }
+ info->uses_fogcoord = TRUE;
+ }
+ else if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FACE) {
+ info->uses_frontfacing = TRUE;
}
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 9fcffeda368..96be353e264 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -553,7 +553,7 @@ parse_register_dcl_bracket(
report_error( ctx, "Expected literal unsigned integer" );
return FALSE;
}
- bracket->first = (int) uindex;
+ bracket->first = uindex;
eat_opt_white( &ctx->cur );
@@ -617,10 +617,12 @@ parse_register_dcl(
* input primitive. so we want to declare just
* the index relevant to the semantics which is in
* the second bracket */
- if (ctx->processor == TGSI_PROCESSOR_GEOMETRY) {
+ if (ctx->processor == TGSI_PROCESSOR_GEOMETRY && *file == TGSI_FILE_INPUT) {
brackets[0] = brackets[1];
+ *num_brackets = 1;
+ } else {
+ *num_brackets = 2;
}
- *num_brackets = 2;
}
return TRUE;
@@ -738,6 +740,13 @@ parse_src_operand(
return FALSE;
src->Register.File = file;
+ if (parsed_opt_brackets) {
+ src->Register.Dimension = 1;
+ src->Dimension.Indirect = 0;
+ src->Dimension.Dimension = 0;
+ src->Dimension.Index = bracket[0].index;
+ bracket[0] = bracket[1];
+ }
src->Register.Index = bracket[0].index;
if (bracket[0].ind_file != TGSI_FILE_NULL) {
src->Register.Indirect = 1;
@@ -748,12 +757,6 @@ parse_src_operand(
src->Indirect.SwizzleZ = bracket[0].ind_comp;
src->Indirect.SwizzleW = bracket[0].ind_comp;
}
- if (parsed_opt_brackets) {
- src->Register.Dimension = 1;
- src->Dimension.Indirect = 0;
- src->Dimension.Dimension = 0;
- src->Dimension.Index = bracket[1].index;
- }
/* Parse optional swizzle.
*/
@@ -933,7 +936,8 @@ static const char *semantic_names[TGSI_SEMANTIC_COUNT] =
"NORMAL",
"FACE",
"EDGEFLAG",
- "PRIM_ID"
+ "PRIM_ID",
+ "INSTANCEID"
};
static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] =
@@ -968,8 +972,17 @@ static boolean parse_declaration( struct translate_ctx *ctx )
decl = tgsi_default_full_declaration();
decl.Declaration.File = file;
decl.Declaration.UsageMask = writemask;
- decl.Range.First = brackets[0].first;
- decl.Range.Last = brackets[0].last;
+
+ if (num_brackets == 1) {
+ decl.Range.First = brackets[0].first;
+ decl.Range.Last = brackets[0].last;
+ } else {
+ decl.Range.First = brackets[1].first;
+ decl.Range.Last = brackets[1].last;
+
+ decl.Declaration.Dimension = 1;
+ decl.Dim.Index2D = brackets[0].first;
+ }
cur = ctx->cur;
eat_opt_white( &cur );
@@ -1116,7 +1129,9 @@ static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
- "GS_MAX_OUTPUT_VERTICES"
+ "GS_MAX_OUTPUT_VERTICES",
+ "FS_COORD_ORIGIN",
+ "FS_COORD_PIXEL_CENTER"
};
static const char *primitive_names[] =
@@ -1133,6 +1148,19 @@ static const char *primitive_names[] =
"POLYGON"
};
+static const char *fs_coord_origin_names[] =
+{
+ "UPPER_LEFT",
+ "LOWER_LEFT"
+};
+
+static const char *fs_coord_pixel_center_names[] =
+{
+ "HALF_INTEGER",
+ "INTEGER"
+};
+
+
static boolean
parse_primitive( const char **pcur, uint *primitive )
{
@@ -1150,6 +1178,40 @@ parse_primitive( const char **pcur, uint *primitive )
return FALSE;
}
+static boolean
+parse_fs_coord_origin( const char **pcur, uint *fs_coord_origin )
+{
+ uint i;
+
+ for (i = 0; i < sizeof(fs_coord_origin_names) / sizeof(fs_coord_origin_names[0]); i++) {
+ const char *cur = *pcur;
+
+ if (str_match_no_case( &cur, fs_coord_origin_names[i])) {
+ *fs_coord_origin = i;
+ *pcur = cur;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static boolean
+parse_fs_coord_pixel_center( const char **pcur, uint *fs_coord_pixel_center )
+{
+ uint i;
+
+ for (i = 0; i < sizeof(fs_coord_pixel_center_names) / sizeof(fs_coord_pixel_center_names[0]); i++) {
+ const char *cur = *pcur;
+
+ if (str_match_no_case( &cur, fs_coord_pixel_center_names[i])) {
+ *fs_coord_pixel_center = i;
+ *pcur = cur;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static boolean parse_property( struct translate_ctx *ctx )
{
@@ -1191,6 +1253,18 @@ static boolean parse_property( struct translate_ctx *ctx )
ctx->implied_array_size = u_vertices_per_prim(values[0]);
}
break;
+ case TGSI_PROPERTY_FS_COORD_ORIGIN:
+ if (!parse_fs_coord_origin(&ctx->cur, &values[0] )) {
+ report_error( ctx, "Unknown coord origin as property: must be UPPER_LEFT or LOWER_LEFT!" );
+ return FALSE;
+ }
+ break;
+ case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
+ if (!parse_fs_coord_pixel_center(&ctx->cur, &values[0] )) {
+ report_error( ctx, "Unknown coord pixel center as property: must be HALF_INTEGER or INTEGER!" );
+ return FALSE;
+ }
+ break;
default:
if (!parse_uint(&ctx->cur, &values[0] )) {
report_error( ctx, "Expected unsigned integer as property!" );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 8bd6f68dcc0..0ae46785bbe 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -44,6 +44,7 @@ union tgsi_any_token {
struct tgsi_property_data prop_data;
struct tgsi_declaration decl;
struct tgsi_declaration_range decl_range;
+ struct tgsi_declaration_dimension decl_dim;
struct tgsi_declaration_semantic decl_semantic;
struct tgsi_immediate imm;
union tgsi_immediate_data imm_data;
@@ -75,6 +76,14 @@ struct ureg_tokens {
#define UREG_MAX_LOOP 1
#define UREG_MAX_PRED 1
+struct const_decl {
+ struct {
+ unsigned first;
+ unsigned last;
+ } constant_range[UREG_MAX_CONSTANT_RANGE];
+ unsigned nr_constant_ranges;
+};
+
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
@@ -127,13 +136,14 @@ struct ureg_program
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
- struct {
- unsigned first;
- unsigned last;
- } constant_range[UREG_MAX_CONSTANT_RANGE];
- unsigned nr_constant_ranges;
+ struct const_decl const_decls;
+ struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS];
unsigned property_gs_input_prim;
+ unsigned property_gs_output_prim;
+ unsigned property_gs_max_vertices;
+ unsigned char property_fs_coord_origin; /* = TGSI_FS_COORD_ORIGIN_* */
+ unsigned char property_fs_coord_pixel_center; /* = TGSI_FS_COORD_PIXEL_CENTER_* */
unsigned nr_addrs;
unsigned nr_preds;
@@ -235,36 +245,40 @@ ureg_dst_register( unsigned file,
return dst;
}
-static INLINE struct ureg_src
-ureg_src_register( unsigned file,
- unsigned index )
+
+void
+ureg_property_gs_input_prim(struct ureg_program *ureg,
+ unsigned input_prim)
{
- struct ureg_src src;
-
- src.File = file;
- src.SwizzleX = TGSI_SWIZZLE_X;
- src.SwizzleY = TGSI_SWIZZLE_Y;
- src.SwizzleZ = TGSI_SWIZZLE_Z;
- src.SwizzleW = TGSI_SWIZZLE_W;
- src.Indirect = 0;
- src.IndirectIndex = 0;
- src.IndirectSwizzle = 0;
- src.Absolute = 0;
- src.Index = index;
- src.Negate = 0;
- src.Dimension = 0;
- src.DimensionIndex = 0;
-
- return src;
+ ureg->property_gs_input_prim = input_prim;
}
+void
+ureg_property_gs_output_prim(struct ureg_program *ureg,
+ unsigned output_prim)
+{
+ ureg->property_gs_output_prim = output_prim;
+}
+void
+ureg_property_gs_max_vertices(struct ureg_program *ureg,
+ unsigned max_vertices)
+{
+ ureg->property_gs_max_vertices = max_vertices;
+}
void
-ureg_property_gs_input_prim(struct ureg_program *ureg,
- unsigned gs_input_prim)
+ureg_property_fs_coord_origin(struct ureg_program *ureg,
+ unsigned fs_coord_origin)
+{
+ ureg->property_fs_coord_origin = fs_coord_origin;
+}
+
+void
+ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
+ unsigned fs_coord_pixel_center)
{
- ureg->property_gs_input_prim = gs_input_prim;
+ ureg->property_fs_coord_pixel_center = fs_coord_pixel_center;
}
@@ -374,62 +388,92 @@ out:
/* Returns a new constant register. Keep track of which have been
* referred to so that we can emit decls later.
*
+ * Constant operands declared with this function must be addressed
+ * with a two-dimensional index.
+ *
* There is nothing in this code to bind this constant to any tracked
* value or manage any constant_buffer contents -- that's the
* resposibility of the calling code.
*/
-struct ureg_src ureg_DECL_constant(struct ureg_program *ureg,
- unsigned index )
+void
+ureg_DECL_constant2D(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned index2D)
+{
+ struct const_decl *decl = &ureg->const_decls2D[index2D];
+
+ assert(index2D < PIPE_MAX_CONSTANT_BUFFERS);
+
+ if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
+ uint i = decl->nr_constant_ranges++;
+
+ decl->constant_range[i].first = first;
+ decl->constant_range[i].last = last;
+ }
+}
+
+
+/* A one-dimensional, depricated version of ureg_DECL_constant2D().
+ *
+ * Constant operands declared with this function must be addressed
+ * with a one-dimensional index.
+ */
+struct ureg_src
+ureg_DECL_constant(struct ureg_program *ureg,
+ unsigned index)
{
+ struct const_decl *decl = &ureg->const_decls;
unsigned minconst = index, maxconst = index;
unsigned i;
/* Inside existing range?
*/
- for (i = 0; i < ureg->nr_constant_ranges; i++) {
- if (ureg->constant_range[i].first <= index &&
- ureg->constant_range[i].last >= index)
+ for (i = 0; i < decl->nr_constant_ranges; i++) {
+ if (decl->constant_range[i].first <= index &&
+ decl->constant_range[i].last >= index) {
goto out;
+ }
}
/* Extend existing range?
*/
- for (i = 0; i < ureg->nr_constant_ranges; i++) {
- if (ureg->constant_range[i].last == index - 1) {
- ureg->constant_range[i].last = index;
+ for (i = 0; i < decl->nr_constant_ranges; i++) {
+ if (decl->constant_range[i].last == index - 1) {
+ decl->constant_range[i].last = index;
goto out;
}
- if (ureg->constant_range[i].first == index + 1) {
- ureg->constant_range[i].first = index;
+ if (decl->constant_range[i].first == index + 1) {
+ decl->constant_range[i].first = index;
goto out;
}
- minconst = MIN2(minconst, ureg->constant_range[i].first);
- maxconst = MAX2(maxconst, ureg->constant_range[i].last);
+ minconst = MIN2(minconst, decl->constant_range[i].first);
+ maxconst = MAX2(maxconst, decl->constant_range[i].last);
}
/* Create new range?
*/
- if (ureg->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
- i = ureg->nr_constant_ranges++;
- ureg->constant_range[i].first = index;
- ureg->constant_range[i].last = index;
+ if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
+ i = decl->nr_constant_ranges++;
+ decl->constant_range[i].first = index;
+ decl->constant_range[i].last = index;
goto out;
}
/* Collapse all ranges down to one:
*/
i = 0;
- ureg->constant_range[0].first = minconst;
- ureg->constant_range[0].last = maxconst;
- ureg->nr_constant_ranges = 1;
+ decl->constant_range[0].first = minconst;
+ decl->constant_range[0].last = maxconst;
+ decl->nr_constant_ranges = 1;
out:
- assert(i < ureg->nr_constant_ranges);
- assert(ureg->constant_range[i].first <= index);
- assert(ureg->constant_range[i].last >= index);
- return ureg_src_register( TGSI_FILE_CONSTANT, index );
+ assert(i < decl->nr_constant_ranges);
+ assert(decl->constant_range[i].first <= index);
+ assert(decl->constant_range[i].last >= index);
+ return ureg_src_register(TGSI_FILE_CONSTANT, index);
}
@@ -578,7 +622,7 @@ decl_immediate( struct ureg_program *ureg,
unsigned type )
{
unsigned i, j;
- unsigned swizzle;
+ unsigned swizzle = 0;
/* Could do a first pass where we examine all existing immediates
* without expanding.
@@ -656,6 +700,35 @@ ureg_DECL_immediate_uint( struct ureg_program *ureg,
struct ureg_src
+ureg_DECL_immediate_block_uint( struct ureg_program *ureg,
+ const unsigned *v,
+ unsigned nr )
+{
+ uint index;
+ uint i;
+
+ if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) {
+ set_bad(ureg);
+ return ureg_src_register(TGSI_FILE_IMMEDIATE, 0);
+ }
+
+ index = ureg->nr_immediates;
+ ureg->nr_immediates += (nr + 3) / 4;
+
+ for (i = index; i < ureg->nr_immediates; i++) {
+ ureg->immediate[i].type = TGSI_IMM_UINT32;
+ ureg->immediate[i].nr = nr > 4 ? 4 : nr;
+ memcpy(ureg->immediate[i].value.u,
+ &v[(i - index) * 4],
+ ureg->immediate[i].nr * sizeof(uint));
+ nr -= 4;
+ }
+
+ return ureg_src_register(TGSI_FILE_IMMEDIATE, index);
+}
+
+
+struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *ureg,
const int *v,
unsigned nr )
@@ -691,7 +764,7 @@ ureg_emit_src( struct ureg_program *ureg,
if (src.Indirect) {
out[0].src.Indirect = 1;
out[n].value = 0;
- out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.File = src.IndirectFile;
out[n].src.SwizzleX = src.IndirectSwizzle;
out[n].src.SwizzleY = src.IndirectSwizzle;
out[n].src.SwizzleZ = src.IndirectSwizzle;
@@ -1058,6 +1131,31 @@ static void emit_decl_range( struct ureg_program *ureg,
}
static void
+emit_decl_range2D(struct ureg_program *ureg,
+ unsigned file,
+ unsigned first,
+ unsigned last,
+ unsigned index2D)
+{
+ union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = 0xf;
+ out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+ out[0].decl.Dimension = 1;
+
+ out[1].value = 0;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = last;
+
+ out[2].value = 0;
+ out[2].decl_dim.Index2D = index2D;
+}
+
+static void
emit_immediate( struct ureg_program *ureg,
const unsigned *v,
unsigned type )
@@ -1104,6 +1202,38 @@ static void emit_decls( struct ureg_program *ureg )
ureg->property_gs_input_prim);
}
+ if (ureg->property_gs_output_prim != ~0) {
+ assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_GS_OUTPUT_PRIM,
+ ureg->property_gs_output_prim);
+ }
+
+ if (ureg->property_gs_max_vertices != ~0) {
+ assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_GS_MAX_VERTICES,
+ ureg->property_gs_max_vertices);
+ }
+
+ if (ureg->property_fs_coord_origin) {
+ assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_FS_COORD_ORIGIN,
+ ureg->property_fs_coord_origin);
+ }
+
+ if (ureg->property_fs_coord_pixel_center) {
+ assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
+
+ emit_property(ureg,
+ TGSI_PROPERTY_FS_COORD_PIXEL_CENTER,
+ ureg->property_fs_coord_pixel_center);
+ }
+
if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
for (i = 0; i < UREG_MAX_INPUT; i++) {
if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
@@ -1152,13 +1282,29 @@ static void emit_decls( struct ureg_program *ureg )
ureg->sampler[i].Index, 1 );
}
- if (ureg->nr_constant_ranges) {
- for (i = 0; i < ureg->nr_constant_ranges; i++)
- emit_decl_range( ureg,
- TGSI_FILE_CONSTANT,
- ureg->constant_range[i].first,
- (ureg->constant_range[i].last + 1 -
- ureg->constant_range[i].first) );
+ if (ureg->const_decls.nr_constant_ranges) {
+ for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) {
+ emit_decl_range(ureg,
+ TGSI_FILE_CONSTANT,
+ ureg->const_decls.constant_range[i].first,
+ ureg->const_decls.constant_range[i].last - ureg->const_decls.constant_range[i].first + 1);
+ }
+ }
+
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ struct const_decl *decl = &ureg->const_decls2D[i];
+
+ if (decl->nr_constant_ranges) {
+ uint j;
+
+ for (j = 0; j < decl->nr_constant_ranges; j++) {
+ emit_decl_range2D(ureg,
+ TGSI_FILE_CONSTANT,
+ decl->constant_range[j].first,
+ decl->constant_range[j].last,
+ i);
+ }
+ }
}
if (ureg->nr_temps) {
@@ -1314,6 +1460,8 @@ struct ureg_program *ureg_create( unsigned processor )
ureg->processor = processor;
ureg->property_gs_input_prim = ~0;
+ ureg->property_gs_output_prim = ~0;
+ ureg->property_gs_max_vertices = ~0;
return ureg;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index 03eaf24854c..e25f35c6dc3 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -52,9 +52,10 @@ struct ureg_src
unsigned Absolute : 1; /* BOOL */
unsigned Negate : 1; /* BOOL */
int Index : 16; /* SINT */
+ unsigned IndirectFile : 4; /* TGSI_FILE_ */
int IndirectIndex : 16; /* SINT */
- int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
- int DimensionIndex : 16; /* SINT */
+ unsigned IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
+ int DimensionIndex : 16; /* SINT */
};
/* Very similar to a tgsi_dst_register, removing unsupported fields
@@ -125,8 +126,23 @@ ureg_create_shader_and_destroy( struct ureg_program *p,
void
ureg_property_gs_input_prim(struct ureg_program *ureg,
- unsigned gs_input_prim);
+ unsigned input_prim);
+
+void
+ureg_property_gs_output_prim(struct ureg_program *ureg,
+ unsigned output_prim);
+void
+ureg_property_gs_max_vertices(struct ureg_program *ureg,
+ unsigned max_vertices);
+
+void
+ureg_property_fs_coord_origin(struct ureg_program *ureg,
+ unsigned fs_coord_origin);
+
+void
+ureg_property_fs_coord_pixel_center(struct ureg_program *ureg,
+ unsigned fs_coord_pixel_center);
/***********************************************************************
* Build shader declarations:
@@ -168,10 +184,21 @@ ureg_DECL_immediate_uint( struct ureg_program *,
unsigned nr );
struct ureg_src
+ureg_DECL_immediate_block_uint( struct ureg_program *,
+ const unsigned *v,
+ unsigned nr );
+
+struct ureg_src
ureg_DECL_immediate_int( struct ureg_program *,
const int *v,
unsigned nr );
+void
+ureg_DECL_constant2D(struct ureg_program *ureg,
+ unsigned first,
+ unsigned last,
+ unsigned index2D);
+
struct ureg_src
ureg_DECL_constant( struct ureg_program *,
unsigned index );
@@ -768,8 +795,9 @@ static INLINE struct ureg_src
ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
{
assert(reg.File != TGSI_FILE_NULL);
- assert(addr.File == TGSI_FILE_ADDRESS);
+ assert(addr.File == TGSI_FILE_ADDRESS || addr.File == TGSI_FILE_TEMPORARY);
reg.Indirect = 1;
+ reg.IndirectFile = addr.File;
reg.IndirectIndex = addr.Index;
reg.IndirectSwizzle = addr.SwizzleX;
return reg;
@@ -789,6 +817,8 @@ ureg_dst( struct ureg_src src )
{
struct ureg_dst dst;
+ assert(!src.Indirect || src.IndirectFile == TGSI_FILE_ADDRESS);
+
dst.File = src.File;
dst.WriteMask = TGSI_WRITEMASK_XYZW;
dst.Indirect = src.Indirect;
@@ -807,6 +837,30 @@ ureg_dst( struct ureg_src src )
}
static INLINE struct ureg_src
+ureg_src_register(unsigned file,
+ unsigned index)
+{
+ struct ureg_src src;
+
+ src.File = file;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Indirect = 0;
+ src.IndirectFile = TGSI_FILE_NULL;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
+ src.Absolute = 0;
+ src.Index = index;
+ src.Negate = 0;
+ src.Dimension = 0;
+ src.DimensionIndex = 0;
+
+ return src;
+}
+
+static INLINE struct ureg_src
ureg_src( struct ureg_dst dst )
{
struct ureg_src src;
@@ -817,6 +871,7 @@ ureg_src( struct ureg_dst dst )
src.SwizzleZ = TGSI_SWIZZLE_Z;
src.SwizzleW = TGSI_SWIZZLE_W;
src.Indirect = dst.Indirect;
+ src.IndirectFile = TGSI_FILE_ADDRESS;
src.IndirectIndex = dst.IndirectIndex;
src.IndirectSwizzle = dst.IndirectSwizzle;
src.Absolute = 0;
@@ -863,6 +918,7 @@ ureg_src_undef( void )
src.SwizzleZ = 0;
src.SwizzleW = 0;
src.Indirect = 0;
+ src.IndirectFile = TGSI_FILE_NULL;
src.IndirectIndex = 0;
src.IndirectSwizzle = 0;
src.Absolute = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c
index f4ca9e21ed9..0a7e4105a80 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.c
@@ -28,7 +28,6 @@
#include "util/u_debug.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi_parse.h"
-#include "tgsi_build.h"
#include "tgsi_util.h"
union pointer_hack
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 3f74e2aa8b8..eb63bec7b50 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -92,7 +92,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* disabled blending/masking */
memset(&ctx->blend, 0, sizeof(ctx->blend));
- ctx->blend.colormask = PIPE_MASK_RGBA;
+ ctx->blend.rt[0].colormask = PIPE_MASK_RGBA;
/* no-op depth/stencil/alpha */
memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
@@ -226,8 +226,8 @@ setup_vertex_data_tex(struct blit_state *ctx,
offset = get_next_slot( ctx );
- pipe_buffer_write(ctx->pipe->screen, ctx->vbuf,
- offset, sizeof(ctx->vertices), ctx->vertices);
+ pipe_buffer_write_nooverlap(ctx->pipe->screen, ctx->vbuf,
+ offset, sizeof(ctx->vertices), ctx->vertices);
return offset;
}
@@ -262,6 +262,10 @@ regions_overlap(int srcX0, int srcY0,
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
* Flipping and stretching are supported.
+ * \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR
+ * \param writemask controls which channels in the dest surface are sourced
+ * from the src surface. Disabled channels are sourced
+ * from (0,0,0,1).
* XXX what about clipping???
* XXX need some control over blitting Z and/or stencil.
*/
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 249a0375fc5..935e11c5d85 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -125,7 +125,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
memset(&blend, 0, sizeof(blend));
ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
/* depth stencil alpha state objects */
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 76023794dcd..8611231ed70 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1287,7 +1287,7 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/* disabled blending/masking */
memset(&ctx->blend, 0, sizeof(ctx->blend));
- ctx->blend.colormask = PIPE_MASK_RGBA;
+ ctx->blend.rt[0].colormask = PIPE_MASK_RGBA;
/* no-op depth/stencil/alpha */
memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
@@ -1411,8 +1411,8 @@ set_vertex_data(struct gen_mipmap_state *ctx,
offset = get_next_slot( ctx );
- pipe_buffer_write(ctx->pipe->screen, ctx->vbuf,
- offset, sizeof(ctx->vertices), ctx->vertices);
+ pipe_buffer_write_nooverlap(ctx->pipe->screen, ctx->vbuf,
+ offset, sizeof(ctx->vertices), ctx->vertices);
return offset;
}
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index f66376ad750..70de140ec9d 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -37,7 +37,6 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
-#include "util/u_format.h"
#include "util/u_surface.h"
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index f9936eb1cb2..c25e1e52e9d 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -390,7 +390,7 @@ a4r4g4b4_put_tile_rgba(ushort *dst,
g >>= 4;
b >>= 4;
a >>= 4;
- *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
+ *dst++ = (a << 12) | (r << 8) | (g << 4) | b;
}
p += src_stride;
}
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 975ee89c455..55a65375c81 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -85,7 +85,9 @@ my_buffer_write(struct pipe_screen *screen,
map = pipe_buffer_map_range(screen, buf, offset, size,
PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
+ PIPE_BUFFER_USAGE_DISCARD |
+ PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
if (map == NULL)
return PIPE_ERROR_OUT_OF_MEMORY;
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index d394f5b4f1b..a7669575b95 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -54,7 +54,10 @@ objects. They all follow simple, one-method binding calls, e.g.
* ``set_blend_color``
* ``set_clip_state``
* ``set_polygon_stipple``
-* ``set_scissor_state``
+* ``set_scissor_state`` sets the bounds for the scissor test, which culls
+ pixels before blending to render targets. If the :ref:`Rasterizer` does
+ 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``
@@ -145,9 +148,51 @@ draws. Queries may be nested, though no state tracker currently
exercises this.
Queries can be created with ``create_query`` and deleted with
-``destroy_query``. To enable a query, use ``begin_query``, and when finished,
-use ``end_query`` to stop the query. Finally, ``get_query_result`` is used
-to retrieve the results.
+``destroy_query``. To start a query, use ``begin_query``, and when finished,
+use ``end_query`` to end the query.
+
+``get_query_result`` is used to retrieve the results of a query. If
+the ``wait`` parameter is TRUE, then the ``get_query_result`` call
+will block until the results of the query are ready (and TRUE will be
+returned). Otherwise, if the ``wait`` parameter is FALSE, the call
+will not block and the return value will be TRUE if the query has
+completed or FALSE otherwise.
+
+A common type of query is the occlusion query which counts the number of
+fragments/pixels which are written to the framebuffer (and not culled by
+Z/stencil/alpha testing or shader KILL instructions).
+
+
+Conditional Rendering
+^^^^^^^^^^^^^^^^^^^^^
+
+A drawing command can be skipped depending on the outcome of a query
+(typically an occlusion query). The ``render_condition`` function specifies
+the query which should be checked prior to rendering anything.
+
+If ``render_condition`` is called with ``query`` = NULL, conditional
+rendering is disabled and drawing takes place normally.
+
+If ``render_condition`` is called with a non-null ``query`` subsequent
+drawing commands will be predicated on the outcome of the query. If
+the query result is zero subsequent drawing commands will be skipped.
+
+If ``mode`` is PIPE_RENDER_COND_WAIT the driver will wait for the
+query to complete before deciding whether to render.
+
+If ``mode`` is PIPE_RENDER_COND_NO_WAIT and the query has not yet
+completed, the drawing command will be executed normally. If the query
+has completed, drawing will be predicated on the outcome of the query.
+
+If ``mode`` is PIPE_RENDER_COND_BY_REGION_WAIT or
+PIPE_RENDER_COND_BY_REGION_NO_WAIT rendering will be predicated as above
+for the non-REGION modes but in the case that an occulusion query returns
+a non-zero result, regions which were occluded may be ommitted by subsequent
+drawing commands. This can result in better performance with some GPUs.
+Normally, if the occlusion query returned a non-zero result subsequent
+drawing happens normally so fragments may be generated, shaded and
+processed even where they're known to be obscured.
+
Flushing
^^^^^^^^
diff --git a/src/gallium/docs/source/cso/blend.rst b/src/gallium/docs/source/cso/blend.rst
index fd9e4a1e2d5..55c0f328859 100644
--- a/src/gallium/docs/source/cso/blend.rst
+++ b/src/gallium/docs/source/cso/blend.rst
@@ -6,9 +6,50 @@ Blend
This state controls blending of the final fragments into the target rendering
buffers.
-XXX it is unresolved what behavior should result if blend_enable is off.
+Blend Factors
+-------------
+
+The blend factors largely follow the same pattern as their counterparts
+in other modern and legacy drawing APIs.
+
+XXX blurb about dual-source blends
Members
-------
-XXX undocumented members
+independent_blend_enable
+ If enabled, blend state is different for each render target, and
+ for each render target set in the respective member of the rt array.
+ If disabled, blend state is the same for all render targets, and only
+ the first member of the rt array contains valid data.
+logicop_enable
+ Enables logic ops. Cannot be enabled at the same time as blending, and
+ is always the same for all render targets.
+logicop_func
+ The logic operation to use if logic ops are enabled. One of PIPE_LOGICOP.
+dither
+ Whether dithering is enabled.
+rt
+ Contains the per-rendertarget blend state.
+
+Per-rendertarget Members
+------------------------
+
+blend_enable
+ If blending is enabled, perform a blend calculation according to blend
+ functions and source/destination factors. Otherwise, the incoming fragment
+ color gets passed unmodified (but colormask still applies).
+rgb_func
+ The blend function to use for rgb channels. One of PIPE_BLEND.
+rgb_src_factor
+ The blend source factor to use for rgb channels. One of PIPE_BLENDFACTOR.
+rgb_dst_factor
+ The blend destination factor to use for rgb channels. One of PIPE_BLENDFACTOR.
+alpha_func
+ The blend function to use for the alpha channel. One of PIPE_BLEND.
+alpha_src_factor
+ The blend source factor to use for the alpha channel. One of PIPE_BLENDFACTOR.
+alpha_dst_factor
+ The blend destination factor to use for alpha channel. One of PIPE_BLENDFACTOR.
+colormask
+ Bitmask of which channels to write. Combination of PIPE_MASK bits.
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index 4d8e1708e7c..bfa4a1170a2 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -7,32 +7,69 @@ 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
-------
+bypass_vs_clip_and_viewport
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Whether the entire TCL pipeline should be bypassed. This implies that
+vertices are pre-transformed for the viewport, and will not be run
+through the vertex shader.
+
+.. note::
+
+ Implementations may still clip away vertices that are not in the viewport
+ when this is set.
+
flatshade
- If set, the provoking vertex of each polygon is used to determine the
- color of the entire polygon. If not set, fragment colors will be
- interpolated between the vertex colors.
- Note that this is separate from the fragment shader input attributes
- CONSTANT, LINEAR and PERSPECTIVE. We need the flatshade state at
+^^^^^^^^^
+
+If set, the provoking vertex of each polygon is used to determine the color
+of the entire polygon. If not set, fragment colors will be interpolated
+between the vertex colors.
+
+The actual interpolated shading algorithm is obviously
+implementation-dependent, but will usually be Gourard for most hardware.
+
+.. note::
+
+ This is separate from the fragment shader input attributes
+ CONSTANT, LINEAR and PERSPECTIVE. The flatshade state is needed at
clipping time to determine how to set the color of new vertices.
- Also note that the draw module can implement flat shading by copying
- the provoking vertex color to all the other vertices in the primitive.
+
+ :ref:`Draw` can implement flat shading by copying the provoking vertex
+ color to all the other vertices in the primitive.
flatshade_first
- Whether the first vertex should be the provoking vertex, for most
- primitives. If not set, the last vertex is the provoking vertex.
+^^^^^^^^^^^^^^^
+
+Whether the first vertex should be the provoking vertex, for most primitives.
+If not set, the last vertex is the provoking vertex.
+
+There are several important exceptions to the specification of this rule.
+
+* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
+ vertex. If the caller wishes to change the provoking vertex, they merely
+ need to rotate the vertices themselves.
+* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no
+ effect; the provoking vertex is always the last vertex.
+* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
+ second vertex, not the first. This permits each segment of the fan to have
+ a different color.
+
+Other Members
+^^^^^^^^^^^^^
light_twoside
- If set, there are per-vertex back-facing colors. The draw module
+ If set, there are per-vertex back-facing colors. :ref:`Draw`
uses this state along with the front/back information to set the
final vertex colors prior to rasterization.
front_winding
Indicates the window order of front-facing polygons, either
PIPE_WINDING_CW or PIPE_WINDING_CCW
+
cull_mode
Indicates which polygons to cull, either PIPE_WINDING_NONE (cull no
polygons), PIPE_WINDING_CW (cull clockwise-winding polygons),
@@ -68,7 +105,7 @@ line_stipple_enable
line_stipple_pattern
16-bit bitfield of on/off flags, used to pattern the line stipple.
line_stipple_factor
- When drawinga stippled line, each bit in the stipple pattern is
+ When drawing a stippled line, each bit in the stipple pattern is
repeated N times, where N = line_stipple_factor + 1.
line_last_pixel
Controls whether the last pixel in a line is drawn or not. OpenGL
@@ -96,7 +133,7 @@ sprite_coord_mode
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 the 'draw' module because that's where each
+ 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.
@@ -108,45 +145,9 @@ scissor
Whether the scissor test is enabled.
multisample
- Whether :ref:`MSAA` is enabled.
-
-bypass_vs_clip_and_viewport
- Whether the entire TCL pipeline should be bypassed. This implies that
- vertices are pre-transformed for the viewport, and will not be run
- through the vertex shader. Note that implementations may still clip away
- vertices that are not in the viewport.
+ Whether :term:`MSAA` is enabled.
gl_rasterization_rules
Whether the rasterizer should use (0.5, 0.5) pixel centers. When not set,
the rasterizer will use (0, 0) for pixel centers.
-
-Notes
------
-
-flatshade
-^^^^^^^^^
-
-The actual interpolated shading algorithm is obviously
-implementation-dependent, but will usually be Gourard for most hardware.
-
-bypass_vs_clip_and_viewport
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When set, this implies that vertices are pre-transformed for the viewport, and
-will not be run through the vertex shader. Note that implementations may still
-clip away vertices that are not visible.
-
-flatshade_first
-^^^^^^^^^^^^^^^
-
-There are several important exceptions to the specification of this rule.
-
-* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
- vertex. If the caller wishes to change the provoking vertex, they merely
- need to rotate the vertices themselves.
-* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no
- effect; the provoking vertex is always the last vertex.
-* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
- second vertex, not the first. This permits each segment of the fan to have
- a different color.
diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst
index e3f1757f57a..8b67ca57f12 100644
--- a/src/gallium/docs/source/cso/sampler.rst
+++ b/src/gallium/docs/source/cso/sampler.rst
@@ -12,8 +12,6 @@ with the traditional (S, T, R, Q) notation.
Members
-------
-XXX undocumented compare_mode, compare_func
-
wrap_s
How to wrap the S coordinate. One of PIPE_TEX_WRAP.
wrap_t
@@ -27,12 +25,18 @@ min_mip_filter
PIPE_TEX_FILTER.
mag_img_filter
The filter to use when magnifying texels. One of PIPE_TEX_FILTER.
+compare_mode
+ If set to PIPE_TEX_COMPARE_R_TO_TEXTURE, texture output is computed
+ according to compare_func, using r coord and the texture value as operands.
+ If set to PIPE_TEX_COMPARE_NONE, no comparison calculation is performed.
+compare_func
+ How the comparison is computed. One of PIPE_FUNC.
normalized_coords
Whether the texture coordinates are normalized. If normalized, they will
always be in [0, 1]. If not, they will be in the range of each dimension
of the loaded texture.
prefilter
- XXX From the Doxy, "weird sampling state exposed by some APIs." Refine.
+ Cylindrical texcoord wrap enable per coord. Not exposed by most APIs.
lod_bias
The bias to apply to the level of detail.
min_lod
diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst
index a448203c6fa..0ef9fe2645c 100644
--- a/src/gallium/docs/source/distro.rst
+++ b/src/gallium/docs/source/distro.rst
@@ -61,10 +61,7 @@ VMWare SVGA
ATI r300
^^^^^^^^
-AMD/ATI r600
-^^^^^^^^^^^^
-
-Highly experimental.
+Testing-quality.
Softpipe
^^^^^^^^
@@ -109,20 +106,31 @@ Auxiliary
CSO Cache
^^^^^^^^^
+The CSO cache is used to accelerate preparation of state by saving
+driver-specific state structures for later use.
+
+.. _draw:
+
Draw
^^^^
+Draw is a software :term:`TCL` pipeline for hardware that lacks vertex shaders
+or other essential parts of pre-rasterization vertex preparation.
+
Gallivm
^^^^^^^
Indices
^^^^^^^
-Tool for translating or generating element indices for element-based
-rendering.
+Indices provides tools for translating or generating element indices for
+use with element-based rendering.
+
+Pipe Buffer Managers
+^^^^^^^^^^^^^^^^^^^^
-Pipe Buffer Manager
-^^^^^^^^^^^^^^^^^^^
+Each of these managers provides various services to drivers that are not
+fully utilizing a memory manager.
Remote Debugger
^^^^^^^^^^^^^^^
@@ -133,7 +141,8 @@ Runtime Assembly Emission
TGSI
^^^^
-Basic utilities for manipulating TGSI streams.
+The TGSI auxiliary module provides basic utilities for manipulating TGSI
+streams.
Translate
^^^^^^^^^
diff --git a/src/gallium/docs/source/glossary.rst b/src/gallium/docs/source/glossary.rst
index 6a9110ce786..0696cb5d277 100644
--- a/src/gallium/docs/source/glossary.rst
+++ b/src/gallium/docs/source/glossary.rst
@@ -8,3 +8,16 @@ Glossary
Multi-Sampled Anti-Aliasing. A basic anti-aliasing technique that takes
multiple samples of the depth buffer, and uses this information to
smooth the edges of polygons.
+
+ TCL
+ Transform, Clipping, & Lighting. The three stages of preparation in a
+ rasterizing pipeline prior to the actual rasterization of vertices into
+ fragments.
+
+ NPOT
+ Non-power-of-two. Usually applied to textures which have at least one
+ dimension which is not a power of two.
+
+ LOD
+ Level of Detail. Also spelled "LoD." The value that determines when the
+ switches between mipmaps occur during texture sampling.
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 9631e6967ef..3e57a282fd4 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -3,6 +3,160 @@ Screen
A screen is an object representing the context-independent part of a device.
+Useful Flags
+------------
+
+.. _pipe_cap:
+
+PIPE_CAP
+^^^^^^^^
+
+Pipe capabilities help expose hardware functionality not explicitly required
+by Gallium. For floating-point values, use :ref:`get_paramf`, and for boolean
+or integer values, use :ref:`get_param`.
+
+The integer capabilities:
+
+* ``MAX_TEXTURE_IMAGE_UNITS``: The maximum number of samplers available.
+* ``NPOT_TEXTURES``: Whether :term:`NPOT` textures may have repeat modes,
+ normalized coordinates, and mipmaps.
+* ``TWO_SIDED_STENCIL``: Whether the stencil test can also affect back-facing
+ polygons.
+* ``GLSL``: Deprecated.
+* ``DUAL_SOURCE_BLEND``: Whether dual-source blend factors are supported. See
+ :ref:`Blend` for more information.
+* ``ANISOTROPIC_FILTER``: Whether textures can be filtered anisotropically.
+* ``POINT_SPRITE``: Whether point sprites are available.
+* ``MAX_RENDER_TARGETS``: The maximum number of render targets that may be
+ bound.
+* ``OCCLUSION_QUERY``: Whether occlusion queries are available.
+* ``TEXTURE_SHADOW_MAP``: XXX
+* ``MAX_TEXTURE_2D_LEVELS``: The maximum number of mipmap levels available
+ for a 2D texture.
+* ``MAX_TEXTURE_3D_LEVELS``: The maximum number of mipmap levels available
+ for a 3D texture.
+* ``MAX_TEXTURE_CUBE_LEVELS``: The maximum number of mipmap levels available
+ for a cubemap.
+* ``TEXTURE_MIRROR_CLAMP``: Whether mirrored texture coordinates with clamp
+ are supported.
+* ``TEXTURE_MIRROR_REPEAT``: Whether mirrored repeating texture coordinates
+ are supported.
+* ``MAX_VERTEX_TEXTURE_UNITS``: The maximum number of samplers addressable
+ inside the vertex shader. If this is 0, then the vertex shader cannot
+ sample textures.
+* ``TGSI_CONT_SUPPORTED``: Whether the TGSI CONT opcode is supported.
+* ``BLEND_EQUATION_SEPARATE``: Whether alpha blend equations may be different
+ from color blend equations, in :ref:`Blend` state.
+* ``SM3``: Whether the vertex shader and fragment shader support equivalent
+ opcodes to the Shader Model 3 specification. XXX oh god this is horrible
+* ``MAX_PREDICATE_REGISTERS``: XXX
+* ``MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from
+ the vertex and fragment shader, inclusive.
+* ``MAX_CONST_BUFFERS``: Maximum number of constant buffers that can be bound
+ to any shader stage using ``set_constant_buffer``. If 0 or 1, the pipe will
+ only permit binding one constant buffer per shader, and the shaders will
+ not permit two-dimensional access to constants.
+* ``MAX_CONST_BUFFER_SIZE``: Maximum byte size of a single constant buffer.
+* ``INDEP_BLEND_ENABLE``: Whether per-rendertarget blend enabling and channel
+ masks are supported. If 0, then the first rendertarget's blend mask is
+ replicated across all MRTs.
+* ``INDEP_BLEND_FUNC``: Whether per-rendertarget blend functions are
+ available. If 0, then the first rendertarget's blend functions affect all
+ MRTs.
+* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT``: Whether the TGSI property
+ FS_COORD_ORIGIN with value UPPER_LEFT is supported.
+* ``PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT``: Whether the TGSI property
+ FS_COORD_ORIGIN with value LOWER_LEFT is supported.
+* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER``: Whether the TGSI
+ property FS_COORD_PIXEL_CENTER with value HALF_INTEGER is supported.
+* ``PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER``: Whether the TGSI
+ property FS_COORD_PIXEL_CENTER with value INTEGER is supported.
+
+The floating-point capabilities:
+
+* ``MAX_LINE_WIDTH``: The maximum width of a regular line.
+* ``MAX_LINE_WIDTH_AA``: The maximum width of a smoothed line.
+* ``MAX_POINT_WIDTH``: The maximum width and height of a point.
+* ``MAX_POINT_WIDTH_AA``: The maximum width and height of a smoothed point.
+* ``MAX_TEXTURE_ANISOTROPY``: The maximum level of anisotropy that can be
+ applied to anisotropically filtered textures.
+* ``MAX_TEXTURE_LOD_BIAS``: The maximum :term:`LOD` bias that may be applied
+ to filtered textures.
+* ``GUARD_BAND_LEFT``, ``GUARD_BAND_TOP``, ``GUARD_BAND_RIGHT``,
+ ``GUARD_BAND_BOTTOM``: XXX
+
+XXX Is there a better home for this? vvv
+
+If 0 is returned, the driver is not aware of multiple constant buffers,
+supports binding of only one constant buffer, and does not support
+two-dimensional CONST register file access in TGSI shaders.
+
+If a value greater than 0 is returned, the driver can have multiple
+constant buffers bound to shader stages. The CONST register file can
+be accessed with two-dimensional indices, like in the example below.
+
+DCL CONST[0][0..7] # declare first 8 vectors of constbuf 0
+DCL CONST[3][0] # declare first vector of constbuf 3
+MOV OUT[0], CONST[0][3] # copy vector 3 of constbuf 0
+
+For backwards compatibility, one-dimensional access to CONST register
+file is still supported. In that case, the constbuf index is assumed
+to be 0.
+
+.. _pipe_buffer_usage:
+
+PIPE_BUFFER_USAGE
+^^^^^^^^^^^^^^^^^
+
+These flags control buffer creation. Buffers may only have one role, so
+care should be taken to not allocate a buffer with the wrong usage.
+
+* ``PIXEL``: This is the flag to use for all textures.
+* ``VERTEX``: A vertex buffer.
+* ``INDEX``: An element buffer.
+* ``CONSTANT``: A buffer of shader constants.
+
+Buffers are inevitably abstracting the pipe's underlying memory management,
+so many of their usage flags can be used to direct the way the buffer is
+handled.
+
+* ``CPU_READ``, ``CPU_WRITE``: Whether the user will map and, in the case of
+ the latter, write to, the buffer. The convenience flag ``CPU_READ_WRITE`` is
+ available to signify a read/write buffer.
+* ``GPU_READ``, ``GPU_WRITE``: Whether the driver will internally need to
+ read from or write to the buffer. The latter will only happen if the buffer
+ is made into a render target.
+* ``DISCARD``: When set on a map, the contents of the map will be discarded
+ beforehand. Cannot be used with ``CPU_READ``.
+* ``DONTBLOCK``: When set on a map, the map will fail if the buffer cannot be
+ mapped immediately.
+* ``UNSYNCHRONIZED``: When set on a map, any outstanding operations on the
+ buffer will be ignored. The interaction of any writes to the map and any
+ operations pending with the buffer are undefined. Cannot be used with
+ ``CPU_READ``.
+* ``FLUSH_EXPLICIT``: When set on a map, written ranges of the map require
+ explicit flushes using :ref:`buffer_flush_mapped_range`. Requires
+ ``CPU_WRITE``.
+
+.. _pipe_texture_usage:
+
+PIPE_TEXTURE_USAGE
+^^^^^^^^^^^^^^^^^^
+
+These flags determine the possible roles a texture may be used for during its
+lifetime. Texture usage flags are cumulative and may be combined to create a
+texture that can be used as multiple things.
+
+* ``RENDER_TARGET``: A colorbuffer or pixelbuffer.
+* ``DISPLAY_TARGET``: A sharable buffer that can be given to another process.
+* ``PRIMARY``: A frontbuffer or scanout buffer.
+* ``DEPTH_STENCIL``: A depthbuffer, stencilbuffer, or Z buffer. Gallium does
+ not explicitly provide for stencil-only buffers, so any stencilbuffer
+ validated here is implicitly also a depthbuffer.
+* ``SAMPLER``: A texture that may be sampled from in a fragment or vertex
+ shader.
+* ``DYNAMIC``: A texture that will be mapped frequently.
+
Methods
-------
@@ -18,22 +172,87 @@ get_vendor
Returns the screen vendor.
+.. _get_param:
+
get_param
^^^^^^^^^
Get an integer/boolean screen parameter.
+**param** is one of the :ref:`PIPE_CAP` names.
+
+.. _get_paramf:
+
get_paramf
^^^^^^^^^^
Get a floating-point screen parameter.
+**param** is one of the :ref:`PIPE_CAP` names.
+
is_format_supported
^^^^^^^^^^^^^^^^^^^
See if a format can be used in a specific manner.
+**usage** is a bitmask of :ref:`PIPE_TEXTURE_USAGE` flags.
+
+Returns TRUE if all usages can be satisfied.
+
+.. note::
+
+ ``PIPE_TEXTURE_USAGE_DYNAMIC`` is not a valid usage.
+
+.. _texture_create:
+
texture_create
^^^^^^^^^^^^^^
-Given a template of texture setup, create a BO-backed texture.
+Given a template of texture setup, create a buffer and texture.
+
+texture_blanket
+^^^^^^^^^^^^^^^
+
+Like :ref:`texture_create`, but use a supplied buffer instead of creating a
+new one.
+
+texture_destroy
+^^^^^^^^^^^^^^^
+
+Destroy a texture. The buffer backing the texture is destroyed if it has no
+more references.
+
+buffer_map
+^^^^^^^^^^
+
+Map a buffer into memory.
+
+**usage** is a bitmask of :ref:`PIPE_TEXTURE_USAGE` flags.
+
+Returns a pointer to the map, or NULL if the mapping failed.
+
+buffer_map_range
+^^^^^^^^^^^^^^^^
+
+Map a range of a buffer into memory.
+
+The returned map is always relative to the beginning of the buffer, not the
+beginning of the mapped range.
+
+.. _buffer_flush_mapped_range:
+
+buffer_flush_mapped_range
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Flush a range of mapped memory into a buffer.
+
+The buffer must have been mapped with ``PIPE_BUFFER_USAGE_FLUSH_EXPLICIT``.
+
+**usage** is a bitmask of :ref:`PIPE_TEXTURE_USAGE` flags.
+
+buffer_unmap
+^^^^^^^^^^^^
+
+Unmap a buffer from memory.
+
+Any pointers into the map should be considered invalid and discarded.
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index ebee4902b05..3e702ceeda4 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -516,8 +516,11 @@ SEQ - Set On Equal
.. math::
dst.x = (src0.x == src1.x) ? 1 : 0
+
dst.y = (src0.y == src1.y) ? 1 : 0
+
dst.z = (src0.z == src1.z) ? 1 : 0
+
dst.w = (src0.w == src1.w) ? 1 : 0
@@ -526,8 +529,11 @@ SFL - Set On False
.. math::
dst.x = 0
+
dst.y = 0
+
dst.z = 0
+
dst.w = 0
Considered for removal.
@@ -537,8 +543,11 @@ SGT - Set On Greater Than
.. math::
dst.x = (src0.x > src1.x) ? 1 : 0
+
dst.y = (src0.y > src1.y) ? 1 : 0
+
dst.z = (src0.z > src1.z) ? 1 : 0
+
dst.w = (src0.w > src1.w) ? 1 : 0
@@ -560,8 +569,11 @@ SLE - Set On Less Equal Than
.. math::
dst.x = (src0.x <= src1.x) ? 1 : 0
+
dst.y = (src0.y <= src1.y) ? 1 : 0
+
dst.z = (src0.z <= src1.z) ? 1 : 0
+
dst.w = (src0.w <= src1.w) ? 1 : 0
@@ -570,8 +582,11 @@ SNE - Set On Not Equal
.. math::
dst.x = (src0.x != src1.x) ? 1 : 0
+
dst.y = (src0.y != src1.y) ? 1 : 0
+
dst.z = (src0.z != src1.z) ? 1 : 0
+
dst.w = (src0.w != src1.w) ? 1 : 0
@@ -580,8 +595,11 @@ STR - Set On True
.. math::
dst.x = 1
+
dst.y = 1
+
dst.z = 1
+
dst.w = 1
@@ -629,8 +647,11 @@ X2D - 2D Coordinate Transformation
.. math::
dst.x = src0.x + src1.x \times src2.x + src1.y \times src2.y
+
dst.y = src0.y + src1.x \times src2.z + src1.y \times src2.w
+
dst.z = src0.x + src1.x \times src2.x + src1.y \times src2.y
+
dst.w = src0.y + src1.x \times src2.z + src1.y \times src2.w
Considered for removal.
@@ -979,13 +1000,13 @@ XOR - Bitwise Xor
.. math::
- dst.x = src0.x ^ src1.x
+ dst.x = src0.x \oplus src1.x
- dst.y = src0.y ^ src1.y
+ dst.y = src0.y \oplus src1.y
- dst.z = src0.z ^ src1.z
+ dst.z = src0.z \oplus src1.z
- dst.w = src0.w ^ src1.w
+ dst.w = src0.w \oplus src1.w
SAD - Sum Of Absolute Differences
@@ -1090,6 +1111,117 @@ BREAKC - Break Conditional
TBD
+Double Opcodes
+^^^^^^^^^^^^^^^
+
+DADD - Add Double
+
+.. math::
+
+ dst.xy = src0.xy + src1.xy
+
+ dst.zw = src0.zw + src1.zw
+
+
+DDIV - Divide Double
+
+.. math::
+
+ dst.xy = src0.xy / src1.xy
+
+ dst.zw = src0.zw / src1.zw
+
+DSEQ - Set Double on Equal
+
+.. math::
+
+ dst.xy = src0.xy == src1.xy ? 1.0F : 0.0F
+
+ dst.zw = src0.zw == src1.zw ? 1.0F : 0.0F
+
+DSLT - Set Double on Less than
+
+.. math::
+
+ dst.xy = src0.xy < src1.xy ? 1.0F : 0.0F
+
+ dst.zw = src0.zw < src1.zw ? 1.0F : 0.0F
+
+DFRAC - Double Fraction
+
+.. math::
+
+ dst.xy = src.xy - \lfloor src.xy\rfloor
+
+ dst.zw = src.zw - \lfloor src.zw\rfloor
+
+
+DFRACEXP - Convert Double Number to Fractional and Integral Components
+
+.. math::
+
+ dst0.xy = frexp(src.xy, dst1.xy)
+
+ dst0.zw = frexp(src.zw, dst1.zw)
+
+DLDEXP - Multiple Double Number by Integral Power of 2
+
+.. math::
+
+ dst.xy = ldexp(src0.xy, src1.xy)
+
+ dst.zw = ldexp(src0.zw, src1.zw)
+
+DMIN - Minimum Double
+
+.. math::
+
+ dst.xy = min(src0.xy, src1.xy)
+
+ dst.zw = min(src0.zw, src1.zw)
+
+DMAX - Maximum Double
+
+.. math::
+
+ dst.xy = max(src0.xy, src1.xy)
+
+ dst.zw = max(src0.zw, src1.zw)
+
+DMUL - Multiply Double
+
+.. math::
+
+ dst.xy = src0.xy \times src1.xy
+
+ dst.zw = src0.zw \times src1.zw
+
+
+DMAD - Multiply And Add Doubles
+
+.. math::
+
+ dst.xy = src0.xy \times src1.xy + src2.xy
+
+ dst.zw = src0.zw \times src1.zw + src2.zw
+
+
+DRCP - Reciprocal Double
+
+.. math::
+
+ dst.xy = \frac{1}{src.xy}
+
+ dst.zw = \frac{1}{src.zw}
+
+DSQRT - Square root double
+
+.. math::
+
+ dst.xy = \sqrt{src.xy}
+
+ dst.zw = \sqrt{src.zw}
+
Explanation of symbols used
------------------------------
@@ -1187,9 +1319,8 @@ are the Cartesian coordinates, and ``w`` is the homogenous coordinate and used
for the perspective divide, if enabled.
As a vertex shader output, position should be scaled to the viewport. When
-used in fragment shaders, position will ---
-
-XXX --- wait a minute. Should position be in [0,1] for x and y?
+used in fragment shaders, position will be in window coordinates. The convention
+used depends on the FS_COORD_ORIGIN and FS_COORD_PIXEL_CENTER properties.
XXX additionally, is there a way to configure the perspective divide? it's
accelerated on most chipsets AFAIK...
@@ -1268,3 +1399,45 @@ TGSI_SEMANTIC_EDGEFLAG
""""""""""""""""""""""
XXX no clue
+
+
+Properties
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+
+ Properties are general directives that apply to the whole TGSI program.
+
+FS_COORD_ORIGIN
+"""""""""""""""
+
+Specifies the fragment shader TGSI_SEMANTIC_POSITION coordinate origin.
+The default value is UPPER_LEFT.
+
+If UPPER_LEFT, the position will be (0,0) at the upper left corner and
+increase downward and rightward.
+If LOWER_LEFT, the position will be (0,0) at the lower left corner and
+increase upward and rightward.
+
+OpenGL defaults to LOWER_LEFT, and is configurable with the
+GL_ARB_fragment_coord_conventions extension.
+
+DirectX 9/10 use UPPER_LEFT.
+
+FS_COORD_PIXEL_CENTER
+"""""""""""""""""""""
+
+Specifies the fragment shader TGSI_SEMANTIC_POSITION pixel center convention.
+The default value is HALF_INTEGER.
+
+If HALF_INTEGER, the fractionary part of the position will be 0.5
+If INTEGER, the fractionary part of the position will be 0.0
+
+Note that this does not affect the set of fragments generated by
+rasterization, which is instead controlled by gl_rasterization_rules in the
+rasterizer.
+
+OpenGL defaults to HALF_INTEGER, and is configurable with the
+GL_ARB_fragment_coord_conventions extension.
+
+DirectX 9 uses INTEGER.
+DirectX 10 uses HALF_INTEGER.
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index 0a4da8ecc85..c674d0be633 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -59,7 +59,7 @@ cell_map_constant_buffers(struct cell_context *sp)
}
}
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
+ draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, 0,
sp->mapped_constants[PIPE_SHADER_VERTEX],
sp->constants[PIPE_SHADER_VERTEX]->size);
}
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
index 66d4b3b6a31..0dab34075da 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
@@ -408,7 +408,7 @@ gen_blend(const struct pipe_blend_state *blend,
int one_reg = -1;
int constR_reg = -1, constG_reg = -1, constB_reg = -1, constA_reg = -1;
- ASSERT(blend->blend_enable);
+ ASSERT(blend->rt[0].blend_enable);
/* packed RGBA -> float colors */
unpack_colors(f, color_format, fbRGBA_reg,
@@ -420,7 +420,7 @@ gen_blend(const struct pipe_blend_state *blend,
* because in some cases (like PIPE_BLENDFACTOR_ONE and
* PIPE_BLENDFACTOR_ZERO) we can avoid doing unnecessary math.
*/
- switch (blend->rgb_src_factor) {
+ switch (blend->rt[0].rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
/* factors = (1,1,1), so term = (R,G,B) */
spe_move(f, term1R_reg, fragR_reg);
@@ -574,7 +574,7 @@ gen_blend(const struct pipe_blend_state *blend,
* the full term A*factor, not just the factor itself, because
* in many cases we can avoid doing unnecessary multiplies.
*/
- switch (blend->alpha_src_factor) {
+ switch (blend->rt[0].alpha_src_factor) {
case PIPE_BLENDFACTOR_ZERO:
/* factor = 0, so term = 0 */
spe_load_float(f, term1A_reg, 0.0f);
@@ -648,7 +648,7 @@ gen_blend(const struct pipe_blend_state *blend,
* the full term (Rfb,Gfb,Bfb)*(factor), not just the factor itself, because
* in many cases we can avoid doing unnecessary multiplies.
*/
- switch (blend->rgb_dst_factor) {
+ switch (blend->rt[0].rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* factors = (1,1,1), so term = (Rfb,Gfb,Bfb) */
spe_move(f, term2R_reg, fbR_reg);
@@ -786,7 +786,7 @@ gen_blend(const struct pipe_blend_state *blend,
* the full term Afb*factor, not just the factor itself, because
* in many cases we can avoid doing unnecessary multiplies.
*/
- switch (blend->alpha_dst_factor) {
+ switch (blend->rt[0].alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* factor = 1, so term = Afb */
spe_move(f, term2A_reg, fbA_reg);
@@ -858,7 +858,7 @@ gen_blend(const struct pipe_blend_state *blend,
/*
* Combine Src/Dest RGB terms as per the blend equation.
*/
- switch (blend->rgb_func) {
+ switch (blend->rt[0].rgb_func) {
case PIPE_BLEND_ADD:
spe_fa(f, fragR_reg, term1R_reg, term2R_reg);
spe_fa(f, fragG_reg, term1G_reg, term2G_reg);
@@ -891,7 +891,7 @@ gen_blend(const struct pipe_blend_state *blend,
/*
* Combine Src/Dest A term
*/
- switch (blend->alpha_func) {
+ switch (blend->rt[0].alpha_func) {
case PIPE_BLEND_ADD:
spe_fa(f, fragA_reg, term1A_reg, term2A_reg);
break;
@@ -2118,7 +2118,7 @@ cell_gen_fragment_function(struct cell_context *cell,
spe_comment(f, 0, "Fetch quad colors from tile");
spe_lqx(f, fbRGBA_reg, color_tile_reg, quad_offset_reg);
- if (blend->blend_enable) {
+ if (blend->rt[0].blend_enable) {
spe_comment(f, 0, "Perform blending");
gen_blend(blend, blend_color, f, color_format,
fragR_reg, fragG_reg, fragB_reg, fragA_reg, fbRGBA_reg);
@@ -2143,9 +2143,9 @@ cell_gen_fragment_function(struct cell_context *cell,
gen_logicop(blend, f, rgba_reg, fbRGBA_reg);
}
- if (blend->colormask != PIPE_MASK_RGBA) {
+ if (blend->rt[0].colormask != PIPE_MASK_RGBA) {
spe_comment(f, 0, "Compute color mask");
- gen_colormask(f, blend->colormask, color_format, rgba_reg, fbRGBA_reg);
+ gen_colormask(f, blend->rt[0].colormask, color_format, rgba_reg, fbRGBA_reg);
}
/* Mix fragment colors with framebuffer colors using the quad/pixel mask:
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index d185c6b8497..37b04396b3e 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -86,6 +86,12 @@ cell_get_param(struct pipe_screen *screen, int param)
return 0; /* XXX to do */
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
index d97c22b2efe..21af7ed1c3f 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
@@ -999,23 +999,23 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
/* Does the selected blend mode make use of the source / destination
* color (RGB) blend factors?
*/
- boolean need_color_factor = b->blend_enable
- && (b->rgb_func != PIPE_BLEND_MIN)
- && (b->rgb_func != PIPE_BLEND_MAX);
+ boolean need_color_factor = b->rt[0].blend_enable
+ && (b->rt[0].rgb_func != PIPE_BLEND_MIN)
+ && (b->rt[0].rgb_func != PIPE_BLEND_MAX);
/* Does the selected blend mode make use of the source / destination
* alpha blend factors?
*/
- boolean need_alpha_factor = b->blend_enable
- && (b->alpha_func != PIPE_BLEND_MIN)
- && (b->alpha_func != PIPE_BLEND_MAX);
+ boolean need_alpha_factor = b->rt[0].blend_enable
+ && (b->rt[0].alpha_func != PIPE_BLEND_MIN)
+ && (b->rt[0].alpha_func != PIPE_BLEND_MAX);
- if (b->blend_enable) {
- sF[0] = b->rgb_src_factor;
+ if (b->rt[0].blend_enable) {
+ sF[0] = b->rt[0].rgb_src_factor;
sF[1] = sF[0];
sF[2] = sF[0];
- switch (b->alpha_src_factor & 0x0f) {
+ switch (b->rt[0].alpha_src_factor & 0x0f) {
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
sF[3] = PIPE_BLENDFACTOR_ONE;
break;
@@ -1023,30 +1023,30 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
case PIPE_BLENDFACTOR_DST_COLOR:
case PIPE_BLENDFACTOR_CONST_COLOR:
case PIPE_BLENDFACTOR_SRC1_COLOR:
- sF[3] = b->alpha_src_factor + 1;
+ sF[3] = b->rt[0].alpha_src_factor + 1;
break;
default:
- sF[3] = b->alpha_src_factor;
+ sF[3] = b->rt[0].alpha_src_factor;
}
- dF[0] = b->rgb_dst_factor;
+ dF[0] = b->rt[0].rgb_dst_factor;
dF[1] = dF[0];
dF[2] = dF[0];
- switch (b->alpha_dst_factor & 0x0f) {
+ switch (b->rt[0].alpha_dst_factor & 0x0f) {
case PIPE_BLENDFACTOR_SRC_COLOR:
case PIPE_BLENDFACTOR_DST_COLOR:
case PIPE_BLENDFACTOR_CONST_COLOR:
case PIPE_BLENDFACTOR_SRC1_COLOR:
- dF[3] = b->alpha_dst_factor + 1;
+ dF[3] = b->rt[0].alpha_dst_factor + 1;
break;
default:
- dF[3] = b->alpha_dst_factor;
+ dF[3] = b->rt[0].alpha_dst_factor;
}
- func[0] = b->rgb_func;
+ func[0] = b->rt[0].rgb_func;
func[1] = func[0];
func[2] = func[0];
- func[3] = b->alpha_func;
+ func[3] = b->rt[0].alpha_func;
} else {
sF[0] = PIPE_BLENDFACTOR_ONE;
sF[1] = PIPE_BLENDFACTOR_ONE;
@@ -1067,7 +1067,7 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
/* If alpha writing is enabled and the alpha blend mode requires use of
* the alpha factor, calculate the alpha factor.
*/
- if (((b->colormask & 8) != 0) && need_alpha_factor) {
+ if (((b->rt[0].colormask & 8) != 0) && need_alpha_factor) {
src_factor[3] = emit_alpha_factor_calculation(f, sF[3], const_color[3],
frag[3], pixel[3]);
@@ -1091,8 +1091,8 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
src_factor[2] = dst_factor[3];
} else if (need_color_factor) {
emit_color_factor_calculation(f,
- b->rgb_src_factor,
- b->colormask,
+ b->rt[0].rgb_src_factor,
+ b->rt[0].colormask,
frag, pixel, const_color, src_factor);
}
@@ -1111,15 +1111,15 @@ cell_generate_alpha_blend(struct cell_blend_state *cb)
dst_factor[2] = src_factor[2];
} else if (need_color_factor) {
emit_color_factor_calculation(f,
- b->rgb_dst_factor,
- b->colormask,
+ b->rt[0].rgb_dst_factor,
+ b->rt[0].colormask,
frag, pixel, const_color, dst_factor);
}
for (i = 0; i < 4; ++i) {
- if ((b->colormask & (1U << i)) != 0) {
+ if ((b->rt[0].colormask & (1U << i)) != 0) {
emit_blend_calculation(f,
func[i], sF[i], dF[i],
frag[i], src_factor[i],
@@ -1216,7 +1216,7 @@ cell_generate_logic_op(struct spe_function *f,
/* Short-circuit the noop and invert cases.
*/
- if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->colormask == 0)) {
+ if ((logic_op == PIPE_LOGICOP_NOOP) || (blend->rt[0].colormask == 0)) {
spe_bi(f, 0, 0, 0);
return;
} else if (logic_op == PIPE_LOGICOP_INVERT) {
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index b18f4c22ef1..a9d72f84d56 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -100,8 +100,10 @@ struct spu_framebuffer
void *depth_start; /**< addr of depth surface in main memory */
enum pipe_format color_format;
enum pipe_format depth_format;
- uint width, height; /**< size in pixels */
- uint width_tiles, height_tiles; /**< width and height in tiles */
+ uint width; /**< width in pixels */
+ uint height; /**< height in pixels */
+ uint width_tiles; /**< width in tiles */
+ uint height_tiles; /**< width in tiles */
uint color_clear_value;
uint depth_clear_value;
@@ -116,15 +118,23 @@ PIPE_ALIGN_TYPE(16,
struct spu_texture_level
{
void *start;
- ushort width, height, depth;
+ ushort width;
+ ushort height;
+ ushort depth;
ushort tiles_per_row;
uint bytes_per_image;
/** texcoord scale factors */
- vector float scale_s, scale_t, scale_r;
+ vector float scale_s;
+ vector float scale_t;
+ vector float scale_r;
/** texcoord masks (if REPEAT then size-1, else ~0) */
- vector signed int mask_s, mask_t, mask_r;
+ vector signed int mask_s;
+ vector signed int mask_t;
+ vector signed int mask_r;
/** texcoord clamp limits */
- vector signed int max_s, max_t, max_r;
+ vector signed int max_s;
+ vector signed int max_t;
+ vector signed int max_r;
});
@@ -166,7 +176,8 @@ struct spu_global
boolean read_depth_stencil;
/** Current tiles' status */
- ubyte cur_ctile_status, cur_ztile_status;
+ ubyte cur_ctile_status;
+ ubyte cur_ztile_status;
/** Status of all tiles in framebuffer */
PIPE_ALIGN_VAR(16) ubyte ctile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE];
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 90530f2826f..0d0859f8f33 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -32,7 +32,6 @@
#include "util/u_clear.h"
#include "i915_context.h"
-#include "i915_state.h"
/**
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 89feeade756..a0c80d02286 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -29,12 +29,9 @@
#include "i915_state.h"
#include "i915_screen.h"
#include "i915_batch.h"
-#include "i915_texture.h"
-#include "i915_reg.h"
#include "draw/draw_context.h"
#include "pipe/p_defines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "pipe/p_screen.h"
@@ -84,7 +81,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
}
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
i915->current.constants[PIPE_SHADER_VERTEX],
(i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
4 * sizeof(float)));
diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c
index c6e6d6fd313..237654d26b2 100644
--- a/src/gallium/drivers/i915/i915_debug.c
+++ b/src/gallium/drivers/i915/i915_debug.c
@@ -29,7 +29,6 @@
#include "i915_context.h"
#include "i915_debug.h"
#include "i915_batch.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_debug.h"
diff --git a/src/gallium/drivers/i915/i915_debug_fp.c b/src/gallium/drivers/i915/i915_debug_fp.c
index 9c5b117b6dd..f9c40d8a110 100644
--- a/src/gallium/drivers/i915/i915_debug_fp.c
+++ b/src/gallium/drivers/i915/i915_debug_fp.c
@@ -29,7 +29,6 @@
#include "i915_reg.h"
#include "i915_debug.h"
#include "pipe/internal/p_winsys_screen.h"
-#include "util/u_memory.h"
static void
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index d4ee8f5339b..7b8d66b8aa1 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -117,6 +117,12 @@ i915_get_param(struct pipe_screen *screen, int param)
return 8; /* max 128x128x128 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 11; /* max 1024x1024 */
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 0fab6e1bc36..23e4d6b9938 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -30,7 +30,6 @@
#include "draw/draw_context.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -38,7 +37,6 @@
#include "i915_context.h"
#include "i915_reg.h"
-#include "i915_state.h"
#include "i915_state_inlines.h"
#include "i915_fpc.h"
@@ -105,13 +103,13 @@ i915_create_blend_state(struct pipe_context *pipe,
struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state );
{
- unsigned eqRGB = blend->rgb_func;
- unsigned srcRGB = blend->rgb_src_factor;
- unsigned dstRGB = blend->rgb_dst_factor;
+ unsigned eqRGB = blend->rt[0].rgb_func;
+ unsigned srcRGB = blend->rt[0].rgb_src_factor;
+ unsigned dstRGB = blend->rt[0].rgb_dst_factor;
- unsigned eqA = blend->alpha_func;
- unsigned srcA = blend->alpha_src_factor;
- unsigned dstA = blend->alpha_dst_factor;
+ unsigned eqA = blend->rt[0].alpha_func;
+ unsigned srcA = blend->rt[0].alpha_src_factor;
+ unsigned dstA = blend->rt[0].alpha_dst_factor;
/* Special handling for MIN/MAX filter modes handled at
* state_tracker level.
@@ -148,22 +146,22 @@ i915_create_blend_state(struct pipe_context *pipe,
if (blend->dither)
cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE;
- if ((blend->colormask & PIPE_MASK_R) == 0)
+ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_RED;
- if ((blend->colormask & PIPE_MASK_G) == 0)
+ if ((blend->rt[0].colormask & PIPE_MASK_G) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_GREEN;
- if ((blend->colormask & PIPE_MASK_B) == 0)
+ if ((blend->rt[0].colormask & PIPE_MASK_B) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_BLUE;
- if ((blend->colormask & PIPE_MASK_A) == 0)
+ if ((blend->rt[0].colormask & PIPE_MASK_A) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA;
- if (blend->blend_enable) {
- unsigned funcRGB = blend->rgb_func;
- unsigned srcRGB = blend->rgb_src_factor;
- unsigned dstRGB = blend->rgb_dst_factor;
+ if (blend->rt[0].blend_enable) {
+ unsigned funcRGB = blend->rt[0].rgb_func;
+ unsigned srcRGB = blend->rt[0].rgb_src_factor;
+ unsigned dstRGB = blend->rt[0].rgb_dst_factor;
cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE |
SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) |
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index 03dd5091a61..f5b0e9f011e 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -33,7 +33,6 @@
#include "i915_context.h"
#include "i915_state.h"
#include "i915_reg.h"
-#include "i915_fpc.h"
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index cbac4175c8f..e5c6d87215b 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -27,7 +27,6 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "util/u_memory.h"
#include "i915_state_inlines.h"
#include "i915_context.h"
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index c693eb30e87..1ff6b9f4c63 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -27,14 +27,8 @@
#include "i915_context.h"
#include "i915_blit.h"
-#include "i915_state.h"
#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_format.h"
-#include "util/u_tile.h"
-#include "util/u_rect.h"
/* Assumes all values are within bounds -- no checking at this level -
diff --git a/src/gallium/drivers/i915/i915_texture.c b/src/gallium/drivers/i915/i915_texture.c
index 50a9e19094b..612e5c1cdd5 100644
--- a/src/gallium/drivers/i915/i915_texture.c
+++ b/src/gallium/drivers/i915/i915_texture.c
@@ -34,14 +34,12 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "i915_context.h"
#include "i915_texture.h"
-#include "i915_debug.h"
#include "i915_screen.h"
#include "intel_winsys.h"
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c
index 22607dc6083..003b1fd5bf0 100644
--- a/src/gallium/drivers/i965/brw_batchbuffer.c
+++ b/src/gallium/drivers/i965/brw_batchbuffer.c
@@ -155,7 +155,7 @@ _brw_batchbuffer_flush(struct brw_batchbuffer *batch,
enum pipe_error
brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
struct brw_winsys_buffer *buffer,
- uint32_t usage,
+ enum brw_buffer_usage usage,
uint32_t delta)
{
int ret;
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.h b/src/gallium/drivers/i965/brw_batchbuffer.h
index 7473f5bea4d..6ca9f617f5e 100644
--- a/src/gallium/drivers/i965/brw_batchbuffer.h
+++ b/src/gallium/drivers/i965/brw_batchbuffer.h
@@ -64,12 +64,12 @@ brw_batchbuffer_reset(struct brw_batchbuffer *batch);
* Consider it a convenience function wrapping multple
* intel_buffer_dword() calls.
*/
-int brw_batchbuffer_data(struct brw_batchbuffer *batch,
+enum pipe_error brw_batchbuffer_data(struct brw_batchbuffer *batch,
const void *data, GLuint bytes,
enum cliprect_mode cliprect_mode);
-int brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
+enum pipe_error brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
struct brw_winsys_buffer *buffer,
enum brw_buffer_usage usage,
uint32_t offset);
diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c
index 3e070f5591a..4a543276f54 100644
--- a/src/gallium/drivers/i965/brw_cc.c
+++ b/src/gallium/drivers/i965/brw_cc.c
@@ -32,7 +32,6 @@
#include "brw_context.h"
#include "brw_state.h"
-#include "brw_defines.h"
static enum pipe_error prepare_cc_vp( struct brw_context *brw )
diff --git a/src/gallium/drivers/i965/brw_clip.c b/src/gallium/drivers/i965/brw_clip.c
index d67a1a62633..ccba205e8c7 100644
--- a/src/gallium/drivers/i965/brw_clip.c
+++ b/src/gallium/drivers/i965/brw_clip.c
@@ -38,7 +38,6 @@
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_state.h"
#include "brw_pipe_rast.h"
#include "brw_clip.h"
diff --git a/src/gallium/drivers/i965/brw_clip_line.c b/src/gallium/drivers/i965/brw_clip_line.c
index 54282d975ed..66caadc4d53 100644
--- a/src/gallium/drivers/i965/brw_clip_line.c
+++ b/src/gallium/drivers/i965/brw_clip_line.c
@@ -33,7 +33,6 @@
#include "brw_defines.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_clip.h"
diff --git a/src/gallium/drivers/i965/brw_clip_point.c b/src/gallium/drivers/i965/brw_clip_point.c
index e0a5330556d..124156c1b50 100644
--- a/src/gallium/drivers/i965/brw_clip_point.c
+++ b/src/gallium/drivers/i965/brw_clip_point.c
@@ -31,7 +31,6 @@
#include "brw_defines.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_clip.h"
diff --git a/src/gallium/drivers/i965/brw_clip_tri.c b/src/gallium/drivers/i965/brw_clip_tri.c
index 4cde7294ea0..069524bc14f 100644
--- a/src/gallium/drivers/i965/brw_clip_tri.c
+++ b/src/gallium/drivers/i965/brw_clip_tri.c
@@ -31,7 +31,6 @@
#include "brw_defines.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_clip.h"
static void release_tmps( struct brw_clip_compile *c )
diff --git a/src/gallium/drivers/i965/brw_clip_util.c b/src/gallium/drivers/i965/brw_clip_util.c
index 97a57103105..23e51ee9bcd 100644
--- a/src/gallium/drivers/i965/brw_clip_util.c
+++ b/src/gallium/drivers/i965/brw_clip_util.c
@@ -32,7 +32,6 @@
#include "brw_defines.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_clip.h"
diff --git a/src/gallium/drivers/i965/brw_context.c b/src/gallium/drivers/i965/brw_context.c
index e67551882dc..d60b7b99b6e 100644
--- a/src/gallium/drivers/i965/brw_context.c
+++ b/src/gallium/drivers/i965/brw_context.c
@@ -34,7 +34,6 @@
#include "util/u_simple_list.h"
#include "brw_context.h"
-#include "brw_defines.h"
#include "brw_draw.h"
#include "brw_state.h"
#include "brw_batchbuffer.h"
diff --git a/src/gallium/drivers/i965/brw_curbe.c b/src/gallium/drivers/i965/brw_curbe.c
index 3f031577d5a..4b215a001c4 100644
--- a/src/gallium/drivers/i965/brw_curbe.c
+++ b/src/gallium/drivers/i965/brw_curbe.c
@@ -36,9 +36,7 @@
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_state.h"
-#include "brw_util.h"
#include "brw_debug.h"
-#include "brw_screen.h"
/**
diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c
index ea8d39adaf0..1b5cd23995b 100644
--- a/src/gallium/drivers/i965/brw_draw.c
+++ b/src/gallium/drivers/i965/brw_draw.c
@@ -34,7 +34,6 @@
#include "brw_context.h"
#include "brw_state.h"
#include "brw_debug.h"
-#include "brw_screen.h"
#include "brw_batchbuffer.h"
diff --git a/src/gallium/drivers/i965/brw_gs.c b/src/gallium/drivers/i965/brw_gs.c
index 921b201bae2..06826635a8a 100644
--- a/src/gallium/drivers/i965/brw_gs.c
+++ b/src/gallium/drivers/i965/brw_gs.c
@@ -34,7 +34,6 @@
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_state.h"
#include "brw_gs.h"
diff --git a/src/gallium/drivers/i965/brw_gs_emit.c b/src/gallium/drivers/i965/brw_gs_emit.c
index fd8e2accedd..9b58773b3bd 100644
--- a/src/gallium/drivers/i965/brw_gs_emit.c
+++ b/src/gallium/drivers/i965/brw_gs_emit.c
@@ -35,7 +35,6 @@
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_gs.h"
static void brw_gs_alloc_regs( struct brw_gs_compile *c,
diff --git a/src/gallium/drivers/i965/brw_pipe_blend.c b/src/gallium/drivers/i965/brw_pipe_blend.c
index b759a910b63..21f786f8715 100644
--- a/src/gallium/drivers/i965/brw_pipe_blend.c
+++ b/src/gallium/drivers/i965/brw_pipe_blend.c
@@ -118,14 +118,14 @@ static void *brw_create_blend_state( struct pipe_context *pipe,
blend->cc2.logicop_enable = 1;
blend->cc5.logicop_func = translate_logicop(templ->logicop_func);
}
- else if (templ->blend_enable) {
- blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor);
- blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor);
- blend->cc6.blend_function = translate_blend_equation(templ->rgb_func);
+ else if (templ->rt[0].blend_enable) {
+ blend->cc6.dest_blend_factor = translate_blend_factor(templ->rt[0].rgb_dst_factor);
+ blend->cc6.src_blend_factor = translate_blend_factor(templ->rt[0].rgb_src_factor);
+ blend->cc6.blend_function = translate_blend_equation(templ->rt[0].rgb_func);
- blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor);
- blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor);
- blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func);
+ blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->rt[0].alpha_dst_factor);
+ blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->rt[0].alpha_src_factor);
+ blend->cc5.ia_blend_function = translate_blend_equation(templ->rt[0].alpha_func);
blend->cc3.blend_enable = 1;
blend->cc3.ia_blend_enable =
@@ -146,10 +146,10 @@ static void *brw_create_blend_state( struct pipe_context *pipe,
/* Per-surface color mask -- just follow global state:
*/
- blend->ss0.writedisable_red = (templ->colormask & PIPE_MASK_R) ? 0 : 1;
- blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 0 : 1;
- blend->ss0.writedisable_blue = (templ->colormask & PIPE_MASK_B) ? 0 : 1;
- blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 0 : 1;
+ blend->ss0.writedisable_red = (templ->rt[0].colormask & PIPE_MASK_R) ? 0 : 1;
+ blend->ss0.writedisable_green = (templ->rt[0].colormask & PIPE_MASK_G) ? 0 : 1;
+ blend->ss0.writedisable_blue = (templ->rt[0].colormask & PIPE_MASK_B) ? 0 : 1;
+ blend->ss0.writedisable_alpha = (templ->rt[0].colormask & PIPE_MASK_A) ? 0 : 1;
return (void *)blend;
}
diff --git a/src/gallium/drivers/i965/brw_pipe_fb.c b/src/gallium/drivers/i965/brw_pipe_fb.c
index 5d4e5025f97..c1f049272ac 100644
--- a/src/gallium/drivers/i965/brw_pipe_fb.c
+++ b/src/gallium/drivers/i965/brw_pipe_fb.c
@@ -3,7 +3,6 @@
#include "pipe/p_state.h"
#include "brw_context.h"
-#include "brw_debug.h"
/**
* called from intelDrawBuffer()
diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c
index 81712798a5d..ef6c1bb3155 100644
--- a/src/gallium/drivers/i965/brw_pipe_sampler.c
+++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
@@ -7,7 +7,6 @@
#include "brw_context.h"
#include "brw_defines.h"
-#include "brw_debug.h"
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 0ecacac9a3a..a8f9892d71d 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -138,6 +138,9 @@ brw_get_name(struct pipe_screen *screen)
case PCI_CHIP_ILM_G:
chipset = "ILM_G";
break;
+ default:
+ chipset = "unknown";
+ break;
}
util_snprintf(buffer, sizeof(buffer), "i965 (chipset: %s)", chipset);
@@ -172,6 +175,12 @@ brw_get_param(struct pipe_screen *screen, int param)
return 8; /* max 128x128x128 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 11; /* max 1024x1024 */
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/i965/brw_sf.c b/src/gallium/drivers/i965/brw_sf.c
index e1986a9dbbd..6e99eaa09d8 100644
--- a/src/gallium/drivers/i965/brw_sf.c
+++ b/src/gallium/drivers/i965/brw_sf.c
@@ -36,7 +36,6 @@
#include "brw_context.h"
#include "brw_pipe_rast.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_sf.h"
#include "brw_state.h"
diff --git a/src/gallium/drivers/i965/brw_sf_emit.c b/src/gallium/drivers/i965/brw_sf_emit.c
index 3b85725e368..497634ec9ed 100644
--- a/src/gallium/drivers/i965/brw_sf_emit.c
+++ b/src/gallium/drivers/i965/brw_sf_emit.c
@@ -35,7 +35,6 @@
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_eu.h"
-#include "brw_util.h"
#include "brw_sf.h"
diff --git a/src/gallium/drivers/i965/brw_state_cache.c b/src/gallium/drivers/i965/brw_state_cache.c
index 16b643ceb28..85c20076fb8 100644
--- a/src/gallium/drivers/i965/brw_state_cache.c
+++ b/src/gallium/drivers/i965/brw_state_cache.c
@@ -59,7 +59,6 @@
#include "brw_debug.h"
#include "brw_state.h"
-#include "brw_batchbuffer.h"
/* XXX: Fixme - have to include these to get the sizes of the prog_key
* structs:
diff --git a/src/gallium/drivers/i965/brw_util.c b/src/gallium/drivers/i965/brw_util.c
index 458058d668d..1fd2e297137 100644
--- a/src/gallium/drivers/i965/brw_util.c
+++ b/src/gallium/drivers/i965/brw_util.c
@@ -30,8 +30,6 @@
*/
-#include "brw_util.h"
-#include "brw_defines.h"
diff --git a/src/gallium/drivers/i965/brw_vs.c b/src/gallium/drivers/i965/brw_vs.c
index e3ea5a3a135..ca8ee79550d 100644
--- a/src/gallium/drivers/i965/brw_vs.c
+++ b/src/gallium/drivers/i965/brw_vs.c
@@ -33,9 +33,7 @@
#include "brw_context.h"
#include "brw_vs.h"
-#include "brw_util.h"
#include "brw_state.h"
-#include "brw_pipe_rast.h"
diff --git a/src/gallium/drivers/i965/brw_vs_surface_state.c b/src/gallium/drivers/i965/brw_vs_surface_state.c
index 177a5170d23..004e3cb4e6f 100644
--- a/src/gallium/drivers/i965/brw_vs_surface_state.c
+++ b/src/gallium/drivers/i965/brw_vs_surface_state.c
@@ -31,7 +31,6 @@
#include "brw_context.h"
#include "brw_state.h"
-#include "brw_defines.h"
#include "brw_winsys.h"
/* XXX: disabled true constant buffer functionality
diff --git a/src/gallium/drivers/i965/brw_wm_fp.c b/src/gallium/drivers/i965/brw_wm_fp.c
index 9c5b527f897..9c67759ad0b 100644
--- a/src/gallium/drivers/i965/brw_wm_fp.c
+++ b/src/gallium/drivers/i965/brw_wm_fp.c
@@ -41,7 +41,6 @@
#include "tgsi/tgsi_util.h"
#include "brw_wm.h"
-#include "brw_util.h"
#include "brw_debug.h"
diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c
index f92b8198ed3..b01a7f194b7 100644
--- a/src/gallium/drivers/i965/brw_wm_surface_state.c
+++ b/src/gallium/drivers/i965/brw_wm_surface_state.c
@@ -34,7 +34,6 @@
#include "brw_batchbuffer.h"
#include "brw_context.h"
#include "brw_state.h"
-#include "brw_defines.h"
#include "brw_screen.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
index 2b4bc5c819d..7245730350c 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
@@ -35,7 +35,6 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
-#include "lp_bld_arit.h"
#include "lp_bld_logic.h"
#include "lp_bld_flow.h"
#include "lp_bld_debug.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
index ced7b9c11d7..ad1dbbc9b19 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -314,9 +314,10 @@ lp_build_blend_aos(LLVMBuilderRef builder,
LLVMValueRef dst_term;
/* FIXME */
- assert(blend->colormask == 0xf);
+ assert(blend->independent_blend_enable == 0);
+ assert(blend->rt[0].colormask == 0xf);
- if(!blend->blend_enable)
+ if(!blend->rt[0].blend_enable)
return src;
/* It makes no sense to blend unless values are normalized */
@@ -333,14 +334,16 @@ lp_build_blend_aos(LLVMBuilderRef builder,
* combinations it is possible to reorder the operations and therefore saving
* some instructions. */
- src_term = lp_build_blend_factor(&bld, src, blend->rgb_src_factor, blend->alpha_src_factor, alpha_swizzle);
- dst_term = lp_build_blend_factor(&bld, dst, blend->rgb_dst_factor, blend->alpha_dst_factor, alpha_swizzle);
+ src_term = lp_build_blend_factor(&bld, src, blend->rt[0].rgb_src_factor,
+ blend->rt[0].alpha_src_factor, alpha_swizzle);
+ dst_term = lp_build_blend_factor(&bld, dst, blend->rt[0].rgb_dst_factor,
+ blend->rt[0].alpha_dst_factor, alpha_swizzle);
lp_build_name(src_term, "src_term");
lp_build_name(dst_term, "dst_term");
- if(blend->rgb_func == blend->alpha_func) {
- return lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term);
+ if(blend->rt[0].rgb_func == blend->rt[0].alpha_func) {
+ return lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term);
}
else {
/* Seperate RGB / A functions */
@@ -348,8 +351,8 @@ lp_build_blend_aos(LLVMBuilderRef builder,
LLVMValueRef rgb;
LLVMValueRef alpha;
- rgb = lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term);
- alpha = lp_build_blend_func(&bld.base, blend->alpha_func, src_term, dst_term);
+ rgb = lp_build_blend_func(&bld.base, blend->rt[0].rgb_func, src_term, dst_term);
+ alpha = lp_build_blend_func(&bld.base, blend->rt[0].alpha_func, src_term, dst_term);
return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
index 9511299d558..a73d1158e79 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
@@ -71,7 +71,6 @@
#include "pipe/p_state.h"
#include "lp_bld_type.h"
-#include "lp_bld_const.h"
#include "lp_bld_arit.h"
#include "lp_bld_blend.h"
@@ -218,7 +217,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
}
for (i = 0; i < 4; ++i) {
- if (blend->colormask & (1 << i)) {
+ if (blend->rt[0].colormask & (1 << i)) {
if (blend->logicop_enable) {
if(!type.floating) {
res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]);
@@ -226,10 +225,10 @@ lp_build_blend_soa(LLVMBuilderRef builder,
else
res[i] = dst[i];
}
- else if (blend->blend_enable) {
- unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor;
- unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor;
- unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func;
+ else if (blend->rt[0].blend_enable) {
+ unsigned src_factor = i < 3 ? blend->rt[0].rgb_src_factor : blend->rt[0].alpha_src_factor;
+ unsigned dst_factor = i < 3 ? blend->rt[0].rgb_dst_factor : blend->rt[0].alpha_dst_factor;
+ unsigned func = i < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func;
boolean func_commutative = lp_build_blend_func_commutative(func);
/* It makes no sense to blend unless values are normalized */
@@ -270,7 +269,7 @@ lp_build_blend_soa(LLVMBuilderRef builder,
/* See if this function has been previously applied */
for(j = 0; j < i; ++j) {
- unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func;
+ unsigned prev_func = j < 3 ? blend->rt[0].rgb_func : blend->rt[0].alpha_func;
unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func);
if((!func_reverse &&
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/drivers/llvmpipe/lp_bld_conv.c
index 9fa88372022..f77cf787213 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c
@@ -63,11 +63,9 @@
#include "util/u_debug.h"
#include "util/u_math.h"
-#include "util/u_cpu_detect.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
-#include "lp_bld_intr.h"
#include "lp_bld_arit.h"
#include "lp_bld_pack.h"
#include "lp_bld_conv.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
index 10e82f120bb..dfa080b8533 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
@@ -38,7 +38,6 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
-#include "lp_bld_logic.h"
#include "lp_bld_swizzle.h"
#include "lp_bld_format.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index fb1eda4423b..85e3b1bdd42 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -47,13 +47,11 @@
#include "tgsi/tgsi_exec.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
-#include "lp_bld_intr.h"
#include "lp_bld_arit.h"
#include "lp_bld_logic.h"
#include "lp_bld_swizzle.h"
#include "lp_bld_flow.h"
#include "lp_bld_tgsi.h"
-#include "lp_bld_debug.h"
#define LP_MAX_TEMPS 256
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 3989cce7445..3dd68d5794e 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -33,8 +33,6 @@
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_inlines.h"
#include "util/u_prim.h"
#include "lp_buffer.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 07f32848c7f..edd480d7ed9 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -35,7 +35,6 @@
#include "lp_flush.h"
#include "lp_context.h"
#include "lp_surface.h"
-#include "lp_winsys.h"
#include "lp_setup.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 9fad7033db5..310fc2b8479 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -40,7 +40,6 @@
#include "lp_debug.h"
#include "lp_screen.h"
#include "lp_bld_intr.h"
-#include "lp_bld_misc.h"
#include "lp_jit.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index a3adc81e9f9..ca64c418276 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -115,6 +115,16 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ return 0;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return 0;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index a7514ee011d..0602e940d92 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -66,7 +66,6 @@
#include "util/u_format.h"
#include "util/u_debug_dump.h"
#include "util/u_time.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
#include "tgsi/tgsi_dump.h"
@@ -568,7 +567,7 @@ generate_blend(const struct pipe_blend_state *blend,
lp_build_blend_soa(builder, blend, type, src, dst, con, res);
for(chan = 0; chan < 4; ++chan) {
- if(blend->colormask & (1 << chan)) {
+ if(blend->rt[0].colormask & (1 << chan)) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
lp_build_name(res[chan], "res.%c", "rgba"[chan]);
res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
@@ -871,15 +870,15 @@ generate_variant(struct llvmpipe_context *lp,
if(key->blend.logicop_enable) {
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
}
- else if(key->blend.blend_enable) {
- debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
- debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
- debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
- debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
- debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
- debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
+ else if(key->blend.rt[0].blend_enable) {
+ debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rt[0].rgb_func, TRUE));
+ debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE));
+ debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE));
+ debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.rt[0].alpha_func, TRUE));
+ debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE));
+ debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE));
}
- debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
+ debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
if(key->sampler[i].format) {
debug_printf("sampler[%u] = \n", i);
@@ -1020,7 +1019,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
pipe_buffer_reference(&llvmpipe->constants[shader], constants);
if(shader == PIPE_SHADER_VERTEX) {
- draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX,
+ draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0,
data, size);
}
@@ -1078,7 +1077,7 @@ make_variant_key(struct llvmpipe_context *lp,
enum util_format_swizzle swizzle = format_desc->swizzle[chan];
if(swizzle <= UTIL_FORMAT_SWIZZLE_W)
- key->cbuf_blend[i].colormask |= (1 << chan);
+ key->blend.rt[0].colormask |= (1 << chan);
}
}
@@ -1128,8 +1127,8 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
/* TODO: put this in the variant */
/* TODO: most of these can be relaxed, in particular the colormask */
opaque = !key.blend.logicop_enable &&
- !key.blend.blend_enable &&
- key.blend.colormask == 0xf &&
+ !key.blend.rt[0].blend_enable &&
+ key.blend.rt[0].colormask == 0xf &&
!key.alpha.enabled &&
!key.depth.enabled &&
!key.scissor &&
diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c
index 0e9f03b90b8..aa4241a80db 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c
@@ -32,7 +32,6 @@
#include "util/u_surface.h"
#include "lp_context.h"
#include "lp_state.h"
-#include "lp_surface.h"
#include "lp_setup.h"
#include "draw/draw_context.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
index 1a17631a4c6..57ac25ea0cb 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -31,7 +31,6 @@
#include "lp_context.h"
#include "lp_state.h"
-#include "lp_surface.h"
#include "draw/draw_context.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 6c29e8d8ace..ee72f6ce4fc 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -38,7 +38,6 @@
#include "lp_bld_type.h"
-#include "lp_bld_arit.h"
#include "lp_bld_blend.h"
#include "lp_bld_debug.h"
#include "lp_test.h"
@@ -104,18 +103,18 @@ write_tsv_row(FILE *fp,
fprintf(fp,
"%s\t%s\t%s\t",
- blend->rgb_func != blend->alpha_func ? "true" : "false",
- blend->rgb_src_factor != blend->alpha_src_factor ? "true" : "false",
- blend->rgb_dst_factor != blend->alpha_dst_factor ? "true" : "false");
+ blend->rt[0].rgb_func != blend->rt[0].alpha_func ? "true" : "false",
+ blend->rt[0].rgb_src_factor != blend->rt[0].alpha_src_factor ? "true" : "false",
+ blend->rt[0].rgb_dst_factor != blend->rt[0].alpha_dst_factor ? "true" : "false");
fprintf(fp,
"%s\t%s\t%s\t%s\t%s\t%s\n",
- debug_dump_blend_func(blend->rgb_func, TRUE),
- debug_dump_blend_factor(blend->rgb_src_factor, TRUE),
- debug_dump_blend_factor(blend->rgb_dst_factor, TRUE),
- debug_dump_blend_func(blend->alpha_func, TRUE),
- debug_dump_blend_factor(blend->alpha_src_factor, TRUE),
- debug_dump_blend_factor(blend->alpha_dst_factor, TRUE));
+ debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
+ debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
+ debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
+ debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
+ debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
+ debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
fflush(fp);
}
@@ -137,12 +136,12 @@ dump_blend_type(FILE *fp,
fprintf(fp,
" %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
- "rgb_func", debug_dump_blend_func(blend->rgb_func, TRUE),
- "rgb_src_factor", debug_dump_blend_factor(blend->rgb_src_factor, TRUE),
- "rgb_dst_factor", debug_dump_blend_factor(blend->rgb_dst_factor, TRUE),
- "alpha_func", debug_dump_blend_func(blend->alpha_func, TRUE),
- "alpha_src_factor", debug_dump_blend_factor(blend->alpha_src_factor, TRUE),
- "alpha_dst_factor", debug_dump_blend_factor(blend->alpha_dst_factor, TRUE));
+ "rgb_func", debug_dump_blend_func(blend->rt[0].rgb_func, TRUE),
+ "rgb_src_factor", debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE),
+ "rgb_dst_factor", debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE),
+ "alpha_func", debug_dump_blend_func(blend->rt[0].alpha_func, TRUE),
+ "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE),
+ "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE));
fprintf(fp, " ...\n");
fflush(fp);
@@ -401,13 +400,15 @@ compute_blend_ref(const struct pipe_blend_state *blend,
double src_term[4];
double dst_term[4];
- compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, con, src_term);
- compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, con, dst_term);
+ compute_blend_ref_term(blend->rt[0].rgb_src_factor, blend->rt[0].alpha_src_factor,
+ src, src, dst, con, src_term);
+ compute_blend_ref_term(blend->rt[0].rgb_dst_factor, blend->rt[0].alpha_dst_factor,
+ dst, src, dst, con, dst_term);
/*
* Combine RGB terms
*/
- switch (blend->rgb_func) {
+ switch (blend->rt[0].rgb_func) {
case PIPE_BLEND_ADD:
ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */
ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */
@@ -440,7 +441,7 @@ compute_blend_ref(const struct pipe_blend_state *blend,
/*
* Combine A terms
*/
- switch (blend->alpha_func) {
+ switch (blend->rt[0].alpha_func) {
case PIPE_BLEND_ADD:
ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */
break;
@@ -806,14 +807,14 @@ test_all(unsigned verbose, FILE *fp)
continue;
memset(&blend, 0, sizeof blend);
- blend.blend_enable = 1;
- blend.rgb_func = *rgb_func;
- blend.rgb_src_factor = *rgb_src_factor;
- blend.rgb_dst_factor = *rgb_dst_factor;
- blend.alpha_func = *alpha_func;
- blend.alpha_src_factor = *alpha_src_factor;
- blend.alpha_dst_factor = *alpha_dst_factor;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 1;
+ blend.rt[0].rgb_func = *rgb_func;
+ blend.rt[0].rgb_src_factor = *rgb_src_factor;
+ blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
+ blend.rt[0].alpha_func = *alpha_func;
+ blend.rt[0].alpha_src_factor = *alpha_src_factor;
+ blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
if(!test_one(verbose, fp, &blend, mode, *type))
success = FALSE;
@@ -865,14 +866,14 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
type = &blend_types[rand() % num_types];
memset(&blend, 0, sizeof blend);
- blend.blend_enable = 1;
- blend.rgb_func = *rgb_func;
- blend.rgb_src_factor = *rgb_src_factor;
- blend.rgb_dst_factor = *rgb_dst_factor;
- blend.alpha_func = *alpha_func;
- blend.alpha_src_factor = *alpha_src_factor;
- blend.alpha_dst_factor = *alpha_dst_factor;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 1;
+ blend.rt[0].rgb_func = *rgb_func;
+ blend.rt[0].rgb_src_factor = *rgb_src_factor;
+ blend.rt[0].rgb_dst_factor = *rgb_dst_factor;
+ blend.rt[0].alpha_func = *alpha_func;
+ blend.rt[0].alpha_src_factor = *alpha_src_factor;
+ blend.rt[0].alpha_dst_factor = *alpha_dst_factor;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
if(!test_one(verbose, fp, &blend, mode, *type))
success = FALSE;
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index d59d7681398..7f55f1ae83f 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -44,7 +44,6 @@
#include "pipe/p_shader_tokens.h"
#include "lp_bld_debug.h"
#include "lp_bld_type.h"
-#include "lp_bld_intr.h"
#include "lp_bld_sample.h"
#include "lp_bld_tgsi.h"
#include "lp_jit.h"
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 36e2ebb41a3..c9b6eb180ff 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -33,7 +33,6 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_format.h"
#include "util/u_math.h"
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 7ebc94ed6c7..1ad539d2858 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -260,6 +260,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
void
nouveau_screen_fini(struct nouveau_screen *screen)
{
+ struct pipe_winsys *ws = screen->base.winsys;
nouveau_channel_free(&screen->channel);
+ ws->destroy(ws);
}
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index 7c5b6e8229a..97538964af8 100644
--- a/src/gallium/drivers/nv04/nv04_screen.c
+++ b/src/gallium/drivers/nv04/nv04_screen.c
@@ -45,6 +45,16 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)
case NOUVEAU_CAP_HW_VTXBUF:
case NOUVEAU_CAP_HW_IDXBUF:
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;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c
index b67f1e16b1c..1fdb764b532 100644
--- a/src/gallium/drivers/nv04/nv04_state.c
+++ b/src/gallium/drivers/nv04/nv04_state.c
@@ -17,11 +17,11 @@ nv04_blend_state_create(struct pipe_context *pipe,
cb = MALLOC(sizeof(struct nv04_blend_state));
- cb->b_enable = cso->blend_enable ? 1 : 0;
- cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
- (nvgl_blend_func(cso->rgb_src_factor)));
- cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
- (nvgl_blend_func(cso->rgb_dst_factor)));
+ cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
+ cb->b_src = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_src_factor)));
+ cb->b_dst = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
return (void *)cb;
diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c
index 34847718145..2db61d89412 100644
--- a/src/gallium/drivers/nv04/nv04_vbo.c
+++ b/src/gallium/drivers/nv04/nv04_vbo.c
@@ -45,7 +45,7 @@ void nv04_draw_elements( struct pipe_context *pipe,
draw_set_mapped_element_buffer(draw, 0, NULL);
}
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
nv04->constbuf[PIPE_SHADER_VERTEX],
nv04->constbuf_nr[PIPE_SHADER_VERTEX]);
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index 69a6dab866a..4e6bc129943 100644
--- a/src/gallium/drivers/nv10/nv10_screen.c
+++ b/src/gallium/drivers/nv10/nv10_screen.c
@@ -40,6 +40,16 @@ nv10_screen_get_param(struct pipe_screen *screen, int param)
case NOUVEAU_CAP_HW_VTXBUF:
case NOUVEAU_CAP_HW_IDXBUF:
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;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c
index ad7def53b12..9aafc604116 100644
--- a/src/gallium/drivers/nv10/nv10_state.c
+++ b/src/gallium/drivers/nv10/nv10_state.c
@@ -17,16 +17,16 @@ nv10_blend_state_create(struct pipe_context *pipe,
cb = MALLOC(sizeof(struct nv10_blend_state));
- cb->b_enable = cso->blend_enable ? 1 : 0;
- cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
- (nvgl_blend_func(cso->rgb_src_factor)));
- cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
- (nvgl_blend_func(cso->rgb_dst_factor)));
-
- cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
- ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
- ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
- ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
+ cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
+ cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_src_factor)));
+ cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
+
+ cb->c_mask = (((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));
cb->d_enable = cso->dither ? 1 : 0;
diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c
index 9180c72c9b0..da5c93f0814 100644
--- a/src/gallium/drivers/nv10/nv10_vbo.c
+++ b/src/gallium/drivers/nv10/nv10_vbo.c
@@ -46,6 +46,7 @@ void nv10_draw_elements( struct pipe_context *pipe,
draw_set_mapped_constant_buffer(draw,
PIPE_SHADER_VERTEX,
+ 0,
nv10->constbuf[PIPE_SHADER_VERTEX],
nv10->constbuf_nr[PIPE_SHADER_VERTEX]);
diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c
index d091335063b..df9401bcce0 100644
--- a/src/gallium/drivers/nv20/nv20_screen.c
+++ b/src/gallium/drivers/nv20/nv20_screen.c
@@ -40,6 +40,16 @@ nv20_screen_get_param(struct pipe_screen *screen, int param)
case NOUVEAU_CAP_HW_VTXBUF:
case NOUVEAU_CAP_HW_IDXBUF:
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;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c
index 45697a60efd..83335c790a0 100644
--- a/src/gallium/drivers/nv20/nv20_state.c
+++ b/src/gallium/drivers/nv20/nv20_state.c
@@ -17,16 +17,16 @@ nv20_blend_state_create(struct pipe_context *pipe,
cb = MALLOC(sizeof(struct nv20_blend_state));
- cb->b_enable = cso->blend_enable ? 1 : 0;
- cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
- (nvgl_blend_func(cso->rgb_src_factor)));
- cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
- (nvgl_blend_func(cso->rgb_dst_factor)));
-
- cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
- ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
- ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
- ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));
+ cb->b_enable = cso->rt[0].blend_enable ? 1 : 0;
+ cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_src_factor)));
+ cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) |
+ (nvgl_blend_func(cso->rt[0].rgb_dst_factor)));
+
+ cb->c_mask = (((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));
cb->d_enable = cso->dither ? 1 : 0;
diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c
index 52991a0d856..6dc95389013 100644
--- a/src/gallium/drivers/nv20/nv20_vbo.c
+++ b/src/gallium/drivers/nv20/nv20_vbo.c
@@ -45,7 +45,7 @@ void nv20_draw_elements( struct pipe_context *pipe,
draw_set_mapped_element_buffer(draw, 0, NULL);
}
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
nv20->constbuf[PIPE_SHADER_VERTEX],
nv20->constbuf_nr[PIPE_SHADER_VERTEX]);
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 9ed48178dc2..ee83ec56760 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -67,6 +67,16 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param)
case NOUVEAU_CAP_HW_VTXBUF:
case NOUVEAU_CAP_HW_IDXBUF:
return 1;
+ 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;
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index 065c927a10d..1f4c9642705 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -16,27 +16,27 @@ nv30_blend_state_create(struct pipe_context *pipe,
struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso));
struct nouveau_stateobj *so = so_new(5, 8, 0);
- if (cso->blend_enable) {
+ 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->alpha_src_factor) << 16) |
- nvgl_blend_func(cso->rgb_src_factor));
- so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 |
- nvgl_blend_func(cso->rgb_dst_factor));
+ 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->rgb_func));
+ 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->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
- ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
- ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
- ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
+ 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);
diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c
index d826f8c2f5f..a2fd5f6c02f 100644
--- a/src/gallium/drivers/nv40/nv40_draw.c
+++ b/src/gallium/drivers/nv40/nv40_draw.c
@@ -271,7 +271,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe,
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,
+ draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX, 0,
map, nr);
}
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 9e55e5a089c..b1a7343b409 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -52,6 +52,16 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param)
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;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 7d990f7d567..7a63fba18c5 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -18,26 +18,26 @@ nv40_blend_state_create(struct pipe_context *pipe,
struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso));
struct nouveau_stateobj *so = so_new(5, 8, 0);
- if (cso->blend_enable) {
+ 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->alpha_src_factor) << 16) |
- nvgl_blend_func(cso->rgb_src_factor));
- so_data (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 |
- nvgl_blend_func(cso->rgb_dst_factor));
+ 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->alpha_func) << 16 |
- nvgl_blend_eqn(cso->rgb_func));
+ 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->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
- ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
- ((cso->colormask & PIPE_MASK_G) ? (0x01 << 8) : 0) |
- ((cso->colormask & PIPE_MASK_B) ? (0x01 << 0) : 0)));
+ 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);
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 22a8498c69b..5c705ccc8f1 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -34,6 +34,11 @@ nv50_flush(struct pipe_context *pipe, unsigned flags,
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_channel *chan = nv50->screen->base.channel;
+ if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
+ BEGIN_RING(chan, nv50->screen->tesla, 0x1338, 1);
+ OUT_RING (chan, 0x20);
+ }
+
if (flags & PIPE_FLUSH_FRAME)
FIRE_RING(chan);
}
@@ -81,6 +86,10 @@ nv50_destroy(struct pipe_context *pipe)
so_ref(NULL, &nv50->state.vtxattr);
draw_destroy(nv50->draw);
+
+ if (nv50->screen->cur_ctx == nv50)
+ nv50->screen->cur_ctx = NULL;
+
FREE(nv50);
}
@@ -104,7 +113,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv50->pipe.destroy = nv50_destroy;
nv50->pipe.draw_arrays = nv50_draw_arrays;
+ nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced;
nv50->pipe.draw_elements = nv50_draw_elements;
+ nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced;
nv50->pipe.clear = nv50_clear;
nv50->pipe.flush = nv50_flush;
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index d024be6ea95..bebcd95054f 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -29,9 +29,7 @@
#define NV50_CB_PVP 1
#define NV50_CB_PFP 2
#define NV50_CB_PGP 3
-#define NV50_CB_TIC 4
-#define NV50_CB_TSC 5
-#define NV50_CB_PUPLOAD 6
+#define NV50_CB_AUX 4
#define NV50_NEW_BLEND (1 << 0)
#define NV50_NEW_ZSA (1 << 1)
@@ -137,6 +135,7 @@ struct nv50_state {
struct nouveau_stateobj *vtxfmt;
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
+ struct nouveau_stateobj *instbuf;
unsigned vtxelt_nr;
};
@@ -198,11 +197,22 @@ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50);
/* nv50_vbo.c */
extern void nv50_draw_arrays(struct pipe_context *, unsigned mode,
unsigned start, unsigned count);
+extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode,
+ unsigned start, unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount);
extern void nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start,
unsigned count);
+extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start,
+ unsigned count,
+ unsigned startInstance,
+ unsigned instanceCount);
extern void nv50_vbo_validate(struct nv50_context *nv50);
/* nv50_clear.c */
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index acd695b39bc..e74a526c626 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -95,6 +95,8 @@ struct nv50_reg {
int vtx; /* vertex index, for GP inputs (TGSI Dimension.Index) */
int indirect[2]; /* index into pc->addr, or -1 */
+
+ ubyte buf_index; /* c{0 .. 15}[] or g{0 .. 15}[] */
};
#define NV50_MOD_NEG 1
@@ -188,6 +190,7 @@ ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw)
reg->vtx = -1;
reg->acc = 0;
reg->indirect[0] = reg->indirect[1] = -1;
+ reg->buf_index = (type == P_CONST) ? 1 : 0;
}
static INLINE unsigned
@@ -474,6 +477,12 @@ is_join(struct nv50_program_exec *e)
return FALSE;
}
+static INLINE boolean
+is_control_flow(struct nv50_program_exec *e)
+{
+ return (e->inst[0] & 2);
+}
+
static INLINE void
set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx,
struct nv50_program_exec *e)
@@ -631,7 +640,7 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s,
set_addr(e, pc->addr[src->indirect[0]]);
}
- e->inst[1] |= (((src->type == P_IMMD) ? 0 : 1) << 22);
+ e->inst[1] |= (src->buf_index << 22);
}
/* Never apply nv50_reg::mod in emit_mov, or carefully check the code !!! */
@@ -3163,7 +3172,9 @@ nv50_program_tx_insn(struct nv50_pc *pc,
if (!is_long(pc->p->exec_tail))
convert_to_long(pc, pc->p->exec_tail);
else
- if (is_immd(pc->p->exec_tail) || is_join(pc->p->exec_tail))
+ if (is_immd(pc->p->exec_tail) ||
+ is_join(pc->p->exec_tail) ||
+ is_control_flow(pc->p->exec_tail))
emit_nop(pc);
pc->p->exec_tail->inst[1] |= 1; /* set exit bit */
@@ -3272,7 +3283,7 @@ prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)
static unsigned
nv50_revdep_reorder(unsigned m[4], unsigned rdep[4])
{
- unsigned i, c, x, unsafe;
+ unsigned i, c, x, unsafe = 0;
for (c = 0; c < 4; c++)
m[c] = c;
@@ -3483,6 +3494,19 @@ load_frontfacing(struct nv50_pc *pc, struct nv50_reg *sv)
}
static void
+load_instance_id(struct nv50_pc *pc, unsigned index)
+{
+ struct nv50_reg reg, mem;
+
+ ctor_reg(&reg, P_TEMP, -1, -1);
+ ctor_reg(&mem, P_CONST, -1, 24); /* startInstance */
+ mem.buf_index = 2;
+
+ emit_add_b32(pc, &reg, &pc->sysval[index], &mem);
+ pc->sysval[index] = reg;
+}
+
+static void
copy_semantic_info(struct nv50_program *p)
{
unsigned i, id;
@@ -3668,8 +3692,10 @@ nv50_program_tx_prep(struct nv50_pc *pc)
}
if (p->cfg.regs[0] & (1 << 0))
pc->sysval[vertex_id].hw = rid++;
- if (p->cfg.regs[0] & (1 << 4))
+ if (p->cfg.regs[0] & (1 << 4)) {
pc->sysval[instance_id].hw = rid++;
+ load_instance_id(pc, instance_id);
+ }
}
for (i = 0, rid = 0; i < pc->result_nr; ++i) {
@@ -3702,13 +3728,21 @@ nv50_program_tx_prep(struct nv50_pc *pc)
copy_semantic_info(p);
} else
if (p->type == PIPE_SHADER_FRAGMENT) {
- int rid, aid, base;
+ int rid, aid;
unsigned n = 0, m = pc->attr_nr - flat_nr;
pc->allow32 = TRUE;
- base = (TGSI_SEMANTIC_POSITION ==
- p->info.input_semantic_name[0]) ? 0 : 1;
+ /* do we read FragCoord ? */
+ if (pc->attr_nr &&
+ p->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
+ /* select FCRD components we want accessible */
+ for (c = 0; c < 4; ++c)
+ if (pc->attr[c].acc)
+ p->cfg.regs[1] |= 1 << (24 + c);
+ aid = 0;
+ } else /* offset by 1 if FCRD.w is needed for pinterp */
+ aid = popcnt4(p->cfg.regs[1] >> 24);
/* non-flat interpolants have to be mapped to
* the lower hardware IDs, so sort them:
@@ -3724,12 +3758,6 @@ nv50_program_tx_prep(struct nv50_pc *pc)
}
copy_semantic_info(p);
- if (!base) /* set w-coordinate mask from perspective interp */
- p->cfg.in[0].mask |= p->cfg.regs[1] >> 24;
-
- aid = popcnt4( /* if fcrd isn't contained in cfg.io */
- base ? (p->cfg.regs[1] >> 24) : p->cfg.in[0].mask);
-
for (n = 0; n < pc->attr_nr; ++n) {
p->cfg.in[n].hw = rid = aid;
i = p->cfg.in[n].id;
@@ -3751,9 +3779,6 @@ nv50_program_tx_prep(struct nv50_pc *pc)
aid += popcnt4(p->cfg.in[n].mask);
}
- if (!base)
- p->cfg.regs[1] |= p->cfg.in[0].mask << 24;
-
m = popcnt4(p->cfg.regs[1] >> 24);
/* set count of non-position inputs and of non-flat
@@ -4641,6 +4666,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
nouveau_bo_ref(NULL, &p->bo);
+ FREE(p->immd);
nouveau_resource_free(&p->data[0]);
p->translated = 0;
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 5a4ab3508b8..9eba4c96115 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -48,7 +48,7 @@ nv50_query_create(struct pipe_context *pipe, unsigned type)
assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER);
q->type = type;
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 256,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 256,
16, &q->bo);
if (ret) {
FREE(q);
@@ -95,11 +95,13 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
MARK_RING (chan, 5, 2); /* flush on lack of space or relocs */
BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4);
- OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
OUT_RING (chan, 0x00000000);
OUT_RING (chan, 0x0100f002);
- FIRE_RING (chan);
+
+ BEGIN_RING(chan, tesla, NV50TCL_SAMPLECNT_ENABLE, 1);
+ OUT_RING (chan, 0);
}
static boolean
@@ -123,6 +125,35 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
return q->ready;
}
+static void
+nv50_render_condition(struct pipe_context *pipe,
+ struct pipe_query *pq, uint mode)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nv50_query *q;
+
+ if (!pq) {
+ BEGIN_RING(chan, tesla, NV50TCL_COND_MODE, 1);
+ OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS);
+ return;
+ }
+ q = nv50_query(pq);
+
+ if (mode == PIPE_RENDER_COND_WAIT ||
+ mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
+ /* XXX: big fence, FIFO semaphore might be better */
+ BEGIN_RING(chan, tesla, 0x0110, 1);
+ OUT_RING (chan, 0);
+ }
+
+ BEGIN_RING(chan, tesla, NV50TCL_COND_ADDRESS_HIGH, 3);
+ OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ OUT_RING (chan, NV50TCL_COND_MODE_RES);
+}
+
void
nv50_init_query_functions(struct nv50_context *nv50)
{
@@ -131,4 +162,5 @@ nv50_init_query_functions(struct nv50_context *nv50)
nv50->pipe.begin_query = nv50_query_begin;
nv50->pipe.end_query = nv50_query_end;
nv50->pipe.get_query_result = nv50_query_result;
+ nv50->pipe.render_condition = nv50_render_condition;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 73205652cc4..c4465a228ca 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -135,6 +135,16 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
return 1;
case NOUVEAU_CAP_HW_IDXBUF:
return 0;
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ return 1;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return 0;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
@@ -329,7 +339,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_ref(NULL, &so);
/* Static tesla init */
- so = so_new(44, 90, 22);
+ so = so_new(47, 95, 24);
so_method(so, screen->tesla, NV50TCL_COND_MODE, 1);
so_data (so, NV50TCL_COND_MODE_ALWAYS);
@@ -372,7 +382,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
}
for (i = 0; i < 3; i++) {
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (128 * 4) * 4,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4,
&screen->constbuf_parm[i]);
if (ret) {
nv50_screen_destroy(pscreen);
@@ -411,6 +421,18 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
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);
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index 7a155ca9c45..0d786b0f2e3 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -23,6 +23,8 @@ struct nv50_screen {
struct nouveau_resource *immd_heap[1];
struct nouveau_resource *parm_heap[PIPE_SHADER_TYPES];
+ struct pipe_buffer *strm_vbuf[16];
+
struct nouveau_bo *tic;
struct nouveau_bo *tsc;
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 6ab33be663d..da8dc933b03 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -31,6 +31,23 @@
#include "nouveau/nouveau_stateobj.h"
+static INLINE uint32_t
+nv50_colormask(unsigned mask)
+{
+ uint32_t cmask = 0;
+
+ if (mask & PIPE_MASK_R)
+ cmask |= 0x0001;
+ if (mask & PIPE_MASK_G)
+ cmask |= 0x0010;
+ if (mask & PIPE_MASK_B)
+ cmask |= 0x0100;
+ if (mask & PIPE_MASK_A)
+ cmask |= 0x1000;
+
+ return cmask;
+}
+
static void *
nv50_blend_state_create(struct pipe_context *pipe,
const struct pipe_blend_state *cso)
@@ -38,28 +55,37 @@ nv50_blend_state_create(struct pipe_context *pipe,
struct nouveau_stateobj *so = so_new(5, 24, 0);
struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj);
- unsigned cmask = 0, i;
+ unsigned i, blend_enabled = 0;
/*XXX ignored:
* - dither
*/
- if (cso->blend_enable == 0) {
- so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
+ so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
+ if (cso->independent_blend_enable) {
+ for (i = 0; i < 8; ++i) {
+ so_data(so, cso->rt[i].blend_enable);
+ if (cso->rt[i].blend_enable)
+ blend_enabled = 1;
+ }
+ } else
+ if (cso->rt[0].blend_enable) {
+ blend_enabled = 1;
for (i = 0; i < 8; i++)
- so_data(so, 0);
+ so_data(so, 1);
} else {
- so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
for (i = 0; i < 8; i++)
- so_data(so, 1);
+ so_data(so, 0);
+ }
+ if (blend_enabled) {
so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5);
- so_data (so, nvgl_blend_eqn(cso->rgb_func));
- so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_src_factor));
- so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_dst_factor));
- so_data (so, nvgl_blend_eqn(cso->alpha_func));
- so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_src_factor));
+ so_data (so, nvgl_blend_eqn(cso->rt[0].rgb_func));
+ so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_src_factor));
+ so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].rgb_dst_factor));
+ so_data (so, nvgl_blend_eqn(cso->rt[0].alpha_func));
+ so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_src_factor));
so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1);
- so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor));
+ so_data (so, 0x4000 | nvgl_blend_func(cso->rt[0].alpha_dst_factor));
}
if (cso->logicop_enable == 0 ) {
@@ -71,17 +97,15 @@ nv50_blend_state_create(struct pipe_context *pipe,
so_data (so, nvgl_logicop_func(cso->logicop_func));
}
- if (cso->colormask & PIPE_MASK_R)
- cmask |= (1 << 0);
- if (cso->colormask & PIPE_MASK_G)
- cmask |= (1 << 4);
- if (cso->colormask & PIPE_MASK_B)
- cmask |= (1 << 8);
- if (cso->colormask & PIPE_MASK_A)
- cmask |= (1 << 12);
so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8);
- for (i = 0; i < 8; i++)
- so_data(so, cmask);
+ if (cso->independent_blend_enable)
+ for (i = 0; i < 8; ++i)
+ so_data(so, nv50_colormask(cso->rt[i].colormask));
+ else {
+ uint32_t cmask = nv50_colormask(cso->rt[0].colormask);
+ for (i = 0; i < 8; i++)
+ so_data(so, cmask);
+ }
bso->pipe = *cso;
so_ref(so, &bso->so);
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index fcd07b59cd6..956da9b304c 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -274,6 +274,9 @@ nv50_state_flush_notify(struct nouveau_channel *chan)
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);
+
+ if (nv50->state.instbuf)
+ so_emit_reloc_markers(chan, nv50->state.instbuf);
}
boolean
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 871536dca9b..9f1a1713032 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -220,11 +220,8 @@ nv50_tex_validate(struct nv50_context *nv50)
return;
}
- /* not sure if the following really do what I think: */
so_method(so, tesla, 0x1330, 1); /* flush TIC */
so_data (so, 0);
- so_method(so, tesla, 0x1338, 1); /* flush texture caches */
- so_data (so, 0x20);
so_ref(so, &nv50->state.tic_upload);
so_ref(NULL, &so);
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 89a94d2fe81..bfb1b34d27a 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -40,6 +40,8 @@ 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)
{
@@ -160,6 +162,309 @@ 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 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;
+}
+
+static void
+step_per_instance_arrays_immd(struct nv50_context *nv50,
+ unsigned pos[16], unsigned step[16])
+{
+ struct nouveau_bo *bo;
+ unsigned i, b;
+
+ 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);
+
+ step[i] = 0;
+ pos[i] += nv50->vtxbuf[b].stride;
+
+ nv50_set_static_vtxattr(nv50, i, (uint8_t *)bo->map + pos[i]);
+ }
+}
+
+static void
+step_per_instance_arrays(struct nv50_context *nv50,
+ unsigned pos[16], unsigned step[16])
+{
+ 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);
+
+ for (i = 0; i < nv50->vtxelt_nr; ++i) {
+ if (!nv50->vtxelt[i].instance_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;
+ }
+
+ 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
+nv50_draw_arrays_instanced(struct pipe_context *pipe,
+ unsigned mode, unsigned start, unsigned count,
+ 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;
+ unsigned i, nz_divisors;
+ unsigned step[16], pos[16];
+
+ if (!NV50_USING_LOATHED_EDGEFLAG(nv50))
+ nv50_upload_user_vbufs(nv50);
+
+ nv50_state_validate(nv50);
+
+ nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+
+ 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));
+
+ 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);
+
+ 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);
+}
+
void
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
@@ -190,6 +495,8 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
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);
@@ -218,7 +525,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
unsigned nr = count > 2046 ? 2046 : count;
int i;
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1);
+ 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]);
@@ -251,7 +558,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
unsigned nr = count > 2046 ? 2046 : count;
int i;
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x40000000, nr >> 1);
+ 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]);
@@ -276,7 +583,7 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
while (count) {
unsigned nr = count > 2047 ? 2047 : count;
- BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x40000000, nr);
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VB_ELEMENT_U32, nr);
OUT_RINGp (chan, map, nr);
count -= nr;
@@ -285,6 +592,77 @@ nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
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;
+ }
+}
+
+void
+nv50_draw_elements_instanced(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count,
+ unsigned startInstance, unsigned instanceCount)
+{
+ struct nv50_context *nv50 = nv50_context(pipe);
+ 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];
+
+ 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);
+
+ nz_divisors = init_per_instance_arrays(nv50, startInstance, pos, step);
+
+ 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);
+
+ 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);
+
+ BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
+ OUT_RING (chan, 0);
+ }
+ nv50_unmap_vbufs(nv50);
+
+ so_ref(NULL, &nv50->state.instbuf);
+}
+
void
nv50_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer, unsigned indexSize,
@@ -295,7 +673,6 @@ nv50_draw_elements(struct pipe_context *pipe,
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct pipe_screen *pscreen = pipe->screen;
void *map;
- boolean ret;
map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
@@ -308,29 +685,15 @@ nv50_draw_elements(struct pipe_context *pipe,
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1);
OUT_RING (chan, nv50_prim(mode));
- switch (indexSize) {
- case 1:
- ret = nv50_draw_elements_inline_u08(nv50, map, start, count);
- break;
- case 2:
- ret = nv50_draw_elements_inline_u16(nv50, map, start, count);
- break;
- case 4:
- ret = nv50_draw_elements_inline_u32(nv50, map, start, count);
- break;
- default:
- assert(0);
- ret = FALSE;
- break;
- }
+
+ nv50_draw_elements_inline(nv50, map, indexSize, start, count);
+
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
+ nv50_unmap_vbufs(nv50);
+
pipe_buffer_unmap(pscreen, indexBuffer);
-
- /* XXX: what to do if ret != TRUE? Flush and retry?
- */
- assert(ret);
}
static INLINE boolean
@@ -343,23 +706,16 @@ nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
struct nouveau_stateobj *so;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
- float *v;
+ float v[4];
int ret;
- enum pipe_format pf = ve->src_format;
- const struct util_format_description *desc;
-
- desc = util_format_description(pf);
- assert(desc);
-
- if ((desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT) ||
- util_format_get_component_bits(pf, UTIL_FORMAT_COLORSPACE_RGB, 0) != 32)
- return FALSE;
ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
if (ret)
return FALSE;
- v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset));
+ util_format_read_4f(ve->src_format, v, 0, (uint8_t *)bo->map +
+ (vb->buffer_offset + ve->src_offset), 0,
+ 0, 0, 1, 1);
so = *pso;
if (!so)
*pso = so = so_new(nv50->vtxelt_nr, nv50->vtxelt_nr * 4, 0);
@@ -417,7 +773,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
!(nv50->vtxbuf[i].buffer->usage & PIPE_BUFFER_USAGE_VERTEX))
nv50->vbo_fifo = 0xffff;
- if (nv50->vertprog->cfg.edgeflag_in < 16)
+ 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);
@@ -445,17 +801,20 @@ nv50_vbo_validate(struct nv50_context *nv50)
nv50->vbo_fifo &= ~(1 << i);
continue;
}
- so_data(vtxfmt, hw | i);
if (nv50->vbo_fifo) {
+ 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);
- so_data (vtxbuf, 0x20000000 | vb->stride);
+ so_data (vtxbuf, 0x20000000 |
+ (ve->instance_divisor ? 0 : vb->stride));
so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
@@ -493,7 +852,7 @@ typedef void (*pfn_push)(struct nouveau_channel *, void *);
struct nv50_vbo_emitctx
{
pfn_push push[16];
- void *map[16];
+ uint8_t *map[16];
unsigned stride[16];
unsigned nr_ve;
unsigned vtx_dwords;
@@ -531,19 +890,18 @@ nv50_map_vbufs(struct nv50_context *nv50)
for (i = 0; i < nv50->vtxbuf_nr; ++i) {
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i];
- unsigned size, delta;
+ unsigned size = vb->stride * (vb->max_index + 1) + 16;
if (nouveau_bo(vb->buffer)->map)
continue;
- size = vb->stride * (vb->max_index + 1);
- delta = vb->buffer_offset;
-
+ size = vb->stride * (vb->max_index + 1) + 16;
+ size = MIN2(size, vb->buffer->size);
if (!size)
- size = vb->buffer->size - vb->buffer_offset;
+ size = vb->buffer->size;
if (nouveau_bo_map_range(nouveau_bo(vb->buffer),
- delta, size, NOUVEAU_BO_RD))
+ 0, size, NOUVEAU_BO_RD))
break;
}
@@ -554,16 +912,6 @@ nv50_map_vbufs(struct nv50_context *nv50)
return FALSE;
}
-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));
-}
-
static void
emit_b32_1(struct nouveau_channel *chan, void *data)
{
@@ -658,12 +1006,13 @@ emit_prepare(struct nv50_context *nv50, struct nv50_vbo_emitctx *emit,
ve = &nv50->vtxelt[i];
vb = &nv50->vtxbuf[ve->vertex_buffer_index];
- if (!(nv50->vbo_fifo & (1 << i)))
+ if (!(nv50->vbo_fifo & (1 << i)) || ve->instance_divisor)
continue;
n = emit->nr_ve++;
emit->stride[n] = vb->stride;
- emit->map[n] = nouveau_bo(vb->buffer)->map +
+ 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);
@@ -753,13 +1102,12 @@ nv50_push_arrays(struct nv50_context *nv50, unsigned start, unsigned count)
set_edgeflag(chan, tesla, &emit, 0); /* nr will be 1 */
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
for (i = 0; i < nr; ++i)
emit_vtx_next(chan, &emit);
count -= nr;
}
- nv50_unmap_vbufs(nv50);
return TRUE;
}
@@ -780,13 +1128,12 @@ nv50_push_elements_u32(struct nv50_context *nv50, uint32_t *map, unsigned count)
set_edgeflag(chan, tesla, &emit, *map);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
for (i = 0; i < nr; ++i)
emit_vtx(chan, &emit, *map++);
count -= nr;
}
- nv50_unmap_vbufs(nv50);
return TRUE;
}
@@ -807,13 +1154,12 @@ nv50_push_elements_u16(struct nv50_context *nv50, uint16_t *map, unsigned count)
set_edgeflag(chan, tesla, &emit, *map);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
for (i = 0; i < nr; ++i)
emit_vtx(chan, &emit, *map++);
count -= nr;
}
- nv50_unmap_vbufs(nv50);
return TRUE;
}
@@ -834,13 +1180,12 @@ nv50_push_elements_u08(struct nv50_context *nv50, uint8_t *map, unsigned count)
set_edgeflag(chan, tesla, &emit, *map);
- BEGIN_RING(chan, tesla, NV50TCL_VERTEX_DATA | 0x40000000, dw);
+ BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, dw);
for (i = 0; i < nr; ++i)
emit_vtx(chan, &emit, *map++);
count -= nr;
}
- nv50_unmap_vbufs(nv50);
return TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index c14414fff6b..cdedb302209 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -23,8 +23,6 @@
#include "r300_blit.h"
#include "r300_context.h"
-#include "util/u_rect.h"
-
static void r300_blitter_save_states(struct r300_context* r300)
{
util_blitter_save_blend(r300->blitter, r300->blend_state.state);
@@ -75,13 +73,15 @@ void r300_clear(struct pipe_context* pipe,
*/
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
r300_blitter_save_states(r300);
util_blitter_clear(r300->blitter,
- r300->framebuffer_state.width,
- r300->framebuffer_state.height,
- r300->framebuffer_state.nr_cbufs,
+ fb->width,
+ fb->height,
+ fb->nr_cbufs,
buffers, rgba, depth, stencil);
}
@@ -99,7 +99,7 @@ void r300_surface_copy(struct pipe_context* pipe,
* is really transparent. The states will be restored by the blitter once
* copying is done. */
r300_blitter_save_states(r300);
- util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+ util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_save_fragment_sampler_states(
r300->blitter, r300->sampler_count, (void**)r300->sampler_states);
@@ -123,7 +123,7 @@ void r300_surface_fill(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
r300_blitter_save_states(r300);
- util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+ util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
util_blitter_fill(r300->blitter,
dst, dstx, dsty, width, height, value);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 5e4f6552c36..9837530a7ac 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -22,9 +22,6 @@
#include "draw/draw_context.h"
-#include "tgsi/tgsi_scan.h"
-
-#include "util/u_hash_table.h"
#include "util/u_memory.h"
#include "util/u_simple_list.h"
@@ -35,30 +32,16 @@
#include "r300_query.h"
#include "r300_render.h"
#include "r300_screen.h"
-#include "r300_state_derived.h"
#include "r300_state_invariant.h"
#include "r300_texture.h"
#include "r300_winsys.h"
-static enum pipe_error r300_clear_hash_table(void* key, void* value,
- void* data)
-{
- FREE(key);
- FREE(value);
- return PIPE_OK;
-}
-
static void r300_destroy_context(struct pipe_context* context)
{
struct r300_context* r300 = r300_context(context);
struct r300_query* query, * temp;
util_blitter_destroy(r300->blitter);
-
- util_hash_table_foreach(r300->shader_hash_table, r300_clear_hash_table,
- NULL);
- util_hash_table_destroy(r300->shader_hash_table);
-
draw_destroy(r300->draw);
/* Free the OQ BO. */
@@ -72,9 +55,9 @@ static void r300_destroy_context(struct pipe_context* context)
FREE(r300->blend_color_state.state);
FREE(r300->clip_state.state);
- FREE(r300->rs_block);
+ FREE(r300->rs_block_state.state);
FREE(r300->scissor_state.state);
- FREE(r300->vertex_info);
+ FREE(r300->vertex_format_state.state);
FREE(r300->viewport_state.state);
FREE(r300->ztop_state.state);
FREE(r300);
@@ -87,7 +70,7 @@ r300_is_texture_referenced(struct pipe_context *pipe,
{
struct pipe_buffer* buf = 0;
- r300_get_texture_buffer(texture, &buf, NULL);
+ r300_get_texture_buffer(pipe->screen, texture, &buf, NULL);
return pipe->is_buffer_referenced(pipe, buf);
}
@@ -129,14 +112,18 @@ static void r300_setup_atoms(struct r300_context* r300)
* an upper bound on each atom, to keep the emission machinery from
* underallocating space. */
make_empty_list(&r300->atom_list);
+ R300_INIT_ATOM(invariant, 71);
R300_INIT_ATOM(ztop, 2);
R300_INIT_ATOM(blend, 8);
R300_INIT_ATOM(blend_color, 3);
R300_INIT_ATOM(clip, 29);
R300_INIT_ATOM(dsa, 8);
- R300_INIT_ATOM(rs, 22);
+ R300_INIT_ATOM(fb, 56);
+ R300_INIT_ATOM(rs, 25);
R300_INIT_ATOM(scissor, 3);
R300_INIT_ATOM(viewport, 9);
+ R300_INIT_ATOM(rs_block, 21);
+ R300_INIT_ATOM(vertex_format, 26);
}
struct pipe_context* r300_create_context(struct pipe_screen* screen,
@@ -153,8 +140,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.winsys = (struct pipe_winsys*)radeon_winsys;
r300->context.screen = screen;
- r300_init_debug(r300);
-
r300->context.destroy = r300_destroy_context;
r300->context.clear = r300_clear;
@@ -184,16 +169,13 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.is_texture_referenced = r300_is_texture_referenced;
r300->context.is_buffer_referenced = r300_is_buffer_referenced;
- r300->shader_hash_table = util_hash_table_create(r300_shader_key_hash,
- r300_shader_key_compare);
-
r300_setup_atoms(r300);
r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
r300->clip_state.state = CALLOC_STRUCT(pipe_clip_state);
- r300->rs_block = CALLOC_STRUCT(r300_rs_block);
+ r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
- r300->vertex_info = CALLOC_STRUCT(r300_vertex_info);
+ r300->vertex_format_state.state = CALLOC_STRUCT(r300_vertex_info);
r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
@@ -210,7 +192,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300_init_state_functions(r300);
- r300_emit_invariant_state(r300);
+ r300->invariant_state.dirty = TRUE;
r300->winsys->set_flush_cb(r300->winsys, r300_flush_cb, r300);
r300->dirty_state = R300_NEW_KITCHEN_SINK;
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 682b9179c83..3f461640a03 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -30,6 +30,8 @@
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
+#include "r300_screen.h"
+
struct r300_context;
struct r300_fragment_shader;
@@ -82,13 +84,14 @@ struct r300_rs_state {
struct pipe_rasterizer_state rs;
uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */
+ uint32_t antialiasing_config; /* R300_GB_AA_CONFIG: 0x4020 */
uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */
uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */
uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */
- uint32_t depth_scale_front; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */
- uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */
- uint32_t depth_scale_back; /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */
- uint32_t depth_offset_back; /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */
+ float depth_scale; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */
+ /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */
+ float depth_offset; /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */
+ /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */
uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */
uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */
uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */
@@ -136,15 +139,12 @@ struct r300_ztop_state {
uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */
};
-#define R300_NEW_FRAMEBUFFERS 0x00000010
#define R300_NEW_FRAGMENT_SHADER 0x00000020
#define R300_NEW_FRAGMENT_SHADER_CONSTANTS 0x00000040
-#define R300_NEW_RS_BLOCK 0x00000100
#define R300_NEW_SAMPLER 0x00000200
#define R300_ANY_NEW_SAMPLERS 0x0001fe00
#define R300_NEW_TEXTURE 0x00040000
#define R300_ANY_NEW_TEXTURES 0x03fc0000
-#define R300_NEW_VERTEX_FORMAT 0x04000000
#define R300_NEW_VERTEX_SHADER 0x08000000
#define R300_NEW_VERTEX_SHADER_CONSTANTS 0x10000000
#define R300_NEW_QUERY 0x40000000
@@ -269,11 +269,8 @@ struct r300_context {
struct r300_query *query_current;
struct r300_query query_list;
- /* Shader hash table. Used to store vertex formatting information, which
- * depends on the combination of both currently loaded shaders. */
- struct util_hash_table* shader_hash_table;
/* Vertex formatting information. */
- struct r300_vertex_info* vertex_info;
+ struct r300_atom vertex_format_state;
/* Various CSO state objects. */
/* Beginning of atom list. */
@@ -290,12 +287,12 @@ struct r300_context {
struct r300_atom dsa_state;
/* Fragment shader. */
struct r300_fragment_shader* fs;
- /* Framebuffer state. We currently don't need our own version of this. */
- struct pipe_framebuffer_state framebuffer_state;
+ /* Framebuffer state. */
+ struct r300_atom fb_state;
/* Rasterizer state. */
struct r300_atom rs_state;
/* RS block state. */
- struct r300_rs_block* rs_block;
+ struct r300_atom rs_block_state;
/* Sampler states. */
struct r300_sampler_state* sampler_states[8];
int sampler_count;
@@ -311,6 +308,9 @@ struct r300_context {
/* ZTOP state. */
struct r300_atom ztop_state;
+ /* Invariant state. This must be emitted to get the engine started. */
+ struct r300_atom invariant_state;
+
/* Vertex buffers for Gallium. */
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
int vertex_buffer_count;
@@ -324,9 +324,10 @@ struct r300_context {
uint32_t dirty_hw;
/* Whether the TCL engine should be in bypass mode. */
boolean tcl_bypass;
-
- /** Combination of DBG_xxx flags */
- unsigned debug;
+ /* Whether polygon offset is enabled. */
+ boolean polygon_offset_enabled;
+ /* Z buffer bit depth. */
+ uint32_t zbuffer_bpp;
};
/* Convenience cast wrapper. */
@@ -340,35 +341,15 @@ 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);
-/* Debug functionality. */
-
-/**
- * Debug flags to disable/enable certain groups of debugging outputs.
- *
- * \note These may be rather coarse, and the grouping may be impractical.
- * If you find, while debugging the driver, that a different grouping
- * of these flags would be beneficial, just feel free to change them
- * but make sure to update the documentation in r300_debug.c to reflect
- * those changes.
- */
-/*@{*/
-#define DBG_HELP 0x0000001
-#define DBG_FP 0x0000002
-#define DBG_VP 0x0000004
-#define DBG_CS 0x0000008
-#define DBG_DRAW 0x0000010
-#define DBG_TEX 0x0000020
-#define DBG_FALL 0x0000040
-/*@}*/
-
-static INLINE boolean DBG_ON(struct r300_context * ctx, unsigned flags)
+static INLINE boolean CTX_DBG_ON(struct r300_context * ctx, unsigned flags)
{
- return (ctx->debug & flags) ? TRUE : FALSE;
+ return SCREEN_DBG_ON(r300_screen(ctx->context.screen), flags);
}
-static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * fmt, ...)
+static INLINE void CTX_DBG(struct r300_context * ctx, unsigned flags,
+ const char * fmt, ...)
{
- if (DBG_ON(ctx, flags)) {
+ if (CTX_DBG_ON(ctx, flags)) {
va_list va;
va_start(va, fmt);
debug_vprintf(fmt, va);
@@ -376,6 +357,8 @@ static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * f
}
}
-void r300_init_debug(struct r300_context * ctx);
+#define DBG_ON CTX_DBG_ON
+#define DBG CTX_DBG
#endif /* R300_CONTEXT_H */
+
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index 2a6ed54ac9b..b881730848a 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -22,8 +22,6 @@
#include "r300_context.h"
-#include <ctype.h>
-
struct debug_option {
const char * name;
@@ -46,7 +44,7 @@ static struct debug_option debug_options[] = {
{ 0, 0, 0 }
};
-void r300_init_debug(struct r300_context * ctx)
+void r300_init_debug(struct r300_screen * screen)
{
const char * options = debug_get_option("RADEON_DEBUG", 0);
boolean printhint = FALSE;
@@ -64,7 +62,7 @@ void r300_init_debug(struct r300_context * ctx)
for(opt = debug_options; opt->name; ++opt) {
if (!strncmp(options, opt->name, length)) {
- ctx->debug |= opt->flag;
+ screen->debug |= opt->flag;
break;
}
}
@@ -77,11 +75,11 @@ void r300_init_debug(struct r300_context * ctx)
options += length;
}
- if (!ctx->debug)
+ if (!screen->debug)
printhint = TRUE;
}
- if (printhint || ctx->debug & DBG_HELP) {
+ 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");
for(opt = debug_options; opt->name; ++opt) {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 9f93327e598..a429457625a 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -32,20 +32,20 @@
#include "r300_emit.h"
#include "r300_fs.h"
#include "r300_screen.h"
-#include "r300_state_derived.h"
#include "r300_state_inlines.h"
-#include "r300_texture.h"
#include "r300_vs.h"
void r300_emit_blend_state(struct r300_context* r300, void* state)
{
struct r300_blend_state* blend = (struct r300_blend_state*)state;
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
CS_LOCALS(r300);
BEGIN_CS(8);
OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
- if (r300->framebuffer_state.nr_cbufs) {
+ if (fb->nr_cbufs) {
OUT_CS(blend->blend_control);
OUT_CS(blend->alpha_blend_control);
OUT_CS(blend->color_channel_mask);
@@ -112,6 +112,8 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state)
{
struct r300_dsa_state* dsa = (struct r300_dsa_state*)state;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
CS_LOCALS(r300);
BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6);
@@ -124,7 +126,7 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state)
OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
- if (r300->framebuffer_state.zsbuf) {
+ if (fb->zsbuf) {
OUT_CS(dsa->z_buffer_control);
OUT_CS(dsa->z_stencil_control);
} else {
@@ -168,9 +170,8 @@ static const float * get_shader_constant(
vec[1] = 1.0 / tex->height0;
break;
- /* Texture compare-fail value. */
- /* XXX Since Gallium doesn't support GL_ARB_shadow_ambient,
- * this is always (0,0,0,0), right? */
+ /* Texture compare-fail value. Shouldn't ever show up, but if
+ * it does, we'll be ready. */
case RC_STATE_SHADOW_AMBIENT:
vec[3] = 0;
break;
@@ -384,17 +385,14 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
END_CS;
}
-void r300_emit_fb_state(struct r300_context* r300,
- struct pipe_framebuffer_state* fb)
+void r300_emit_fb_state(struct r300_context* r300, void* state)
{
+ struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
struct r300_texture* tex;
struct pipe_surface* surf;
int i;
CS_LOCALS(r300);
- /* Shouldn't fail unless there is a bug in the state tracker. */
- assert(fb->nr_cbufs <= 4);
-
BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) +
(fb->zsbuf ? 10 : 0) + 6);
@@ -407,7 +405,14 @@ void r300_emit_fb_state(struct r300_context* r300,
R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
/* Set the number of colorbuffers. */
- OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs));
+ if (fb->nr_cbufs > 1) {
+ OUT_CS_REG(R300_RB3D_CCTL,
+ R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) |
+ R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE |
+ R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE);
+ } else {
+ OUT_CS_REG(R300_RB3D_CCTL, 0x0);
+ }
/* Set up colorbuffers. */
for (i = 0; i < fb->nr_cbufs; i++) {
@@ -584,19 +589,40 @@ void r300_emit_query_end(struct r300_context* r300)
void r300_emit_rs_state(struct r300_context* r300, void* state)
{
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ float scale, offset;
CS_LOCALS(r300);
- BEGIN_CS(22);
+ BEGIN_CS(20 + (rs->polygon_offset_enable ? 5 : 0));
OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
+
+ OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config);
+
OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
OUT_CS(rs->point_minmax);
OUT_CS(rs->line_control);
- OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6);
- OUT_CS(rs->depth_scale_front);
- OUT_CS(rs->depth_offset_front);
- OUT_CS(rs->depth_scale_back);
- OUT_CS(rs->depth_offset_back);
+
+ if (rs->polygon_offset_enable) {
+ scale = rs->depth_scale * 12;
+ offset = rs->depth_offset;
+
+ switch (r300->zbuffer_bpp) {
+ case 16:
+ offset *= 4;
+ break;
+ case 24:
+ offset *= 2;
+ break;
+ }
+
+ OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);
+ OUT_CS_32F(scale);
+ OUT_CS_32F(offset);
+ OUT_CS_32F(scale);
+ OUT_CS_32F(offset);
+ }
+
+ OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2);
OUT_CS(rs->polygon_offset_enable);
OUT_CS(rs->cull_mode);
OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
@@ -606,10 +632,10 @@ void r300_emit_rs_state(struct r300_context* r300, void* state)
END_CS;
}
-void r300_emit_rs_block_state(struct r300_context* r300,
- struct r300_rs_block* rs)
+void r300_emit_rs_block_state(struct r300_context* r300, void* state)
{
- int i;
+ struct r300_rs_block* rs = (struct r300_rs_block*)state;
+ unsigned i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
CS_LOCALS(r300);
@@ -652,11 +678,13 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state)
uint32_t top_left, bottom_right;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state;
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
CS_LOCALS(r300);
minx = miny = 0;
- maxx = r300->framebuffer_state.width;
- maxy = r300->framebuffer_state.height;
+ maxx = fb->width;
+ maxy = fb->height;
if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
minx = MAX2(minx, scissor->minx);
@@ -665,6 +693,22 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state)
maxy = MIN2(maxy, scissor->maxy);
}
+ /* Special case for zero-area scissor.
+ *
+ * We can't allow the variables maxx and maxy to be zero because they are
+ * subtracted from later in the code, which would cause emitting ~0 and
+ * making the kernel checker angry.
+ *
+ * Let's consider we change maxx and maxy to 1, which is effectively
+ * a one-pixel area. We must then change minx and miny to a number which is
+ * greater than 1 to get the zero area back. */
+ if (!maxx || !maxy) {
+ minx = 2;
+ miny = 2;
+ maxx = 1;
+ maxy = 1;
+ }
+
if (r300screen->caps->is_r500) {
top_left =
(minx << R300_SCISSORS_X_SHIFT) |
@@ -705,12 +749,18 @@ void r300_emit_texture(struct r300_context* r300,
filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
}
- /* 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);
- format0 |= R300_TX_NUM_LEVELS(max_level);
- filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+ if (tex->is_npot) {
+ /* NPOT textures don't support mip filter, unfortunately.
+ * This prevents incorrect rendering. */
+ filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
+ } 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);
+ format0 |= R300_TX_NUM_LEVELS(max_level);
+ filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+ }
BEGIN_CS(16);
OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 |
@@ -729,22 +779,6 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
-static boolean r300_validate_aos(struct r300_context *r300)
-{
- struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
- struct pipe_vertex_element *velem = r300->vertex_element;
- 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;
- }
- }
- return TRUE;
-}
-
void r300_emit_aos(struct r300_context* r300, unsigned offset)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
@@ -754,12 +788,6 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
unsigned packet_size = (aos_count * 3 + 1) / 2;
CS_LOCALS(r300);
- /* XXX Move this checking to a more approriate place. */
- if (!r300_validate_aos(r300)) {
- /* XXX We should fallback using Draw. */
- assert(0);
- }
-
BEGIN_CS(2 + packet_size + aos_count * 2);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);
OUT_CS(aos_count);
@@ -791,38 +819,39 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
END_CS;
}
-void r300_emit_vertex_format_state(struct r300_context* r300)
+void r300_emit_vertex_format_state(struct r300_context* r300, void* state)
{
- int i;
+ struct r300_vertex_info* vertex_info = (struct r300_vertex_info*)state;
+ unsigned i;
CS_LOCALS(r300);
DBG(r300, DBG_DRAW, "r300: VAP/PSC emit:\n");
BEGIN_CS(26);
- OUT_CS_REG(R300_VAP_VTX_SIZE, r300->vertex_info->vinfo.size);
+ OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_info->vinfo.size);
OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
- OUT_CS(r300->vertex_info->vinfo.hwfmt[0]);
- OUT_CS(r300->vertex_info->vinfo.hwfmt[1]);
+ OUT_CS(vertex_info->vinfo.hwfmt[0]);
+ OUT_CS(vertex_info->vinfo.hwfmt[1]);
OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
- OUT_CS(r300->vertex_info->vinfo.hwfmt[2]);
- OUT_CS(r300->vertex_info->vinfo.hwfmt[3]);
+ OUT_CS(vertex_info->vinfo.hwfmt[2]);
+ OUT_CS(vertex_info->vinfo.hwfmt[3]);
for (i = 0; i < 4; i++) {
DBG(r300, DBG_DRAW, " : hwfmt%d: 0x%08x\n", i,
- r300->vertex_info->vinfo.hwfmt[i]);
+ vertex_info->vinfo.hwfmt[i]);
}
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
for (i = 0; i < 8; i++) {
- OUT_CS(r300->vertex_info->vap_prog_stream_cntl[i]);
+ OUT_CS(vertex_info->vap_prog_stream_cntl[i]);
DBG(r300, DBG_DRAW, " : prog_stream_cntl%d: 0x%08x\n", i,
- r300->vertex_info->vap_prog_stream_cntl[i]);
+ vertex_info->vap_prog_stream_cntl[i]);
}
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
for (i = 0; i < 8; i++) {
- OUT_CS(r300->vertex_info->vap_prog_stream_cntl_ext[i]);
+ OUT_CS(vertex_info->vap_prog_stream_cntl_ext[i]);
DBG(r300, DBG_DRAW, " : prog_stream_cntl_ext%d: 0x%08x\n", i,
- r300->vertex_info->vap_prog_stream_cntl_ext[i]);
+ vertex_info->vap_prog_stream_cntl_ext[i]);
}
END_CS;
}
@@ -987,39 +1016,21 @@ static void r300_flush_pvs(struct r300_context* r300)
END_CS;
}
-/* Emit all dirty state. */
-void r300_emit_dirty_state(struct r300_context* r300)
+void r300_emit_buffer_validate(struct r300_context *r300)
{
- struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct pipe_framebuffer_state* fb =
+ (struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_texture* tex;
- struct r300_atom* atom;
- unsigned i, dwords = 1024;
- int dirty_tex = 0;
+ unsigned i;
boolean invalid = FALSE;
- /* Check the required number of dwords against the space remaining in the
- * current CS object. If we need more, then flush. */
-
- foreach(atom, &r300->atom_list) {
- if (atom->dirty || atom->always_dirty) {
- dwords += atom->size;
- }
- }
-
- /* Make sure we have at least 2*1024 spare dwords. */
- /* XXX It would be nice to know the number of dwords we really need to
- * XXX emit. */
- if (!r300->winsys->check_cs(r300->winsys, dwords)) {
- r300->context.flush(&r300->context, 0, NULL);
- }
-
/* Clean out BOs. */
r300->winsys->reset_bos(r300->winsys);
validate:
/* Color buffers... */
- for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
- tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture;
+ 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)) {
@@ -1028,8 +1039,8 @@ validate:
}
}
/* ...depth buffer... */
- if (r300->framebuffer_state.zsbuf) {
- tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture;
+ 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)) {
@@ -1076,6 +1087,31 @@ validate:
invalid = TRUE;
goto validate;
}
+}
+
+/* Emit all dirty state. */
+void r300_emit_dirty_state(struct r300_context* r300)
+{
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct r300_atom* atom;
+ unsigned i, dwords = 1024;
+ int dirty_tex = 0;
+
+ /* Check the required number of dwords against the space remaining in the
+ * current CS object. If we need more, then flush. */
+
+ foreach(atom, &r300->atom_list) {
+ if (atom->dirty || atom->always_dirty) {
+ dwords += atom->size;
+ }
+ }
+
+ /* Make sure we have at least 2*1024 spare dwords. */
+ /* XXX It would be nice to know the number of dwords we really need to
+ * XXX emit. */
+ while (!r300->winsys->check_cs(r300->winsys, dwords)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ }
if (r300->dirty_state & R300_NEW_QUERY) {
r300_emit_query_start(r300);
@@ -1110,16 +1146,6 @@ validate:
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
- if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {
- r300_emit_fb_state(r300, &r300->framebuffer_state);
- r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
- }
-
- if (r300->dirty_state & R300_NEW_RS_BLOCK) {
- r300_emit_rs_block_state(r300, r300->rs_block);
- r300->dirty_state &= ~R300_NEW_RS_BLOCK;
- }
-
/* Samplers and textures are tracked separately but emitted together. */
if (r300->dirty_state &
(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) {
@@ -1145,11 +1171,6 @@ validate:
r300_flush_textures(r300);
}
- if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) {
- r300_emit_vertex_format_state(r300);
- r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;
- }
-
if (r300->dirty_state & (R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS)) {
r300_flush_pvs(r300);
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 05a6bfeae86..6b96d9b57c0 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -51,8 +51,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
void r500_emit_fs_constant_buffer(struct r300_context* r300,
struct rc_constant_list* constants);
-void r300_emit_fb_state(struct r300_context* r300,
- struct pipe_framebuffer_state* fb);
+void r300_emit_fb_state(struct r300_context* r300, void* state);
void r300_emit_query_begin(struct r300_context* r300,
struct r300_query* query);
@@ -61,8 +60,7 @@ void r300_emit_query_end(struct r300_context* r300);
void r300_emit_rs_state(struct r300_context* r300, void* state);
-void r300_emit_rs_block_state(struct r300_context* r300,
- struct r300_rs_block* rs);
+void r300_emit_rs_block_state(struct r300_context* r300, void* state);
void r300_emit_scissor_state(struct r300_context* r300, void* state);
@@ -73,7 +71,7 @@ void r300_emit_texture(struct r300_context* r300,
void r300_emit_vertex_buffer(struct r300_context* r300);
-void r300_emit_vertex_format_state(struct r300_context* r300);
+void r300_emit_vertex_format_state(struct r300_context* r300, void* state);
void r300_emit_vertex_program_code(struct r300_context* r300,
struct r300_vertex_program_code* code);
@@ -95,4 +93,6 @@ void r300_flush_textures(struct r300_context* r300);
/* Emit all dirty state. */
void r300_emit_dirty_state(struct r300_context* r300);
+void r300_emit_buffer_validate(struct r300_context *r300);
+
#endif /* R300_EMIT_H */
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 59819cb1061..e37d3092703 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -29,7 +29,6 @@
#include "r300_cs.h"
#include "r300_emit.h"
#include "r300_flush.h"
-#include "r300_state_invariant.h"
static void r300_flush(struct pipe_context* pipe,
unsigned flags,
@@ -53,7 +52,6 @@ static void r300_flush(struct pipe_context* pipe,
if (r300->dirty_hw) {
FLUSH_CS;
- r300_emit_invariant_state(r300);
r300->dirty_state = R300_NEW_KITCHEN_SINK;
r300->dirty_hw = 0;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 710d850163f..95b7cb5fa49 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -26,10 +26,9 @@
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
-#include "indices/u_indices.h"
-
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_prim.h"
@@ -116,20 +115,60 @@ static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
return color_control;
}
-static void r300_emit_draw_immediate(struct r300_context *r300,
- unsigned mode,
- unsigned start,
- unsigned count)
+static boolean immd_is_good_idea(struct r300_context *r300,
+ unsigned count)
{
- struct pipe_buffer* vbo = r300->vertex_buffer[0].buffer;
- unsigned vertex_size = r300->vertex_buffer[0].stride / sizeof(float);
- unsigned i;
- uint32_t* map;
+ return count <= 4;
+}
+
+static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
+ unsigned mode,
+ unsigned start,
+ unsigned count)
+{
+ struct pipe_vertex_element* velem;
+ struct pipe_vertex_buffer* vbuf;
+ unsigned vertex_element_count = r300->vertex_element_count;
+ unsigned i, v, vbi, dw, elem_offset;
+
+ /* Size of the vertex, in dwords. */
+ unsigned vertex_size = 0;
+
+ /* Offsets of the attribute, in dwords, from the start of the vertex. */
+ unsigned offset[PIPE_MAX_ATTRIBS];
+
+ /* Size of the vertex element, in dwords. */
+ unsigned size[PIPE_MAX_ATTRIBS];
+
+ /* Stride to the same attrib in the next vertex in the vertex buffer,
+ * in dwords. */
+ unsigned stride[PIPE_MAX_ATTRIBS];
+
+ /* Mapped vertex buffers. */
+ uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
+
CS_LOCALS(r300);
- map = (uint32_t*)pipe_buffer_map_range(r300->context.screen, vbo,
- start * vertex_size, count * vertex_size,
- PIPE_BUFFER_USAGE_CPU_READ);
+ /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
+ for (i = 0; i < vertex_element_count; i++) {
+ velem = &r300->vertex_element[i];
+ offset[i] = velem->src_offset / 4;
+ size[i] = util_format_get_blocksize(velem->src_format) / 4;
+ vertex_size += size[i];
+ vbi = velem->vertex_buffer_index;
+
+ /* Map the buffer. */
+ if (!map[vbi]) {
+ vbuf = &r300->vertex_buffer[vbi];
+ map[vbi] = (uint32_t*)pipe_buffer_map(r300->context.screen,
+ vbuf->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ map[vbi] += vbuf->buffer_offset / 4;
+ stride[vbi] = vbuf->stride / 4;
+ }
+ }
+
+ r300_emit_dirty_state(r300);
BEGIN_CS(10 + count * vertex_size);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
@@ -140,18 +179,31 @@ static void r300_emit_draw_immediate(struct r300_context *r300,
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));
- //debug_printf("r300: Immd %d verts, %d attrs\n", count, vertex_size);
- for (i = 0; i < count * vertex_size; i++) {
- if (i % vertex_size == 0) {
- //debug_printf("r300: -- vert --\n");
+
+ /* Emit vertices. */
+ for (v = 0; v < count; v++) {
+ for (i = 0; i < vertex_element_count; i++) {
+ velem = &r300->vertex_element[i];
+ vbi = velem->vertex_buffer_index;
+ elem_offset = offset[i] + stride[vbi] * (v + start);
+
+ for (dw = 0; dw < size[i]; dw++) {
+ OUT_CS(map[vbi][elem_offset + dw]);
+ }
}
- //debug_printf("r300: 0x%08x\n", *map);
- OUT_CS(*map);
- map++;
}
END_CS;
- pipe_buffer_unmap(r300->context.screen, vbo);
+ /* Unmap buffers. */
+ for (i = 0; i < vertex_element_count; i++) {
+ vbi = r300->vertex_element[i].vertex_buffer_index;
+
+ if (map[vbi]) {
+ vbuf = &r300->vertex_buffer[vbi];
+ pipe_buffer_unmap(r300->context.screen, vbuf->buffer);
+ map[vbi] = NULL;
+ }
+ }
}
static void r300_emit_draw_arrays(struct r300_context *r300,
@@ -223,17 +275,18 @@ static void r300_emit_draw_elements(struct r300_context *r300,
END_CS;
}
-
static boolean r300_setup_vertex_buffers(struct r300_context *r300)
{
struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->vertex_element;
+ struct pipe_buffer *pbuf;
validate:
for (int i = 0; i < r300->vertex_element_count; i++) {
- if (!r300->winsys->add_buffer(r300->winsys,
- vbuf[velem[i].vertex_buffer_index].buffer,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ 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);
goto validate;
}
@@ -247,40 +300,35 @@ validate:
return TRUE;
}
-static struct pipe_buffer* r300_translate_elts(struct r300_context* r300,
- struct pipe_buffer* elts,
- unsigned* size,
- unsigned* mode,
- unsigned* count)
+static void r300_shorten_ubyte_elts(struct r300_context* r300,
+ struct pipe_buffer** elts,
+ unsigned count)
{
struct pipe_screen* screen = r300->context.screen;
struct pipe_buffer* new_elts;
- void *in_map, *out_map;
- unsigned out_prim, out_index_size, out_nr;
- u_translate_func out_translate;
-
- (void)u_index_translator(~0, *mode, *size, *count, PV_LAST, PV_LAST,
- &out_prim, &out_index_size, &out_nr, &out_translate);
+ unsigned char *in_map;
+ unsigned short *out_map;
+ unsigned i;
new_elts = screen->buffer_create(screen, 32,
PIPE_BUFFER_USAGE_INDEX |
PIPE_BUFFER_USAGE_CPU_WRITE |
PIPE_BUFFER_USAGE_GPU_READ,
- out_index_size * out_nr);
+ 2 * count);
- in_map = pipe_buffer_map(screen, elts, PIPE_BUFFER_USAGE_CPU_READ);
+ 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);
- out_translate(in_map, *count, out_map);
+ for (i = 0; i < count; i++) {
+ *out_map = (unsigned short)*in_map;
+ in_map++;
+ out_map++;
+ }
- pipe_buffer_unmap(screen, elts);
+ pipe_buffer_unmap(screen, *elts);
pipe_buffer_unmap(screen, new_elts);
- *size = out_index_size;
- *mode = out_prim;
- *count = out_nr;
-
- return new_elts;
+ *elts = new_elts;
}
/* This is the fast-path drawing & emission for HW TCL. */
@@ -309,13 +357,15 @@ void r300_draw_range_elements(struct pipe_context* pipe,
r300_update_derived_state(r300);
+ r300_emit_buffer_validate(r300);
+
if (!r300_setup_vertex_buffers(r300)) {
return;
}
if (indexSize == 1) {
- indexBuffer = r300_translate_elts(r300, indexBuffer,
- &indexSize, &mode, &count);
+ r300_shorten_ubyte_elts(r300, &indexBuffer, count);
+ indexSize = 2;
}
if (!r300->winsys->add_buffer(r300->winsys, indexBuffer,
@@ -368,15 +418,16 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
r300_update_derived_state(r300);
- if (!r300_setup_vertex_buffers(r300)) {
- return;
- }
-
- r300_emit_dirty_state(r300);
+ r300_emit_buffer_validate(r300);
- if (FALSE && count <= 4 && r300->vertex_buffer_count == 1) {
- r300_emit_draw_immediate(r300, mode, start, count);
+ if (immd_is_good_idea(r300, count)) {
+ r300_emit_draw_arrays_immediate(r300, mode, start, count);
} else {
+ if (!r300_setup_vertex_buffers(r300)) {
+ return;
+ }
+
+ r300_emit_dirty_state(r300);
r300_emit_aos(r300, start);
r300_emit_draw_arrays(r300, mode, count);
}
@@ -411,6 +462,7 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
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));
@@ -455,6 +507,7 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
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));
@@ -506,7 +559,7 @@ r300_render_get_vertex_info(struct vbuf_render* render)
r300_update_derived_state(r300);
- return &r300->vertex_info->vinfo;
+ return (struct vertex_info*)r300->vertex_format_state.state;
}
static boolean r300_render_allocate_vertices(struct vbuf_render* render,
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 287664b1d20..fa8ed581dae 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -113,6 +113,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
* ~ C.
*/
return 1;
+ case PIPE_CAP_DUAL_SOURCE_BLEND:
+ return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
@@ -149,6 +151,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
} else {
return 0;
}
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ if (r300screen->caps->is_r500) {
+ return 1;
+ } else {
+ return 0;
+ }
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return 0;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
default:
debug_printf("r300: Implementation error: Bad param %d\n",
param);
@@ -183,10 +199,20 @@ static float r300_get_paramf(struct pipe_screen* pscreen, int param)
}
}
-static boolean check_tex_format(enum pipe_format format, uint32_t usage,
- boolean is_r500)
+static boolean r300_is_format_supported(struct pipe_screen* screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned usage,
+ unsigned geom_flags)
{
uint32_t retval = 0;
+ boolean is_r500 = r300_screen(screen)->caps->is_r500;
+
+ if (target >= PIPE_MAX_TEXTURE_TYPES) {
+ debug_printf("r300: Implementation error: Received bogus texture "
+ "target %d in %s\n", target, __FUNCTION__);
+ return FALSE;
+ }
switch (format) {
/* Supported formats. */
@@ -194,6 +220,8 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage,
case PIPE_FORMAT_A4R4G4B4_UNORM:
case PIPE_FORMAT_R5G6B5_UNORM:
case PIPE_FORMAT_A1R5G5B5_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
retval = usage &
(PIPE_TEXTURE_USAGE_RENDER_TARGET |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
@@ -208,7 +236,6 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage,
case PIPE_FORMAT_DXT3_RGBA:
case PIPE_FORMAT_DXT5_RGBA:
case PIPE_FORMAT_YCBCR:
- case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_A8L8_UNORM:
retval = usage & PIPE_TEXTURE_USAGE_SAMPLER;
break;
@@ -247,28 +274,13 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage,
case PIPE_FORMAT_Z32_UNORM:
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
- debug_printf("r300: Note: Got unsupported format: %s in %s\n",
- pf_name(format), __FUNCTION__);
+ SCREEN_DBG(r300_screen(screen), DBG_TEX,
+ "r300: Note: Got unsupported format: %s in %s\n",
+ pf_name(format), __FUNCTION__);
return FALSE;
- /* XXX These don't even exist
- case PIPE_FORMAT_A32R32G32B32:
- case PIPE_FORMAT_A16R16G16B16: */
- /* XXX What the deuce is UV88? (r3xx accel page 14)
- debug_printf("r300: Warning: Got unimplemented format: %s in %s\n",
- pf_name(format), __FUNCTION__);
- return FALSE; */
-
- /* XXX Supported yet unimplemented r5xx formats: */
- /* XXX Again, what is UV1010 this time? (r5xx accel page 148) */
- /* XXX Even more that don't exist
- case PIPE_FORMAT_A10R10G10B10_UNORM:
- case PIPE_FORMAT_A2R10G10B10_UNORM:
- case PIPE_FORMAT_I10_UNORM:
- debug_printf(
- "r300: Warning: Got unimplemented r500 format: %s in %s\n",
- pf_name(format), __FUNCTION__);
- return FALSE; */
+ /* XXX Add all remaining gallium-supported formats,
+ * see util/u_format.csv. */
default:
/* Unknown format... */
@@ -286,30 +298,6 @@ static boolean check_tex_format(enum pipe_format format, uint32_t usage,
return (retval >= usage);
}
-static boolean r300_is_format_supported(struct pipe_screen* pscreen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned tex_usage,
- unsigned geom_flags)
-{
- switch (target) {
- case PIPE_TEXTURE_1D: /* handle 1D textures as 2D ones */
- case PIPE_TEXTURE_2D:
- case PIPE_TEXTURE_3D:
- case PIPE_TEXTURE_CUBE:
- return check_tex_format(format, tex_usage,
- r300_screen(pscreen)->caps->is_r500);
-
- default:
- debug_printf("r300: Fatal: This is not a format target: %d\n",
- target);
- assert(0);
- break;
- }
-
- return FALSE;
-}
-
static struct pipe_transfer*
r300_get_tex_transfer(struct pipe_screen *screen,
struct pipe_texture *texture,
@@ -319,6 +307,7 @@ r300_get_tex_transfer(struct pipe_screen *screen,
{
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 */
@@ -330,11 +319,8 @@ r300_get_tex_transfer(struct pipe_screen *screen,
trans->transfer.y = y;
trans->transfer.width = w;
trans->transfer.height = h;
- trans->transfer.stride = r300_texture_get_stride(tex, level);
+ trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level);
trans->transfer.usage = usage;
-
- /* XXX not sure whether it's required to set these two,
- the driver doesn't use them */
trans->transfer.zslice = zslice;
trans->transfer.face = face;
@@ -396,6 +382,7 @@ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys)
caps->num_frag_pipes = radeon_winsys->gb_pipes;
caps->num_z_pipes = radeon_winsys->z_pipes;
+ r300_init_debug(r300screen);
r300_parse_chipset(caps);
r300screen->caps = caps;
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index 2217988addd..580fda3984e 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -35,6 +35,9 @@ struct r300_screen {
/* Chipset capabilities */
struct r300_capabilities* caps;
+
+ /** Combination of DBG_xxx flags */
+ unsigned debug;
};
struct r300_transfer {
@@ -60,4 +63,44 @@ r300_transfer(struct pipe_transfer* transfer)
/* Creates a new r300 screen. */
struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys);
+/* Debug functionality. */
+
+/**
+ * Debug flags to disable/enable certain groups of debugging outputs.
+ *
+ * \note These may be rather coarse, and the grouping may be impractical.
+ * If you find, while debugging the driver, that a different grouping
+ * of these flags would be beneficial, just feel free to change them
+ * but make sure to update the documentation in r300_debug.c to reflect
+ * those changes.
+ */
+/*@{*/
+#define DBG_HELP 0x0000001
+#define DBG_FP 0x0000002
+#define DBG_VP 0x0000004
+#define DBG_CS 0x0000008
+#define DBG_DRAW 0x0000010
+#define DBG_TEX 0x0000020
+#define DBG_FALL 0x0000040
+/*@}*/
+
+static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
+{
+ return (screen->debug & flags) ? TRUE : FALSE;
+}
+
+static INLINE void SCREEN_DBG(struct r300_screen * screen, unsigned flags,
+ const char * fmt, ...)
+{
+ if (SCREEN_DBG_ON(screen, flags)) {
+ va_list va;
+ va_start(va, fmt);
+ debug_vprintf(fmt, va);
+ va_end(va);
+ }
+}
+
+void r300_init_debug(struct r300_screen* ctx);
+
#endif /* R300_SCREEN_H */
+
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 60ad763cf48..a5c0869066c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -30,7 +30,6 @@
#include "tgsi/tgsi_parse.h"
#include "pipe/p_config.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "r300_context.h"
#include "r300_reg.h"
@@ -162,17 +161,18 @@ static boolean blend_discard_if_src_alpha_color_1(unsigned srcRGB, unsigned srcA
static void* r300_create_blend_state(struct pipe_context* pipe,
const struct pipe_blend_state* state)
{
+ struct r300_screen* r300screen = r300_screen(pipe->screen);
struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
- if (state->blend_enable)
+ if (state->rt[0].blend_enable)
{
- unsigned eqRGB = state->rgb_func;
- unsigned srcRGB = state->rgb_src_factor;
- unsigned dstRGB = state->rgb_dst_factor;
+ unsigned eqRGB = state->rt[0].rgb_func;
+ unsigned srcRGB = state->rt[0].rgb_src_factor;
+ unsigned dstRGB = state->rt[0].rgb_dst_factor;
- unsigned eqA = state->alpha_func;
- unsigned srcA = state->alpha_src_factor;
- unsigned dstA = state->alpha_dst_factor;
+ unsigned eqA = state->rt[0].alpha_func;
+ unsigned srcA = state->rt[0].alpha_src_factor;
+ unsigned dstA = state->rt[0].alpha_dst_factor;
/* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha,
* this is just the crappy D3D naming */
@@ -289,18 +289,18 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
(state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
}
- /* Color Channel Mask */
- if (state->colormask & PIPE_MASK_R) {
- blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_RED_MASK0;
- }
- if (state->colormask & PIPE_MASK_G) {
- blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0;
- }
- if (state->colormask & PIPE_MASK_B) {
- blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0;
- }
- if (state->colormask & PIPE_MASK_A) {
- blend->color_channel_mask |= RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0;
+ /* Color channel masks for all MRTs. */
+ blend->color_channel_mask = state->rt[0].colormask;
+ if (r300screen->caps->is_r500 && state->independent_blend_enable) {
+ if (state->rt[1].blend_enable) {
+ blend->color_channel_mask |= (state->rt[1].colormask << 4);
+ }
+ if (state->rt[2].blend_enable) {
+ blend->color_channel_mask |= (state->rt[2].colormask << 8);
+ }
+ if (state->rt[3].blend_enable) {
+ blend->color_channel_mask |= (state->rt[3].colormask << 12);
+ }
}
if (state->dither) {
@@ -486,19 +486,47 @@ static void
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
+ uint32_t zbuffer_bpp = 0;
+
+ r300->fb_state.size = (10 * state->nr_cbufs) +
+ (2 * (4 - state->nr_cbufs)) +
+ (state->zsbuf ? 10 : 0) + 6;
+
+ if (state->nr_cbufs > 4) {
+ debug_printf("r300: Implementation error: Too many MRTs in %s, "
+ "refusing to bind framebuffer state!\n", __FUNCTION__);
+ return;
+ }
if (r300->draw) {
draw_flush(r300->draw);
}
- r300->framebuffer_state = *state;
+ r300->fb_state.state = state;
/* Don't rely on the order of states being set for the first time. */
- r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
-
+ /* XXX wait what */
r300->blend_state.dirty = TRUE;
r300->dsa_state.dirty = TRUE;
+ r300->fb_state.dirty = TRUE;
r300->scissor_state.dirty = TRUE;
+
+ /* Polygon offset depends on the zbuffer bit depth. */
+ if (state->zsbuf && r300->polygon_offset_enabled) {
+ switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
+ case 2:
+ zbuffer_bpp = 16;
+ break;
+ case 4:
+ zbuffer_bpp = 24;
+ break;
+ }
+
+ if (r300->zbuffer_bpp != zbuffer_bpp) {
+ r300->zbuffer_bpp = zbuffer_bpp;
+ r300->rs_state.dirty = TRUE;
+ }
+ }
}
/* Create fragment shader state. */
@@ -534,7 +562,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
r300_pick_fragment_shader(r300);
if (r300->vs && r300_vertex_shader_setup_wpos(r300)) {
- r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
+ r300->vertex_format_state.dirty = TRUE;
}
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER | R300_NEW_FRAGMENT_SHADER_CONSTANTS;
@@ -602,9 +630,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->line_control = pack_float_16_6x(state->line_width) |
R300_GA_LINE_CNTL_END_TYPE_COMP;
- /* XXX I think there is something wrong with the polygon mode,
- * XXX re-test when r300g is in a better shape */
-
/* Enable polygon mode */
if (state->fill_cw != PIPE_POLYGON_MODE_FILL ||
state->fill_ccw != PIPE_POLYGON_MODE_FILL) {
@@ -657,10 +682,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
}
if (rs->polygon_offset_enable) {
- rs->depth_offset_front = rs->depth_offset_back =
- fui(state->offset_units);
- rs->depth_scale_front = rs->depth_scale_back =
- fui(state->offset_scale);
+ rs->depth_offset = state->offset_units;
+ rs->depth_scale = state->offset_scale;
}
if (state->line_stipple_enable) {
@@ -694,8 +717,10 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
if (rs) {
r300->tcl_bypass = rs->rs.bypass_vs_clip_and_viewport;
+ r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
} else {
r300->tcl_bypass = FALSE;
+ r300->polygon_offset_enabled = FALSE;
}
r300->rs_state.state = rs;
@@ -705,7 +730,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
r300->viewport_state.dirty = TRUE;
/* XXX Clean these up when we move to atom emits */
- r300->dirty_state |= R300_NEW_RS_BLOCK;
if (r300->fs && r300->fs->inputs.wpos != ATTR_UNUSED) {
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS;
}
@@ -906,7 +930,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
draw_set_vertex_buffers(r300->draw, count, buffers);
}
- r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
+ r300->vertex_format_state.dirty = TRUE;
+}
+
+static boolean r300_validate_aos(struct r300_context *r300)
+{
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_element *velem = r300->vertex_element;
+ 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;
+ }
+ }
+ return TRUE;
}
static void r300_set_vertex_elements(struct pipe_context* pipe,
@@ -924,6 +964,12 @@ static void r300_set_vertex_elements(struct pipe_context* pipe,
draw_flush(r300->draw);
draw_set_vertex_elements(r300->draw, count, elements);
}
+
+ if (!r300_validate_aos(r300)) {
+ /* XXX We should fallback using draw. */
+ assert(0);
+ abort();
+ }
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -964,9 +1010,10 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
r300_vertex_shader_setup_wpos(r300);
}
+ r300->vertex_format_state.dirty = TRUE;
+
r300->dirty_state |=
- R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS |
- R300_NEW_VERTEX_FORMAT;
+ R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS;
} else {
draw_flush(r300->draw);
draw_bind_vertex_shader(r300->draw,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 192846411ba..bad9e76067c 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -37,32 +37,6 @@
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
-struct r300_shader_key {
- struct r300_vertex_shader* vs;
- struct r300_fragment_shader* fs;
-};
-
-struct r300_shader_derived_value {
- struct r300_vertex_format* vformat;
- struct r300_rs_block* rs_block;
-};
-
-unsigned r300_shader_key_hash(void* key) {
- struct r300_shader_key* shader_key = (struct r300_shader_key*)key;
- unsigned vs = (intptr_t)shader_key->vs;
- unsigned fs = (intptr_t)shader_key->fs;
-
- return (vs << 16) | (fs & 0xffff);
-}
-
-int r300_shader_key_compare(void* key1, void* key2) {
- struct r300_shader_key* shader_key1 = (struct r300_shader_key*)key1;
- struct r300_shader_key* shader_key2 = (struct r300_shader_key*)key2;
-
- return (shader_key1->vs == shader_key2->vs) &&
- (shader_key1->fs == shader_key2->fs);
-}
-
static void r300_draw_emit_attrib(struct r300_context* r300,
enum attrib_emit emit,
enum interp_mode interp,
@@ -74,7 +48,9 @@ static void r300_draw_emit_attrib(struct r300_context* r300,
output = draw_find_shader_output(r300->draw,
info->output_semantic_name[index],
info->output_semantic_index[index]);
- draw_emit_vertex_attr(&r300->vertex_info->vinfo, emit, interp, output);
+ draw_emit_vertex_attr(
+ (struct vertex_info*)r300->vertex_format_state.state,
+ emit, interp, output);
}
static void r300_draw_emit_all_attribs(struct r300_context* r300)
@@ -130,7 +106,8 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
/* Update the PSC tables. */
static void r300_vertex_psc(struct r300_context* r300)
{
- struct r300_vertex_info *vformat = r300->vertex_info;
+ struct r300_vertex_info *vformat =
+ (struct r300_vertex_info*)r300->vertex_format_state.state;
uint16_t type, swizzle;
enum pipe_format format;
unsigned i;
@@ -182,7 +159,8 @@ static void r300_vertex_psc(struct r300_context* r300)
/* Update the PSC tables for SW TCL, using Draw. */
static void r300_swtcl_vertex_psc(struct r300_context* r300)
{
- struct r300_vertex_info *vformat = r300->vertex_info;
+ struct r300_vertex_info *vformat =
+ (struct r300_vertex_info*)r300->vertex_format_state.state;
struct vertex_info* vinfo = &vformat->vinfo;
uint16_t type, swizzle;
enum pipe_format format;
@@ -327,7 +305,7 @@ static void r300_update_rs_block(struct r300_context* r300,
struct r300_shader_semantics* vs_outputs,
struct r300_shader_semantics* fs_inputs)
{
- struct r300_rs_block* rs = r300->rs_block;
+ struct r300_rs_block rs = { { 0 } };
int i, col_count = 0, tex_count = 0, fp_offset = 0;
void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean);
void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
@@ -350,14 +328,15 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Rasterize colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+ if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
+ vs_outputs->color[1] != ATTR_UNUSED) {
/* Always rasterize if it's written by the VS,
* otherwise it locks up. */
- rX00_rs_col(rs, col_count, i, FALSE);
+ rX00_rs_col(&rs, col_count, i, FALSE);
/* Write it to the FS input register if it's used by the FS. */
if (fs_inputs->color[i] != ATTR_UNUSED) {
- rX00_rs_col_write(rs, col_count, fp_offset);
+ rX00_rs_col_write(&rs, col_count, fp_offset);
fp_offset++;
}
col_count++;
@@ -375,11 +354,11 @@ static void r300_update_rs_block(struct r300_context* r300,
if (vs_outputs->generic[i] != ATTR_UNUSED) {
/* Always rasterize if it's written by the VS,
* otherwise it locks up. */
- rX00_rs_tex(rs, tex_count, tex_count, FALSE);
+ rX00_rs_tex(&rs, tex_count, tex_count, FALSE);
/* Write it to the FS input register if it's used by the FS. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
- rX00_rs_tex_write(rs, tex_count, fp_offset);
+ rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
}
tex_count++;
@@ -396,11 +375,11 @@ static void r300_update_rs_block(struct r300_context* r300,
if (vs_outputs->fog != ATTR_UNUSED) {
/* Always rasterize if it's written by the VS,
* otherwise it locks up. */
- rX00_rs_tex(rs, tex_count, tex_count, TRUE);
+ rX00_rs_tex(&rs, tex_count, tex_count, TRUE);
/* Write it to the FS input register if it's used by the FS. */
if (fs_inputs->fog != ATTR_UNUSED) {
- rX00_rs_tex_write(rs, tex_count, fp_offset);
+ rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
}
tex_count++;
@@ -415,8 +394,8 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Rasterize WPOS. */
/* If the FS doesn't need it, it's not written by the VS. */
if (fs_inputs->wpos != ATTR_UNUSED) {
- rX00_rs_tex(rs, tex_count, tex_count, FALSE);
- rX00_rs_tex_write(rs, tex_count, fp_offset);
+ rX00_rs_tex(&rs, tex_count, tex_count, FALSE);
+ rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
tex_count++;
@@ -424,51 +403,33 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Rasterize at least one color, or bad things happen. */
if (col_count == 0 && tex_count == 0) {
- rX00_rs_col(rs, 0, 0, TRUE);
+ rX00_rs_col(&rs, 0, 0, TRUE);
col_count++;
}
- rs->count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
+ rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
R300_HIRES_EN;
- rs->inst_count = MAX3(col_count - 1, tex_count - 1, 0);
+ rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0);
+
+ /* Now, after all that, see if we actually need to update the state. */
+ if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) {
+ memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block));
+ r300->rs_block_state.dirty = TRUE;
+ }
}
-/* Update the vertex format. */
+/* Update the shader-dependant states. */
static void r300_update_derived_shader_state(struct r300_context* r300)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct r300_vertex_info *vformat =
+ (struct r300_vertex_info*)r300->vertex_format_state.state;
+ struct vertex_info* vinfo = &vformat->vinfo;
- /*
- struct r300_shader_key* key;
- struct r300_shader_derived_value* value;
- key = CALLOC_STRUCT(r300_shader_key);
- key->vs = r300->vs;
- key->fs = r300->fs;
-
- value = (struct r300_shader_derived_value*)
- util_hash_table_get(r300->shader_hash_table, (void*)key);
- if (value) {
- //vformat = value->vformat;
- rs_block = value->rs_block;
-
- FREE(key);
- } else {
- rs_block = CALLOC_STRUCT(r300_rs_block);
- value = CALLOC_STRUCT(r300_shader_derived_value);
-
- r300_update_rs_block(r300, rs_block);
-
- //value->vformat = vformat;
- value->rs_block = rs_block;
- util_hash_table_set(r300->shader_hash_table,
- (void*)key, (void*)value);
- } */
-
- /* Reset structures */
- memset(r300->rs_block, 0, sizeof(struct r300_rs_block));
- memset(r300->vertex_info, 0, sizeof(struct r300_vertex_info));
- memcpy(r300->vertex_info->vinfo.hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
+ /* Mmm, delicious hax */
+ memset(r300->vertex_format_state.state, 0, sizeof(struct r300_vertex_info));
+ memcpy(vinfo->hwfmt, r300->vs->hwfmt, sizeof(uint)*4);
r300_update_rs_block(r300, &r300->vs->outputs, &r300->fs->inputs);
@@ -476,11 +437,10 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
r300_vertex_psc(r300);
} else {
r300_draw_emit_all_attribs(r300);
- draw_compute_vertex_size(&r300->vertex_info->vinfo);
+ draw_compute_vertex_size(
+ (struct vertex_info*)r300->vertex_format_state.state);
r300_swtcl_vertex_psc(r300);
}
-
- r300->dirty_state |= R300_NEW_RS_BLOCK;
}
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
@@ -558,8 +518,8 @@ void r300_update_derived_state(struct r300_context* r300)
{
/* XXX */
if (r300->dirty_state &
- (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER |
- R300_NEW_VERTEX_FORMAT) || r300->rs_state.dirty) {
+ (R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER) ||
+ r300->vertex_format_state.dirty || r300->rs_state.dirty) {
r300_update_derived_shader_state(r300);
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 35be00e1b01..5df6815221f 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -81,9 +81,6 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
return R300_BLEND_GL_CONST_COLOR;
case PIPE_BLENDFACTOR_CONST_ALPHA:
return R300_BLEND_GL_CONST_ALPHA;
- /* XXX WTF are these?
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- case PIPE_BLENDFACTOR_SRC1_ALPHA: */
case PIPE_BLENDFACTOR_ZERO:
return R300_BLEND_GL_ZERO;
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
@@ -98,9 +95,16 @@ static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
- /* XXX see above
+
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ debug_printf("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);
assert(0);
@@ -331,7 +335,10 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format)
{
switch (format) {
/* 8-bit buffers */
+ case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ /* case PIPE_FORMAT_S8_UNORM: ??? */
return R300_COLOR_FORMAT_I8;
/* 16-bit buffers */
case PIPE_FORMAT_R5G6B5_UNORM:
@@ -408,6 +415,16 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
return R300_US_OUT_FMT_C4_8 |
R300_C0_SEL_A | R300_C1_SEL_B |
R300_C2_SEL_G | R300_C3_SEL_R;
+
+ /* 8-bit outputs */
+ case PIPE_FORMAT_A8_UNORM:
+ return R300_US_OUT_FMT_C4_8 |
+ R300_C0_SEL_A;
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ return R300_US_OUT_FMT_C4_8 |
+ R300_C0_SEL_R;
+ /* R300_OUT_SIGN(x) */
default:
debug_printf("r300: Implementation error: "
"Got unsupported output format %s in %s\n",
@@ -537,6 +554,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
static INLINE uint16_t
r300_translate_vertex_data_swizzle(enum pipe_format format) {
const struct util_format_description *desc = util_format_description(format);
+ unsigned swizzle[4], i;
assert(format);
@@ -547,11 +565,26 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
return 0;
}
- return ((desc->swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
- (desc->swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
- (desc->swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
- (desc->swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
- (0xf << R300_WRITE_ENA_SHIFT));
+ /* Swizzles for 8bits formats are in the reversed order, not sure why. */
+ if (desc->channel[0].size == 8) {
+ for (i = 0; i < 4; i++) {
+ if (desc->swizzle[i] <= 3) {
+ swizzle[i] = 3 - desc->swizzle[i];
+ } else {
+ swizzle[i] = desc->swizzle[i];
+ }
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ swizzle[i] = desc->swizzle[i];
+ }
+ }
+
+ return ((swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) |
+ (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) |
+ (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) |
+ (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT) |
+ (0xf << R300_WRITE_ENA_SHIFT));
}
#endif /* R300_STATE_INLINES_H */
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index b0f309695c9..97927acf1b4 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -38,12 +38,12 @@ struct pipe_viewport_state r300_viewport_identity = {
*
* Note that eventually this should be empty, but it's useful for development
* and general unduplication of code. */
-void r300_emit_invariant_state(struct r300_context* r300)
+void r300_emit_invariant_state(struct r300_context* r300, void* state)
{
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(16 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(14 + (caps->has_tcl ? 2: 0));
/*** Graphics Backend (GB) ***/
/* Various GB enables */
@@ -58,8 +58,6 @@ void r300_emit_invariant_state(struct r300_context* r300)
*/
/* Source of fog depth */
OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);
- /* AA enable */
- OUT_CS_REG(R300_GB_AA_CONFIG, 0x0);
/*** Fog (FG) ***/
OUT_CS_REG(R300_FG_FOG_BLEND, 0x0);
@@ -79,7 +77,8 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) + (caps->is_r500 ? 4 : 0));
+ BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) +
+ (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0));
if (caps->has_tcl) {
/*Flushing PVS is required before the VAP_GB registers can be changed*/
diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h
index 05cff0d6dfe..5d1a9636545 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.h
+++ b/src/gallium/drivers/r300/r300_state_invariant.h
@@ -25,6 +25,6 @@
struct r300_context;
-void r300_emit_invariant_state(struct r300_context* r300);
+void r300_emit_invariant_state(struct r300_context* r300, void* state);
#endif /* R300_STATE_INVARIANT_H */
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index a9bbdd56d84..67bf8ce13fd 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -30,6 +30,8 @@
#include "r300_texture.h"
#include "r300_screen.h"
+#include "radeon_winsys.h"
+
#define TILE_WIDTH 0
#define TILE_HEIGHT 1
@@ -42,10 +44,11 @@ static const unsigned microblock_table[5][3][2] = {
{{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
};
-static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500)
+static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
{
struct r300_texture_state* state = &tex->state;
struct pipe_texture *pt = &tex->tex;
+ boolean is_r500 = screen->caps->is_r500;
state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
@@ -79,8 +82,8 @@ static void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500)
}
assert(is_r500 || (pt->width0 <= 2048 && pt->height0 <= 2048));
- debug_printf("r300: Set texture state (%dx%d, %d levels)\n",
- pt->width0, pt->height0, pt->last_level);
+ SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
+ pt->width0, pt->height0, pt->last_level);
}
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
@@ -123,7 +126,8 @@ static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim)
* Return the stride, in bytes, of the texture images of the given texture
* at the given level.
*/
-unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
+unsigned r300_texture_get_stride(struct r300_screen* screen,
+ struct r300_texture* tex, unsigned level)
{
unsigned tile_width, width;
@@ -132,16 +136,20 @@ unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
/* Check the level. */
if (level > tex->tex.last_level) {
- debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__,
- level, tex->tex.last_level);
+ SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
+ __FUNCTION__, level, tex->tex.last_level);
return 0;
}
- tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH);
- width = align(u_minify(tex->tex.width0, level), tile_width);
+ width = u_minify(tex->tex.width0, level);
- /* Should already be aligned except for S3TC. */
- return align(util_format_get_stride(tex->tex.format, width), 32);
+ if (!util_format_is_compressed(tex->tex.format)) {
+ tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH);
+ width = align(width, tile_width);
+ return util_format_get_stride(tex->tex.format, width);
+ } else {
+ return align(util_format_get_stride(tex->tex.format, width), 32);
+ }
}
static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
@@ -149,21 +157,27 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
{
unsigned height, tile_height;
- tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT);
- height = align(u_minify(tex->tex.height0, level), tile_height);
+ height = u_minify(tex->tex.height0, level);
+
+ if (!util_format_is_compressed(tex->tex.format)) {
+ tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT);
+ height = align(height, tile_height);
+ }
return util_format_get_nblocksy(tex->tex.format, height);
}
-static void r300_setup_miptree(struct r300_texture* tex)
+static void r300_setup_miptree(struct r300_screen* screen,
+ struct r300_texture* tex)
{
struct pipe_texture* base = &tex->tex;
unsigned stride, size, layer_size, nblocksy, i;
- debug_printf("r300: Making miptree for texture, format %s\n", pf_name(base->format));
+ SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
+ pf_name(base->format));
for (i = 0; i <= base->last_level; i++) {
- stride = r300_texture_get_stride(tex, i);
+ stride = r300_texture_get_stride(screen, tex, i);
nblocksy = r300_texture_get_nblocksy(tex, i);
layer_size = stride * nblocksy;
@@ -177,7 +191,7 @@ static void r300_setup_miptree(struct r300_texture* tex)
tex->layer_size[i] = layer_size;
tex->pitch[i] = stride / util_format_get_blocksize(base->format);
- debug_printf("r300: Texture miptree: Level %d "
+ SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
"(%dx%dx%d px, pitch %d bytes) %d bytes total\n",
i, u_minify(base->width0, i), u_minify(base->height0, i),
u_minify(base->depth0, i), stride, tex->size);
@@ -196,6 +210,8 @@ static struct pipe_texture*
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;
if (!tex) {
return NULL;
@@ -206,12 +222,16 @@ static struct pipe_texture*
tex->tex.screen = screen;
r300_setup_flags(tex);
- r300_setup_miptree(tex);
- r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);
+ 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);
if (!tex->buffer) {
FREE(tex);
@@ -273,6 +293,7 @@ static struct pipe_texture*
struct pipe_buffer* buffer)
{
struct r300_texture* tex;
+ struct r300_screen* rscreen = r300_screen(screen);
/* Support only 2D textures without mipmaps */
if (base->target != PIPE_TEXTURE_2D ||
@@ -294,7 +315,7 @@ static struct pipe_texture*
tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
r300_setup_flags(tex);
- r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500);
+ r300_setup_texture_state(rscreen, tex);
pipe_buffer_reference(&tex->buffer, buffer);
@@ -361,7 +382,8 @@ void r300_init_screen_texture_functions(struct pipe_screen* screen)
screen->video_surface_destroy= r300_video_surface_destroy;
}
-boolean r300_get_texture_buffer(struct pipe_texture* texture,
+boolean r300_get_texture_buffer(struct pipe_screen* screen,
+ struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride)
{
@@ -373,7 +395,7 @@ boolean r300_get_texture_buffer(struct pipe_texture* texture,
pipe_buffer_reference(buffer, tex->buffer);
if (stride) {
- *stride = r300_texture_get_stride(tex, 0);
+ *stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
}
return TRUE;
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 55ceb1a5136..453fb1accc2 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -31,7 +31,8 @@ struct r300_texture;
void r300_init_screen_texture_functions(struct pipe_screen* screen);
-unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level);
+unsigned r300_texture_get_stride(struct r300_screen* screen,
+ struct r300_texture* tex, unsigned level);
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
unsigned zslice, unsigned face);
@@ -41,6 +42,7 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
{
switch (format) {
/* X8 */
+ case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, X8);
case PIPE_FORMAT_L8_UNORM:
@@ -115,7 +117,8 @@ r300_video_surface(struct pipe_video_surface *pvs)
#ifndef R300_WINSYS_H
-boolean r300_get_texture_buffer(struct pipe_texture* texture,
+boolean r300_get_texture_buffer(struct pipe_screen* screen,
+ struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 68aef70872e..9fbb830047f 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -124,7 +124,8 @@ static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
/* Colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+ 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;
}
@@ -182,7 +183,8 @@ static void r300_stream_locations_notcl(
/* Colors. */
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
+ if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
+ vs_outputs->color[1] != ATTR_UNUSED) {
stream_loc[tabi++] = 2 + i;
}
}
@@ -259,7 +261,8 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
for (i = 0; i < ATTR_COLOR_COUNT; i++) {
if (outputs->color[i] != ATTR_UNUSED) {
c->code->outputs[outputs->color[i]] = reg++;
- } else if (any_bcolor_used) {
+ } else if (any_bcolor_used ||
+ outputs->color[1] != ATTR_UNUSED) {
reg++;
}
}
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 1ae6de70fee..bdb8b54bab6 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -40,7 +40,8 @@ extern "C" {
struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct radeon_winsys* radeon_winsys);
-boolean r300_get_texture_buffer(struct pipe_texture* texture,
+boolean r300_get_texture_buffer(struct pipe_screen* screen,
+ struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index bcb887a0b26..e4ac49fa85f 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -32,6 +32,7 @@ C_SOURCES = \
sp_tex_tile_cache.c \
sp_tile_cache.c \
sp_surface.c \
- sp_video_context.c
+ sp_video_context.c \
+ sp_winsys.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index aac9edf44e6..3042e556c64 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -34,6 +34,7 @@ softpipe = env.ConvenienceLibrary(
'sp_texture.c',
'sp_tile_cache.c',
'sp_video_context.c',
+ 'sp_winsys.c'
])
Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 8e017939402..53133d28888 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -43,7 +43,6 @@
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_tex_tile_cache.h"
-#include "sp_texture.h"
#include "sp_winsys.h"
#include "sp_query.h"
@@ -112,9 +111,13 @@ softpipe_destroy( struct pipe_context *pipe )
pipe_texture_reference(&softpipe->vertex_textures[i], NULL);
}
- for (i = 0; i < Elements(softpipe->constants); i++) {
- if (softpipe->constants[i]) {
- pipe_buffer_reference(&softpipe->constants[i], NULL);
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ uint j;
+
+ for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
+ if (softpipe->constants[i][j]) {
+ pipe_buffer_reference(&softpipe->constants[i][j], NULL);
+ }
}
}
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index da673c57ada..be4613b6228 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -63,7 +63,7 @@ struct softpipe_context {
/** Other rendering state */
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
- struct pipe_buffer *constants[PIPE_SHADER_TYPES];
+ struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
@@ -92,7 +92,7 @@ struct softpipe_context {
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
/** Mapped constant buffers */
- void *mapped_constants[PIPE_SHADER_TYPES];
+ 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 03b58d2fb72..2b82427d546 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -49,30 +49,36 @@ static void
softpipe_map_constant_buffers(struct softpipe_context *sp)
{
struct pipe_winsys *ws = sp->pipe.winsys;
- uint i, vssize, gssize;
+ uint i;
for (i = 0; i < PIPE_SHADER_TYPES; 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);
+ 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);
+ }
+ }
}
- if (sp->constants[PIPE_SHADER_VERTEX])
- vssize = sp->constants[PIPE_SHADER_VERTEX]->size;
- else
- vssize = 0;
-
- if (sp->constants[PIPE_SHADER_GEOMETRY])
- gssize = sp->constants[PIPE_SHADER_GEOMETRY]->size;
- else
- gssize = 0;
-
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
- sp->mapped_constants[PIPE_SHADER_VERTEX],
- vssize);
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY,
- sp->mapped_constants[PIPE_SHADER_GEOMETRY],
- gssize);
+ 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);
+ }
+ }
}
@@ -87,13 +93,28 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)
*/
draw_flush(sp->draw);
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0);
- draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0);
+ 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++) {
- if (sp->constants[i] && sp->constants[i]->size)
- ws->buffer_unmap(ws, sp->constants[i]);
- sp->mapped_constants[i] = NULL;
+ 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;
+ }
}
}
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 75dac810a12..e8952bf4fb8 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -34,11 +34,9 @@
#include "draw/draw_context.h"
#include "sp_flush.h"
#include "sp_context.h"
-#include "sp_surface.h"
#include "sp_state.h"
#include "sp_tile_cache.h"
#include "sp_tex_tile_cache.h"
-#include "sp_winsys.h"
void
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index f9129506585..acee2136706 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -135,7 +135,7 @@ fs_sse_run( const struct sp_fragment_shader *base,
tgsi_set_exec_mask(machine, 1, 1, 1, 1);
shader->func( machine,
- machine->Consts,
+ (const float (*)[4])machine->Consts[0],
(const float (*)[4])shader->immediates,
machine->InterpCoefs
/*, &machine->QuadPos*/
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 7f573aef3c3..98c08eaffaf 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -526,6 +526,8 @@ static void
sp_vbuf_destroy(struct vbuf_render *vbr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
+ if(cvbr->vertex_buffer)
+ align_free(cvbr->vertex_buffer);
sp_setup_destroy_context(cvbr->setup);
FREE(cvbr);
}
@@ -541,7 +543,6 @@ sp_create_vbuf_backend(struct softpipe_context *sp)
assert(sp->draw);
-
cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index d9babe81dad..d65307b7f60 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -35,7 +35,6 @@
#include "util/u_memory.h"
#include "sp_context.h"
#include "sp_quad.h"
-#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_quad_pipe.h"
@@ -224,7 +223,8 @@ logicop_quad(struct quad_stage *qs,
static void
blend_quad(struct quad_stage *qs,
float (*quadColor)[4],
- float (*dest)[4])
+ float (*dest)[4],
+ unsigned cbuf)
{
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
@@ -234,7 +234,7 @@ blend_quad(struct quad_stage *qs,
/*
* Compute src/first term RGB
*/
- switch (softpipe->blend->rgb_src_factor) {
+ switch (softpipe->blend->rt[cbuf].rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
VEC4_COPY(source[0], quadColor[0]); /* R */
VEC4_COPY(source[1], quadColor[1]); /* G */
@@ -384,7 +384,7 @@ blend_quad(struct quad_stage *qs,
/*
* Compute src/first term A
*/
- switch (softpipe->blend->alpha_src_factor) {
+ switch (softpipe->blend->rt[cbuf].alpha_src_factor) {
case PIPE_BLENDFACTOR_ONE:
VEC4_COPY(source[3], quadColor[3]); /* A */
break;
@@ -453,7 +453,7 @@ blend_quad(struct quad_stage *qs,
/*
* Compute dest/second term RGB
*/
- switch (softpipe->blend->rgb_dst_factor) {
+ switch (softpipe->blend->rt[cbuf].rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* dest = dest * 1 NO-OP, leave dest as-is */
break;
@@ -593,7 +593,7 @@ blend_quad(struct quad_stage *qs,
/*
* Compute dest/second term A
*/
- switch (softpipe->blend->alpha_dst_factor) {
+ switch (softpipe->blend->rt[cbuf].alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
/* dest = dest * 1 NO-OP, leave dest as-is */
break;
@@ -656,7 +656,7 @@ blend_quad(struct quad_stage *qs,
/*
* Combine RGB terms
*/
- switch (softpipe->blend->rgb_func) {
+ switch (softpipe->blend->rt[cbuf].rgb_func) {
case PIPE_BLEND_ADD:
VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
@@ -689,7 +689,7 @@ blend_quad(struct quad_stage *qs,
/*
* Combine A terms
*/
- switch (softpipe->blend->alpha_func) {
+ switch (softpipe->blend->rt[cbuf].alpha_func) {
case PIPE_BLEND_ADD:
VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
break;
@@ -711,26 +711,24 @@ blend_quad(struct quad_stage *qs,
}
static void
-colormask_quad(struct quad_stage *qs,
+colormask_quad(unsigned colormask,
float (*quadColor)[4],
float (*dest)[4])
{
- struct softpipe_context *softpipe = qs->softpipe;
-
/* R */
- if (!(softpipe->blend->colormask & PIPE_MASK_R))
+ if (!(colormask & PIPE_MASK_R))
COPY_4V(quadColor[0], dest[0]);
/* G */
- if (!(softpipe->blend->colormask & PIPE_MASK_G))
+ if (!(colormask & PIPE_MASK_G))
COPY_4V(quadColor[1], dest[1]);
/* B */
- if (!(softpipe->blend->colormask & PIPE_MASK_B))
+ if (!(colormask & PIPE_MASK_B))
COPY_4V(quadColor[2], dest[2]);
/* A */
- if (!(softpipe->blend->colormask & PIPE_MASK_A))
+ if (!(colormask & PIPE_MASK_A))
COPY_4V(quadColor[3], dest[3]);
}
@@ -773,12 +771,12 @@ blend_fallback(struct quad_stage *qs,
if (blend->logicop_enable) {
logicop_quad( qs, quadColor, dest );
}
- else if (blend->blend_enable) {
- blend_quad( qs, quadColor, dest );
+ else if (blend->rt[cbuf].blend_enable) {
+ blend_quad( qs, quadColor, dest, cbuf );
}
- if (blend->colormask != 0xf)
- colormask_quad( qs, quadColor, dest );
+ if (blend->rt[cbuf].colormask != 0xf)
+ colormask_quad( blend->rt[cbuf].colormask, quadColor, dest);
/* Output color values
*/
@@ -954,23 +952,23 @@ choose_blend_quad(struct quad_stage *qs,
qs->run = blend_noop;
}
else if (!softpipe->blend->logicop_enable &&
- softpipe->blend->colormask == 0xf &&
+ softpipe->blend->rt[0].colormask == 0xf &&
softpipe->framebuffer.nr_cbufs == 1)
{
- if (!blend->blend_enable) {
+ if (!blend->rt[0].blend_enable) {
qs->run = single_output_color;
}
- else if (blend->rgb_src_factor == blend->alpha_src_factor &&
- blend->rgb_dst_factor == blend->alpha_dst_factor &&
- blend->rgb_func == blend->alpha_func)
+ else if (blend->rt[0].rgb_src_factor == blend->rt[0].alpha_src_factor &&
+ blend->rt[0].rgb_dst_factor == blend->rt[0].alpha_dst_factor &&
+ blend->rt[0].rgb_func == blend->rt[0].alpha_func)
{
- if (blend->alpha_func == PIPE_BLEND_ADD) {
- if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
- blend->rgb_dst_factor == PIPE_BLENDFACTOR_ONE) {
+ if (blend->rt[0].alpha_func == PIPE_BLEND_ADD) {
+ if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
+ blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_ONE) {
qs->run = blend_single_add_one_one;
}
- else if (blend->rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA &&
- blend->rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
+ else if (blend->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA &&
+ blend->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
qs->run = blend_single_add_src_alpha_inv_src_alpha;
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index 0ca86c4e1cb..a981775cbd3 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -30,11 +30,11 @@
*/
#include "pipe/p_defines.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
#include "tgsi/tgsi_scan.h"
#include "sp_context.h"
#include "sp_quad.h"
-#include "sp_surface.h"
#include "sp_quad_pipe.h"
#include "sp_tile_cache.h"
#include "sp_state.h" /* for sp_fragment_shader */
@@ -651,6 +651,20 @@ static unsigned mask_count[16] =
+/** helper to get number of Z buffer bits */
+static unsigned
+get_depth_bits(struct quad_stage *qs)
+{
+ struct pipe_surface *zsurf = qs->softpipe->framebuffer.zsbuf;
+ if (zsurf)
+ return util_format_get_component_bits(zsurf->format,
+ UTIL_FORMAT_COLORSPACE_ZS, 0);
+ else
+ return 0;
+}
+
+
+
static void
depth_test_quads_fallback(struct quad_stage *qs,
struct quad_header *quads[],
@@ -666,7 +680,7 @@ depth_test_quads_fallback(struct quad_stage *qs,
nr = alpha_test_quads(qs, quads, nr);
}
- if (qs->softpipe->framebuffer.zsbuf &&
+ if (get_depth_bits(qs) > 0 &&
(qs->softpipe->depth_stencil->depth.enabled ||
qs->softpipe->depth_stencil->stencil[0].enabled)) {
@@ -884,7 +898,7 @@ choose_depth_test(struct quad_stage *qs,
boolean alpha = qs->softpipe->depth_stencil->alpha.enabled;
- boolean depth = (qs->softpipe->framebuffer.zsbuf &&
+ boolean depth = (get_depth_bits(qs) > 0 &&
qs->softpipe->depth_stencil->depth.enabled);
unsigned depthfunc = qs->softpipe->depth_stencil->depth.func;
@@ -895,7 +909,6 @@ choose_depth_test(struct quad_stage *qs,
boolean occlusion = qs->softpipe->active_query_count;
-
if (!alpha &&
!depth &&
!stencil) {
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 1e7533d0f9e..ad04dc2afc3 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -45,8 +45,6 @@
#include "sp_state.h"
#include "sp_quad.h"
#include "sp_quad_pipe.h"
-#include "sp_texture.h"
-#include "sp_tex_sample.h"
struct quad_shade_stage
@@ -109,10 +107,11 @@ shade_quads(struct quad_stage *qs,
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
struct tgsi_exec_machine *machine = qss->machine;
-
unsigned i, pass = 0;
-
- machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
+
+ for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
+ machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i];
+ }
machine->InterpCoefs = quads[0]->coef;
for (i = 0; i < nr; i++) {
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index bd3532de4f4..714a1cf5343 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -91,6 +91,19 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
+ case PIPE_CAP_MAX_CONST_BUFFERS:
+ return PIPE_MAX_CONSTANT_BUFFERS;
+ case PIPE_CAP_MAX_CONST_BUFFER_SIZE:
+ return 4096 * 4 * sizeof(float);
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ return 1;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 1;
default:
return 0;
}
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 3da75364c5d..bb1bff581cf 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -38,10 +38,8 @@
#include "sp_setup.h"
#include "sp_state.h"
#include "draw/draw_context.h"
-#include "draw/draw_private.h"
#include "draw/draw_vertex.h"
#include "pipe/p_shader_tokens.h"
-#include "pipe/p_thread.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -506,21 +504,24 @@ static void tri_persp_coeff( struct setup_context *setup,
/**
* Special coefficient setup for gl_FragCoord.
- * X and Y are trivial, though Y has to be inverted for OpenGL.
+ * X and Y are trivial, though Y may have to be inverted for OpenGL.
* Z and W are copied from posCoef which should have already been computed.
* We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
*/
static void
setup_fragcoord_coeff(struct setup_context *setup, uint slot)
{
+ struct sp_fragment_shader* spfs = setup->softpipe->fs;
/*X*/
- setup->coef[slot].a0[0] = 0;
+ setup->coef[slot].a0[0] = spfs->pixel_center_integer ? 0.0 : 0.5;
setup->coef[slot].dadx[0] = 1.0;
setup->coef[slot].dady[0] = 0.0;
/*Y*/
- setup->coef[slot].a0[1] = 0.0;
+ setup->coef[slot].a0[1] =
+ (spfs->origin_lower_left ? setup->softpipe->framebuffer.height : 0)
+ + (spfs->pixel_center_integer ? 0.0 : 0.5);
setup->coef[slot].dadx[1] = 0.0;
- setup->coef[slot].dady[1] = 1.0;
+ setup->coef[slot].dady[1] = spfs->origin_lower_left ? -1.0 : 1.0;
/*Z*/
setup->coef[slot].a0[2] = setup->posCoef.a0[2];
setup->coef[slot].dadx[2] = setup->posCoef.dadx[2];
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 7f244c4fd49..a83cae73617 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -68,6 +68,9 @@ struct sp_fragment_shader {
struct tgsi_shader_info info;
+ boolean origin_lower_left; /**< fragment shader uses lower left position origin? */
+ boolean pixel_center_integer; /**< fragment shader uses integer pixel center? */
+
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler **samplers);
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index b7ed4441b43..de3edde9760 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -44,6 +44,7 @@ softpipe_create_fs_state(struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader *state;
+ unsigned i;
/* debug */
if (softpipe->dump_fs)
@@ -60,6 +61,13 @@ softpipe_create_fs_state(struct pipe_context *pipe,
/* get/save the summary info for this shader */
tgsi_scan_shader(templ->tokens, &state->info);
+ for (i = 0; i < state->info.num_properties; ++i) {
+ if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN)
+ state->origin_lower_left = state->info.properties[i].data[0];
+ else if (state->info.properties[i].name == TGSI_PROPERTY_FS_COORD_PIXEL_CENTER)
+ state->pixel_center_integer = state->info.properties[i].data[0];
+ }
+
return state;
}
@@ -164,12 +172,12 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
struct softpipe_context *softpipe = softpipe_context(pipe);
assert(shader < PIPE_SHADER_TYPES);
- assert(index == 0);
+ assert(index < PIPE_MAX_CONSTANT_BUFFERS);
draw_flush(softpipe->draw);
/* note: reference counting */
- pipe_buffer_reference(&softpipe->constants[shader], buf);
+ pipe_buffer_reference(&softpipe->constants[shader][index], buf);
softpipe->dirty |= SP_NEW_CONSTANTS;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index f6154109ea8..39466782195 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -30,7 +30,6 @@
#include "sp_context.h"
#include "sp_state.h"
-#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "draw/draw_context.h"
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index 46b6991195d..b491d92ed15 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -31,7 +31,6 @@
#include "sp_context.h"
#include "sp_state.h"
-#include "sp_surface.h"
#include "draw/draw_context.h"
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 1ae8fecacf7..473ec3e150a 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -517,7 +517,6 @@ compute_lambda_1d(const struct sp_sampler_varient *samp,
const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
float rho = MAX2(dsdx, dsdy) * texture->width0;
@@ -533,7 +532,6 @@ compute_lambda_2d(const struct sp_sampler_varient *samp,
const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
@@ -553,7 +551,6 @@ compute_lambda_3d(const struct sp_sampler_varient *samp,
const float p[QUAD_SIZE])
{
const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
index e50a76a73bc..50242d5bd69 100644
--- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -37,7 +37,6 @@
#include "util/u_tile.h"
#include "util/u_math.h"
#include "sp_context.h"
-#include "sp_surface.h"
#include "sp_texture.h"
#include "sp_tex_tile_cache.h"
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index a9436a33942..a5fff915077 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -38,7 +38,6 @@
#include "util/u_memory.h"
#include "sp_context.h"
-#include "sp_state.h"
#include "sp_texture.h"
#include "sp_screen.h"
#include "sp_winsys.h"
@@ -57,13 +56,8 @@ softpipe_texture_layout(struct pipe_screen *screen,
unsigned width = pt->width0;
unsigned height = pt->height0;
unsigned depth = pt->depth0;
-
unsigned buffer_size = 0;
- pt->width0 = width;
- pt->height0 = height;
- pt->depth0 = depth;
-
for (level = 0; level <= pt->last_level; level++) {
spt->stride[level] = util_format_get_stride(pt->format, width);
@@ -296,6 +290,10 @@ softpipe_get_tex_transfer(struct pipe_screen *screen,
assert(texture);
assert(level <= texture->last_level);
+ /* make sure the requested region is in the image bounds */
+ assert(x + w <= u_minify(texture->width0, level));
+ assert(y + h <= u_minify(texture->height0, level));
+
spt = CALLOC_STRUCT(softpipe_transfer);
if (spt) {
struct pipe_transfer *pt = &spt->base;
diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c
index cae2d3efc58..d0723ebe9e0 100644
--- a/src/gallium/drivers/softpipe/sp_video_context.c
+++ b/src/gallium/drivers/softpipe/sp_video_context.c
@@ -185,17 +185,18 @@ init_pipe_state(struct sp_mpeg12_context *ctx)
ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
- blend.blend_enable = 0;
- blend.rgb_func = PIPE_BLEND_ADD;
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_func = PIPE_BLEND_ADD;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.independent_blend_enable = 0;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].rgb_func = PIPE_BLEND_ADD;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_func = PIPE_BLEND_ADD;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
blend.logicop_enable = 0;
blend.logicop_func = PIPE_LOGICOP_CLEAR;
/* Needed to allow color writes to FB, even if blending disabled */
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
blend.dither = 0;
ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
diff --git a/src/gallium/drivers/softpipe/sp_winsys.c b/src/gallium/drivers/softpipe/sp_winsys.c
new file mode 100644
index 00000000000..38bcd64c6a5
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_winsys.c
@@ -0,0 +1,244 @@
+/**************************************************************************
+ *
+ * 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 "pipe/internal/p_winsys_screen.h"/* port to just p_screen */
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "softpipe/sp_winsys.h"
+
+
+struct st_softpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+ void *mapped;
+};
+
+
+/** Cast wrapper */
+static INLINE struct st_softpipe_buffer *
+st_softpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct st_softpipe_buffer *)buf;
+}
+
+
+static void *
+st_softpipe_buffer_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
+ st_softpipe_buf->mapped = st_softpipe_buf->data;
+ return st_softpipe_buf->mapped;
+}
+
+
+static void
+st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
+ st_softpipe_buf->mapped = NULL;
+}
+
+
+static void
+st_softpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
+
+ if (oldBuf->data) {
+ if (!oldBuf->userBuffer)
+ align_free(oldBuf->data);
+
+ oldBuf->data = NULL;
+ }
+
+ FREE(oldBuf);
+}
+
+
+static void
+st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+}
+
+
+
+static const char *
+st_softpipe_get_name(struct pipe_winsys *winsys)
+{
+ return "softpipe";
+}
+
+
+static struct pipe_buffer *
+st_softpipe_buffer_create(struct pipe_winsys *winsys,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
+ void *ptr,
+ unsigned bytes)
+{
+ struct st_softpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(st_softpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+static struct pipe_buffer *
+st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ const unsigned alignment = 64;
+ unsigned nblocksy;
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ *stride = align(util_format_get_stride(format, width), alignment);
+
+ return winsys->buffer_create(winsys, alignment,
+ usage,
+ *stride * nblocksy);
+}
+
+
+static void
+st_softpipe_fence_reference(struct pipe_winsys *winsys,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+}
+
+
+static int
+st_softpipe_fence_signalled(struct pipe_winsys *winsys,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static int
+st_softpipe_fence_finish(struct pipe_winsys *winsys,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static void
+st_softpipe_destroy(struct pipe_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+
+struct pipe_screen *
+softpipe_create_screen_malloc(void)
+{
+ static struct pipe_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = CALLOC_STRUCT(pipe_winsys);
+ if(!winsys)
+ return NULL;
+
+ winsys->destroy = st_softpipe_destroy;
+
+ winsys->buffer_create = st_softpipe_buffer_create;
+ winsys->user_buffer_create = st_softpipe_user_buffer_create;
+ winsys->buffer_map = st_softpipe_buffer_map;
+ winsys->buffer_unmap = st_softpipe_buffer_unmap;
+ winsys->buffer_destroy = st_softpipe_buffer_destroy;
+
+ winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
+
+ winsys->fence_reference = st_softpipe_fence_reference;
+ winsys->fence_signalled = st_softpipe_fence_signalled;
+ winsys->fence_finish = st_softpipe_fence_finish;
+
+ winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
+ winsys->get_name = st_softpipe_get_name;
+
+ screen = softpipe_create_screen(winsys);
+ if(!screen)
+ st_softpipe_destroy(winsys);
+
+ return screen;
+}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index f203ded29ee..3042e01a05c 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -49,10 +49,17 @@ struct pipe_buffer;
struct pipe_context *softpipe_create( struct pipe_screen * );
+/**
+ * Create a softpipe screen that uses the
+ * given winsys for allocating buffers.
+ */
+struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
-struct pipe_screen *
-softpipe_create_screen(struct pipe_winsys *);
-
+/**
+ * Create a softpipe screen that uses
+ * regular malloc to create all its buffers.
+ */
+struct pipe_screen *softpipe_create_screen_malloc(void);
boolean
softpipe_get_texture_buffer( struct pipe_texture *texture,
diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c
index 75492dffca2..6b6ebc9b585 100644
--- a/src/gallium/drivers/svga/svga_draw_arrays.c
+++ b/src/gallium/drivers/svga/svga_draw_arrays.c
@@ -26,7 +26,6 @@
#include "svga_cmd.h"
#include "pipe/p_inlines.h"
-#include "util/u_prim.h"
#include "indices/u_indices.h"
#include "svga_hw_reg.h"
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c
index 167d8178315..022b444eb91 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -24,7 +24,6 @@
**********************************************************/
#include "pipe/p_inlines.h"
-#include "util/u_prim.h"
#include "util/u_upload_mgr.h"
#include "indices/u_indices.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c
index 855d228755f..9df5485f462 100644
--- a/src/gallium/drivers/svga/svga_pipe_blend.c
+++ b/src/gallium/drivers/svga/svga_pipe_blend.c
@@ -29,7 +29,6 @@
#include "util/u_memory.h"
#include "svga_context.h"
-#include "svga_state.h"
#include "svga_hw_reg.h"
@@ -182,15 +181,15 @@ svga_create_blend_state(struct pipe_context *pipe,
}
}
else {
- blend->rt[i].blend_enable = templ->blend_enable;
+ blend->rt[i].blend_enable = templ->rt[0].blend_enable;
- if (templ->blend_enable) {
- blend->rt[i].srcblend = svga_translate_blend_factor(templ->rgb_src_factor);
- blend->rt[i].dstblend = svga_translate_blend_factor(templ->rgb_dst_factor);
- blend->rt[i].blendeq = svga_translate_blend_func(templ->rgb_func);
- blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->alpha_src_factor);
- blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->alpha_dst_factor);
- blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->alpha_func);
+ if (templ->rt[0].blend_enable) {
+ blend->rt[i].srcblend = svga_translate_blend_factor(templ->rt[0].rgb_src_factor);
+ blend->rt[i].dstblend = svga_translate_blend_factor(templ->rt[0].rgb_dst_factor);
+ blend->rt[i].blendeq = svga_translate_blend_func(templ->rt[0].rgb_func);
+ blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_src_factor);
+ blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_dst_factor);
+ blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->rt[0].alpha_func);
if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
@@ -201,7 +200,7 @@ svga_create_blend_state(struct pipe_context *pipe,
}
}
- blend->rt[i].writemask = templ->colormask;
+ blend->rt[i].writemask = templ->rt[0].colormask;
}
return blend;
diff --git a/src/gallium/drivers/svga/svga_pipe_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c
index ca2c7c49d72..9022f7c4394 100644
--- a/src/gallium/drivers/svga/svga_pipe_constants.c
+++ b/src/gallium/drivers/svga/svga_pipe_constants.c
@@ -26,13 +26,9 @@
#include "pipe/p_inlines.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
-#include "util/u_memory.h"
#include "tgsi/tgsi_parse.h"
#include "svga_context.h"
-#include "svga_state.h"
-#include "svga_hw_reg.h"
-#include "svga_cmd.h"
/***********************************************************************
* Constant buffers
diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
index df636c08a05..34e60cb341a 100644
--- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c
+++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c
@@ -29,7 +29,6 @@
#include "util/u_memory.h"
#include "svga_context.h"
-#include "svga_state.h"
#include "svga_hw_reg.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index 0f24ef4ee8d..4e0c499dc3e 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -33,7 +33,6 @@
#include "svga_hw_reg.h"
#include "svga_context.h"
#include "svga_screen.h"
-#include "svga_winsys.h"
#include "svga_draw.h"
#include "svga_state.h"
#include "svga_swtnl.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c
index 0becb0765ac..3eb10336c4e 100644
--- a/src/gallium/drivers/svga/svga_pipe_flush.c
+++ b/src/gallium/drivers/svga/svga_pipe_flush.c
@@ -28,13 +28,8 @@
#include "svga_screen_texture.h"
#include "svga_context.h"
#include "svga_winsys.h"
-#include "svga_draw.h"
#include "svga_debug.h"
-#include "svga_hw_reg.h"
-
-
-
static void svga_flush( struct pipe_context *pipe,
unsigned flags,
diff --git a/src/gallium/drivers/svga/svga_pipe_fs.c b/src/gallium/drivers/svga/svga_pipe_fs.c
index 5f1213e46a3..32f07fb2616 100644
--- a/src/gallium/drivers/svga/svga_pipe_fs.c
+++ b/src/gallium/drivers/svga/svga_pipe_fs.c
@@ -32,11 +32,9 @@
#include "svga_screen.h"
#include "svga_context.h"
-#include "svga_state.h"
#include "svga_tgsi.h"
#include "svga_hw_reg.h"
#include "svga_cmd.h"
-#include "svga_draw.h"
#include "svga_debug.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c
index 58cb1e6e230..8cf1f2e083a 100644
--- a/src/gallium/drivers/svga/svga_pipe_misc.c
+++ b/src/gallium/drivers/svga/svga_pipe_misc.c
@@ -27,12 +27,6 @@
#include "svga_context.h"
#include "svga_screen_texture.h"
-#include "svga_state.h"
-#include "svga_winsys.h"
-
-#include "svga_hw_reg.h"
-
-
static void svga_set_scissor_state( struct pipe_context *pipe,
diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c
index 01336b0a2c3..08283e37317 100644
--- a/src/gallium/drivers/svga/svga_pipe_query.c
+++ b/src/gallium/drivers/svga/svga_pipe_query.c
@@ -32,7 +32,6 @@
#include "svga_screen.h"
#include "svga_screen_buffer.h"
#include "svga_winsys.h"
-#include "svga_draw.h"
#include "svga_debug.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index b03f8eb9cf3..9ea11aad9a9 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -30,7 +30,6 @@
#include "util/u_memory.h"
#include "svga_context.h"
-#include "svga_state.h"
#include "svga_hw_reg.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index 460a101f8c0..161c66dd4ff 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -32,9 +32,6 @@
#include "svga_context.h"
#include "svga_screen_texture.h"
-#include "svga_state.h"
-
-#include "svga_hw_reg.h"
#include "svga_debug.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 42f290d162a..724166a3352 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -26,16 +26,11 @@
#include "pipe/p_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"
#include "svga_screen_buffer.h"
#include "svga_context.h"
-#include "svga_state.h"
-#include "svga_winsys.h"
-
-#include "svga_hw_reg.h"
static void svga_set_vertex_buffers(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/svga/svga_pipe_vs.c b/src/gallium/drivers/svga/svga_pipe_vs.c
index 7e6ab576add..c4ac5304ac6 100644
--- a/src/gallium/drivers/svga/svga_pipe_vs.c
+++ b/src/gallium/drivers/svga/svga_pipe_vs.c
@@ -33,7 +33,6 @@
#include "svga_screen.h"
#include "svga_context.h"
-#include "svga_state.h"
#include "svga_tgsi.h"
#include "svga_hw_reg.h"
#include "svga_cmd.h"
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index fc1b3c980ef..c9db9ac8747 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -33,10 +33,8 @@
#include "svga_screen.h"
#include "svga_screen_texture.h"
#include "svga_screen_buffer.h"
-#include "svga_cmd.h"
#include "svga_debug.h"
-#include "svga_hw_reg.h"
#include "svga3d_shaderdefs.h"
@@ -146,6 +144,13 @@ svga_get_paramf(struct pipe_screen *screen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE: /* req. for GL 1.5 */
return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
+
default:
return 0;
}
@@ -393,8 +398,6 @@ svga_screen_create(struct svga_winsys_screen *sws)
pipe_mutex_init(svgascreen->tex_mutex);
pipe_mutex_init(svgascreen->swc_mutex);
- LIST_INITHEAD(&svgascreen->cached_buffers);
-
svga_screen_cache_init(svgascreen);
return screen;
diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h
index b94ca7fc1ca..a009b607200 100644
--- a/src/gallium/drivers/svga/svga_screen.h
+++ b/src/gallium/drivers/svga/svga_screen.h
@@ -68,12 +68,6 @@ struct svga_screen
pipe_mutex tex_mutex;
pipe_mutex swc_mutex; /* Protects the use of swc and dirty_buffers */
- /**
- * List of buffers with cached GMR. Ordered from the most recently used to
- * the least recently used
- */
- struct list_head cached_buffers;
-
struct svga_host_surface_cache cache;
};
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_screen_buffer.c
index 58a1aba464b..430a6970fde 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.c
+++ b/src/gallium/drivers/svga/svga_screen_buffer.c
@@ -113,68 +113,9 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
if(sbuf->hw.buf) {
sws->buffer_destroy(sws, sbuf->hw.buf);
sbuf->hw.buf = NULL;
- assert(sbuf->head.prev && sbuf->head.next);
- LIST_DEL(&sbuf->head);
-#ifdef DEBUG
- sbuf->head.next = sbuf->head.prev = NULL;
-#endif
}
}
-static INLINE enum pipe_error
-svga_buffer_backup(struct svga_screen *ss, struct svga_buffer *sbuf)
-{
- if (sbuf->hw.buf && sbuf->hw.num_ranges) {
- void *src;
-
- if (!sbuf->swbuf)
- sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
- if (!sbuf->swbuf)
- return PIPE_ERROR_OUT_OF_MEMORY;
-
- src = ss->sws->buffer_map(ss->sws, sbuf->hw.buf,
- PIPE_BUFFER_USAGE_CPU_READ);
- if (!src)
- return PIPE_ERROR;
-
- memcpy(sbuf->swbuf, src, sbuf->base.size);
- ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
- }
-
- return PIPE_OK;
-}
-
-/**
- * Try to make GMR space available by freeing the hardware storage of
- * unmapped
- */
-boolean
-svga_buffer_free_cached_hw_storage(struct svga_screen *ss)
-{
- struct list_head *curr;
- struct svga_buffer *sbuf;
- enum pipe_error ret = PIPE_OK;
-
- curr = ss->cached_buffers.prev;
-
- /* free the least recently used buffer's hw storage which is not mapped */
- do {
- if(curr == &ss->cached_buffers)
- return FALSE;
-
- sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
-
- curr = curr->prev;
- if (sbuf->map.count == 0)
- ret = svga_buffer_backup(ss, sbuf);
-
- } while(sbuf->map.count != 0 || ret != PIPE_OK);
-
- svga_buffer_destroy_hw_storage(ss, sbuf);
-
- return TRUE;
-}
-
struct svga_winsys_buffer *
svga_winsys_buffer_create( struct svga_screen *ss,
unsigned alignment,
@@ -195,12 +136,6 @@ svga_winsys_buffer_create( struct svga_screen *ss,
svga_screen_flush(ss, NULL);
buf = sws->buffer_create(sws, alignment, usage, size);
- SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "evicting buffers to find %d bytes GMR\n",
- size);
-
- /* Try evicing all buffer storage */
- while(!buf && svga_buffer_free_cached_hw_storage(ss))
- buf = sws->buffer_create(sws, alignment, usage, size);
}
return buf;
@@ -226,8 +161,6 @@ svga_buffer_create_hw_storage(struct svga_screen *ss,
return PIPE_ERROR_OUT_OF_MEMORY;
assert(!sbuf->needs_flush);
- assert(!sbuf->head.prev && !sbuf->head.next);
- LIST_ADD(&sbuf->head, &ss->cached_buffers);
}
return PIPE_OK;
@@ -311,7 +244,6 @@ static void
svga_buffer_upload_flush(struct svga_context *svga,
struct svga_buffer *sbuf)
{
- struct svga_screen *ss = svga_screen(svga->pipe.screen);
SVGA3dCopyBox *boxes;
unsigned i;
@@ -348,13 +280,16 @@ svga_buffer_upload_flush(struct svga_context *svga,
assert(sbuf->head.prev && sbuf->head.next);
LIST_DEL(&sbuf->head);
+#ifdef DEBUG
+ sbuf->head.next = sbuf->head.prev = NULL;
+#endif
sbuf->needs_flush = FALSE;
- /* XXX: do we care about cached_buffers any more ?*/
- LIST_ADD(&sbuf->head, &ss->cached_buffers);
sbuf->hw.svga = NULL;
sbuf->hw.boxes = NULL;
+ sbuf->host_written = TRUE;
+
/* Decrement reference count */
pipe_reference(&(sbuf->base.reference), NULL);
sbuf = NULL;
@@ -437,17 +372,17 @@ svga_buffer_map_range( struct pipe_screen *screen,
}
else {
if(!sbuf->hw.buf) {
- struct svga_winsys_surface *handle = sbuf->handle;
-
if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
return NULL;
/* Populate the hardware storage if the host surface pre-existed */
- if((usage & PIPE_BUFFER_USAGE_CPU_READ) && handle) {
+ if(sbuf->host_written) {
SVGA3dSurfaceDMAFlags flags;
enum pipe_error ret;
struct pipe_fence_handle *fence = NULL;
+ assert(sbuf->handle);
+
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n",
sbuf->handle, 0, sbuf->base.size);
@@ -478,17 +413,6 @@ svga_buffer_map_range( struct pipe_screen *screen,
sws->fence_reference(sws, &fence, NULL);
}
}
- else {
- if((usage & PIPE_BUFFER_USAGE_CPU_READ) && !sbuf->needs_flush) {
- /* We already had the hardware storage but we would have to issue
- * a download if we hadn't, so move the buffer to the begginning
- * of the LRU list.
- */
- assert(sbuf->head.prev && sbuf->head.next);
- LIST_DEL(&sbuf->head);
- LIST_ADD(&sbuf->head, &ss->cached_buffers);
- }
- }
map = sws->buffer_map(sws, sbuf->hw.buf, usage);
}
@@ -572,10 +496,8 @@ svga_buffer_destroy( struct pipe_buffer *buf )
assert(!sbuf->needs_flush);
- if(sbuf->handle) {
- SVGA_DBG(DEBUG_DMA, "release sid %p sz %d\n", sbuf->handle, sbuf->base.size);
- svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
- }
+ if(sbuf->handle)
+ svga_buffer_destroy_host_surface(ss, sbuf);
if(sbuf->hw.buf)
svga_buffer_destroy_hw_storage(ss, sbuf);
@@ -595,6 +517,9 @@ svga_buffer_create(struct pipe_screen *screen,
struct svga_screen *ss = svga_screen(screen);
struct svga_buffer *sbuf;
+ assert(size);
+ assert(alignment);
+
sbuf = CALLOC_STRUCT(svga_buffer);
if(!sbuf)
goto error1;
@@ -755,8 +680,7 @@ svga_buffer_handle(struct svga_context *svga,
assert(sbuf->hw.svga == svga);
sbuf->needs_flush = TRUE;
- assert(sbuf->head.prev && sbuf->head.next);
- LIST_DEL(&sbuf->head);
+ assert(!sbuf->head.prev && !sbuf->head.next);
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
}
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_screen_buffer.h
index 5d7af5a7c50..448ac107c7f 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.h
+++ b/src/gallium/drivers/svga/svga_screen_buffer.h
@@ -135,6 +135,11 @@ struct svga_buffer
*/
struct svga_winsys_surface *handle;
+ /**
+ * Whether the host has been ever written.
+ */
+ boolean host_written;
+
struct {
unsigned count;
boolean writing;
@@ -178,9 +183,6 @@ svga_buffer_handle(struct svga_context *svga,
void
svga_context_flush_buffers(struct svga_context *svga);
-boolean
-svga_buffer_free_cached_hw_storage(struct svga_screen *ss);
-
struct svga_winsys_buffer *
svga_winsys_buffer_create(struct svga_screen *ss,
unsigned alignment,
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
index 2224c2d3945..0d69007fd87 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ b/src/gallium/drivers/svga/svga_screen_texture.c
@@ -306,11 +306,19 @@ svga_texture_create(struct pipe_screen *screen,
tex->key.numFaces = 1;
}
+ tex->key.cachable = 1;
+
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ tex->key.cachable = 0;
+ }
+
+ if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
+ tex->key.cachable = 0;
+ }
/*
* XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
@@ -333,8 +341,6 @@ svga_texture_create(struct pipe_screen *screen,
if(tex->key.format == SVGA3D_FORMAT_INVALID)
goto error2;
- tex->key.cachable = 1;
-
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
if (tex->handle)
@@ -416,6 +422,62 @@ svga_texture_blanket(struct pipe_screen * screen,
}
+struct pipe_texture *
+svga_screen_texture_wrap_surface(struct pipe_screen *screen,
+ struct pipe_texture *base,
+ enum SVGA3dSurfaceFormat format,
+ struct svga_winsys_surface *srf)
+{
+ struct svga_texture *tex;
+ assert(screen);
+
+ /* Only supports one type */
+ if (base->target != PIPE_TEXTURE_2D ||
+ base->last_level != 0 ||
+ base->depth0 != 1) {
+ return NULL;
+ }
+
+ if (!srf)
+ return NULL;
+
+ if (svga_translate_format(base->format) != format) {
+ unsigned f1 = svga_translate_format(base->format);
+ unsigned f2 = 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 (format == 1)
+ tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ else if (format == 2)
+ tex->base.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ pipe_reference_init(&tex->base.reference, 1);
+ tex->base.screen = screen;
+
+ SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
+
+ tex->key.cachable = 0;
+ tex->handle = srf;
+
+ return &tex->base;
+}
+
+
static void
svga_texture_destroy(struct pipe_texture *pt)
{
diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c
index cfdcae4ee4a..eda1aefd67a 100644
--- a/src/gallium/drivers/svga/svga_state_framebuffer.c
+++ b/src/gallium/drivers/svga/svga_state_framebuffer.c
@@ -32,8 +32,6 @@
#include "svga_cmd.h"
#include "svga_debug.h"
-#include "svga_hw_reg.h"
-
/***********************************************************************
* Hardware state update
diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c
index 8b6803a285a..2f9adaeb561 100644
--- a/src/gallium/drivers/svga/svga_state_rss.c
+++ b/src/gallium/drivers/svga/svga_state_rss.c
@@ -31,9 +31,6 @@
#include "svga_state.h"
#include "svga_cmd.h"
-#include "svga_hw_reg.h"
-
-
struct rs_queue {
unsigned rs_count;
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index b3137945202..b3c9687b1a4 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -33,8 +33,6 @@
#include "svga_state.h"
#include "svga_cmd.h"
-#include "svga_hw_reg.h"
-
void svga_cleanup_tss_binding(struct svga_context *svga)
{
diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c
index b4f757a47a9..aafb3e26b0b 100644
--- a/src/gallium/drivers/svga/svga_swtnl_backend.c
+++ b/src/gallium/drivers/svga/svga_swtnl_backend.c
@@ -31,7 +31,6 @@
#include "pipe/p_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
-#include "util/u_simple_shaders.h"
#include "svga_context.h"
#include "svga_state.h"
@@ -87,13 +86,13 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render,
if (!svga_render->vbuf) {
svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size);
svga_render->vbuf = pipe_buffer_create(screen,
- 0,
+ 16,
PIPE_BUFFER_USAGE_VERTEX,
svga_render->vbuf_size);
if(!svga_render->vbuf) {
svga_context_flush(svga, NULL);
svga_render->vbuf = pipe_buffer_create(screen,
- 0,
+ 16,
PIPE_BUFFER_USAGE_VERTEX,
svga_render->vbuf_size);
assert(svga_render->vbuf);
@@ -123,7 +122,9 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render )
char *ptr = (char*)pipe_buffer_map(screen,
svga_render->vbuf,
PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
+ PIPE_BUFFER_USAGE_DISCARD |
+ PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
return ptr + svga_render->vbuf_offset;
}
@@ -259,14 +260,14 @@ svga_vbuf_render_draw( struct vbuf_render *render,
if (!svga_render->ibuf) {
svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size);
svga_render->ibuf = pipe_buffer_create(screen,
- 0,
+ 2,
PIPE_BUFFER_USAGE_VERTEX,
svga_render->ibuf_size);
svga_render->ibuf_offset = 0;
}
- pipe_buffer_write(screen, svga_render->ibuf,
- svga_render->ibuf_offset, 2 * nr_indices, indices);
+ pipe_buffer_write_nooverlap(screen, svga_render->ibuf,
+ svga_render->ibuf_offset, 2 * nr_indices, indices);
/* off to hardware */
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index 7655121bec1..5e6e30c7dfb 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -27,7 +27,6 @@
#include "draw/draw_vbuf.h"
#include "pipe/p_inlines.h"
#include "pipe/p_state.h"
-#include "util/u_memory.h"
#include "svga_context.h"
#include "svga_swtnl.h"
@@ -90,7 +89,7 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
PIPE_BUFFER_USAGE_CPU_READ);
assert(map);
draw_set_mapped_constant_buffer(
- draw, PIPE_SHADER_VERTEX,
+ draw, PIPE_SHADER_VERTEX, 0,
map,
svga->curr.cb[PIPE_SHADER_VERTEX]->size);
}
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 94b6ccc62dd..fe03e207fff 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -27,7 +27,6 @@
#include "draw/draw_vbuf.h"
#include "pipe/p_inlines.h"
#include "pipe/p_state.h"
-#include "util/u_memory.h"
#include "svga_context.h"
#include "svga_swtnl.h"
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
index 23b3ace7f30..1ae99067610 100644
--- a/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm20.c
@@ -29,9 +29,6 @@
#include "util/u_memory.h"
#include "svga_tgsi_emit.h"
-#include "svga_context.h"
-
-
static boolean ps20_input( struct svga_shader_emitter *emit,
diff --git a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
index d1c7336dec4..43fc0d32359 100644
--- a/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
+++ b/src/gallium/drivers/svga/svga_tgsi_decl_sm30.c
@@ -29,7 +29,6 @@
#include "util/u_memory.h"
#include "svga_tgsi_emit.h"
-#include "svga_context.h"
static boolean translate_vs_ps_semantic( struct tgsi_declaration_semantic semantic,
unsigned *usage,
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 59f299c1858..27b99fe4c10 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -296,4 +296,10 @@ svga_screen_buffer_from_texture(struct pipe_texture *texture,
struct pipe_buffer **buffer,
unsigned *stride);
+struct pipe_texture *
+svga_screen_texture_wrap_surface(struct pipe_screen *screen,
+ struct pipe_texture *base,
+ enum SVGA3dSurfaceFormat format,
+ struct svga_winsys_surface *srf);
+
#endif /* SVGA_WINSYS_H_ */
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 48d1c4051cc..e7ca3a86ead 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -173,6 +173,7 @@ trace_drm_create(struct drm_api *api)
if (!tr_api)
goto error;
+ tr_api->base.driver_name = api->driver_name;
tr_api->base.create_screen = trace_drm_create_screen;
tr_api->base.create_context = trace_drm_create_context;
tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index 32f61f8c944..dbca5de0a52 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -323,9 +323,23 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_
trace_dump_struct_end();
}
+static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state)
+{
+ trace_dump_member(uint, state, rgb_func);
+ trace_dump_member(uint, state, rgb_src_factor);
+ trace_dump_member(uint, state, rgb_dst_factor);
+
+ trace_dump_member(uint, state, alpha_func);
+ trace_dump_member(uint, state, alpha_src_factor);
+ trace_dump_member(uint, state, alpha_dst_factor);
+
+ trace_dump_member(uint, state, colormask);
+
+}
void trace_dump_blend_state(const struct pipe_blend_state *state)
{
+ unsigned valid_entries = 1;
if (!trace_dumping_enabled_locked())
return;
@@ -336,21 +350,17 @@ void trace_dump_blend_state(const struct pipe_blend_state *state)
trace_dump_struct_begin("pipe_blend_state");
- trace_dump_member(bool, state, blend_enable);
-
- trace_dump_member(uint, state, rgb_func);
- trace_dump_member(uint, state, rgb_src_factor);
- trace_dump_member(uint, state, rgb_dst_factor);
-
- trace_dump_member(uint, state, alpha_func);
- trace_dump_member(uint, state, alpha_src_factor);
- trace_dump_member(uint, state, alpha_dst_factor);
+ trace_dump_member(bool, state, dither);
trace_dump_member(bool, state, logicop_enable);
trace_dump_member(uint, state, logicop_func);
- trace_dump_member(uint, state, colormask);
- trace_dump_member(bool, state, dither);
+ trace_dump_member(bool, state, independent_blend_enable);
+
+ if (state->independent_blend_enable)
+ valid_entries = PIPE_MAX_COLOR_BUFS;
+
+ trace_dump_struct_array(rt_blend_state, state->rt, valid_entries);
trace_dump_struct_end();
}
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 18ebd0c9483..6a9018aa3a0 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -63,7 +63,7 @@
#include <stdbool.h>
-#ifndef __HAIKU__
+#if !defined(__HAIKU__) && !defined(__USE_MISC)
typedef unsigned int uint;
typedef unsigned short ushort;
#endif
@@ -104,7 +104,8 @@ typedef unsigned char boolean;
/* Function visibility */
#ifndef PUBLIC
-# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
+# if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \
+ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define PUBLIC __attribute__((visibility("default")))
# else
# define PUBLIC
@@ -140,7 +141,7 @@ typedef unsigned char boolean;
/* Macros for data alignment. */
-#if defined(__GNUC__)
+#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
/* See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Type-Attributes.html */
#define PIPE_ALIGN_TYPE(_alignment, _type) _type __attribute__((aligned(_alignment)))
@@ -162,6 +163,13 @@ typedef unsigned char boolean;
#define PIPE_ALIGN_STACK
+#elif defined(SWIG)
+
+#define PIPE_ALIGN_TYPE(_alignment, _type) _type
+#define PIPE_ALIGN_VAR(_alignment)
+
+#define PIPE_ALIGN_STACK
+
#else
#error "Unsupported compiler"
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 0b8f6da2f4a..f1e6a60e041 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -103,7 +103,7 @@ struct pipe_context {
/**
* Predicate subsequent rendering on occlusion query result
* \param query the query predicate, or NULL if no predicate
- * \param mode one of PIPE_COND_RENDER_x
+ * \param mode one of PIPE_RENDER_COND_x
*/
void (*render_condition)( struct pipe_context *pipe,
struct pipe_query *query,
@@ -122,6 +122,11 @@ struct pipe_context {
void (*begin_query)(struct pipe_context *pipe, struct pipe_query *q);
void (*end_query)(struct pipe_context *pipe, struct pipe_query *q);
+ /**
+ * Get results of a query.
+ * \param wait if true, this query will block until the result is ready
+ * \return TRUE if results are ready, FALSE otherwise
+ */
boolean (*get_query_result)(struct pipe_context *pipe,
struct pipe_query *q,
boolean wait,
@@ -271,30 +276,30 @@ struct pipe_context {
/**
* Check whether a texture is referenced by an unflushed hw command.
- * The state-tracker uses this function to optimize away unnecessary
- * flushes. It is safe (but wasteful) to always return.
+ * The state-tracker uses this function to avoid unnecessary flushes.
+ * It is safe (but wasteful) to always return
* PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
- * \param pipe The pipe context whose unflushed hw commands will be
- * checked.
- * \param level mipmap level.
+ * \param pipe context whose unflushed hw commands will be checked.
* \param texture texture to check.
* \param face cubemap face. Use 0 for non-cubemap texture.
+ * \param level mipmap level.
+ * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
*/
- unsigned int (*is_texture_referenced) (struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level);
+ unsigned int (*is_texture_referenced)(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level);
/**
* Check whether a buffer is referenced by an unflushed hw command.
- * The state-tracker uses this function to optimize away unnecessary
- * flushes. It is safe (but wasteful) to always return
+ * The state-tracker uses this function to avoid unnecessary flushes.
+ * It is safe (but wasteful) to always return
* PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
- * \param pipe The pipe context whose unflushed hw commands will be
- * checked.
- * \param buf Buffer to check.
+ * \param pipe context whose unflushed hw commands will be checked.
+ * \param buf buffer to check.
+ * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
*/
- unsigned int (*is_buffer_referenced) (struct pipe_context *pipe,
- struct pipe_buffer *buf);
+ unsigned int (*is_buffer_referenced)(struct pipe_context *pipe,
+ struct pipe_buffer *buf);
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 35f3830ebcf..63ba3119b81 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -377,7 +377,7 @@ enum pipe_transfer_usage {
#define PIPE_CAP_NPOT_TEXTURES 2
#define PIPE_CAP_TWO_SIDED_STENCIL 3
#define PIPE_CAP_GLSL 4 /* XXX need something better */
-#define PIPE_CAP_S3TC 5 /* XXX: deprecated; cap determined via supported sampler formats */
+#define PIPE_CAP_DUAL_SOURCE_BLEND 5
#define PIPE_CAP_ANISOTROPIC_FILTER 6
#define PIPE_CAP_POINT_SPRITE 7
#define PIPE_CAP_MAX_RENDER_TARGETS 8
@@ -405,6 +405,14 @@ enum pipe_transfer_usage {
#define PIPE_CAP_MAX_PREDICATE_REGISTERS 30
#define PIPE_CAP_MAX_COMBINED_SAMPLERS 31 /*< Maximum texture image units accessible from vertex
and fragment shaders combined */
+#define PIPE_CAP_MAX_CONST_BUFFERS 32
+#define PIPE_CAP_MAX_CONST_BUFFER_SIZE 33 /*< In bytes */
+#define PIPE_CAP_INDEP_BLEND_ENABLE 34 /*< blend enables and write masks per rendertarget */
+#define PIPE_CAP_INDEP_BLEND_FUNC 35 /*< different blend funcs per rendertarget */
+#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT 36
+#define PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT 37
+#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 38
+#define PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER 39
/**
diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h
index 5fbd62a03d2..72f5c1dc2a2 100644
--- a/src/gallium/include/pipe/p_inlines.h
+++ b/src/gallium/include/pipe/p_inlines.h
@@ -63,13 +63,6 @@ pipe_buffer_map(struct pipe_screen *screen,
if(screen->buffer_map_range) {
unsigned offset = 0;
unsigned length = buf->size;
-
- /* XXX: Actually we should be using/detecting DISCARD
- * instead of assuming that WRITE implies discard */
- if((usage & PIPE_BUFFER_USAGE_CPU_WRITE) &&
- !(usage & PIPE_BUFFER_USAGE_DISCARD))
- usage |= PIPE_BUFFER_USAGE_CPU_READ;
-
return screen->buffer_map_range(screen, buf, offset, length, usage);
}
else
@@ -126,7 +119,39 @@ pipe_buffer_write(struct pipe_screen *screen,
map = pipe_buffer_map_range(screen, buf, offset, size,
PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
+ PIPE_BUFFER_USAGE_DISCARD);
+ assert(map);
+ if(map) {
+ memcpy((uint8_t *)map + offset, data, size);
+ pipe_buffer_flush_mapped_range(screen, buf, offset, size);
+ pipe_buffer_unmap(screen, buf);
+ }
+}
+
+/**
+ * Special case for writing non-overlapping ranges.
+ *
+ * We can avoid GPU/CPU synchronization when writing range that has never
+ * been written before.
+ */
+static INLINE void
+pipe_buffer_write_nooverlap(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned offset, unsigned size,
+ const void *data)
+{
+ void *map;
+
+ assert(offset < buf->size);
+ assert(offset + size <= buf->size);
+ assert(size);
+
+ map = pipe_buffer_map_range(screen, buf, offset, size,
+ PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
+ PIPE_BUFFER_USAGE_DISCARD |
+ PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
assert(map);
if(map) {
memcpy((uint8_t *)map + offset, data, size);
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index b489b044667..21581a4674f 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -109,10 +109,11 @@ struct tgsi_declaration
unsigned File : 4; /**< one of TGSI_FILE_x */
unsigned UsageMask : 4; /**< bitmask of TGSI_WRITEMASK_x flags */
unsigned Interpolate : 4; /**< one of TGSI_INTERPOLATE_x */
+ unsigned Dimension : 1; /**< any extra dimension info? */
unsigned Semantic : 1; /**< BOOL, any semantic info? */
unsigned Centroid : 1; /**< centroid sampling? */
unsigned Invariant : 1; /**< invariant optimization? */
- unsigned Padding : 5;
+ unsigned Padding : 4;
};
struct tgsi_declaration_range
@@ -121,6 +122,12 @@ struct tgsi_declaration_range
unsigned Last : 16; /**< UINT */
};
+struct tgsi_declaration_dimension
+{
+ unsigned Index2D:16; /**< UINT */
+ unsigned Padding:16;
+};
+
#define TGSI_SEMANTIC_POSITION 0
#define TGSI_SEMANTIC_COLOR 1
#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */
@@ -163,7 +170,9 @@ union tgsi_immediate_data
#define TGSI_PROPERTY_GS_INPUT_PRIM 0
#define TGSI_PROPERTY_GS_OUTPUT_PRIM 1
#define TGSI_PROPERTY_GS_MAX_VERTICES 2
-#define TGSI_PROPERTY_COUNT 3
+#define TGSI_PROPERTY_FS_COORD_ORIGIN 3
+#define TGSI_PROPERTY_FS_COORD_PIXEL_CENTER 4
+#define TGSI_PROPERTY_COUNT 5
struct tgsi_property {
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_PROPERTY */
@@ -172,6 +181,12 @@ struct tgsi_property {
unsigned Padding : 12;
};
+#define TGSI_FS_COORD_ORIGIN_UPPER_LEFT 0
+#define TGSI_FS_COORD_ORIGIN_LOWER_LEFT 1
+
+#define TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER 0
+#define TGSI_FS_COORD_PIXEL_CENTER_INTEGER 1
+
struct tgsi_property_data {
unsigned Data;
};
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index fdd29ed4492..03cd74efed3 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -58,7 +58,7 @@ extern "C" {
#define PIPE_MAX_ATTRIBS 32
#define PIPE_MAX_CLIP_PLANES 6
#define PIPE_MAX_COLOR_BUFS 8
-#define PIPE_MAX_CONSTANT 32
+#define PIPE_MAX_CONSTANT_BUFFERS 32
#define PIPE_MAX_SAMPLERS 16
#define PIPE_MAX_VERTEX_SAMPLERS 16
#define PIPE_MAX_SHADER_INPUTS 16
@@ -217,7 +217,7 @@ struct pipe_depth_stencil_alpha_state
};
-struct pipe_blend_state
+struct pipe_rt_blend_state
{
unsigned blend_enable:1;
@@ -229,11 +229,16 @@ struct pipe_blend_state
unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */
unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
+ unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */
+};
+
+struct pipe_blend_state
+{
+ unsigned independent_blend_enable:1;
unsigned logicop_enable:1;
unsigned logicop_func:4; /**< PIPE_LOGICOP_x */
-
- unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */
unsigned dither:1;
+ struct pipe_rt_blend_state rt[PIPE_MAX_COLOR_BUFS];
};
@@ -269,7 +274,7 @@ struct pipe_sampler_state
unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */
unsigned compare_func:3; /**< PIPE_FUNC_x */
unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */
- unsigned prefilter:4; /**< Wierd sampling state exposed by some api's */
+ unsigned prefilter:4; /**< Cylindrical texcoord wrap, per coord, exposed by some api's */
float lod_bias; /**< LOD/lambda bias */
float min_lod, max_lod; /**< LOD clamp range, after bias */
float border_color[4];
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index bb928928c90..b248a818808 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -31,6 +31,11 @@ struct drm_api
const char *name;
/**
+ * Kernel driver name, as accepted by drmOpenByName.
+ */
+ const char *driver_name;
+
+ /**
* Special buffer functions
*/
/*@{*/
diff --git a/src/gallium/state_trackers/Makefile b/src/gallium/state_trackers/Makefile
index 265ca468c2d..0900efc664f 100644
--- a/src/gallium/state_trackers/Makefile
+++ b/src/gallium/state_trackers/Makefile
@@ -21,5 +21,9 @@ clean:
rm -f `find . -name depend`
-# Dummy install target
install:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index f2e5f3fb23c..07f0554cc0d 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -101,6 +101,12 @@ dri_destroy_context(__DRIcontext * cPriv)
{
struct dri_context *ctx = dri_context(cPriv);
+ /* note: we are freeing values and nothing more because
+ * driParseConfigFiles allocated values only - the rest
+ * is owned by screen optionCache.
+ */
+ FREE(ctx->optionCache.values);
+
/* No particular reason to wait for command completion before
* destroying a context, but it is probably worthwhile flushing it
* to avoid having to add code elsewhere to cope with flushing a
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 0fdfa96b35a..1f456cb8297 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -35,7 +35,6 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
#include "main/mtypes.h"
#include "main/renderbuffer.h"
#include "state_tracker/drm_api.h"
@@ -123,11 +122,12 @@ dri_get_buffers(__DRIdrawable * dPriv)
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *surface = NULL;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ 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 = ((struct dri_screen*)(dri_screen->private))->api;
+ struct drm_api *api = st_screen->api;
boolean have_depth = FALSE;
int i, count;
@@ -180,7 +180,9 @@ dri_get_buffers(__DRIdrawable * dPriv)
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
- continue;
+ if (!st_screen->auto_fake_front)
+ continue;
+ /* fallthrough */
case __DRI_BUFFER_FAKE_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = drawable->color_format;
@@ -373,8 +375,8 @@ dri_create_buffer(__DRIscreen * sPriv,
/* TODO incase of double buffer visual, delay fake creation */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_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)
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 8b014a2a8b8..1259813a412 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -50,6 +50,7 @@
#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
@@ -98,6 +99,7 @@ static const struct dri_extension card_extensions[] = {
{"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},
@@ -130,6 +132,9 @@ 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);
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 793db087ee1..a412b81256e 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -37,14 +37,10 @@
#include "dri_context.h"
#include "dri_drawable.h"
-#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
#include "pipe/p_format.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_cb_fbo.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
@@ -83,7 +79,7 @@ dri_fill_in_modes(struct dri_screen *screen,
unsigned num_modes;
uint8_t depth_bits_array[5];
uint8_t stencil_bits_array[5];
- uint8_t msaa_samples_array[1];
+ uint8_t msaa_samples_array[2];
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
unsigned msaa_samples_factor;
@@ -147,8 +143,9 @@ dri_fill_in_modes(struct dri_screen *screen,
}
msaa_samples_array[0] = 0;
+ msaa_samples_array[1] = 4;
back_buffer_factor = 3;
- msaa_samples_factor = 1;
+ msaa_samples_factor = 2;
num_modes =
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
@@ -158,7 +155,7 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array, msaa_samples_factor);
} else {
__DRIconfig **configs_a8r8g8b8 = NULL;
__DRIconfig **configs_x8r8g8b8 = NULL;
@@ -170,7 +167,8 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array,
+ msaa_samples_factor);
if (pf_x8r8g8b8)
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
@@ -178,7 +176,8 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array,
+ msaa_samples_factor);
if (configs_a8r8g8b8 && configs_x8r8g8b8)
configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
@@ -289,6 +288,8 @@ dri_init_screen2(__DRIscreen * sPriv)
{
struct dri_screen *screen;
struct drm_create_screen_arg arg;
+ const __DRIdri2LoaderExtension *dri2_ext =
+ sPriv->dri2.loader;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -314,6 +315,9 @@ dri_init_screen2(__DRIscreen * sPriv)
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
+ screen->auto_fake_front = dri2_ext->base.version >= 3 &&
+ dri2_ext->getBuffersWithFormat != NULL;
+
return dri_fill_in_modes(screen, 32);
fail:
return NULL;
@@ -323,8 +327,18 @@ 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);
+
FREE(screen);
sPriv->private = NULL;
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 03387a0e813..75a0ee4250e 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -59,6 +59,7 @@ struct dri_screen
struct pipe_screen *pipe_screen;
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
+ boolean auto_fake_front;
};
/** cast wrapper */
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index e825aa718b6..b696f2fae93 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -1,19 +1,75 @@
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = egldrm
-
-LIBRARY_INCLUDES = \
+common_INCLUDES = \
+ -I. \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/mesa/drivers/dri/common \
- -I$(TOP)/src/mesa \
- -I$(TOP)/include \
-I$(TOP)/src/egl/main \
+ -I$(TOP)/include
+
+common_SOURCES = $(wildcard common/*.c)
+common_OBJECTS = $(common_SOURCES:.c=.o)
+
+
+x11_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/glx/x11 \
+ -I$(TOP)/src/egl/drivers/xdri \
+ -I$(TOP)/src/mesa \
$(shell pkg-config --cflags-only-I libdrm)
+x11_SOURCES = $(wildcard x11/*.c) \
+ $(TOP)/src/glx/x11/dri2.c \
+ $(TOP)/src/egl/drivers/xdri/glxinit.c
+x11_OBJECTS = $(x11_SOURCES:.c=.o)
+
+
+kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm)
+kms_SOURCES = $(wildcard kms/*.c)
+kms_OBJECTS = $(kms_SOURCES:.c=.o)
+
+
+ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES)
+ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES)
+ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS)
+
+##### TARGETS #####
+
+EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a)
+
+default: depend $(EGL_DISPLAYS_MODS)
+
+
+libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile
+ $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS)
+
+libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile
+ $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS)
+
+depend:
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+clean:
+ rm -f $(ALL_OBJECTS)
+ rm -f $(EGL_DISPLAYS_MODS)
+ rm -f depend depend.bak
+
+# Dummy target
+install:
+ @echo -n ""
+
+##### RULES #####
+
+$(common_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-C_SOURCES = $(wildcard ./*.c)
+$(x11_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+$(kms_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-include ../../Makefile.template
+sinclude depend
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 51da8e19f5e..6c8f3b9f79c 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -26,6 +26,7 @@
#include <string.h>
#include "pipe/p_screen.h"
#include "util/u_memory.h"
+#include "util/u_rect.h"
#include "egldriver.h"
#include "eglcurrent.h"
#include "eglconfigutil.h"
@@ -44,8 +45,13 @@ 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);
- EGLint num_surfaces;
- EGLint s, i;
+ 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;
@@ -53,6 +59,7 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
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);
@@ -66,30 +73,31 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!gctx->force_validate) {
unsigned int seq_num;
- gsurf->native->validate(gsurf->native,
- gbuf->native_atts, gbuf->num_atts,
+ gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
&seq_num, NULL, NULL, NULL);
/* skip validation */
if (gsurf->sequence_number == seq_num)
continue;
}
- gsurf->native->validate(gsurf->native,
- gbuf->native_atts, gbuf->num_atts,
+ 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 (i = 0; i < gbuf->num_atts; i++) {
- struct pipe_texture *pt = textures[i];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *pt = textures[att];
struct pipe_surface *ps;
- if (pt) {
+ 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,
- gbuf->st_atts[i], ps);
+ st_att_map[att], ps);
- if (gbuf->native_atts[i] == gsurf->render_att)
+ if (gsurf->render_att == att)
pipe_surface_reference(&gsurf->render_surface, ps);
pipe_surface_reference(&ps, NULL);
@@ -128,13 +136,7 @@ static void
egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
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 s, i;
+ EGLint s;
/* route draw and read buffers' attachments */
for (s = 0; s < 2; s++) {
@@ -150,11 +152,7 @@ egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
gbuf = &gctx->read;
}
- gbuf->native_atts[0] = gsurf->render_att;
- gbuf->num_atts = 1;
-
- for (i = 0; i < gbuf->num_atts; i++)
- gbuf->st_atts[i] = st_att_map[gbuf->native_atts[i]];
+ 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,
@@ -196,19 +194,19 @@ egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!gdraw || priv != (void *) &gdraw->base) {
gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
gctx->draw.st_fb = NULL;
- gctx->draw.num_atts = 0;
+ gctx->draw.attachment_mask = 0x0;
}
if (is_equal) {
gctx->read.st_fb = NULL;
- gctx->draw.num_atts = 0;
+ 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.num_atts = 0;
+ gctx->draw.attachment_mask = 0x0;
}
}
}
@@ -246,17 +244,6 @@ egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
}
/**
- * Return the current context of the given API.
- */
-static struct egl_g3d_context *
-egl_g3d_get_current_context(EGLint api)
-{
- _EGLThreadInfo *t = _eglGetCurrentThread();
- EGLint api_index = _eglConvertApiToIndex(api);
- return egl_g3d_context(t->CurrentContexts[api_index]);
-}
-
-/**
* Return the state tracker for the given context.
*/
static const struct egl_g3d_st *
@@ -297,6 +284,71 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
/**
+ * Initialize the state trackers.
+ */
+static void
+egl_g3d_init_st(_EGLDriver *drv)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ EGLint i;
+
+ /* already initialized */
+ if (gdrv->api_mask)
+ return;
+
+ for (i = 0; i < NUM_EGL_G3D_STS; i++) {
+ gdrv->stapis[i] = egl_g3d_get_st(i);
+ if (gdrv->stapis[i])
+ gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+ }
+
+ if (gdrv->api_mask)
+ _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
+ else
+ _eglLog(_EGL_WARNING, "No supported client API");
+}
+
+/**
+ * Get the probe object of the display.
+ *
+ * Note that this function may be called before the display is initialized.
+ */
+static struct native_probe *
+egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct native_probe *nprobe;
+
+ nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
+ if (!nprobe || nprobe->display != dpy->NativeDisplay) {
+ if (nprobe)
+ nprobe->destroy(nprobe);
+ nprobe = native_create_probe(dpy->NativeDisplay);
+ _eglSetProbeCache(gdrv->probe_key, (void *) nprobe);
+ }
+
+ return nprobe;
+}
+
+/**
+ * Destroy the probe object of the display. The display may be NULL.
+ *
+ * Note that this function may be called before the display is initialized.
+ */
+static void
+egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct native_probe *nprobe;
+
+ nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
+ if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) {
+ nprobe->destroy(nprobe);
+ _eglSetProbeCache(gdrv->probe_key, NULL);
+ }
+}
+
+/**
* Return an API mask that consists of the state trackers that supports the
* given mode.
*
@@ -412,18 +464,18 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
struct egl_g3d_config *gconf;
EGLBoolean valid;
+ gconf = CALLOC_STRUCT(egl_g3d_config);
+ if (!gconf)
+ continue;
+
+ _eglInitConfig(&gconf->base, 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);
- continue;
}
- gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
-
- _eglInitConfig(&gconf->base, id);
valid = _eglConfigFromContextModesRec(&gconf->base,
&native_configs[i]->mode, api_mask, api_mask);
if (valid) {
@@ -480,7 +532,7 @@ egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
* Set force_validate to skip an unnecessary check.
*/
gctx->force_validate = EGL_TRUE;
- egl_g3d_validate_context(gctx->base.Display, &gctx->base);
+ egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
}
static EGLBoolean
@@ -517,6 +569,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy;
+ /* the probe object is unlikely to be needed again */
+ egl_g3d_destroy_probe(drv, dpy);
+
gdpy = CALLOC_STRUCT(egl_g3d_display);
if (!gdpy) {
_eglError(EGL_BAD_ALLOC, "eglInitialize");
@@ -533,6 +588,7 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *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;
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
@@ -605,21 +661,30 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return &gctx->base;
}
-static EGLBoolean
-egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+/**
+ * Destroy a context.
+ */
+static void
+destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- if (_eglIsContextBound(&gctx->base))
- return EGL_TRUE;
+ /* FIXME a context might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
egl_g3d_realloc_context(dpy, &gctx->base);
-
- /* it will destroy pipe context */
+ /* it will destroy the associated pipe context */
gctx->stapi->st_destroy_context(gctx->st_ctx);
free(gctx);
+}
+static EGLBoolean
+egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ if (!_eglIsContextBound(ctx))
+ destroy_context(dpy, ctx);
return EGL_TRUE;
}
@@ -628,7 +693,7 @@ init_surface_geometry(_EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- return gsurf->native->validate(gsurf->native, NULL, 0,
+ return gsurf->native->validate(gsurf->native, 0x0,
&gsurf->sequence_number, NULL,
&gsurf->base.Width, &gsurf->base.Height);
}
@@ -750,17 +815,28 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return &gsurf->base;
}
-static EGLBoolean
-egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+/**
+ * Destroy a surface.
+ */
+static void
+destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- if (_eglIsSurfaceBound(&gsurf->base))
- return EGL_TRUE;
+ /* FIXME a surface might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
pipe_surface_reference(&gsurf->render_surface, NULL);
gsurf->native->destroy(gsurf->native);
free(gsurf);
+}
+
+static EGLBoolean
+egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ if (!_eglIsSurfaceBound(surf))
+ destroy_surface(dpy, surf);
return EGL_TRUE;
}
@@ -769,18 +845,14 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
{
struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
struct egl_g3d_context *old_gctx;
- EGLint api;
EGLBoolean ok = EGL_TRUE;
- /* find the old context */
- api = (gctx) ? gctx->base.ClientAPI : eglQueryAPI();
- old_gctx = egl_g3d_get_current_context(api);
- if (old_gctx && !_eglIsContextLinked(&old_gctx->base))
- old_gctx = NULL;
-
- if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &draw, &read))
return EGL_FALSE;
+ old_gctx = egl_g3d_context(ctx);
if (old_gctx) {
/* flush old context */
@@ -796,8 +868,6 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
}
if (gctx) {
- struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
-
ok = egl_g3d_realloc_context(dpy, &gctx->base);
if (ok) {
ok = gctx->stapi->st_make_current(gctx->st_ctx,
@@ -817,6 +887,13 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
+ if (ctx && !_eglIsContextLinked(ctx))
+ destroy_context(dpy, ctx);
+ if (draw && !_eglIsSurfaceLinked(draw))
+ destroy_surface(dpy, draw);
+ if (read && read != draw && !_eglIsSurfaceLinked(read))
+ destroy_surface(dpy, read);
+
return ok;
}
@@ -864,6 +941,101 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;
}
+/**
+ * Find a config that supports the pixmap.
+ */
+static _EGLConfig *
+find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf;
+ EGLint i;
+
+ for (i = 0; i < dpy->NumConfigs; i++) {
+ gconf = egl_g3d_config(dpy->Configs[i]);
+ if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
+ break;
+ }
+
+ return (i < dpy->NumConfigs) ? &gconf->base : NULL;
+}
+
+/**
+ * Get the pipe surface of the given attachment of the native surface.
+ */
+static struct pipe_surface *
+get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
+ enum native_attachment natt)
+{
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_surface *psurf;
+
+ textures[natt] = NULL;
+ nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
+ if (!textures[natt])
+ return NULL;
+
+ psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
+ 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
+ pipe_texture_reference(&textures[natt], NULL);
+
+ return psurf;
+}
+
+static EGLBoolean
+egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+ EGLNativePixmapType target)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_config *gconf;
+ struct native_surface *nsurf;
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_surface *psurf;
+
+ if (!gsurf->render_surface)
+ return EGL_TRUE;
+
+ gconf = egl_g3d_config(find_pixmap_config(dpy, target));
+ if (!gconf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ target, gconf->native);
+ if (!nsurf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ /* 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,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+ if (psurf) {
+ struct pipe_context pipe;
+
+ /**
+ * 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;
+
+ util_surface_copy(&pipe, FALSE, psurf, 0, 0,
+ gsurf->render_surface, 0, 0, psurf->width, psurf->height);
+
+ pipe_surface_reference(&psurf, NULL);
+ nsurf->flush_frontbuffer(nsurf);
+ }
+
+ nsurf->destroy(nsurf);
+
+ return EGL_TRUE;
+}
+
static EGLBoolean
egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
@@ -875,14 +1047,15 @@ egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
static EGLBoolean
egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
- _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
if (engine != EGL_CORE_NATIVE_ENGINE)
return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
- if (gsurf)
+ if (ctx && ctx->DrawSurface) {
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
gsurf->native->wait(gsurf->native);
+ }
return EGL_TRUE;
}
@@ -894,6 +1067,9 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
_EGLProc proc;
EGLint i;
+ /* 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];
if (stapi) {
@@ -911,7 +1087,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLSurface *surf, EGLint buffer)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct egl_g3d_context *gctx;
+ _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
enum pipe_format target_format;
int target;
@@ -942,14 +1119,12 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
}
/* flush properly if the surface is bound */
- if (gsurf->base.Binding) {
- gctx = egl_g3d_context(gsurf->base.Binding);
+ if (gsurf->base.CurrentContext) {
+ gctx = egl_g3d_context(gsurf->base.CurrentContext);
gctx->stapi->st_flush(gctx->st_ctx,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
- /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
- gctx = egl_g3d_get_current_context(EGL_OPENGL_API);
if (gctx) {
if (!gsurf->render_surface)
return EGL_FALSE;
@@ -975,10 +1150,8 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
if (gsurf->render_surface) {
- _EGLThreadInfo *t = _eglGetCurrentThread();
- /* XXX change to EGL_OPENGL_ES_API once OpenGL ES is merged */
- struct egl_g3d_context *gctx = egl_g3d_context(
- t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)]);
+ _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)
@@ -1084,10 +1257,41 @@ egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
#endif /* EGL_MESA_screen_surface */
+static EGLint
+egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct native_probe *nprobe;
+ enum native_probe_result res;
+ EGLint score;
+
+ nprobe = egl_g3d_get_probe(drv, dpy);
+ res = native_get_probe_result(nprobe);
+
+ switch (res) {
+ case NATIVE_PROBE_UNKNOWN:
+ default:
+ score = 0;
+ break;
+ case NATIVE_PROBE_FALLBACK:
+ score = 40;
+ break;
+ case NATIVE_PROBE_SUPPORTED:
+ score = 50;
+ break;
+ case NATIVE_PROBE_EXACT:
+ score = 100;
+ break;
+ }
+
+ return score;
+}
+
static void
egl_g3d_unload(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+
+ egl_g3d_destroy_probe(drv, NULL);
free(gdrv);
}
@@ -1096,7 +1300,6 @@ _eglMain(const char *args)
{
static char driver_name[64];
struct egl_g3d_driver *gdrv;
- EGLint i;
snprintf(driver_name, sizeof(driver_name),
"Gallium/%s", native_get_name());
@@ -1117,6 +1320,7 @@ _eglMain(const char *args)
gdrv->base.API.DestroySurface = egl_g3d_destroy_surface;
gdrv->base.API.MakeCurrent = egl_g3d_make_current;
gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers;
+ gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers;
gdrv->base.API.WaitClient = egl_g3d_wait_client;
gdrv->base.API.WaitNative = egl_g3d_wait_native;
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
@@ -1130,18 +1334,11 @@ _eglMain(const char *args)
#endif
gdrv->base.Name = driver_name;
+ gdrv->base.Probe = egl_g3d_probe;
gdrv->base.Unload = egl_g3d_unload;
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- gdrv->stapis[i] = egl_g3d_get_st(i);
- if (gdrv->stapis[i])
- gdrv->api_mask |= gdrv->stapis[i]->api_bit;
- }
-
- if (gdrv->api_mask)
- _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
- else
- _eglLog(_EGL_WARNING, "No supported client API");
+ /* the key is " EGL G3D" */
+ gdrv->probe_key = 0x0E61063D;
return &gdrv->base;
}
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 4c8b8dfe9e0..3dae8c40529 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -44,6 +44,8 @@ struct egl_g3d_driver {
_EGLDriver base;
const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
EGLint api_mask;
+
+ EGLint probe_key;
};
struct egl_g3d_display {
@@ -52,9 +54,7 @@ struct egl_g3d_display {
struct egl_g3d_buffer {
struct st_framebuffer *st_fb;
- EGLint num_atts;
- enum native_attachment native_atts[NUM_NATIVE_ATTACHMENTS];
- uint st_atts[NUM_NATIVE_ATTACHMENTS];
+ uint attachment_mask;
};
struct egl_g3d_context {
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c
index a88ff911cd5..a88ff911cd5 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_st.c
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h
index 8fb464bd3d7..8fb464bd3d7 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_st.h
diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 76f0e0c78ac..72a9cec7ef1 100644
--- a/src/gallium/state_trackers/egl_g3d/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -47,6 +47,27 @@ enum native_attachment {
NUM_NATIVE_ATTACHMENTS
};
+/**
+ * Enumerations for probe results.
+ */
+enum native_probe_result {
+ NATIVE_PROBE_UNKNOWN,
+ NATIVE_PROBE_FALLBACK,
+ NATIVE_PROBE_SUPPORTED,
+ NATIVE_PROBE_EXACT,
+};
+
+/**
+ * A probe object for display probe.
+ */
+struct native_probe {
+ int magic;
+ EGLNativeDisplayType display;
+ void *data;
+
+ void (*destroy)(struct native_probe *nprobe);
+};
+
struct native_surface {
void (*destroy)(struct native_surface *nsurf);
@@ -64,18 +85,18 @@ struct native_surface {
boolean (*flush_frontbuffer)(struct native_surface *nsurf);
/**
- * Validate the buffers of the surface. The returned textures are owned by
- * the caller. A sequence number is also returned. The caller can use it
- * to check if anything has changed since the last call. Any of the pointers
- * may be NULL and it indicates the caller has no interest in those values.
+ * Validate the buffers of the surface. textures, if not NULL, points to an
+ * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned
+ * by the caller. A sequence number is also returned. The caller can use
+ * it to check if anything has changed since the last call. Any of the
+ * pointers may be NULL and it indicates the caller has no interest in those
+ * values.
*
- * If this function is called multiple times with different attachments,
- * those not listed in the latest call might be destroyed. This behavior
- * might change in the future.
+ * If this function is called multiple times with different attachment
+ * masks, those not listed in the latest call might be destroyed. This
+ * behavior might change in the future.
*/
- boolean (*validate)(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
+ boolean (*validate)(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height);
@@ -136,6 +157,17 @@ struct native_display {
int *num_configs);
/**
+ * Test if a pixmap is supported by the given config. Required unless no
+ * config has GLX_PIXMAP_BIT set.
+ *
+ * This function is usually called to find a config that supports a given
+ * pixmap. Thus, it is usually called with the same pixmap in a row.
+ */
+ boolean (*is_pixmap_supported)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf);
+
+ /**
* Create a pipe context.
*/
struct pipe_context *(*create_context)(struct native_display *ndpy,
@@ -211,6 +243,31 @@ struct native_display_modeset {
const struct native_mode *nmode);
};
+/**
+ * Test whether an attachment is set in the mask.
+ */
+static INLINE boolean
+native_attachment_mask_test(uint mask, enum native_attachment att)
+{
+ return !!(mask & (1 << att));
+}
+
+/**
+ * Return a probe object for the given display.
+ *
+ * Note that the returned object may be cached and used by different native
+ * display modules. It allows fast probing when multiple modules probe the
+ * same display.
+ */
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy);
+
+/**
+ * Probe the probe object.
+ */
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe);
+
const char *
native_get_name(void);
diff --git a/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
index 507a0ec4027..507a0ec4027 100644
--- a/src/gallium/state_trackers/egl_g3d/common/st_public_tmp.h
+++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h
diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c
deleted file mode 100644
index fee186c6010..00000000000
--- a/src/gallium/state_trackers/egl/egl_context.c
+++ /dev/null
@@ -1,105 +0,0 @@
-
-#include "utils.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-
-#include "state_tracker/st_public.h"
-#include "state_tracker/drm_api.h"
-
-#include "GL/internal/glcore.h"
-
-_EGLContext *
-drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_context *ctx;
- struct drm_context *share = NULL;
- struct st_context *st_share = NULL;
- int i;
- __GLcontextModes *visual;
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- /* no attribs defined for now */
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
- }
-
- ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
- if (!ctx)
- goto err_c;
-
- _eglInitContext(drv, &ctx->base, conf, attrib_list);
-
- ctx->pipe = dev->api->create_context(dev->api, dev->screen);
- if (!ctx->pipe)
- goto err_pipe;
-
- if (share)
- st_share = share->st;
-
- visual = drm_visual_from_config(conf);
- ctx->st = st_create_context(ctx->pipe, visual, st_share);
- drm_visual_modes_destroy(visual);
-
- if (!ctx->st)
- goto err_gl;
-
- return &ctx->base;
-
-err_gl:
- ctx->pipe->destroy(ctx->pipe);
-err_pipe:
- free(ctx);
-err_c:
- return NULL;
-}
-
-EGLBoolean
-drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
-{
- struct drm_context *c = lookup_drm_context(context);
- if (!_eglIsContextBound(&c->base)) {
- st_destroy_context(c->st);
- free(c);
- }
- return EGL_TRUE;
-}
-
-EGLBoolean
-drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context)
-{
- struct drm_surface *readSurf = lookup_drm_surface(read);
- struct drm_surface *drawSurf = lookup_drm_surface(draw);
- struct drm_context *ctx = lookup_drm_context(context);
- EGLBoolean b;
-
- b = _eglMakeCurrent(drv, dpy, draw, read, context);
- if (!b)
- return EGL_FALSE;
-
- if (ctx) {
- if (!drawSurf || !readSurf)
- return EGL_FALSE;
-
- st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
-
- /* st_resize_framebuffer needs a bound context to work */
- st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
- st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
- } else {
- st_make_current(NULL, NULL, NULL);
- }
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
deleted file mode 100644
index d55aa51b82d..00000000000
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ /dev/null
@@ -1,443 +0,0 @@
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-#include "pipe/p_inlines.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_context.h"
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_format.h"
-#include "util/u_rect.h"
-
-/*
- * Util functions
- */
-
-static drmModeModeInfoPtr
-drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
-{
- int i;
- drmModeModeInfoPtr m = NULL;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
- break;
- m = &connector->modes[0]; /* if we can't find one, return first */
- }
-
- return m;
-}
-
-static struct st_framebuffer *
-drm_create_framebuffer(struct pipe_screen *screen,
- const __GLcontextModes *visual,
- unsigned width,
- unsigned height,
- void *priv)
-{
- enum pipe_format color_format, depth_stencil_format;
- boolean d_depth_bits_last;
- boolean ds_depth_bits_last;
-
- d_depth_bits_last =
- screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- ds_depth_bits_last =
- screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-
- if (visual->redBits == 8) {
- if (visual->alphaBits == 8)
- color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- else
- color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
- } else {
- color_format = PIPE_FORMAT_R5G6B5_UNORM;
- }
-
- switch(visual->depthBits) {
- default:
- case 0:
- depth_stencil_format = PIPE_FORMAT_NONE;
- break;
- case 16:
- depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
- break;
- case 24:
- if (visual->stencilBits == 0) {
- depth_stencil_format = (d_depth_bits_last) ?
- PIPE_FORMAT_X8Z24_UNORM:
- PIPE_FORMAT_Z24X8_UNORM;
- } else {
- depth_stencil_format = (ds_depth_bits_last) ?
- PIPE_FORMAT_S8Z24_UNORM:
- PIPE_FORMAT_Z24S8_UNORM;
- }
- break;
- case 32:
- depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- break;
- }
-
- return st_create_framebuffer(visual,
- color_format,
- depth_stencil_format,
- depth_stencil_format,
- width,
- height,
- priv);
-}
-
-static void
-drm_create_texture(_EGLDisplay *dpy,
- struct drm_screen *scrn,
- unsigned w, unsigned h)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct pipe_screen *screen = dev->screen;
- struct pipe_surface *surface;
- struct pipe_texture *texture;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
- unsigned pitch = 0;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth0 = 1;
- templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
- templat.width0 = w;
- templat.height0 = h;
-
- texture = screen->texture_create(dev->screen,
- &templat);
-
- if (!texture)
- goto err_tex;
-
- surface = screen->get_tex_surface(screen,
- texture,
- 0,
- 0,
- 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- if (!surface)
- goto err_surf;
-
- scrn->tex = texture;
- scrn->surface = surface;
- scrn->front.width = w;
- scrn->front.height = h;
- scrn->front.pitch = pitch;
- dev->api->local_handle_from_texture(dev->api, screen, texture,
- &scrn->front.pitch, &scrn->front.handle);
- if (0)
- goto err_handle;
-
- return;
-
-err_handle:
- pipe_surface_reference(&surface, NULL);
-err_surf:
- pipe_texture_reference(&texture, NULL);
-err_tex:
- pipe_buffer_reference(&buf, NULL);
- return;
-}
-
-/*
- * Exported functions
- */
-
-void
-drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
-
- screen->surf = NULL;
-
- drmModeSetCrtc(
- dev->drmFD,
- screen->crtcID,
- 0, /* FD */
- 0, 0,
- NULL, 0, /* List of output ids */
- NULL);
-
- drmModeRmFB(dev->drmFD, screen->fbID);
- drmModeFreeFB(screen->fb);
- screen->fb = NULL;
-
- pipe_surface_reference(&screen->surface, NULL);
- pipe_texture_reference(&screen->tex, NULL);
-
- screen->shown = 0;
-}
-
-/**
- * Called by libEGL's eglCreateWindowSurface().
- */
-_EGLSurface *
-drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Called by libEGL's eglCreatePixmapSurface().
- */
-_EGLSurface *
-drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Called by libEGL's eglCreatePbufferSurface().
- */
-_EGLSurface *
-drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- int i;
- int width = -1;
- int height = -1;
- struct drm_surface *surf = NULL;
- __GLcontextModes *visual;
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- width = attrib_list[++i];
- break;
- case EGL_HEIGHT:
- height = attrib_list[++i];
- break;
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
- }
-
- if (width < 1 || height < 1) {
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return NULL;
- }
-
- surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
- if (!surf)
- goto err;
-
- if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list))
- goto err_surf;
-
- surf->w = width;
- surf->h = height;
-
- visual = drm_visual_from_config(conf);
- surf->stfb = drm_create_framebuffer(dev->screen, visual,
- width, height,
- (void*)surf);
- drm_visual_modes_destroy(visual);
-
- return &surf->base;
-
-err_surf:
- free(surf);
-err:
- return NULL;
-}
-
-/**
- * Called by libEGL's eglCreateScreenSurfaceMESA().
- */
-_EGLSurface *
-drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg,
- const EGLint *attrib_list)
-{
- EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
-
- return surf;
-}
-
-/**
- * Called by libEGL's eglShowScreenSurfaceMESA().
- */
-EGLBoolean
-drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLScreen *screen,
- _EGLSurface *surface, _EGLMode *mode)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_surface *surf = lookup_drm_surface(surface);
- struct drm_screen *scrn = lookup_drm_screen(screen);
- int ret;
- unsigned int i, k;
-
- if (scrn->shown)
- drm_takedown_shown_screen(dpy, scrn);
-
-
- drm_create_texture(dpy, scrn, mode->Width, mode->Height);
- if (!scrn->tex)
- goto err_tex;
-
- ret = drmModeAddFB(dev->drmFD,
- scrn->front.width, scrn->front.height,
- 32, 32, scrn->front.pitch,
- scrn->front.handle,
- &scrn->fbID);
-
- if (ret)
- goto err_bo;
-
- scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID);
- if (!scrn->fb)
- goto err_bo;
-
- /* find a fitting crtc */
- {
- drmModeConnector *con = scrn->connector;
-
- scrn->mode = drm_find_mode(con, mode);
- if (!scrn->mode)
- goto err_fb;
-
- for (k = 0; k < con->count_encoders; k++) {
- drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]);
- for (i = 0; i < dev->res->count_crtcs; i++) {
- if (enc->possible_crtcs & (1<<i)) {
- /* save the ID */
- scrn->crtcID = dev->res->crtcs[i];
-
- /* skip the rest */
- i = dev->res->count_crtcs;
- k = dev->res->count_encoders;
- }
- }
- drmModeFreeEncoder(enc);
- }
- }
-
- ret = drmModeSetCrtc(dev->drmFD,
- scrn->crtcID,
- scrn->fbID,
- 0, 0,
- &scrn->connectorID, 1,
- scrn->mode);
-
- if (ret)
- goto err_crtc;
-
-
- if (scrn->dpms)
- drmModeConnectorSetProperty(dev->drmFD,
- scrn->connectorID,
- scrn->dpms->prop_id,
- DRM_MODE_DPMS_ON);
-
- surf->screen = scrn;
-
- scrn->surf = surf;
- scrn->shown = 1;
-
- return EGL_TRUE;
-
-err_crtc:
- scrn->crtcID = 0;
-
-err_fb:
- drmModeRmFB(dev->drmFD, scrn->fbID);
- drmModeFreeFB(scrn->fb);
- scrn->fb = NULL;
-
-err_bo:
- pipe_surface_reference(&scrn->surface, NULL);
- pipe_texture_reference(&scrn->tex, NULL);
-
-err_tex:
- return EGL_FALSE;
-}
-
-/**
- * Called by libEGL's eglDestroySurface().
- */
-EGLBoolean
-drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
-{
- struct drm_surface *surf = lookup_drm_surface(surface);
- if (!_eglIsSurfaceBound(&surf->base)) {
- if (surf->screen)
- drm_takedown_shown_screen(dpy, surf->screen);
- st_unreference_framebuffer(surf->stfb);
- free(surf);
- }
- return EGL_TRUE;
-}
-
-/**
- * Called by libEGL's eglSwapBuffers().
- */
-EGLBoolean
-drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_surface *surf = lookup_drm_surface(draw);
- struct pipe_surface *back_surf;
-
- if (!surf)
- return EGL_FALSE;
-
- st_get_framebuffer_surface(surf->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
-
- if (back_surf) {
- struct drm_context *ctx = lookup_drm_context(draw->Binding);
-
- st_notify_swapbuffers(surf->stfb);
-
- if (ctx && surf->screen) {
- if (ctx->pipe->surface_copy) {
- ctx->pipe->surface_copy(ctx->pipe,
- surf->screen->surface,
- 0, 0,
- back_surf,
- 0, 0,
- surf->w, surf->h);
- } else {
- util_surface_copy(ctx->pipe, FALSE,
- surf->screen->surface,
- 0, 0,
- back_surf,
- 0, 0,
- surf->w, surf->h);
- }
- ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
-
-#ifdef DRM_MODE_FEATURE_DIRTYFB
- /* TODO query connector property to see if this is needed */
- drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0);
-#else
- (void)dev;
-#endif
-
- /* TODO more stuff here */
- }
- }
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
deleted file mode 100644
index 9345b0f4908..00000000000
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ /dev/null
@@ -1,274 +0,0 @@
-
-#include "utils.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include <fcntl.h>
-
-#include "egllog.h"
-#include "state_tracker/drm_api.h"
-
-#include "pipe/p_screen.h"
-#include "pipe/internal/p_winsys_screen.h"
-
-/** HACK */
-void* driDriverAPI;
-
-
-/*
- * Exported functions
- */
-
-/** Called by libEGL just prior to unloading/closing the driver.
- */
-static void
-drm_unload(_EGLDriver *drv)
-{
- free(drv);
-}
-
-/**
- * The bootstrap function. Return a new drm_driver object and
- * plug in API functions.
- * libEGL finds this function with dlopen()/dlsym() and calls it from
- * "load driver" function.
- */
-_EGLDriver *
-_eglMain(const char *args)
-{
- _EGLDriver *drv;
-
- drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver));
- if (!drv) {
- return NULL;
- }
-
- /* First fill in the dispatch table with defaults */
- _eglInitDriverFallbacks(drv);
- /* then plug in our Drm-specific functions */
- drv->API.Initialize = drm_initialize;
- drv->API.Terminate = drm_terminate;
- drv->API.CreateContext = drm_create_context;
- drv->API.MakeCurrent = drm_make_current;
- drv->API.CreateWindowSurface = drm_create_window_surface;
- drv->API.CreatePixmapSurface = drm_create_pixmap_surface;
- drv->API.CreatePbufferSurface = drm_create_pbuffer_surface;
- drv->API.DestroySurface = drm_destroy_surface;
- drv->API.DestroyContext = drm_destroy_context;
- drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
- drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
- drv->API.SwapBuffers = drm_swap_buffers;
-
- drv->Name = "DRM/Gallium/Win";
- drv->Unload = drm_unload;
-
- return drv;
-}
-
-static void
-drm_get_device_id(struct drm_device *device)
-{
- char path[512];
- FILE *file;
- char *ret;
-
- /* TODO get the real minor */
- int minor = 0;
-
- device->deviceID = 0;
-
- snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
- file = fopen(path, "r");
- if (!file) {
- _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
- return;
- }
-
- ret = fgets(path, sizeof( path ), file);
- fclose(file);
- if (!ret)
- return;
-
- sscanf(path, "%x", &device->deviceID);
-}
-
-static void
-drm_update_res(struct drm_device *dev)
-{
- drmModeFreeResources(dev->res);
- dev->res = drmModeGetResources(dev->drmFD);
-}
-
-static void
-drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
-{
- drmModeModeInfoPtr m = NULL;
- int i;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
- }
-}
-
-static void
-drm_find_dpms(struct drm_device *dev, struct drm_screen *screen)
-{
- drmModeConnectorPtr c = screen->connector;
- drmModePropertyPtr p;
- int i;
-
- for (i = 0; i < c->count_props; i++) {
- p = drmModeGetProperty(dev->drmFD, c->props[i]);
- if (!strcmp(p->name, "DPMS"))
- break;
-
- drmModeFreeProperty(p);
- p = NULL;
- }
-
- screen->dpms = p;
-}
-
-static int drm_open_minor(int minor)
-{
- char buf[64];
-
- sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
- return open(buf, O_RDWR, 0);
-}
-
-EGLBoolean
-drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
-{
- struct drm_device *dev;
- struct drm_screen *screen = NULL;
- drmModeConnectorPtr connector = NULL;
- drmModeResPtr res = NULL;
- unsigned count_connectors = 0;
- int num_screens = 0;
- EGLint i;
- int fd;
- _EGLConfig *config;
-
- dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
- if (!dev)
- return EGL_FALSE;
- dev->api = drm_api_create();
-
- /* try the first node */
- fd = drm_open_minor(0);
- if (fd < 0)
- goto err_fd;
-
- dev->drmFD = fd;
- drm_get_device_id(dev);
-
- dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL);
- if (!dev->screen)
- goto err_screen;
- dev->winsys = dev->screen->winsys;
-
- driInitExtensions(NULL, NULL, GL_FALSE);
-
- drm_update_res(dev);
- res = dev->res;
- if (res)
- count_connectors = res->count_connectors;
- else
- _eglLog(_EGL_WARNING, "Could not retrive kms information\n");
-
- for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
- connector = drmModeGetConnector(fd, res->connectors[i]);
-
- if (!connector)
- continue;
-
- if (connector->connection != DRM_MODE_CONNECTED) {
- drmModeFreeConnector(connector);
- continue;
- }
-
- screen = malloc(sizeof(struct drm_screen));
- memset(screen, 0, sizeof(*screen));
- screen->connector = connector;
- screen->connectorID = connector->connector_id;
- _eglInitScreen(&screen->base);
- _eglAddScreen(disp, &screen->base);
- drm_add_modes_from_connector(&screen->base, connector);
- drm_find_dpms(dev, screen);
- dev->screens[num_screens++] = screen;
- }
- dev->count_screens = num_screens;
-
- disp->DriverData = dev;
-
- /* for now we only have one config */
- config = calloc(1, sizeof(*config));
- memset(config, 1, sizeof(*config));
- _eglInitConfig(config, 1);
- _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
- _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
- _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
- _eglAddConfig(disp, config);
-
- disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
- /* enable supported extensions */
- disp->Extensions.MESA_screen_surface = EGL_TRUE;
- disp->Extensions.MESA_copy_context = EGL_TRUE;
-
- *major = 1;
- *minor = 4;
-
- return EGL_TRUE;
-
-err_screen:
- drmClose(fd);
-err_fd:
- free(dev);
- return EGL_FALSE;
-}
-
-EGLBoolean
-drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_screen *screen;
- int i = 0;
-
- _eglReleaseDisplayResources(drv, dpy);
- _eglCleanupDisplay(dpy);
-
- drmFreeVersion(dev->version);
-
- for (i = 0; i < dev->count_screens; i++) {
- screen = dev->screens[i];
-
- if (screen->shown)
- drm_takedown_shown_screen(dpy, screen);
-
- drmModeFreeProperty(screen->dpms);
- drmModeFreeConnector(screen->connector);
- _eglDestroyScreen(&screen->base);
- dev->screens[i] = NULL;
- }
-
- dev->screen->destroy(dev->screen);
- dev->winsys = NULL;
-
- drmClose(dev->drmFD);
-
- dev->api->destroy(dev->api);
- free(dev);
- dpy->DriverData = NULL;
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h
deleted file mode 100644
index 73eb1a1226e..00000000000
--- a/src/gallium/state_trackers/egl/egl_tracker.h
+++ /dev/null
@@ -1,195 +0,0 @@
-
-#ifndef _EGL_TRACKER_H_
-#define _EGL_TRACKER_H_
-
-#include <stdint.h>
-
-#include "eglconfig.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglglobals.h"
-#include "eglmode.h"
-#include "eglscreen.h"
-#include "eglsurface.h"
-
-#include "xf86drm.h"
-#include "xf86drmMode.h"
-
-#include "pipe/p_compiler.h"
-
-#include "state_tracker/st_public.h"
-
-#define MAX_SCREENS 16
-
-struct pipe_winsys;
-struct pipe_screen;
-struct pipe_context;
-struct state_tracker;
-
-struct drm_screen;
-struct drm_context;
-
-struct drm_device
-{
- /*
- * pipe
- */
-
- struct drm_api *api;
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- /*
- * drm
- */
-
- int drmFD;
- drmVersionPtr version;
- int deviceID;
-
- drmModeResPtr res;
-
- struct drm_screen *screens[MAX_SCREENS];
- size_t count_screens;
-};
-
-struct drm_surface
-{
- _EGLSurface base; /* base class/object */
-
- /*
- * pipe
- */
-
-
- struct st_framebuffer *stfb;
-
- /*
- * drm
- */
-
- struct drm_screen *screen;
-
- int w;
- int h;
-};
-
-struct drm_context
-{
- _EGLContext base; /* base class/object */
-
- /* pipe */
-
- struct pipe_context *pipe;
- struct st_context *st;
-};
-
-struct drm_screen
-{
- _EGLScreen base;
-
- /*
- * pipe
- */
-
- struct pipe_texture *tex;
- struct pipe_surface *surface;
-
- /*
- * drm
- */
-
- struct {
- unsigned height;
- unsigned width;
- unsigned pitch;
- unsigned handle;
- } front;
-
- /* currently only support one connector */
- drmModeConnectorPtr connector;
- uint32_t connectorID;
-
- /* dpms property */
- drmModePropertyPtr dpms;
-
- /* Has this screen been shown */
- int shown;
-
- /* Surface that is currently attached to this screen */
- struct drm_surface *surf;
-
- /* framebuffer */
- drmModeFBPtr fb;
- uint32_t fbID;
-
- /* crtc and mode used */
- /*drmModeCrtcPtr crtc;*/
- uint32_t crtcID;
-
- drmModeModeInfoPtr mode;
-};
-
-
-static INLINE struct drm_device *
-lookup_drm_device(_EGLDisplay *d)
-{
- return (struct drm_device *) d->DriverData;
-}
-
-
-static INLINE struct drm_context *
-lookup_drm_context(_EGLContext *c)
-{
- return (struct drm_context *) c;
-}
-
-
-static INLINE struct drm_surface *
-lookup_drm_surface(_EGLSurface *s)
-{
- return (struct drm_surface *) s;
-}
-
-static INLINE struct drm_screen *
-lookup_drm_screen(_EGLScreen *s)
-{
- return (struct drm_screen *) s;
-}
-
-/**
- * egl_visual.h
- */
-/*@{*/
-void drm_visual_modes_destroy(__GLcontextModes *modes);
-__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size);
-__GLcontextModes* drm_visual_from_config(_EGLConfig *conf);
-/*@}*/
-
-/**
- * egl_surface.h
- */
-/*@{*/
-void drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen);
-/*@}*/
-
-/**
- * All function exported to the egl side.
- */
-/*@{*/
-EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
-EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy);
-_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
-EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context);
-_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
-_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
-_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
-EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
-EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context);
-EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
-/*@}*/
-
-#endif
diff --git a/src/gallium/state_trackers/egl/egl_visual.c b/src/gallium/state_trackers/egl/egl_visual.c
deleted file mode 100644
index e59f893851e..00000000000
--- a/src/gallium/state_trackers/egl/egl_visual.c
+++ /dev/null
@@ -1,85 +0,0 @@
-
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-void
-drm_visual_modes_destroy(__GLcontextModes *modes)
-{
- _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
-
- while (modes) {
- __GLcontextModes * const next = modes->next;
- free(modes);
- modes = next;
- }
-}
-
-__GLcontextModes *
-drm_visual_modes_create(unsigned count, size_t minimum_size)
-{
- /* This code copied from libGLX, and modified */
- const size_t size = (minimum_size > sizeof(__GLcontextModes))
- ? minimum_size : sizeof(__GLcontextModes);
- __GLcontextModes * head = NULL;
- __GLcontextModes ** next;
- unsigned i;
-
- _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
-
- next = & head;
- for (i = 0 ; i < count ; i++) {
- *next = (__GLcontextModes *) calloc(1, size);
- if (*next == NULL) {
- drm_visual_modes_destroy(head);
- head = NULL;
- break;
- }
-
- (*next)->doubleBufferMode = 1;
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = 0;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = & ((*next)->next);
- }
-
- return head;
-}
-
-__GLcontextModes *
-drm_visual_from_config(_EGLConfig *conf)
-{
- __GLcontextModes *visual;
- (void)conf;
-
- visual = drm_visual_modes_create(1, sizeof(*visual));
- visual->redBits = 8;
- visual->greenBits = 8;
- visual->blueBits = 8;
- visual->alphaBits = 8;
-
- visual->rgbBits = 32;
- visual->doubleBufferMode = 1;
-
- visual->depthBits = 24;
- visual->haveDepthBuffer = visual->depthBits > 0;
- visual->stencilBits = 8;
- visual->haveStencilBuffer = visual->stencilBits > 0;
-
- return visual;
-}
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index 65829fc7b3d..d5baf2c2f05 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -33,9 +33,7 @@
#include "native_kms.h"
static boolean
-kms_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
+kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height)
{
@@ -43,12 +41,9 @@ kms_surface_validate(struct native_surface *nsurf,
struct kms_display *kdpy = ksurf->kdpy;
struct pipe_screen *screen = kdpy->base.screen;
struct pipe_texture templ, *ptex;
- int i;
-
- if (num_natts) {
- if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
+ int att;
+ if (attachment_mask) {
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
@@ -62,17 +57,21 @@ kms_surface_validate(struct native_surface *nsurf,
}
/* create textures */
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
- ptex = ksurf->textures[natt];
+ ptex = ksurf->textures[att];
if (!ptex) {
ptex = screen->texture_create(screen, &templ);
- ksurf->textures[natt] = ptex;
+ ksurf->textures[att] = ptex;
}
- if (textures)
- pipe_texture_reference(&textures[i], ptex);
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], ptex);
+ }
}
if (seq_num)
@@ -113,7 +112,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
if (!fb->texture) {
/* make sure the texture has been allocated */
- kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL, NULL);
+ kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL);
if (!ksurf->textures[natt])
return FALSE;
@@ -821,6 +820,18 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
return &kdpy->base;
}
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ return NULL;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ return NATIVE_PROBE_UNKNOWN;
+}
+
/* the api is destroyed with the native display */
static struct drm_api *drm_api;
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index 095186e3cf3..095186e3cf3 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index f497d8c1c77..07f82d878c5 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -134,22 +134,18 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
}
static boolean
-dri2_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
- unsigned int *seq_num,
- struct pipe_texture **textures,
- int *width, int *height)
+dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
- EGLint texture_indices[NUM_NATIVE_ATTACHMENTS];
struct pipe_texture templ;
struct x11_drawable_buffer *xbufs;
- int num_ins, num_outs, i;
+ int num_ins, num_outs, att, i;
- if (num_natts) {
+ if (attachment_mask) {
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
@@ -160,24 +156,27 @@ dri2_surface_validate(struct native_surface *nsurf,
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
+ memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS);
}
/* create textures for pbuffer */
if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
struct pipe_screen *screen = dri2dpy->base.screen;
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
- struct pipe_texture *ptex = dri2surf->pbuffer_textures[natt];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *ptex = dri2surf->pbuffer_textures[att];
+
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
if (!ptex) {
ptex = screen->texture_create(screen, &templ);
- dri2surf->pbuffer_textures[natt] = ptex;
+ dri2surf->pbuffer_textures[att] = ptex;
}
if (textures)
- pipe_texture_reference(&textures[i], ptex);
+ pipe_texture_reference(&textures[att], ptex);
}
if (seq_num)
@@ -190,34 +189,34 @@ dri2_surface_validate(struct native_surface *nsurf,
return TRUE;
}
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
- texture_indices[i] = -1;
-
/* prepare the attachments */
- num_ins = num_natts;
- for (i = 0; i < num_natts; i++) {
- unsigned int dri2att;
+ num_ins = 0;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(attachment_mask, att)) {
+ unsigned int dri2att;
+
+ switch (att) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ dri2att = DRI2BufferFrontLeft;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ dri2att = DRI2BufferBackLeft;
+ break;
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ dri2att = DRI2BufferFrontRight;
+ break;
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ dri2att = DRI2BufferBackRight;
+ break;
+ default:
+ assert(0);
+ dri2att = 0;
+ break;
+ }
- switch (natts[i]) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- dri2att = DRI2BufferFrontLeft;
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- dri2att = DRI2BufferBackLeft;
- break;
- case NATIVE_ATTACHMENT_FRONT_RIGHT:
- dri2att = DRI2BufferFrontRight;
- break;
- case NATIVE_ATTACHMENT_BACK_RIGHT:
- dri2att = DRI2BufferBackRight;
- break;
- default:
- assert(0);
- dri2att = 0;
- break;
+ dri2atts[num_ins] = dri2att;
+ num_ins++;
}
- dri2atts[i] = dri2att;
- texture_indices[natts[i]] = i;
}
dri2surf->have_back = FALSE;
@@ -266,13 +265,13 @@ dri2_surface_validate(struct native_surface *nsurf,
break;
}
- if (!desc || texture_indices[natt] < 0 ||
- (textures && textures[texture_indices[natt]])) {
+ if (!desc || !native_attachment_mask_test(attachment_mask, natt) ||
+ (textures && textures[natt])) {
if (!desc)
_eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
- else if (texture_indices[natt] < 0)
+ else if (!native_attachment_mask_test(attachment_mask, natt))
_eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
- else if (textures && textures[texture_indices[natt]])
+ else
_eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
continue;
}
@@ -284,7 +283,7 @@ dri2_surface_validate(struct native_surface *nsurf,
desc, xbuf->pitch, xbuf->name);
if (ptex) {
/* the caller owns the textures */
- textures[texture_indices[natt]] = ptex;
+ textures[natt] = ptex;
}
}
}
@@ -589,6 +588,21 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
return configs;
}
+static boolean
+dri2_display_is_pixmap_supported(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ uint depth, nconf_depth;
+
+ depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
+ nconf_depth = util_format_get_blocksizebits(nconf->color_format);
+
+ /* simple depth match for now */
+ return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
+}
+
static void
dri2_display_destroy(struct native_display *ndpy)
{
@@ -681,6 +695,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
dri2dpy->base.destroy = dri2_display_destroy;
dri2dpy->base.get_configs = dri2_display_get_configs;
+ dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
dri2dpy->base.create_context = dri2_display_create_context;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 583ce3d3293..dd3c9f8b6ac 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -24,13 +24,90 @@
#include <string.h>
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
#include "egllog.h"
#include "native_x11.h"
+#include "x11_screen.h"
+
+#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
static struct drm_api *api;
+static void
+x11_probe_destroy(struct native_probe *nprobe)
+{
+ if (nprobe->data)
+ free(nprobe->data);
+ free(nprobe);
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ struct native_probe *nprobe;
+ struct x11_screen *xscr;
+ int scr;
+ const char *driver_name = NULL;
+ Display *xdpy;
+
+ nprobe = CALLOC_STRUCT(native_probe);
+ if (!nprobe)
+ return NULL;
+
+ xdpy = dpy;
+ if (!xdpy) {
+ xdpy = XOpenDisplay(NULL);
+ if (!xdpy) {
+ free(nprobe);
+ return NULL;
+ }
+ }
+
+ scr = DefaultScreen(xdpy);
+ xscr = x11_screen_create(xdpy, scr);
+ if (xscr) {
+ if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
+ driver_name = x11_screen_probe_dri2(xscr);
+ if (driver_name)
+ nprobe->data = strdup(driver_name);
+ }
+
+ x11_screen_destroy(xscr);
+ }
+
+ if (xdpy != dpy)
+ XCloseDisplay(xdpy);
+
+ nprobe->magic = X11_PROBE_MAGIC;
+ nprobe->display = dpy;
+
+ nprobe->destroy = x11_probe_destroy;
+
+ return nprobe;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
+ return NATIVE_PROBE_UNKNOWN;
+
+ if (!api)
+ api = drm_api_create();
+
+ /* this is a software driver */
+ if (!api)
+ return NATIVE_PROBE_SUPPORTED;
+
+ /* the display does not support DRI2 or the driver mismatches */
+ if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
+ return NATIVE_PROBE_FALLBACK;
+
+ return NATIVE_PROBE_EXACT;
+}
+
const char *
native_get_name(void)
{
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 622ddac5df6..622ddac5df6 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 24a50df7a0a..dfa8df22234 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -66,7 +66,6 @@ struct ximage_buffer {
XImage *ximage;
struct pipe_texture *texture;
- struct pipe_transfer *transfer;
XShmSegmentInfo *shm_info;
boolean xshm_attached;
};
@@ -115,12 +114,7 @@ ximage_surface_free_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;
- if (xbuf->transfer) {
- screen->tex_transfer_destroy(xbuf->transfer);
- xbuf->transfer = NULL;
- }
pipe_texture_reference(&xbuf->texture, NULL);
if (xbuf->shm_info) {
@@ -193,13 +187,6 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
xbuf->texture = screen->texture_create(screen, &templ);
}
- if (xbuf->texture) {
- xbuf->transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!xbuf->transfer)
- pipe_texture_reference(&xbuf->texture, NULL);
- }
-
/* clean up the buffer if allocation failed */
if (!xbuf->texture)
ximage_surface_free_buffer(&xsurf->base, which);
@@ -214,13 +201,25 @@ 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;
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return TRUE;
assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
- xbuf->ximage->data = screen->transfer_map(screen, xbuf->transfer);
+ transfer = screen->get_tex_transfer(screen, xbuf->texture,
+ 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
+ if (!transfer)
+ return FALSE;
+
+ xbuf->ximage->bytes_per_line = transfer->stride;
+ xbuf->ximage->data = screen->transfer_map(screen, transfer);
+ if (!xbuf->ximage->data) {
+ screen->tex_transfer_destroy(transfer);
+ return FALSE;
+ }
+
if (xbuf->shm_info)
XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
@@ -230,7 +229,13 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, xbuf->transfer);
+ screen->transfer_unmap(screen, transfer);
+
+ /*
+ * softpipe allows the pipe transfer to be re-used, but we don't want to
+ * rely on that behavior.
+ */
+ screen->tex_transfer_destroy(transfer);
XSync(xsurf->xdpy->dpy, FALSE);
@@ -289,27 +294,21 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
}
static boolean
-ximage_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
- unsigned int *seq_num,
- struct pipe_texture **textures,
- int *width, int *height)
+ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean new_buffers = FALSE, error = FALSE;
- unsigned i;
+ boolean new_buffers = FALSE;
+ int att;
ximage_surface_update_geometry(&xsurf->base);
- if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
-
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
- struct ximage_buffer *xbuf = &xsurf->buffers[natt];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[att];
- if (!xbuf)
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
continue;
/* reallocate the texture */
@@ -317,29 +316,19 @@ ximage_surface_validate(struct native_surface *nsurf,
xsurf->width != xbuf->texture->width0 ||
xsurf->height != xbuf->texture->height0) {
new_buffers = TRUE;
- if (ximage_surface_alloc_buffer(&xsurf->base, natt)) {
+ if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
/* update ximage */
if (xbuf->ximage) {
- xbuf->ximage->width = xbuf->transfer->width;
- xbuf->ximage->height = xbuf->transfer->height;
- xbuf->ximage->bytes_per_line = xbuf->transfer->stride;
+ xbuf->ximage->width = xsurf->width;
+ xbuf->ximage->height = xsurf->height;
}
}
}
- /* allocation failed */
- if (!xbuf->texture) {
- unsigned j;
- for (j = 0; j < i; j++)
- pipe_texture_reference(&textures[j], NULL);
- for (j = i; j < num_natts; j++)
- textures[j] = NULL;
- error = TRUE;
- break;
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], xbuf->texture);
}
-
- if (textures)
- pipe_texture_reference(&textures[i], xbuf->texture);
}
/* increase the sequence number so that caller knows */
@@ -353,7 +342,7 @@ ximage_surface_validate(struct native_surface *nsurf,
if (height)
*height = xsurf->height;
- return !error;
+ return TRUE;
}
static void
@@ -615,6 +604,34 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
return configs;
}
+static boolean
+ximage_display_is_pixmap_supported(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt;
+ uint depth;
+
+ depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
+ switch (depth) {
+ case 32:
+ fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case 24:
+ fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+ break;
+ case 16:
+ fmt = PIPE_FORMAT_R5G6B5_UNORM;
+ break;
+ default:
+ fmt = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return (fmt == nconf->color_format);
+}
+
static void
ximage_display_destroy(struct native_display *ndpy)
{
@@ -667,6 +684,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_configs = ximage_display_get_configs;
+ xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
xdpy->base.create_context = ximage_display_create_context;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
diff --git a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
index 6ee3ede38cb..6ee3ede38cb 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.c
+++ b/src/gallium/state_trackers/egl/x11/sw_winsys.c
diff --git a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h
index f96c5a14b0a..f96c5a14b0a 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/sw_winsys.h
+++ b/src/gallium/state_trackers/egl/x11/sw_winsys.h
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index 1e98943242a..76ce45ee574 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -30,6 +30,7 @@
#include <X11/extensions/XShm.h>
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_format.h"
#include "xf86drm.h"
#include "egllog.h"
@@ -41,6 +42,10 @@ struct x11_screen {
Display *dpy;
int number;
+ /*
+ * This is used to fetch GLX visuals/fbconfigs. It uses code from egl_xdri.
+ * It might be better to rewrite the part in Xlib or XCB.
+ */
__GLXdisplayPrivate *glx_dpy;
int dri_major, dri_minor;
@@ -50,6 +55,10 @@ struct x11_screen {
XVisualInfo *visuals;
int num_visuals;
+
+ /* cached values for x11_drawable_get_depth */
+ Drawable last_drawable;
+ unsigned int last_depth;
};
@@ -88,8 +97,8 @@ x11_screen_destroy(struct x11_screen *xscr)
if (xscr->dri_device)
Xfree(xscr->dri_device);
- if (xscr->glx_dpy)
- __glXRelease(xscr->glx_dpy);
+ /* xscr->glx_dpy will be destroyed with the X display */
+
if (xscr->visuals)
XFree(xscr->visuals);
free(xscr);
@@ -245,6 +254,22 @@ x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
}
/**
+ * Probe the screen for the DRI2 driver name.
+ */
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr)
+{
+ /* get the driver name and the device name */
+ if (!xscr->dri_driver) {
+ if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
+ &xscr->dri_driver, &xscr->dri_device))
+ xscr->dri_driver = xscr->dri_device = NULL;
+ }
+
+ return xscr->dri_driver;
+}
+
+/**
* Enable DRI2 and returns the file descriptor of the DRM device. The file
* descriptor will be closed automatically when the screen is destoryed.
*/
@@ -256,13 +281,8 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
drm_magic_t magic;
/* get the driver name and the device name first */
- if (!xscr->dri_driver) {
- if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
- &xscr->dri_driver, &xscr->dri_device)) {
- xscr->dri_driver = xscr->dri_device = NULL;
- return -1;
- }
- }
+ if (!x11_screen_probe_dri2(xscr))
+ return -1;
if (!x11_screen_is_driver_equal(xscr, driver)) {
_eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
@@ -351,6 +371,37 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
}
/**
+ * Return the depth of a drawable.
+ *
+ * Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
+ */
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
+{
+ unsigned int depth;
+
+ if (drawable != xscr->last_drawable) {
+ Window root;
+ int x, y;
+ unsigned int w, h, border;
+ Status ok;
+
+ ok = XGetGeometry(xscr->dpy, drawable, &root,
+ &x, &y, &w, &h, &border, &depth);
+ if (!ok)
+ depth = 0;
+
+ xscr->last_drawable = drawable;
+ xscr->last_depth = depth;
+ }
+ else {
+ depth = xscr->last_depth;
+ }
+
+ return depth;
+}
+
+/**
* Create a mode list of the given size.
*/
__GLcontextModes *
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h
index 86e8e0501a3..5432858ac3e 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -70,6 +70,9 @@ x11_screen_get_glx_configs(struct x11_screen *xscr);
const __GLcontextModes *
x11_screen_get_glx_visuals(struct x11_screen *xscr);
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr);
+
int
x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
@@ -96,4 +99,7 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
int *width, int *height, unsigned int *attachments,
boolean with_format, int num_ins, int *num_outs);
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
+
#endif /* _X11_SCREEN_H_ */
diff --git a/src/gallium/state_trackers/egl_g3d/Makefile b/src/gallium/state_trackers/egl_g3d/Makefile
deleted file mode 100644
index 213eb3e815b..00000000000
--- a/src/gallium/state_trackers/egl_g3d/Makefile
+++ /dev/null
@@ -1,72 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-common_INCLUDES = \
- -I. \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/egl/main \
- -I$(TOP)/include
-
-common_SOURCES = $(wildcard common/*.c)
-common_OBJECTS = $(common_SOURCES:.c=.o)
-
-
-x11_INCLUDES = \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/glx/x11 \
- -I$(TOP)/src/mesa \
- $(shell pkg-config --cflags-only-I libdrm)
-
-x11_SOURCES = $(wildcard x11/*.c) $(TOP)/src/glx/x11/dri2.c
-x11_OBJECTS = $(x11_SOURCES:.c=.o)
-
-
-kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm)
-kms_SOURCES = $(wildcard kms/*.c)
-kms_OBJECTS = $(kms_SOURCES:.c=.o)
-
-
-ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES)
-ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES)
-ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS)
-
-##### TARGETS #####
-
-EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a)
-
-default: depend $(EGL_DISPLAYS_MODS)
-
-
-libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile
- $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS)
-
-libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile
- $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS)
-
-depend:
- rm -f depend
- touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
-
-clean:
- rm -f $(ALL_OBJECTS)
- rm -f $(EGL_DISPLAYS_MODS)
- rm -f depend depend.bak
-
-# Dummy target
-install:
- @echo -n ""
-
-##### RULES #####
-
-$(common_OBJECTS): %.o: %.c
- $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-
-$(x11_OBJECTS): %.o: %.c
- $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-
-$(kms_OBJECTS): %.o: %.c
- $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-
-sinclude depend
diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.c b/src/gallium/state_trackers/egl_g3d/x11/glxinit.c
deleted file mode 100644
index c955a908b93..00000000000
--- a/src/gallium/state_trackers/egl_g3d/x11/glxinit.c
+++ /dev/null
@@ -1,573 +0,0 @@
-/**
- * GLX initialization. Code based on glxext.c, glx_query.c, and
- * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI
- * related code here.
- *
- */
-
-#include <assert.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include <sys/time.h>
-
-#include "x11_screen.h"
-#include "glxinit.h"
-
-typedef struct GLXGenericGetString
-{
- CARD8 reqType;
- CARD8 glxCode;
- CARD16 length B16;
- CARD32 for_whom B32;
- CARD32 name B32;
-} xGLXGenericGetStringReq;
-
-#define sz_xGLXGenericGetStringReq 12
-#define X_GLXGenericGetString 0
-
-/* Extension required boiler plate */
-
-static char *__glXExtensionName = GLX_EXTENSION_NAME;
-static XExtensionInfo *__glXExtensionInfo = NULL;
-
-static /* const */ XExtensionHooks __glXExtensionHooks = { NULL };
-static
-XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
- __glXExtensionName, &__glXExtensionHooks,
- __GLX_NUMBER_EVENTS, NULL)
-
-static GLint
-_gl_convert_from_x_visual_type(int visualType)
-{
-#define NUM_VISUAL_TYPES 6
- static const int glx_visual_types[NUM_VISUAL_TYPES] = {
- GLX_STATIC_GRAY, GLX_GRAY_SCALE,
- GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
- GLX_TRUE_COLOR, GLX_DIRECT_COLOR
- };
-
- return ((unsigned) visualType < NUM_VISUAL_TYPES)
- ? glx_visual_types[visualType] : GLX_NONE;
-}
-
-_X_HIDDEN char *
-__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
-{
- xGLXGenericGetStringReq *req;
- xGLXSingleReply reply;
- int length;
- int numbytes;
- char *buf;
- CARD32 for_whom = screen;
- CARD32 glxCode = X_GLXQueryServerString;
-
-
- LockDisplay(dpy);
-
-
- /* All of the GLX protocol requests for getting a string from the server
- * look the same. The exact meaning of the for_whom field is usually
- * either the screen number (for glXQueryServerString) or the context tag
- * (for GLXSingle).
- */
-
- GetReq(GLXGenericGetString, req);
- req->reqType = opcode;
- req->glxCode = glxCode;
- req->for_whom = for_whom;
- req->name = name;
-
- _XReply(dpy, (xReply *) & reply, 0, False);
-
- length = reply.length * 4;
- numbytes = reply.size;
-
- buf = (char *) Xmalloc(numbytes);
- if (buf != NULL) {
- _XRead(dpy, buf, numbytes);
- length -= numbytes;
- }
-
- _XEatData(dpy, length);
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return buf;
-}
-
-/************************************************************************/
-/*
-** Free the per screen configs data as well as the array of
-** __glXScreenConfigs.
-*/
-static void
-FreeScreenConfigs(__GLXdisplayPrivate * priv)
-{
- __GLXscreenConfigs *psc;
- GLint i, screens;
-
- /* Free screen configuration information */
- psc = priv->screenConfigs;
- screens = ScreenCount(priv->dpy);
- for (i = 0; i < screens; i++, psc++) {
- if (psc->configs) {
- x11_context_modes_destroy(psc->configs);
- psc->configs = NULL; /* NOTE: just for paranoia */
- }
- if (psc->visuals) {
- x11_context_modes_destroy(psc->visuals);
- psc->visuals = NULL; /* NOTE: just for paranoia */
- }
- Xfree((char *) psc->serverGLXexts);
- }
- XFree((char *) priv->screenConfigs);
- priv->screenConfigs = NULL;
-}
-
-/************************************************************************/
-
-/*
-** Query the version of the GLX extension. This procedure works even if
-** the client extension is not completely set up.
-*/
-static Bool
-QueryVersion(Display * dpy, int opcode, int *major, int *minor)
-{
- xGLXQueryVersionReq *req;
- xGLXQueryVersionReply reply;
-
- /* Send the glXQueryVersion request */
- LockDisplay(dpy);
- GetReq(GLXQueryVersion, req);
- req->reqType = opcode;
- req->glxCode = X_GLXQueryVersion;
- req->majorVersion = GLX_MAJOR_VERSION;
- req->minorVersion = GLX_MINOR_VERSION;
- _XReply(dpy, (xReply *) & reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (reply.majorVersion != GLX_MAJOR_VERSION) {
- /*
- ** The server does not support the same major release as this
- ** client.
- */
- return GL_FALSE;
- }
- *major = reply.majorVersion;
- *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
- return GL_TRUE;
-}
-
-_X_HIDDEN void
-__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
- const INT32 * bp, Bool tagged_only,
- Bool fbconfig_style_tags)
-{
- int i;
-
- if (!tagged_only) {
- /* Copy in the first set of properties */
- config->visualID = *bp++;
-
- config->visualType = _gl_convert_from_x_visual_type(*bp++);
-
- config->rgbMode = *bp++;
-
- config->redBits = *bp++;
- config->greenBits = *bp++;
- config->blueBits = *bp++;
- config->alphaBits = *bp++;
- config->accumRedBits = *bp++;
- config->accumGreenBits = *bp++;
- config->accumBlueBits = *bp++;
- config->accumAlphaBits = *bp++;
-
- config->doubleBufferMode = *bp++;
- config->stereoMode = *bp++;
-
- config->rgbBits = *bp++;
- config->depthBits = *bp++;
- config->stencilBits = *bp++;
- config->numAuxBuffers = *bp++;
- config->level = *bp++;
-
- count -= __GLX_MIN_CONFIG_PROPS;
- }
-
- /*
- ** Additional properties may be in a list at the end
- ** of the reply. They are in pairs of property type
- ** and property value.
- */
-
-#define FETCH_OR_SET(tag) \
- config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
-
- for (i = 0; i < count; i += 2) {
- switch (*bp++) {
- case GLX_RGBA:
- FETCH_OR_SET(rgbMode);
- break;
- case GLX_BUFFER_SIZE:
- config->rgbBits = *bp++;
- break;
- case GLX_LEVEL:
- config->level = *bp++;
- break;
- case GLX_DOUBLEBUFFER:
- FETCH_OR_SET(doubleBufferMode);
- break;
- case GLX_STEREO:
- FETCH_OR_SET(stereoMode);
- break;
- case GLX_AUX_BUFFERS:
- config->numAuxBuffers = *bp++;
- break;
- case GLX_RED_SIZE:
- config->redBits = *bp++;
- break;
- case GLX_GREEN_SIZE:
- config->greenBits = *bp++;
- break;
- case GLX_BLUE_SIZE:
- config->blueBits = *bp++;
- break;
- case GLX_ALPHA_SIZE:
- config->alphaBits = *bp++;
- break;
- case GLX_DEPTH_SIZE:
- config->depthBits = *bp++;
- break;
- case GLX_STENCIL_SIZE:
- config->stencilBits = *bp++;
- break;
- case GLX_ACCUM_RED_SIZE:
- config->accumRedBits = *bp++;
- break;
- case GLX_ACCUM_GREEN_SIZE:
- config->accumGreenBits = *bp++;
- break;
- case GLX_ACCUM_BLUE_SIZE:
- config->accumBlueBits = *bp++;
- break;
- case GLX_ACCUM_ALPHA_SIZE:
- config->accumAlphaBits = *bp++;
- break;
- case GLX_VISUAL_CAVEAT_EXT:
- config->visualRating = *bp++;
- break;
- case GLX_X_VISUAL_TYPE:
- config->visualType = *bp++;
- break;
- case GLX_TRANSPARENT_TYPE:
- config->transparentPixel = *bp++;
- break;
- case GLX_TRANSPARENT_INDEX_VALUE:
- config->transparentIndex = *bp++;
- break;
- case GLX_TRANSPARENT_RED_VALUE:
- config->transparentRed = *bp++;
- break;
- case GLX_TRANSPARENT_GREEN_VALUE:
- config->transparentGreen = *bp++;
- break;
- case GLX_TRANSPARENT_BLUE_VALUE:
- config->transparentBlue = *bp++;
- break;
- case GLX_TRANSPARENT_ALPHA_VALUE:
- config->transparentAlpha = *bp++;
- break;
- case GLX_VISUAL_ID:
- config->visualID = *bp++;
- break;
- case GLX_DRAWABLE_TYPE:
- config->drawableType = *bp++;
- break;
- case GLX_RENDER_TYPE:
- config->renderType = *bp++;
- break;
- case GLX_X_RENDERABLE:
- config->xRenderable = *bp++;
- break;
- case GLX_FBCONFIG_ID:
- config->fbconfigID = *bp++;
- break;
- case GLX_MAX_PBUFFER_WIDTH:
- config->maxPbufferWidth = *bp++;
- break;
- case GLX_MAX_PBUFFER_HEIGHT:
- config->maxPbufferHeight = *bp++;
- break;
- case GLX_MAX_PBUFFER_PIXELS:
- config->maxPbufferPixels = *bp++;
- break;
- case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
- config->optimalPbufferWidth = *bp++;
- break;
- case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
- config->optimalPbufferHeight = *bp++;
- break;
- case GLX_VISUAL_SELECT_GROUP_SGIX:
- config->visualSelectGroup = *bp++;
- break;
- case GLX_SWAP_METHOD_OML:
- config->swapMethod = *bp++;
- break;
- case GLX_SAMPLE_BUFFERS_SGIS:
- config->sampleBuffers = *bp++;
- break;
- case GLX_SAMPLES_SGIS:
- config->samples = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_RGB_EXT:
- config->bindToTextureRgb = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_RGBA_EXT:
- config->bindToTextureRgba = *bp++;
- break;
- case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
- config->bindToMipmapTexture = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
- config->bindToTextureTargets = *bp++;
- break;
- case GLX_Y_INVERTED_EXT:
- config->yInverted = *bp++;
- break;
- case None:
- i = count;
- break;
- default:
- break;
- }
- }
-
- config->renderType =
- (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
-
- config->haveAccumBuffer = ((config->accumRedBits +
- config->accumGreenBits +
- config->accumBlueBits +
- config->accumAlphaBits) > 0);
- config->haveDepthBuffer = (config->depthBits > 0);
- config->haveStencilBuffer = (config->stencilBits > 0);
-}
-
-static __GLcontextModes *
-createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
- int screen, GLboolean tagged_only)
-{
- INT32 buf[__GLX_TOTAL_CONFIG], *props;
- unsigned prop_size;
- __GLcontextModes *modes, *m;
- int i;
-
- if (nprops == 0)
- return NULL;
-
- /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
-
- /* Check number of properties */
- if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
- return NULL;
-
- /* Allocate memory for our config structure */
- modes = x11_context_modes_create(nvisuals);
- if (!modes)
- return NULL;
-
- prop_size = nprops * __GLX_SIZE_INT32;
- if (prop_size <= sizeof(buf))
- props = buf;
- else
- props = Xmalloc(prop_size);
-
- /* Read each config structure and convert it into our format */
- m = modes;
- for (i = 0; i < nvisuals; i++) {
- _XRead(dpy, (char *) props, prop_size);
- /* Older X servers don't send this so we default it here. */
- m->drawableType = GLX_WINDOW_BIT;
- __glXInitializeVisualConfigFromTags(m, nprops, props,
- tagged_only, GL_TRUE);
- m->screen = screen;
- m = m->next;
- }
-
- if (props != buf)
- Xfree(props);
-
- return modes;
-}
-
-static GLboolean
-getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
-{
- xGLXGetVisualConfigsReq *req;
- __GLXscreenConfigs *psc;
- xGLXGetVisualConfigsReply reply;
-
- LockDisplay(dpy);
-
- psc = priv->screenConfigs + screen;
- psc->visuals = NULL;
- GetReq(GLXGetVisualConfigs, req);
- req->reqType = priv->majorOpcode;
- req->glxCode = X_GLXGetVisualConfigs;
- req->screen = screen;
-
- if (!_XReply(dpy, (xReply *) & reply, 0, False))
- goto out;
-
- psc->visuals = createConfigsFromProperties(dpy,
- reply.numVisuals,
- reply.numProps,
- screen, GL_FALSE);
-
- out:
- UnlockDisplay(dpy);
- return psc->visuals != NULL;
-}
-
-static GLboolean
-getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
-{
- xGLXGetFBConfigsReq *fb_req;
- xGLXGetFBConfigsSGIXReq *sgi_req;
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXGetFBConfigsReply reply;
- __GLXscreenConfigs *psc;
-
- psc = priv->screenConfigs + screen;
- psc->serverGLXexts =
- __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
-
- LockDisplay(dpy);
-
- psc->configs = NULL;
- if (atof(priv->serverGLXversion) >= 1.3) {
- GetReq(GLXGetFBConfigs, fb_req);
- fb_req->reqType = priv->majorOpcode;
- fb_req->glxCode = X_GLXGetFBConfigs;
- fb_req->screen = screen;
- }
- else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXGetFBConfigsSGIXReq +
- sz_xGLXVendorPrivateWithReplyReq, vpreq);
- sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
- sgi_req->reqType = priv->majorOpcode;
- sgi_req->glxCode = X_GLXVendorPrivateWithReply;
- sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
- sgi_req->screen = screen;
- }
- else
- goto out;
-
- if (!_XReply(dpy, (xReply *) & reply, 0, False))
- goto out;
-
- psc->configs = createConfigsFromProperties(dpy,
- reply.numFBConfigs,
- reply.numAttribs * 2,
- screen, GL_TRUE);
-
- out:
- UnlockDisplay(dpy);
- return psc->configs != NULL;
-}
-
-static GLboolean
-AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
-{
- __GLXscreenConfigs *psc;
- GLint i, screens;
-
- /*
- ** First allocate memory for the array of per screen configs.
- */
- screens = ScreenCount(dpy);
- psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
- if (!psc) {
- return GL_FALSE;
- }
- memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
- priv->screenConfigs = psc;
-
- priv->serverGLXversion =
- __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
- if (priv->serverGLXversion == NULL) {
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
-
- for (i = 0; i < screens; i++, psc++) {
- getFBConfigs(dpy, priv, i);
- getVisualConfigs(dpy, priv, i);
- psc->scr = i;
- psc->dpy = dpy;
- }
-
- SyncHandle();
-
- return GL_TRUE;
-}
-
-_X_HIDDEN void
-__glXRelease(__GLXdisplayPrivate *dpyPriv)
-{
- FreeScreenConfigs(dpyPriv);
-
- if (dpyPriv->serverGLXvendor) {
- Xfree((char *) dpyPriv->serverGLXvendor);
- dpyPriv->serverGLXvendor = NULL;
- }
- if (dpyPriv->serverGLXversion) {
- Xfree((char *) dpyPriv->serverGLXversion);
- dpyPriv->serverGLXversion = NULL;
- }
-
- Xfree(dpyPriv);
-}
-
-_X_HIDDEN __GLXdisplayPrivate *
-__glXInitialize(Display * dpy)
-{
- XExtDisplayInfo *info = __glXFindDisplay(dpy);
- __GLXdisplayPrivate *dpyPriv;
- int major, minor;
-
- if (!XextHasExtension(info))
- return NULL;
-
- /* See if the versions are compatible */
- if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
- return NULL;
-
- dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
- if (!dpyPriv)
- return NULL;
-
- /*
- ** Init the display private and then read in the screen config
- ** structures from the server.
- */
- dpyPriv->majorOpcode = info->codes->major_opcode;
- dpyPriv->majorVersion = major;
- dpyPriv->minorVersion = minor;
- dpyPriv->dpy = dpy;
-
- dpyPriv->serverGLXvendor = NULL;
- dpyPriv->serverGLXversion = NULL;
-
- if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
- Xfree(dpyPriv);
- return NULL;
- }
-
- return dpyPriv;
-}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/glxinit.h b/src/gallium/state_trackers/egl_g3d/x11/glxinit.h
deleted file mode 100644
index 515a8252220..00000000000
--- a/src/gallium/state_trackers/egl_g3d/x11/glxinit.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef GLXINIT_INCLUDED
-#define GLXINIT_INCLUDED
-
-#include <X11/Xlib.h>
-
-#ifndef GLX_DIRECT_RENDERING
-#define GLX_DIRECT_RENDERING
-#endif
-#include "glxclient.h"
-
-extern void
-__glXRelease(__GLXdisplayPrivate *dpyPriv);
-
-#endif /* GLXINIT_INCLUDED */
diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile
new file mode 100644
index 00000000000..b0365512719
--- /dev/null
+++ b/src/gallium/state_trackers/es/Makefile
@@ -0,0 +1,84 @@
+# src/gallium/state_trackers/es/Makefile
+
+# Build the ES 1/2 state tracker libraries
+# This consists of core Mesa ES, plus GL/gallium state tracker.
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+GLES_1_VERSION_MAJOR = 1
+GLES_1_VERSION_MINOR = 1
+GLES_1_VERSION_PATCH = 0
+
+GLES_2_VERSION_MAJOR = 2
+GLES_2_VERSION_MINOR = 0
+GLES_2_VERSION_PATCH = 0
+
+
+# Maybe move these into configs/default:
+GLES_1_LIB = GLESv1_CM
+GLES_1_LIB_NAME = lib$(GLES_1_LIB).so
+GLES_2_LIB = GLESv2
+GLES_2_LIB_NAME = lib$(GLES_2_LIB).so
+
+
+ES1_OBJECTS = st_es1.o
+ES2_OBJECTS = st_es2.o
+
+
+ES1_LIBS = \
+ $(TOP)/src/mesa/es/libes1gallium.a \
+ $(TOP)/src/mesa/es/libes1api.a
+
+ES2_LIBS = \
+ $(TOP)/src/mesa/es/libes2gallium.a \
+ $(TOP)/src/mesa/es/libes2api.a
+
+SYS_LIBS = -lm -pthread
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/src/gallium/include
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+
+
+# Default: make both GL ES 1.1 and GL ES 2.0 libraries
+default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)
+
+# Make the shared libs
+$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES)
+ $(MKLIB) -o $(GLES_1_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(GLES_1_VERSION_MAJOR) \
+ -minor $(GLES_1_VERSION_MINOR) \
+ -patch $(GLES_1_VERSION_PATCH) \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ $(ES1_OBJECTS) \
+ -Wl,--whole-archive $(ES1_LIBS) -Wl,--no-whole-archive \
+ $(GALLIUM_AUXILIARIES) $(SYS_LIBS)
+
+$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES)
+ $(MKLIB) -o $(GLES_2_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(GLES_2_VERSION_MAJOR) \
+ -minor $(GLES_2_VERSION_MINOR) \
+ -patch $(GLES_2_VERSION_PATCH) \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ $(ES2_OBJECTS) \
+ -Wl,--whole-archive $(ES2_LIBS) -Wl,--no-whole-archive \
+ $(GALLIUM_AUXILIARIES) $(SYS_LIBS)
+
+install: default
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
+ $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES2
+ $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES2
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+
+clean:
+ -rm -f *.o *~
+ -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)*
+
+depend:
diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c
new file mode 100644
index 00000000000..25bc53b21eb
--- /dev/null
+++ b/src/gallium/state_trackers/es/st_es1.c
@@ -0,0 +1,3 @@
+#include "pipe/p_compiler.h"
+
+PUBLIC const int st_api_OpenGL_ES1 = 1;
diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c
new file mode 100644
index 00000000000..171ea62b97f
--- /dev/null
+++ b/src/gallium/state_trackers/es/st_es2.c
@@ -0,0 +1,3 @@
+#include "pipe/p_compiler.h"
+
+PUBLIC const int st_api_OpenGL_ES2 = 1;
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
index 84d47b12edc..bd4a85caa04 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -193,7 +193,7 @@ _glxapi_get_proc_address(const char *funcName)
}
-__GLXextFuncPtr
+PUBLIC __GLXextFuncPtr
glXGetProcAddressARB(const GLubyte *procName)
{
__GLXextFuncPtr f;
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 8498a90812e..527e065cd91 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -21,6 +21,7 @@ if 'python' in env['statetrackers']:
'gdi32',
'user32',
'kernel32',
+ 'ws2_32',
])
else:
env.Append(LIBS = [
diff --git a/src/gallium/state_trackers/python/samples/gs.py b/src/gallium/state_trackers/python/samples/gs.py
index a07cf557f2f..cd68abac9a1 100644
--- a/src/gallium/state_trackers/python/samples/gs.py
+++ b/src/gallium/state_trackers/python/samples/gs.py
@@ -72,11 +72,11 @@ def test(dev):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py
index e5e168bdc8d..f0b5e3dc984 100644
--- a/src/gallium/state_trackers/python/samples/tri.py
+++ b/src/gallium/state_trackers/python/samples/tri.py
@@ -72,11 +72,11 @@ def test(dev):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index d144af2447d..e41125f6f99 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -180,11 +180,11 @@ st_context_create(struct st_device *st_dev)
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(st_ctx->cso, &blend);
}
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index a3294e877a6..dfe3e465f77 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -35,225 +35,10 @@
* @author Jose Fonseca
*/
-
-#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
#include "softpipe/sp_winsys.h"
#include "st_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);
-}
-
-
-static struct pipe_screen *
-st_softpipe_screen_create(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;
-}
-
-
-static struct pipe_context *
-st_softpipe_context_create(struct pipe_screen *screen)
-{
- return softpipe_create(screen);
-}
-
-
const struct st_winsys st_softpipe_winsys = {
- &st_softpipe_screen_create,
- &st_softpipe_context_create,
+ &softpipe_create_screen_malloc,
+ &softpipe_create,
};
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh
new file mode 100644
index 00000000000..85fb9ea4e7f
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh
@@ -0,0 +1,13 @@
+FRAG
+
+DCL IN[0], COLOR, LINEAR
+DCL OUT[0], COLOR
+DCL CONST[1]
+DCL CONST[3]
+DCL TEMP[0..1]
+
+ADD TEMP[0], IN[0], CONST[1]
+RCP TEMP[1], CONST[3].xxxx
+MUL OUT[0], TEMP[0], TEMP[1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh
new file mode 100644
index 00000000000..f70a5146f4e
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh
@@ -0,0 +1,9 @@
+FRAG
+
+DCL IN[0], COLOR, LINEAR
+DCL OUT[0], COLOR
+DCL CONST[1][1..2]
+
+MAD OUT[0], IN[0], CONST[1][2], CONST[1][1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
index f2a1521cbf0..d58b7886a12 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
DCL IN[0], COLOR, LINEAR
DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
index 8d3bf9d4d7e..41dd69d2542 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
@@ -26,6 +26,7 @@
#
##########################################################################
+import struct
from gallium import *
@@ -50,11 +51,11 @@ def test(dev, name):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
@@ -146,6 +147,42 @@ def test(dev, name):
fs = Shader(file('frag-' + name + '.sh', 'rt').read())
ctx.set_fragment_shader(fs)
+ constbuf0 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
+ cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
+ cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
+ cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
+
+ constbuf0.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
+ 0,
+ constbuf0)
+
+ constbuf1 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
+ cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
+ cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
+ cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
+
+ constbuf1.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
+ 1,
+ constbuf1)
+
xy = [
-0.8, -0.8,
0.8, -0.8,
@@ -184,6 +221,8 @@ def main():
tests = [
'abs',
'add',
+ 'cb-1d',
+ 'cb-2d',
'dp3',
'dp4',
'dst',
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh
new file mode 100644
index 00000000000..b41fe5dd38f
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh
@@ -0,0 +1,16 @@
+VERT
+
+DCL IN[0], POSITION
+DCL IN[1], COLOR
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL CONST[1]
+DCL CONST[3]
+DCL TEMP[0..1]
+
+MOV OUT[0], IN[0]
+ADD TEMP[0], IN[1], CONST[1]
+RCP TEMP[1], CONST[3].xxxx
+MUL OUT[1], TEMP[0], TEMP[1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh
new file mode 100644
index 00000000000..45f5e6b7299
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh
@@ -0,0 +1,12 @@
+VERT
+
+DCL IN[0], POSITION
+DCL IN[1], COLOR
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL CONST[1][1..2]
+
+MOV OUT[0], IN[0]
+MAD OUT[1], IN[1], CONST[1][2], CONST[1][1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
index 01bf5a3210d..2c44f872e1d 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
@@ -27,6 +27,8 @@
##########################################################################
+import struct
+
from gallium import *
def make_image(surface):
@@ -50,11 +52,11 @@ def test(dev, name):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
@@ -143,6 +145,42 @@ def test(dev, name):
''')
ctx.set_fragment_shader(fs)
+ constbuf0 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
+ cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
+ cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
+ cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
+
+ constbuf0.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
+ 0,
+ constbuf0)
+
+ constbuf1 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
+ cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
+ cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
+ cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
+
+ constbuf1.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
+ 1,
+ constbuf1)
+
xy = [
0.0, 0.8,
-0.2, 0.4,
@@ -213,6 +251,8 @@ def main():
'add',
'arl',
'arr',
+ 'cb-1d',
+ 'cb-2d',
'dp3',
'dp4',
'dst',
diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py
index 79287f2cace..0fac1ea5ef3 100755
--- a/src/gallium/state_trackers/python/tests/texture_render.py
+++ b/src/gallium/state_trackers/python/tests/texture_render.py
@@ -115,11 +115,11 @@ class TextureTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# no-op depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py
index 520961c8051..db32b537a17 100755
--- a/src/gallium/state_trackers/python/tests/texture_sample.py
+++ b/src/gallium/state_trackers/python/tests/texture_sample.py
@@ -140,11 +140,11 @@ class TextureColorSampleTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# no-op depth/stencil/alpha
@@ -327,11 +327,11 @@ class TextureDepthSampleTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index fc97bf51f8f..037d8dc911a 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -1,8 +1,14 @@
-# src/mesa/Makefile
+# src/gallium/state_trackers/vega/Makefile
TOP = ../../../..
include $(TOP)/configs/current
-GALLIUM = $(TOP)
+
+VG_LIB = OpenVG
+VG_LIB_NAME = lib$(VG_LIB).so
+
+VG_MAJOR = 1
+VG_MINOR = 0
+VG_TINY = 0
### Lists of source files, included by Makefiles
@@ -34,88 +40,54 @@ VG_SOURCES = \
shader.c \
shaders_cache.c
+VG_OBJECTS = $(VG_SOURCES:.c=.o)
-### All the core C sources
-
-ALL_SOURCES = \
- $(VG_SOURCES)
-
-
-### Object files
-VG_OBJECTS = \
- $(VG_SOURCES:.c=.o)
+VG_LIBS = $(GALLIUM_AUXILIARIES) -lm
### Include directories
INCLUDE_DIRS = \
-I$(TOP)/include \
- -I$(GALLIUM)/include \
- -I$(GALLIUM)/src/gallium/include \
- -I$(GALLIUM)/src/gallium/auxiliary
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary
-VG_LIB = OpenVG
-VG_LIB_NAME = lib$(VG_LIB).so
-
-VG_MAJOR = 1
-VG_MINOR = 0
-VG_TINY = 0
-
-GALLIUM_LIBS = \
- $(GALLIUM)/src/gallium/auxiliary/libgallium.a
-
-.SUFFIXES : .cpp
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
-.cpp.o:
- $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
-
-.S.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
-
-
-default: depend subdirs $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
+default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
# Make the OpenVG library
-$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(GALLIUM_LIBS)
- $(TOP)/bin/mklib -o $(VG_LIB) \
+$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(VG_LIBS)
+ $(MKLIB) -o $(VG_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major $(VG_MAJOR) \
-minor $(VG_MINOR) \
-patch $(VG_TINY) \
-install $(TOP)/$(LIB_DIR) \
- $(VG_OBJECTS) $(GALLIUM_LIBS) \
- -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive $(SYS_LIBS)
+ $(VG_OBJECTS) $(VG_LIBS)
######################################################################
# Generic stuff
-depend: $(ALL_SOURCES)
+depend: $(VG_SOURCES)
@ echo "running $(MKDEP)"
@ rm -f depend # workaround oops on gutsy?!?
@ touch depend
- @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
+ @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(VG_SOURCES) \
> /dev/null 2>/dev/null
-
-subdirs:
-
install: default
- $(INSTALL) -d $(INSTALL_DIR)/include/VG
- $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
- $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(INSTALL_DIR)/include/VG
- @if [ -e $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(INSTALL_DIR)/$(LIB_DIR); \
- fi
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/VG
+ $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(DESTDIR)$(INSTALL_DIR)/include/VG
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
# Emacs tags
tags:
etags `find . -name \*.[ch]` $(TOP)/include/VG/*.h
clean:
- -rm -f *.o
- -rm -f */*.o
- -rm -f */*/*.o
- -rm -f depend depend.bak
+ rm -f $(VG_OBJECTS)
+ rm -f depend depend.bak
-include depend
+sinclude depend
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 8f69ee01099..cf4a11bb142 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -127,19 +127,19 @@ static void setup_blend()
struct vg_context *ctx = vg_current_context();
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
if (ctx->state.vg.filter_channel_mask & VG_RED)
- blend.colormask |= PIPE_MASK_R;
+ blend.rt[0].colormask |= PIPE_MASK_R;
if (ctx->state.vg.filter_channel_mask & VG_GREEN)
- blend.colormask |= PIPE_MASK_G;
+ blend.rt[0].colormask |= PIPE_MASK_G;
if (ctx->state.vg.filter_channel_mask & VG_BLUE)
- blend.colormask |= PIPE_MASK_B;
+ blend.rt[0].colormask |= PIPE_MASK_B;
if (ctx->state.vg.filter_channel_mask & VG_ALPHA)
- blend.colormask |= PIPE_MASK_A;
- blend.blend_enable = 1;
+ blend.rt[0].colormask |= PIPE_MASK_A;
+ blend.rt[0].blend_enable = 0;
cso_set_blend(ctx->cso_context, &blend);
}
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 4f9f3dae173..e6070c7353b 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -32,7 +32,6 @@
#include "vg_context.h"
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h" /* for winsys->update_buffer */
#include "util/u_pack_color.h"
#include "util/u_draw_quad.h"
@@ -116,8 +115,8 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/
- if (st->pipe->winsys && st->pipe->winsys->update_buffer)
- st->pipe->winsys->update_buffer( st->pipe->winsys,
+ 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);
@@ -129,14 +128,11 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask |= PIPE_MASK_R;
- blend.colormask |= PIPE_MASK_G;
- blend.colormask |= PIPE_MASK_B;
- blend.colormask |= PIPE_MASK_A;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(st->cso_context, &blend);
}
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 3e260e70736..ba8ecef1d2d 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -354,15 +354,12 @@ static void setup_mask_blend()
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_R;
- blend.colormask |= PIPE_MASK_G;
- blend.colormask |= PIPE_MASK_B;
- blend.colormask |= PIPE_MASK_A;
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
cso_set_blend(ctx->cso_context, &blend);
}
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index d385ee567fa..f5352ee84e5 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -248,12 +248,12 @@ VGboolean polygon_is_closed(struct polygon *p)
static void set_blend_for_fill(struct pipe_blend_state *blend)
{
memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->colormask = 0; /*disable colorwrites*/
+ blend->rt[0].colormask = 0; /*disable colorwrites*/
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
}
static void draw_polygon(struct vg_context *ctx,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 64e3a7c5453..47e18dc1e23 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -317,11 +317,11 @@ void renderer_copy_texture(struct renderer *ctx,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(ctx->cso, &blend);
}
@@ -486,11 +486,11 @@ void renderer_copy_surface(struct renderer *ctx,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(ctx->cso, &blend);
}
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index bd5ae79e551..8e59d53dc7a 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -135,8 +135,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
textures[2] = stfb->blend_texture;
if (!samplers[0] || !textures[0]) {
- samplers[1] = samplers[2];
- textures[1] = textures[2];
+ samplers[0] = samplers[2];
+ textures[0] = textures[2];
}
if (!samplers[1] || !textures[1]) {
samplers[1] = samplers[0];
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index c16ac036e3b..64207d97bac 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -252,7 +252,7 @@ static void update_clip_state(struct vg_context *ctx)
ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
/* disable color writes */
- blend->colormask = 0; /*disable colorwrites*/
+ blend->rt[0].colormask = 0; /*disable colorwrites*/
cso_set_blend(ctx->cso_context, blend);
/* enable scissoring */
@@ -286,7 +286,6 @@ static void update_clip_state(struct vg_context *ctx)
renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
}
- blend->colormask = 1; /*enable colorwrites*/
cso_restore_blend(ctx->cso_context);
cso_restore_fragment_shader(ctx->cso_context);
@@ -301,57 +300,56 @@ void vg_validate_state(struct vg_context *ctx)
if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->blend_enable = 1;
- blend->colormask |= PIPE_MASK_R;
- blend->colormask |= PIPE_MASK_G;
- blend->colormask |= PIPE_MASK_B;
- blend->colormask |= PIPE_MASK_A;
+ blend->rt[0].blend_enable = 1;
+ blend->rt[0].colormask = PIPE_MASK_RGBA;
switch (ctx->state.vg.blend_mode) {
case VG_BLEND_SRC:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].blend_enable = 0;
break;
case VG_BLEND_SRC_OVER:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
break;
case VG_BLEND_DST_OVER:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
break;
case VG_BLEND_SRC_IN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
break;
case VG_BLEND_DST_IN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
break;
case VG_BLEND_MULTIPLY:
case VG_BLEND_SCREEN:
case VG_BLEND_DARKEN:
case VG_BLEND_LIGHTEN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].blend_enable = 0;
break;
case VG_BLEND_ADDITIVE:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
break;
default:
assert(!"not implemented blend mode");
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index ff8c1a04217..bc88c8d139d 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -50,7 +50,7 @@ struct st_renderbuffer {
};
struct st_framebuffer {
- VGint init_width, init_height;
+ VGint width, height;
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index ff80aab03a3..617c174eb6a 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -193,8 +193,8 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
*/
stfb->alpha_mask = 0;
- stfb->init_width = width;
- stfb->init_height = height;
+ stfb->width = width;
+ stfb->height = height;
stfb->privateData = privateData;
}
@@ -282,11 +282,14 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
/* If this is a noop, exit early and don't do the clear, etc below.
*/
- if (strb->width == width &&
- strb->height == height &&
+ if (stfb->width == width &&
+ stfb->height == height &&
state->zsbuf)
return;
+ stfb->width = width;
+ stfb->height = height;
+
if (strb->width != width || strb->height != height)
st_renderbuffer_alloc_storage(ctx, strb,
width, height);
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 54cc3614129..7d4c2430b0c 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -95,8 +95,6 @@ stw_pf_depth_stencil[] = {
{ PIPE_FORMAT_Z24X8_UNORM, {24, 0} },
{ PIPE_FORMAT_X8Z24_UNORM, {24, 0} },
{ PIPE_FORMAT_Z16_UNORM, {16, 0} },
- /* pure stencil */
- { PIPE_FORMAT_S8_UNORM, { 0, 8} },
/* combined depth-stencil */
{ PIPE_FORMAT_S8Z24_UNORM, {24, 8} },
{ PIPE_FORMAT_Z24S8_UNORM, {24, 8} }
@@ -220,7 +218,8 @@ stw_pixelformat_init( void )
const struct stw_pf_color_info *color = &stw_pf_color[j];
if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ PIPE_TEXTURE_USAGE_RENDER_TARGET |
+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET, 0))
continue;
for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) {
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 1c248a629e6..c50873c1508 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -4,10 +4,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
-#include "util/u_draw_quad.h"
-#include "util/u_math.h"
-#include "pipe/p_inlines.h"
/*XXX also in Xrender.h but the including it here breaks compilition */
#define XFixedToDouble(f) (((double) (f)) / 65536.)
@@ -220,13 +217,13 @@ bind_blend_state(struct exa_context *exa, int op,
blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 1;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
- blend.rgb_src_factor = blend_opt.rgb_src;
- blend.alpha_src_factor = blend_opt.rgb_src;
- blend.rgb_dst_factor = blend_opt.rgb_dst;
- blend.alpha_dst_factor = blend_opt.rgb_dst;
+ blend.rt[0].rgb_src_factor = blend_opt.rgb_src;
+ blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
+ blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst;
+ blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
cso_set_blend(exa->renderer->cso, &blend);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 650d2c0d1db..2395d549752 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -50,7 +50,6 @@
#endif
#include "pipe/p_inlines.h"
-#include "util/u_format.h"
#include "util/u_rect.h"
#ifdef HAVE_LIBKMS
@@ -243,7 +242,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
unsigned attr[8];
attr[0] = KMS_BO_TYPE;
+#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
+ attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
+#else
attr[1] = KMS_BO_TYPE_CURSOR;
+#endif
attr[2] = KMS_WIDTH;
attr[3] = 64;
attr[4] = KMS_HEIGHT;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index fd82f4fa1d1..59588f0ff75 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -41,12 +41,14 @@
#include "pipe/p_inlines.h"
#include "util/u_format.h"
-#include "util/u_rect.h"
/* Make all the #if cases in the code esier to read */
-/* XXX can it be set to 1? */
#ifndef DRI2INFOREC_VERSION
-#define DRI2INFOREC_VERSION 0
+#define DRI2INFOREC_VERSION 1
+#endif
+
+#if DRI2INFOREC_VERSION == 2
+static Bool set_format_in_do_create_buffer;
#endif
typedef struct {
@@ -147,7 +149,9 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
#if DRI2INFOREC_VERSION == 2
- ((DRI2Buffer2Ptr)buffer)->format = 0;
+ /* ABI forwards/backwards compatibility */
+ if (set_format_in_do_create_buffer)
+ ((DRI2Buffer2Ptr)buffer)->format = 0;
#elif DRI2INFOREC_VERSION >= 3
buffer->format = 0;
#endif
@@ -211,7 +215,9 @@ dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
xfree(buffer);
}
-#else /* DRI2INFOREC_VERSION < 2 */
+#endif /* DRI2INFOREC_VERSION >= 2 */
+
+#if DRI2INFOREC_VERSION <= 2
static DRI2BufferPtr
dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count)
@@ -261,7 +267,7 @@ dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
-#endif /* DRI2INFOREC_VERSION >= 2 */
+#endif /* DRI2INFOREC_VERSION <= 2 */
static void
dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
@@ -369,12 +375,19 @@ xorg_dri2_init(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
-
#if DRI2INFOREC_VERSION >= 2
- dri2info.version = DRI2INFOREC_VERSION;
-#else
- dri2info.version = 1;
+ int major, minor;
+
+ if (xf86LoaderCheckSymbol("DRI2Version")) {
+ DRI2Version(&major, &minor);
+ } else {
+ /* Assume version 1.0 */
+ major = 1;
+ minor = 0;
+ }
#endif
+
+ dri2info.version = DRI2INFOREC_VERSION;
dri2info.fd = ms->fd;
dri2info.driverName = pScrn->driverName;
@@ -383,7 +396,22 @@ xorg_dri2_init(ScreenPtr pScreen)
#if DRI2INFOREC_VERSION >= 2
dri2info.CreateBuffer = dri2_create_buffer;
dri2info.DestroyBuffer = dri2_destroy_buffer;
-#else
+#endif
+
+ /* For X servers in the 1.6.x series there where two DRI2 version.
+ * This allows us to build one binary that works on both servers.
+ */
+#if DRI2INFOREC_VERSION == 2
+ if (minor == 0) {
+ set_format_in_do_create_buffer = FALSE;
+ dri2info.CreateBuffers = dri2_create_buffers;
+ dri2info.DestroyBuffers = dri2_destroy_buffers;
+ } else
+ set_format_in_do_create_buffer = FALSE;
+#endif
+
+ /* For version 1 set these unconditionaly. */
+#if DRI2INFOREC_VERSION == 1
dri2info.CreateBuffers = dri2_create_buffers;
dri2info.DestroyBuffers = dri2_destroy_buffers;
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index b02fe68f313..f53a879a14a 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -45,7 +45,6 @@
#include "miscstruct.h"
#include "dixstruct.h"
#include "xf86xv.h"
-#include <X11/extensions/Xv.h>
#ifndef XSERVER_LIBPCIACCESS
#error "libpciaccess needed"
#endif
@@ -79,11 +78,13 @@ typedef enum
{
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
+ OPTION_DEBUG_FALLBACK,
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -111,6 +112,28 @@ xorg_tracker_set_functions(ScrnInfoPtr scrn)
scrn->ValidMode = drv_valid_mode;
}
+Bool
+xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device)
+{
+ char *BusID = xalloc(64);
+ sprintf(BusID, "pci:%04x:%02x:%02x.%d",
+ device->domain, device->bus,
+ device->dev, device->func);
+
+ if (drmCheckModesettingSupported(BusID)) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
+ "Drm modesetting not supported %s\n", BusID);
+ xfree(BusID);
+ return FALSE;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
+ "Drm modesetting supported on %s\n", BusID);
+
+ xfree(BusID);
+ return TRUE;
+}
+
/*
* Internal function definitions
@@ -206,16 +229,41 @@ drv_init_drm(ScrnInfoPtr pScrn)
ms->PciInfo->dev, ms->PciInfo->func
);
- ms->fd = drmOpen(NULL, BusID);
- if (ms->fd < 0)
- return FALSE;
+ ms->api = drm_api_create();
+ ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID);
+ xfree(BusID);
+
+ if (ms->fd >= 0)
+ return TRUE;
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+
+ ms->api = NULL;
+
+ return FALSE;
}
return TRUE;
}
static Bool
+drv_close_drm(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+ ms->api = NULL;
+
+ drmClose(ms->fd);
+ ms->fd = -1;
+
+ return TRUE;
+}
+
+static Bool
drv_init_resource_management(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
@@ -229,7 +277,6 @@ drv_init_resource_management(ScrnInfoPtr pScrn)
if (ms->screen || ms->kms)
return TRUE;
- ms->api = drm_api_create();
if (ms->api) {
ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
@@ -269,10 +316,6 @@ drv_close_resource_management(ScrnInfoPtr pScrn)
}
ms->screen = NULL;
- if (ms->api && ms->api->destroy)
- ms->api->destroy(ms->api);
- ms->api = NULL;
-
#ifdef HAVE_LIBKMS
if (ms->kms)
kms_destroy(&ms->kms);
@@ -629,10 +672,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
+ ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
+ ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
+
if (ms->screen) {
- ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
- OPTION_2D_ACCEL, TRUE));
- ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+ ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
xorg_xv_init(pScreen);
#ifdef DRI2
@@ -640,6 +684,17 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#endif
}
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
+ ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
+ ms->debug_fallback ? "enabled" : "disabled");
+#ifdef DRI2
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is %s\n",
+ ms->screen ? "enabled" : "disabled");
+#else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
+#endif
+
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
@@ -823,8 +878,7 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
drv_close_resource_management(pScrn);
- drmClose(ms->fd);
- ms->fd = -1;
+ drv_close_drm(pScrn);
pScrn->vtSema = FALSE;
pScreen->CloseScreen = ms->CloseScreen;
@@ -954,7 +1008,11 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
int ret;
attr[0] = KMS_BO_TYPE;
+#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8
+ attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8;
+#else
attr[1] = KMS_BO_TYPE_SCANOUT;
+#endif
attr[2] = KMS_WIDTH;
attr[3] = pScrn->virtualX;
attr[4] = KMS_HEIGHT;
@@ -1012,12 +1070,22 @@ drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
goto err_destroy;
pScreen->ModifyPixmapHeader(rootPixmap,
- pScreen->width,
- pScreen->height,
+ pScrn->virtualX,
+ pScrn->virtualY,
pScreen->rootDepth,
pScrn->bitsPerPixel,
stride,
ptr);
+
+ /* This a hack to work around EnableDisableFBAccess setting the pointer
+ * the real fix would be to replace pScrn->EnableDisableFBAccess hook
+ * and set the rootPixmap->devPrivate.ptr to something valid before that.
+ *
+ * But in its infinit visdome something uses either this some times before
+ * that, so our hook doesn't get called before the crash happens.
+ */
+ pScrn->pixmapPrivate.ptr = ptr;
+
return TRUE;
err_destroy:
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index d9432babf18..70af0c5fed3 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -41,9 +41,7 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-#include "util/u_format.h"
#include "util/u_rect.h"
#include "util/u_math.h"
#include "util/u_debug.h"
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index bed17caab77..3e5e6bd6a6e 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -6,11 +6,9 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_memory.h"
-#include "util/u_simple_shaders.h"
#include "tgsi/tgsi_ureg.h"
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 251f331ea7a..13c3fb97e3b 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -49,8 +49,6 @@
#include <X11/extensions/dpms.h>
#endif
-#include "X11/Xatom.h"
-
#include "xorg_tracker.h"
static char *output_enum_list[] = {
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 8f729b565b1..a3c3993ab81 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -5,7 +5,6 @@
#include "cso_cache/cso_context.h"
#include "util/u_draw_quad.h"
-#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
@@ -445,11 +444,11 @@ void renderer_copy_prepare(struct xorg_renderer *r,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(r->cso, &blend);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 4d5d4780dc4..a88b1d520dc 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -112,6 +112,7 @@ typedef struct _modesettingRec
/* exa */
struct exa_context *exa;
Bool noEvict;
+ Bool accelerate_2d;
Bool debug_fallback;
/* winsys hocks */
diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h
index 47ee4b9ffd8..865733bca2b 100644
--- a/src/gallium/state_trackers/xorg/xorg_winsys.h
+++ b/src/gallium/state_trackers/xorg/xorg_winsys.h
@@ -45,5 +45,6 @@
void xorg_tracker_set_functions(ScrnInfoPtr scrn);
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
+Bool xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device);
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 5bf0e94b627..3dcef22c132 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -11,9 +11,6 @@
#include "cso_cache/cso_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
-
-#include "util/u_format.h"
/*XXX get these from pipe's texture limits */
#define IMAGE_MAX_WIDTH 2048
@@ -403,14 +400,14 @@ bind_blend_state(struct xorg_xv_port_priv *port)
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
/* porter&duff src */
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
cso_set_blend(port->r->cso, &blend);
}
diff --git a/src/gallium/winsys/drm/Makefile.egl_g3d b/src/gallium/winsys/drm/Makefile.egl
index 3ce27258529..b1f20385502 100644
--- a/src/gallium/winsys/drm/Makefile.egl_g3d
+++ b/src/gallium/winsys/drm/Makefile.egl
@@ -1,4 +1,4 @@
-# src/gallium/winsys/drm/Makefile.egl_g3d
+# src/gallium/winsys/drm/Makefile.egl
# The driver Makefile should define
#
@@ -13,10 +13,10 @@ EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
common_LIBS = -ldrm -lm -ldl
-x11_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglx11.a
+x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a
x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
-kms_ST = $(TOP)/src/gallium/state_trackers/egl_g3d/libeglkms.a
+kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
kms_LIBS = $(common_LIBS)
##### RULES #####
@@ -29,17 +29,16 @@ kms_LIBS = $(common_LIBS)
EGL_DISPLAY_DRIVERS = $(foreach dpy, $(EGL_DISPLAYS), egl_$(dpy)_$(EGL_DRIVER_NAME).so)
-LIB_GALLIUM_DIR = $(TOP)/$(LIB_DIR)/gallium
-EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(LIB_GALLIUM_DIR)/$(drv))
+EGL_DISPLAY_LIBS = $(foreach drv, $(EGL_DISPLAY_DRIVERS), $(TOP)/$(LIB_DIR)/$(drv))
default: $(EGL_DISPLAY_LIBS)
-$(EGL_DISPLAY_LIBS): $(LIB_GALLIUM_DIR)/%.so: %.so
- @mkdir -p $(LIB_GALLIUM_DIR)
- $(INSTALL) $^ $(LIB_GALLIUM_DIR)
+$(EGL_DISPLAY_LIBS): $(TOP)/$(LIB_DIR)/%.so: %.so
+ $(INSTALL) $< $(TOP)/$(LIB_DIR)
define mklib-egl
-$(MKLIB) -noprefix -o $@ $(EGL_DRIVER_OBJECTS) \
+$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \
-Wl,--whole-archive $($(1)_ST) -Wl,--no-whole-archive \
$(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $($(1)_LIBS) $(EGL_DRIVER_LIBS)
endef
@@ -55,10 +54,9 @@ clean:
-rm -f $(EGL_DISPLAY_DRIVERS)
install: $(EGL_DISPLAY_LIBS)
- @$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
- @echo "Install $(EGL_DISPLAY_DRIVERS)"
- @for lib in "$(EGL_DISPLAY_LIBS)"; do \
- $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR); \
+ $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
+ for lib in $(EGL_DISPLAY_LIBS); do \
+ $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
done
depend:
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 9635c3c50e9..960353a73d9 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -82,18 +82,11 @@ SHARED_INCLUDES = \
default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
- $(MKLIB) -noprefix -o $@ \
+ $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
$(OBJECTS) $(PIPE_DRIVERS) \
-Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
$(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
-$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
- $(MKLIB) -o $(LIBNAME_EGL) \
- -linker "$(CC)" \
- -noprefix \
- $(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \
- --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS)
-
$(TOP)/$(LIB_DIR)/gallium:
mkdir -p $@
diff --git a/src/gallium/winsys/drm/i965/egl/Makefile b/src/gallium/winsys/drm/i965/egl/Makefile
index a1b32eb2a79..1c132582005 100644
--- a/src/gallium/winsys/drm/i965/egl/Makefile
+++ b/src/gallium/winsys/drm/i965/egl/Makefile
@@ -1,29 +1,14 @@
TOP = ../../../../../..
-GALLIUMDIR = ../../../..
include $(TOP)/configs/current
-LIBNAME = EGL_i965.so
+EGL_DRIVER_NAME = i965
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
- $(GALLIUMDIR)/winsys/drm/i965/gem/libi965drm.a \
+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
-DRIVER_SOURCES =
-
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES) \
- $(DRIVER_SOURCES)
-
-DRIVER_EXTRAS = -ldrm_intel
-
-ASM_SOURCES =
-
-DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
- && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
-
-include ../../Makefile.template
-
-symlinks:
+include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/i965/egl_g3d/dummy.c b/src/gallium/winsys/drm/i965/egl/dummy.c
index 4a1bc28b0b6..4a1bc28b0b6 100644
--- a/src/gallium/winsys/drm/i965/egl_g3d/dummy.c
+++ b/src/gallium/winsys/drm/i965/egl/dummy.c
diff --git a/src/gallium/winsys/drm/i965/egl_g3d/Makefile b/src/gallium/winsys/drm/i965/egl_g3d/Makefile
deleted file mode 100644
index dd2efe24855..00000000000
--- a/src/gallium/winsys/drm/i965/egl_g3d/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_g3d
diff --git a/src/gallium/winsys/drm/i965/xorg/Makefile b/src/gallium/winsys/drm/i965/xorg/Makefile
index 65d521fc1ce..c25726b0bb1 100644
--- a/src/gallium/winsys/drm/i965/xorg/Makefile
+++ b/src/gallium/winsys/drm/i965/xorg/Makefile
@@ -36,7 +36,7 @@ all default: $(TARGET) $(TARGET_STAGING)
$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
- $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_radeon
+ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
$(TOP)/$(LIB_DIR)/gallium:
mkdir -p $@
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index 1397e9f7290..60d675ca73d 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -1,29 +1,14 @@
TOP = ../../../../../..
-GALLIUMDIR = ../../../..
include $(TOP)/configs/current
-LIBNAME = EGL_i915.so
+EGL_DRIVER_NAME = i915
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_intel
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
- $(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
+EGL_DRIVER_PIPES = \
+ $(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915/libi915.a
-DRIVER_SOURCES =
-
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES) \
- $(DRIVER_SOURCES)
-
-DRIVER_EXTRAS = -ldrm_intel
-
-ASM_SOURCES =
-
-DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
- && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
-
-include ../../Makefile.template
-
-symlinks:
+include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/intel/egl_g3d/dummy.c b/src/gallium/winsys/drm/intel/egl/dummy.c
index 4a1bc28b0b6..4a1bc28b0b6 100644
--- a/src/gallium/winsys/drm/intel/egl_g3d/dummy.c
+++ b/src/gallium/winsys/drm/intel/egl/dummy.c
diff --git a/src/gallium/winsys/drm/intel/egl_g3d/Makefile b/src/gallium/winsys/drm/intel/egl_g3d/Makefile
deleted file mode 100644
index cdbb680773c..00000000000
--- a/src/gallium/winsys/drm/intel/egl_g3d/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = i915
-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/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/i915/libi915.a
-
-include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
index 450ae09b345..8c8176e44ac 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -196,6 +196,7 @@ destroy(struct drm_api *api)
struct drm_api intel_drm_api =
{
.name = "i915",
+ .driver_name = "i915",
.create_context = intel_drm_create_context,
.create_screen = intel_drm_create_screen,
.texture_from_shared_handle = intel_drm_texture_from_shared_handle,
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 4b2c6a1025e..75cd1e2902b 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -54,6 +54,16 @@ static struct dri1_api nouveau_dri1_api = {
nouveau_dri1_front_surface,
};
+static void
+nouveau_drm_destroy_winsys(struct pipe_winsys *s)
+{
+ struct nouveau_winsys *nv_winsys = nouveau_winsys(s);
+ struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen);
+ nouveau_device_close(&nv_screen->device);
+ FREE(nv_winsys->pctx);
+ FREE(nv_winsys);
+}
+
static struct pipe_screen *
nouveau_drm_create_screen(struct drm_api *api, int fd,
struct drm_create_screen_arg *arg)
@@ -105,6 +115,7 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return NULL;
}
ws = &nvws->base;
+ ws->destroy = nouveau_drm_destroy_winsys;
nvws->pscreen = init(ws, dev);
if (!nvws->pscreen) {
@@ -255,6 +266,7 @@ nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
struct drm_api drm_api_hooks = {
.name = "nouveau",
+ .driver_name = "nouveau",
.create_screen = nouveau_drm_create_screen,
.create_context = nouveau_drm_create_context,
.texture_from_shared_handle = nouveau_drm_pt_from_name,
diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile b/src/gallium/winsys/drm/nouveau/egl/Makefile
index 865a5d56a97..8e812acc86b 100644
--- a/src/gallium/winsys/drm/nouveau/egl_g3d/Makefile
+++ b/src/gallium/winsys/drm/nouveau/egl/Makefile
@@ -16,4 +16,4 @@ EGL_DRIVER_PIPES = \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-include ../../Makefile.egl_g3d
+include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c b/src/gallium/winsys/drm/nouveau/egl/dummy.c
index 4a1bc28b0b6..4a1bc28b0b6 100644
--- a/src/gallium/winsys/drm/nouveau/egl_g3d/dummy.c
+++ b/src/gallium/winsys/drm/nouveau/egl/dummy.c
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 385fa857b56..f484503e0e6 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -51,6 +51,26 @@ 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,
@@ -58,6 +78,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
{
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);
@@ -70,18 +91,16 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
radeon_buffer->base.usage = usage;
radeon_buffer->base.size = size;
- domain = 0;
-
- 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;
+ 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) {
@@ -133,8 +152,16 @@ static void radeon_buffer_del(struct pipe_buffer *buffer)
struct radeon_pipe_buffer *radeon_buffer =
(struct radeon_pipe_buffer*)buffer;
- radeon_bo_unref(radeon_buffer->bo);
- free(radeon_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,
@@ -146,6 +173,10 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
(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;
@@ -174,7 +205,31 @@ static void radeon_buffer_unmap(struct pipe_winsys *ws,
struct radeon_pipe_buffer *radeon_buffer =
(struct radeon_pipe_buffer*)buffer;
- radeon_bo_unmap(radeon_buffer->bo);
+ 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_pipe_buffer *radeon_buffer =
+ (struct radeon_pipe_buffer*)buffer;
+ uint32_t flags = 0;
+
+ if (microtiled) {
+ flags |= RADEON_BO_FLAGS_MICRO_TILE;
+ }
+ if (macrotiled) {
+ flags |= RADEON_BO_FLAGS_MACRO_TILE;
+ }
+
+ radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch);
}
static void radeon_fence_reference(struct pipe_winsys *ws,
@@ -279,5 +334,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
radeon_ws->base.get_name = radeon_get_name;
+ radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling;
+
return radeon_ws;
}
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index d7f17564a9f..de71cb2f42d 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -36,7 +36,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-//#include "state_tracker/st_public.h"
+#include "pipebuffer/pb_buffer.h"
#include "util/u_memory.h"
@@ -49,7 +49,10 @@
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;
};
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 851c2236979..bff6fdc1ad0 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -40,12 +40,16 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys)
struct drm_radeon_info info = {0};
int target = 0;
int retval;
+ drmVersionPtr version;
info.value = (unsigned long)&target;
/* We do things in a specific order here.
*
- * First, the PCI ID. This is essential and should return usable numbers
+ * DRM version first. We need to be sure we're running on a KMS chipset.
+ * This is also for some features.
+ *
+ * Then, the PCI ID. This is essential and should return usable numbers
* for all Radeons. If this fails, we probably got handed an FD for some
* non-Radeon card.
*
@@ -55,8 +59,18 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys)
*
* The GEM info is actually bogus on the kernel side, as well as our side
* (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
- * we don't actually use the info for anything yet.
- * XXX update the above when we can safely use vram_size instead of vram_visible */
+ * we don't actually use the info for anything yet. */
+
+ version = drmGetVersion(fd);
+ if (version->version_major != 2) {
+ fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
+ "only compatible with 2.x.x\n", __FUNCTION__,
+ version->version_major, version->version_minor,
+ version->version_patchlevel);
+ drmFreeVersion(version);
+ exit(1);
+ }
+
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
@@ -92,16 +106,18 @@ static void do_ioctls(int fd, struct radeon_winsys* winsys)
exit(1);
}
winsys->gart_size = gem_info.gart_size;
- /* XXX */
- winsys->vram_size = gem_info.vram_visible;
-}
-
-/* Guess at whether this chipset should use r300g.
- *
- * I believe that this check is valid, but I haven't been exhaustive. */
-static boolean is_r3xx(int pciid)
-{
- return (pciid > 0x3150) && (pciid < 0x796f);
+ winsys->vram_size = gem_info.vram_size;
+
+ debug_printf("radeon: Successfully grabbed chipset info from kernel!\n"
+ "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n"
+ "radeon: GART size: %d MB VRAM size: %d MB\n",
+ version->version_major, version->version_minor,
+ version->version_patchlevel, winsys->pci_id,
+ winsys->gb_pipes, winsys->z_pipes,
+ winsys->gart_size / 1024 / 1024,
+ winsys->vram_size / 1024 / 1024);
+
+ drmFreeVersion(version);
}
/* Create a pipe_screen. */
@@ -136,12 +152,13 @@ struct pipe_context* radeon_create_context(struct drm_api* api,
}
boolean radeon_buffer_from_texture(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride)
{
/* XXX fix this */
- return r300_get_texture_buffer(texture, buffer, stride);
+ return r300_get_texture_buffer(screen, texture, buffer, stride);
}
/* Create a buffer from a handle. */
@@ -208,7 +225,7 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api,
struct radeon_pipe_buffer* radeon_buffer;
struct pipe_buffer *buffer = NULL;
- if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
return FALSE;
}
@@ -240,7 +257,7 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api,
unsigned *handle)
{
struct pipe_buffer *buffer = NULL;
- if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
return FALSE;
}
@@ -253,6 +270,7 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api,
struct drm_api drm_api_hooks = {
.name = "radeon",
+ .driver_name = "radeon",
.create_screen = radeon_create_screen,
.create_context = radeon_create_context,
.texture_from_shared_handle = radeon_texture_from_shared_handle,
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index bf0e78138d7..077388ee028 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -56,6 +56,7 @@ struct pipe_context* radeon_create_context(struct drm_api* api,
struct pipe_screen* screen);
boolean radeon_buffer_from_texture(struct drm_api* api,
+ struct pipe_screen* screen,
struct pipe_texture* texture,
struct pipe_buffer** buffer,
unsigned* stride);
@@ -76,4 +77,13 @@ boolean radeon_global_handle_from_buffer(struct drm_api* api,
unsigned* handle);
void radeon_destroy_drm_api(struct drm_api* api);
+
+/* Guess at whether this chipset should use r300g.
+ *
+ * I believe that this check is valid, but I haven't been exhaustive. */
+static INLINE boolean is_r3xx(int pciid)
+{
+ return (pciid > 0x3150) && (pciid < 0x796f);
+}
+
#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 0875ee41cbf..d759beaba13 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -81,9 +81,13 @@ static void radeon_write_cs_reloc(struct radeon_winsys* winsys,
uint32_t flags)
{
int retval = 0;
+ struct radeon_pipe_buffer* radeon_buffer =
+ (struct radeon_pipe_buffer*)pbuffer;
- retval = radeon_cs_write_reloc(winsys->priv->cs,
- ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
+ 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",
@@ -108,6 +112,11 @@ 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) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
index 9edc9e038c3..864082b99b3 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h
@@ -100,6 +100,12 @@ struct radeon_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/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile
index 6a1448d1b9b..cd4f9b20f06 100644
--- a/src/gallium/winsys/drm/radeon/egl/Makefile
+++ b/src/gallium/winsys/drm/radeon/egl/Makefile
@@ -1,26 +1,14 @@
TOP = ../../../../../..
-GALLIUMDIR = ../../../..
include $(TOP)/configs/current
-LIBNAME = EGL_r300.so
+EGL_DRIVER_NAME = radeon
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS = -ldrm_radeon
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
- $(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \
+EGL_DRIVER_PIPES = \
+ $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
-DRIVER_SOURCES =
-
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES) \
- $(DRIVER_SOURCES)
-
-DRIVER_EXTRAS = -ldrm_radeon
-
-ASM_SOURCES =
-
-include ../../Makefile.template
-
-symlinks:
+include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c b/src/gallium/winsys/drm/radeon/egl/dummy.c
index 4a1bc28b0b6..4a1bc28b0b6 100644
--- a/src/gallium/winsys/drm/radeon/egl_g3d/dummy.c
+++ b/src/gallium/winsys/drm/radeon/egl/dummy.c
diff --git a/src/gallium/winsys/drm/radeon/egl_g3d/Makefile b/src/gallium/winsys/drm/radeon/egl_g3d/Makefile
deleted file mode 100644
index 9027a5ff46d..00000000000
--- a/src/gallium/winsys/drm/radeon/egl_g3d/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = r300
-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/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/r300/libr300.a
-
-include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/swrast/Makefile b/src/gallium/winsys/drm/swrast/Makefile
new file mode 100644
index 00000000000..363b89584f2
--- /dev/null
+++ b/src/gallium/winsys/drm/swrast/Makefile
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 00000000000..93931ae22b9
--- /dev/null
+++ b/src/gallium/winsys/drm/swrast/core/Makefile
@@ -0,0 +1,10 @@
+# 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/core/swrast_drm_api.c b/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c
new file mode 100644
index 00000000000..8c9f80e2c15
--- /dev/null
+++ b/src/gallium/winsys/drm/swrast/core/swrast_drm_api.c
@@ -0,0 +1,13 @@
+#include "state_tracker/drm_api.h"
+
+static struct drm_api swrast_drm_api =
+{
+ .name = "swrast",
+};
+
+struct drm_api *
+drm_api_create()
+{
+ (void) swrast_drm_api;
+ return NULL;
+}
diff --git a/src/gallium/winsys/drm/swrast/egl/Makefile b/src/gallium/winsys/drm/swrast/egl/Makefile
new file mode 100644
index 00000000000..26fe2d2805a
--- /dev/null
+++ b/src/gallium/winsys/drm/swrast/egl/Makefile
@@ -0,0 +1,12 @@
+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/egl_g3d/dummy.c b/src/gallium/winsys/drm/swrast/egl/dummy.c
index 4a1bc28b0b6..4a1bc28b0b6 100644
--- a/src/gallium/winsys/drm/vmware/egl_g3d/dummy.c
+++ b/src/gallium/winsys/drm/swrast/egl/dummy.c
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_context.c b/src/gallium/winsys/drm/vmware/core/vmw_context.c
index b6997588de4..b5fd4f5a6a1 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_context.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_context.c
@@ -41,9 +41,18 @@
#define VMW_COMMAND_SIZE (64*1024)
#define VMW_SURFACE_RELOCS (1024)
+#define VMW_REGION_RELOCS (512)
#define VMW_MUST_FLUSH_STACK 8
+struct vmw_region_relocation
+{
+ struct SVGAGuestPtr *where;
+ struct pb_buffer *buffer;
+ /* TODO: put offset info inside where */
+ uint32 offset;
+};
+
struct vmw_svga_winsys_context
{
struct svga_winsys_context base;
@@ -69,10 +78,31 @@ struct vmw_svga_winsys_context
uint32_t staged;
uint32_t reserved;
} surface;
+
+ struct {
+ struct vmw_region_relocation relocs[VMW_REGION_RELOCS];
+ uint32_t size;
+ uint32_t used;
+ uint32_t staged;
+ uint32_t reserved;
+ } region;
struct pb_validate *validate;
uint32_t last_fence;
+
+ /**
+ * The amount of GMR that is referred by the commands currently batched
+ * in the context.
+ */
+ uint32_t seen_regions;
+
+ /**
+ * Whether this context should fail to reserve more commands, not because it
+ * ran out of command space, but because a substantial ammount of GMR was
+ * referred.
+ */
+ boolean preemptive_flush;
};
@@ -96,6 +126,19 @@ vmw_swc_flush(struct svga_winsys_context *swc,
ret = pb_validate_validate(vswc->validate);
assert(ret == PIPE_OK);
if(ret == PIPE_OK) {
+
+ /* Apply relocations */
+ for(i = 0; i < vswc->region.used; ++i) {
+ struct vmw_region_relocation *reloc = &vswc->region.relocs[i];
+ struct SVGAGuestPtr ptr;
+
+ if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr))
+ assert(0);
+
+ ptr.offset += reloc->offset;
+
+ *reloc->where = ptr;
+ }
if (vswc->command.used)
vmw_ioctl_command(vswc->vws,
@@ -121,9 +164,18 @@ vmw_swc_flush(struct svga_winsys_context *swc,
vswc->surface.used = 0;
vswc->surface.reserved = 0;
+ for(i = 0; i < vswc->region.used + vswc->region.staged; ++i) {
+ pb_reference(&vswc->region.relocs[i].buffer, NULL);
+ }
+
+ vswc->region.used = 0;
+ vswc->region.reserved = 0;
+
#ifdef DEBUG
vswc->must_flush = FALSE;
#endif
+ vswc->preemptive_flush = FALSE;
+ vswc->seen_regions = 0;
if(pfence)
*pfence = fence;
@@ -151,8 +203,10 @@ vmw_swc_reserve(struct svga_winsys_context *swc,
if(nr_bytes > vswc->command.size)
return NULL;
- if(vswc->command.used + nr_bytes > vswc->command.size ||
- vswc->surface.used + nr_relocs > vswc->surface.size) {
+ if(vswc->preemptive_flush ||
+ vswc->command.used + nr_bytes > vswc->command.size ||
+ vswc->surface.used + nr_relocs > vswc->surface.size ||
+ vswc->region.used + nr_relocs > vswc->region.size) {
#ifdef DEBUG
vswc->must_flush = TRUE;
debug_backtrace_capture(vswc->must_flush_stack, 1,
@@ -163,11 +217,14 @@ vmw_swc_reserve(struct svga_winsys_context *swc,
assert(vswc->command.used + nr_bytes <= vswc->command.size);
assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
-
+ assert(vswc->region.used + nr_relocs <= vswc->region.size);
+
vswc->command.reserved = nr_bytes;
vswc->surface.reserved = nr_relocs;
vswc->surface.staged = 0;
-
+ vswc->region.reserved = nr_relocs;
+ vswc->region.staged = 0;
+
return vswc->command.buffer + vswc->command.used;
}
@@ -206,20 +263,41 @@ vmw_swc_region_relocation(struct svga_winsys_context *swc,
unsigned flags)
{
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
- struct SVGAGuestPtr ptr;
- struct pb_buffer *buf = vmw_pb_buffer(buffer);
+ struct vmw_region_relocation *reloc;
enum pipe_error ret;
+
+ assert(vswc->region.staged < vswc->region.reserved);
- if(!vmw_gmr_bufmgr_region_ptr(buf, &ptr))
- assert(0);
-
- ptr.offset += offset;
+ reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged];
+ reloc->where = where;
+ pb_reference(&reloc->buffer, vmw_pb_buffer(buffer));
+ reloc->offset = offset;
- *where = ptr;
+ ++vswc->region.staged;
- ret = pb_validate_add_buffer(vswc->validate, buf, flags);
+ ret = pb_validate_add_buffer(vswc->validate, reloc->buffer, flags);
/* TODO: Update pipebuffer to reserve buffers and not fail here */
assert(ret == PIPE_OK);
+
+ /*
+ * Flush preemptively the FIFO commands to keep the GMR working set within
+ * the GMR pool size.
+ *
+ * This is necessary for applications like SPECviewperf that generate huge
+ * amounts of immediate vertex data, so that we don't pile up too much of
+ * that vertex data neither in the guest nor in the host.
+ *
+ * Note that in the current implementation if a region is referred twice in
+ * a command stream, it will be accounted twice. We could detect repeated
+ * regions and count only once, but there is no incentive to do that, since
+ * regions are typically short-lived; always referred in a single command;
+ * and at the worst we just flush the commands a bit sooner, which for the
+ * SVGA virtual device it's not a performance issue since flushing commands
+ * to the FIFO won't cause flushing in the host.
+ */
+ vswc->seen_regions += reloc->buffer->base.size;
+ if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/2)
+ vswc->preemptive_flush = TRUE;
}
@@ -238,6 +316,12 @@ vmw_swc_commit(struct svga_winsys_context *swc)
vswc->surface.used += vswc->surface.staged;
vswc->surface.staged = 0;
vswc->surface.reserved = 0;
+
+ assert(vswc->region.staged <= vswc->region.reserved);
+ assert(vswc->region.used + vswc->region.staged <= vswc->region.size);
+ vswc->region.used += vswc->region.staged;
+ vswc->region.staged = 0;
+ vswc->region.reserved = 0;
}
@@ -246,6 +330,11 @@ vmw_swc_destroy(struct svga_winsys_context *swc)
{
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
unsigned i;
+
+ for(i = 0; i < vswc->region.used; ++i) {
+ pb_reference(&vswc->region.relocs[i].buffer, NULL);
+ }
+
for(i = 0; i < vswc->surface.used; ++i) {
p_atomic_dec(&vswc->surface.handles[i]->validated);
vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
@@ -279,6 +368,7 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
vswc->command.size = VMW_COMMAND_SIZE;
vswc->surface.size = VMW_SURFACE_RELOCS;
+ vswc->region.size = VMW_REGION_RELOCS;
vswc->validate = pb_validate_create();
if(!vswc->validate) {
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen.h b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
index a875107370c..f1d69865e77 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen.h
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen.h
@@ -40,6 +40,10 @@
#include "svga_winsys.h"
+
+#define VMW_GMR_POOL_SIZE (16*1024*1024)
+
+
struct pb_manager;
struct vmw_region;
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
index 4f5ccea4677..d9abde30793 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_dri.c
@@ -85,6 +85,23 @@ vmw_drm_create_screen(struct drm_api *drm_api,
struct pipe_screen *screen;
struct dri1_create_screen_arg *dri1;
+ if (!arg || arg->mode == DRM_CREATE_NORMAL) {
+ struct dri1_api_version drm_ver;
+ drmVersionPtr ver;
+
+ ver = drmGetVersion(fd);
+ if (ver == NULL)
+ return NULL;
+
+ drm_ver.major = ver->version_major;
+ drm_ver.minor = ver->version_minor;
+
+ drmFreeVersion(ver);
+ if (!vmw_dri1_check_version(&drm_ver, &drm_required,
+ &drm_compat, "vmwgfx drm driver"))
+ return NULL;
+ }
+
if (arg != NULL) {
switch (arg->mode) {
case DRM_CREATE_NORMAL:
@@ -220,22 +237,19 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
vmw_svga_winsys_surface_reference(&vsrf, NULL);
}
-/**
- * FIXME: We'd probably want to cache these buffers in the
- * screen, based on handle.
- */
-
-static struct pipe_buffer *
-vmw_drm_buffer_from_handle(struct drm_api *drm_api,
- struct pipe_screen *screen,
- const char *name,
- unsigned handle)
+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)
{
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_buffer *buf;
+ struct pipe_texture *tex;
union drm_vmw_surface_reference_arg arg;
struct drm_vmw_surface_arg *req = &arg.req;
struct drm_vmw_surface_create_req *rep = &arg.rep;
@@ -282,43 +296,28 @@ vmw_drm_buffer_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;
ssrf = svga_winsys_surface(vsrf);
- buf = svga_screen_buffer_wrap_surface(screen, rep->format, ssrf);
- if (!buf)
+ tex = svga_screen_texture_wrap_surface(screen, templat, rep->format, ssrf);
+ if (!tex)
vmw_svga_winsys_surface_reference(&vsrf, NULL);
- return buf;
+ return tex;
out_mip:
vmw_ioctl_surface_destroy(vws, handle);
return NULL;
}
-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)
-{
- struct pipe_buffer *buffer;
- buffer = vmw_drm_buffer_from_handle(drm_api, screen, name, handle);
-
- if (!buffer)
- return NULL;
-
- return screen->texture_blanket(screen, templat, &stride, buffer);
-}
-
static boolean
-vmw_drm_handle_from_buffer(struct drm_api *drm_api,
+vmw_drm_handle_from_texture(struct drm_api *drm_api,
struct pipe_screen *screen,
- struct pipe_buffer *buffer,
+ struct pipe_texture *texture,
+ unsigned *stride,
unsigned *handle)
{
struct svga_winsys_surface *surface =
- svga_screen_buffer_get_winsys_surface(buffer);
+ svga_screen_texture_get_winsys_surface(texture);
struct vmw_svga_winsys_surface *vsrf;
if (!surface)
@@ -326,25 +325,13 @@ vmw_drm_handle_from_buffer(struct drm_api *drm_api,
vsrf = vmw_svga_winsys_surface(surface);
*handle = vsrf->sid;
+ *stride = util_format_get_nblocksx(texture->format, texture->width0) *
+ util_format_get_blocksize(texture->format);
+
vmw_svga_winsys_surface_reference(&vsrf, NULL);
return TRUE;
}
-static boolean
-vmw_drm_handle_from_texture(struct drm_api *drm_api,
- struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned *stride,
- unsigned *handle)
-{
- struct pipe_buffer *buffer;
-
- if (!svga_screen_buffer_from_texture(texture, &buffer, stride))
- return FALSE;
-
- return vmw_drm_handle_from_buffer(drm_api, screen, buffer, handle);
-}
-
static struct pipe_context*
vmw_drm_create_context(struct drm_api *drm_api,
struct pipe_screen *screen)
@@ -359,6 +346,7 @@ static struct dri1_api dri1_api_hooks = {
static struct drm_api vmw_drm_api_hooks = {
.name = "vmwgfx",
+ .driver_name = "vmwgfx",
.create_screen = vmw_drm_create_screen,
.create_context = vmw_drm_create_context,
.texture_from_shared_handle = vmw_drm_texture_from_handle,
diff --git a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
index b1c24b0cb6a..b9823d78575 100644
--- a/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
+++ b/src/gallium/winsys/drm/vmware/core/vmw_screen_pools.c
@@ -53,14 +53,32 @@ vmw_pools_init(struct vmw_winsys_screen *vws)
goto error;
vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
- 16*1024*1024,
+ VMW_GMR_POOL_SIZE,
12 /* 4096 alignment */);
if(!vws->pools.gmr_mm)
goto error;
+ /*
+ * GMR buffers are typically shortlived, but it's possible that at a given
+ * instance a buffer is mapped. So to avoid stalling we tell pipebuffer to
+ * forbid creation of buffers beyond half the GMR pool size,
+ *
+ * XXX: It is unclear weather we want to limit the total amount of temporary
+ * malloc memory used to backup unvalidated GMR buffers. On one hand it is
+ * preferrable to fail an allocation than exhausting the guest memory with
+ * temporary data, but on the other hand it is possible that a stupid
+ * application creates large vertex buffers and does not use them for a long
+ * time -- since the svga pipe driver only emits the DMA uploads when a
+ * buffer is used for drawing this would effectively disabling swapping GMR
+ * buffers to memory. So far, the preemptively flush already seems to keep
+ * total allocated memory within relatively small numbers, so we don't
+ * limit.
+ */
vws->pools.gmr_fenced = fenced_bufmgr_create(
vws->pools.gmr_mm,
- vmw_fence_ops_create(vws));
+ vmw_fence_ops_create(vws),
+ VMW_GMR_POOL_SIZE/2,
+ ~0);
#ifdef DEBUG
vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
diff --git a/src/gallium/winsys/drm/vmware/egl/Makefile b/src/gallium/winsys/drm/vmware/egl/Makefile
index 8e2980c318c..a3e73131c35 100644
--- a/src/gallium/winsys/drm/vmware/egl/Makefile
+++ b/src/gallium/winsys/drm/vmware/egl/Makefile
@@ -1,18 +1,14 @@
-
TOP = ../../../../../..
include $(TOP)/configs/current
-LIBNAME = EGL_svga.so
+EGL_DRIVER_NAME = vmwgfx
+EGL_DRIVER_SOURCES = dummy.c
+EGL_DRIVER_LIBS =
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+EGL_DRIVER_PIPES = \
$(TOP)/src/gallium/winsys/drm/vmware/core/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES)
-
-include ../../Makefile.template
-
-symlinks:
+include ../../Makefile.egl
diff --git a/src/gallium/winsys/drm/vmware/egl/dummy.c b/src/gallium/winsys/drm/vmware/egl/dummy.c
new file mode 100644
index 00000000000..4a1bc28b0b6
--- /dev/null
+++ b/src/gallium/winsys/drm/vmware/egl/dummy.c
@@ -0,0 +1 @@
+/* mklib expects at least one object file */
diff --git a/src/gallium/winsys/drm/vmware/egl_g3d/Makefile b/src/gallium/winsys/drm/vmware/egl_g3d/Makefile
deleted file mode 100644
index 3cf79924e08..00000000000
--- a/src/gallium/winsys/drm/vmware/egl_g3d/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = vmwgfx
-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/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/svga/libsvga.a
-
-include ../../Makefile.egl_g3d
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
index b065b96346a..ff3b992d078 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_video.c
@@ -649,7 +649,8 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
return XvBadAlloc;
}
- port->currBuf = ++port->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
+ if (++(port->currBuf) >= VMWARE_VID_NUM_BUFFERS)
+ port->currBuf = 0;
return Success;
}
diff --git a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
index 4b208719ca3..cd273d091fe 100644
--- a/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
+++ b/src/gallium/winsys/drm/vmware/xorg/vmw_xorg.c
@@ -34,10 +34,10 @@
#include "vmw_hook.h"
static void vmw_xorg_identify(int flags);
-static Bool vmw_xorg_pci_probe(DriverPtr driver,
- int entity_num,
- struct pci_device *device,
- intptr_t match_data);
+_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver,
+ int entity_num,
+ struct pci_device *device,
+ intptr_t match_data);
static const struct pci_id_match vmw_xorg_device_match[] = {
{0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
@@ -126,7 +126,7 @@ vmw_xorg_identify(int flags)
vmw_xorg_chipsets);
}
-static Bool
+_X_EXPORT Bool
vmw_xorg_pci_probe(DriverPtr driver,
int entity_num, struct pci_device *device, intptr_t match_data)
{
diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile
deleted file mode 100644
index 3efb7ed4afa..00000000000
--- a/src/gallium/winsys/egl_xlib/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# src/gallium/winsys/egl_xlib/Makefile
-
-# Build softpipe/xlib/EGL driver library/object: "egl_softpipe.so"
-
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-
-DRIVER_NAME = egl_softpipe.so
-
-
-INCLUDE_DIRS = \
- -I$(TOP)/include \
- -I$(TOP)/src/egl/main \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/auxiliary
-
-WINSYS_SOURCES = \
- egl_xlib.c \
- sw_winsys.c
-
-WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o)
-
-
-LIBS = \
- $(GALLIUM_DRIVERS) \
- $(GALLIUM_AUXILIARIES)
-
-# XXX temporary (should create a separate lib with the GL API funcs and
-# mesa code, as done for ES 1.x, 2.x, OpenVG, etc)
-UNUSED_LIBS = \
- $(TOP)/src/mesa/libglapi.a \
- $(TOP)/src/mesa/libmesagallium.a \
-
-
-LOCAL_CFLAGS =
-
-
-.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
-
-
-.PHONY: library
-
-
-default: depend library Makefile
-
-
-library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME)
-
-
-# Make the egl_softpipe.so library
-$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS)
- $(TOP)/bin/mklib -o $(DRIVER_NAME) \
- -linker "$(CC)" \
- -noprefix \
- -install $(TOP)/$(LIB_DIR) \
- $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \
- -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive
-
-
-depend: $(ALL_SOURCES)
- @ echo "running $(MKDEP)"
- @ rm -f depend # workaround oops on gutsy?!?
- @ touch depend
- @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
- > /dev/null 2>/dev/null
-
-
-install: default
- $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
- @if [ -e $(TOP)/$(LIB_DIR) ]; then \
- $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \
- fi
-
-
-# Emacs tags
-tags:
- etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
-
-clean:
- -rm -f *.o *~ *.bak
-
-
-include depend
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
deleted file mode 100644
index 1d9bac3871c..00000000000
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ /dev/null
@@ -1,853 +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.
- *
- **************************************************************************/
-
-/**
- * EGL / softpipe / xlib winsys module
- *
- * Authors: Brian Paul
- */
-
-
-#include <dlfcn.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-#include "pipe/p_state.h"
-#include "pipe/internal/p_winsys_screen.h"
-#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "softpipe/sp_winsys.h"
-#include "softpipe/sp_texture.h"
-
-#include "eglconfig.h"
-#include "eglconfigutil.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglglobals.h"
-#include "egllog.h"
-#include "eglsurface.h"
-
-#include "state_tracker/st_public.h"
-
-#include "sw_winsys.h"
-
-
-/** subclass of _EGLDriver */
-struct xlib_egl_driver
-{
- _EGLDriver Base; /**< base class */
- EGLint apis;
-};
-
-
-/** driver data of _EGLDisplay */
-struct xlib_egl_display
-{
- Display *Dpy;
-
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-};
-
-
-/** subclass of _EGLContext */
-struct xlib_egl_context
-{
- _EGLContext Base; /**< base class */
-
- struct pipe_context *pipe; /**< Gallium driver context */
- struct st_context *Context; /**< Mesa/gallium state tracker context */
-};
-
-
-/** subclass of _EGLSurface */
-struct xlib_egl_surface
-{
- _EGLSurface Base; /**< base class */
-
- /* These are set for window surface */
- Display *Dpy; /**< The X Display of the window */
- Window Win; /**< The user-created window ID */
- GC Gc;
- XVisualInfo VisInfo;
-
- struct pipe_winsys *winsys;
-
- struct st_framebuffer *Framebuffer;
-};
-
-
-static void
-flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *psurf,
- void *context_private);
-
-
-/** cast wrapper */
-static INLINE struct xlib_egl_driver *
-xlib_egl_driver(_EGLDriver *drv)
-{
- return (struct xlib_egl_driver *) drv;
-}
-
-
-static INLINE struct xlib_egl_display *
-xlib_egl_display(_EGLDisplay *dpy)
-{
- return (struct xlib_egl_display *) dpy->DriverData;
-}
-
-
-static INLINE struct xlib_egl_surface *
-lookup_surface(_EGLSurface *surf)
-{
- return (struct xlib_egl_surface *) surf;
-}
-
-
-static INLINE struct xlib_egl_context *
-lookup_context(_EGLContext *ctx)
-{
- return (struct xlib_egl_context *) ctx;
-}
-
-
-/**
- * Create the EGLConfigs. (one per X visual)
- */
-static void
-create_configs(struct xlib_egl_display *xdpy, _EGLDisplay *disp)
-{
- static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
- EGL_OPENGL_ES2_BIT |
- EGL_OPENVG_BIT |
- EGL_OPENGL_BIT);
- XVisualInfo *visInfo, visTemplate;
- int num_visuals, i;
-
- /* get list of all X visuals, create an EGL config for each */
- visTemplate.screen = DefaultScreen(xdpy->Dpy);
- visInfo = XGetVisualInfo(xdpy->Dpy, VisualScreenMask,
- &visTemplate, &num_visuals);
- if (!visInfo) {
- printf("egl_xlib.c: couldn't get any X visuals\n");
- abort();
- }
-
- for (i = 0; i < num_visuals; i++) {
- _EGLConfig *config = calloc(1, sizeof(_EGLConfig));
- int id = i + 1;
- int rbits = util_bitcount(visInfo[i].red_mask);
- int gbits = util_bitcount(visInfo[i].green_mask);
- int bbits = util_bitcount(visInfo[i].blue_mask);
- int abits = bbits == 8 ? 8 : 0;
- int zbits = 24;
- int sbits = 8;
- int visid = visInfo[i].visualid;
-#if defined(__cplusplus) || defined(c_plusplus)
- int vistype = visInfo[i].c_class;
-#else
- int vistype = visInfo[i].class;
-#endif
-
- _eglInitConfig(config, id);
- SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, rbits + gbits + bbits + abits);
- SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, rbits);
- SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, gbits);
- SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, bbits);
- SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, abits);
- SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, zbits);
- SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits);
- SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid);
- SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype);
- SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
- SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
- SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
- SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT);
- SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
- SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
-
- _eglAddConfig(disp, config);
- }
-
- XFree(visInfo);
-}
-
-
-/**
- * Called via eglInitialize(), drv->API.Initialize().
- */
-static EGLBoolean
-xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLint *major, EGLint *minor)
-{
- struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
- struct xlib_egl_display *xdpy;
-
- xdpy = CALLOC_STRUCT(xlib_egl_display);
- if (!xdpy)
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
- xdpy->Dpy = (Display *) dpy->NativeDisplay;
- if (!xdpy->Dpy) {
- xdpy->Dpy = XOpenDisplay(NULL);
- if (!xdpy->Dpy) {
- free(xdpy);
- return EGL_FALSE;
- }
- }
-
- /* create winsys and pipe screen */
- xdpy->winsys = create_sw_winsys();
- if (!xdpy->winsys) {
- free(xdpy);
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
- }
- xdpy->winsys->flush_frontbuffer = flush_frontbuffer;
- xdpy->screen = softpipe_create_screen(xdpy->winsys);
- if (!xdpy->screen) {
- free(xdpy->winsys);
- free(xdpy);
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
- }
-
- dpy->DriverData = (void *) xdpy;
- dpy->ClientAPIsMask = xdrv->apis;
-
- create_configs(xdpy, dpy);
-
- /* we're supporting EGL 1.4 */
- *major = 1;
- *minor = 4;
-
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglTerminate(), drv->API.Terminate().
- */
-static EGLBoolean
-xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- struct xlib_egl_display *xdpy = xlib_egl_display(dpy);
-
- _eglReleaseDisplayResources(drv, dpy);
- _eglCleanupDisplay(dpy);
-
- xdpy->screen->destroy(xdpy->screen);
- free(xdpy->winsys);
-
- if (!dpy->NativeDisplay)
- XCloseDisplay(xdpy->Dpy);
- free(xdpy);
-
- return EGL_TRUE;
-}
-
-
-static _EGLProc
-xlib_eglGetProcAddress(_EGLDriver *drv, const char *procname)
-{
- return (_EGLProc) st_get_proc_address(procname);
-}
-
-
-static void
-get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo)
-{
- XWindowAttributes attr;
- XVisualInfo visTemp, *vis;
- int num_visuals;
-
- XGetWindowAttributes(dpy, d, &attr);
-
- visTemp.screen = DefaultScreen(dpy);
- visTemp.visualid = attr.visual->visualid;
- vis = XGetVisualInfo(dpy,
- (VisualScreenMask | VisualIDMask),
- &visTemp, &num_visuals);
- if (vis)
- *visInfo = *vis;
-
- XFree(vis);
-}
-
-
-
-/** Get size of given window */
-static Status
-get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
-{
- Window root;
- Status stat;
- int xpos, ypos;
- unsigned int w, h, bw, depth;
- stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
- *width = w;
- *height = h;
- return stat;
-}
-
-
-static void
-check_and_update_buffer_size(struct xlib_egl_surface *surface)
-{
- uint width, height;
- if (surface->Base.Type == EGL_PBUFFER_BIT) {
- width = surface->Base.Width;
- height = surface->Base.Height;
- }
- else {
- get_drawable_size(surface->Dpy, surface->Win, &width, &height);
- }
- st_resize_framebuffer(surface->Framebuffer, width, height);
- surface->Base.Width = width;
- surface->Base.Height = height;
-}
-
-
-
-static void
-display_surface(struct pipe_winsys *pws,
- struct pipe_surface *psurf,
- struct xlib_egl_surface *xsurf)
-{
- struct softpipe_texture *spt = softpipe_texture(psurf->texture);
- XImage *ximage;
- void *data;
-
- if (xsurf->Base.Type == EGL_PBUFFER_BIT)
- return;
-
- ximage = XCreateImage(xsurf->Dpy,
- xsurf->VisInfo.visual,
- xsurf->VisInfo.depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 32, /* bitmap_pad */
- 0); /* bytes_per_line */
-
-
- assert(ximage->format);
- assert(ximage->bitmap_unit);
-
- data = pws->buffer_map(pws, spt->buffer, 0);
-
- /* update XImage's fields */
- ximage->data = data;
- ximage->width = psurf->width;
- ximage->height = psurf->height;
- ximage->bytes_per_line = spt->stride[psurf->level];
-
- XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
- ximage, 0, 0, 0, 0, psurf->width, psurf->height);
-
- XSync(xsurf->Dpy, 0);
-
- ximage->data = NULL;
- XDestroyImage(ximage);
-
- pws->buffer_unmap(pws, spt->buffer);
-}
-
-
-
-/** Display gallium surface in X window */
-static void
-flush_frontbuffer(struct pipe_winsys *pws,
- struct pipe_surface *psurf,
- void *context_private)
-{
- struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private;
- display_surface(pws, psurf, xsurf);
-}
-
-
-
-/**
- * Called via eglCreateContext(), drv->API.CreateContext().
- */
-static _EGLContext *
-xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- _EGLContext *share_list, const EGLint *attrib_list)
-{
- struct xlib_egl_display *xdpy = xlib_egl_display(dpy);
- struct xlib_egl_context *ctx;
- struct st_context *share_ctx = NULL; /* XXX fix */
- __GLcontextModes visual;
-
- ctx = CALLOC_STRUCT(xlib_egl_context);
- if (!ctx)
- return NULL;
-
- /* let EGL lib init the common stuff */
- if (!_eglInitContext(drv, &ctx->Base, conf, attrib_list)) {
- free(ctx);
- return NULL;
- }
-
- /* API-dependent context creation */
- switch (ctx->Base.ClientAPI) {
- case EGL_OPENVG_API:
- case EGL_OPENGL_ES_API:
- _eglLog(_EGL_DEBUG, "Create Context for ES version %d\n",
- ctx->Base.ClientVersion);
- /* fall-through */
- case EGL_OPENGL_API:
- /* create a softpipe context */
- ctx->pipe = softpipe_create(xdpy->screen);
- /* Now do xlib / state tracker inits here */
- _eglConfigToContextModesRec(conf, &visual);
- ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx);
- break;
- default:
- _eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)");
- free(ctx);
- return NULL;
- }
-
- return &ctx->Base;
-}
-
-
-static EGLBoolean
-xlib_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct xlib_egl_context *context = lookup_context(ctx);
-
- if (!_eglIsContextBound(&context->Base)) {
- /* API-dependent clean-up */
- switch (context->Base.ClientAPI) {
- case EGL_OPENGL_ES_API:
- case EGL_OPENVG_API:
- /* fall-through */
- case EGL_OPENGL_API:
- st_destroy_context(context->Context);
- break;
- default:
- assert(0);
- }
- free(context);
- }
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglMakeCurrent(), drv->API.MakeCurrent().
- */
-static EGLBoolean
-xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
-{
- struct xlib_egl_context *context = lookup_context(ctx);
- struct xlib_egl_surface *draw_surf = lookup_surface(draw);
- struct xlib_egl_surface *read_surf = lookup_surface(read);
- struct st_context *oldcontext = NULL;
- _EGLContext *oldctx;
-
- oldctx = _eglGetCurrentContext();
- if (oldctx && _eglIsContextLinked(oldctx))
- oldcontext = st_get_current();
-
- if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
- return EGL_FALSE;
-
- /* Flush before switching context. Check client API? */
- if (oldcontext)
- st_flush(oldcontext, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
- st_make_current((context ? context->Context : NULL),
- (draw_surf ? draw_surf->Framebuffer : NULL),
- (read_surf ? read_surf->Framebuffer : NULL));
-
- if (draw_surf)
- check_and_update_buffer_size(draw_surf);
- if (read_surf && read_surf != draw_surf)
- check_and_update_buffer_size(draw_surf);
-
- return EGL_TRUE;
-}
-
-
-static enum pipe_format
-choose_color_format(const __GLcontextModes *visual)
-{
- if (visual->redBits == 8 &&
- visual->greenBits == 8 &&
- visual->blueBits == 8 &&
- visual->alphaBits == 8) {
- /* XXX this really also depends on the ordering of R,G,B,A */
- return PIPE_FORMAT_A8R8G8B8_UNORM;
- }
- else {
- assert(0);
- return PIPE_FORMAT_NONE;
- }
-}
-
-
-static enum pipe_format
-choose_depth_format(const __GLcontextModes *visual)
-{
- if (visual->depthBits > 0)
- return PIPE_FORMAT_S8Z24_UNORM;
- else
- return PIPE_FORMAT_NONE;
-}
-
-
-static enum pipe_format
-choose_stencil_format(const __GLcontextModes *visual)
-{
- if (visual->stencilBits > 0)
- return PIPE_FORMAT_S8Z24_UNORM;
- else
- return PIPE_FORMAT_NONE;
-}
-
-
-/**
- * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
- */
-static _EGLSurface *
-xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
- NativeWindowType window, const EGLint *attrib_list)
-{
- struct xlib_egl_display *xdpy = xlib_egl_display(disp);
- struct xlib_egl_surface *surf;
- __GLcontextModes visual;
- uint width, height;
-
- surf = CALLOC_STRUCT(xlib_egl_surface);
- if (!surf)
- return NULL;
-
- /* Let EGL lib init the common stuff */
- if (!_eglInitSurface(drv, &surf->Base, EGL_WINDOW_BIT,
- conf, attrib_list)) {
- free(surf);
- return NULL;
- }
-
- /*
- * Now init the Xlib and gallium stuff
- */
- surf->Win = (Window) window; /* The X window ID */
- surf->Dpy = xdpy->Dpy; /* The X display */
- surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL);
-
- surf->winsys = xdpy->winsys;
-
- _eglConfigToContextModesRec(conf, &visual);
- get_drawable_size(surf->Dpy, surf->Win, &width, &height);
- get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo);
-
- surf->Base.Width = width;
- surf->Base.Height = height;
-
- /* Create GL statetracker framebuffer */
- surf->Framebuffer = st_create_framebuffer(&visual,
- choose_color_format(&visual),
- choose_depth_format(&visual),
- choose_stencil_format(&visual),
- width, height,
- (void *) surf);
-
- st_resize_framebuffer(surf->Framebuffer, width, height);
-
- return &surf->Base;
-}
-
-
-static _EGLSurface *
-xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- struct xlib_egl_display *xdpy = xlib_egl_display(disp);
- struct xlib_egl_surface *surf;
- __GLcontextModes visual;
- uint width, height;
- EGLBoolean bind_texture;
-
- surf = CALLOC_STRUCT(xlib_egl_surface);
- if (!surf) {
- _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
- return NULL;
- }
-
- if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
- conf, attrib_list)) {
- free(surf);
- return NULL;
- }
- if (surf->Base.Width < 0 || surf->Base.Height < 0) {
- _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface");
- free(surf);
- return NULL;
- }
-
- bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE);
- width = (uint) surf->Base.Width;
- height = (uint) surf->Base.Height;
- if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) ||
- (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) {
- _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
- free(surf);
- return NULL;
- }
- /* a framebuffer of zero width or height confuses st */
- if (width == 0 || height == 0) {
- _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
- free(surf);
- return NULL;
- }
- /* no mipmap generation */
- if (surf->Base.MipmapTexture) {
- _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
- free(surf);
- return NULL;
- }
-
- surf->winsys = xdpy->winsys;
-
- _eglConfigToContextModesRec(conf, &visual);
-
- /* Create GL statetracker framebuffer */
- surf->Framebuffer = st_create_framebuffer(&visual,
- choose_color_format(&visual),
- choose_depth_format(&visual),
- choose_stencil_format(&visual),
- width, height,
- (void *) surf);
- st_resize_framebuffer(surf->Framebuffer, width, height);
-
- return &surf->Base;
-}
-
-
-static EGLBoolean
-xlib_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
-{
- struct xlib_egl_surface *surf = lookup_surface(surface);
- if (!_eglIsSurfaceBound(&surf->Base)) {
- if (surf->Base.Type != EGL_PBUFFER_BIT)
- XFreeGC(surf->Dpy, surf->Gc);
- st_unreference_framebuffer(surf->Framebuffer);
- free(surf);
- }
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-xlib_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLSurface *surface, EGLint buffer)
-{
- struct xlib_egl_surface *xsurf = lookup_surface(surface);
- struct xlib_egl_context *xctx;
- struct pipe_surface *psurf;
- enum pipe_format format;
- int target;
-
- if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT)
- return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
- if (buffer != EGL_BACK_BUFFER)
- return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
- if (xsurf->Base.BoundToTexture)
- return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
-
- /* this should be updated when choose_color_format is */
- switch (xsurf->Base.TextureFormat) {
- case EGL_TEXTURE_RGB:
- format = PIPE_FORMAT_R8G8B8_UNORM;
- break;
- case EGL_TEXTURE_RGBA:
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
- break;
- default:
- return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- }
-
- switch (xsurf->Base.TextureTarget) {
- case EGL_TEXTURE_2D:
- target = ST_TEXTURE_2D;
- break;
- default:
- return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- }
-
- /* flush properly */
- if (eglGetCurrentSurface(EGL_DRAW) == surface) {
- xctx = lookup_context(_eglGetCurrentContext());
- st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
- NULL);
- }
- else if (_eglIsSurfaceBound(&xsurf->Base)) {
- xctx = lookup_context(xsurf->Base.Binding);
- if (xctx)
- st_finish(xctx->Context);
- }
-
- st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
- &psurf);
- st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format);
- xsurf->Base.BoundToTexture = EGL_TRUE;
-
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-xlib_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
- EGLint buffer)
-{
- struct xlib_egl_surface *xsurf = lookup_surface(surface);
- struct pipe_surface *psurf;
-
- if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT ||
- !xsurf->Base.BoundToTexture)
- return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
- if (buffer != EGL_BACK_BUFFER)
- return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
-
- st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
- &psurf);
- st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel);
- xsurf->Base.BoundToTexture = EGL_FALSE;
-
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
-{
- struct xlib_egl_surface *xsurf = lookup_surface(draw);
- struct pipe_winsys *pws = xsurf->winsys;
- struct pipe_surface *psurf;
-
- st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
- &psurf);
-
- st_notify_swapbuffers(xsurf->Framebuffer);
-
- display_surface(pws, psurf, xsurf);
-
- check_and_update_buffer_size(xsurf);
-
- return EGL_TRUE;
-}
-
-
-/**
- * Determine which API(s) is(are) present by looking for some specific
- * global symbols.
- */
-static EGLint
-find_supported_apis(void)
-{
- EGLint mask = 0;
- void *handle;
-
- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
- if(!handle)
- return mask;
-
- if (dlsym(handle, "st_api_OpenGL_ES1"))
- mask |= EGL_OPENGL_ES_BIT;
-
- if (dlsym(handle, "st_api_OpenGL_ES2"))
- mask |= EGL_OPENGL_ES2_BIT;
-
- if (dlsym(handle, "st_api_OpenGL"))
- mask |= EGL_OPENGL_BIT;
-
- if (dlsym(handle, "st_api_OpenVG"))
- mask |= EGL_OPENVG_BIT;
-
- dlclose(handle);
-
- return mask;
-}
-
-
-static void
-xlib_Unload(_EGLDriver *drv)
-{
- struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
- free(xdrv);
-}
-
-
-/**
- * This is the main entrypoint into the driver.
- * Called by libEGL to instantiate an _EGLDriver object.
- */
-_EGLDriver *
-_eglMain(const char *args)
-{
- struct xlib_egl_driver *xdrv;
-
- _eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args);
-
- xdrv = CALLOC_STRUCT(xlib_egl_driver);
- if (!xdrv)
- return NULL;
-
- _eglInitDriverFallbacks(&xdrv->Base);
- xdrv->Base.API.Initialize = xlib_eglInitialize;
- xdrv->Base.API.Terminate = xlib_eglTerminate;
- xdrv->Base.API.GetProcAddress = xlib_eglGetProcAddress;
- xdrv->Base.API.CreateContext = xlib_eglCreateContext;
- xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
- xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
- xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface;
- xdrv->Base.API.DestroySurface = xlib_eglDestroySurface;
- xdrv->Base.API.BindTexImage = xlib_eglBindTexImage;
- xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage;
- xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
- xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
-
- xdrv->apis = find_supported_apis();
- if (xdrv->apis == 0x0) {
- /* the app isn't directly linked with any EGL-supprted APIs
- * (such as libGLESv2.so) so use an EGL utility to see what
- * APIs might be loaded dynamically on this system.
- */
- xdrv->apis = _eglFindAPIs();
- }
-
- xdrv->Base.Name = "Xlib/softpipe";
- xdrv->Base.Unload = xlib_Unload;
-
- return &xdrv->Base;
-}
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
deleted file mode 100644
index 6ee3ede38cb..00000000000
--- a/src/gallium/winsys/egl_xlib/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 "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_state.h"
-#include "pipe/p_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/winsys/egl_xlib/sw_winsys.h b/src/gallium/winsys/egl_xlib/sw_winsys.h
deleted file mode 100644
index f96c5a14b0a..00000000000
--- a/src/gallium/winsys/egl_xlib/sw_winsys.h
+++ /dev/null
@@ -1,40 +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.
- *
- **************************************************************************/
-
-
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
-
-
-struct pipe_winsys;
-
-
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c
index 13117712c23..67617a470d6 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/winsys/xlib/xlib.c
@@ -105,3 +105,34 @@ 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_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index f7c0099584e..bf78aca6869 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -63,7 +63,7 @@ struct xm_buffer
XImage *tempImage;
#ifdef USE_XSHM
- int shm;
+ boolean shm; /** Is this a shared memory buffer? */
XShmSegmentInfo shminfo;
#endif
};
@@ -152,7 +152,7 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
&b->shminfo,
width, height);
if (b->tempImage == NULL) {
- b->shm = 0;
+ b->shm = FALSE;
return;
}
@@ -169,12 +169,12 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
mesaXErrorFlag = 0;
XDestroyImage(b->tempImage);
b->tempImage = NULL;
- b->shm = 0;
+ b->shm = FALSE;
(void) XSetErrorHandler(old_handler);
return;
}
- b->shm = 1;
+ b->shm = TRUE;
}
#endif /* USE_XSHM */
@@ -204,6 +204,14 @@ 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) {
@@ -213,12 +221,20 @@ xm_buffer_destroy(struct pipe_buffer *buf)
oldBuf->shminfo.shmid = -1;
oldBuf->shminfo.shmaddr = (char *) -1;
}
- else
+
+ if (oldBuf->shm) {
+ oldBuf->data = NULL;
+ }
+
+ if (oldBuf->tempImage) {
+ XDestroyImage(oldBuf->tempImage);
+ oldBuf->tempImage = NULL;
+ }
#endif
- {
- if (!oldBuf->userBuffer) {
- align_free(oldBuf->data);
- }
+
+ if (oldBuf->data && !oldBuf->userBuffer) {
+ /* this was regular malloc'd memory */
+ align_free(oldBuf->data);
}
oldBuf->data = NULL;
@@ -327,10 +343,8 @@ xm_buffer_create(struct pipe_winsys *pws,
buffer->base.usage = usage;
buffer->base.size = size;
- if (buffer->data == NULL) {
- /* align to 16-byte multiple for Cell */
- buffer->data = align_malloc(size, max(alignment, 16));
- }
+ /* align to 16-byte multiple for Cell */
+ buffer->data = align_malloc(size, max(alignment, 16));
return &buffer->base;
}