summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile16
-rw-r--r--SConstruct58
-rw-r--r--common.py9
-rw-r--r--configs/autoconf.in10
-rw-r--r--configs/default16
-rw-r--r--configs/linux-llvm3
-rw-r--r--configure.ac892
-rw-r--r--docs/GL3.txt5
-rw-r--r--docs/egl.html45
-rw-r--r--docs/opengles.html19
-rw-r--r--docs/openvg.html10
-rw-r--r--docs/relnotes-7.11.html2
-rw-r--r--include/EGL/eglplatform.h6
-rw-r--r--include/GL/internal/dri_interface.h5
-rw-r--r--scons/custom.py79
-rwxr-xr-xscons/gallium.py99
-rw-r--r--src/SConscript1
-rw-r--r--src/driclient/include/driclient.h97
-rw-r--r--src/driclient/include/xf86dri.h119
-rw-r--r--src/driclient/src/Makefile19
-rw-r--r--src/driclient/src/XF86dri.c618
-rw-r--r--src/driclient/src/driclient.c310
-rw-r--r--src/driclient/src/xf86dristr.h342
-rw-r--r--src/egl/drivers/dri2/Makefile9
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c86
-rw-r--r--src/egl/drivers/dri2/egl_dri2.h21
-rw-r--r--src/egl/drivers/dri2/platform_drm.c99
-rw-r--r--src/egl/drivers/dri2/platform_wayland.c143
-rw-r--r--src/egl/drivers/dri2/platform_x11.c9
-rw-r--r--src/egl/drivers/glx/egl_glx.c26
-rw-r--r--src/egl/main/Makefile4
-rw-r--r--src/egl/main/eglapi.c30
-rw-r--r--src/egl/main/eglapi.h30
-rw-r--r--src/egl/main/eglarray.c28
-rw-r--r--src/egl/main/eglarray.h28
-rw-r--r--src/egl/main/eglcompiler.h29
-rw-r--r--src/egl/main/eglconfig.c115
-rw-r--r--src/egl/main/eglconfig.h42
-rw-r--r--src/egl/main/eglcontext.c30
-rw-r--r--src/egl/main/eglcontext.h30
-rw-r--r--src/egl/main/eglcurrent.c28
-rw-r--r--src/egl/main/eglcurrent.h28
-rw-r--r--src/egl/main/egldefines.h25
-rw-r--r--src/egl/main/egldisplay.c30
-rw-r--r--src/egl/main/egldisplay.h30
-rw-r--r--src/egl/main/egldriver.c30
-rw-r--r--src/egl/main/egldriver.h30
-rw-r--r--src/egl/main/eglfallbacks.c28
-rw-r--r--src/egl/main/eglglobals.c30
-rw-r--r--src/egl/main/eglglobals.h30
-rw-r--r--src/egl/main/eglimage.c29
-rw-r--r--src/egl/main/eglimage.h29
-rw-r--r--src/egl/main/egllog.c30
-rw-r--r--src/egl/main/egllog.h29
-rw-r--r--src/egl/main/eglmisc.c26
-rw-r--r--src/egl/main/eglmisc.h26
-rw-r--r--src/egl/main/eglmode.c30
-rw-r--r--src/egl/main/eglmode.h30
-rw-r--r--src/egl/main/eglmutex.h28
-rw-r--r--src/egl/main/eglscreen.c30
-rw-r--r--src/egl/main/eglscreen.h30
-rw-r--r--src/egl/main/eglstring.c30
-rw-r--r--src/egl/main/eglstring.h30
-rw-r--r--src/egl/main/eglsurface.c30
-rw-r--r--src/egl/main/eglsurface.h30
-rw-r--r--src/egl/main/eglsync.c28
-rw-r--r--src/egl/main/eglsync.h28
-rw-r--r--src/egl/main/egltypedefs.h30
-rw-r--r--src/egl/wayland/wayland-drm/wayland-drm.c4
-rw-r--r--src/gallium/SConscript74
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aapoint.c9
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.cpp8
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp4
-rw-r--r--src/gallium/auxiliary/indices/u_unfilled_gen.py4
-rw-r--r--src/gallium/auxiliary/indices/u_unfilled_indices.c7
-rw-r--r--src/gallium/auxiliary/os/os_memory.h2
-rw-r--r--src/gallium/auxiliary/os/os_misc.h4
-rw-r--r--src/gallium/auxiliary/os/os_thread.h12
-rw-r--r--src/gallium/auxiliary/os/os_time.c5
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c46
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.h20
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c58
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.h12
-rw-r--r--src/gallium/drivers/i915/Makefile1
-rw-r--r--src/gallium/drivers/i915/SConscript1
-rw-r--r--src/gallium/drivers/i915/TODO15
-rw-r--r--src/gallium/drivers/i915/i915_clear.c2
-rw-r--r--src/gallium/drivers/i915/i915_context.c25
-rw-r--r--src/gallium/drivers/i915/i915_context.h3
-rw-r--r--src/gallium/drivers/i915/i915_fpc.h5
-rw-r--r--src/gallium/drivers/i915/i915_fpc_emit.c72
-rw-r--r--src/gallium/drivers/i915/i915_fpc_translate.c134
-rw-r--r--src/gallium/drivers/i915/i915_query.c86
-rw-r--r--src/gallium/drivers/i915/i915_query.h36
-rw-r--r--src/gallium/drivers/i915/i915_resource.c4
-rw-r--r--src/gallium/drivers/i915/i915_resource.h12
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c196
-rw-r--r--src/gallium/drivers/i915/i915_screen.c15
-rw-r--r--src/gallium/drivers/i915/i915_screen.h6
-rw-r--r--src/gallium/drivers/i915/i915_state.c14
-rw-r--r--src/gallium/drivers/i915/i915_state_derived.c28
-rw-r--r--src/gallium/drivers/i915/i915_state_emit.c94
-rw-r--r--src/gallium/drivers/i915/i915_state_inlines.h25
-rw-r--r--src/gallium/drivers/i915/i915_state_sampler.c52
-rw-r--r--src/gallium/drivers/i915/i915_state_static.c15
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c14
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c15
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c8
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c15
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.c16
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c7
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h1
-rw-r--r--src/gallium/drivers/r300/r300_render.c102
-rw-r--r--src/gallium/drivers/r300/r300_texture.c21
-rw-r--r--src/gallium/drivers/r600/SConscript6
-rw-r--r--src/gallium/drivers/r600/eg_state_inlines.h5
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c8
-rw-r--r--src/gallium/drivers/r600/r600.h1
-rw-r--r--src/gallium/drivers/r600/r600_asm.c2
-rw-r--r--src/gallium/drivers/r600/r600_blit.c47
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c11
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h19
-rw-r--r--src/gallium/drivers/r600/r600_query.c3
-rw-r--r--src/gallium/drivers/r600/r600_shader.c206
-rw-r--r--src/gallium/drivers/r600/r600_shader.h2
-rw-r--r--src/gallium/drivers/r600/r600_state.c59
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c112
-rw-r--r--src/gallium/drivers/r600/r600_state_inlines.h4
-rw-r--r--src/gallium/drivers/r600/r600_texture.c11
-rw-r--r--src/gallium/drivers/r600/r600d.h3
-rw-r--r--src/gallium/drivers/svga/svga_context.c8
-rw-r--r--src/gallium/drivers/svga/svga_context.h3
-rw-r--r--src/gallium/drivers/svga/svga_draw.c17
-rw-r--r--src/gallium/drivers/svga/svga_draw.h3
-rw-r--r--src/gallium/drivers/svga/svga_draw_private.h7
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c216
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h12
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c17
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c119
-rw-r--r--src/gallium/include/pipe/p_config.h4
-rw-r--r--src/gallium/include/state_tracker/st_api.h25
-rw-r--r--src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp33
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.c4
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c1
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h1
-rw-r--r--src/gallium/state_trackers/dri/drm/SConscript2
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c23
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c5
-rw-r--r--src/gallium/state_trackers/egl/Makefile3
-rw-r--r--src/gallium/state_trackers/egl/SConscript5
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c60
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h8
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c141
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c73
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_loader.h1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c2
-rw-r--r--src/gallium/state_trackers/egl/common/native.h50
-rw-r--r--src/gallium/state_trackers/egl/common/native_buffer.h31
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c117
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.h14
-rw-r--r--src/gallium/state_trackers/egl/drm/modeset.c36
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.c124
-rw-r--r--src/gallium/state_trackers/egl/drm/native_drm.h6
-rw-r--r--src/gallium/state_trackers/egl/fbdev/native_fbdev.c384
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c58
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_drm.c34
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_shm.c12
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.c38
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.h7
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c45
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c20
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h6
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c109
-rw-r--r--src/gallium/state_trackers/gbm/Makefile46
-rw-r--r--src/gallium/state_trackers/gbm/gbm_drm.c226
-rw-r--r--src/gallium/state_trackers/gbm/gbm_gallium_drmint.h74
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c15
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c2
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h5
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c48
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c6
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pbuffer.c2
-rw-r--r--src/gallium/state_trackers/wgl/stw_st.c2
-rw-r--r--src/gallium/state_trackers/xorg/SConscript5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c6
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c1
-rw-r--r--src/gallium/targets/Makefile.xorg2
-rw-r--r--src/gallium/targets/SConscript.dri2
-rw-r--r--src/gallium/targets/dri-i915/SConscript4
-rw-r--r--src/gallium/targets/dri-i965/SConscript4
-rw-r--r--src/gallium/targets/dri-swrast/SConscript2
-rw-r--r--src/gallium/targets/egl-static/Makefile201
-rw-r--r--src/gallium/targets/egl-static/SConscript16
-rw-r--r--src/gallium/targets/egl-static/egl.c111
-rw-r--r--src/gallium/targets/egl-static/egl_st.c127
-rw-r--r--src/gallium/targets/egl-static/egl_st.h3
-rw-r--r--src/gallium/targets/egl-static/st_GL.c (renamed from src/gallium/targets/egl/egl.h)22
-rw-r--r--src/gallium/targets/egl/Makefile242
-rw-r--r--src/gallium/targets/egl/egl.c495
-rw-r--r--src/gallium/targets/egl/st_GL.c8
-rw-r--r--src/gallium/targets/egl/st_OpenVG.c8
-rw-r--r--src/gallium/targets/gbm/Makefile169
-rw-r--r--src/gallium/targets/gbm/gbm.c61
-rw-r--r--src/gallium/targets/gbm/pipe_i915.c (renamed from src/gallium/targets/egl/pipe_i915.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_i965.c (renamed from src/gallium/targets/egl/pipe_i965.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_loader.c192
-rw-r--r--src/gallium/targets/gbm/pipe_loader.h48
-rw-r--r--src/gallium/targets/gbm/pipe_nouveau.c (renamed from src/gallium/targets/egl/pipe_nouveau.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_r300.c (renamed from src/gallium/targets/egl/pipe_r300.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_r600.c (renamed from src/gallium/targets/egl/pipe_r600.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_swrast.c (renamed from src/gallium/targets/egl/pipe_swrast.c)0
-rw-r--r--src/gallium/targets/gbm/pipe_vmwgfx.c (renamed from src/gallium/targets/egl/pipe_vmwgfx.c)0
-rw-r--r--src/gallium/targets/libgl-xlib/SConscript2
-rw-r--r--src/gallium/targets/xorg-nouveau/Makefile5
-rw-r--r--src/gallium/targets/xorg-nouveau/nouveau_xorg.c75
-rw-r--r--src/gallium/targets/xorg-vmwgfx/SConscript4
-rw-r--r--src/gallium/tests/trivial/Makefile11
-rw-r--r--src/gallium/tests/trivial/quad-tex.c4
-rw-r--r--src/gallium/tests/trivial/tri.c4
-rw-r--r--src/gallium/winsys/i915/drm/SConscript2
-rw-r--r--src/gallium/winsys/i965/drm/SConscript2
-rw-r--r--src/gallium/winsys/r600/drm/SConscript6
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c15
-rw-r--r--src/gallium/winsys/r600/drm/r600_hw_context.c4
-rw-r--r--src/gallium/winsys/radeon/drm/SConscript6
-rw-r--r--src/gallium/winsys/svga/drm/SConscript2
-rw-r--r--src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c71
-rw-r--r--src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h9
-rw-r--r--src/gallium/winsys/sw/wayland/wayland_sw_winsys.h1
-rw-r--r--src/gbm/Makefile14
-rw-r--r--src/gbm/backends/Makefile14
-rw-r--r--src/gbm/backends/Makefile.template65
-rw-r--r--src/gbm/backends/dri/Makefile22
-rw-r--r--src/gbm/backends/dri/driver_name.c89
-rw-r--r--src/gbm/backends/dri/gbm_dri.c378
-rw-r--r--src/gbm/backends/dri/gbm_driint.h78
-rw-r--r--src/gbm/main/Makefile90
-rw-r--r--src/gbm/main/backend.c128
-rw-r--r--src/gbm/main/backend.h36
-rw-r--r--src/gbm/main/common.c88
-rw-r--r--src/gbm/main/common.h42
-rw-r--r--src/gbm/main/common_drm.h48
-rw-r--r--src/gbm/main/gbm.c190
-rw-r--r--src/gbm/main/gbm.h100
-rw-r--r--src/gbm/main/gbm.pc.in12
-rw-r--r--src/gbm/main/gbmint.h82
-rw-r--r--src/glsl/SConscript4
-rw-r--r--src/glsl/ast_function.cpp35
-rw-r--r--src/glsl/ast_to_hir.cpp16
-rw-r--r--src/glsl/glsl_parser_extras.cpp327
-rw-r--r--src/glsl/glsl_parser_extras.h44
-rw-r--r--src/glsl/ir.cpp8
-rw-r--r--src/glsl/ir.h4
-rw-r--r--src/glsl/ir_constant_expression.cpp13
-rw-r--r--src/glsl/ir_function.cpp9
-rw-r--r--src/glsl/ir_validate.cpp14
-rw-r--r--src/glsl/linker.cpp41
-rw-r--r--src/glsl/lower_if_to_cond_assign.cpp4
-rw-r--r--src/glsl/lower_instructions.cpp11
-rw-r--r--src/glsl/lower_mat_op_to_vec.cpp298
-rw-r--r--src/glsl/main.cpp1
-rw-r--r--src/glw/GLwDrawA.h8
-rw-r--r--src/glw/GLwDrawAP.h4
-rw-r--r--src/glx/SConscript85
-rw-r--r--src/glx/apple/apple_glapi.c24
-rw-r--r--src/glx/applegl_glx.c9
-rw-r--r--src/glx/dri2_glx.c6
-rw-r--r--src/glx/dri_common.c26
-rw-r--r--src/glx/dri_glx.c7
-rw-r--r--src/glx/drisw_glx.c11
-rw-r--r--src/glx/glx_pbuffer.c71
-rw-r--r--src/glx/glxclient.h3
-rw-r--r--src/glx/glxcmds.c44
-rw-r--r--src/glx/glxcurrent.c47
-rw-r--r--src/glx/indirect_glx.c1
-rw-r--r--src/mapi/glapi/SConscript15
-rw-r--r--src/mapi/glapi/gen/ARB_geometry_shader4.xml2
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c8
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c13
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c24
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_state.c19
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h58
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp11
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp2
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_emit.cpp7
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp9
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_visitor.cpp234
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c24
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_state.c19
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c152
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf.c22
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c15
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h30
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c227
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_dump.c26
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c18
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c22
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_state.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_vtbl.c21
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c23
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h12
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c40
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen6_cc.c3
-rw-r--r--src/mesa/drivers/dri/i965/gen6_gs_state.c5
-rw-r--r--src/mesa/drivers/dri/i965/gen6_sampler_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/gen6_scissor_state.c4
-rw-r--r--src/mesa/drivers/dri/i965/gen6_urb.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen6_viewport_state.c3
-rw-r--r--src/mesa/drivers/dri/i965/gen6_vs_state.c7
-rw-r--r--src/mesa/drivers/dri/i965/gen6_wm_state.c28
-rw-r--r--src/mesa/drivers/dri/i965/gen7_disable.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen7_urb.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen7_vs_state.c2
-rw-r--r--src/mesa/drivers/dri/i965/gen7_wm_state.c20
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c72
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.h2
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffers.c84
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c7
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h3
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c182
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.h70
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c27
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c22
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c153
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_obj.h30
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c6
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c68
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c3
-rw-r--r--src/mesa/main/buffers.c21
-rw-r--r--src/mesa/main/buffers.h4
-rw-r--r--src/mesa/main/context.c26
-rw-r--r--src/mesa/main/fbobject.c60
-rw-r--r--src/mesa/main/mtypes.h3
-rw-r--r--src/mesa/main/pack.c15
-rw-r--r--src/mesa/main/renderbuffer.c23
-rw-r--r--src/mesa/main/renderbuffer.h3
-rw-r--r--src/mesa/main/state.c65
-rw-r--r--src/mesa/main/teximage.c8
-rw-r--r--src/mesa/main/texobj.c2
-rw-r--r--src/mesa/main/texstore.c9
-rw-r--r--src/mesa/main/version.h4
-rw-r--r--src/mesa/program/ir_to_mesa.cpp4
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c2
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c10
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c7
-rw-r--r--src/mesa/state_tracker/st_cb_viewport.c15
-rw-r--r--src/mesa/state_tracker/st_context.h6
-rw-r--r--src/mesa/state_tracker/st_draw.c18
-rw-r--r--src/mesa/state_tracker/st_format.c122
-rw-r--r--src/mesa/state_tracker/st_format.h3
-rw-r--r--src/mesa/state_tracker/st_manager.c163
-rw-r--r--src/mesa/vbo/vbo_rebase.c6
371 files changed, 9928 insertions, 5705 deletions
diff --git a/Makefile b/Makefile
index 07ec6868856..0a3deb8168e 100644
--- a/Makefile
+++ b/Makefile
@@ -183,7 +183,7 @@ ultrix-gcc:
# Rules for making release tarballs
-VERSION=7.11-devel
+VERSION=7.12-devel
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
GLUT_NAME = MesaGLUT-$(VERSION)
@@ -345,6 +345,16 @@ EGL_FILES = \
$(DIRECTORY)/src/egl/main/*.pc.in \
$(DIRECTORY)/src/egl/main/*.def
+GBM_FILES = \
+ $(DIRECTORY)/src/gbm/Makefile \
+ $(DIRECTORY)/src/gbm/main/*.pc.in \
+ $(DIRECTORY)/src/gbm/main/*.[ch] \
+ $(DIRECTORY)/src/gbm/main/Makefile \
+ $(DIRECTORY)/src/gbm/backends/Makefile \
+ $(DIRECTORY)/src/gbm/backends/Makefile.template \
+ $(DIRECTORY)/src/gbm/backends/*/*.[ch] \
+ $(DIRECTORY)/src/gbm/backends/*/Makefile \
+
GALLIUM_FILES = \
$(DIRECTORY)/src/mesa/state_tracker/*[ch] \
$(DIRECTORY)/src/gallium/Makefile \
@@ -376,8 +386,7 @@ DRI_FILES = \
$(DIRECTORY)/src/glx/Makefile \
$(DIRECTORY)/src/glx/*.[ch] \
$(APPLE_DRI_FILES) \
- $(DIRECTORY)/src/mesa/drivers/dri/Makefile \
- $(DIRECTORY)/src/mesa/drivers/dri/Makefile.template \
+ $(DIRECTORY)/src/mesa/drivers/dri/Makefile* \
$(DIRECTORY)/src/mesa/drivers/dri/dri.pc.in \
$(DIRECTORY)/src/mesa/drivers/dri/common/xmlpool/*.po \
$(DIRECTORY)/src/mesa/drivers/dri/*/*.[chS] \
@@ -443,6 +452,7 @@ LIB_FILES = \
$(MAPI_FILES) \
$(ES_FILES) \
$(EGL_FILES) \
+ $(GBM_FILES) \
$(GALLIUM_FILES) \
$(DRI_FILES) \
$(SGI_GLU_FILES) \
diff --git a/SConstruct b/SConstruct
index 8607d2cd8e0..4a3fef08059 100644
--- a/SConstruct
+++ b/SConstruct
@@ -40,6 +40,9 @@ env = Environment(
ENV = os.environ,
)
+# XXX: This creates a many problems as it saves...
+#opts.Save('config.py', env)
+
# Backwards compatability with old target configuration variable
try:
targets = ARGUMENTS['targets']
@@ -80,44 +83,6 @@ env.Append(CPPPATH = [
if env['msvc']:
env.Append(CPPPATH = ['#include/c99'])
-# Embedded
-if env['platform'] == 'embedded':
- env.Append(CPPDEFINES = [
- '_POSIX_SOURCE',
- ('_POSIX_C_SOURCE', '199309L'),
- '_SVID_SOURCE',
- '_BSD_SOURCE',
- '_GNU_SOURCE',
-
- 'PTHREADS',
- ])
- env.Append(LIBS = [
- 'm',
- 'pthread',
- 'dl',
- ])
-
-# Posix
-if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'):
- env.Append(CPPDEFINES = [
- '_POSIX_SOURCE',
- ('_POSIX_C_SOURCE', '199309L'),
- '_SVID_SOURCE',
- '_BSD_SOURCE',
- '_GNU_SOURCE',
- 'PTHREADS',
- 'HAVE_POSIX_MEMALIGN',
- ])
- if env['gcc']:
- env.Append(CFLAGS = ['-fvisibility=hidden'])
- if env['platform'] == 'darwin':
- env.Append(CPPDEFINES = ['_DARWIN_C_SOURCE'])
- env.Append(LIBS = [
- 'm',
- 'pthread',
- 'dl',
- ])
-
# for debugging
#print env.Dump()
@@ -130,7 +95,7 @@ if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'):
#
# Create host environent
-if env['crosscompile'] and env['platform'] != 'embedded':
+if env['crosscompile'] and not env['embedded']:
host_env = Environment(
options = opts,
# no tool used
@@ -179,3 +144,18 @@ SConscript(
duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
)
+
+########################################################################
+# List all aliases
+
+try:
+ from SCons.Node.Alias import default_ans
+except ImportError:
+ pass
+else:
+ aliases = default_ans.keys()
+ aliases.sort()
+ env.Help('\n')
+ env.Help('Recognized targets:\n')
+ for alias in aliases:
+ env.Help(' %s\n' % alias)
diff --git a/common.py b/common.py
index 0a3dcdcf543..8657030ea3f 100644
--- a/common.py
+++ b/common.py
@@ -79,14 +79,17 @@ def AddOptions(opts):
from SCons.Options.EnumOption import EnumOption
opts.Add(EnumOption('build', 'build type', 'debug',
allowed_values=('debug', 'checked', 'profile', 'release')))
- opts.Add(BoolOption('quiet', 'quiet command lines', 'yes'))
+ opts.Add(BoolOption('verbose', 'verbose output', 'no'))
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'ppc', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', host_platform,
- allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos', 'freebsd8')))
+ allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'cygwin', 'sunos', 'freebsd8')))
+ opts.Add(BoolOption('embedded', 'embedded build', 'no'))
opts.Add('toolchain', 'compiler toolchain', default_toolchain)
opts.Add(BoolOption('gles', 'EXPERIMENTAL: enable OpenGL ES support', 'no'))
opts.Add(BoolOption('llvm', 'use LLVM', default_llvm))
opts.Add(BoolOption('debug', 'DEPRECATED: debug build', 'yes'))
opts.Add(BoolOption('profile', 'DEPRECATED: profile build', 'no'))
- opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
+ opts.Add(BoolOption('quiet', 'DEPRECATED: profile build', 'yes'))
+ if host_platform == 'windows':
+ opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
diff --git a/configs/autoconf.in b/configs/autoconf.in
index abc01b1b2dd..cac4befe940 100644
--- a/configs/autoconf.in
+++ b/configs/autoconf.in
@@ -75,6 +75,7 @@ GLESv2_LIB = GLESv2
VG_LIB = OpenVG
GLAPI_LIB = glapi
WAYLAND_EGL_LIB = wayland-egl
+GBM_LIB = gbm
# Library names (actual file names)
GL_LIB_NAME = @GL_LIB_NAME@
@@ -88,6 +89,7 @@ GLESv2_LIB_NAME = @GLESv2_LIB_NAME@
VG_LIB_NAME = @VG_LIB_NAME@
GLAPI_LIB_NAME = @GLAPI_LIB_NAME@
WAYLAND_EGL_LIB_NAME = @WAYLAND_EGL_LIB_NAME@
+GBM_LIB_NAME = @GBM_LIB_NAME@
# Globs used to install the lib and all symlinks
GL_LIB_GLOB = @GL_LIB_GLOB@
@@ -101,6 +103,7 @@ GLESv2_LIB_GLOB = @GLESv2_LIB_GLOB@
VG_LIB_GLOB = @VG_LIB_GLOB@
GLAPI_LIB_GLOB = @GLAPI_LIB_GLOB@
WAYLAND_EGL_LIB_GLOB = @WAYLAND_EGL_LIB_GLOB@
+GBM_LIB_GLOB = @GBM_LIB_GLOB@
# Directories to build
LIB_DIR = @LIB_DIR@
@@ -108,6 +111,7 @@ SRC_DIRS = @SRC_DIRS@
GLU_DIRS = @GLU_DIRS@
DRIVER_DIRS = @DRIVER_DIRS@
EGL_DRIVERS_DIRS = @EGL_DRIVERS_DIRS@
+GBM_BACKEND_DIRS = @GBM_BACKEND_DIRS@
GALLIUM_DIRS = @GALLIUM_DIRS@
GALLIUM_DRIVERS_DIRS = @GALLIUM_DRIVERS_DIRS@
GALLIUM_WINSYS_DIRS = @GALLIUM_WINSYS_DIRS@
@@ -147,7 +151,8 @@ GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_CM_LIB_DEPS@
GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv2_LIB_DEPS@
VG_LIB_DEPS = $(EXTRA_LIB_PATH) @VG_LIB_DEPS@
GLAPI_LIB_DEPS = $(EXTRA_LIB_PATH) @GLAPI_LIB_DEPS@
-WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIBPATH) @WAYLAND_EGL_LIB_DEPS@
+WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIB_PATH) @WAYLAND_EGL_LIB_DEPS@
+GBM_LIB_DEPS = $(EXTRA_LIB_PATH) @GBM_LIB_DEPS@
# DRI dependencies
MESA_MODULES = @MESA_MODULES@
@@ -206,6 +211,9 @@ EGL_PC_CFLAGS = @GL_PC_CFLAGS@
WAYLAND_EGL_PC_REQ_PRIV = @WAYLAND_EGL_PC_REQ_PRIV@
WAYLAND_EGL_PC_LIB_PRIV = @WAYLAND_EGL_PC_LIB_PRIV@
WAYLAND_EGL_PC_CFLAGS = @WAYLAND_EGL_PC_CFLAGS@
+GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@
+GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@
+GBM_PC_CFLAGS = @GBM_PC_CFLAGS@
XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
diff --git a/configs/default b/configs/default
index b7acfd2f1a5..132ccbee3cf 100644
--- a/configs/default
+++ b/configs/default
@@ -9,7 +9,7 @@ CONFIG_NAME = default
# Version info
MESA_MAJOR=7
-MESA_MINOR=11
+MESA_MINOR=12
MESA_TINY=0
MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY)
@@ -63,7 +63,7 @@ GLESv2_LIB = GLESv2
VG_LIB = OpenVG
GLAPI_LIB = glapi
WAYLAND_EGL_LIB = wayland-egl
-
+GBM_LIB = gbm
# Library names (actual file names)
GL_LIB_NAME = lib$(GL_LIB).so
@@ -77,6 +77,7 @@ GLESv2_LIB_NAME = lib$(GLESv2_LIB).so
VG_LIB_NAME = lib$(VG_LIB).so
GLAPI_LIB_NAME = lib$(GLAPI_LIB).so
WAYLAND_EGL_LIB_NAME = lib$(WAYLAND_EGL_LIB).so
+GBM_LIB_NAME = lib$(GBM_LIB).so
# globs used to install the lib and all symlinks
GL_LIB_GLOB = $(GL_LIB_NAME)*
@@ -90,6 +91,7 @@ GLESv2_LIB_GLOB = $(GLESv2_LIB_NAME)*
VG_LIB_GLOB = $(VG_LIB_NAME)*
GLAPI_LIB_GLOB = $(GLAPI_LIB_NAME)*
WAYLAND_EGL_LIB_GLOB = $(WAYLAND_EGL_LIB_NAME)*
+GBM_LIB_GLOB = $(GBM_LIB_NAME)*
DRI_CFLAGS = $(CFLAGS)
DRI_CXXFLAGS = $(CXXFLAGS)
@@ -113,6 +115,9 @@ DRIVER_DIRS = x11 osmesa
# EGL drivers to build
EGL_DRIVERS_DIRS = glx
+# gbm backends to build
+GBM_BACKEND_DIRS = dri
+
# Gallium directories and
GALLIUM_DIRS = auxiliary drivers state_trackers
GALLIUM_AUXILIARIES = $(TOP)/src/gallium/auxiliary/libgallium.a
@@ -140,6 +145,7 @@ GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread
VG_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread
GLAPI_LIB_DEPS = $(EXTRA_LIB_PATH) -lpthread
WAYLAND_EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lwayland-client -ldrm
+GBM_LIB_DEPS = $(EXTRA_LIB_PATH) -ludev -ldl
# Program dependencies - specific GL/glut libraries added in Makefiles
APP_LIB_DEPS = -lm
@@ -159,6 +165,9 @@ DRI_DRIVER_SEARCH_DIR = $(DRI_DRIVER_INSTALL_DIR)
# EGL driver install directory
EGL_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/egl
+# gbm backend install directory
+GBM_BACKEND_INSTALL_DIR = $(INSTALL_LIB_DIR)/gbm
+
# Xorg driver install directory (for xorg state-tracker)
XORG_DRIVER_INSTALL_DIR = $(INSTALL_LIB_DIR)/xorg/modules/drivers
@@ -191,3 +200,6 @@ VG_PC_CFLAGS =
WAYLAND_EGL_PC_REQ_PRIV =
WAYLAND_EGL_PC_LIB_PRIV =
WAYLAND_EGL_PC_CFLAGS =
+GBM_PC_REQ_PRIV =
+GBM_PC_LIB_PRIV =
+GBM_PC_CFLAGS =
diff --git a/configs/linux-llvm b/configs/linux-llvm
index 359bee28250..54d82b5376c 100644
--- a/configs/linux-llvm
+++ b/configs/linux-llvm
@@ -42,3 +42,6 @@ endif
LD = g++
GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++
+
+# to allow the NV drivers to compile
+LIBDRM_CFLAGS = $(shell pkg-config --cflags libdrm)
diff --git a/configure.ac b/configure.ac
index a99a4e25f74..f19f6478b6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -177,8 +177,10 @@ if test "x$GXX" = xyes; then
AC_MSG_CHECKING([whether $CXX supports -fvisibility=hidden])
VISIBILITY_CXXFLAGS="-fvisibility=hidden"
CXXFLAGS="$CXXFLAGS $VISIBILITY_CXXFLAGS"
+ AC_LANG_PUSH([C++])
AC_LINK_IFELSE([AC_LANG_PROGRAM()], AC_MSG_RESULT([yes]),
[VISIBILITY_CXXFLAGS="" ; AC_MSG_RESULT([no])]);
+ AC_LANG_POP([C++])
# Restore CXXFLAGS; VISIBILITY_CXXFLAGS are added to it where needed.
CXXFLAGS=$save_CXXFLAGS
@@ -187,6 +189,15 @@ if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"
fi
+dnl even if the compiler appears to support it, using visibility attributes isn't
+dnl going to do anything useful currently on cygwin apart from emit lots of warnings
+case "$host_os" in
+cygwin*)
+ VISIBILITY_CFLAGS=""
+ VISIBILITY_CXXFLAGS=""
+ ;;
+esac
+
AC_SUBST([VISIBILITY_CFLAGS])
AC_SUBST([VISIBILITY_CXXFLAGS])
@@ -352,6 +363,7 @@ GLESv2_LIB_NAME='lib$(GLESv2_LIB).'${LIB_EXTENSION}
VG_LIB_NAME='lib$(VG_LIB).'${LIB_EXTENSION}
GLAPI_LIB_NAME='lib$(GLAPI_LIB).'${LIB_EXTENSION}
WAYLAND_EGL_LIB_NAME='lib$(WAYLAND_EGL_LIB).'${LIB_EXTENSION}
+GBM_LIB_NAME='lib$(GBM_LIB).'${LIB_EXTENSION}
GL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
GLU_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLU_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
@@ -365,6 +377,7 @@ GLESv2_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLESv2_LIB)'${LIB_VERSION_SEPARATOR}'*'${LI
VG_LIB_GLOB=${LIB_PREFIX_GLOB}'$(VG_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
GLAPI_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLAPI_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
WAYLAND_EGL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(WAYLAND_EGL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
+GBM_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GBM_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
AC_SUBST([GL_LIB_NAME])
AC_SUBST([GLU_LIB_NAME])
@@ -377,6 +390,7 @@ AC_SUBST([GLESv2_LIB_NAME])
AC_SUBST([VG_LIB_NAME])
AC_SUBST([GLAPI_LIB_NAME])
AC_SUBST([WAYLAND_EGL_LIB_NAME])
+AC_SUBST([GBM_LIB_NAME])
AC_SUBST([GL_LIB_GLOB])
AC_SUBST([GLU_LIB_GLOB])
@@ -389,6 +403,7 @@ AC_SUBST([GLESv2_LIB_GLOB])
AC_SUBST([VG_LIB_GLOB])
AC_SUBST([GLAPI_LIB_GLOB])
AC_SUBST([WAYLAND_EGL_LIB_GLOB])
+AC_SUBST([GBM_LIB_GLOB])
dnl
dnl Arch/platform-specific settings
@@ -507,7 +522,7 @@ if test "x$enable_selinux" = "xyes"; then
DEFINES="$DEFINES -DMESA_SELINUX"
fi
-dnl Determine which APIs to support
+dnl Options for APIs
AC_ARG_ENABLE([opengl],
[AS_HELP_STRING([--disable-opengl],
[disable support for standard OpenGL API @<:@default=no@:>@])],
@@ -523,32 +538,92 @@ AC_ARG_ENABLE([gles2],
[enable support for OpenGL ES 2.x API @<:@default=no@:>@])],
[enable_gles2="$enableval"],
[enable_gles2=no])
-AC_ARG_ENABLE([gles-overlay],
- [AS_HELP_STRING([--enable-gles-overlay],
- [DEPRECATED. Same as --enable-gles1 and --enable-gles2])],
- [enable_gles1="$enableval"; enable_gles2="$enableval"],
- [])
-
AC_ARG_ENABLE([openvg],
[AS_HELP_STRING([--enable-openvg],
[enable support for OpenVG API @<:@default=no@:>@])],
[enable_openvg="$enableval"],
[enable_openvg=no])
-dnl smooth the transition; should be removed eventually
-if test "x$enable_openvg" = xno; then
- case "x$with_state_trackers" in
- x*vega*)
- AC_MSG_WARN([vega state tracker is enabled without --enable-openvg])
- enable_openvg=yes
- ;;
- esac
-fi
+AC_ARG_ENABLE([dri],
+ [AS_HELP_STRING([--enable-dri],
+ [enable DRI modules @<:@default=auto@:>@])],
+ [enable_dri="$enableval"],
+ [enable_dri=auto])
+AC_ARG_ENABLE([glx],
+ [AS_HELP_STRING([--enable-glx],
+ [enable GLX library @<:@default=auto@:>@])],
+ [enable_glx="$enableval"],
+ [enable_glx=auto])
+AC_ARG_ENABLE([osmesa],
+ [AS_HELP_STRING([--enable-osmesa],
+ [enable OSMesa library @<:@default=auto@:>@])],
+ [enable_osmesa="$enableval"],
+ [enable_osmesa=auto])
+AC_ARG_ENABLE([egl],
+ [AS_HELP_STRING([--disable-egl],
+ [disable EGL library @<:@default=enabled@:>@])],
+ [enable_egl="$enableval"],
+ [enable_egl=yes])
+
+AC_ARG_ENABLE([xorg],
+ [AS_HELP_STRING([--enable-xorg],
+ [enable support for X.Org DDX API @<:@default=no@:>@])],
+ [enable_xorg="$enableval"],
+ [enable_xorg=no])
+AC_ARG_ENABLE([xa],
+ [AS_HELP_STRING([--enable-xa],
+ [enable build of the XA X Acceleration API @<:@default=no@:>@])],
+ [enable_xa="$enableval"],
+ [enable_xa=no])
+AC_ARG_ENABLE([d3d1x],
+ [AS_HELP_STRING([--enable-d3d1x],
+ [enable support for Direct3D 10 & 11 low-level API @<:@default=no@:>@])],
+ [enable_d3d1x="$enableval"],
+ [enable_d3d1x=no])
+AC_ARG_ENABLE([gbm],
+ [AS_HELP_STRING([--enable-gbm],
+ [enable gbm library @<:@default=auto@:>@])],
+ [enable_gbm="$enableval"],
+ [enable_gbm=auto])
+
+AC_ARG_ENABLE([xlib_glx],
+ [AS_HELP_STRING([--enable-xlib-glx],
+ [make GLX library Xlib-based instead of DRI-based @<:@default=disable@:>@])],
+ [enable_xlib_glx="$enableval"],
+ [enable_xlib_glx=auto])
+AC_ARG_ENABLE([gallium_egl],
+ [AS_HELP_STRING([--enable-gallium-egl],
+ [enable optional EGL state tracker (not required
+ for EGL support in Gallium with OpenGL and OpenGL ES)
+ @<:@default=disable@:>@])],
+ [enable_gallium_egl="$enableval"],
+ [enable_gallium_egl=no])
+AC_ARG_ENABLE([gallium_gbm],
+ [AS_HELP_STRING([--enable-gallium-gbm],
+ [enable optional gbm state tracker (not required for
+ gbm support in Gallium)
+ @<:@default=auto@:>@])],
+ [enable_gallium_gbm="$enableval"],
+ [enable_gallium_gbm=auto])
+
+# Option for Gallium drivers
+GALLIUM_DRIVERS_DEFAULT="r300,r600,swrast"
+
+AC_ARG_WITH([gallium-drivers],
+ [AS_HELP_STRING([--with-gallium-drivers@<:@=DIRS...@:>@],
+ [comma delimited Gallium drivers list, e.g.
+ "i915,i965,nouveau,r300,r600,svga,swrast"
+ @<:@default=r300,r600,swrast@:>@])],
+ [with_gallium_drivers="$withval"],
+ [with_gallium_drivers="$GALLIUM_DRIVERS_DEFAULT"])
if test "x$enable_opengl" = xno -a \
"x$enable_gles1" = xno -a \
"x$enable_gles2" = xno -a \
- "x$enable_openvg" = xno; then
+ "x$enable_openvg" = xno -a \
+ "x$enable_xorg" = xno -a \
+ "x$enable_xa" = xno -a \
+ "x$enable_d3d1x" = xno; then
AC_MSG_ERROR([at least one API should be enabled])
fi
@@ -602,24 +677,60 @@ if test "x$enable_opengl" = xno; then
fi
AC_ARG_WITH([driver],
- [AS_HELP_STRING([--with-driver=DRIVER],
- [driver for Mesa: xlib,dri,osmesa @<:@default=dri when available, or xlib@:>@])],
+ [AS_HELP_STRING([--with-driver=DRIVER], [DEPRECATED])],
[mesa_driver="$withval"],
- [mesa_driver="$default_driver"])
+ [mesa_driver=auto])
dnl Check for valid option
case "x$mesa_driver" in
-xxlib|xdri|xosmesa)
- if test "x$enable_opengl" = xno; then
- AC_MSG_ERROR([Driver '$mesa_driver' requires OpenGL enabled])
+xxlib|xdri|xosmesa|xno)
+ if test "x$enable_dri" != xauto -o \
+ "x$enable_glx" != xauto -o \
+ "x$enable_osmesa" != xauto -o \
+ "x$enable_xlib_glx" != xauto; then
+ AC_MSG_ERROR([--with-driver=$mesa_driver is deprecated])
fi
;;
-xno)
+xauto)
+ mesa_driver="$default_driver"
;;
*)
AC_MSG_ERROR([Driver '$mesa_driver' is not a valid option])
;;
esac
+# map $mesa_driver to APIs
+if test "x$enable_dri" = xauto; then
+ case "x$mesa_driver" in
+ xdri) enable_dri=yes ;;
+ *) enable_dri=no ;;
+ esac
+fi
+
+if test "x$enable_glx" = xauto; then
+ case "x$mesa_driver" in
+ xdri|xxlib) enable_glx=yes ;;
+ *) enable_glx=no ;;
+ esac
+fi
+
+if test "x$enable_osmesa" = xauto; then
+ case "x$mesa_driver" in
+ xxlib|xosmesa) enable_osmesa=yes ;;
+ *) enable_osmesa=no ;;
+ esac
+fi
+
+if test "x$enable_xlib_glx" = xauto; then
+ case "x$mesa_driver" in
+ xxlib) enable_xlib_glx=yes ;;
+ *) enable_xlib_glx=no ;;
+ esac
+fi
+
+if test "x$enable_glx" = xno; then
+ enable_xlib_glx=no
+fi
+
dnl
dnl Driver specific build directories
dnl
@@ -657,11 +768,6 @@ if test "x$enable_gles2" = xyes; then
CORE_DIRS="$CORE_DIRS mapi/es2api"
fi
-# build vgapi if OpenVG is enabled
-if test "x$enable_openvg" = xyes; then
- CORE_DIRS="$CORE_DIRS mapi/vgapi"
-fi
-
# build glsl and mesa if OpenGL or OpenGL ES is enabled
case "x$enable_opengl$enable_gles1$enable_gles2" in
x*yes*)
@@ -669,24 +775,36 @@ x*yes*)
;;
esac
-case "$mesa_driver" in
-xlib)
- DRIVER_DIRS="x11"
+case "x$enable_glx$enable_xlib_glx" in
+xyesyes)
+ DRIVER_DIRS="$DRIVER_DIRS x11"
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib"
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS libgl-xlib"
+ GALLIUM_STATE_TRACKERS_DIRS="glx $GALLIUM_STATE_TRACKERS_DIRS"
;;
-dri)
+xyesno)
+ # DRI-based GLX
SRC_DIRS="$SRC_DIRS glx"
- DRIVER_DIRS="dri"
- GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri"
- ;;
-osmesa)
- DRIVER_DIRS="osmesa"
- ;;
-no)
- DRIVER_DRIS=""
;;
esac
+
+if test "x$enable_dri" = xyes; then
+ DRIVER_DIRS="$DRIVER_DIRS dri"
+
+ GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri"
+ GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS"
+ HAVE_ST_DRI="yes"
+fi
+
+if test "x$enable_osmesa" = xyes; then
+ # the empty space matters for osmesa... (see src/mesa/Makefile)
+ if test -n "$DRIVER_DIRS"; then
+ DRIVER_DIRS="$DRIVER_DIRS osmesa"
+ else
+ DRIVER_DIRS="osmesa"
+ fi
+fi
+
AC_SUBST([SRC_DIRS])
AC_SUBST([GLU_DIRS])
AC_SUBST([DRIVER_DIRS])
@@ -697,6 +815,22 @@ AC_SUBST([GALLIUM_DRIVERS_DIRS])
AC_SUBST([GALLIUM_STATE_TRACKERS_DIRS])
AC_SUBST([MESA_LLVM])
+# Check for libdrm
+PKG_CHECK_MODULES([LIBDRM], [libdrm >= $LIBDRM_REQUIRED],
+ [have_libdrm=yes], [have_libdrm=no])
+
+if test "x$enable_dri" = xyes; then
+ # DRI must be shared, I think
+ if test "$enable_static" = yes; then
+ AC_MSG_ERROR([Can't use static libraries for DRI drivers])
+ fi
+
+ # not a hard requirement as swrast does not depend on it
+ if test "x$have_libdrm" = xyes; then
+ DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED"
+ fi
+fi
+
dnl
dnl Find out if X is available. The variable have_x is set if libX11 is
dnl found to mimic AC_PATH_XTRA.
@@ -731,13 +865,9 @@ m4_divert_once([HELP_BEGIN],
pkg-config utility.])
dnl We need X for xlib and dri, so bomb now if it's not found
-case "$mesa_driver" in
-xlib|dri)
- if test "$no_x" = yes; then
- AC_MSG_ERROR([X11 development libraries needed for $mesa_driver driver])
- fi
- ;;
-esac
+if test "x$enable_glx" = xyes -a "x$no_x" = xyes; then
+ AC_MSG_ERROR([X11 development libraries needed for GLX])
+fi
dnl XCB - this is only used for GLX right now
AC_ARG_ENABLE([xcb],
@@ -775,8 +905,9 @@ AC_ARG_ENABLE([driglx-direct],
dnl
dnl libGL configuration per driver
dnl
-case "$mesa_driver" in
-xlib)
+case "x$enable_glx$enable_xlib_glx" in
+xyesyes)
+ # Xlib-based GLX
if test "$x11_pkgconfig" = yes; then
PKG_CHECK_MODULES([XLIBGL], [x11 xext])
GL_PC_REQ_PRIV="x11 xext"
@@ -799,22 +930,16 @@ xlib)
GL_LIB_DEPS=""
fi
;;
-dri|no) # these checks are still desired when there is no mesa_driver
- # DRI must be shared, I think
- if test "$enable_static" = yes; then
- AC_MSG_ERROR([Can't use static libraries for DRI drivers])
- fi
-
+xyesno)
+ # DRI-based GLX
PKG_CHECK_MODULES([GLPROTO], [glproto >= $GLPROTO_REQUIRED])
GL_PC_REQ_PRIV="glproto >= $GLPROTO_REQUIRED"
- DRI_PC_REQ_PRIV=""
-
if test x"$driglx_direct" = xyes; then
- # Check for libdrm
- PKG_CHECK_MODULES([LIBDRM], [libdrm >= $LIBDRM_REQUIRED])
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([Direct rendering requires libdrm >= $LIBDRM_REQUIRED])
+ fi
PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED dri2proto >= $DRI2PROTO_REQUIRED"
- DRI_PC_REQ_PRIV="libdrm >= $LIBDRM_REQUIRED"
fi
# find the DRI deps for libGL
@@ -839,7 +964,11 @@ dri|no) # these checks are still desired when there is no mesa_driver
else
# should check these...
X11_INCLUDES="$X11_INCLUDES $X_CFLAGS"
- GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes"
+ if test "x$HAVE_XF86VIDMODE" == xyes; then
+ GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXxf86vm -lXdamage -lXfixes"
+ else
+ GL_LIB_DEPS="$X_LIBS -lX11 -lXext -lXdamage -lXfixes"
+ fi
GL_PC_LIB_PRIV="$GL_LIB_DEPS"
GL_PC_CFLAGS="$X11_INCLUDES"
@@ -855,16 +984,14 @@ dri|no) # these checks are still desired when there is no mesa_driver
# need DRM libs, -lpthread, etc.
GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
GL_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
- GLESv1_CM_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
- GLESv1_CM_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
- GLESv2_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
- GLESv2_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
- ;;
-osmesa)
- # No libGL for osmesa
- GL_LIB_DEPS=""
;;
esac
+
+GLESv1_CM_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
+GLESv1_CM_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
+GLESv2_LIB_DEPS="$LIBDRM_LIBS -lm -lpthread $DLOPEN_LIBS"
+GLESv2_PC_LIB_PRIV="-lm -lpthread $DLOPEN_LIBS"
+
AC_SUBST([GL_LIB_DEPS])
AC_SUBST([GL_PC_REQ_PRIV])
AC_SUBST([GL_PC_LIB_PRIV])
@@ -890,7 +1017,7 @@ AC_ARG_ENABLE([shared-dricore],
[link DRI modules with shared core DRI routines @<:@default=disabled@:>@])],
[enable_dricore="$enableval"],
[enable_dricore=no])
-if test "$mesa_driver" = dri ; then
+if test "x$enable_dri" = xyes ; then
if test "$enable_dricore" = yes ; then
if test "$GCC$GXX" != yesyes ; then
AC_MSG_WARN([Shared dricore requires GCC-compatible rpath handling. Disabling shared dricore])
@@ -921,11 +1048,19 @@ PKG_CHECK_MODULES([LIBDRM_RADEON],
HAVE_LIBDRM_RADEON=no)
dnl
-dnl More X11 setup
+dnl More GLX setup
dnl
-if test "$mesa_driver" = xlib; then
+case "x$enable_glx$enable_xlib_glx" in
+xyesyes)
DEFINES="$DEFINES -DUSE_XSHM"
-fi
+ ;;
+xyesno)
+ DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING"
+ if test "x$driglx_direct" = xyes; then
+ DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
+ fi
+ ;;
+esac
dnl
dnl TLS detection
@@ -975,7 +1110,10 @@ DRI_DIRS=""
case "$with_dri_drivers" in
no) ;;
yes)
- DRI_DIRS="yes"
+ # classic DRI drivers require FEATURE_GL to build
+ if test "x$enable_opengl" = xyes; then
+ DRI_DIRS="yes"
+ fi
;;
*)
# verify the requested driver directories exist
@@ -985,19 +1123,19 @@ yes)
AC_MSG_ERROR([DRI driver directory '$driver' doesn't exist])
done
DRI_DIRS="$dri_drivers"
+ if test -n "$DRI_DIRS" -a "x$enable_opengl" != xyes; then
+ AC_MSG_ERROR([--with-dri-drivers requires OpenGL])
+ fi
;;
esac
dnl Set DRI_DIRS, DEFINES and LIB_DEPS
-if test "$mesa_driver" = dri -o "$mesa_driver" = no; then
+if test "x$enable_dri" = xyes; then
# Platform specific settings and drivers to build
case "$host_os" in
linux*)
DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER"
- if test "x$driglx_direct" = xyes; then
- DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
- fi
- DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS"
+ DEFINES="$DEFINES -DHAVE_ALIAS"
case "$host_cpu" in
x86_64)
@@ -1027,10 +1165,6 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then
freebsd* | dragonfly* | *netbsd*)
DEFINES="$DEFINES -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1"
DEFINES="$DEFINES -DIN_DRI_DRIVER -DHAVE_ALIAS"
- DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING"
- if test "x$driglx_direct" = xyes; then
- DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
- fi
if test "x$DRI_DIRS" = "xyes"; then
DRI_DIRS="i810 i915 i965 mach64 mga nouveau r128 r200 r300 r600 \
@@ -1039,21 +1173,13 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then
;;
gnu*)
DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER"
- DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS"
+ DEFINES="$DEFINES -DHAVE_ALIAS"
;;
solaris*)
DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER"
- DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING"
- if test "x$driglx_direct" = xyes; then
- DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
- fi
;;
cygwin*)
DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER"
- DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING"
- if test "x$driglx_direct" = xyes; then
- DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
- fi
if test "x$DRI_DIRS" = "xyes"; then
DRI_DIRS="swrast"
fi
@@ -1069,7 +1195,7 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then
DRI_DIRS=`echo "$DRI_DIRS" | $SED 's/ */ /g'`
# Check for expat
- if test "$mesa_driver" = dri; then
+ if test "x$enable_dri" = xyes; then
EXPAT_INCLUDES=""
EXPAT_LIB=-lexpat
AC_ARG_WITH([expat],
@@ -1085,6 +1211,13 @@ if test "$mesa_driver" = dri -o "$mesa_driver" = no; then
[AC_MSG_ERROR([Expat required for DRI.])])
fi
+ # libdrm is required for all except swrast
+ if test -n "$DRI_DIRS" -a x"$DRI_DIRS" != xswrast; then
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([DRI drivers requires libdrm >= $LIBDRM_REQUIRED])
+ fi
+ fi
+
# put all the necessary libs together, including possibly libdricore
DRI_LIB_DEPS="$DRI_LIB_DEPS $SELINUX_LIBS $LIBDRM_LIBS $EXPAT_LIB -lm -lpthread $DLOPEN_LIBS"
fi
@@ -1119,26 +1252,6 @@ AC_SUBST([RADEON_LDFLAGS])
dnl
dnl OSMesa configuration
dnl
-if test "$mesa_driver" = xlib; then
- default_gl_osmesa=yes
-else
- default_gl_osmesa=no
-fi
-AC_ARG_ENABLE([gl-osmesa],
- [AS_HELP_STRING([--enable-gl-osmesa],
- [enable OSMesa with libGL @<:@default=enabled for xlib driver@:>@])],
- [gl_osmesa="$enableval"],
- [gl_osmesa="$default_gl_osmesa"])
-if test "x$gl_osmesa" = xyes; then
- if test "x$enable_opengl" = xno; then
- AC_MSG_ERROR([OpenGL is not available for OSMesa driver])
- fi
- if test "$mesa_driver" = osmesa; then
- AC_MSG_ERROR([libGL is not available for OSMesa driver])
- else
- DRIVER_DIRS="$DRIVER_DIRS osmesa"
- fi
-fi
dnl Configure the channel bits for OSMesa (libOSMesa, libOSMesa16, ...)
AC_ARG_WITH([osmesa-bits],
@@ -1146,9 +1259,11 @@ AC_ARG_WITH([osmesa-bits],
[OSMesa channel bits and library name: 8, 16, 32 @<:@default=8@:>@])],
[osmesa_bits="$withval"],
[osmesa_bits=8])
-if test "$mesa_driver" != osmesa && test "x$osmesa_bits" != x8; then
- AC_MSG_WARN([Ignoring OSMesa channel bits for non-OSMesa driver])
- osmesa_bits=8
+if test "x$osmesa_bits" != x8; then
+ if test "x$enable_dri" = xyes -o "x$enable_glx" = xyes; then
+ AC_MSG_WARN([Ignoring OSMesa channel bits because of non-OSMesa driver])
+ osmesa_bits=8
+ fi
fi
case "x$osmesa_bits" in
x8)
@@ -1164,8 +1279,7 @@ x16|x32)
esac
AC_SUBST([OSMESA_LIB])
-case "$DRIVER_DIRS" in
-*osmesa*)
+if test "x$enable_osmesa" = xyes; then
# only link libraries with osmesa if shared
if test "$enable_static" = no; then
OSMESA_LIB_DEPS="-lm -lpthread $SELINUX_LIBS $DLOPEN_LIBS"
@@ -1174,8 +1288,7 @@ case "$DRIVER_DIRS" in
fi
OSMESA_MESA_DEPS=""
OSMESA_PC_LIB_PRIV="-lm -lpthread $SELINUX_LIBS $DLOPEN_LIBS"
- ;;
-esac
+fi
AC_SUBST([OSMESA_LIB_DEPS])
AC_SUBST([OSMESA_MESA_DEPS])
AC_SUBST([OSMESA_PC_REQ])
@@ -1184,26 +1297,16 @@ AC_SUBST([OSMESA_PC_LIB_PRIV])
dnl
dnl EGL configuration
dnl
-AC_ARG_ENABLE([egl],
- [AS_HELP_STRING([--disable-egl],
- [disable EGL library @<:@default=enabled@:>@])],
- [enable_egl="$enableval"],
- [enable_egl=yes])
-if test "x$enable_egl" = xno; then
- if test "x$mesa_driver" = xno; then
- AC_MSG_ERROR([cannot disable EGL when there is no mesa driver])
- fi
- if test "x$enable_openvg" = xyes; then
- AC_MSG_ERROR([cannot enable OpenVG without EGL])
- fi
-fi
+EGL_CLIENT_APIS=""
+
if test "x$enable_egl" = xyes; then
SRC_DIRS="$SRC_DIRS egl"
EGL_LIB_DEPS="$DLOPEN_LIBS $SELINUX_LIBS -lpthread"
EGL_DRIVERS_DIRS=""
+
if test "$enable_static" != yes; then
# build egl_glx when libGL is built
- if test "$mesa_driver" = xlib -o "$mesa_driver" = dri; then
+ if test "x$enable_glx" = xyes; then
EGL_DRIVERS_DIRS="glx"
fi
@@ -1212,7 +1315,7 @@ if test "x$enable_egl" = xyes; then
if test "$have_libudev" = yes; then
DEFINES="$DEFINES -DHAVE_LIBUDEV"
fi
- if test "$mesa_driver" = dri; then
+ if test "x$enable_dri" = xyes; then
# build egl_dri2 when xcb-dri2 is available
PKG_CHECK_MODULES([XCB_DRI2], [x11-xcb xcb-dri2 xcb-xfixes],
[have_xcb_dri2=yes],[have_xcb_dri2=no])
@@ -1233,6 +1336,142 @@ AC_SUBST([EGL_LIB_DEPS])
AC_SUBST([EGL_DRIVERS_DIRS])
dnl
+dnl gbm configuration
+dnl
+if test "x$enable_gbm" = xauto; then
+ case "$with_egl_platforms" in
+ *drm*)
+ enable_gbm=yes ;;
+ *)
+ enable_gbm=no ;;
+ esac
+fi
+if test "x$enable_gbm" = xyes; then
+ SRC_DIRS="$SRC_DIRS gbm"
+ GBM_BACKEND_DIRS=""
+
+ PKG_CHECK_MODULES([LIBUDEV], [libudev], [],
+ AC_MSG_ERROR([gbm needs udev]))
+ GBM_LIB_DEPS="$DLOPEN_LIBS $LIBUDEV_LIBS"
+
+ if test "x$enable_dri" = xyes; then
+ GBM_BACKEND_DIRS="$GBM_BACKEND_DIRS dri"
+ if test "$SHARED_GLAPI" -eq 0; then
+ AC_MSG_ERROR([gbm_dri requires --enable-shared-glapi])
+ fi
+ fi
+fi
+AC_SUBST([GBM_LIB_DEPS])
+AC_SUBST([GBM_BACKEND_DIRS])
+GBM_PC_REQ_PRIV="libudev"
+GBM_PC_LIB_PRIV="$DLOPEN_LIBS"
+GBM_PC_CFLAGS=
+AC_SUBST([GBM_PC_REQ_PRIV])
+AC_SUBST([GBM_PC_LIB_PRIV])
+AC_SUBST([GBM_PC_CFLAGS])
+
+dnl
+dnl EGL Gallium configuration
+dnl
+if test "x$enable_gallium_egl" = xyes; then
+ if test "x$with_gallium_drivers" = x; then
+ AC_MSG_ERROR([cannot enable egl_gallium without Gallium])
+ fi
+ if test "x$enable_egl" = xno; then
+ AC_MSG_ERROR([cannot enable egl_gallium without EGL])
+ fi
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([egl_gallium requires libdrm >= $LIBDRM_REQUIRED])
+ fi
+
+ GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS"
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl-static"
+ HAVE_ST_EGL="yes"
+fi
+
+dnl
+dnl gbm Gallium configuration
+dnl
+if test "x$enable_gallium_gbm" = xauto; then
+ case "$enable_gbm$HAVE_ST_EGL$with_egl_platforms" in
+ yesyes*drm*)
+ enable_gallium_gbm=yes ;;
+ *)
+ enable_gallium_gbm=no ;;
+ esac
+fi
+if test "x$enable_gallium_gbm" = xyes; then
+ if test "x$with_gallium_drivers" = x; then
+ AC_MSG_ERROR([cannot enable gbm_gallium without Gallium])
+ fi
+ if test "x$enable_gbm" = xno; then
+ AC_MSG_ERROR([cannot enable gbm_gallium without gbm])
+ fi
+
+ GALLIUM_STATE_TRACKERS_DIRS="gbm $GALLIUM_STATE_TRACKERS_DIRS"
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS gbm"
+ HAVE_ST_GBM="yes"
+fi
+
+dnl
+dnl X.Org DDX configuration
+dnl
+if test "x$enable_xorg" = xyes; then
+ PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
+ PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
+ PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
+ PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
+ HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
+ HAVE_XEXTPROTO_71="no")
+ GALLIUM_STATE_TRACKERS_DIRS="xorg $GALLIUM_STATE_TRACKERS_DIRS"
+ HAVE_ST_XORG=yes
+fi
+
+dnl
+dnl XA configuration
+dnl
+if test "x$enable_xa" = xyes; then
+ GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS"
+ HAVE_ST_XA=yes
+fi
+
+dnl
+dnl OpenVG configuration
+dnl
+VG_LIB_DEPS=""
+
+if test "x$enable_openvg" = xyes; then
+ if test "x$enable_egl" = xno; then
+ AC_MSG_ERROR([cannot enable OpenVG without EGL])
+ fi
+ if test "x$with_gallium_drivers" = x; then
+ AC_MSG_ERROR([cannot enable OpenVG without Gallium])
+ fi
+ if test "x$enable_gallium_egl" = xno; then
+ AC_MSG_ERROR([cannot enable OpenVG without egl_gallium])
+ fi
+
+ EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
+ VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread"
+ CORE_DIRS="$CORE_DIRS mapi/vgapi"
+ GALLIUM_STATE_TRACKERS_DIRS="vega $GALLIUM_STATE_TRACKERS_DIRS"
+ HAVE_ST_VEGA=yes
+fi
+
+dnl
+dnl D3D1X configuration
+dnl
+
+if test "x$enable_d3d1x" = xyes; then
+ if test "x$with_gallium_drivers" = x; then
+ AC_MSG_ERROR([cannot enable D3D1X without Gallium])
+ fi
+
+ GALLIUM_STATE_TRACKERS_DIRS="d3d1x $GALLIUM_STATE_TRACKERS_DIRS"
+ HAVE_ST_D3D1X=yes
+fi
+
+dnl
dnl GLU configuration
dnl
AC_ARG_ENABLE([glu],
@@ -1241,16 +1480,17 @@ AC_ARG_ENABLE([glu],
[enable_glu="$enableval"],
[enable_glu=yes])
-if test "x$enable_glu" = xyes -a "x$mesa_driver" = xno; then
- AC_MSG_NOTICE([Disabling GLU since there is no OpenGL driver])
- enable_glu=no
+if test "x$enable_glu" = xyes; then
+ if test "x$enable_glx" = xno -a "x$enable_osmesa" = xno; then
+ AC_MSG_NOTICE([Disabling GLU since there is no OpenGL driver])
+ enable_glu=no
+ fi
fi
if test "x$enable_glu" = xyes; then
SRC_DIRS="$SRC_DIRS glu"
- case "$mesa_driver" in
- osmesa)
+ if test "x$enable_glx" = xno; then
# Link libGLU to libOSMesa instead of libGL
GLU_LIB_DEPS=""
GLU_PC_REQ="osmesa"
@@ -1259,8 +1499,7 @@ if test "x$enable_glu" = xyes; then
else
GLU_MESA_DEPS=""
fi
- ;;
- *)
+ else
# If static, empty GLU_LIB_DEPS and add libs for programs to link
GLU_PC_REQ="gl"
GLU_PC_LIB_PRIV="-lm"
@@ -1272,8 +1511,7 @@ if test "x$enable_glu" = xyes; then
GLU_MESA_DEPS=""
APP_LIB_DEPS="$APP_LIB_DEPS -lstdc++"
fi
- ;;
- esac
+ fi
fi
if test "$enable_static" = no; then
GLU_LIB_DEPS="$GLU_LIB_DEPS $OS_CPLUSPLUS_LIBS"
@@ -1295,13 +1533,9 @@ AC_ARG_ENABLE([glw],
[enable_glw="$enableval"],
[enable_glw=yes])
dnl Don't build GLw on osmesa
-if test "x$enable_glw" = xyes; then
- case "$mesa_driver" in
- osmesa|no)
- AC_MSG_NOTICE([Disabling GLw since there is no OpenGL driver])
- enable_glw=no
- ;;
- esac
+if test "x$enable_glw" = xyes -a "x$enable_glx" = xno; then
+ AC_MSG_NOTICE([Disabling GLw since there is no OpenGL driver])
+ enable_glw=no
fi
AC_ARG_ENABLE([motif],
[AS_HELP_STRING([--enable-motif],
@@ -1375,14 +1609,10 @@ AC_ARG_ENABLE([glut],
[enable_glut="$enableval"],
[enable_glut="$default_glut"])
-dnl Don't build glut on osmesa
-if test "x$enable_glut" = xyes; then
- case "$mesa_driver" in
- osmesa|no)
- AC_MSG_NOTICE([Disabling glut since there is no OpenGL driver])
- enable_glut=no
- ;;
- esac
+dnl Don't build glut without GLX
+if test "x$enable_glut" = xyes -a "x$enable_glx" = xno; then
+ AC_MSG_NOTICE([Disabling glut since there is no OpenGL driver])
+ enable_glut=no
fi
dnl Can't build glut if GLU not available
if test "x$enable_glu$enable_glut" = xnoyes; then
@@ -1448,17 +1678,11 @@ AC_SUBST([PROGRAM_DIRS])
dnl
dnl Gallium configuration
dnl
-AC_ARG_ENABLE([gallium],
- [AS_HELP_STRING([--disable-gallium],
- [build gallium @<:@default=enabled@:>@])],
- [enable_gallium="$enableval"],
- [enable_gallium=yes])
-if test "x$enable_gallium" = xno -a "x$enable_openvg" = xyes; then
- AC_MSG_ERROR([cannot enable OpenVG without Gallium])
-fi
-if test "x$enable_gallium" = xyes; then
+if test "x$with_gallium_drivers" != x; then
SRC_DIRS="$SRC_DIRS gallium gallium/winsys gallium/targets"
AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no])
+else
+ LLVM_CONFIG=no
fi
AC_SUBST([LLVM_CFLAGS])
@@ -1466,174 +1690,31 @@ AC_SUBST([LLVM_LIBS])
AC_SUBST([LLVM_LDFLAGS])
AC_SUBST([LLVM_VERSION])
-dnl
-dnl Gallium state trackers configuration
-dnl
-
-AC_ARG_ENABLE([gallium-egl],
- [AS_HELP_STRING([--enable-gallium-egl],
- [enable gallium EGL state tracker @<:@default=auto@:>@])],
- [enable_gallium_egl="$enableval"],
- [enable_gallium_egl=auto])
-if test "x$enable_gallium_egl" = xauto; then
- case "$mesa_driver" in
- dri|no)
- enable_gallium_egl=$enable_egl
- ;;
- *)
- enable_gallium_egl=$enable_openvg
- ;;
- esac
-fi
-case "x$enable_egl$enable_gallium_egl" in
-xnoyes)
- AC_MSG_ERROR([cannot build Gallium EGL state tracker without EGL])
-esac
-
-AC_ARG_WITH([state-trackers],
- [AS_HELP_STRING([--with-state-trackers@<:@=DIRS...@:>@],
- [comma delimited state_trackers list, e.g.
- "egl,glx" @<:@default=auto@:>@])],
- [with_state_trackers="$withval"],
- [with_state_trackers=yes])
-
-case "$with_state_trackers" in
-no)
- GALLIUM_STATE_TRACKERS_DIRS=""
- ;;
-yes)
- # look at what else is built
- case "$mesa_driver" in
- xlib)
- GALLIUM_STATE_TRACKERS_DIRS=glx
- ;;
- dri)
- GALLIUM_STATE_TRACKERS_DIRS="dri"
- HAVE_ST_DRI="yes"
- # Have only tested st/xorg on 1.6.0 servers
- PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED],
- HAVE_ST_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
- HAVE_ST_XORG="no")
- ;;
- esac
-
- if test "x$enable_egl" = xyes; then
- if test "$enable_openvg" = yes; then
- GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vega"
- st_egl="yes"
- fi
-
- if test "$enable_gallium_egl" = yes; then
- GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
- HAVE_ST_EGL="yes"
- fi
- fi
- ;;
-*)
- # verify the requested state tracker exist
- state_trackers=""
- _state_trackers=`IFS=', '; echo $with_state_trackers`
- for tracker in $_state_trackers; do
- case "$tracker" in
- dri)
- if test "x$mesa_driver" != xdri; then
- AC_MSG_ERROR([cannot build dri state tracker without mesa driver set to dri])
- fi
- HAVE_ST_DRI="yes"
- ;;
- egl)
- if test "x$enable_egl" != xyes; then
- AC_MSG_ERROR([cannot build egl state tracker without EGL library])
- fi
- HAVE_ST_EGL="yes"
- ;;
- xorg)
- PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
- PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
- PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
- HAVE_ST_XORG="yes"
- ;;
- vega)
- if test "x$enable_openvg" != xyes; then
- AC_MSG_ERROR([cannot build vega state tracker without --enable-openvg])
- fi
- have_st_vega="yes"
- ;;
- xa)
- HAVE_ST_XA="yes"
- ;;
- esac
- if test -n "$tracker"; then
- test -d "$srcdir/src/gallium/state_trackers/$tracker" || \
- AC_MSG_ERROR([state tracker '$tracker' doesn't exist])
- if test -n "$state_trackers"; then
- state_trackers="$state_trackers $tracker"
- else
- state_trackers="$tracker"
- fi
- fi
- done
- GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
-
- # append --enable-openvg/--enable-gallium-egl to --with-state-trackers
- if test "x$have_st_vega" != xyes -a "x$enable_openvg" = xyes; then
- AC_MSG_ERROR([--with-state-trackers specified but vega is missing])
- fi
- if test "x$HAVE_ST_EGL" != xyes -a "x$enable_gallium_egl" = xyes; then
- AC_MSG_ERROR([--with-state-trackers specified but egl is missing])
- fi
- ;;
-esac
-
-
-EGL_CLIENT_APIS=""
-VG_LIB_DEPS=""
case "x$enable_opengl$enable_gles1$enable_gles2" in
x*yes*)
EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(GL_LIB)'
;;
esac
-if test "x$enable_openvg" = xyes; then
- EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
- VG_LIB_DEPS="$VG_LIB_DEPS $SELINUX_LIBS -lpthread"
-fi
AC_SUBST([VG_LIB_DEPS])
AC_SUBST([EGL_CLIENT_APIS])
-if test "x$HAVE_ST_EGL" = xyes; then
- GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
-fi
-
-if test "x$HAVE_ST_XORG" = xyes; then
- PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
- HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
- HAVE_XEXTPROTO_71="no")
-fi
-
AC_ARG_WITH([egl-platforms],
[AS_HELP_STRING([--with-egl-platforms@<:@=DIRS...@:>@],
[comma delimited native platforms libEGL supports, e.g.
"x11,drm" @<:@default=auto@:>@])],
[with_egl_platforms="$withval"],
[with_egl_platforms=yes])
-AC_ARG_WITH([egl-displays],
- [AS_HELP_STRING([--with-egl-displays@<:@=DIRS...@:>@],
- [DEPRECATED. Use --with-egl-platforms instead])],
- [with_egl_platforms="$withval"])
EGL_PLATFORMS=""
WAYLAND_EGL_LIB_DEPS=""
case "$with_egl_platforms" in
yes)
- if test "x$enable_egl" = xyes && test "x$mesa_driver" != xosmesa; then
+ if test "x$enable_egl" = xyes; then
EGL_PLATFORMS="x11"
- if test "$mesa_driver" = dri; then
- EGL_PLATFORMS="$EGL_PLATFORMS drm"
- fi
fi
;;
*)
@@ -1654,6 +1735,13 @@ yes)
WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS"
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/wayland"
fi
+ if test "$plat" = "drm" && test "x$enable_gbm" = "xno"; then
+ AC_MSG_ERROR([EGL platform drm needs gbm])
+ fi
+ case "$plat$have_libudev" in
+ waylandno|drmno)
+ AC_MSG_ERROR([cannot build $plat platfrom without udev]) ;;
+ esac
done
EGL_PLATFORMS="$egl_platforms"
;;
@@ -1707,6 +1795,9 @@ AC_ARG_ENABLE([gallium-llvm],
[build gallium LLVM support @<:@default=enabled on x86/x86_64@:>@])],
[enable_gallium_llvm="$enableval"],
[enable_gallium_llvm=auto])
+if test "x$with_gallium_drivers" = x; then
+ enable_gallium_llvm=no
+fi
if test "x$enable_gallium_llvm" = xauto; then
case "$host_cpu" in
i*86|x86_64) enable_gallium_llvm=yes;;
@@ -1735,6 +1826,9 @@ dnl
gallium_check_st() {
if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes ||
test "x$HAVE_ST_XA" = xyes; then
+ if test "x$have_libdrm" != xyes; then
+ AC_MSG_ERROR([DRI or Xorg DDX requires libdrm >= $LIBDRM_REQUIRED])
+ fi
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS $1"
fi
if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then
@@ -1756,107 +1850,46 @@ gallium_require_llvm() {
fi
}
-dnl
-dnl Gallium SVGA configuration
-dnl
-AC_ARG_ENABLE([gallium-svga],
- [AS_HELP_STRING([--enable-gallium-svga],
- [build gallium SVGA @<:@default=disabled@:>@])],
- [enable_gallium_svga="$enableval"],
- [enable_gallium_svga=auto])
-if test "x$enable_gallium_svga" = xyes; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
- gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" "xa-vmwgfx"
-elif test "x$enable_gallium_svga" = xauto; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
-fi
-
-dnl
-dnl Gallium i915 configuration
-dnl
-AC_ARG_ENABLE([gallium-i915],
- [AS_HELP_STRING([--enable-gallium-i915],
- [build gallium i915 @<:@default=disabled@:>@])],
- [enable_gallium_i915="$enableval"],
- [enable_gallium_i915=auto])
-if test "x$enable_gallium_i915" = xyes; then
+dnl Gallium drivers
+if test "x$with_gallium_drivers" != x; then
+ # This is for compile-testing
+ GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965 r300 svga"
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
- gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
-elif test "x$enable_gallium_i915" = xauto; then
- GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
-fi
-dnl
-dnl Gallium i965 configuration
-dnl
-AC_ARG_ENABLE([gallium-i965],
- [AS_HELP_STRING([--enable-gallium-i965],
- [build gallium i965 @<:@default=disabled@:>@])],
- [enable_gallium_i965="$enableval"],
- [enable_gallium_i965=auto])
-if test "x$enable_gallium_i965" = xyes; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
- gallium_check_st "i965/drm" "dri-i965" "xorg-i965"
-elif test "x$enable_gallium_i965" = xauto; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
-fi
-
-dnl
-dnl Gallium Radeon r300g configuration
-dnl
-AC_ARG_ENABLE([gallium-r300],
- [AS_HELP_STRING([--disable-gallium-r300],
- [build R300 driver @<:@default=enabled@:>@])],
- [enable_gallium_r300="$enableval"],
- [enable_gallium_r300=yes])
-
-if test "x$enable_gallium_r300" = xyes && test "x$mesa_driver" = xdri; then
- gallium_require_llvm "Gallium R300"
-
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
- gallium_check_st "radeon/drm" "dri-r300" "xorg-r300"
-fi
-
-dnl
-dnl Gallium Radeon r600g configuration
-dnl
-AC_ARG_ENABLE([gallium-r600],
- [AS_HELP_STRING([--enable-gallium-r600],
- [build gallium r600 @<:@default=disabled@:>@])],
- [enable_gallium_r600="$enableval"],
- [enable_gallium_r600=auto])
-if test "x$enable_gallium_r600" = xyes; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
- gallium_check_st "r600/drm" "dri-r600"
-fi
-
-dnl
-dnl Gallium Nouveau configuration
-dnl
-AC_ARG_ENABLE([gallium-nouveau],
- [AS_HELP_STRING([--enable-gallium-nouveau],
- [build gallium nouveau @<:@default=disabled@:>@])],
- [enable_gallium_nouveau="$enableval"],
- [enable_gallium_nouveau=no])
-if test "x$enable_gallium_nouveau" = xyes; then
- GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
-fi
-
-dnl
-dnl Gallium swrast configuration
-dnl
-AC_ARG_ENABLE([gallium-swrast],
- [AS_HELP_STRING([--enable-gallium-swrast],
- [build gallium swrast @<:@default=auto@:>@])],
- [enable_gallium_swrast="$enableval"],
- [enable_gallium_swrast=auto])
-if test "x$enable_gallium_swrast" = xyes || test "x$enable_gallium_swrast" = xauto; then
- if test "x$HAVE_ST_DRI" = xyes; then
- GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
- fi
+ gallium_drivers=`IFS=', '; echo $with_gallium_drivers`
+ for driver in $gallium_drivers; do
+ case "x$driver" in
+ xsvga)
+ gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" "xa-vmwgfx"
+ ;;
+ xi915)
+ gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
+ ;;
+ xi965)
+ gallium_check_st "i965/drm" "dri-i965" "xorg-i965"
+ ;;
+ xr300)
+ gallium_require_llvm "Gallium R300"
+ gallium_check_st "radeon/drm" "dri-r300" "xorg-r300"
+ ;;
+ xr600)
+ GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
+ gallium_check_st "r600/drm" "dri-r600"
+ ;;
+ xnouveau)
+ GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50 nvc0"
+ gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
+ ;;
+ xswrast)
+ if test "x$HAVE_ST_DRI" = xyes; then
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
+ fi
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown Gallium driver: $driver])
+ ;;
+ esac
+ done
fi
dnl prepend CORE_DIRS to SRC_DIRS
@@ -1877,6 +1910,12 @@ fi
ln -s autoconf configs/current
])
+dnl Sort the dirs alphabetically
+GALLIUM_TARGET_DIRS=`echo $GALLIUM_TARGET_DIRS|tr " " "\n"|sort|tr "\n" " "`
+GALLIUM_WINSYS_DIRS=`echo $GALLIUM_WINSYS_DIRS|tr " " "\n"|sort|tr "\n" " "`
+GALLIUM_DRIVERS_DIRS=`echo $GALLIUM_DRIVERS_DIRS|tr " " "\n"|sort|tr "\n" " "`
+GALLIUM_STATE_TRACKERS_DIRS=`echo $GALLIUM_STATE_TRACKERS_DIRS|tr " " "\n"|sort|tr "\n" " "`
+
AC_OUTPUT
dnl
@@ -1895,14 +1934,13 @@ echo " OpenVG: $enable_openvg"
dnl Driver info
echo ""
-echo " Driver: $mesa_driver"
-if test "$mesa_driver" != no; then
- if echo "$DRIVER_DIRS" | grep 'osmesa' >/dev/null 2>&1; then
+if test "x$enable_osmesa" != xno; then
echo " OSMesa: lib$OSMESA_LIB"
- else
+else
echo " OSMesa: no"
- fi
- if test "$mesa_driver" = dri; then
+fi
+
+if test "x$enable_dri" != xno; then
# cleanup the drivers var
dri_dirs=`echo $DRI_DIRS | $SED 's/^ *//;s/ */ /;s/ *$//'`
if test "x$DRI_DIRS" = x; then
@@ -1911,10 +1949,22 @@ if test "$mesa_driver" != no; then
echo " DRI drivers: $dri_dirs"
fi
echo " DRI driver dir: $DRI_DRIVER_INSTALL_DIR"
- echo " Use XCB: $enable_xcb"
echo " Shared dricore: $enable_dricore"
- fi
fi
+
+case "x$enable_glx$enable_xlib_glx" in
+xyesyes)
+ echo " GLX: Xlib-based"
+ ;;
+xyesno)
+ echo " GLX: DRI-based"
+ echo " Use XCB: $enable_xcb"
+ ;;
+*)
+ echo " GLX: $enable_glx"
+ ;;
+esac
+
echo ""
echo " GLU: $enable_glu"
echo " GLw: $enable_glw (Motif: $enable_motif)"
@@ -1931,7 +1981,7 @@ if test "$enable_egl" = yes; then
egl_drivers="$egl_drivers builtin:egl_$d"
done
- if test "$enable_gallium" = yes -a "$HAVE_ST_EGL" = yes; then
+ if test "x$HAVE_ST_EGL" = xyes; then
echo " EGL drivers: ${egl_drivers} egl_gallium"
echo " EGL Gallium STs:$EGL_CLIENT_APIS"
else
diff --git a/docs/GL3.txt b/docs/GL3.txt
index d86c4b0bf60..49b48472a4a 100644
--- a/docs/GL3.txt
+++ b/docs/GL3.txt
@@ -40,7 +40,7 @@ glTexParameterI, glGetTexParameterI commands DONE
glVertexAttribI commands DONE (but converts int
values to floats)
Depth format cube textures 0% done
-
+GLX_ARB_create_context (GLX 1.4 is required) not started
GL 3.1:
@@ -49,7 +49,7 @@ GLSL 1.40 not started
Instanced drawing (GL_ARB_draw_instanced) DONE (gallium, swrast)
Buffer copying (GL_ARB_copy_buffer) DONE
Primitive restart (GL_NV_primitive_restart) DONE (gallium)
-16 vertex texture image units not started
+16 vertex texture image units DONE
Texture buffer objs (GL_ARB_texture_buffer_object) not started
Rectangular textures (GL_ARB_texture_rectangle) DONE
Uniform buffer objs (GL_ARB_uniform_buffer_object) not started
@@ -69,6 +69,7 @@ Seamless cubemaps (GL_ARB_seamless_cube_map) DONE
Multisample textures (GL_ARB_texture_multisample) not started
Frag depth clamp (GL_ARB_depth_clamp) DONE
Fence objects (GL_ARB_sync) DONE
+GLX_ARB_create_context_profile not started
GL 3.3:
diff --git a/docs/egl.html b/docs/egl.html
index fb15086679f..5b750070ca1 100644
--- a/docs/egl.html
+++ b/docs/egl.html
@@ -29,12 +29,14 @@ directly dispatched to the drivers.</p>
the driver for your hardware. For example</p>
<pre>
- $ ./configure --enable-gles2 --enable-openvg --enable-gallium-nouveau
+ $ ./configure --enable-gles1 --enable-gles2 \
+ --with-dri-drivers=... \
+ --with-gallium-drivers=...
</pre>
-<p>The main library and OpenGL is enabled by default. The first option above
-enables <a href="opengles.html">OpenGL ES 2.x</a>. The second option enables
-<a href="openvg.html">OpenVG</a>.</p>
+<p>The main library and OpenGL is enabled by default. The first two options
+above enables <a href="opengles.html">OpenGL ES 1.x and 2.x</a>. The last two
+options enables the listed classic and and Gallium drivers respectively.</p>
</li>
@@ -42,8 +44,8 @@ enables <a href="opengles.html">OpenGL ES 2.x</a>. The second option enables
</ol>
<p>In the given example, it will build and install <code>libEGL</code>,
-<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>,
-<code>libOpenVG</code>, and one or more EGL drivers.</p>
+<code>libGL</code>, <code>libGLESv1_CM</code>, <code>libGLESv2</code>, and one
+or more EGL drivers.</p>
<h3>Configure Options</h3>
@@ -65,6 +67,12 @@ drivers will be installed to <code>${libdir}/egl</code>.</p>
</li>
+<li><code>--enable-gallium-egl</code>
+
+<p>Enable the optional <code>egl_gallium</code> driver.</p>
+
+</li>
+
<li><code>--with-egl-platforms</code>
<p>List the platforms (window systems) to support. Its argument is a comma
@@ -88,15 +96,17 @@ internal library that supports multiple APIs.</p>
</li>
-<li><code>--enable-openvg</code>
+<li><code>--enable-shared-glapi</code>
-<p>OpenVG must be explicitly enabled by this option.</p>
+<p>By default, <code>libGL</code> has its own copy of <code>libglapi</code>.
+This options makes <code>libGL</code> use the shared <code>libglapi</code>. This
+is required if applications mix OpenGL and OpenGL ES.</p>
</li>
-<li><code>--enable-gallium-egl</code>
+<li><code>--enable-openvg</code>
-<p>Explicitly enable or disable <code>egl_gallium</code>.</p>
+<p>OpenVG must be explicitly enabled by this option.</p>
</li>
@@ -220,8 +230,7 @@ distribution.</p>
<p>Generally, <code>egl_dri2</code> is preferred over <code>egl_gallium</code>
when the system already has DRI drivers. As <code>egl_gallium</code> is loaded
before <code>egl_dri2</code> when both are available, <code>egl_gallium</code>
-may either be disabled with <code>--disable-gallium-egl</code> or packaged
-separately.</p>
+is disabled by default.</p>
<h2>Developers</h2>
@@ -307,17 +316,5 @@ not be called with the sample display at the same time. If a driver has access
to an <code>EGLDisplay</code> without going through the EGL APIs, the driver
should as well lock the display before using it.
-<h3>TODOs</h3>
-
-<ul>
-<li>Pass the conformance tests</li>
-<li>Mixed use of OpenGL, OpenGL ES 1.1, and OpenGL ES 2.0 is supported. But
-which one of <code>libGL.so</code>, <code>libGLESv1_CM.so</code>, and
-<code>libGLESv2.so</code> should an application link to? Bad things may happen
-when, say, an application is linked to <code>libGLESv2.so</code> and
-<code>libcairo</code>, which is linked to <code>libGL.so</code> instead.</li>
-
-</ul>
-
</body>
</html>
diff --git a/docs/opengles.html b/docs/opengles.html
index 742182e76a3..0fee488e1a1 100644
--- a/docs/opengles.html
+++ b/docs/opengles.html
@@ -34,27 +34,10 @@ EGL drivers for your hardware.</p>
<h2>Run the Demos</h2>
-<p>There are some demos in <code>progs/egl/</code>. You can use them to test
-your build. For example,</p>
-
-<pre>
- $ cd progs/egl/eglut
- $ make
- $ cd ../opengles1
- $ make
- $ ./torus_x11
-</pre>
+<p>There are some demos in <code>mesa/demos</code> repository.</p>
<h2>Developers</h2>
-<h3>Internal Libraries</h3>
-
-<table border="1" style="text-align: center;">
- <tr><td>Library Name</td><td>Used By</td><td>Enabled</td><td>OpenGL</td><td>OpenGL ES 1.x</td><td>OpenGL ES 2.x</td></tr>
- <tr><td><code>libmesa.a</td><td>Classic DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr>
- <tr><td><code>libmesagallium.a</td><td>Gallium EGL and DRI drivers</td><td>y</td><td>y</td><td>--enable-gles1</td><td>--enable-gles2</td></tr>
-</table>
-
<h3>Dispatch Table</h3>
<p>OpenGL ES has an additional indirection when dispatching fucntions</p>
diff --git a/docs/openvg.html b/docs/openvg.html
index eff8c5828e2..81e50b65f36 100644
--- a/docs/openvg.html
+++ b/docs/openvg.html
@@ -11,7 +11,7 @@
<H1>OpenVG State Tracker</H1>
<p>
-The current version of the OpenVG state tracker implements OpenVG 1.0.
+The current version of the OpenVG state tracker implements OpenVG 1.1.
</p>
<p>
More informations about OpenVG can be found at
@@ -26,9 +26,9 @@ Please refer to <a href="egl.html">Mesa EGL</a> for more information about EGL.
<h2>Building the library</h2>
<ol>
-<li>Run <code>configure</code> with <code>--enable-openvg</code>. If you do
-not need OpenGL, you can add <code>--disable-opengl</code> to save the
-compilation time.</li>
+<li>Run <code>configure</code> with <code>--enable-openvg</code> and
+<code>--enable-gallium-egl</code>. If you do not need OpenGL, you can add
+<code>--disable-opengl</code> to save the compilation time.</li>
<li>Build and install Mesa as usual.</li>
</ol>
@@ -36,7 +36,7 @@ compilation time.</li>
<h3>Sample build</h3>
A sample build looks as follows:
<pre>
- $ ./configure --disable-opengl --enable-openvg
+ $ ./configure --disable-opengl --enable-openvg --enable-gallium-egl
$ make
$ make install
</pre>
diff --git a/docs/relnotes-7.11.html b/docs/relnotes-7.11.html
index aaeabc25288..c81ac9f15c9 100644
--- a/docs/relnotes-7.11.html
+++ b/docs/relnotes-7.11.html
@@ -45,7 +45,7 @@ tbd
<li>GL_ARB_robustness (all drivers)
<li>GL_ARB_sampler_objects (gallium drivers)
<li>GL_ARB_seamless_cube_map (gallium r600)
-<li>GL_ARB_shader_texture_lod (gallium drivers)
+<li>GL_ARB_shader_texture_lod (gallium drivers, i965)
<li>GL_ARB_sync (gallium drivers only, intel support was in 7.6)
<li>GL_ARB_texture_compression_rgtc (gallium drivers, swrast, i965)
<li>GL_ARB_texture_float (gallium, i965)
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
index e4aa0994be9..fbfdce32ef4 100644
--- a/include/EGL/eglplatform.h
+++ b/include/EGL/eglplatform.h
@@ -84,6 +84,12 @@ typedef struct wl_display *EGLNativeDisplayType;
typedef struct wl_egl_pixmap *EGLNativePixmapType;
typedef struct wl_egl_window *EGLNativeWindowType;
+#elif defined(__GBM__)
+
+typedef struct gbm_device *EGLNativeDisplayType;
+typedef struct gbm_bo *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
#elif defined(__unix__) || defined(__unix)
#ifdef MESA_EGL_NO_X11_HEADERS
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index f022b44b260..4fe9e943b55 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -849,6 +849,11 @@ struct __DRIimageExtensionRec {
void *loaderPrivate);
GLboolean (*queryImage)(__DRIimage *image, int attrib, int *value);
+
+ /**
+ * The new __DRIimage will share the content with the old one, see dup(2).
+ */
+ __DRIimage *(*dupImage)(__DRIimage *image, void *loaderPrivate);
};
diff --git a/scons/custom.py b/scons/custom.py
index a2c690f655e..df7ac93bb00 100644
--- a/scons/custom.py
+++ b/scons/custom.py
@@ -33,6 +33,8 @@ Custom builders and methods.
import os
import os.path
import re
+import sys
+import subprocess
import SCons.Action
import SCons.Builder
@@ -154,15 +156,90 @@ def createCodeGenerateMethod(env):
env.AddMethod(code_generate, 'CodeGenerate')
+def _pkg_check_modules(env, name, modules):
+ '''Simple wrapper for pkg-config.'''
+
+ env['HAVE_' + name] = False
+
+ # For backwards compatability
+ env[name.lower()] = False
+
+ if env['platform'] == 'windows':
+ return
+
+ if not env.Detect('pkg-config'):
+ return
+
+ if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0:
+ return
+
+ # Other flags may affect the compilation of unrelated targets, so store
+ # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
+ try:
+ flags = env.ParseFlags('!pkg-config --cflags --libs ' + ' '.join(modules))
+ except OSError:
+ return
+ prefix = name + '_'
+ for flag_name, flag_value in flags.iteritems():
+ assert '_' not in flag_name
+ env[prefix + flag_name] = flag_value
+
+ env['HAVE_' + name] = True
+
+def pkg_check_modules(env, name, modules):
+
+ sys.stdout.write('Checking for %s...' % name)
+ _pkg_check_modules(env, name, modules)
+ result = env['HAVE_' + name]
+ sys.stdout.write(' %s\n' % ['no', 'yes'][int(bool(result))])
+
+ # XXX: For backwards compatability
+ env[name.lower()] = result
+
+
+def pkg_use_modules(env, names):
+ '''Search for all environment flags that match NAME_FOO and append them to
+ the FOO environment variable.'''
+
+ names = env.Flatten(names)
+
+ for name in names:
+ prefix = name + '_'
+
+ if not 'HAVE_' + name in env:
+ print 'Attempt to use unknown module %s' % name
+ env.Exit(1)
+
+ if not env['HAVE_' + name]:
+ print 'Attempt to use unavailable module %s' % name
+ env.Exit(1)
+
+ flags = {}
+ for flag_name, flag_value in env.Dictionary().iteritems():
+ if flag_name.startswith(prefix):
+ flag_name = flag_name[len(prefix):]
+ if '_' not in flag_name:
+ flags[flag_name] = flag_value
+ if flags:
+ env.MergeFlags(flags)
+
+
+def createPkgConfigMethods(env):
+ env.AddMethod(pkg_check_modules, 'PkgCheckModules')
+ env.AddMethod(pkg_use_modules, 'PkgUseModules')
+
+
def generate(env):
"""Common environment generation code"""
- if env.get('quiet', True):
+ verbose = env.get('verbose', False) or not env.get('quiet', True)
+ if not verbose:
quietCommandLines(env)
# Custom builders and methods
createConvenienceLibBuilder(env)
createCodeGenerateMethod(env)
+ createPkgConfigMethods(env)
# for debugging
#print env.Dump()
diff --git a/scons/gallium.py b/scons/gallium.py
index a94bf736480..8cd3bc7f6e0 100755
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -104,41 +104,6 @@ def num_jobs():
return 1
-def pkg_config_modules(env, name, modules):
- '''Simple wrapper for pkg-config.'''
-
- env[name] = False
-
- if env['platform'] == 'windows':
- return
-
- if not env.Detect('pkg-config'):
- return
-
- if subprocess.call(["pkg-config", "--exists", ' '.join(modules)]) != 0:
- return
-
- # Put -I and -L flags directly into the environment, as these don't affect
- # the compilation of targets that do not use them
- try:
- env.ParseConfig('pkg-config --cflags-only-I --libs-only-L ' + ' '.join(modules))
- except OSError:
- return
-
- # Other flags may affect the compilation of unrelated targets, so store
- # them with a prefix, (e.g., XXX_CFLAGS, XXX_LIBS, etc)
- try:
- flags = env.ParseFlags('!pkg-config --cflags-only-other --libs-only-l --libs-only-other ' + ' '.join(modules))
- except OSError:
- return
- prefix = name.upper() + '_'
- for flag_name, flag_value in flags.iteritems():
- env[prefix + flag_name] = flag_value
-
- env[name] = True
-
-
-
def generate(env):
"""Common environment generation code"""
@@ -247,6 +212,8 @@ def generate(env):
# configuration. See also http://www.scons.org/wiki/AdvancedBuildExample
build_topdir = 'build'
build_subdir = env['platform']
+ if env['embedded']:
+ build_subdir = 'embedded-' + build_subdir
if env['machine'] != 'generic':
build_subdir += '-' + env['machine']
if env['build'] != 'release':
@@ -277,6 +244,31 @@ def generate(env):
cppdefines += ['NDEBUG']
if env['build'] == 'profile':
cppdefines += ['PROFILE']
+ if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'):
+ cppdefines += [
+ '_POSIX_SOURCE',
+ ('_POSIX_C_SOURCE', '199309L'),
+ '_SVID_SOURCE',
+ '_BSD_SOURCE',
+ '_GNU_SOURCE',
+ 'PTHREADS',
+ 'HAVE_POSIX_MEMALIGN',
+ ]
+ if env['platform'] == 'darwin':
+ cppdefines += [
+ '_DARWIN_C_SOURCE',
+ 'GLX_USE_APPLEGL',
+ 'GLX_DIRECT_RENDERING',
+ ]
+ else:
+ cppdefines += [
+ 'GLX_DIRECT_RENDERING',
+ 'GLX_INDIRECT_RENDERING',
+ ]
+ if env['platform'] in ('linux', 'freebsd'):
+ cppdefines += ['HAVE_ALIAS']
+ else:
+ cppdefines += ['GLX_ALIAS_UNSUPPORTED']
if platform == 'windows':
cppdefines += [
'WIN32',
@@ -349,8 +341,8 @@ def generate(env):
if platform == 'wince':
cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE']
cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE_OGL']
- if platform == 'embedded':
- cppdefines += ['PIPE_OS_EMBEDDED']
+ if env['embedded']:
+ cppdefines += ['PIPE_SUBSYSTEM_EMBEDDED']
env.Append(CPPDEFINES = cppdefines)
# C compiler options
@@ -367,6 +359,8 @@ def generate(env):
ccflags += ['-O0']
else:
ccflags += ['-O3']
+ # Work around aliasing bugs - developers should comment this out
+ ccflags += ['-fno-strict-aliasing']
ccflags += ['-g3']
if env['build'] in ('checked', 'profile'):
# See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling?
@@ -403,6 +397,8 @@ def generate(env):
ccflags += ['-m64']
if platform == 'darwin':
ccflags += ['-fno-common']
+ if env['platform'] != 'windows':
+ ccflags += ['-fvisibility=hidden']
# See also:
# - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
ccflags += [
@@ -421,10 +417,10 @@ def generate(env):
]
if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'):
ccflags += [
- '-Werror=pointer-arith',
+ '-Wpointer-arith',
]
cflags += [
- '-Werror=declaration-after-statement',
+ '-Wdeclaration-after-statement',
]
if msvc:
# See also:
@@ -595,7 +591,10 @@ def generate(env):
env['LINK'] = env['CXX']
# Default libs
- env.Append(LIBS = [])
+ libs = []
+ if env['platform'] in ('posix', 'linux', 'freebsd', 'darwin'):
+ libs += ['m', 'pthread', 'dl']
+ env.Append(LIBS = libs)
# Load tools
env.Tool('lex')
@@ -603,19 +602,21 @@ def generate(env):
if env['llvm']:
env.Tool('llvm')
- pkg_config_modules(env, 'x11', ['x11', 'xext'])
- pkg_config_modules(env, 'drm', ['libdrm'])
- pkg_config_modules(env, 'drm_intel', ['libdrm_intel'])
- pkg_config_modules(env, 'drm_radeon', ['libdrm_radeon'])
- pkg_config_modules(env, 'xorg', ['xorg-server'])
- pkg_config_modules(env, 'kms', ['libkms'])
-
- env['dri'] = env['x11'] and env['drm']
-
# Custom builders and methods
env.Tool('custom')
createInstallMethods(env)
+ env.PkgCheckModules('X11', ['x11', 'xext', 'xdamage', 'xfixes'])
+ env.PkgCheckModules('XF86VIDMODE', ['xxf86vm'])
+ env.PkgCheckModules('DRM', ['libdrm'])
+ env.PkgCheckModules('DRM_INTEL', ['libdrm_intel'])
+ env.PkgCheckModules('DRM_RADEON', ['libdrm_radeon'])
+ env.PkgCheckModules('XORG', ['xorg-server'])
+ env.PkgCheckModules('KMS', ['libkms'])
+ env.PkgCheckModules('UDEV', ['libudev'])
+
+ env['dri'] = env['x11'] and env['drm']
+
# for debugging
#print env.Dump()
diff --git a/src/SConscript b/src/SConscript
index 7b614daeea1..6d7bd6cd6ec 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -22,6 +22,7 @@ SConscript('mesa/SConscript')
SConscript('mapi/vgapi/SConscript')
if env['platform'] != 'embedded':
+ SConscript('glx/SConscript')
SConscript('egl/main/SConscript')
SConscript('glu/sgi/SConscript')
SConscript('glut/glx/SConscript')
diff --git a/src/driclient/include/driclient.h b/src/driclient/include/driclient.h
deleted file mode 100644
index d3915250392..00000000000
--- a/src/driclient/include/driclient.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef driclient_h
-#define driclient_h
-
-#include <stdint.h>
-#include <X11/Xlib.h>
-#include <drm_sarea.h>
-#include "xf86dri.h"
-
-/* TODO: Bring in DRI XML options */
-
-typedef struct dri_version
-{
- int major;
- int minor;
- int patch;
-} dri_version_t;
-
-typedef struct dri_screen
-{
- Display *display;
- unsigned int num;
- dri_version_t ddx, dri, drm;
- int draw_lock_id;
- int fd;
- drm_sarea_t *sarea;
- void *drawable_hash;
- void *private;
-} dri_screen_t;
-
-struct dri_context;
-
-typedef struct dri_drawable
-{
- drm_drawable_t drm_drawable;
- Drawable x_drawable;
- unsigned int sarea_index;
- unsigned int *sarea_stamp;
- unsigned int last_sarea_stamp;
- int x, y, w, h;
- int back_x, back_y;
- int num_cliprects, num_back_cliprects;
- drm_clip_rect_t *cliprects, *back_cliprects;
- dri_screen_t *dri_screen;
- unsigned int refcount;
- void *private;
-} dri_drawable_t;
-
-typedef struct dri_context
-{
- XID id;
- drm_context_t drm_context;
- dri_screen_t *dri_screen;
- void *private;
-} dri_context_t;
-
-typedef struct dri_framebuffer
-{
- drm_handle_t drm_handle;
- int base, size, stride;
- int private_size;
- void *private;
-} dri_framebuffer_t;
-
-int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf);
-int driDestroyScreen(dri_screen_t *dri_screen);
-int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable);
-int driUpdateDrawableInfo(dri_drawable_t *dri_drawable);
-int driDestroyDrawable(dri_drawable_t *dri_drawable);
-int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context);
-int driDestroyContext(dri_context_t *dri_context);
-
-#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable) \
-do \
-{ \
- if (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \
- driUpdateDrawableInfo(dri_drawable); \
-} while (0)
-
-#define DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable) \
-do \
-{ \
- while (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp) \
- { \
- register unsigned int hwContext = dri_screen->sarea->lock.lock & \
- ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \
- DRM_UNLOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \
- \
- DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \
- DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable); \
- DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id); \
- \
- DRM_LIGHT_LOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext); \
- } \
-} while (0)
-
-#endif
-
diff --git a/src/driclient/include/xf86dri.h b/src/driclient/include/xf86dri.h
deleted file mode 100644
index baf80a7a9dd..00000000000
--- a/src/driclient/include/xf86dri.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/**
- * \file xf86dri.h
- * Protocol numbers and function prototypes for DRI X protocol.
- *
- * \author Kevin E. Martin <martin@valinux.com>
- * \author Jens Owen <jens@tungstengraphics.com>
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-#ifndef _XF86DRI_H_
-#define _XF86DRI_H_
-
-#include <X11/Xfuncproto.h>
-#include <xf86drm.h>
-
-#define X_XF86DRIQueryVersion 0
-#define X_XF86DRIQueryDirectRenderingCapable 1
-#define X_XF86DRIOpenConnection 2
-#define X_XF86DRICloseConnection 3
-#define X_XF86DRIGetClientDriverName 4
-#define X_XF86DRICreateContext 5
-#define X_XF86DRIDestroyContext 6
-#define X_XF86DRICreateDrawable 7
-#define X_XF86DRIDestroyDrawable 8
-#define X_XF86DRIGetDrawableInfo 9
-#define X_XF86DRIGetDeviceInfo 10
-#define X_XF86DRIAuthConnection 11
-#define X_XF86DRIOpenFullScreen 12 /* Deprecated */
-#define X_XF86DRICloseFullScreen 13 /* Deprecated */
-
-#define XF86DRINumberEvents 0
-
-#define XF86DRIClientNotLocal 0
-#define XF86DRIOperationNotSupported 1
-#define XF86DRINumberErrors (XF86DRIOperationNotSupported + 1)
-
-#ifndef _XF86DRI_SERVER_
-
-_XFUNCPROTOBEGIN
-
-Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
-
-Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion,
- int *patchVersion );
-
-Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen,
- Bool *isCapable );
-
-Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA,
- char **busIDString );
-
-Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic );
-
-Bool XF86DRICloseConnection( Display *dpy, int screen );
-
-Bool XF86DRIGetClientDriverName( Display *dpy, int screen,
- int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
- int *ddxDriverPatchVersion, char **clientDriverName );
-
-Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual,
- XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
-
-Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID,
- XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
-
-Bool XF86DRIDestroyContext( Display *dpy, int screen,
- XID context_id );
-
-Bool XF86DRICreateDrawable( Display *dpy, int screen,
- Drawable drawable, drm_drawable_t *hHWDrawable );
-
-Bool XF86DRIDestroyDrawable( Display *dpy, int screen,
- Drawable drawable);
-
-Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects, drm_clip_rect_t **pBackClipRects );
-
-Bool XF86DRIGetDeviceInfo( Display *dpy, int screen,
- drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize,
- int *fbStride, int *devPrivateSize, void **pDevPrivate );
-
-_XFUNCPROTOEND
-
-#endif /* _XF86DRI_SERVER_ */
-
-#endif /* _XF86DRI_H_ */
-
diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile
deleted file mode 100644
index 34435a2086e..00000000000
--- a/src/driclient/src/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = libdriclient.a
-OBJECTS = driclient.o XF86dri.o
-DRMDIR ?= /usr
-
-CFLAGS += -g -Wall -fPIC -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm
-
-#############################################
-
-.PHONY = all clean
-
-all: ${TARGET}
-
-${TARGET}: ${OBJECTS}
- ar rcs $@ $^
- if ! test -d ../lib; then mkdir ../lib; fi
- cp ${TARGET} ../lib
-
-clean:
- rm -rf ${OBJECTS} ${TARGET} ../lib/${TARGET}
diff --git a/src/driclient/src/XF86dri.c b/src/driclient/src/XF86dri.c
deleted file mode 100644
index 831a7603396..00000000000
--- a/src/driclient/src/XF86dri.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD */
-
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include "xf86dristr.h"
-
-static XExtensionInfo _xf86dri_info_data;
-static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
-static char xf86dri_extension_name[] = XF86DRINAME;
-
-#define XF86DRICheckExtension(dpy,i,val) \
- XextCheckExtension (dpy, i, xf86dri_extension_name, val)
-
-/*****************************************************************************
- * *
- * private utility routines *
- * *
- *****************************************************************************/
-
-static int close_display(Display *dpy, XExtCodes *extCodes);
-static /* const */ XExtensionHooks xf86dri_extension_hooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- close_display, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- NULL, /* error_string */
-};
-
-static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info,
- xf86dri_extension_name,
- &xf86dri_extension_hooks,
- 0, NULL)
-
-static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
-
-
-/*****************************************************************************
- * *
- * public XFree86-DRI Extension routines *
- * *
- *****************************************************************************/
-
-#if 0
-#include <stdio.h>
-#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg);
-#else
-#define TRACE(msg)
-#endif
-
-#define PUBLIC
-
-PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
- Display *dpy;
- int *event_basep, *error_basep;
-{
- XExtDisplayInfo *info = find_display (dpy);
-
- TRACE("QueryExtension...");
- if (XextHasExtension(info)) {
- *event_basep = info->codes->first_event;
- *error_basep = info->codes->first_error;
- TRACE("QueryExtension... return True");
- return True;
- } else {
- TRACE("QueryExtension... return False");
- return False;
- }
-}
-
-PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
- Display* dpy;
- int* majorVersion;
- int* minorVersion;
- int* patchVersion;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIQueryVersionReply rep;
- xXF86DRIQueryVersionReq *req;
-
- TRACE("QueryVersion...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryVersion, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryVersion;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return False");
- return False;
- }
- *majorVersion = rep.majorVersion;
- *minorVersion = rep.minorVersion;
- *patchVersion = rep.patchVersion;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryVersion... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
- Display* dpy;
- int screen;
- Bool* isCapable;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIQueryDirectRenderingCapableReply rep;
- xXF86DRIQueryDirectRenderingCapableReq *req;
-
- TRACE("QueryDirectRenderingCapable...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIQueryDirectRenderingCapable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return False");
- return False;
- }
- *isCapable = rep.isCapable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("QueryDirectRenderingCapable... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
- Display* dpy;
- int screen;
- drm_handle_t * hSAREA;
- char **busIdString;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIOpenConnectionReply rep;
- xXF86DRIOpenConnectionReq *req;
-
- TRACE("OpenConnection...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIOpenConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIOpenConnection;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
-
- *hSAREA = rep.hSAREALow;
- if (sizeof(drm_handle_t) == 8) {
- int shift = 32; /* var to prevent warning on next line */
- *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
- }
-
- if (rep.length) {
- if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
- _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return False");
- return False;
- }
- _XReadPad(dpy, *busIdString, rep.busIdStringLength);
- } else {
- *busIdString = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("OpenConnection... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic)
- Display* dpy;
- int screen;
- drm_magic_t magic;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIAuthConnectionReq *req;
- xXF86DRIAuthConnectionReply rep;
-
- TRACE("AuthConnection...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIAuthConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIAuthConnection;
- req->screen = screen;
- req->magic = magic;
- rep.authenticated = 0;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return False");
- return False;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("AuthConnection... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRICloseConnection(dpy, screen)
- Display* dpy;
- int screen;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRICloseConnectionReq *req;
-
- TRACE("CloseConnection...");
-
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICloseConnection, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICloseConnection;
- req->screen = screen;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CloseConnection... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion,
- ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
- Display* dpy;
- int screen;
- int* ddxDriverMajorVersion;
- int* ddxDriverMinorVersion;
- int* ddxDriverPatchVersion;
- char** clientDriverName;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIGetClientDriverNameReply rep;
- xXF86DRIGetClientDriverNameReq *req;
-
- TRACE("GetClientDriverName...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetClientDriverName, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetClientDriverName;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
-
- *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
- *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
- *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
-
- if (rep.length) {
- if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
- _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return False");
- return False;
- }
- _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
- } else {
- *clientDriverName = NULL;
- }
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetClientDriverName... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
- hHWContext)
- Display* dpy;
- int screen;
- int configID;
- XID* context;
- drm_context_t * hHWContext;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRICreateContextReply rep;
- xXF86DRICreateContextReq *req;
-
- TRACE("CreateContext...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateContext;
- req->visual = configID;
- req->screen = screen;
- *context = XAllocID(dpy);
- req->context = *context;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return False");
- return False;
- }
- *hHWContext = rep.hHWContext;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateContext... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
- Display* dpy;
- int screen;
- Visual* visual;
- XID* context;
- drm_context_t * hHWContext;
-{
- return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
- context, hHWContext );
-}
-
-PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen,
- XID context )
-{
- Display * const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIDestroyContextReq *req;
-
- TRACE("DestroyContext...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyContext, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyContext;
- req->screen = screen;
- req->context = context;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyContext... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen,
- Drawable drawable, drm_drawable_t * hHWDrawable )
-{
- Display * const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRICreateDrawableReply rep;
- xXF86DRICreateDrawableReq *req;
-
- TRACE("CreateDrawable...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRICreateDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRICreateDrawable;
- req->screen = screen;
- req->drawable = drawable;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return False");
- return False;
- }
- *hHWDrawable = rep.hHWDrawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("CreateDrawable... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen,
- Drawable drawable )
-{
- Display * const dpy = (Display *) ndpy;
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIDestroyDrawableReq *req;
-
- TRACE("DestroyDrawable...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIDestroyDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIDestroyDrawable;
- req->screen = screen;
- req->drawable = drawable;
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("DestroyDrawable... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
- unsigned int* index, unsigned int* stamp,
- int* X, int* Y, int* W, int* H,
- int* numClipRects, drm_clip_rect_t ** pClipRects,
- int* backX, int* backY,
- int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIGetDrawableInfoReply rep;
- xXF86DRIGetDrawableInfoReq *req;
- int total_rects;
-
- TRACE("GetDrawableInfo...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDrawableInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDrawableInfo;
- req->screen = screen;
- req->drawable = drawable;
-
- if (!_XReply(dpy, (xReply *)&rep, 1, xFalse))
- {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
- *index = rep.drawableTableIndex;
- *stamp = rep.drawableTableStamp;
- *X = (int)rep.drawableX;
- *Y = (int)rep.drawableY;
- *W = (int)rep.drawableWidth;
- *H = (int)rep.drawableHeight;
- *numClipRects = rep.numClipRects;
- total_rects = *numClipRects;
-
- *backX = rep.backX;
- *backY = rep.backY;
- *numBackClipRects = rep.numBackClipRects;
- total_rects += *numBackClipRects;
-
-#if 0
- /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
- * backwards compatibility (Because of the >> 2 shift) but the fix
- * enables multi-threaded apps to work.
- */
- if (rep.length != ((((SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply) +
- total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
- _XEatData(dpy, rep.length);
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return False");
- return False;
- }
-#endif
-
- if (*numClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numClipRects);
-
- *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
- if (*pClipRects)
- _XRead(dpy, (char*)*pClipRects, len);
- } else {
- *pClipRects = NULL;
- }
-
- if (*numBackClipRects) {
- int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
-
- *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
- if (*pBackClipRects)
- _XRead(dpy, (char*)*pBackClipRects, len);
- } else {
- *pBackClipRects = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDrawableInfo... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer,
- fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
- Display* dpy;
- int screen;
- drm_handle_t * hFrameBuffer;
- int* fbOrigin;
- int* fbSize;
- int* fbStride;
- int* devPrivateSize;
- void** pDevPrivate;
-{
- XExtDisplayInfo *info = find_display (dpy);
- xXF86DRIGetDeviceInfoReply rep;
- xXF86DRIGetDeviceInfoReq *req;
-
- TRACE("GetDeviceInfo...");
- XF86DRICheckExtension (dpy, info, False);
-
- LockDisplay(dpy);
- GetReq(XF86DRIGetDeviceInfo, req);
- req->reqType = info->codes->major_opcode;
- req->driReqType = X_XF86DRIGetDeviceInfo;
- req->screen = screen;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
-
- *hFrameBuffer = rep.hFrameBufferLow;
- if (sizeof(drm_handle_t) == 8) {
- int shift = 32; /* var to prevent warning on next line */
- *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
- }
-
- *fbOrigin = rep.framebufferOrigin;
- *fbSize = rep.framebufferSize;
- *fbStride = rep.framebufferStride;
- *devPrivateSize = rep.devPrivateSize;
-
- if (rep.length) {
- if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
- _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return False");
- return False;
- }
- _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
- } else {
- *pDevPrivate = NULL;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
- TRACE("GetDeviceInfo... return True");
- return True;
-}
-
-PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
- Display* dpy;
- int screen;
- Drawable drawable;
-{
- /* This function and the underlying X protocol are deprecated.
- */
- (void) dpy;
- (void) screen;
- (void) drawable;
- return False;
-}
-
-PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
- Display* dpy;
- int screen;
- Drawable drawable;
-{
- /* This function and the underlying X protocol are deprecated.
- */
- (void) dpy;
- (void) screen;
- (void) drawable;
- return True;
-}
-
diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c
deleted file mode 100644
index dc2189afec3..00000000000
--- a/src/driclient/src/driclient.c
+++ /dev/null
@@ -1,310 +0,0 @@
-#include "driclient.h"
-#include <assert.h>
-#include <stdlib.h>
-
-int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf)
-{
- int evbase, errbase;
- char *driver_name;
- int newly_opened;
- drm_magic_t magic;
- drmVersionPtr drm_version;
- drm_handle_t sarea_handle;
- char *bus_id;
- dri_screen_t *dri_scrn;
-
- assert(display);
- assert(dri_screen);
-
- if (!XF86DRIQueryExtension(display, &evbase, &errbase))
- return 1;
-
- dri_scrn = calloc(1, sizeof(dri_screen_t));
-
- if (!dri_scrn)
- return 1;
-
- if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch))
- goto free_screen;
-
- dri_scrn->display = display;
- dri_scrn->num = screen;
- dri_scrn->draw_lock_id = 1;
-
- if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id))
- goto free_screen;
-
- dri_scrn->fd = -1;
- dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened);
- XFree(bus_id);
-
- if (dri_scrn->fd < 0)
- goto close_connection;
-
- if (drmGetMagic(dri_scrn->fd, &magic))
- goto close_drm;
-
- drm_version = drmGetVersion(dri_scrn->fd);
-
- if (!drm_version)
- goto close_drm;
-
- dri_scrn->drm.major = drm_version->version_major;
- dri_scrn->drm.minor = drm_version->version_minor;
- dri_scrn->drm.patch = drm_version->version_patchlevel;
- drmFreeVersion(drm_version);
-
- if (!XF86DRIAuthConnection(display, screen, magic))
- goto close_drm;
-
- if (!XF86DRIGetClientDriverName
- (
- display,
- screen,
- &dri_scrn->ddx.major,
- &dri_scrn->ddx.minor,
- &dri_scrn->ddx.patch,
- &driver_name
- ))
- goto close_drm;
-
- if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea))
- goto close_drm;
-
- dri_scrn->drawable_hash = drmHashCreate();
-
- if (!dri_scrn->drawable_hash)
- goto unmap_sarea;
-
- if (dri_framebuf)
- {
- if (!XF86DRIGetDeviceInfo
- (
- display,
- screen, &dri_framebuf->drm_handle,
- &dri_framebuf->base,
- &dri_framebuf->size,
- &dri_framebuf->stride,
- &dri_framebuf->private_size,
- &dri_framebuf->private
- ))
- goto destroy_hash;
- }
-
- *dri_screen = dri_scrn;
-
- return 0;
-
-destroy_hash:
- drmHashDestroy(dri_scrn->drawable_hash);
-unmap_sarea:
- drmUnmap(dri_scrn->sarea, SAREA_MAX);
-close_drm:
- drmCloseOnce(dri_scrn->fd);
-close_connection:
- XF86DRICloseConnection(display, screen);
-free_screen:
- free(dri_scrn);
-
- return 1;
-}
-
-int driDestroyScreen(dri_screen_t *dri_screen)
-{
- Drawable draw;
- dri_drawable_t *dri_draw;
-
- assert(dri_screen);
-
- if (drmHashFirst(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
- {
- dri_draw->refcount = 1;
- driDestroyDrawable(dri_draw);
-
- while (drmHashNext(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
- {
- dri_draw->refcount = 1;
- driDestroyDrawable(dri_draw);
- }
- }
-
- drmHashDestroy(dri_screen->drawable_hash);
- drmUnmap(dri_screen->sarea, SAREA_MAX);
- drmCloseOnce(dri_screen->fd);
- XF86DRICloseConnection(dri_screen->display, dri_screen->num);
- free(dri_screen);
-
- return 0;
-}
-
-int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable)
-{
- int evbase, errbase;
- dri_drawable_t *dri_draw;
-
- assert(dri_screen);
- assert(dri_drawable);
-
- if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
- return 1;
-
- if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable))
- {
- /* Found */
- (*dri_drawable)->refcount++;
- return 0;
- }
-
- dri_draw = calloc(1, sizeof(dri_drawable_t));
-
- if (!dri_draw)
- return 1;
-
- if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable))
- {
- free(dri_draw);
- return 1;
- }
-
- dri_draw->x_drawable = drawable;
- dri_draw->sarea_index = 0;
- dri_draw->sarea_stamp = NULL;
- dri_draw->last_sarea_stamp = 0;
- dri_draw->dri_screen = dri_screen;
- dri_draw->refcount = 1;
-
- if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw))
- {
- XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
- free(dri_draw);
- return 1;
- }
-
- if (!dri_draw->sarea_stamp || *dri_draw->sarea_stamp != dri_draw->last_sarea_stamp)
- {
- DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
-
- if (driUpdateDrawableInfo(dri_draw))
- {
- XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
- free(dri_draw);
- DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
- return 1;
- }
-
- DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
- }
-
- *dri_drawable = dri_draw;
-
- return 0;
-}
-
-int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
-{
- assert(dri_drawable);
-
- if (dri_drawable->cliprects)
- {
- XFree(dri_drawable->cliprects);
- dri_drawable->cliprects = NULL;
- }
- if (dri_drawable->back_cliprects)
- {
- XFree(dri_drawable->back_cliprects);
- dri_drawable->back_cliprects = NULL;
- }
-
- DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
-
- if (!XF86DRIGetDrawableInfo
- (
- dri_drawable->dri_screen->display,
- dri_drawable->dri_screen->num,
- dri_drawable->x_drawable,
- &dri_drawable->sarea_index,
- &dri_drawable->last_sarea_stamp,
- &dri_drawable->x,
- &dri_drawable->y,
- &dri_drawable->w,
- &dri_drawable->h,
- &dri_drawable->num_cliprects,
- &dri_drawable->cliprects,
- &dri_drawable->back_x,
- &dri_drawable->back_y,
- &dri_drawable->num_back_cliprects,
- &dri_drawable->back_cliprects
- ))
- {
- dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp;
- dri_drawable->num_cliprects = 0;
- dri_drawable->cliprects = NULL;
- dri_drawable->num_back_cliprects = 0;
- dri_drawable->back_cliprects = 0;
-
- return 1;
- }
- else
- dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp;
-
- DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
-
- return 0;
-}
-
-int driDestroyDrawable(dri_drawable_t *dri_drawable)
-{
- assert(dri_drawable);
-
- if (--dri_drawable->refcount == 0)
- {
- if (dri_drawable->cliprects)
- XFree(dri_drawable->cliprects);
- if (dri_drawable->back_cliprects)
- XFree(dri_drawable->back_cliprects);
- drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable);
- XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable);
- free(dri_drawable);
- }
-
- return 0;
-}
-
-int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context)
-{
- int evbase, errbase;
- dri_context_t *dri_ctx;
-
- assert(dri_screen);
- assert(visual);
- assert(dri_context);
-
- if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
- return 1;
-
- dri_ctx = calloc(1, sizeof(dri_context_t));
-
- if (!dri_ctx)
- return 1;
-
- if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context))
- {
- free(dri_ctx);
- return 1;
- }
-
- dri_ctx->dri_screen = dri_screen;
- *dri_context = dri_ctx;
-
- return 0;
-}
-
-int driDestroyContext(dri_context_t *dri_context)
-{
- assert(dri_context);
-
- XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id);
- free(dri_context);
-
- return 0;
-}
diff --git a/src/driclient/src/xf86dristr.h b/src/driclient/src/xf86dristr.h
deleted file mode 100644
index b834bd1a1a0..00000000000
--- a/src/driclient/src/xf86dristr.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sub license, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice (including the
-next paragraph) shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Fiath <faith@valinux.com>
- *
- */
-
-#ifndef _XF86DRISTR_H_
-#define _XF86DRISTR_H_
-
-#include "xf86dri.h"
-
-#define XF86DRINAME "XFree86-DRI"
-
-/* The DRI version number. This was originally set to be the same of the
- * XFree86 version number. However, this version is really indepedent of
- * the XFree86 version.
- *
- * Version History:
- * 4.0.0: Original
- * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
- * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
- */
-#define XF86DRI_MAJOR_VERSION 4
-#define XF86DRI_MINOR_VERSION 1
-#define XF86DRI_PATCH_VERSION 0
-
-typedef struct _XF86DRIQueryVersion {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIQueryVersion */
- CARD16 length B16;
-} xXF86DRIQueryVersionReq;
-#define sz_xXF86DRIQueryVersionReq 4
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD16 majorVersion B16; /* major version of DRI protocol */
- CARD16 minorVersion B16; /* minor version of DRI protocol */
- CARD32 patchVersion B32; /* patch version of DRI protocol */
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIQueryVersionReply;
-#define sz_xXF86DRIQueryVersionReply 32
-
-typedef struct _XF86DRIQueryDirectRenderingCapable {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIQueryDirectRenderingCapableReq;
-#define sz_xXF86DRIQueryDirectRenderingCapableReq 8
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- BOOL isCapable;
- BOOL pad2;
- BOOL pad3;
- BOOL pad4;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
- CARD32 pad9 B32;
-} xXF86DRIQueryDirectRenderingCapableReply;
-#define sz_xXF86DRIQueryDirectRenderingCapableReply 32
-
-typedef struct _XF86DRIOpenConnection {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIOpenConnectionReq;
-#define sz_xXF86DRIOpenConnectionReq 8
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hSAREALow B32;
- CARD32 hSAREAHigh B32;
- CARD32 busIdStringLength B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
- CARD32 pad8 B32;
-} xXF86DRIOpenConnectionReply;
-#define sz_xXF86DRIOpenConnectionReply 32
-
-typedef struct _XF86DRIAuthConnection {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 magic B32;
-} xXF86DRIAuthConnectionReq;
-#define sz_xXF86DRIAuthConnectionReq 12
-
-typedef struct {
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 authenticated B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIAuthConnectionReply;
-#define zx_xXF86DRIAuthConnectionReply 32
-
-typedef struct _XF86DRICloseConnection {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseConnection */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRICloseConnectionReq;
-#define sz_xXF86DRICloseConnectionReq 8
-
-typedef struct _XF86DRIGetClientDriverName {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetClientDriverName */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetClientDriverNameReq;
-#define sz_xXF86DRIGetClientDriverNameReq 8
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 ddxDriverMajorVersion B32;
- CARD32 ddxDriverMinorVersion B32;
- CARD32 ddxDriverPatchVersion B32;
- CARD32 clientDriverNameLength B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIGetClientDriverNameReply;
-#define sz_xXF86DRIGetClientDriverNameReply 32
-
-typedef struct _XF86DRICreateContext {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 visual B32;
- CARD32 context B32;
-} xXF86DRICreateContextReq;
-#define sz_xXF86DRICreateContextReq 16
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWContext B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateContextReply;
-#define sz_xXF86DRICreateContextReply 32
-
-typedef struct _XF86DRIDestroyContext {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyContext */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 context B32;
-} xXF86DRIDestroyContextReq;
-#define sz_xXF86DRIDestroyContextReq 12
-
-typedef struct _XF86DRICreateDrawable {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICreateDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICreateDrawableReq;
-#define sz_xXF86DRICreateDrawableReq 12
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hHWDrawable B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRICreateDrawableReply;
-#define sz_xXF86DRICreateDrawableReply 32
-
-typedef struct _XF86DRIDestroyDrawable {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIDestroyDrawable */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIDestroyDrawableReq;
-#define sz_xXF86DRIDestroyDrawableReq 12
-
-typedef struct _XF86DRIGetDrawableInfo {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDrawableInfo */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIGetDrawableInfoReq;
-#define sz_xXF86DRIGetDrawableInfoReq 12
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 drawableTableIndex B32;
- CARD32 drawableTableStamp B32;
- INT16 drawableX B16;
- INT16 drawableY B16;
- INT16 drawableWidth B16;
- INT16 drawableHeight B16;
- CARD32 numClipRects B32;
- INT16 backX B16;
- INT16 backY B16;
- CARD32 numBackClipRects B32;
-} xXF86DRIGetDrawableInfoReply;
-
-#define sz_xXF86DRIGetDrawableInfoReply 36
-
-
-typedef struct _XF86DRIGetDeviceInfo {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIGetDeviceInfo */
- CARD16 length B16;
- CARD32 screen B32;
-} xXF86DRIGetDeviceInfoReq;
-#define sz_xXF86DRIGetDeviceInfoReq 8
-
-typedef struct {
- BYTE type; /* X_Reply */
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 hFrameBufferLow B32;
- CARD32 hFrameBufferHigh B32;
- CARD32 framebufferOrigin B32;
- CARD32 framebufferSize B32;
- CARD32 framebufferStride B32;
- CARD32 devPrivateSize B32;
-} xXF86DRIGetDeviceInfoReply;
-#define sz_xXF86DRIGetDeviceInfoReply 32
-
-typedef struct _XF86DRIOpenFullScreen {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRIOpenFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRIOpenFullScreenReq;
-#define sz_xXF86DRIOpenFullScreenReq 12
-
-typedef struct {
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 isFullScreen B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
-} xXF86DRIOpenFullScreenReply;
-#define sz_xXF86DRIOpenFullScreenReply 32
-
-typedef struct _XF86DRICloseFullScreen {
- CARD8 reqType; /* always DRIReqCode */
- CARD8 driReqType; /* always X_DRICloseFullScreen */
- CARD16 length B16;
- CARD32 screen B32;
- CARD32 drawable B32;
-} xXF86DRICloseFullScreenReq;
-#define sz_xXF86DRICloseFullScreenReq 12
-
-typedef struct {
- BYTE type;
- BOOL pad1;
- CARD16 sequenceNumber B16;
- CARD32 length B32;
- CARD32 pad2 B32;
- CARD32 pad3 B32;
- CARD32 pad4 B32;
- CARD32 pad5 B32;
- CARD32 pad6 B32;
- CARD32 pad7 B32;
-} xXF86DRICloseFullScreenReply;
-#define sz_xXF86DRICloseFullScreenReply 32
-
-
-#endif /* _XF86DRISTR_H_ */
diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile
index f8ff82b49c2..d2b1f4f077a 100644
--- a/src/egl/drivers/dri2/Makefile
+++ b/src/egl/drivers/dri2/Makefile
@@ -4,12 +4,14 @@ TOP = ../../../..
include $(TOP)/configs/current
EGL_DRIVER = egl_dri2
-EGL_SOURCES = egl_dri2.c platform_drm.c common.c
+EGL_SOURCES = egl_dri2.c common.c
EGL_INCLUDES = \
-I$(TOP)/include \
-I$(TOP)/src/egl/main \
-I$(TOP)/src/mapi \
+ -I$(TOP)/src/gbm/main \
+ -I$(TOP)/src/gbm/backends/dri \
-DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
$(LIBUDEV_CFLAGS) \
$(LIBDRM_CFLAGS)
@@ -29,6 +31,11 @@ EGL_INCLUDES += -DHAVE_X11_PLATFORM $(XCB_DRI2_CFLAGS)
EGL_LIBS += $(XCB_DRI2_LIBS)
endif
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
+EGL_SOURCES += platform_drm.c
+EGL_INCLUDES += -DHAVE_DRM_PLATFORM
+endif
+
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
EGL_SOURCES += platform_wayland.c
EGL_INCLUDES += -DHAVE_WAYLAND_PLATFORM $(WAYLAND_CFLAGS) \
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index d430145d09c..5680c360f1d 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -244,7 +244,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
return conf;
}
-static __DRIimage *
+__DRIimage *
dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
{
_EGLDisplay *disp = data;
@@ -433,42 +433,12 @@ dri2_load_driver_swrast(_EGLDisplay *disp)
return EGL_TRUE;
}
-EGLBoolean
-dri2_create_screen(_EGLDisplay *disp)
+void
+dri2_setup_screen(_EGLDisplay *disp)
{
- const __DRIextension **extensions;
- struct dri2_egl_display *dri2_dpy;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int api_mask;
- dri2_dpy = disp->DriverData;
-
- if (dri2_dpy->dri2) {
- dri2_dpy->dri_screen =
- dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
- &dri2_dpy->driver_configs, disp);
- } else {
- assert(dri2_dpy->swrast);
- dri2_dpy->dri_screen =
- dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions,
- &dri2_dpy->driver_configs, disp);
- }
-
- if (dri2_dpy->dri_screen == NULL) {
- _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
- return EGL_FALSE;
- }
-
- extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
-
- if (dri2_dpy->dri2) {
- if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
- goto cleanup_dri_screen;
- } else {
- assert(dri2_dpy->swrast);
- if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions))
- goto cleanup_dri_screen;
- }
-
if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 2)
api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
@@ -510,6 +480,46 @@ dri2_create_screen(_EGLDisplay *disp)
disp->Extensions.KHR_image_base = EGL_TRUE;
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
}
+}
+
+EGLBoolean
+dri2_create_screen(_EGLDisplay *disp)
+{
+ const __DRIextension **extensions;
+ struct dri2_egl_display *dri2_dpy;
+
+ dri2_dpy = disp->DriverData;
+
+ if (dri2_dpy->dri2) {
+ dri2_dpy->dri_screen =
+ dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
+ &dri2_dpy->driver_configs, disp);
+ } else {
+ assert(dri2_dpy->swrast);
+ dri2_dpy->dri_screen =
+ dri2_dpy->swrast->createNewScreen(0, dri2_dpy->extensions,
+ &dri2_dpy->driver_configs, disp);
+ }
+
+ if (dri2_dpy->dri_screen == NULL) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+ return EGL_FALSE;
+ }
+
+ dri2_dpy->own_dri_screen = 1;
+
+ extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+
+ if (dri2_dpy->dri2) {
+ if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
+ goto cleanup_dri_screen;
+ } else {
+ assert(dri2_dpy->swrast);
+ if (!dri2_bind_extensions(dri2_dpy, swrast_core_extensions, extensions))
+ goto cleanup_dri_screen;
+ }
+
+ dri2_setup_screen(disp);
return EGL_TRUE;
@@ -538,10 +548,12 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp)
#endif
#ifdef HAVE_LIBUDEV
+#ifdef HAVE_DRM_PLATFORM
case _EGL_PLATFORM_DRM:
if (disp->Options.TestOnly)
return EGL_TRUE;
return dri2_initialize_drm(drv, disp);
+#endif
#ifdef HAVE_WAYLAND_PLATFORM
case _EGL_PLATFORM_WAYLAND:
if (disp->Options.TestOnly)
@@ -566,10 +578,12 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
_eglReleaseDisplayResources(drv, disp);
_eglCleanupDisplay(disp);
- dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+ if (dri2_dpy->own_dri_screen)
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
if (dri2_dpy->fd)
close(dri2_dpy->fd);
- dlclose(dri2_dpy->driver);
+ if (dri2_dpy->driver)
+ dlclose(dri2_dpy->driver);
if (disp->PlatformDisplay == NULL) {
switch (disp->Platform) {
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index dd9eb94cf7a..3854200bc69 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -44,6 +44,10 @@
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
+#ifdef HAVE_DRM_PLATFORM
+#include <gbm_driint.h>
+#endif
+
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
@@ -69,6 +73,7 @@ struct dri2_egl_display
int dri2_major;
int dri2_minor;
__DRIscreen *dri_screen;
+ int own_dri_screen;
const __DRIconfig **driver_configs;
void *driver;
__DRIcoreExtension *core;
@@ -79,12 +84,16 @@ struct dri2_egl_display
__DRIimageExtension *image;
int fd;
+#ifdef HAVE_DRM_PLATFORM
+ struct gbm_dri_device *gbm_dri;
+#endif
+
char *device_name;
char *driver_name;
__DRIdri2LoaderExtension dri2_loader_extension;
__DRIswrastLoaderExtension swrast_loader_extension;
- const __DRIextension *extensions[3];
+ const __DRIextension *extensions[4];
#ifdef HAVE_X11_PLATFORM
xcb_connection_t *conn;
@@ -110,6 +119,7 @@ struct dri2_egl_context
enum wayland_buffer_type {
WL_BUFFER_FRONT,
WL_BUFFER_BACK,
+ WL_BUFFER_THIRD,
WL_BUFFER_COUNT
};
@@ -145,9 +155,11 @@ struct dri2_egl_surface
struct wl_egl_window *wl_win;
struct wl_egl_pixmap *wl_pix;
struct wl_buffer *wl_drm_buffer[WL_BUFFER_COUNT];
+ int wl_buffer_lock[WL_BUFFER_COUNT];
int dx;
int dy;
__DRIbuffer *dri_buffers[__DRI_BUFFER_COUNT];
+ __DRIbuffer *third_buffer;
__DRIbuffer *pending_buffer;
EGLBoolean block_swap_buffers;
#endif
@@ -182,12 +194,19 @@ extern const __DRIuseInvalidateExtension use_invalidate;
EGLBoolean
dri2_load_driver(_EGLDisplay *disp);
+/* Helper for platforms not using dri2_create_screen */
+void
+dri2_setup_screen(_EGLDisplay *disp);
+
EGLBoolean
dri2_load_driver_swrast(_EGLDisplay *disp);
EGLBoolean
dri2_create_screen(_EGLDisplay *disp);
+__DRIimage *
+dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);
+
struct dri2_egl_config *
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
int depth, EGLint surface_type, const EGLint *attr_list);
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 27846de39d2..579baf9f9d2 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -33,6 +33,50 @@
#include "egl_dri2.h"
+static _EGLImage *
+dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct gbm_dri_bo *dri_bo = gbm_dri_bo((struct gbm_bo *) buffer);
+ struct dri2_egl_image *dri2_img;
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp)) {
+ free(dri2_img);
+ return NULL;
+ }
+
+ dri2_img->dri_image = dri2_dpy->image->dupImage(dri_bo->image, dri2_img);
+ if (dri2_img->dri_image == NULL) {
+ free(dri2_img);
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr_pixmap");
+ return NULL;
+ }
+
+ return &dri2_img->base;
+}
+
+static _EGLImage *
+dri2_drm_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ (void) drv;
+
+ switch (target) {
+ case EGL_NATIVE_PIXMAP_KHR:
+ return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+ default:
+ return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+ }
+}
+
static int
dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
{
@@ -45,57 +89,58 @@ EGLBoolean
dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
+ struct gbm_device *gbm;
int i;
dri2_dpy = malloc(sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
+
memset(dri2_dpy, 0, sizeof *dri2_dpy);
disp->DriverData = (void *) dri2_dpy;
- dri2_dpy->fd = (int) (intptr_t) disp->PlatformDisplay;
- dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
- if (dri2_dpy->driver_name == NULL)
- return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
+ gbm = (struct gbm_device *) disp->PlatformDisplay;
+ if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
+ free(dri2_dpy);
+ return EGL_FALSE;
+ }
- dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
- if (dri2_dpy->device_name == NULL) {
- _eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
- goto cleanup_driver_name;
+ dri2_dpy->gbm_dri = gbm_dri_device(gbm);
+ if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
+ free(dri2_dpy);
+ return EGL_FALSE;
}
- if (!dri2_load_driver(disp))
- goto cleanup_device_name;
+ dri2_dpy->fd = gbm_device_get_fd(gbm);
+ dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
+ dri2_dpy->driver_name = dri2_dpy->gbm_dri->base.driver_name;
+
+ dri2_dpy->dri_screen = dri2_dpy->gbm_dri->screen;
+ dri2_dpy->core = dri2_dpy->gbm_dri->core;
+ dri2_dpy->dri2 = dri2_dpy->gbm_dri->dri2;
+ dri2_dpy->image = dri2_dpy->gbm_dri->image;
+ dri2_dpy->driver_configs = dri2_dpy->gbm_dri->driver_configs;
- dri2_dpy->extensions[0] = &image_lookup_extension.base;
- dri2_dpy->extensions[1] = &use_invalidate.base;
- dri2_dpy->extensions[2] = NULL;
+ dri2_dpy->gbm_dri->lookup_image = dri2_lookup_egl_image;
+ dri2_dpy->gbm_dri->lookup_user_data = disp;
- if (!dri2_create_screen(disp))
- goto cleanup_driver;
+ dri2_setup_screen(disp);
for (i = 0; dri2_dpy->driver_configs[i]; i++)
- dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0, NULL);
+ dri2_add_config(disp, dri2_dpy->driver_configs[i],
+ i + 1, 0, 0, NULL);
+
+ drv->API.CreateImageKHR = dri2_drm_create_image_khr;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
dri2_dpy->authenticate = dri2_drm_authenticate;
-
+
/* we're supporting EGL 1.4 */
disp->VersionMajor = 1;
disp->VersionMinor = 4;
return EGL_TRUE;
-
- cleanup_driver:
- dlclose(dri2_dpy->driver);
- cleanup_device_name:
- free(dri2_dpy->device_name);
- cleanup_driver_name:
- free(dri2_dpy->driver_name);
-
- return EGL_FALSE;
}
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index e786780d3fb..c4fa126951b 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -59,6 +59,29 @@ force_roundtrip(struct wl_display *display)
wl_display_iterate(display, WL_DISPLAY_READABLE);
}
+static void
+wl_buffer_release(void *data, struct wl_buffer *buffer)
+{
+ struct dri2_egl_surface *dri2_surf = data;
+ int i;
+
+ for (i = 0; i < WL_BUFFER_COUNT; ++i)
+ if (dri2_surf->wl_drm_buffer[i] == buffer)
+ break;
+
+ assert(i <= WL_BUFFER_COUNT);
+
+ /* not found? */
+ if (i == WL_BUFFER_COUNT)
+ return;
+
+ dri2_surf->wl_buffer_lock[i] = 0;
+
+}
+
+static struct wl_buffer_listener wl_buffer_listener = {
+ wl_buffer_release
+};
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
@@ -85,13 +108,16 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
goto cleanup_surf;
- for (i = 0; i < WL_BUFFER_COUNT; ++i)
+ for (i = 0; i < WL_BUFFER_COUNT; ++i) {
dri2_surf->wl_drm_buffer[i] = NULL;
+ dri2_surf->wl_buffer_lock[i] = 0;
+ }
for (i = 0; i < __DRI_BUFFER_COUNT; ++i)
dri2_surf->dri_buffers[i] = NULL;
dri2_surf->pending_buffer = NULL;
+ dri2_surf->third_buffer = NULL;
dri2_surf->block_swap_buffers = EGL_FALSE;
switch (type) {
@@ -187,6 +213,11 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
dri2_surf->dri_buffers[i]);
+ if (dri2_surf->third_buffer) {
+ dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+ dri2_surf->third_buffer);
+ }
+
free(surf);
return EGL_TRUE;
@@ -215,10 +246,14 @@ wayland_create_buffer(struct dri2_egl_surface *dri2_surf,
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
+ struct wl_buffer *buf;
- return wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
- dri2_surf->base.Width, dri2_surf->base.Height,
- buffer->pitch, visual);
+ buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,
+ dri2_surf->base.Width, dri2_surf->base.Height,
+ buffer->pitch, visual);
+ wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf);
+
+ return buf;
}
static void
@@ -232,6 +267,8 @@ dri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)
switch (dri2_surf->type) {
case DRI2_WINDOW_SURFACE:
/* allocate a front buffer for our double-buffered window*/
+ if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL)
+ break;
dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
__DRI_BUFFER_FRONT_LEFT, format,
@@ -289,6 +326,12 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf)
dri2_egl_display(dri2_surf->base.Resource.Display);
int i;
+ if (dri2_surf->third_buffer) {
+ dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+ dri2_surf->third_buffer);
+ dri2_surf->third_buffer = NULL;
+ }
+
for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
if (dri2_surf->dri_buffers[i]) {
switch (i) {
@@ -309,6 +352,76 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf)
}
}
+static inline void
+pointer_swap(const void **p1, const void **p2)
+{
+ const void *tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+static void
+destroy_third_buffer(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ if (dri2_surf->third_buffer == NULL)
+ return;
+
+ dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
+ dri2_surf->third_buffer);
+ dri2_surf->third_buffer = NULL;
+
+ if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD])
+ wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]);
+ dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL;
+ dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0;
+}
+
+static void
+swap_wl_buffers(struct dri2_egl_surface *dri2_surf,
+ enum wayland_buffer_type a, enum wayland_buffer_type b)
+{
+ int tmp;
+
+ tmp = dri2_surf->wl_buffer_lock[a];
+ dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b];
+ dri2_surf->wl_buffer_lock[b] = tmp;
+
+ pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a],
+ (const void **) &dri2_surf->wl_drm_buffer[b]);
+}
+
+static void
+swap_back_and_third(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD])
+ destroy_third_buffer(dri2_surf);
+
+ pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT],
+ (const void **) &dri2_surf->third_buffer);
+
+ swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD);
+}
+
+static void
+dri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf,
+ unsigned int type)
+{
+ switch (type) {
+ case __DRI_BUFFER_BACK_LEFT:
+ if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK])
+ swap_back_and_third(dri2_surf);
+ else if (dri2_surf->third_buffer)
+ destroy_third_buffer(dri2_surf);
+ break;
+ default:
+ break;
+
+ }
+}
+
static __DRIbuffer *
dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
int *width, int *height,
@@ -335,6 +448,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
if (dri2_surf->wl_drm_buffer[i])
wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);
dri2_surf->wl_drm_buffer[i] = NULL;
+ dri2_surf->wl_buffer_lock[i] = 0;
}
}
@@ -343,6 +457,8 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
assert(attachments[i] < __DRI_BUFFER_COUNT);
assert(dri2_surf->buffer_count < 5);
+ dri2_prior_buffer_creation(dri2_surf, attachments[i]);
+
if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
dri2_surf->dri_buffers[attachments[i]] =
@@ -443,14 +559,6 @@ wayland_frame_callback(struct wl_surface *surface, void *data, uint32_t time)
dri2_surf->block_swap_buffers = EGL_FALSE;
}
-static inline void
-pointer_swap(const void **p1, const void **p2)
-{
- const void *tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
-}
-
/**
* Called via eglSwapBuffers(), drv->API.SwapBuffers().
*/
@@ -466,8 +574,8 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
dri2_surf->block_swap_buffers = EGL_TRUE;
wl_display_frame_callback(dri2_dpy->wl_dpy,
- dri2_surf->wl_win->surface,
- wayland_frame_callback, dri2_surf);
+ dri2_surf->wl_win->surface,
+ wayland_frame_callback, dri2_surf);
if (dri2_surf->type == DRI2_WINDOW_SURFACE) {
pointer_swap(
@@ -479,8 +587,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
__DRI_BUFFER_BACK_LEFT;
- pointer_swap((const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
- (const void **) &dri2_surf->wl_drm_buffer[WL_BUFFER_BACK]);
+ swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);
if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])
dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =
@@ -493,6 +600,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
wl_surface_attach(dri2_surf->wl_win->surface,
dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],
dri2_surf->dx, dri2_surf->dy);
+ dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;
dri2_surf->wl_win->attached_width = dri2_surf->base.Width;
dri2_surf->wl_win->attached_height = dri2_surf->base.Height;
@@ -720,7 +828,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
dri2_dpy->extensions[1] = &image_lookup_extension.base;
- dri2_dpy->extensions[2] = NULL;
+ dri2_dpy->extensions[2] = &use_invalidate.base;
+ dri2_dpy->extensions[3] = NULL;
if (!dri2_create_screen(disp))
goto cleanup_driver;
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
index 8bff294c9e6..4e00c958cbd 100644
--- a/src/egl/drivers/dri2/platform_x11.c
+++ b/src/egl/drivers/dri2/platform_x11.c
@@ -479,10 +479,19 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
xcb_generic_error_t *error;
xcb_screen_iterator_t s;
char *driver_name, *device_name;
+ const xcb_query_extension_reply_t *extension;
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id);
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id);
+ extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_xfixes_id);
+ if (!(extension && extension->present))
+ return EGL_FALSE;
+
+ extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri2_id);
+ if (!(extension && extension->present))
+ return EGL_FALSE;
+
xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn,
XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION);
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index c3c11c7b6eb..7cf8f4d5514 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -1,8 +1,10 @@
/**************************************************************************
- *
+ *
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,19 +12,19 @@
* 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.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 6c4a392760f..775fbbe178b 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -61,9 +61,13 @@ LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a
ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
EGL_LIB_DEPS += $(XCB_DRI2_LIBS)
endif
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
+EGL_LIB_DEPS += -lgbm
+endif
EGL_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
endif
+
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
endif
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index bdfdcb3817d..0ba7794e2c9 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* Public EGL API entrypoints
*
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index c9913f10a10..4fcbe40cd4c 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLAPI_INCLUDED
#define EGLAPI_INCLUDED
diff --git a/src/egl/main/eglarray.c b/src/egl/main/eglarray.c
index fe2f1a7f32f..3ccc8a649f0 100644
--- a/src/egl/main/eglarray.c
+++ b/src/egl/main/eglarray.c
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/egl/main/eglarray.h b/src/egl/main/eglarray.h
index a88189a6252..d07f301f242 100644
--- a/src/egl/main/eglarray.h
+++ b/src/egl/main/eglarray.h
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLARRAY_INCLUDED
#define EGLARRAY_INCLUDED
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
index 90c75e84b29..1bc8cc89fa4 100644
--- a/src/egl/main/eglcompiler.h
+++ b/src/egl/main/eglcompiler.h
@@ -1,3 +1,32 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLCOMPILER_INCLUDED
#define EGLCOMPILER_INCLUDED
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 5b377b7f610..483d9807cf0 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* EGL Configuration (pixel format) functions.
*/
@@ -305,6 +335,7 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
break;
default:
assert(0);
+ mask = 0;
break;
}
if (val & ~mask)
@@ -456,8 +487,6 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
return EGL_FALSE;
switch (attr) {
- case EGL_MATCH_NATIVE_PIXMAP:
- return EGL_FALSE;
case EGL_Y_INVERTED_NOK:
return conf->Display->Extensions.NOK_texture_from_pixmap;
default:
@@ -634,7 +663,7 @@ void _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2)
* qsort() in that the compare function accepts an additional
* argument.
*/
-void
+static void
_eglSortConfigs(const _EGLConfig **configs, EGLint count,
EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
void *),
@@ -672,34 +701,27 @@ _eglSortConfigs(const _EGLConfig **configs, EGLint count,
}
-static int
-_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2,
- void *priv_data)
-{
- const _EGLConfig *criteria = (const _EGLConfig *) priv_data;
- return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
-}
-
-
/**
- * Typical fallback routine for eglChooseConfig
+ * A helper function for implementing eglChooseConfig. See _eglFilterArray and
+ * _eglSortConfigs for the meanings of match and compare.
*/
EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
- EGLConfig *configs, EGLint config_size, EGLint *num_configs)
+_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs,
+ EGLint config_size, EGLint *num_configs,
+ EGLBoolean (*match)(const _EGLConfig *, void *),
+ EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
+ void *),
+ void *priv_data)
{
- _EGLConfig **configList, criteria;
+ _EGLConfig **configList;
EGLint i, count;
if (!num_configs)
return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
- if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
- return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
-
/* get the number of matched configs */
- count = _eglFilterArray(disp->Configs, NULL, 0,
- (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+ count = _eglFilterArray(array, NULL, 0,
+ (_EGLArrayForEach) match, priv_data);
if (!count) {
*num_configs = count;
return EGL_TRUE;
@@ -710,13 +732,13 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
/* get the matched configs */
- _eglFilterArray(disp->Configs, (void **) configList, count,
- (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+ _eglFilterArray(array, (void **) configList, count,
+ (_EGLArrayForEach) match, priv_data);
/* perform sorting of configs */
if (configs && count) {
_eglSortConfigs((const _EGLConfig **) configList, count,
- _eglFallbackCompare, (void *) &criteria);
+ compare, priv_data);
count = MIN2(count, config_size);
for (i = 0; i < count; i++)
configs[i] = _eglGetConfigHandle(configList[i]);
@@ -730,6 +752,41 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
}
+static EGLBoolean
+_eglFallbackMatch(const _EGLConfig *conf, void *priv_data)
+{
+ return _eglMatchConfig(conf, (const _EGLConfig *) priv_data);
+}
+
+
+static EGLint
+_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2,
+ void *priv_data)
+{
+ return _eglCompareConfigs(conf1, conf2,
+ (const _EGLConfig *) priv_data, EGL_TRUE);
+}
+
+
+/**
+ * Typical fallback routine for eglChooseConfig
+ */
+EGLBoolean
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size, EGLint *num_configs)
+{
+ _EGLConfig criteria;
+
+ if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
+ return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
+
+ return _eglFilterConfigArray(disp->Configs,
+ configs, config_size, num_configs,
+ _eglFallbackMatch, _eglFallbackCompare,
+ (void *) &criteria);
+}
+
+
/**
* Fallback for eglGetConfigAttrib.
*/
@@ -739,6 +796,16 @@ _eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
{
if (!_eglIsConfigAttribValid(conf, attribute))
return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
+
+ /* nonqueryable attributes */
+ switch (attribute) {
+ case EGL_MATCH_NATIVE_PIXMAP:
+ return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
+ break;
+ default:
+ break;
+ }
+
if (!value)
return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib");
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 2169960fd1d..adab95cd6a3 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLCONFIG_INCLUDED
#define EGLCONFIG_INCLUDED
@@ -172,11 +202,13 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
const _EGLConfig *criteria, EGLBoolean compare_id);
-PUBLIC void
-_eglSortConfigs(const _EGLConfig **configs, EGLint count,
- EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
- void *),
- void *priv_data);
+PUBLIC EGLBoolean
+_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs,
+ EGLint config_size, EGLint *num_configs,
+ EGLBoolean (*match)(const _EGLConfig *, void *),
+ EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
+ void *),
+ void *filter_data);
extern EGLBoolean
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 33dcfa68756..38e195f0446 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <assert.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 8cd0df17313..0ac846219a7 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLCONTEXT_INCLUDED
#define EGLCONTEXT_INCLUDED
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 4221a9be3e1..54fc4f742e5 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <stdlib.h>
#include <string.h>
#include "egllog.h"
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index e5c94ce60ab..a64821eb125 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLCURRENT_INCLUDED
#define EGLCURRENT_INCLUDED
diff --git a/src/egl/main/egldefines.h b/src/egl/main/egldefines.h
index 4ecd4c1420c..d468d7b76cc 100644
--- a/src/egl/main/egldefines.h
+++ b/src/egl/main/egldefines.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* 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
@@ -10,23 +10,22 @@
* 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.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
-
/**
* Internal EGL defines
*/
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 30592947297..60f31777272 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* Functions related to EGLDisplay.
*/
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 97ae2b01ba0..9cd4dbfcc8a 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index b75e8b6a2cb..ffdd1462846 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* Functions for choosing and opening/loading device drivers.
*/
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 3cde102d12d..4bb9612765b 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLDRIVER_INCLUDED
#define EGLDRIVER_INCLUDED
diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c
index 7c93adb76aa..b4f35d742ae 100644
--- a/src/egl/main/eglfallbacks.c
+++ b/src/egl/main/eglfallbacks.c
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <string.h>
#include "egltypedefs.h"
#include "egldriver.h"
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index 52eebb07f6c..f53f078d710 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <stdlib.h>
#include <assert.h>
#include "eglglobals.h"
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index c3771a8ef10..b40e30e2251 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLGLOBALS_INCLUDED
#define EGLGLOBALS_INCLUDED
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 6d4ee4e08b9..458a2e424d3 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -1,3 +1,32 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <assert.h>
#include <string.h>
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index adb939a9e02..acb36aaeb18 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -1,3 +1,32 @@
+/**************************************************************************
+ *
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLIMAGE_INCLUDED
#define EGLIMAGE_INCLUDED
diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c
index 12c55f901a5..43eed64c299 100644
--- a/src/egl/main/egllog.c
+++ b/src/egl/main/egllog.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* Logging facility for debug/info messages.
* _EGL_FATAL messages are printed to stderr
diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h
index 03bef2670f1..10a418447bd 100644
--- a/src/egl/main/egllog.h
+++ b/src/egl/main/egllog.h
@@ -1,3 +1,32 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLLOG_INCLUDED
#define EGLLOG_INCLUDED
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 6bb2498eef4..da189b689a3 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -1,8 +1,10 @@
/**************************************************************************
- *
+ *
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,19 +12,19 @@
* 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.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h
index a753307a14b..da0adbd0ee2 100644
--- a/src/egl/main/eglmisc.h
+++ b/src/egl/main/eglmisc.h
@@ -1,8 +1,10 @@
/**************************************************************************
- *
+ *
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,19 +12,19 @@
* 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.
- *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
index a9653496c32..617d4c2d60a 100644
--- a/src/egl/main/eglmode.c
+++ b/src/egl/main/eglmode.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <assert.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index ed4eb2c34af..a423f026483 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLMODE_INCLUDED
#define EGLMODE_INCLUDED
diff --git a/src/egl/main/eglmutex.h b/src/egl/main/eglmutex.h
index 29faba0f241..852e25195c4 100644
--- a/src/egl/main/eglmutex.h
+++ b/src/egl/main/eglmutex.h
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Chia-I Wu <olvaffe@gmail.com>
+ * 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 NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLMUTEX_INCLUDED
#define EGLMUTEX_INCLUDED
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 3abe85ff22f..e21952094a2 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/*
* Ideas for screen management extension to EGL.
*
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 2a99f23c50a..5e2f6579e62 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLSCREEN_INCLUDED
#define EGLSCREEN_INCLUDED
diff --git a/src/egl/main/eglstring.c b/src/egl/main/eglstring.c
index e4ab19136fb..e3568cb3c20 100644
--- a/src/egl/main/eglstring.c
+++ b/src/egl/main/eglstring.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* String utils.
*/
diff --git a/src/egl/main/eglstring.h b/src/egl/main/eglstring.h
index d4c89541362..d3ab435ab7f 100644
--- a/src/egl/main/eglstring.h
+++ b/src/egl/main/eglstring.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010-2011 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLSTRING_INCLUDED
#define EGLSTRING_INCLUDED
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index cc505045e12..c9cfb01388e 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
/**
* Surface-related functions.
*/
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index ef01b32ede3..0541ff4e2f1 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLSURFACE_INCLUDED
#define EGLSURFACE_INCLUDED
diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c
index 95e97c73542..d8e3ee0c3bf 100644
--- a/src/egl/main/eglsync.c
+++ b/src/egl/main/eglsync.c
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#include <string.h>
#include "eglsync.h"
diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h
index a0025237e7a..1a56889642e 100644
--- a/src/egl/main/eglsync.h
+++ b/src/egl/main/eglsync.h
@@ -1,3 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLSYNC_INCLUDED
#define EGLSYNC_INCLUDED
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 20b67b28bc6..120a277b5fb 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
#ifndef EGLTYPEDEFS_INCLUDED
#define EGLTYPEDEFS_INCLUDED
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c
index 6cc442b9d53..3023cd02b07 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -88,17 +88,17 @@ drm_create_buffer(struct wl_client *client, struct wl_drm *drm,
{
struct wl_drm_buffer *buffer;
- buffer = malloc(sizeof *buffer);
+ buffer = calloc(1, sizeof *buffer);
if (buffer == NULL) {
wl_client_post_no_memory(client);
return;
}
buffer->drm = drm;
- buffer->buffer.compositor = NULL;
buffer->buffer.width = width;
buffer->buffer.height = height;
buffer->buffer.visual = visual;
+ buffer->buffer.client = client;
if (!visual || visual->object.interface != &wl_visual_interface) {
wl_client_post_error(client, &drm->object,
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index 428bc31f86b..3072ee936f2 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -53,7 +53,7 @@ if env['drm']:
# Needed by some state trackers
SConscript('winsys/sw/null/SConscript')
-if env['platform'] != 'embedded':
+if not env['embedded']:
SConscript('state_trackers/vega/SConscript')
SConscript('state_trackers/egl/SConscript')
@@ -66,8 +66,8 @@ if env['platform'] != 'embedded':
if env['dri'] and env['xorg']:
SConscript('state_trackers/xorg/SConscript')
-if env['platform'] == 'windows':
- SConscript('state_trackers/wgl/SConscript')
+ if env['platform'] == 'windows':
+ SConscript('state_trackers/wgl/SConscript')
#
# Winsys
@@ -83,55 +83,55 @@ SConscript([
'targets/graw-null/SConscript',
])
-if env['platform'] != 'embedded':
+if not env['embedded']:
SConscript([
'targets/egl-static/SConscript'
])
-if env['x11']:
- SConscript([
- 'targets/graw-xlib/SConscript',
- 'targets/libgl-xlib/SConscript',
- ])
+ if env['x11']:
+ SConscript([
+ 'targets/graw-xlib/SConscript',
+ 'targets/libgl-xlib/SConscript',
+ ])
-if env['platform'] == 'windows':
- SConscript([
- 'targets/graw-gdi/SConscript',
- 'targets/libgl-gdi/SConscript',
- ])
+ if env['platform'] == 'windows':
+ SConscript([
+ 'targets/graw-gdi/SConscript',
+ 'targets/libgl-gdi/SConscript',
+ ])
-if env['dri']:
- SConscript([
- 'targets/SConscript.dri',
- 'targets/dri-swrast/SConscript',
- 'targets/dri-vmwgfx/SConscript',
- #'targets/dri-nouveau/SConscript',
- ])
- if env['drm_intel']:
+ if env['dri']:
SConscript([
- 'targets/dri-i915/SConscript',
- 'targets/dri-i965/SConscript',
+ 'targets/SConscript.dri',
+ 'targets/dri-swrast/SConscript',
+ 'targets/dri-vmwgfx/SConscript',
+ #'targets/dri-nouveau/SConscript',
])
- if env['drm_radeon']:
+ if env['drm_intel']:
+ SConscript([
+ 'targets/dri-i915/SConscript',
+ 'targets/dri-i965/SConscript',
+ ])
+ if env['drm_radeon']:
+ SConscript([
+ 'targets/dri-r300/SConscript',
+ 'targets/dri-r600/SConscript',
+ ])
+
+ if env['xorg'] and env['drm']:
SConscript([
- 'targets/dri-r300/SConscript',
- 'targets/dri-r600/SConscript',
+ #'targets/xorg-i915/SConscript',
+ #'targets/xorg-i965/SConscript',
+ #'targets/xorg-nouveau/SConscript',
+ #'targets/xorg-radeon/SConscript',
+ 'targets/xorg-vmwgfx/SConscript',
])
-if env['xorg'] and env['drm']:
- SConscript([
- #'targets/xorg-i915/SConscript',
- #'targets/xorg-i965/SConscript',
- #'targets/xorg-nouveau/SConscript',
- #'targets/xorg-radeon/SConscript',
- 'targets/xorg-vmwgfx/SConscript',
- ])
-
#
# Unit tests & tools
#
-if env['platform'] != 'embedded':
+if not env['embedded']:
SConscript('tests/unit/SConscript')
SConscript('tests/graw/SConscript')
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 56c26f57cce..f33c9078c9c 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1163,6 +1163,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
struct lp_build_loop_state lp_loop;
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+ LLVMValueRef fetch_max;
void *code;
struct lp_build_sampler_soa *sampler = 0;
LLVMValueRef ret, ret_ptr;
@@ -1234,6 +1235,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
draw_llvm_variant_key_samplers(&variant->key),
context_ptr);
+ fetch_max = LLVMBuildSub(builder, count,
+ lp_build_const_int32(gallivm, 1),
+ "fetch_max");
+
#if DEBUG_STORE
lp_build_printf(builder, "start = %d, end = %d, step = %d\n",
start, end, step);
@@ -1257,6 +1262,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
builder,
lp_loop.counter,
lp_build_const_int32(gallivm, i), "");
+
+ /* make sure we're not out of bounds which can happen
+ * if fetch_count % 4 != 0, because on the last iteration
+ * a few of the 4 vertex fetches will be out of bounds */
+ true_index = lp_build_min(&bld, true_index, fetch_max);
+
for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
LLVMValueRef vb_index = lp_build_const_int32(gallivm, velem->vertex_buffer_index);
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 32af29ae144..458f85def2c 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -784,6 +784,14 @@ aaline_destroy(struct draw_stage *stage)
draw_free_temp_verts( stage );
+ /* restore the old entry points */
+ pipe->create_fs_state = aaline->driver_create_fs_state;
+ pipe->bind_fs_state = aaline->driver_bind_fs_state;
+ pipe->delete_fs_state = aaline->driver_delete_fs_state;
+
+ pipe->bind_fragment_sampler_states = aaline->driver_bind_sampler_states;
+ pipe->set_fragment_sampler_views = aaline->driver_set_sampler_views;
+
FREE( stage );
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 60f6380c503..9265c379de8 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -768,7 +768,16 @@ aapoint_reset_stipple_counter(struct draw_stage *stage)
static void
aapoint_destroy(struct draw_stage *stage)
{
+ struct aapoint_stage* aapoint = aapoint_stage(stage);
+ struct pipe_context *pipe = stage->draw->pipe;
+
draw_free_temp_verts( stage );
+
+ /* restore the old entry points */
+ pipe->create_fs_state = aapoint->driver_create_fs_state;
+ pipe->bind_fs_state = aapoint->driver_bind_fs_state;
+ pipe->delete_fs_state = aapoint->driver_delete_fs_state;
+
FREE( stage );
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
index 0b724a34948..01e660ef7d9 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
@@ -207,7 +207,11 @@ lp_disassemble(const void* func)
}
raw_debug_ostream Out;
+#if HAVE_LLVM >= 0x0300
+ TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "");
+#else
TargetMachine *TM = T->createTargetMachine(Triple, "");
+#endif
#if HAVE_LLVM >= 0x0300
unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
@@ -287,7 +291,11 @@ lp_disassemble(const void* func)
pc += Size;
+#if HAVE_LLVM >= 0x0300
+ const MCInstrDesc &TID = TII->get(Inst.getOpcode());
+#else
const TargetInstrDesc &TID = TII->get(Inst.getOpcode());
+#endif
/*
* Keep track of forward jumps to a nearby address.
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index d2d7eccd92f..85fabc574b2 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -83,8 +83,12 @@ lp_set_target_options(void)
* to only assume a 4 bytes alignment for backwards compatibility.
*/
#if defined(PIPE_ARCH_X86)
+#if HAVE_LLVM >= 0x0300
+ llvm::StackAlignmentOverride = 4;
+#else
llvm::StackAlignment = 4;
#endif
+#endif
#if defined(DEBUG) || defined(PROFILE)
llvm::NoFramePointerElim = true;
diff --git a/src/gallium/auxiliary/indices/u_unfilled_gen.py b/src/gallium/auxiliary/indices/u_unfilled_gen.py
index 36896ce605d..085c47a114a 100644
--- a/src/gallium/auxiliary/indices/u_unfilled_gen.py
+++ b/src/gallium/auxiliary/indices/u_unfilled_gen.py
@@ -167,8 +167,8 @@ def trifan(intype, outtype):
def polygon(intype, outtype):
preamble(intype, outtype, prim='polygon')
- print ' for (j = i = 0; j < nr; j+=6, i++) { '
- do_tri( intype, outtype, 'out+j', '0', 'i+1', 'i+2' );
+ print ' for (j = i = 0; j < nr; j+=2, i++) { '
+ line( intype, outtype, 'out+j', 'i', '(i+1)%(nr/2)' )
print ' }'
postamble()
diff --git a/src/gallium/auxiliary/indices/u_unfilled_indices.c b/src/gallium/auxiliary/indices/u_unfilled_indices.c
index 26c5d4d4c72..c353717d656 100644
--- a/src/gallium/auxiliary/indices/u_unfilled_indices.c
+++ b/src/gallium/auxiliary/indices/u_unfilled_indices.c
@@ -71,6 +71,11 @@ static void generate_linear_uint( unsigned nr,
}
+/**
+ * Given a primitive type and number of vertices, return the number of vertices
+ * needed to draw the primitive with fill mode = PIPE_POLYGON_MODE_LINE using
+ * separate lines (PIPE_PRIM_LINES).
+ */
static unsigned nr_lines( unsigned prim,
unsigned nr )
{
@@ -86,7 +91,7 @@ static unsigned nr_lines( unsigned prim,
case PIPE_PRIM_QUAD_STRIP:
return (nr - 2) / 2 * 8;
case PIPE_PRIM_POLYGON:
- return (nr - 2) * 6;
+ return 2 * nr; /* a line (two verts) for each polygon edge */
default:
assert(0);
return 0;
diff --git a/src/gallium/auxiliary/os/os_memory.h b/src/gallium/auxiliary/os/os_memory.h
index 556662d35e1..91a84a24bc8 100644
--- a/src/gallium/auxiliary/os/os_memory.h
+++ b/src/gallium/auxiliary/os/os_memory.h
@@ -39,7 +39,7 @@
#include "pipe/p_compiler.h"
-#if defined(PIPE_OS_EMBEDDED)
+#if defined(PIPE_SUBSYSTEM_EMBEDDED)
#ifdef __cplusplus
extern "C" {
diff --git a/src/gallium/auxiliary/os/os_misc.h b/src/gallium/auxiliary/os/os_misc.h
index d59f9819fec..48522dac4d7 100644
--- a/src/gallium/auxiliary/os/os_misc.h
+++ b/src/gallium/auxiliary/os/os_misc.h
@@ -58,8 +58,6 @@ extern "C" {
# define os_break() __debugbreak()
#elif defined(PIPE_OS_UNIX)
# define os_break() kill(getpid(), SIGTRAP)
-#elif defined(PIPE_OS_EMBEDDED)
-void os_break(void);
#else
# define os_break() abort()
#endif
@@ -70,8 +68,6 @@ void os_break(void);
*/
#if defined(DEBUG) || defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
# define os_abort() os_break()
-#elif defined(PIPE_OS_EMBEDDED)
-void os_abort(void);
#else
# define os_abort() abort()
#endif
diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h
index 6b4281ad661..8f1245bff55 100644
--- a/src/gallium/auxiliary/os/os_thread.h
+++ b/src/gallium/auxiliary/os/os_thread.h
@@ -40,7 +40,7 @@
#include "util/u_debug.h" /* for assert */
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
#include <pthread.h> /* POSIX threads headers */
#include <stdio.h> /* for perror() */
@@ -314,7 +314,7 @@ typedef int64_t pipe_condvar;
* pipe_barrier
*/
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
typedef pthread_barrier_t pipe_barrier;
@@ -442,7 +442,7 @@ pipe_semaphore_wait(pipe_semaphore *sema)
*/
typedef struct {
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
pthread_key_t key;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
DWORD key;
@@ -457,7 +457,7 @@ typedef struct {
static INLINE void
pipe_tsd_init(pipe_tsd *tsd)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
perror("pthread_key_create(): failed to allocate key for thread specific data");
exit(-1);
@@ -474,7 +474,7 @@ pipe_tsd_get(pipe_tsd *tsd)
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
pipe_tsd_init(tsd);
}
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
return pthread_getspecific(tsd->key);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
assert(0);
@@ -491,7 +491,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value)
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
pipe_tsd_init(tsd);
}
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_EMBEDDED) || defined(PIPE_OS_CYGWIN)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
if (pthread_setspecific(tsd->key, value) != 0) {
perror("pthread_set_specific() failed");
exit(-1);
diff --git a/src/gallium/auxiliary/os/os_time.c b/src/gallium/auxiliary/os/os_time.c
index 325f316784c..73d86296d91 100644
--- a/src/gallium/auxiliary/os/os_time.c
+++ b/src/gallium/auxiliary/os/os_time.c
@@ -35,8 +35,6 @@
#include "pipe/p_config.h"
-#if !defined(PIPE_OS_EMBEDDED)
-
#if defined(PIPE_OS_UNIX)
# include <sys/time.h> /* timeval */
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
@@ -123,6 +121,3 @@ os_time_sleep(int64_t usecs)
}
#endif
-
-
-#endif /* !PIPE_OS_EMBEDDED */
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 36ce4b57713..004df439ff5 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -48,7 +48,7 @@
void _debug_vprintf(const char *format, va_list ap)
{
-#if defined(PIPE_OS_WINDOWS) || defined(PIPE_OS_EMBEDDED)
+#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED)
/* We buffer until we find a newline. */
static char buf[4096] = {'\0'};
size_t len = strlen(buf);
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 9562acb8210..e50db6d67fe 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -72,6 +72,22 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
return upload;
}
+void u_upload_unmap( struct u_upload_mgr *upload )
+{
+ if (upload->transfer) {
+ struct pipe_box *box = &upload->transfer->box;
+ if (upload->offset > box->x) {
+
+ pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
+ box->x, upload->offset - box->x);
+ }
+ pipe_transfer_unmap(upload->pipe, upload->transfer);
+ pipe_transfer_destroy(upload->pipe, upload->transfer);
+ upload->transfer = NULL;
+ upload->map = NULL;
+ }
+}
+
/* Release old buffer.
*
* This must usually be called prior to firing the command stream
@@ -84,15 +100,7 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
void u_upload_flush( struct u_upload_mgr *upload )
{
/* Unmap and unreference the upload buffer. */
- if (upload->transfer) {
- if (upload->offset) {
- pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
- 0, upload->offset);
- }
- pipe_transfer_unmap(upload->pipe, upload->transfer);
- pipe_transfer_destroy(upload->pipe, upload->transfer);
- upload->transfer = NULL;
- }
+ u_upload_unmap(upload);
pipe_resource_reference( &upload->buffer, NULL );
upload->size = 0;
}
@@ -172,6 +180,15 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
offset = MAX2(upload->offset, alloc_offset);
+ if (!upload->map) {
+ upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
+ offset, upload->size - offset,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_FLUSH_EXPLICIT |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &upload->transfer);
+ }
+
assert(offset < upload->buffer->width0);
assert(offset + size <= upload->buffer->width0);
assert(size);
@@ -223,10 +240,11 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
struct pipe_transfer *transfer = NULL;
const char *map = NULL;
- map = (const char *)pipe_buffer_map(upload->pipe,
- inbuf,
- PIPE_TRANSFER_READ,
- &transfer);
+ map = (const char *)pipe_buffer_map_range(upload->pipe,
+ inbuf,
+ offset, size,
+ PIPE_TRANSFER_READ,
+ &transfer);
if (map == NULL) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
@@ -239,7 +257,7 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
ret = u_upload_data( upload,
min_out_offset,
size,
- map + offset,
+ map,
out_offset,
outbuf, flushed );
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h
index c9a2ffeb572..98915139801 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -56,15 +56,27 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
*/
void u_upload_destroy( struct u_upload_mgr *upload );
-/* Unmap and release old buffer.
+/* Unmap and release old upload buffer.
*
+ * This is like u_upload_unmap() except the upload buffer is released for
+ * recycling. This should be called on real hardware flushes on systems
+ * that don't support the PIPE_TRANSFER_UNSYNCHRONIZED flag, as otherwise
+ * the next u_upload_buffer will cause a sync on the buffer.
+ */
+
+void u_upload_flush( struct u_upload_mgr *upload );
+
+/**
+ * Unmap upload buffer
+ *
+ * \param upload Upload manager
+ *
* This must usually be called prior to firing the command stream
* which references the upload buffer, as many memory managers either
* don't like firing a mapped buffer or cause subsequent maps of a
- * fired buffer to wait. For now, it's easiest just to grab a new
- * buffer.
+ * fired buffer to wait.
*/
-void u_upload_flush( struct u_upload_mgr *upload );
+void u_upload_unmap( struct u_upload_mgr *upload );
/**
* Sub-allocate new memory from the upload buffer.
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index 04149525ea7..374fc336b83 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -152,9 +152,9 @@ void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgrb)
}
-static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
- int min_index, int max_index,
- boolean *upload_flushed)
+static enum u_vbuf_return_flags
+u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index)
{
struct translate_key key;
struct translate_element *te;
@@ -166,6 +166,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
struct pipe_resource *out_buffer = NULL;
unsigned i, num_verts, out_offset;
struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
+ boolean upload_flushed = FALSE;
memset(&key, 0, sizeof(key));
memset(tr_elem_index, 0xff, sizeof(tr_elem_index));
@@ -248,7 +249,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
u_upload_alloc(mgr->b.uploader,
key.output_stride * min_index,
key.output_stride * num_verts,
- &out_offset, &out_buffer, upload_flushed,
+ &out_offset, &out_buffer, &upload_flushed,
(void**)&out_map);
out_offset -= key.output_stride * min_index;
@@ -308,6 +309,8 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
}
pipe_resource_reference(&out_buffer, NULL);
+
+ return upload_flushed ? U_VBUF_UPLOAD_FLUSHED : 0;
}
static void u_vbuf_translate_end(struct u_vbuf_mgr_priv *mgr)
@@ -510,14 +513,15 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
mgr->b.nr_real_vertex_buffers = count;
}
-static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
- int min_index, int max_index,
- unsigned instance_count,
- boolean *upload_flushed)
+static enum u_vbuf_return_flags
+u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index,
+ unsigned instance_count)
{
unsigned i, nr = mgr->ve->count;
unsigned count = max_index + 1 - min_index;
boolean uploaded[PIPE_MAX_ATTRIBS] = {0};
+ enum u_vbuf_return_flags retval = 0;
for (i = 0; i < nr; i++) {
unsigned index = mgr->ve->ve[i].vertex_buffer_index;
@@ -537,6 +541,11 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
} else if (vb->stride) {
first = vb->stride * min_index;
size = vb->stride * count;
+
+ /* Unusual case when stride is smaller than the format size.
+ * XXX This won't work with interleaved arrays. */
+ if (mgr->ve->native_format_size[i] > vb->stride)
+ size += mgr->ve->native_format_size[i] - vb->stride;
} else {
first = 0;
size = mgr->ve->native_format_size[i];
@@ -551,11 +560,14 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
vb->buffer_offset -= first;
uploaded[index] = TRUE;
- *upload_flushed = *upload_flushed || flushed;
+ if (flushed)
+ retval |= U_VBUF_UPLOAD_FLUSHED;
} else {
assert(mgr->b.real_vertex_buffer[index]);
}
}
+
+ return retval;
}
static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
@@ -597,14 +609,13 @@ static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
}
}
-void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
- const struct pipe_draw_info *info,
- boolean *buffers_updated,
- boolean *uploader_flushed)
+enum u_vbuf_return_flags
+u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
+ const struct pipe_draw_info *info)
{
struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
- boolean bufs_updated = FALSE, upload_flushed = FALSE;
int min_index, max_index;
+ enum u_vbuf_return_flags retval = 0;
u_vbuf_mgr_compute_max_index(mgr);
@@ -617,27 +628,20 @@ void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
/* Translate vertices with non-native layouts or formats. */
if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) {
- u_vbuf_translate_begin(mgr, min_index, max_index, &upload_flushed);
+ retval |= u_vbuf_translate_begin(mgr, min_index, max_index);
if (mgr->fallback_ve) {
- bufs_updated = TRUE;
+ retval |= U_VBUF_BUFFERS_UPDATED;
}
}
/* Upload user buffers. */
if (mgr->any_user_vbs) {
- u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count,
- &upload_flushed);
- bufs_updated = TRUE;
- }
-
- /* Set the return values. */
- if (buffers_updated) {
- *buffers_updated = bufs_updated;
- }
- if (uploader_flushed) {
- *uploader_flushed = upload_flushed;
+ retval |= u_vbuf_upload_buffers(mgr, min_index, max_index,
+ info->instance_count);
+ retval |= U_VBUF_BUFFERS_UPDATED;
}
+ return retval;
}
void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgrb)
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.h b/src/gallium/auxiliary/util/u_vbuf_mgr.h
index 9380dce4f72..4e6372435d8 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.h
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.h
@@ -78,6 +78,11 @@ enum u_fetch_alignment {
U_VERTEX_FETCH_DWORD_ALIGNED
};
+enum u_vbuf_return_flags {
+ U_VBUF_BUFFERS_UPDATED = 1,
+ U_VBUF_UPLOAD_FLUSHED = 2
+};
+
struct u_vbuf_mgr *
u_vbuf_mgr_create(struct pipe_context *pipe,
@@ -105,10 +110,9 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgr,
unsigned count,
const struct pipe_vertex_buffer *bufs);
-void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
- const struct pipe_draw_info *info,
- boolean *buffers_updated,
- boolean *uploader_flushed);
+enum u_vbuf_return_flags
+u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
+ const struct pipe_draw_info *info);
void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgr);
diff --git a/src/gallium/drivers/i915/Makefile b/src/gallium/drivers/i915/Makefile
index b3f387f9335..778124728bb 100644
--- a/src/gallium/drivers/i915/Makefile
+++ b/src/gallium/drivers/i915/Makefile
@@ -21,6 +21,7 @@ C_SOURCES = \
i915_screen.c \
i915_prim_emit.c \
i915_prim_vbuf.c \
+ i915_query.c \
i915_resource.c \
i915_resource_texture.c \
i915_resource_buffer.c \
diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript
index 8f5deed64a9..98370601b7f 100644
--- a/src/gallium/drivers/i915/SConscript
+++ b/src/gallium/drivers/i915/SConscript
@@ -16,6 +16,7 @@ i915 = env.ConvenienceLibrary(
'i915_fpc_translate.c',
'i915_prim_emit.c',
'i915_prim_vbuf.c',
+ 'i915_query.c',
'i915_screen.c',
'i915_state.c',
'i915_state_derived.c',
diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO
index fba180064c3..c26db198d20 100644
--- a/src/gallium/drivers/i915/TODO
+++ b/src/gallium/drivers/i915/TODO
@@ -26,5 +26,20 @@ Random list of problems with i915g:
- src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various
commands defined. Scavenge them and see what's useful.
+- Do smarter remapping. Right now we send everything onto tex coords 0-7.
+ We could also use diffuse/specular and pack two sets of 2D coords in a single
+ 4D. Is it a big problem though? We're more limited by the # of texture
+ indirections and the # of instructions.
+
+- Leverage draw to enable more caps:
+ * PIPE_CAP_TGSI_INSTANCEID
+ * PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS
+
+- Finish front/back face. We need to add face support to lp_build_system_values_array and use it in draw_llvm.c.
+
+- Replace constants and immediates which are 0,1,-1 or a combination of those with a swizzle.
+
+- i915_delete_fs_state doesn't call draw_delete_fragment_shader. Why?
+
Other bugs can be found here:
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g
diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c
index 4a97746e981..fcb208d6dae 100644
--- a/src/gallium/drivers/i915/i915_clear.c
+++ b/src/gallium/drivers/i915/i915_clear.c
@@ -66,7 +66,7 @@ i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba,
else
clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16);
- util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color);
+ util_pack_color(rgba, cbuf->format, &u_color);
clear_color8888 = u_color.ui;
} else
clear_color = clear_color8888 = 0;
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 7a98ef73c1f..28ff40a2328 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -29,6 +29,7 @@
#include "i915_state.h"
#include "i915_screen.h"
#include "i915_surface.h"
+#include "i915_query.h"
#include "i915_batch.h"
#include "i915_resource.h"
@@ -53,13 +54,11 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
void *mapped_indices = NULL;
- unsigned cbuf_dirty;
/*
* Ack vs contants here, helps ipers a lot.
*/
- cbuf_dirty = i915->dirty & I915_NEW_VS_CONSTANTS;
i915->dirty &= ~I915_NEW_VS_CONSTANTS;
if (i915->dirty)
@@ -72,15 +71,13 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
draw_set_mapped_index_buffer(draw, mapped_indices);
- if (cbuf_dirty) {
- if (i915->constants[PIPE_SHADER_VERTEX])
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
- i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
- (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
- 4 * sizeof(float)));
- else
- draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
- }
+ if (i915->constants[PIPE_SHADER_VERTEX])
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
+ i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
+ (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
+ 4 * sizeof(float)));
+ else
+ draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0);
/*
* Do the drawing
@@ -106,7 +103,7 @@ static void i915_destroy(struct pipe_context *pipe)
if (i915->blitter)
util_blitter_destroy(i915->blitter);
-
+
if(i915->batch)
i915->iws->batchbuffer_destroy(i915->batch);
@@ -150,6 +147,8 @@ i915_create_context(struct pipe_screen *screen, void *priv)
/* init this before draw */
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
16, UTIL_SLAB_SINGLETHREADED);
+ util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
+ 16, UTIL_SLAB_SINGLETHREADED);
/* Batch stream debugging is a bit hacked up at the moment:
*/
@@ -170,9 +169,11 @@ i915_create_context(struct pipe_screen *screen, void *priv)
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
i915_init_resource_functions(i915);
+ i915_init_query_functions(i915);
draw_install_aaline_stage(i915->draw, &i915->base);
draw_install_aapoint_stage(i915->draw, &i915->base);
+ draw_enable_point_sprites(i915->draw, TRUE);
/* augmented draw pipeline clobbers state functions */
i915_init_fixup_state_functions(i915);
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 964948edc0e..c964208fedd 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -102,6 +102,8 @@ struct i915_fragment_shader
struct tgsi_shader_info info;
+ struct draw_fragment_shader *draw_data;
+
uint *program;
uint program_len;
@@ -260,6 +262,7 @@ struct i915_context {
int num_validation_buffers;
struct util_slab_mempool transfer_pool;
+ struct util_slab_mempool texture_transfer_pool;
/** blitter/hw-clear */
struct blitter_context* blitter;
diff --git a/src/gallium/drivers/i915/i915_fpc.h b/src/gallium/drivers/i915/i915_fpc.h
index 2f0f99d0468..509395cf1f5 100644
--- a/src/gallium/drivers/i915/i915_fpc.h
+++ b/src/gallium/drivers/i915/i915_fpc.h
@@ -37,6 +37,9 @@
#define I915_PROGRAM_SIZE 192
+/* Use those indices for pos/face routing, must be >= I915_TEX_UNITS */
+#define I915_SEMANTIC_POS 10
+#define I915_SEMANTIC_FACE 11
/**
@@ -67,13 +70,13 @@ struct i915_fp_compile {
uint temp_flag; /**< Tracks temporary regs which are in use */
uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */
+ uint register_phases[16];
uint nr_tex_indirect;
uint nr_tex_insn;
uint nr_alu_insn;
uint nr_decl_insn;
boolean error; /**< Set if i915_program_error() is called */
- uint wpos_tex;
uint NumNativeInstructions;
uint NumNativeAluInstructions;
uint NumNativeTexInstructions;
diff --git a/src/gallium/drivers/i915/i915_fpc_emit.c b/src/gallium/drivers/i915/i915_fpc_emit.c
index 76c24d2b2fd..d28595e0fd3 100644
--- a/src/gallium/drivers/i915/i915_fpc_emit.c
+++ b/src/gallium/drivers/i915/i915_fpc_emit.c
@@ -67,7 +67,7 @@ i915_get_temp(struct i915_fp_compile *p)
{
int bit = ffs(~p->temp_flag);
if (!bit) {
- i915_program_error(p, "i915_get_temp: out of temporaries\n");
+ i915_program_error(p, "i915_get_temp: out of temporaries");
return 0;
}
@@ -92,7 +92,7 @@ i915_get_utemp(struct i915_fp_compile * p)
{
int bit = ffs(~p->utemp_flag);
if (!bit) {
- i915_program_error(p, "i915_get_utemp: out of temporaries\n");
+ i915_program_error(p, "i915_get_utemp: out of temporaries");
return 0;
}
@@ -128,9 +128,13 @@ i915_emit_decl(struct i915_fp_compile *p,
else
return reg;
- *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
- *(p->decl++) = D1_MBZ;
- *(p->decl++) = D2_MBZ;
+ if (p->decl< p->declarations + I915_PROGRAM_SIZE) {
+ *(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags);
+ *(p->decl++) = D1_MBZ;
+ *(p->decl++) = D2_MBZ;
+ }
+ else
+ i915_program_error(p, "Out of declarations");
p->nr_decl_insn++;
return reg;
@@ -187,9 +191,16 @@ i915_emit_arith(struct i915_fp_compile * p,
p->utemp_flag = old_utemp_flag; /* restore */
}
- *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
- *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
- *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+ if (p->csr< p->program + I915_PROGRAM_SIZE) {
+ *(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
+ *(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1));
+ *(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2));
+ }
+ else
+ i915_program_error(p, "Out of instructions");
+
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
p->nr_alu_insn++;
return dest;
@@ -245,17 +256,31 @@ uint i915_emit_texld( struct i915_fp_compile *p,
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST);
assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)));
- /* is the sampler coord a texcoord input reg? */
- if (GET_UREG_TYPE(coord) != REG_TYPE_T) {
- p->nr_tex_indirect++;
- }
+ /* Output register being oC or oD defines a phase boundary */
+ if (GET_UREG_TYPE(dest) == REG_TYPE_OC ||
+ GET_UREG_TYPE(dest) == REG_TYPE_OD)
+ p->nr_tex_indirect++;
- *(p->csr++) = (opcode |
- T0_DEST( dest ) |
- T0_SAMPLER( sampler ));
+ /* Reading from an r# register whose contents depend on output of the
+ * current phase defines a phase boundary.
+ */
+ if (GET_UREG_TYPE(coord) == REG_TYPE_R &&
+ p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect)
+ p->nr_tex_indirect++;
+
+ if (p->csr< p->program + I915_PROGRAM_SIZE) {
+ *(p->csr++) = (opcode |
+ T0_DEST( dest ) |
+ T0_SAMPLER( sampler ));
+
+ *(p->csr++) = T1_ADDRESS_REG( coord );
+ *(p->csr++) = T2_MBZ;
+ }
+ else
+ i915_program_error(p, "Out of instructions");
- *(p->csr++) = T1_ADDRESS_REG( coord );
- *(p->csr++) = T2_MBZ;
+ if (GET_UREG_TYPE(dest) == REG_TYPE_R)
+ p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect;
p->nr_tex_insn++;
}
@@ -293,7 +318,7 @@ i915_emit_const1f(struct i915_fp_compile * p, float c0)
}
}
- i915_program_error(p, "i915_emit_const1f: out of constants\n");
+ i915_program_error(p, "i915_emit_const1f: out of constants");
return 0;
}
@@ -313,6 +338,8 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
if (c1 == 1.0)
return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W);
+ // XXX emit swizzle here for 0, 1, -1 and any combination thereof
+ // we can use swizzle + neg for that
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (ifs->constant_flags[reg] == 0xf ||
ifs->constant_flags[reg] == I915_CONSTFLAG_USER)
@@ -329,12 +356,10 @@ i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1)
}
}
- i915_program_error(p, "i915_emit_const2f: out of constants\n");
+ i915_program_error(p, "i915_emit_const2f: out of constants");
return 0;
}
-
-
uint
i915_emit_const4f(struct i915_fp_compile * p,
float c0, float c1, float c2, float c3)
@@ -342,6 +367,9 @@ i915_emit_const4f(struct i915_fp_compile * p,
struct i915_fragment_shader *ifs = p->shader;
unsigned reg;
+ // XXX emit swizzle here for 0, 1, -1 and any combination thereof
+ // we can use swizzle + neg for that
+ printf("const %f %f %f %f\n",c0,c1,c2,c3);
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) {
if (ifs->constant_flags[reg] == 0xf &&
ifs->constants[reg][0] == c0 &&
@@ -363,7 +391,7 @@ i915_emit_const4f(struct i915_fp_compile * p,
}
}
- i915_program_error(p, "i915_emit_const4f: out of constants\n");
+ i915_program_error(p, "i915_emit_const4f: out of constants");
return 0;
}
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index 27f100843bf..0cbd4f2d748 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -41,6 +41,9 @@
#include "draw/draw_vertex.h"
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
/**
* Simple pass-through fragment shader to use when we don't have
@@ -72,19 +75,33 @@ static unsigned passthrough[] =
/* 1, -1/3!, 1/5!, -1/7! */
-static const float sin_constants[4] = { 1.0,
+static const float scs_sin_constants[4] = { 1.0,
-1.0f / (3 * 2 * 1),
1.0f / (5 * 4 * 3 * 2 * 1),
-1.0f / (7 * 6 * 5 * 4 * 3 * 2 * 1)
};
/* 1, -1/2!, 1/4!, -1/6! */
-static const float cos_constants[4] = { 1.0,
+static const float scs_cos_constants[4] = { 1.0,
-1.0f / (2 * 1),
1.0f / (4 * 3 * 2 * 1),
-1.0f / (6 * 5 * 4 * 3 * 2 * 1)
};
+/* 2*pi, -(2*pi)^3/3!, (2*pi)^5/5!, -(2*pi)^7/7! */
+static const float sin_constants[4] = { 2.0 * M_PI,
+ -8.0f * M_PI * M_PI * M_PI / (3 * 2 * 1),
+ 32.0f * M_PI * M_PI * M_PI * M_PI * M_PI / (5 * 4 * 3 * 2 * 1),
+ -128.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (7 * 6 * 5 * 4 * 3 * 2 * 1)
+};
+
+/* 1, -(2*pi)^2/2!, (2*pi)^4/4!, -(2*pi)^6/6! */
+static const float cos_constants[4] = { 1.0,
+ -4.0f * M_PI * M_PI / (2 * 1),
+ 16.0f * M_PI * M_PI * M_PI * M_PI / (4 * 3 * 2 * 1),
+ -64.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (6 * 5 * 4 * 3 * 2 * 1)
+};
+
/**
@@ -185,12 +202,12 @@ src_vector(struct i915_fp_compile *p,
switch (sem_name) {
case TGSI_SEMANTIC_POSITION:
- debug_printf("SKIP SEM POS\n");
- /*
- assert(p->wpos_tex != -1);
- src = i915_emit_decl(p, REG_TYPE_T, p->wpos_tex, D0_CHANNEL_ALL);
- */
- break;
+ {
+ /* for fragcoord */
+ int real_tex_unit = get_mapping(fs, I915_SEMANTIC_POS);
+ src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
+ break;
+ }
case TGSI_SEMANTIC_COLOR:
if (sem_ind == 0) {
src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL);
@@ -212,6 +229,13 @@ src_vector(struct i915_fp_compile *p,
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
break;
}
+ case TGSI_SEMANTIC_FACE:
+ {
+ /* for back/front faces */
+ int real_tex_unit = get_mapping(fs, I915_SEMANTIC_FACE);
+ src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_X);
+ break;
+ }
default:
i915_program_error(p, "Bad source->Index");
return 0;
@@ -237,7 +261,6 @@ src_vector(struct i915_fp_compile *p,
source->Register.SwizzleZ,
source->Register.SwizzleW);
-
/* There's both negate-all-components and per-component negation.
* Try to handle both here.
*/
@@ -252,6 +275,9 @@ src_vector(struct i915_fp_compile *p,
/* XXX enable these assertions, or fix things */
assert(!source->Register.Absolute);
#endif
+ if (source->Register.Absolute)
+ debug_printf("Unhandled absolute value\n");
+
return src;
}
@@ -419,11 +445,6 @@ emit_simple_arith_swap2(struct i915_fp_compile *p,
emit_simple_arith(p, &inst2, opcode, numArgs, fs);
}
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
/*
* Translate TGSI instruction to i915 instruction.
*
@@ -477,13 +498,6 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
- /* By choosing different taylor constants, could get rid of this mul:
- */
- i915_emit_arith(p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0);
-
/*
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1
@@ -516,6 +530,18 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_const4fv(p, cos_constants), 0);
break;
+ case TGSI_OPCODE_DDX:
+ case TGSI_OPCODE_DDY:
+ /* XXX We just output 0 here */
+ debug_printf("Punting DDX/DDX\n");
+ src0 = get_result_vector(p, &inst->Dst[0]);
+ i915_emit_arith(p,
+ A0_MOV,
+ get_result_vector(p, &inst->Dst[0]),
+ get_result_flags(inst), 0,
+ swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0);
+ break;
+
case TGSI_OPCODE_DP2:
src0 = src_vector(p, &inst->Src[0], fs);
src1 = src_vector(p, &inst->Src[1], fs);
@@ -754,9 +780,9 @@ i915_translate_instruction(struct i915_fp_compile *p,
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
* t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x
- * scs.x = DP4 t1, sin_constants
+ * scs.x = DP4 t1, scs_sin_constants
* t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1
- * scs.y = DP4 t1, cos_constants
+ * scs.y = DP4 t1, scs_cos_constants
*/
i915_emit_arith(p,
A0_MUL,
@@ -791,7 +817,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
get_result_vector(p, &inst->Dst[0]),
A0_DEST_CHANNEL_Y, 0,
swizzle(tmp1, W, Z, Y, X),
- i915_emit_const4fv(p, sin_constants), 0);
+ i915_emit_const4fv(p, scs_sin_constants), 0);
}
if (writemask & TGSI_WRITEMASK_X) {
@@ -806,7 +832,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
get_result_vector(p, &inst->Dst[0]),
A0_DEST_CHANNEL_X, 0,
swizzle(tmp, ONE, Z, Y, X),
- i915_emit_const4fv(p, cos_constants), 0);
+ i915_emit_const4fv(p, scs_cos_constants), 0);
}
break;
@@ -853,13 +879,6 @@ i915_translate_instruction(struct i915_fp_compile *p,
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0);
- /* By choosing different taylor constants, could get rid of this mul:
- */
- i915_emit_arith(p,
- A0_MUL,
- tmp, A0_DEST_CHANNEL_X, 0,
- tmp, i915_emit_const1f(p, (float) (M_PI * 2.0)), 0);
-
/*
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x
@@ -907,7 +926,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
break;
case TGSI_OPCODE_SNE:
- /* if we're neither < nor > then we're != */
+ /* if we're < or > then we're != */
src0 = src_vector(p, &inst->Src[0], fs);
src1 = src_vector(p, &inst->Src[1], fs);
tmp = i915_get_utemp(p);
@@ -1070,9 +1089,11 @@ i915_translate_instructions(struct i915_fp_compile *p,
for (i = parse.FullToken.FullDeclaration.Range.First;
i <= parse.FullToken.FullDeclaration.Range.Last;
i++) {
- assert(i < I915_MAX_TEMPORARY);
- /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
- p->temp_flag |= (1 << i); /* mark temp as used */
+ if (i >= I915_MAX_TEMPORARY)
+ debug_printf("Too many temps (%d)\n",i);
+ else
+ /* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
+ p->temp_flag |= (1 << i); /* mark temp as used */
}
}
break;
@@ -1144,6 +1165,8 @@ i915_init_compile(struct i915_context *i915,
ifs->num_constants = 0;
memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags));
+ memset(&p->register_phases, 0, sizeof(p->register_phases));
+
for (i = 0; i < I915_TEX_UNITS; i++)
ifs->generic_mapping[i] = -1;
@@ -1161,8 +1184,6 @@ i915_init_compile(struct i915_context *i915,
p->temp_flag = ~0x0 << I915_MAX_TEMPORARY;
p->utemp_flag = ~0x7;
- p->wpos_tex = -1;
-
/* initialize the first program word */
*(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM;
@@ -1181,7 +1202,7 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
unsigned long decl_size = (unsigned long) (p->decl - p->declarations);
if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT)
- i915_program_error(p, "Exceeded max nr indirect texture lookups");
+ debug_printf("Exceeded max nr indirect texture lookups\n");
if (p->nr_tex_insn > I915_MAX_TEX_INSN)
i915_program_error(p, "Exceeded max TEX instructions");
@@ -1234,40 +1255,6 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
}
-/**
- * Find an unused texture coordinate slot to use for fragment WPOS.
- * Update p->fp->wpos_tex with the result (-1 if no used texcoord slot is found).
- */
-static void
-i915_find_wpos_space(struct i915_fp_compile *p)
-{
-#if 0
- const uint inputs
- = p->shader->inputs_read | (1 << TGSI_ATTRIB_POS); /*XXX hack*/
- uint i;
-
- p->wpos_tex = -1;
-
- if (inputs & (1 << TGSI_ATTRIB_POS)) {
- for (i = 0; i < I915_TEX_UNITS; i++) {
- if ((inputs & (1 << (TGSI_ATTRIB_TEX0 + i))) == 0) {
- p->wpos_tex = i;
- return;
- }
- }
-
- i915_program_error(p, "No free texcoord for wpos value");
- }
-#else
- if (p->shader->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
- /* frag shader using the fragment position input */
-#if 0
- assert(0);
-#endif
- }
-#endif
-}
-
@@ -1314,7 +1301,6 @@ i915_translate_fragment_program( struct i915_context *i915,
}
p = i915_init_compile(i915, fs);
- i915_find_wpos_space(p);
i915_translate_instructions(p, tokens, fs);
i915_fixup_depth_write(p);
diff --git a/src/gallium/drivers/i915/i915_query.c b/src/gallium/drivers/i915/i915_query.c
new file mode 100644
index 00000000000..c886df74bad
--- /dev/null
+++ b/src/gallium/drivers/i915/i915_query.c
@@ -0,0 +1,86 @@
+/**************************************************************************
+ *
+ * Copyright 2011 The Chromium OS authors.
+ * 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 GOOGLE 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.
+ *
+ **************************************************************************/
+
+/* Fake occlusion queries which return 0, it's better than crashing */
+
+#include "pipe/p_compiler.h"
+
+#include "util/u_memory.h"
+
+#include "i915_context.h"
+#include "i915_query.h"
+
+struct i915_query
+{
+ unsigned query;
+};
+
+static struct pipe_query *i915_create_query(struct pipe_context *ctx,
+ unsigned query_type)
+{
+ struct i915_query *query = CALLOC_STRUCT( i915_query );
+
+ return (struct pipe_query *)query;
+}
+
+static void i915_destroy_query(struct pipe_context *ctx,
+ struct pipe_query *query)
+{
+ FREE(query);
+}
+
+static void i915_begin_query(struct pipe_context *ctx,
+ struct pipe_query *query)
+{
+}
+
+static void i915_end_query(struct pipe_context *ctx, struct pipe_query *query)
+{
+}
+
+static boolean i915_get_query_result(struct pipe_context *ctx,
+ struct pipe_query *query,
+ boolean wait,
+ void *vresult)
+{
+ uint64_t *result = (uint64_t*)vresult;
+
+ /* 2* viewport Max */
+ *result = 512*1024*1024;
+ return TRUE;
+}
+
+void
+i915_init_query_functions(struct i915_context *i915)
+{
+ i915->base.create_query = i915_create_query;
+ i915->base.destroy_query = i915_destroy_query;
+ i915->base.begin_query = i915_begin_query;
+ i915->base.end_query = i915_end_query;
+ i915->base.get_query_result = i915_get_query_result;
+}
+
diff --git a/src/gallium/drivers/i915/i915_query.h b/src/gallium/drivers/i915/i915_query.h
new file mode 100644
index 00000000000..2c689ea6b1c
--- /dev/null
+++ b/src/gallium/drivers/i915/i915_query.h
@@ -0,0 +1,36 @@
+/**************************************************************************
+ *
+ * Copyright 2011 The Chromium OS authors.
+ * 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 GOOGLE 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 I915_QUERY_H
+#define I915_QUERY_H
+
+struct i915_context;
+struct pipe_context;
+
+void i915_init_query_functions( struct i915_context *i915 );
+
+#endif /* I915_QUERY_H */
diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c
index 7f52ba11d61..b4719af1fb6 100644
--- a/src/gallium/drivers/i915/i915_resource.c
+++ b/src/gallium/drivers/i915/i915_resource.c
@@ -7,12 +7,12 @@
static struct pipe_resource *
i915_resource_create(struct pipe_screen *screen,
- const struct pipe_resource *template)
+ const struct pipe_resource *template)
{
if (template->target == PIPE_BUFFER)
return i915_buffer_create(screen, template);
else
- return i915_texture_create(screen, template);
+ return i915_texture_create(screen, template, FALSE);
}
diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h
index c15ecdfc22a..14eed2c4a79 100644
--- a/src/gallium/drivers/i915/i915_resource.h
+++ b/src/gallium/drivers/i915/i915_resource.h
@@ -45,6 +45,15 @@ struct i915_buffer {
boolean free_on_destroy;
};
+
+/* Texture transfer. */
+struct i915_transfer {
+ /* Base class. */
+ struct pipe_transfer b;
+ struct pipe_resource *staging_texture;
+};
+
+
#define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */
#define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */
@@ -101,7 +110,8 @@ static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource)
struct pipe_resource *
i915_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *template);
+ const struct pipe_resource *template,
+ boolean force_untiled);
struct pipe_resource *
i915_texture_from_handle(struct pipe_screen * screen,
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index b74b19d0fe4..0b6424f8d16 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -37,6 +37,7 @@
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_rect.h"
#include "i915_context.h"
#include "i915_resource.h"
@@ -710,7 +711,7 @@ i915_texture_destroy(struct pipe_screen *screen,
FREE(tex);
}
-static struct pipe_transfer *
+static struct pipe_transfer *
i915_texture_get_transfer(struct pipe_context *pipe,
struct pipe_resource *resource,
unsigned level,
@@ -719,19 +720,45 @@ i915_texture_get_transfer(struct pipe_context *pipe,
{
struct i915_context *i915 = i915_context(pipe);
struct i915_texture *tex = i915_texture(resource);
- struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
+ struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool);
+ boolean use_staging_texture = FALSE;
if (transfer == NULL)
return NULL;
- transfer->resource = resource;
- transfer->level = level;
- transfer->usage = usage;
- transfer->box = *box;
- transfer->stride = tex->stride;
- /* FIXME: layer_stride */
+ transfer->b.resource = resource;
+ transfer->b.level = level;
+ transfer->b.usage = usage;
+ transfer->b.box = *box;
+ transfer->b.stride = tex->stride;
+ transfer->staging_texture = NULL;
+ /* XXX: handle depth textures everyhwere*/
+ transfer->b.layer_stride = 0;
+ transfer->b.data = NULL;
+
+ /* if we use staging transfers, only support textures we can render to,
+ * because we need that for u_blitter */
+ if (i915->blitter &&
+ i915_is_format_supported(NULL, /* screen */
+ transfer->b.resource->format,
+ 0, /* target */
+ 1, /* sample count */
+ PIPE_BIND_RENDER_TARGET) &&
+ (usage & PIPE_TRANSFER_WRITE) &&
+ !(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
+ use_staging_texture = TRUE;
+
+ use_staging_texture = FALSE;
+
+ if (use_staging_texture) {
+ /*
+ * Allocate the untiled staging texture.
+ * If the alloc fails, transfer->staging_texture is NULL and we fallback to a map()
+ */
+ transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE);
+ }
- return transfer;
+ return (struct pipe_transfer*)transfer;
}
static void
@@ -739,17 +766,33 @@ i915_transfer_destroy(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
struct i915_context *i915 = i915_context(pipe);
- util_slab_free(&i915->transfer_pool, transfer);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+
+ if ((itransfer->staging_texture) &&
+ (transfer->usage & PIPE_TRANSFER_WRITE)) {
+ struct pipe_box sbox;
+
+ u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox);
+ pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level,
+ itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z,
+ itransfer->staging_texture,
+ 0, &sbox);
+ pipe->flush(pipe, NULL);
+ pipe_resource_reference(&itransfer->staging_texture, NULL);
+ }
+
+ util_slab_free(&i915->texture_transfer_pool, itransfer);
}
static void *
i915_texture_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct pipe_resource *resource = transfer->resource;
- struct i915_texture *tex = i915_texture(resource);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+ struct pipe_resource *resource = itransfer->b.resource;
+ struct i915_texture *tex = NULL;
struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
- struct pipe_box *box = &transfer->box;
+ struct pipe_box *box = &itransfer->b.box;
enum pipe_format format = resource->format;
unsigned offset;
char *map;
@@ -757,18 +800,25 @@ i915_texture_transfer_map(struct pipe_context *pipe,
if (resource->target != PIPE_TEXTURE_3D &&
resource->target != PIPE_TEXTURE_CUBE)
assert(box->z == 0);
- offset = i915_texture_offset(tex, transfer->level, box->z);
- /* TODO this is a sledgehammer */
- pipe->flush(pipe, NULL);
+ if (itransfer->staging_texture) {
+ tex = i915_texture(itransfer->staging_texture);
+ } else {
+ /* TODO this is a sledgehammer */
+ tex = i915_texture(resource);
+ pipe->flush(pipe, NULL);
+ }
+
+ offset = i915_texture_offset(tex, itransfer->b.level, box->z);
map = iws->buffer_map(iws, tex->buffer,
- (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
- if (map == NULL)
+ (itransfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
+ if (map == NULL) {
return NULL;
+ }
return map + offset +
- box->y / util_format_get_blockheight(format) * transfer->stride +
+ box->y / util_format_get_blockheight(format) * itransfer->b.stride +
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
@@ -776,14 +826,106 @@ static void
i915_texture_transfer_unmap(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct i915_texture *tex = i915_texture(transfer->resource);
+ struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
+ struct i915_texture *tex = i915_texture(itransfer->b.resource);
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
+
+ if (itransfer->staging_texture)
+ tex = i915_texture(itransfer->staging_texture);
+
iws->buffer_unmap(iws, tex->buffer);
}
+static void i915_transfer_inline_write( struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride)
+{
+ struct pipe_transfer *transfer = NULL;
+ struct i915_transfer *itransfer = NULL;
+ const uint8_t *src_data = data;
+ unsigned i;
+
+ transfer = pipe->get_transfer(pipe,
+ resource,
+ level,
+ usage,
+ box );
+ if (transfer == NULL)
+ goto out;
+
+ itransfer = (struct i915_transfer*)transfer;
+
+ if (itransfer->staging_texture) {
+ struct i915_texture *tex = i915_texture(itransfer->staging_texture);
+ enum pipe_format format = tex->b.b.format;
+ struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
+ size_t offset;
+ size_t size;
+
+ offset = i915_texture_offset(tex, transfer->level, transfer->box.z);
+
+ for (i = 0; i < box->depth; i++) {
+ if (!tex->b.b.last_level &&
+ tex->b.b.width0 == transfer->box.width) {
+ unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+ assert(!offset);
+ assert(!transfer->box.x);
+ assert(tex->stride == transfer->stride);
+
+ offset += tex->stride * nby;
+ size = util_format_get_2d_size(format, transfer->stride,
+ transfer->box.height);
+ iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+
+ } else {
+ unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+ int i;
+ offset += util_format_get_stride(format, transfer->box.x);
+ size = transfer->stride;
+
+ for (i = 0; i < nby; i++) {
+ iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+ offset += tex->stride;
+ }
+ }
+ offset += layer_stride;
+ }
+ } else {
+ uint8_t *map = pipe_transfer_map(pipe, &itransfer->b);
+ if (map == NULL)
+ goto nomap;
+
+ for (i = 0; i < box->depth; i++) {
+ util_copy_rect(map,
+ resource->format,
+ itransfer->b.stride, /* bytes */
+ 0, 0,
+ box->width,
+ box->height,
+ src_data,
+ stride, /* bytes */
+ 0, 0);
+ map += itransfer->b.layer_stride;
+ src_data += layer_stride;
+ }
+nomap:
+ if (map)
+ pipe_transfer_unmap(pipe, &itransfer->b);
+ }
+
+out:
+ if (itransfer)
+ pipe_transfer_destroy(pipe, &itransfer->b);
+}
-struct u_resource_vtbl i915_texture_vtbl =
+
+struct u_resource_vtbl i915_texture_vtbl =
{
i915_texture_get_handle, /* get_handle */
i915_texture_destroy, /* resource_destroy */
@@ -792,7 +934,7 @@ struct u_resource_vtbl i915_texture_vtbl =
i915_texture_transfer_map, /* transfer_map */
u_default_transfer_flush_region, /* transfer_flush_region */
i915_texture_transfer_unmap, /* transfer_unmap */
- u_default_transfer_inline_write /* transfer_inline_write */
+ i915_transfer_inline_write /* transfer_inline_write */
};
@@ -800,7 +942,8 @@ struct u_resource_vtbl i915_texture_vtbl =
struct pipe_resource *
i915_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *template)
+ const struct pipe_resource *template,
+ boolean force_untiled)
{
struct i915_screen *is = i915_screen(screen);
struct i915_winsys *iws = is->iws;
@@ -815,7 +958,10 @@ i915_texture_create(struct pipe_screen *screen,
pipe_reference_init(&tex->b.b.reference, 1);
tex->b.b.screen = screen;
- tex->tiling = i915_texture_tiling(is, tex);
+ if (force_untiled)
+ tex->tiling = I915_TILE_NONE;
+ else
+ tex->tiling = i915_texture_tiling(is, tex);
if (is->is_i945) {
if (!i945_texture_layout(tex))
@@ -836,7 +982,7 @@ i915_texture_create(struct pipe_screen *screen,
buf_usage = I915_NEW_TEXTURE;
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
- &tex->tiling, buf_usage);
+ &tex->tiling, buf_usage);
if (!tex->buffer)
goto fail;
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index c86baa58b28..e743f6031eb 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -109,17 +109,17 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_ANISOTROPIC_FILTER:
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
case PIPE_CAP_NPOT_TEXTURES:
+ case PIPE_CAP_POINT_SPRITE:
case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
case PIPE_CAP_TEXTURE_SHADOW_MAP:
case PIPE_CAP_TWO_SIDED_STENCIL:
+ case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
return 1;
/* Features that should be supported (boolean caps). */
/* XXX: Just test the code */
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
- /* XXX: No code but hw supports it */
- case PIPE_CAP_POINT_SPRITE:
/* Also lie about these when asked to (needed for GLSL / GL 2.0) */
return is->debug.lie ? 1 : 0;
@@ -129,7 +129,6 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_INDEP_BLEND_FUNC:
case PIPE_CAP_TGSI_INSTANCEID:
- case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_TEXTURE_SWIZZLE:
@@ -254,7 +253,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
}
}
-static boolean
+boolean
i915_is_format_supported(struct pipe_screen *screen,
enum pipe_format format,
enum pipe_texture_target target,
@@ -264,7 +263,10 @@ i915_is_format_supported(struct pipe_screen *screen,
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+ PIPE_FORMAT_R8G8B8X8_UNORM,
PIPE_FORMAT_B5G6R5_UNORM,
+ PIPE_FORMAT_B10G10R10A2_UNORM,
PIPE_FORMAT_L8_UNORM,
PIPE_FORMAT_A8_UNORM,
PIPE_FORMAT_I8_UNORM,
@@ -283,7 +285,12 @@ i915_is_format_supported(struct pipe_screen *screen,
};
static const enum pipe_format render_supported[] = {
PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
PIPE_FORMAT_B5G6R5_UNORM,
+ PIPE_FORMAT_B10G10R10A2_UNORM,
+ PIPE_FORMAT_L8_UNORM,
+ PIPE_FORMAT_A8_UNORM,
+ PIPE_FORMAT_I8_UNORM,
PIPE_FORMAT_NONE /* list terminator */
};
static const enum pipe_format depth_supported[] = {
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index cfc585b5350..9f2004eb942 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -65,5 +65,11 @@ i915_screen(struct pipe_screen *pscreen)
return (struct i915_screen *) pscreen;
}
+boolean
+i915_is_format_supported(struct pipe_screen *screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned tex_usage);
#endif /* I915_SCREEN_H */
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 1b57c5776f2..f412626955d 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -146,6 +146,7 @@ i915_create_blend_state(struct pipe_context *pipe,
if (blend->dither)
cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE;
+ /* XXX here take the target fixup into account */
if ((blend->rt[0].colormask & PIPE_MASK_R) == 0)
cso_data->LIS5 |= S5_WRITEDISABLE_RED;
@@ -246,7 +247,7 @@ i915_create_sampler_state(struct pipe_context *pipe,
if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
{
cso->state[0] |= (SS2_SHADOW_ENABLE |
- i915_translate_compare_func(sampler->compare_func));
+ i915_translate_shadow_compare_func(sampler->compare_func));
minFilt = FILTER_4X4_FLAT;
magFilt = FILTER_4X4_FLAT;
@@ -466,6 +467,7 @@ i915_create_fs_state(struct pipe_context *pipe,
if (!ifs)
return NULL;
+ ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
tgsi_scan_shader(templ->tokens, &ifs->info);
@@ -495,6 +497,8 @@ i915_bind_fs_state(struct pipe_context *pipe, void *shader)
i915->fs = (struct i915_fragment_shader*) shader;
+ draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL));
+
i915->dirty |= I915_NEW_FS;
}
@@ -503,12 +507,14 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
{
struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
- if (ifs->program)
+ if (ifs->program) {
FREE(ifs->program);
+ ifs->program = NULL;
+ FREE((struct tgsi_token *)ifs->state.tokens);
+ ifs->state.tokens = NULL;
+ }
ifs->program_len = 0;
- FREE((struct tgsi_token *)ifs->state.tokens);
-
FREE(ifs);
}
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index 392ba191140..e01f16e715c 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -33,6 +33,7 @@
#include "i915_context.h"
#include "i915_state.h"
#include "i915_debug.h"
+#include "i915_fpc.h"
#include "i915_reg.h"
static uint find_mapping(const struct i915_fragment_shader* fs, int unit)
@@ -58,12 +59,12 @@ static void calculate_vertex_layout(struct i915_context *i915)
const struct i915_fragment_shader *fs = i915->fs;
const enum interp_mode colorInterp = i915->rasterizer->color_interp;
struct vertex_info vinfo;
- boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW;
+ boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face;
uint i;
int src;
memset(texCoords, 0, sizeof(texCoords));
- colors[0] = colors[1] = fog = needW = FALSE;
+ colors[0] = colors[1] = fog = needW = face = FALSE;
memset(&vinfo, 0, sizeof(vinfo));
/* Determine which fragment program inputs are needed. Setup HW vertex
@@ -72,6 +73,10 @@ static void calculate_vertex_layout(struct i915_context *i915)
for (i = 0; i < fs->info.num_inputs; i++) {
switch (fs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
+ {
+ uint unit = I915_SEMANTIC_POS;
+ texCoords[find_mapping(fs, unit)] = TRUE;
+ }
break;
case TGSI_SEMANTIC_COLOR:
assert(fs->info.input_semantic_index[i] < 2);
@@ -80,7 +85,6 @@ static void calculate_vertex_layout(struct i915_context *i915)
case TGSI_SEMANTIC_GENERIC:
{
/* texcoords/varyings/other generic */
- /* XXX handle back/front face and point size */
uint unit = fs->info.input_semantic_index[i];
texCoords[find_mapping(fs, unit)] = TRUE;
@@ -90,7 +94,11 @@ static void calculate_vertex_layout(struct i915_context *i915)
case TGSI_SEMANTIC_FOG:
fog = TRUE;
break;
+ case TGSI_SEMANTIC_FACE:
+ face = TRUE;
+ break;
default:
+ debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]);
assert(0);
}
}
@@ -147,6 +155,20 @@ static void calculate_vertex_layout(struct i915_context *i915)
vinfo.hwfmt[1] |= hwtc << (i * 4);
}
+ /* front/back face */
+ if (face) {
+ uint slot = find_mapping(fs, I915_SEMANTIC_FACE);
+ debug_printf("Front/back face is broken\n");
+ /* XXX Because of limitations in the draw module, currently src will be 0
+ * for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw
+ * module by adding an extra shader output.
+ */
+ src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0);
+ draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src);
+ vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4));
+ vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4);
+ }
+
draw_compute_vertex_size(&vinfo);
if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) {
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 0155cd83510..39fb13aec7e 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -34,7 +34,9 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_format.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -128,7 +130,7 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space)
static void
emit_immediate(struct i915_context *i915)
{
- /* remove unwatned bits and S7 */
+ /* remove unwanted bits and S7 */
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 |
@@ -341,6 +343,59 @@ emit_constants(struct i915_context *i915)
}
}
+static const struct
+{
+ enum pipe_format format;
+ uint hw_shift_R;
+ uint hw_shift_G;
+ uint hw_shift_B;
+ uint hw_shift_A;
+} fixup_formats[] = {
+ { PIPE_FORMAT_R8G8B8A8_UNORM, 20, 24, 28, 16 /* BGRA */},
+ { PIPE_FORMAT_L8_UNORM, 28, 28, 28, 16 /* RRRA */},
+ { PIPE_FORMAT_I8_UNORM, 28, 28, 28, 16 /* RRRA */},
+ { PIPE_FORMAT_A8_UNORM, 16, 16, 16, 16 /* AAAA */},
+ { PIPE_FORMAT_NONE, 0, 0, 0, 0},
+};
+
+static boolean need_fixup(struct pipe_surface* p)
+{
+ enum pipe_format f;
+
+ /* if we don't have a surface bound yet, we don't need to fixup the shader */
+ if (!p)
+ return FALSE;
+
+ f = p->format;
+ for(int i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+ if (fixup_formats[i].format == f)
+ return TRUE;
+
+ return FALSE;
+}
+
+static uint fixup_swizzle(enum pipe_format f, uint v)
+{
+ int i;
+
+ for(i=0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++)
+ if (fixup_formats[i].format == f)
+ break;
+
+ if (fixup_formats[i].format == PIPE_FORMAT_NONE)
+ return v;
+
+ uint rgba = v & 0xFFFF0000;
+
+ v &= 0xFFFF;
+ v |= ((rgba >> fixup_formats[i].hw_shift_R) & 0xF) << 28;
+ v |= ((rgba >> fixup_formats[i].hw_shift_G) & 0xF) << 24;
+ v |= ((rgba >> fixup_formats[i].hw_shift_B) & 0xF) << 20;
+ v |= ((rgba >> fixup_formats[i].hw_shift_A) & 0xF) << 16;
+
+ return v;
+}
+
static void
validate_program(struct i915_context *i915, unsigned *batch_space)
{
@@ -350,12 +405,39 @@ validate_program(struct i915_context *i915, unsigned *batch_space)
static void
emit_program(struct i915_context *i915)
{
- uint i;
- /* we should always have, at least, a pass-through program */
- assert(i915->fs->program_len > 0);
- for (i = 0; i < i915->fs->program_len; i++) {
- OUT_BATCH(i915->fs->program[i]);
+ struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0];
+ boolean need_format_fixup = need_fixup(cbuf_surface);
+ int i;
+ int fixup_offset = -1;
+
+ /* we should always have, at least, a pass-through program */
+ assert(i915->fs->program_len > 0);
+
+ if (need_format_fixup) {
+ /* Find where we emit the output color */
+ for (i = i915->fs->program_len - 3; i>0; i-=3) {
+ uint instr = i915->fs->program[i];
+ if ((instr & (REG_NR_MASK << A0_DEST_TYPE_SHIFT)) ==
+ (REG_TYPE_OC << A0_DEST_TYPE_SHIFT) ) {
+ /* Found it! */
+ fixup_offset = i + 1;
+ break;
+ }
+ }
+ if (fixup_offset == -1) {
+ need_format_fixup = FALSE;
+ debug_printf("couldn't find fixup offset\n");
}
+ }
+
+ /* emit the program to the hw */
+ for (i = 0; i < i915->fs->program_len; i++) {
+ if (need_format_fixup && (i == fixup_offset) ) {
+ uint v = fixup_swizzle(cbuf_surface->format, i915->fs->program[i]);
+ OUT_BATCH(v);
+ } else
+ OUT_BATCH(i915->fs->program[i]);
+ }
}
static void
diff --git a/src/gallium/drivers/i915/i915_state_inlines.h b/src/gallium/drivers/i915/i915_state_inlines.h
index b589117fbfe..aa992f75c51 100644
--- a/src/gallium/drivers/i915/i915_state_inlines.h
+++ b/src/gallium/drivers/i915/i915_state_inlines.h
@@ -60,6 +60,31 @@ i915_translate_compare_func(unsigned func)
}
static INLINE unsigned
+i915_translate_shadow_compare_func(unsigned func)
+{
+ switch (func) {
+ case PIPE_FUNC_NEVER:
+ return COMPAREFUNC_ALWAYS;
+ case PIPE_FUNC_LESS:
+ return COMPAREFUNC_LEQUAL;
+ case PIPE_FUNC_LEQUAL:
+ return COMPAREFUNC_LESS;
+ case PIPE_FUNC_GREATER:
+ return COMPAREFUNC_GEQUAL;
+ case PIPE_FUNC_GEQUAL:
+ return COMPAREFUNC_GREATER;
+ case PIPE_FUNC_NOTEQUAL:
+ return COMPAREFUNC_EQUAL;
+ case PIPE_FUNC_EQUAL:
+ return COMPAREFUNC_NOTEQUAL;
+ case PIPE_FUNC_ALWAYS:
+ return COMPAREFUNC_NEVER;
+ default:
+ return COMPAREFUNC_NEVER;
+ }
+}
+
+static INLINE unsigned
i915_translate_stencil_op(unsigned op)
{
switch (op) {
diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c
index be70e7a92c9..0103f7c3530 100644
--- a/src/gallium/drivers/i915/i915_state_sampler.c
+++ b/src/gallium/drivers/i915/i915_state_sampler.c
@@ -62,6 +62,7 @@ static void update_map(struct i915_context *i915,
uint unit,
const struct i915_texture *tex,
const struct i915_sampler_state *sampler,
+ const struct pipe_sampler_view* view,
uint state[2]);
@@ -161,9 +162,10 @@ static void update_samplers(struct i915_context *i915)
i915->current.sampler[unit]); /* the result */
update_map(i915,
unit,
- texture, /* texture */
- i915->sampler[unit], /* sampler state */
- i915->current.texbuffer[unit]); /* the result */
+ texture, /* texture */
+ i915->sampler[unit], /* sampler state */
+ i915->fragment_sampler_views[unit], /* sampler view */
+ i915->current.texbuffer[unit]); /* the result */
i915->current.sampler_enable_nr++;
i915->current.sampler_enable_flags |= (1 << unit);
@@ -180,13 +182,21 @@ struct i915_tracked_state i915_hw_samplers = {
};
-
/***********************************************************************
* Sampler views
*/
-static uint translate_texture_format(enum pipe_format pipeFormat)
+static uint translate_texture_format(enum pipe_format pipeFormat,
+ const struct pipe_sampler_view* view)
{
+ if ( (view->swizzle_r != PIPE_SWIZZLE_RED ||
+ view->swizzle_g != PIPE_SWIZZLE_GREEN ||
+ view->swizzle_b != PIPE_SWIZZLE_BLUE ||
+ view->swizzle_a != PIPE_SWIZZLE_ALPHA ) &&
+ pipeFormat != PIPE_FORMAT_Z24_UNORM_S8_USCALED &&
+ pipeFormat != PIPE_FORMAT_Z24X8_UNORM )
+ debug_printf("i915: unsupported texture swizzle for format %d\n", pipeFormat);
+
switch (pipeFormat) {
case PIPE_FORMAT_L8_UNORM:
return MAPSURF_8BIT | MT_8BIT_L8;
@@ -202,16 +212,16 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
return MAPSURF_16BIT | MT_16BIT_ARGB1555;
case PIPE_FORMAT_B4G4R4A4_UNORM:
return MAPSURF_16BIT | MT_16BIT_ARGB4444;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_ARGB2101010;
case PIPE_FORMAT_B8G8R8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
case PIPE_FORMAT_B8G8R8X8_UNORM:
return MAPSURF_32BIT | MT_32BIT_XRGB8888;
case PIPE_FORMAT_R8G8B8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ABGR8888;
-#if 0
case PIPE_FORMAT_R8G8B8X8_UNORM:
return MAPSURF_32BIT | MT_32BIT_XBGR8888;
-#endif
case PIPE_FORMAT_YUYV:
return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case PIPE_FORMAT_UYVY:
@@ -232,7 +242,25 @@ static uint translate_texture_format(enum pipe_format pipeFormat)
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
case PIPE_FORMAT_Z24X8_UNORM:
- return (MAPSURF_32BIT | MT_32BIT_xI824);
+ {
+ if ( view->swizzle_r == PIPE_SWIZZLE_RED &&
+ view->swizzle_g == PIPE_SWIZZLE_RED &&
+ view->swizzle_b == PIPE_SWIZZLE_RED &&
+ view->swizzle_a == PIPE_SWIZZLE_ONE)
+ return (MAPSURF_32BIT | MT_32BIT_xA824);
+ if ( view->swizzle_r == PIPE_SWIZZLE_RED &&
+ view->swizzle_g == PIPE_SWIZZLE_RED &&
+ view->swizzle_b == PIPE_SWIZZLE_RED &&
+ view->swizzle_a == PIPE_SWIZZLE_RED)
+ return (MAPSURF_32BIT | MT_32BIT_xI824);
+ if ( view->swizzle_r == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_g == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_b == PIPE_SWIZZLE_ZERO &&
+ view->swizzle_a == PIPE_SWIZZLE_RED)
+ return (MAPSURF_32BIT | MT_32BIT_xL824);
+ debug_printf("i915: unsupported depth swizzle\n");
+ return (MAPSURF_32BIT | MT_32BIT_xL824);
+ }
default:
debug_printf("i915: translate_texture_format() bad image format %x\n",
pipeFormat);
@@ -262,6 +290,7 @@ static void update_map(struct i915_context *i915,
uint unit,
const struct i915_texture *tex,
const struct i915_sampler_state *sampler,
+ const struct pipe_sampler_view* view,
uint state[2])
{
const struct pipe_resource *pt = &tex->b.b;
@@ -275,7 +304,7 @@ static void update_map(struct i915_context *i915,
assert(height);
assert(depth);
- format = translate_texture_format(pt->format);
+ format = translate_texture_format(pt->format, view);
pitch = tex->stride;
assert(format);
@@ -318,8 +347,9 @@ static void update_maps(struct i915_context *i915)
update_map(i915,
unit,
- texture, /* texture */
- i915->sampler[unit], /* sampler state */
+ texture, /* texture */
+ i915->sampler[unit], /* sampler state */
+ i915->fragment_sampler_views[unit], /* sampler view */
i915->current.texbuffer[unit]);
}
}
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
index 2865298318c..0e4000bc2ab 100644
--- a/src/gallium/drivers/i915/i915_state_static.c
+++ b/src/gallium/drivers/i915/i915_state_static.c
@@ -42,6 +42,18 @@ static unsigned translate_format(enum pipe_format format)
return COLOR_BUF_ARGB8888;
case PIPE_FORMAT_B5G6R5_UNORM:
return COLOR_BUF_RGB565;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return COLOR_BUF_ARGB1555;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return COLOR_BUF_ARGB8888;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return COLOR_BUF_ARGB4444;
+ case PIPE_FORMAT_B10G10R10A2_UNORM:
+ return COLOR_BUF_ARGB2101010;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ return COLOR_BUF_8BIT;
default:
assert(0);
return 0;
@@ -137,7 +149,8 @@ static void update_framebuffer(struct i915_context *i915)
i915->static_dirty |= I915_DST_RECT;
}
- i915->hardware_dirty |= I915_HW_STATIC;
+ /* we also send a new program to make sure the fixup for RGBA surfaces happens */
+ i915->hardware_dirty |= I915_HW_STATIC | I915_HW_PROGRAM;
/* flush the cache in case we sample from the old renderbuffers */
i915_set_flush_dirty(i915, I915_FLUSH_CACHE);
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index c10a8cbc12c..d6b20ceb5ce 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -79,7 +79,7 @@ llvmpipe = env.ConvenienceLibrary(
env.Alias('llvmpipe', llvmpipe)
-if env['platform'] != 'embedded':
+if not env['embedded']:
env = env.Clone()
env.Prepend(LIBS = [llvmpipe] + gallium)
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 036a6e0c379..4b2ae1436ea 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -423,7 +423,7 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
lp_jit_screen_init(screen);
screen->num_threads = util_cpu_caps.nr_cpus > 1 ? util_cpu_caps.nr_cpus : 0;
-#ifdef PIPE_OS_EMBEDDED
+#ifdef PIPE_SUBSYSTEM_EMBEDDED
screen->num_threads = 0;
#endif
screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 401155bba6e..223e7682ccd 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -81,20 +81,6 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
return bo;
}
-struct nouveau_bo *
-nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
-{
- struct nouveau_device *dev = nouveau_screen(pscreen)->device;
- struct nouveau_bo *bo = NULL;
- int ret;
-
- ret = nouveau_bo_user(dev, ptr, bytes, &bo);
- if (ret)
- return NULL;
-
- return bo;
-}
-
void *
nouveau_screen_bo_map(struct pipe_screen *pscreen,
struct nouveau_bo *bo,
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 186ada39677..d910809a0ec 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -47,8 +47,6 @@ nouveau_screen(struct pipe_screen *pscreen)
struct nouveau_bo *
nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
unsigned usage, unsigned bind, unsigned size);
-struct nouveau_bo *
-nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes);
void *
nouveau_screen_bo_map(struct pipe_screen *pscreen,
struct nouveau_bo *pb,
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 632ca4daf74..ceb83f6e684 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -168,6 +168,7 @@ nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
if (!resource->bo)
return;
+ nv50->residents_size += sizeof(struct resident);
/* We don't need to reference the resource here, it will be referenced
* in the context/state, and bufctx will be reset when state changes.
@@ -189,6 +190,7 @@ nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
if (rsd != top)
*rsd = *top;
+ nv50->residents_size -= sizeof(struct resident);
break;
}
}
@@ -201,11 +203,15 @@ nv50_bufctx_emit_relocs(struct nv50_context *nv50)
struct util_dynarray *array;
unsigned ctx, i, n;
+ n = nv50->residents_size / sizeof(struct resident);
+ n += NV50_SCREEN_RESIDENT_BO_COUNT;
+
+ MARK_RING(nv50->screen->base.channel, n, n);
+
for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
array = &nv50->residents[ctx];
n = array->size / sizeof(struct resident);
- MARK_RING(nv50->screen->base.channel, n, n);
for (i = 0; i < n; ++i) {
rsd = util_dynarray_element(array, struct resident, i);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 3f031994f0a..b4af24f6bce 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -64,6 +64,7 @@ struct nv50_context {
struct nv50_screen *screen;
struct util_dynarray residents[NV50_BUFCTX_COUNT];
+ unsigned residents_size;
uint32_t dirty;
@@ -156,6 +157,7 @@ void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
static INLINE void
nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
{
+ nv50->residents_size -= nv50->residents[ctx].size;
util_dynarray_resize(&nv50->residents[ctx], 0);
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index aea434b8679..64ad209a728 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -19,6 +19,8 @@ struct nv50_context;
#define NV50_SCRATCH_SIZE (2 << 20)
#define NV50_SCRATCH_NR_BUFFERS 2
+#define NV50_SCREEN_RESIDENT_BO_COUNT 5
+
struct nv50_screen {
struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index abdb9ce2f93..bb08941c243 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -404,9 +404,6 @@ nv50_draw_arrays(struct nv50_context *nv50,
struct nouveau_channel *chan = nv50->screen->base.channel;
unsigned prim;
- chan->flush_notify = nv50_draw_vbo_flush_notify;
- chan->user_private = nv50;
-
prim = nv50_prim_gl(mode);
while (instance_count--) {
@@ -420,8 +417,6 @@ nv50_draw_arrays(struct nv50_context *nv50,
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
-
- chan->flush_notify = nv50_default_flush_notify;
}
static void
@@ -523,9 +518,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
unsigned prim;
const unsigned index_size = nv50->idxbuf.index_size;
- chan->flush_notify = nv50_draw_vbo_flush_notify;
- chan->user_private = nv50;
-
prim = nv50_prim_gl(mode);
if (index_bias != nv50->state.index_bias) {
@@ -631,8 +623,6 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
}
-
- chan->flush_notify = nv50_default_flush_notify;
}
void
@@ -659,8 +649,12 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_state_validate(nv50);
+ chan->flush_notify = nv50_draw_vbo_flush_notify;
+ chan->user_private = nv50;
+
if (nv50->vbo_fifo) {
nv50_push_vbo(nv50, info);
+ chan->flush_notify = nv50_default_flush_notify;
return;
}
@@ -712,6 +706,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
info->mode, info->start, info->count,
info->instance_count, info->index_bias);
}
+ chan->flush_notify = nv50_default_flush_notify;
nv50_release_user_vbufs(nv50);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index 2f2a3da7c44..2679b7f86aa 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -169,6 +169,7 @@ nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx,
if (!resource->bo)
return;
+ nvc0->residents_size += sizeof(struct resident);
/* We don't need to reference the resource here, it will be referenced
* in the context/state, and bufctx will be reset when state changes.
@@ -190,6 +191,7 @@ nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx,
top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident);
if (rsd != top)
*rsd = *top;
+ nvc0->residents_size -= sizeof(struct resident);
break;
}
}
@@ -202,11 +204,15 @@ nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0)
struct util_dynarray *array;
unsigned ctx, i, n;
+ n = nvc0->residents_size / sizeof(struct resident);
+ n += NVC0_SCREEN_RESIDENT_BO_COUNT;
+
+ MARK_RING(nvc0->screen->base.channel, n, n);
+
for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) {
array = &nvc0->residents[ctx];
n = array->size / sizeof(struct resident);
- MARK_RING(nvc0->screen->base.channel, n, n);
for (i = 0; i < n; ++i) {
rsd = util_dynarray_element(array, struct resident, i);
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index f97141dd46e..b05cc337d5d 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -62,6 +62,7 @@ struct nvc0_context {
struct nvc0_screen *screen;
struct util_dynarray residents[NVC0_BUFCTX_COUNT];
+ unsigned residents_size;
uint32_t dirty;
@@ -163,6 +164,7 @@ void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx,
static INLINE void
nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx)
{
+ nvc0->residents_size -= nvc0->residents[ctx].size;
util_dynarray_resize(&nvc0->residents[ctx], 0);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index 94bf0cf3481..015807e2f5d 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -16,6 +16,8 @@ struct nvc0_context;
#define NVC0_SCRATCH_SIZE (2 << 20)
#define NVC0_SCRATCH_NR_BUFFERS 2
+#define NVC0_SCREEN_RESIDENT_BO_COUNT 5
+
struct nvc0_screen {
struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index 6bbcf2447ec..41079104b39 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -382,9 +382,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
struct nouveau_channel *chan = nvc0->screen->base.channel;
unsigned prim;
- chan->flush_notify = nvc0_draw_vbo_flush_notify;
- chan->user_private = nvc0;
-
prim = nvc0_prim_gl(mode);
while (instance_count--) {
@@ -397,8 +394,6 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
-
- chan->flush_notify = nvc0_default_flush_notify;
}
static void
@@ -500,9 +495,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
unsigned prim;
const unsigned index_size = nvc0->idxbuf.index_size;
- chan->flush_notify = nvc0_draw_vbo_flush_notify;
- chan->user_private = nvc0;
-
prim = nvc0_prim_gl(mode);
if (index_bias != nvc0->state.index_bias) {
@@ -568,8 +560,6 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
}
-
- chan->flush_notify = nvc0_default_flush_notify;
}
void
@@ -596,8 +586,12 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nvc0_state_validate(nvc0);
+ chan->flush_notify = nvc0_draw_vbo_flush_notify;
+ chan->user_private = nvc0;
+
if (nvc0->vbo_fifo) {
nvc0_push_vbo(nvc0, info);
+ chan->flush_notify = nvc0_default_flush_notify;
return;
}
@@ -648,6 +642,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
info->mode, info->start, info->count,
info->instance_count, info->index_bias);
}
+ chan->flush_notify = nvc0_default_flush_notify;
nvc0_release_user_vbufs(nvc0);
}
diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c
index 2b1510264a1..98603bedde1 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.c
+++ b/src/gallium/drivers/nvfx/nvfx_context.c
@@ -24,9 +24,21 @@ nvfx_flush(struct pipe_context *pipe,
OUT_RING(chan, 1);
}*/
- FIRE_RING(chan);
- if (fence)
+ if (fence) {
+ /* horrific hack to make glFinish() work in the absence of
+ * having proper fences in nvfx. a pending rewrite will
+ * fix this properly, but may be a while off.
+ */
+ MARK_RING(chan, 1, 1);
+ OUT_RELOC(chan, screen->fence, 0, NOUVEAU_BO_WR |
+ NOUVEAU_BO_DUMMY, 0, 0);
+ FIRE_RING(chan);
+ nouveau_bo_map(screen->fence, NOUVEAU_BO_RDWR);
+ nouveau_bo_unmap(screen->fence);
*fence = NULL;
+ } else {
+ FIRE_RING(chan);
+ }
}
static void
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 475138c3c32..7a013a916b9 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -304,6 +304,7 @@ nvfx_screen_destroy(struct pipe_screen *pscreen)
nouveau_notifier_free(&screen->sync);
nouveau_grobj_free(&screen->eng3d);
nvfx_screen_surface_takedown(pscreen);
+ nouveau_bo_ref(NULL, &screen->fence);
nouveau_screen_fini(&screen->base);
@@ -468,6 +469,12 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->is_format_supported = nvfx_screen_is_format_supported;
pscreen->context_create = nvfx_create;
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 4096, &screen->fence);
+ if (ret) {
+ nvfx_screen_destroy(pscreen);
+ return NULL;
+ }
+
switch (dev->chipset & 0xf0) {
case 0x30:
if (NV30_3D_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index b1f07187c78..02e7c5d1cad 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -11,6 +11,7 @@ struct nvfx_screen {
struct nouveau_screen base;
struct nouveau_winsys *nvws;
+ struct nouveau_bo *fence;
struct nvfx_context *cur_ctx;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index d9399d78ef9..b31141a518e 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -175,8 +175,8 @@ static void r300_split_index_bias(struct r300_context *r300, int index_bias,
enum r300_prepare_flags {
PREP_EMIT_STATES = (1 << 0), /* call emit_dirty_state and friends? */
PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */
- PREP_EMIT_AOS = (1 << 2), /* call emit_vertex_arrays? */
- PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
+ PREP_EMIT_VARRAYS = (1 << 2), /* call emit_vertex_arrays? */
+ PREP_EMIT_VARRAYS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */
PREP_INDEXED = (1 << 4) /* is this draw_elements? */
};
@@ -193,23 +193,22 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
unsigned cs_dwords)
{
boolean flushed = FALSE;
- boolean first_draw = flags & PREP_EMIT_STATES;
- boolean emit_vertex_arrays = flags & PREP_EMIT_AOS;
- boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
+ boolean emit_states = flags & PREP_EMIT_STATES;
+ boolean emit_vertex_arrays = flags & PREP_EMIT_VARRAYS;
+ boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
/* Add dirty state, index offset, and AOS. */
- if (first_draw) {
+ if (emit_states)
cs_dwords += r300_get_num_dirty_dwords(r300);
- if (r300->screen->caps.is_r500)
- cs_dwords += 2; /* emit_index_offset */
+ if (r300->screen->caps.is_r500)
+ cs_dwords += 2; /* emit_index_offset */
- if (emit_vertex_arrays)
- cs_dwords += 55; /* emit_vertex_arrays */
+ if (emit_vertex_arrays)
+ cs_dwords += 55; /* emit_vertex_arrays */
- if (emit_vertex_arrays_swtcl)
- cs_dwords += 7; /* emit_vertex_arrays_swtcl */
- }
+ if (emit_vertex_arrays_swtcl)
+ cs_dwords += 7; /* emit_vertex_arrays_swtcl */
cs_dwords += r300_get_num_cs_end_dwords(r300);
@@ -238,46 +237,48 @@ static boolean r300_emit_states(struct r300_context *r300,
int buffer_offset,
int index_bias, int instance_id)
{
- boolean first_draw = flags & PREP_EMIT_STATES;
- boolean emit_vertex_arrays = flags & PREP_EMIT_AOS;
- boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL;
+ boolean emit_states = flags & PREP_EMIT_STATES;
+ boolean emit_vertex_arrays = flags & PREP_EMIT_VARRAYS;
+ boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_VARRAYS_SWTCL;
boolean indexed = flags & PREP_INDEXED;
boolean validate_vbos = flags & PREP_VALIDATE_VBOS;
/* Validate buffers and emit dirty state if needed. */
- if (first_draw) {
+ if (emit_states || (emit_vertex_arrays && validate_vbos)) {
if (!r300_emit_buffer_validate(r300, validate_vbos,
index_buffer)) {
fprintf(stderr, "r300: CS space validation failed. "
"(not enough memory?) Skipping rendering.\n");
return FALSE;
}
+ }
+ if (emit_states)
r300_emit_dirty_state(r300);
- if (r300->screen->caps.is_r500) {
- if (r300->screen->caps.has_tcl)
- r500_emit_index_bias(r300, index_bias);
- else
- r500_emit_index_bias(r300, 0);
- }
- if (emit_vertex_arrays &&
- (r300->vertex_arrays_dirty ||
- r300->vertex_arrays_indexed != indexed ||
- r300->vertex_arrays_offset != buffer_offset ||
- r300->vertex_arrays_instance_id != instance_id)) {
- r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
-
- r300->vertex_arrays_dirty = FALSE;
- r300->vertex_arrays_indexed = indexed;
- r300->vertex_arrays_offset = buffer_offset;
- r300->vertex_arrays_instance_id = instance_id;
- }
+ if (r300->screen->caps.is_r500) {
+ if (r300->screen->caps.has_tcl)
+ r500_emit_index_bias(r300, index_bias);
+ else
+ r500_emit_index_bias(r300, 0);
+ }
- if (emit_vertex_arrays_swtcl)
- r300_emit_vertex_arrays_swtcl(r300, indexed);
+ if (emit_vertex_arrays &&
+ (r300->vertex_arrays_dirty ||
+ r300->vertex_arrays_indexed != indexed ||
+ r300->vertex_arrays_offset != buffer_offset ||
+ r300->vertex_arrays_instance_id != instance_id)) {
+ r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id);
+
+ r300->vertex_arrays_dirty = FALSE;
+ r300->vertex_arrays_indexed = indexed;
+ r300->vertex_arrays_offset = buffer_offset;
+ r300->vertex_arrays_instance_id = instance_id;
}
+ if (emit_vertex_arrays_swtcl)
+ r300_emit_vertex_arrays_swtcl(r300, indexed);
+
return TRUE;
}
@@ -540,7 +541,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
/* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
return;
@@ -662,7 +663,7 @@ static void r300_draw_elements(struct r300_context *r300,
/* 19 dwords for emit_draw_elements. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS |
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
instance_id))
goto done;
@@ -689,7 +690,7 @@ static void r300_draw_elements(struct r300_context *r300,
/* 15 dwords for emit_draw_elements */
if (count) {
if (!r300_prepare_for_rendering(r300,
- PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
+ PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
indexBuffer, 19, buffer_offset, info->index_bias,
instance_id))
goto done;
@@ -715,7 +716,7 @@ static void r300_draw_arrays(struct r300_context *r300,
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
+ PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS,
NULL, 9, start, 0, instance_id))
return;
@@ -736,7 +737,7 @@ static void r300_draw_arrays(struct r300_context *r300,
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
if (count) {
if (!r300_prepare_for_rendering(r300,
- PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
+ PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS, NULL, 9,
start, 0, instance_id))
return;
}
@@ -767,7 +768,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct pipe_draw_info info = *dinfo;
- boolean buffers_updated, uploader_flushed;
info.indexed = info.indexed && r300->index_buffer.buffer;
@@ -779,9 +779,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
r300_update_derived_state(r300);
/* Start the vbuf manager and update buffers if needed. */
- u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info,
- &buffers_updated, &uploader_flushed);
- if (buffers_updated) {
+ if (u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info) & U_VBUF_BUFFERS_UPDATED) {
r300->vertex_arrays_dirty = TRUE;
}
@@ -843,7 +841,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
r300_update_derived_state(r300);
r300_reserve_cs_dwords(r300,
- PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL |
+ PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL |
(indexed ? PREP_INDEXED : 0),
indexed ? 256 : 6);
@@ -1025,12 +1023,12 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
if (r300->draw_first_emitted) {
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+ PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
NULL, dwords, 0, 0, -1))
return;
} else {
if (!r300_emit_states(r300,
- PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL,
+ PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL,
NULL, 0, 0, -1))
return;
}
@@ -1065,12 +1063,12 @@ static void r300_render_draw_elements(struct vbuf_render* render,
if (r300->draw_first_emitted) {
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
NULL, 256, 0, 0, -1))
return;
} else {
if (!r300_emit_states(r300,
- PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ PREP_EMIT_STATES | PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
NULL, 0, 0, -1))
return;
}
@@ -1107,7 +1105,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
if (count) {
if (!r300_prepare_for_rendering(r300,
- PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ PREP_EMIT_VARRAYS_SWTCL | PREP_INDEXED,
NULL, 256, 0, 0, -1))
return;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 38ca9a24e45..62c2f1fff6c 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -447,16 +447,8 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
case PIPE_FORMAT_B8G8R8X8_UNORM:
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
- case PIPE_FORMAT_X8B8G8R8_UNORM:
- /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
case PIPE_FORMAT_R8G8B8X8_UNORM:
/*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
/* These formats work fine with ARGB8888 if US_OUT_FMT is set
@@ -662,10 +654,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
R300_C2_SEL_R | R300_C3_SEL_A;
/* ARGB outputs. */
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- /*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
- case PIPE_FORMAT_X8R8G8B8_UNORM:
- /*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
case PIPE_FORMAT_A16_UNORM:
case PIPE_FORMAT_A16_SNORM:
case PIPE_FORMAT_A16_FLOAT:
@@ -674,15 +662,6 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
R300_C0_SEL_A | R300_C1_SEL_R |
R300_C2_SEL_G | R300_C3_SEL_B;
- /* ABGR outputs. */
- case PIPE_FORMAT_A8B8G8R8_UNORM:
- /*case PIPE_FORMAT_A8B8G8R8_SNORM:*/
- case PIPE_FORMAT_X8B8G8R8_UNORM:
- /*case PIPE_FORMAT_X8B8G8R8_SNORM:*/
- return modifier |
- R300_C0_SEL_A | R300_C1_SEL_B |
- R300_C2_SEL_G | R300_C3_SEL_R;
-
/* RGBA outputs. */
case PIPE_FORMAT_R8G8B8X8_UNORM:
/*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript
index 0135808f10a..19f07b2bef8 100644
--- a/src/gallium/drivers/r600/SConscript
+++ b/src/gallium/drivers/r600/SConscript
@@ -2,11 +2,7 @@ Import('*')
env = env.Clone()
-try:
- env.ParseConfig('pkg-config --cflags libdrm_radeon')
-except OSError:
- print 'warning: not building r600'
- Return()
+env.PkgUseModules('DRM_RADEON')
env.Append(CPPPATH = [
'#/include',
diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h
index f8891781be8..b5590116e8f 100644
--- a/src/gallium/drivers/r600/eg_state_inlines.h
+++ b/src/gallium/drivers/r600/eg_state_inlines.h
@@ -327,6 +327,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
return V_028C70_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
+ case PIPE_FORMAT_R16_FLOAT:
return V_028C70_SWAP_STD;
/* 32-bit buffers. */
@@ -343,6 +344,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
case PIPE_FORMAT_X8R8G8B8_UNORM:
return V_028C70_SWAP_ALT_REV;
case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
return V_028C70_SWAP_STD;
@@ -429,6 +431,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_R16_UNORM:
return V_028C70_COLOR_16;
+ case PIPE_FORMAT_R16_FLOAT:
+ return V_028C70_COLOR_16_FLOAT;
+
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index f86e4d4e3af..dc182611482 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -256,6 +256,8 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
}
rstate = &rs->rstate;
+ rs->clamp_vertex_color = state->clamp_vertex_color;
+ rs->clamp_fragment_color = state->clamp_fragment_color;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
@@ -883,6 +885,7 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx,
/* build states */
rctx->have_depth_fb = 0;
+ rctx->nr_cbufs = state->nr_cbufs;
for (int i = 0; i < state->nr_cbufs; i++) {
evergreen_cb(rctx, rstate, state, i);
}
@@ -1629,7 +1632,10 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
rshader->output[i].name == TGSI_SEMANTIC_STENCIL)
exports_ps |= 1;
else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) {
- num_cout++;
+ if (rshader->fs_write_all)
+ num_cout = rshader->nr_cbufs;
+ else
+ num_cout++;
}
}
exports_ps |= S_02884C_EXPORT_COLORS(num_cout);
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 225c17c2540..151e831e5c6 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -245,6 +245,7 @@ struct r600_context {
unsigned pm4_cdwords;
unsigned pm4_dirty_cdwords;
unsigned ctx_pm4_ndwords;
+ unsigned init_dwords;
unsigned nreloc;
unsigned creloc;
struct r600_reloc *reloc;
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index c447a031063..065f955ebcb 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -1863,6 +1863,8 @@ void r600_bc_dump(struct r600_bc *bc)
break;
case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+ case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
fprintf(stderr, "GPR:%X ", cf->output.gpr);
fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index e9f35c10ac1..6171d285bb9 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -27,9 +27,18 @@
enum r600_blitter_op /* bitmask */
{
- R600_CLEAR = 1,
- R600_CLEAR_SURFACE = 2,
- R600_COPY = 4
+ R600_SAVE_TEXTURES = 1,
+ R600_SAVE_FRAMEBUFFER = 2,
+ R600_DISABLE_RENDER_COND = 4,
+
+ R600_CLEAR = 0,
+
+ R600_CLEAR_SURFACE = R600_SAVE_FRAMEBUFFER,
+
+ R600_COPY = R600_SAVE_FRAMEBUFFER | R600_SAVE_TEXTURES |
+ R600_DISABLE_RENDER_COND,
+
+ R600_DECOMPRESS = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND,
};
static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op)
@@ -58,10 +67,10 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
rctx->vbuf_mgr->nr_vertex_buffers,
rctx->vbuf_mgr->vertex_buffer);
- if (op & (R600_CLEAR_SURFACE | R600_COPY))
+ if (op & R600_SAVE_FRAMEBUFFER)
util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer);
- if (op & R600_COPY) {
+ if (op & R600_SAVE_TEXTURES) {
util_blitter_save_fragment_sampler_states(
rctx->blitter, rctx->ps_samplers.n_samplers,
(void**)rctx->ps_samplers.samplers);
@@ -71,11 +80,23 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
(struct pipe_sampler_view**)rctx->ps_samplers.views);
}
+ if ((op & R600_DISABLE_RENDER_COND) && rctx->current_render_cond) {
+ rctx->saved_render_cond = rctx->current_render_cond;
+ rctx->saved_render_cond_mode = rctx->current_render_cond_mode;
+ rctx->context.render_condition(&rctx->context, NULL, 0);
+ }
+
}
static void r600_blitter_end(struct pipe_context *ctx)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+ if (rctx->saved_render_cond) {
+ rctx->context.render_condition(&rctx->context,
+ rctx->saved_render_cond,
+ rctx->saved_render_cond_mode);
+ rctx->saved_render_cond = NULL;
+ }
r600_context_queries_resume(&rctx->ctx);
rctx->blit = false;
}
@@ -107,7 +128,7 @@ void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_t
rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635)
depth = 0.0f;
- r600_blitter_begin(ctx, R600_CLEAR_SURFACE);
+ r600_blitter_begin(ctx, R600_DECOMPRESS);
util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, rctx->custom_dsa_flush, depth);
r600_blitter_end(ctx);
@@ -273,6 +294,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
{
struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
struct texture_orig_info orig_info[2];
+ struct pipe_box sbox;
+ const struct pipe_box *psbox;
boolean restore_orig[2];
/* Fallback for buffers. */
@@ -290,7 +313,15 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
if (util_format_is_compressed(src->format)) {
r600_compressed_to_blittable(src, src_level, &orig_info[0]);
restore_orig[0] = TRUE;
- }
+ sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
+ sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y);
+ sbox.z = src_box->z;
+ sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width);
+ sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
+ sbox.depth = src_box->depth;
+ psbox=&sbox;
+ } else
+ psbox=src_box;
if (util_format_is_compressed(dst->format)) {
r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
@@ -301,7 +332,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
}
r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
- src, src_level, src_box);
+ src, src_level, psbox);
if (restore_orig[0])
r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 16fe6c54a15..8f3a175587e 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -126,9 +126,6 @@ static void r600_flush(struct pipe_context *ctx,
if (rfence)
*rfence = r600_create_fence(rctx);
- if (!rctx->ctx.pm4_cdwords)
- return;
-
#if 0
sprintf(dname, "gallium-%08d.bof", dc);
if (dc < 20) {
@@ -376,6 +373,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_SM3:
+ case PIPE_CAP_SEAMLESS_CUBE_MAP:
+ case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
return 1;
/* Supported except the original R600. */
@@ -385,14 +384,12 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
return family == CHIP_R600 ? 0 : 1;
/* Supported on Evergreen. */
- case PIPE_CAP_SEAMLESS_CUBE_MAP:
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return family >= CHIP_CEDAR ? 1 : 0;
/* Unsupported features. */
case PIPE_CAP_STREAM_OUTPUT:
case PIPE_CAP_PRIMITIVE_RESTART:
- case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
case PIPE_CAP_TGSI_INSTANCEID:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
@@ -481,9 +478,9 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
return 8; /* FIXME */
case PIPE_SHADER_CAP_MAX_INPUTS:
if(shader == PIPE_SHADER_FRAGMENT)
- return 10;
+ return 34;
else
- return 16;
+ return 32;
case PIPE_SHADER_CAP_MAX_TEMPS:
return 256; /* Max native temporaries. */
case PIPE_SHADER_CAP_MAX_ADDRS:
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 5e534ca905c..2667c80bcef 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -50,6 +50,7 @@ enum r600_pipe_state_id {
R600_PIPE_STATE_BLEND = 0,
R600_PIPE_STATE_BLEND_COLOR,
R600_PIPE_STATE_CONFIG,
+ R600_PIPE_STATE_SEAMLESS_CUBEMAP,
R600_PIPE_STATE_CLIP,
R600_PIPE_STATE_SCISSOR,
R600_PIPE_STATE_VIEWPORT,
@@ -87,6 +88,8 @@ struct r600_pipe_sampler_view {
struct r600_pipe_rasterizer {
struct r600_pipe_state rstate;
+ boolean clamp_vertex_color;
+ boolean clamp_fragment_color;
boolean flatshade;
unsigned sprite_coord_enable;
float offset_units;
@@ -124,6 +127,12 @@ struct r600_pipe_shader {
struct r600_bo *bo;
struct r600_bo *bo_fetch;
struct r600_vertex_element vertex_elements;
+ struct tgsi_token *tokens;
+};
+
+struct r600_pipe_sampler_state {
+ struct r600_pipe_state rstate;
+ boolean seamless_cube_map;
};
/* needed for blitter save */
@@ -191,12 +200,20 @@ struct r600_pipe_context {
struct r600_pipe_rasterizer *rasterizer;
struct r600_pipe_state vgt;
struct r600_pipe_state spi;
+ struct pipe_query *current_render_cond;
+ unsigned current_render_cond_mode;
+ struct pipe_query *saved_render_cond;
+ unsigned saved_render_cond_mode;
/* shader information */
+ boolean clamp_vertex_color;
+ boolean clamp_fragment_color;
+ boolean spi_dirty;
unsigned sprite_coord_enable;
boolean flatshade;
boolean export_16bpc;
unsigned alpha_ref;
boolean alpha_ref_dirty;
+ unsigned nr_cbufs;
struct r600_textures_info ps_samplers;
struct r600_pipe_fences fences;
@@ -254,7 +271,7 @@ void r600_init_query_functions(struct r600_pipe_context *rctx);
void r600_init_context_resource_functions(struct r600_pipe_context *r600);
/* r600_shader.c */
-int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens);
+int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader);
void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *shader);
int r600_find_vs_semantic_index(struct r600_shader *vs,
struct r600_shader *ps, int id);
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
index 181ea3f9e49..bedb48b6031 100644
--- a/src/gallium/drivers/r600/r600_query.c
+++ b/src/gallium/drivers/r600/r600_query.c
@@ -75,6 +75,9 @@ static void r600_render_condition(struct pipe_context *ctx,
struct r600_query *rquery = (struct r600_query *)query;
int wait_flag = 0;
+ rctx->current_render_cond = query;
+ rctx->current_render_cond_mode = mode;
+
if (!query) {
rctx->ctx.predicate_drawing = false;
r600_query_predication(&rctx->ctx, NULL, PREDICATION_OP_CLEAR, 1);
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index b8a86b03143..f83d7079b29 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -118,9 +118,9 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
return 0;
}
-static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
+static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader);
-int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens)
+int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader)
{
static int dump_shaders = -1;
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
@@ -133,10 +133,10 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s
if (dump_shaders) {
fprintf(stderr, "--------------------------------------------------------------\n");
- tgsi_dump(tokens, 0);
+ tgsi_dump(shader->tokens, 0);
}
shader->shader.family = r600_get_family(rctx->radeon);
- r = r600_shader_from_tgsi(tokens, &shader->shader);
+ r = r600_shader_from_tgsi(rctx, shader);
if (r) {
R600_ERR("translation from TGSI failed !\n");
return r;
@@ -159,6 +159,8 @@ void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader
r600_bo_reference(rctx->radeon, &shader->bo, NULL);
r600_bc_clear(&shader->shader.bc);
+
+ memset(&shader->shader,0,sizeof(struct r600_shader));
}
/*
@@ -594,15 +596,17 @@ static int tgsi_split_literal_constant(struct r600_shader_ctx *ctx)
return 0;
}
-static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader)
+static int r600_shader_from_tgsi(struct r600_pipe_context * rctx, struct r600_pipe_shader *pipeshader)
{
+ struct r600_shader *shader = &pipeshader->shader;
+ struct tgsi_token *tokens = pipeshader->tokens;
struct tgsi_full_immediate *immediate;
struct tgsi_full_property *property;
struct r600_shader_ctx ctx;
struct r600_bc_output output[32];
unsigned output_done, noutput;
unsigned opcode;
- int i, r = 0, pos0;
+ int i, j, r = 0, pos0;
ctx.bc = &shader->bc;
ctx.shader = shader;
@@ -616,6 +620,11 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
shader->processor_type = ctx.type;
ctx.bc->type = shader->processor_type;
+ shader->clamp_color = (((ctx.type == TGSI_PROCESSOR_FRAGMENT) && rctx->clamp_fragment_color) ||
+ ((ctx.type == TGSI_PROCESSOR_VERTEX) && rctx->clamp_vertex_color));
+
+ shader->nr_cbufs = rctx->nr_cbufs;
+
/* register allocations */
/* Values [0,127] correspond to GPR[0..127].
* Values [128,159] correspond to constant buffer bank 0
@@ -725,52 +734,103 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
goto out_err;
}
}
- /* export output */
+
noutput = shader->noutput;
+
+ /* clamp color outputs */
+ if (shader->clamp_color) {
+ for (i = 0; i < noutput; i++) {
+ if (shader->output[i].name == TGSI_SEMANTIC_COLOR ||
+ shader->output[i].name == TGSI_SEMANTIC_BCOLOR) {
+
+ int j;
+ for (j = 0; j < 4; j++) {
+ struct r600_bc_alu alu;
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+
+ /* MOV_SAT R, R */
+ alu.inst = BC_INST(ctx.bc, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+ alu.dst.sel = shader->output[i].gpr;
+ alu.dst.chan = j;
+ alu.dst.write = 1;
+ alu.dst.clamp = 1;
+ alu.src[0].sel = alu.dst.sel;
+ alu.src[0].chan = j;
+
+ if (j == 3) {
+ alu.last = 1;
+ }
+ r = r600_bc_add_alu(ctx.bc, &alu);
+ if (r)
+ return r;
+ }
+ }
+ }
+ }
+
+ /* export output */
+ j = 0;
for (i = 0, pos0 = 0; i < noutput; i++) {
memset(&output[i], 0, sizeof(struct r600_bc_output));
- output[i].gpr = shader->output[i].gpr;
- output[i].elem_size = 3;
- output[i].swizzle_x = 0;
- output[i].swizzle_y = 1;
- output[i].swizzle_z = 2;
- output[i].swizzle_w = 3;
- output[i].burst_count = 1;
- output[i].barrier = 1;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
- output[i].array_base = i - pos0;
- output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
+ output[i + j].gpr = shader->output[i].gpr;
+ output[i + j].elem_size = 3;
+ output[i + j].swizzle_x = 0;
+ output[i + j].swizzle_y = 1;
+ output[i + j].swizzle_z = 2;
+ output[i + j].swizzle_w = 3;
+ output[i + j].burst_count = 1;
+ output[i + j].barrier = 1;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+ output[i + j].array_base = i - pos0;
+ output[i + j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
switch (ctx.type) {
case TGSI_PROCESSOR_VERTEX:
if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
- output[i].array_base = 60;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+ output[i + j].array_base = 60;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
/* position doesn't count in array_base */
pos0++;
}
if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) {
- output[i].array_base = 61;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+ output[i + j].array_base = 61;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
/* position doesn't count in array_base */
pos0++;
}
break;
case TGSI_PROCESSOR_FRAGMENT:
if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
- output[i].array_base = shader->output[i].sid;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ output[i + j].array_base = shader->output[i].sid;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ if (shader->fs_write_all && (shader->family >= CHIP_CEDAR)) {
+ for (j = 1; j < shader->nr_cbufs; j++) {
+ memset(&output[i + j], 0, sizeof(struct r600_bc_output));
+ output[i + j].gpr = shader->output[i].gpr;
+ output[i + j].elem_size = 3;
+ output[i + j].swizzle_x = 0;
+ output[i + j].swizzle_y = 1;
+ output[i + j].swizzle_z = 2;
+ output[i + j].swizzle_w = 3;
+ output[i + j].burst_count = 1;
+ output[i + j].barrier = 1;
+ output[i + j].array_base = shader->output[i].sid + j;
+ output[i + j].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ }
+ j--;
+ }
} else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
- output[i].array_base = 61;
- output[i].swizzle_x = 2;
- output[i].swizzle_y = 7;
- output[i].swizzle_z = output[i].swizzle_w = 7;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ output[i + j].array_base = 61;
+ output[i + j].swizzle_x = 2;
+ output[i + j].swizzle_y = 7;
+ output[i + j].swizzle_z = output[i + j].swizzle_w = 7;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
} else if (shader->output[i].name == TGSI_SEMANTIC_STENCIL) {
- output[i].array_base = 61;
- output[i].swizzle_x = 7;
- output[i].swizzle_y = 1;
- output[i].swizzle_z = output[i].swizzle_w = 7;
- output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+ output[i + j].array_base = 61;
+ output[i + j].swizzle_x = 7;
+ output[i + j].swizzle_y = 1;
+ output[i + j].swizzle_z = output[i + j].swizzle_w = 7;
+ output[i + j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
} else {
R600_ERR("unsupported fragment output name %d\n", shader->output[i].name);
r = -EINVAL;
@@ -783,6 +843,7 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
goto out_err;
}
}
+ noutput += j;
/* add fake param output for vertex shader if no param is exported */
if (ctx.type == TGSI_PROCESSOR_VERTEX) {
for (i = 0, pos0 = 0; i < noutput; i++) {
@@ -1303,41 +1364,6 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
struct r600_bc_alu alu;
int r;
- /* dst.x, <- 1.0 */
- memset(&alu, 0, sizeof(struct r600_bc_alu));
- alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
- alu.src[0].sel = V_SQ_ALU_SRC_1; /*1.0*/
- alu.src[0].chan = 0;
- tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
- alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1;
- r = r600_bc_add_alu(ctx->bc, &alu);
- if (r)
- return r;
-
- /* dst.y = max(src.x, 0.0) */
- memset(&alu, 0, sizeof(struct r600_bc_alu));
- alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX);
- r600_bc_src(&alu.src[0], &ctx->src[0], 0);
- alu.src[1].sel = V_SQ_ALU_SRC_0; /*0.0*/
- alu.src[1].chan = 0;
- tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst);
- alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1;
- r = r600_bc_add_alu(ctx->bc, &alu);
- if (r)
- return r;
-
- /* dst.w, <- 1.0 */
- memset(&alu, 0, sizeof(struct r600_bc_alu));
- alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
- alu.src[0].sel = V_SQ_ALU_SRC_1;
- alu.src[0].chan = 0;
- tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst);
- alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1;
- alu.last = 1;
- r = r600_bc_add_alu(ctx->bc, &alu);
- if (r)
- return r;
-
if (inst->Dst[0].Register.WriteMask & (1 << 2))
{
int chan;
@@ -1366,7 +1392,9 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
memset(&alu, 0, sizeof(struct r600_bc_alu));
alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED);
r600_bc_src(&alu.src[0], &ctx->src[0], 1);
- tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+ alu.dst.sel = ctx->temp_reg;
+ alu.dst.chan = 2;
+ alu.dst.write = 1;
alu.last = 1;
r = r600_bc_add_alu(ctx->bc, &alu);
if (r)
@@ -1423,6 +1451,42 @@ static int tgsi_lit(struct r600_shader_ctx *ctx)
return r;
}
}
+
+ /* dst.x, <- 1.0 */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+ alu.src[0].sel = V_SQ_ALU_SRC_1; /*1.0*/
+ alu.src[0].chan = 0;
+ tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.y = max(src.x, 0.0) */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX);
+ r600_bc_src(&alu.src[0], &ctx->src[0], 0);
+ alu.src[1].sel = V_SQ_ALU_SRC_0; /*0.0*/
+ alu.src[1].chan = 0;
+ tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst);
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
+ /* dst.w, <- 1.0 */
+ memset(&alu, 0, sizeof(struct r600_bc_alu));
+ alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
+ alu.src[0].sel = V_SQ_ALU_SRC_1;
+ alu.src[0].chan = 0;
+ tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst);
+ alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1;
+ alu.last = 1;
+ r = r600_bc_add_alu(ctx->bc, &alu);
+ if (r)
+ return r;
+
return 0;
}
@@ -3266,7 +3330,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
{TGSI_OPCODE_MOV, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
{TGSI_OPCODE_LIT, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit},
{TGSI_OPCODE_RCP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate},
- {TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate},
+ {TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_rsq},
{TGSI_OPCODE_EXP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_exp},
{TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_log},
{TGSI_OPCODE_MUL, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index 8f96ce5085c..76aebf2b1ea 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -46,6 +46,8 @@ struct r600_shader {
enum radeon_family family;
boolean uses_kill;
boolean fs_write_all;
+ boolean clamp_color;
+ unsigned nr_cbufs;
};
#endif
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index d927e4a945e..be07f5feff8 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -299,6 +299,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
}
rstate = &rs->rstate;
+ rs->clamp_vertex_color = state->clamp_vertex_color;
+ rs->clamp_fragment_color = state->clamp_fragment_color;
rs->flatshade = state->flatshade;
rs->sprite_coord_enable = state->sprite_coord_enable;
@@ -369,14 +371,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
static void *r600_create_sampler_state(struct pipe_context *ctx,
const struct pipe_sampler_state *state)
{
- struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+ struct r600_pipe_sampler_state *ss = CALLOC_STRUCT(r600_pipe_sampler_state);
+ struct r600_pipe_state *rstate;
union util_color uc;
unsigned aniso_flag_offset = state->max_anisotropy > 1 ? 4 : 0;
- if (rstate == NULL) {
+ if (ss == NULL) {
return NULL;
}
+ ss->seamless_cube_map = state->seamless_cube_map;
+ rstate = &ss->rstate;
rstate->id = R600_PIPE_STATE_SAMPLER;
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
r600_pipe_state_add_reg_noblock(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@@ -559,27 +564,57 @@ static void r600_set_ps_sampler_view(struct pipe_context *ctx, unsigned count,
rctx->ps_samplers.n_views = count;
}
+static void r600_set_seamless_cubemap(struct r600_pipe_context *rctx, boolean enable)
+{
+ struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
+ if (rstate == NULL)
+ return;
+
+ rstate->id = R600_PIPE_STATE_SEAMLESS_CUBEMAP;
+ r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+ (enable ? 0 : S_009508_DISABLE_CUBE_WRAP(1)),
+ 1, NULL);
+
+ free(rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP]);
+ rctx->states[R600_PIPE_STATE_SEAMLESS_CUBEMAP] = rstate;
+ r600_context_pipe_state_set(&rctx->ctx, rstate);
+}
+
static void r600_bind_ps_sampler(struct pipe_context *ctx, unsigned count, void **states)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
- struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
+ struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+ int seamless = -1;
memcpy(rctx->ps_samplers.samplers, states, sizeof(void*) * count);
rctx->ps_samplers.n_samplers = count;
for (int i = 0; i < count; i++) {
- r600_context_pipe_state_set_ps_sampler(&rctx->ctx, rstates[i], i);
+ r600_context_pipe_state_set_ps_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+ if (sstates[i])
+ seamless = sstates[i]->seamless_cube_map;
}
+
+ if (seamless != -1)
+ r600_set_seamless_cubemap(rctx, seamless);
}
static void r600_bind_vs_sampler(struct pipe_context *ctx, unsigned count, void **states)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
- struct r600_pipe_state **rstates = (struct r600_pipe_state **)states;
+ struct r600_pipe_sampler_state **sstates = (struct r600_pipe_sampler_state **)states;
+ int seamless = -1;
for (int i = 0; i < count; i++) {
- r600_context_pipe_state_set_vs_sampler(&rctx->ctx, rstates[i], i);
+ r600_context_pipe_state_set_vs_sampler(&rctx->ctx, &sstates[i]->rstate, i);
+
+ if (sstates[i])
+ seamless = sstates[i]->seamless_cube_map;
}
+
+ if (seamless != -1)
+ r600_set_seamless_cubemap(rctx, seamless);
}
static void r600_set_clip_state(struct pipe_context *ctx,
@@ -1290,14 +1325,22 @@ void r600_init_config(struct r600_pipe_context *rctx)
if (family >= CHIP_RV770) {
r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00004000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000002, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+ S_009508_DISABLE_CUBE_ANISO(1) |
+ S_009508_SYNC_GRADIENT(1) |
+ S_009508_SYNC_WALKER(1) |
+ S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x00420204, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL, 0x00514002, 0xFFFFFFFF, NULL);
} else {
r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x00000000, 0xFFFFFFFF, NULL);
- r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX, 0x07000003, 0xFFFFFFFF, NULL);
+ r600_pipe_state_add_reg(rstate, R_009508_TA_CNTL_AUX,
+ S_009508_DISABLE_CUBE_ANISO(1) |
+ S_009508_SYNC_GRADIENT(1) |
+ S_009508_SYNC_WALKER(1) |
+ S_009508_SYNC_ALIGNER(1), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_009830_DB_DEBUG, 0x82000000, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_009838_DB_WATERMARKS, 0x01020204, 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_0286C8_SPI_THREAD_GROUPING, 0x00000001, 0xFFFFFFFF, NULL);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index fa0c5cb89d7..d9140403e5a 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -28,6 +28,7 @@
#include <util/u_format.h>
#include <pipebuffer/pb_buffer.h>
#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
#include "r600_formats.h"
#include "r600_pipe.h"
#include "r600d.h"
@@ -99,6 +100,8 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
if (state == NULL)
return;
+ rctx->clamp_vertex_color = rs->clamp_vertex_color;
+ rctx->clamp_fragment_color = rs->clamp_fragment_color;
rctx->flatshade = rs->flatshade;
rctx->sprite_coord_enable = rs->sprite_coord_enable;
rctx->rasterizer = rs;
@@ -112,7 +115,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
r600_polygon_offset_update(rctx);
}
if (rctx->ps_shader && rctx->vs_shader)
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
}
void r600_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -257,7 +260,9 @@ void *r600_create_shader_state(struct pipe_context *ctx,
struct r600_pipe_shader *shader = CALLOC_STRUCT(r600_pipe_shader);
int r;
- r = r600_pipe_shader_create(ctx, shader, state->tokens);
+ shader->tokens = tgsi_dup_tokens(state->tokens);
+
+ r = r600_pipe_shader_create(ctx, shader);
if (r) {
return NULL;
}
@@ -274,7 +279,7 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state)
r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate);
}
if (rctx->ps_shader && rctx->vs_shader) {
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
r600_adjust_gprs(rctx);
}
}
@@ -289,7 +294,7 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate);
}
if (rctx->ps_shader && rctx->vs_shader) {
- r600_spi_update(rctx);
+ rctx->spi_dirty = true;
r600_adjust_gprs(rctx);
}
}
@@ -303,6 +308,7 @@ void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
rctx->ps_shader = NULL;
}
+ free(shader->tokens);
r600_pipe_shader_destroy(ctx, shader);
free(shader);
}
@@ -316,6 +322,7 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state)
rctx->vs_shader = NULL;
}
+ free(shader->tokens);
r600_pipe_shader_destroy(ctx, shader);
free(shader);
}
@@ -351,7 +358,7 @@ static void r600_spi_update(struct r600_pipe_context *rctx)
struct r600_pipe_shader *shader = rctx->ps_shader;
struct r600_pipe_state *rstate = &rctx->spi;
struct r600_shader *rshader = &shader->shader;
- unsigned i, tmp;
+ unsigned i, tmp, sid;
if (rctx->spi.id == 0)
r600_spi_block_init(rctx, &rctx->spi);
@@ -360,9 +367,14 @@ static void r600_spi_update(struct r600_pipe_context *rctx)
for (i = 0; i < rshader->ninput; i++) {
if (rshader->input[i].name == TGSI_SEMANTIC_POSITION ||
rshader->input[i].name == TGSI_SEMANTIC_FACE)
- continue;
+ if (rctx->family >= CHIP_CEDAR)
+ continue;
+ else
+ sid=0;
+ else
+ sid=r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i);
- tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i));
+ tmp = S_028644_SEMANTIC(sid);
if (rshader->input[i].name == TGSI_SEMANTIC_COLOR ||
rshader->input[i].name == TGSI_SEMANTIC_BCOLOR ||
@@ -386,6 +398,7 @@ static void r600_spi_update(struct r600_pipe_context *rctx)
r600_pipe_state_mod_reg(rstate, tmp);
}
+ rctx->spi_dirty = false;
r600_context_pipe_state_set(&rctx->ctx, rstate);
}
@@ -525,24 +538,39 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
}
}
+static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shader * shader)
+{
+ struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
+ int r;
+
+ r600_pipe_shader_destroy(ctx, shader);
+ r = r600_pipe_shader_create(ctx, shader);
+ if (r) {
+ return r;
+ }
+ r600_context_pipe_state_set(&rctx->ctx, &shader->rstate);
+
+ return 0;
+}
+
void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_resource *rbuffer;
- u32 vgt_dma_index_type, vgt_dma_swap_mode, vgt_draw_initiator, mask;
struct r600_draw rdraw;
- struct r600_drawl draw = {};
- unsigned prim;
+ struct r600_drawl draw;
+ unsigned prim, mask;
if (!rctx->blit) {
if (rctx->have_depth_fb || rctx->have_depth_texture)
r600_flush_depth_textures(rctx);
}
- u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info, NULL, NULL);
+ u_vbuf_mgr_draw_begin(rctx->vbuf_mgr, info);
r600_vertex_buffer_update(rctx);
draw.info = *info;
draw.ctx = ctx;
+ draw.index_buffer = NULL;
if (info->indexed && rctx->index_buffer.buffer) {
draw.info.start += rctx->index_buffer.offset / rctx->index_buffer.index_size;
pipe_resource_reference(&draw.index_buffer, rctx->index_buffer.buffer);
@@ -560,57 +588,29 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
r600_upload_index_buffer(rctx, &draw);
}
} else {
+ draw.index_size = 0;
+ draw.index_buffer_offset = 0;
draw.info.index_bias = info->start;
}
- vgt_dma_swap_mode = 0;
- switch (draw.index_size) {
- case 2:
- vgt_draw_initiator = 0;
- vgt_dma_index_type = 0;
- if (R600_BIG_ENDIAN) {
- vgt_dma_swap_mode = ENDIAN_8IN16;
- }
- break;
- case 4:
- vgt_draw_initiator = 0;
- vgt_dma_index_type = 1;
- if (R600_BIG_ENDIAN) {
- vgt_dma_swap_mode = ENDIAN_8IN32;
- }
- break;
- case 0:
- vgt_draw_initiator = 2;
- vgt_dma_index_type = 0;
- break;
- default:
- R600_ERR("unsupported index size %d\n", draw.index_size);
- return;
- }
if (r600_conv_pipe_prim(draw.info.mode, &prim))
return;
- if (unlikely(rctx->ps_shader == NULL)) {
- R600_ERR("missing vertex shader\n");
- return;
- }
- if (unlikely(rctx->vs_shader == NULL)) {
- R600_ERR("missing vertex shader\n");
- return;
- }
- /* there should be enough input */
- if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) {
- R600_ERR("%d resources provided, expecting %d\n",
- rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource);
- return;
- }
+
+ if (rctx->vs_shader->shader.clamp_color != rctx->clamp_vertex_color)
+ r600_shader_rebuild(ctx, rctx->vs_shader);
+
+ if ((rctx->ps_shader->shader.clamp_color != rctx->clamp_fragment_color) ||
+ ((rctx->family >= CHIP_CEDAR) && rctx->ps_shader->shader.fs_write_all &&
+ (rctx->ps_shader->shader.nr_cbufs != rctx->nr_cbufs)))
+ r600_shader_rebuild(ctx, rctx->ps_shader);
+
+ if (rctx->spi_dirty)
+ r600_spi_update(rctx);
if (rctx->alpha_ref_dirty)
r600_update_alpha_ref(rctx);
- mask = 0;
- for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) {
- mask |= (0xF << (i * 4));
- }
+ mask = (1ULL << ((unsigned)rctx->framebuffer.nr_cbufs * 4)) - 1;
if (rctx->vgt.id != R600_PIPE_STATE_VGT) {
rctx->vgt.id = R600_PIPE_STATE_VGT;
@@ -644,8 +644,10 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
rdraw.vgt_num_indices = draw.info.count;
rdraw.vgt_num_instances = draw.info.instance_count;
- rdraw.vgt_index_type = vgt_dma_index_type | (vgt_dma_swap_mode << 2);
- rdraw.vgt_draw_initiator = vgt_draw_initiator;
+ rdraw.vgt_index_type = ((draw.index_size == 4) ? 1 : 0);
+ if (R600_BIG_ENDIAN)
+ rdraw.vgt_index_type |= (draw.index_size >> 1) << 2;
+ rdraw.vgt_draw_initiator = draw.index_size ? 0 : 2;
rdraw.indices = NULL;
if (draw.index_buffer) {
rbuffer = (struct r600_resource*)draw.index_buffer;
diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h
index 5418570756f..eb6fb6594b2 100644
--- a/src/gallium/drivers/r600/r600_state_inlines.h
+++ b/src/gallium/drivers/r600/r600_state_inlines.h
@@ -319,6 +319,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
return V_0280A0_SWAP_STD;
case PIPE_FORMAT_R16_UNORM:
+ case PIPE_FORMAT_R16_FLOAT:
return V_0280A0_SWAP_STD;
/* 32-bit buffers. */
@@ -423,6 +424,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
case PIPE_FORMAT_R16_UNORM:
return V_0280A0_COLOR_16;
+ case PIPE_FORMAT_R16_FLOAT:
+ return V_0280A0_COLOR_16_FLOAT;
+
/* 32-bit buffers. */
case PIPE_FORMAT_A8B8G8R8_SRGB:
case PIPE_FORMAT_A8B8G8R8_UNORM:
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 470d26e2c9f..8e75d847dc5 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -243,10 +243,11 @@ static void r600_setup_miptree(struct pipe_screen *screen,
struct radeon *radeon = (struct radeon *)screen->winsys;
enum chip_class chipc = r600_get_family_class(radeon);
unsigned size, layer_size, i, offset;
- unsigned nblocksx, nblocksy;
+ unsigned nblocksx, nblocksy, extra_size = 0;
for (i = 0, offset = 0; i <= ptex->last_level; i++) {
unsigned blocksize = util_format_get_blocksize(ptex->format);
+ unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
r600_texture_set_array_mode(screen, rtex, i, array_mode);
@@ -265,9 +266,13 @@ static void r600_setup_miptree(struct pipe_screen *screen,
else
size = layer_size * ptex->array_size;
+ /* evergreen stores depth and stencil separately */
+ if ((chipc >= EVERGREEN) && util_format_is_depth_or_stencil(ptex->format))
+ extra_size = align(extra_size + (nblocksx * nblocksy * 1), base_align);
+
/* align base image and start of miptree */
if ((i == 0) || (i == 1))
- offset = align(offset, r600_get_base_alignment(screen, ptex->format, array_mode));
+ offset = align(offset, base_align);
rtex->offset[i] = offset;
rtex->layer_size[i] = layer_size;
rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */
@@ -275,7 +280,7 @@ static void r600_setup_miptree(struct pipe_screen *screen,
offset += size;
}
- rtex->size = offset;
+ rtex->size = offset + extra_size;
}
/* Figure out whether u_blitter will fallback to a transfer operation.
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 6373572b65f..f6eec24cc05 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -2556,6 +2556,9 @@
#define S_009508_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 0)
#define G_009508_DISABLE_CUBE_WRAP(x) (((x) >> 0) & 0x1)
#define C_009508_DISABLE_CUBE_WRAP 0xFFFFFFFE
+#define S_009508_DISABLE_CUBE_ANISO(x) (((x) & 0x1) << 1)
+#define G_009508_DISABLE_CUBE_ANISO(x) (((x) >> 1) & 0x1)
+#define C_009508_DISABLE_CUBE_ANISO (~(1 << 1))
#define S_009508_SYNC_GRADIENT(x) (((x) & 0x1) << 24)
#define G_009508_SYNC_GRADIENT(x) (((x) >> 24) & 0x1)
#define C_009508_SYNC_GRADIENT 0xFEFFFFFF
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index dbbc249258d..cfb1b9d8d0d 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -207,6 +207,14 @@ void svga_context_flush( struct svga_context *svga,
svga->curr.nr_fbs = 0;
+ /* Flush the upload managers to ensure recycling of upload buffers
+ * without throttling. This should really be conditioned on
+ * pipe_buffer_map_range not supporting PIPE_TRANSFER_UNSYNCHRONIZED.
+ */
+
+ u_upload_flush(svga->upload_vb);
+ u_upload_flush(svga->upload_ib);
+
/* Ensure that texture dma uploads are processed
* before submitting commands.
*/
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index eca529d262e..34b9e85c1a3 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -372,9 +372,6 @@ struct svga_context
/** List of buffers with queued transfers */
struct list_head dirty_buffers;
-
- /** Was the previous draw done with the SW path? */
- boolean prev_draw_swtnl;
};
/* A flag for each state_tracker state object:
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index d8af615ede1..aa096692888 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -145,7 +145,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
unsigned i;
/* Unmap upload manager vertex buffers */
- u_upload_flush(svga->upload_vb);
+ u_upload_unmap(svga->upload_vb);
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]);
@@ -156,7 +156,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
}
/* Unmap upload manager index buffers */
- u_upload_flush(svga->upload_ib);
+ u_upload_unmap(svga->upload_ib);
for (i = 0; i < hwtnl->cmd.prim_count; i++) {
if (hwtnl->cmd.prim_ib[i]) {
@@ -242,6 +242,11 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
}
+void svga_hwtnl_set_index_bias( struct svga_hwtnl *hwtnl,
+ int index_bias)
+{
+ hwtnl->index_bias = index_bias;
+}
@@ -265,15 +270,16 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
unsigned size = vb ? vb->width0 : 0;
unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
- unsigned index_bias = range->indexBias;
+ int index_bias = (int) range->indexBias + hwtnl->index_bias;
unsigned width;
assert(vb);
assert(size);
assert(offset < size);
- assert(index_bias >= 0);
assert(min_index <= max_index);
- assert(offset + index_bias*stride < size);
+ if (index_bias >= 0) {
+ assert(offset + index_bias*stride < size);
+ }
if (min_index != ~0) {
assert(offset + (index_bias + min_index) * stride < size);
}
@@ -394,6 +400,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
hwtnl->cmd.max_index[hwtnl->cmd.prim_count] = max_index;
hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
+ hwtnl->cmd.prim[hwtnl->cmd.prim_count].indexBias += hwtnl->index_bias;
pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
hwtnl->cmd.prim_count++;
diff --git a/src/gallium/drivers/svga/svga_draw.h b/src/gallium/drivers/svga/svga_draw.h
index a2403d802be..1dac17421e1 100644
--- a/src/gallium/drivers/svga/svga_draw.h
+++ b/src/gallium/drivers/svga/svga_draw.h
@@ -79,5 +79,8 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
enum pipe_error
svga_hwtnl_flush( struct svga_hwtnl *hwtnl );
+void svga_hwtnl_set_index_bias( struct svga_hwtnl *hwtnl,
+ int index_bias);
+
#endif /* SVGA_DRAW_H_ */
diff --git a/src/gallium/drivers/svga/svga_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h
index ca658ac6745..8126f7ee23c 100644
--- a/src/gallium/drivers/svga/svga_draw_private.h
+++ b/src/gallium/drivers/svga/svga_draw_private.h
@@ -116,6 +116,13 @@ struct draw_cmd {
struct svga_hwtnl {
struct svga_context *svga;
struct u_upload_mgr *upload_ib;
+
+ /* Additional negative index bias due to partial buffer uploads
+ * This is compensated for in the offset associated with all
+ * vertex buffers.
+ */
+
+ int index_bias;
/* Flatshade information:
*/
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index 2093bcae101..d53edcb23c5 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -25,6 +25,7 @@
#include "svga_cmd.h"
+#include "util/u_format.h"
#include "util/u_inlines.h"
#include "util/u_prim.h"
#include "util/u_time.h"
@@ -37,6 +38,178 @@
#include "svga_state.h"
#include "svga_swtnl.h"
#include "svga_debug.h"
+#include "svga_resource_buffer.h"
+#include "util/u_upload_mgr.h"
+
+/**
+ * Determine the ranges to upload for the user-buffers referenced
+ * by the next draw command.
+ *
+ * TODO: It might be beneficial to support multiple ranges. In that case,
+ * the struct svga_buffer::uploaded member should be made an array or a
+ * list, since we need to account for the possibility that different ranges
+ * may be uploaded to different hardware buffers chosen by the utility
+ * upload manager.
+ */
+
+static void
+svga_user_buffer_range(struct svga_context *svga,
+ unsigned start,
+ unsigned count,
+ unsigned instance_count)
+{
+ const struct pipe_vertex_element *ve = svga->curr.velems->velem;
+ int i;
+
+ /*
+ * Release old uploaded range (if not done already) and
+ * initialize new ranges.
+ */
+
+ for (i=0; i < svga->curr.velems->count; i++) {
+ struct pipe_vertex_buffer *vb =
+ &svga->curr.vb[ve[i].vertex_buffer_index];
+
+ if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
+ struct svga_buffer *buffer = svga_buffer(vb->buffer);
+
+ pipe_resource_reference(&buffer->uploaded.buffer, NULL);
+ buffer->uploaded.start = ~0;
+ buffer->uploaded.end = 0;
+ }
+ }
+
+ for (i=0; i < svga->curr.velems->count; i++) {
+ struct pipe_vertex_buffer *vb =
+ &svga->curr.vb[ve[i].vertex_buffer_index];
+
+ if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
+ struct svga_buffer *buffer = svga_buffer(vb->buffer);
+ unsigned first, size;
+ unsigned instance_div = ve[i].instance_divisor;
+ unsigned elemSize = util_format_get_blocksize(ve[i].src_format);
+
+ svga->dirty |= SVGA_NEW_VBUFFER;
+
+ if (instance_div) {
+ first = ve[i].src_offset;
+ count = (instance_count + instance_div - 1) / instance_div;
+ size = vb->stride * (count - 1) + elemSize;
+ } else if (vb->stride) {
+ first = vb->stride * start + ve[i].src_offset;
+ size = vb->stride * (count - 1) + elemSize;
+ } else {
+ /* Only a single vertex!
+ * Upload with the largest vertex size the hw supports,
+ * if possible.
+ */
+ first = ve[i].src_offset;
+ size = MIN2(16, vb->buffer->width0);
+ }
+
+ buffer->uploaded.start = MIN2(buffer->uploaded.start, first);
+ buffer->uploaded.end = MAX2(buffer->uploaded.end, first + size);
+ }
+ }
+}
+
+/**
+ * svga_upload_user_buffers - upload parts of user buffers
+ *
+ * This function streams a part of a user buffer to hw and fills
+ * svga_buffer::uploaded with information on the upload.
+ */
+
+static int
+svga_upload_user_buffers(struct svga_context *svga,
+ unsigned start,
+ unsigned count,
+ unsigned instance_count)
+{
+ const struct pipe_vertex_element *ve = svga->curr.velems->velem;
+ unsigned i;
+ int ret;
+
+ svga_user_buffer_range(svga, start, count, instance_count);
+
+ for (i=0; i < svga->curr.velems->count; i++) {
+ struct pipe_vertex_buffer *vb =
+ &svga->curr.vb[ve[i].vertex_buffer_index];
+
+ if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
+ struct svga_buffer *buffer = svga_buffer(vb->buffer);
+ boolean flushed;
+
+ /*
+ * Check if already uploaded. Otherwise go ahead and upload.
+ */
+
+ if (buffer->uploaded.buffer)
+ continue;
+
+ ret = u_upload_buffer( svga->upload_vb,
+ 0,
+ buffer->uploaded.start,
+ buffer->uploaded.end - buffer->uploaded.start,
+ &buffer->b.b,
+ &buffer->uploaded.offset,
+ &buffer->uploaded.buffer,
+ &flushed);
+
+ if (ret)
+ return ret;
+
+ if (0)
+ debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d"
+ " sz %d\n",
+ __FUNCTION__,
+ i,
+ buffer,
+ buffer->uploaded.buffer,
+ buffer->uploaded.offset,
+ buffer->uploaded.start,
+ buffer->uploaded.end - buffer->uploaded.start);
+
+ vb->buffer_offset = buffer->uploaded.offset;
+ }
+ }
+
+ return PIPE_OK;
+}
+
+/**
+ * svga_release_user_upl_buffers - release uploaded parts of user buffers
+ *
+ * This function releases the hw copy of the uploaded fraction of the
+ * user-buffer. It's important to do this as soon as all draw calls
+ * affecting the uploaded fraction are issued, as this allows for
+ * efficient reuse of the hardware surface backing the uploaded fraction.
+ *
+ * svga_buffer::source_offset is set to 0, and svga_buffer::uploaded::buffer
+ * is set to 0.
+ */
+
+static void
+svga_release_user_upl_buffers(struct svga_context *svga)
+{
+ unsigned i;
+ unsigned nr;
+
+ nr = svga->curr.num_vertex_buffers;
+
+ for (i = 0; i < nr; ++i) {
+ struct pipe_vertex_buffer *vb = &svga->curr.vb[i];
+
+ if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
+ struct svga_buffer *buffer = svga_buffer(vb->buffer);
+
+ buffer->uploaded.start = ~0;
+ buffer->uploaded.end = 0;
+ if (buffer->uploaded.buffer)
+ pipe_resource_reference(&buffer->uploaded.buffer, NULL);
+ }
+ }
+}
@@ -50,6 +223,7 @@ retry_draw_range_elements( struct svga_context *svga,
unsigned prim,
unsigned start,
unsigned count,
+ unsigned instance_count,
boolean do_retry )
{
enum pipe_error ret = 0;
@@ -61,6 +235,10 @@ retry_draw_range_elements( struct svga_context *svga,
svga->curr.rast->templ.flatshade,
svga->curr.rast->templ.flatshade_first );
+ ret = svga_upload_user_buffers( svga, min_index + index_bias,
+ max_index - min_index + 1, instance_count );
+ if (ret != PIPE_OK)
+ goto retry;
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
if (ret)
@@ -84,7 +262,7 @@ retry:
index_buffer, index_size, index_bias,
min_index, max_index,
prim, start, count,
- FALSE );
+ instance_count, FALSE );
}
return ret;
@@ -96,6 +274,7 @@ retry_draw_arrays( struct svga_context *svga,
unsigned prim,
unsigned start,
unsigned count,
+ unsigned instance_count,
boolean do_retry )
{
enum pipe_error ret;
@@ -107,6 +286,11 @@ retry_draw_arrays( struct svga_context *svga,
svga->curr.rast->templ.flatshade,
svga->curr.rast->templ.flatshade_first );
+ ret = svga_upload_user_buffers( svga, start, count, instance_count );
+
+ if (ret != PIPE_OK)
+ goto retry;
+
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
if (ret)
goto retry;
@@ -127,6 +311,7 @@ retry:
prim,
start,
count,
+ instance_count,
FALSE );
}
@@ -141,18 +326,11 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
unsigned reduced_prim = u_reduced_prim( info->mode );
unsigned count = info->count;
enum pipe_error ret = 0;
+ boolean needed_swtnl;
if (!u_trim_pipe_prim( info->mode, &count ))
return;
- if (svga->state.sw.need_swtnl != svga->prev_draw_swtnl) {
- /* We're switching between SW and HW drawing. Do a flush to avoid
- * mixing HW and SW rendering with the same vertex buffer.
- */
- pipe->flush(pipe, NULL);
- svga->prev_draw_swtnl = svga->state.sw.need_swtnl;
- }
-
/*
* Mark currently bound target surfaces as dirty
* doesn't really matter if it is done before drawing.
@@ -167,6 +345,8 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
}
+ needed_swtnl = svga->state.sw.need_swtnl;
+
svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL );
#ifdef DEBUG
@@ -176,6 +356,20 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
#endif
if (svga->state.sw.need_swtnl) {
+ if (!needed_swtnl) {
+ /*
+ * We're switching from HW to SW TNL. SW TNL will require mapping all
+ * currently bound vertex buffers, some of which may already be
+ * referenced in the current command buffer as result of previous HW
+ * TNL. So flush now, to prevent the context to flush while a referred
+ * vertex buffer is mapped.
+ */
+
+ svga_context_flush(svga, NULL);
+ }
+
+ /* Avoid leaking the previous hwtnl bias to swtnl */
+ svga_hwtnl_set_index_bias( svga->hwtnl, 0 );
ret = svga_swtnl_draw_vbo( svga, info );
}
else {
@@ -194,6 +388,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
info->mode,
info->start + offset,
info->count,
+ info->instance_count,
TRUE );
}
else {
@@ -201,10 +396,13 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
info->mode,
info->start,
info->count,
+ info->instance_count,
TRUE );
}
}
+ svga_release_user_upl_buffers( svga );
+
if (SVGA_DEBUG & DEBUG_FLUSH) {
svga_hwtnl_flush_retry( svga );
svga_context_flush(svga, NULL);
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index 95032213fa5..ca8c8d1f5ea 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -129,6 +129,12 @@ struct svga_buffer
* is the relative offset within that buffer.
*/
unsigned offset;
+
+ /**
+ * Range of user buffer that is uploaded in @buffer at @offset.
+ */
+ unsigned start;
+ unsigned end;
} uploaded;
/**
@@ -193,7 +199,11 @@ svga_buffer(struct pipe_resource *buffer)
static INLINE boolean
svga_buffer_is_user_buffer( struct pipe_resource *buffer )
{
- return svga_buffer(buffer)->user;
+ if (buffer) {
+ return svga_buffer(buffer)->user;
+ } else {
+ return FALSE;
+ }
}
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 923958674b4..a657a8bc224 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -651,8 +651,6 @@ svga_redefine_user_buffer(struct pipe_context *pipe,
unsigned offset,
unsigned size)
{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_context *svga = svga_context(pipe);
struct svga_buffer *sbuf = svga_buffer(resource);
assert(sbuf->user);
@@ -661,19 +659,8 @@ svga_redefine_user_buffer(struct pipe_context *pipe,
assert(!sbuf->hwbuf);
/*
- * Release any uploaded user buffer.
- *
- * TODO: As an optimization, we could try to update the uploaded buffer
- * instead.
+ * We always treat the contents of user-buffers as volatile,
+ * so no particular action needed here.
*/
- pipe_resource_reference(&sbuf->uploaded.buffer, NULL);
-
- pipe_mutex_lock(ss->swc_mutex);
-
- sbuf->key.size.width = sbuf->b.b.width0 = offset + size;
-
- pipe_mutex_unlock(ss->swc_mutex);
-
- svga->dirty |= SVGA_NEW_VBUFFER | SVGA_NEW_VELEMENT;
}
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index 7c393a1da8d..47eab1a9739 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -38,57 +38,6 @@
#include "svga_hw_reg.h"
-static int
-upload_user_buffers( struct svga_context *svga )
-{
- enum pipe_error ret = PIPE_OK;
- int i;
- int nr;
-
- if (0)
- debug_printf("%s: %d\n", __FUNCTION__, svga->curr.num_vertex_buffers);
-
- nr = svga->curr.num_vertex_buffers;
-
- for (i = 0; i < nr; i++)
- {
- if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
- {
- struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
-
- if (!buffer->uploaded.buffer) {
- boolean flushed;
- ret = u_upload_buffer( svga->upload_vb,
- 0, 0,
- buffer->b.b.width0,
- &buffer->b.b,
- &buffer->uploaded.offset,
- &buffer->uploaded.buffer,
- &flushed);
- if (ret)
- return ret;
-
- if (0)
- debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
- __FUNCTION__,
- i,
- buffer,
- buffer->uploaded.buffer,
- buffer->uploaded.offset,
- buffer->b.b.width0);
- }
-
- svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
- }
- }
-
- if (0)
- debug_printf("%s: DONE\n", __FUNCTION__);
-
- return ret;
-}
-
-
/***********************************************************************
*/
@@ -99,6 +48,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
const struct pipe_vertex_element *ve = svga->curr.velems->velem;
SVGA3dVertexDecl decl;
unsigned i;
+ unsigned neg_bias = 0;
assert(svga->curr.velems->count >=
svga->curr.vs->base.info.file_count[TGSI_FILE_INPUT]);
@@ -106,12 +56,50 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
svga_hwtnl_reset_vdecl( svga->hwtnl,
svga->curr.velems->count );
+ /**
+ * We can't set the VDECL offset to something negative, so we
+ * must calculate a common negative additional index bias, and modify
+ * the VDECL offsets accordingly so they *all* end up positive.
+ *
+ * Note that the exact value of the negative index bias is not that
+ * important, since we compensate for it when we calculate the vertex
+ * buffer offset below. The important thing is that all vertex buffer
+ * offsets remain positive.
+ *
+ * Note that we use a negative bias variable in order to make the
+ * rounding maths more easy to follow, and to avoid int / unsigned
+ * confusion.
+ */
+
for (i = 0; i < svga->curr.velems->count; i++) {
- const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index];
+ const struct pipe_vertex_buffer *vb =
+ &svga->curr.vb[ve[i].vertex_buffer_index];
+ struct svga_buffer *buffer;
+ unsigned int offset = vb->buffer_offset + ve[i].src_offset;
+ unsigned tmp_neg_bias = 0;
+
+ if (!vb->buffer)
+ continue;
+
+ buffer = svga_buffer(vb->buffer);
+ if (buffer->uploaded.start > offset) {
+ tmp_neg_bias = buffer->uploaded.start - offset;
+ if (vb->stride)
+ tmp_neg_bias = (tmp_neg_bias + vb->stride - 1) / vb->stride;
+ neg_bias = MAX2(neg_bias, tmp_neg_bias);
+ }
+ }
+
+ for (i = 0; i < svga->curr.velems->count; i++) {
+ const struct pipe_vertex_buffer *vb =
+ &svga->curr.vb[ve[i].vertex_buffer_index];
unsigned usage, index;
- struct svga_buffer *buffer = svga_buffer(vb->buffer);
+ struct svga_buffer *buffer;
+ if (!vb->buffer)
+ continue;
+ buffer= svga_buffer(vb->buffer);
svga_generate_vdecl_semantics( i, &usage, &index );
/* SVGA_NEW_VELEMENT
@@ -121,8 +109,16 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
decl.identity.usage = usage;
decl.identity.usageIndex = index;
decl.array.stride = vb->stride;
- decl.array.offset = (vb->buffer_offset +
- ve[i].src_offset);
+
+ /* Compensate for partially uploaded vbo, and
+ * for the negative index bias.
+ */
+ decl.array.offset = (vb->buffer_offset
+ + ve[i].src_offset
+ + neg_bias * vb->stride
+ - buffer->uploaded.start);
+
+ assert(decl.array.offset >= 0);
svga_hwtnl_vdecl( svga->hwtnl,
i,
@@ -131,6 +127,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
vb->buffer );
}
+ svga_hwtnl_set_index_bias( svga->hwtnl, -neg_bias );
return 0;
}
@@ -138,23 +135,11 @@ static int emit_hw_vs_vdecl( struct svga_context *svga,
static int emit_hw_vdecl( struct svga_context *svga,
unsigned dirty )
{
- int ret = 0;
-
/* SVGA_NEW_NEED_SWTNL
*/
if (svga->state.sw.need_swtnl)
return 0; /* Do not emit during swtnl */
- /* If we get to here, we know that we're going to draw. Upload
- * userbuffers now and try to combine multiple userbuffers from
- * multiple draw calls into a single host buffer for performance.
- */
- if (svga->curr.any_user_vertex_buffers) {
- ret = upload_user_buffers( svga );
- if (ret)
- return ret;
- }
-
return emit_hw_vs_vdecl( svga, dirty );
}
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index 40f6f2bcb5f..eea3d79e64b 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -134,8 +134,6 @@
#error Unknown Endianness
#endif
-#if !defined(PIPE_OS_EMBEDDED)
-
/*
* Auto-detect the operating system family.
*
@@ -222,7 +220,5 @@
#endif
#endif /* PIPE_OS_WINDOWS */
-#endif /* !PIPE_OS_EMBEDDED */
-
#endif /* P_CONFIG_H_ */
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index 04fc7c6c5de..f7cc2437747 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -253,6 +253,12 @@ struct st_context_attribs
struct st_framebuffer_iface
{
/**
+ * Atomic stamp which changes when framebuffers need to be updated.
+ */
+
+ int32_t stamp;
+
+ /**
* Available for the state tracker manager to use.
*/
void *st_manager_private;
@@ -315,25 +321,6 @@ struct st_context_iface
void (*destroy)(struct st_context_iface *stctxi);
/**
- * Invalidate the current textures that was taken from a framebuffer.
- *
- * The state tracker manager calls this function to let the rendering
- * context know that it should update the textures it got from
- * st_framebuffer_iface::validate. It should do so at the latest time possible.
- * Possible right before sending triangles to the pipe context.
- *
- * For certain platforms this function might be called from a thread other
- * than the thread that the context is currently bound in, and must
- * therefore be thread safe. But it is the state tracker manager's
- * responsibility to make sure that the framebuffer is bound to the context
- * and the API context is current for the duration of this call.
- *
- * Thus reducing the sync primitive needed to a single atomic flag.
- */
- void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi,
- struct st_framebuffer_iface *stfbi);
-
- /**
* Flush all drawing from context to the pipe also flushes the pipe.
*/
void (*flush)(struct st_context_iface *stctxi, unsigned flags,
diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
index 741a97f897d..0bb9d852f84 100644
--- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
+++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp
@@ -250,21 +250,21 @@ struct GalliumDXGIAdapter
DXGI_ADAPTER_DESC1 desc;
std::vector<ComPtr<IDXGIOutput> > outputs;
int num_outputs;
- struct native_event_handler handler;
GalliumDXGIAdapter(GalliumDXGIFactory* factory, const struct native_platform* platform, void* dpy)
{
this->parent = factory;
- /* FIXME handler should be static */
- handler.invalid_surface = handle_invalid_surface;
- handler.new_drm_screen = dxgi_loader_create_drm_screen;
- handler.new_sw_screen = dxgi_loader_create_sw_screen;
- platform->set_event_handler(&handler);
-
- display = platform->create_display(dpy, FALSE, this);
+ display = platform->create_display(dpy, FALSE);
if(!display)
- display = platform->create_display(dpy, TRUE, this);
+ display = platform->create_display(dpy, TRUE);
+ if (display) {
+ display->user_data = this;
+ if (!display->init_screen(display)) {
+ display->destroy(display);
+ display = NULL;
+ }
+ }
if(!display)
throw E_FAIL;
memset(&desc, 0, sizeof(desc));
@@ -1413,6 +1413,11 @@ struct dxgi_binding
static dxgi_binding dxgi_default_binding;
static __thread dxgi_binding dxgi_thread_binding;
+static const struct native_event_handler dxgi_event_handler = {
+ GalliumDXGIAdapter::handle_invalid_surface,
+ dxgi_loader_create_drm_screen,
+ dxgi_loader_create_sw_screen
+};
void STDMETHODCALLTYPE GalliumDXGIUseNothing()
{
@@ -1427,7 +1432,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseNothing()
void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBackend* backend)
{
GalliumDXGIUseNothing();
- dxgi_thread_binding.platform = native_get_x11_platform();
+ dxgi_thread_binding.platform = native_get_x11_platform(&dxgi_event_handler);
dxgi_thread_binding.display = dpy;
if(backend)
@@ -1443,7 +1448,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseX11Display(Display* dpy, IGalliumDXGIBacken
void STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd)
{
GalliumDXGIUseNothing();
- dxgi_thread_binding.platform = native_get_drm_platform();
+ dxgi_thread_binding.platform = native_get_drm_platform(&dxgi_event_handler);
dxgi_thread_binding.display = (void*)fd;
dxgi_thread_binding.backend = 0;
}
@@ -1453,7 +1458,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseDRMCard(int fd)
void STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd)
{
GalliumDXGIUseNothing();
- dxgi_thread_binding.platform = native_get_fbdev_platform();
+ dxgi_thread_binding.platform = native_get_fbdev_platform(&dxgi_event_handler);
dxgi_thread_binding.display = (void*)fd;
dxgi_thread_binding.backend = 0;
}
@@ -1463,7 +1468,7 @@ void STDMETHODCALLTYPE GalliumDXGIUseFBDev(int fd)
void STDMETHODCALLTYPE GalliumDXGIUseHDC(HDC hdc, PFNHWNDRESOLVER resolver, void* resolver_cookie)
{
GalliumDXGIUseNothing();
- dxgi_thread_binding.platform = native_get_gdi_platform();
+ dxgi_thread_binding.platform = native_get_gdi_platform(&dxgi_event_handler);
dxgi_thread_binding.display = (void*)hdc;
dxgi_thread_binding.backend = 0;
}
@@ -1493,7 +1498,7 @@ void STDMETHODCALLTYPE GalliumDXGIMakeDefault()
else if(dxgi_default_binding.platform)
factory = new GalliumDXGIFactory(dxgi_default_binding.platform, dxgi_default_binding.display, dxgi_default_binding.backend);
else
- factory = new GalliumDXGIFactory(native_get_x11_platform(), NULL, NULL);
+ factory = new GalliumDXGIFactory(native_get_x11_platform(&dxgi_event_handler), NULL, NULL);
HRESULT hres = factory->QueryInterface(riid, out_factory);
factory->Release();
return hres;
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index e23c1bcafaf..08bbdf96e34 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -151,8 +151,6 @@ dri_unbind_context(__DRIcontext * cPriv)
if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
stapi->make_current(stapi, NULL, NULL, NULL);
- draw->context = NULL;
- read->context = NULL;
}
}
@@ -180,12 +178,10 @@ dri_make_current(__DRIcontext * cPriv,
else if (!driDrawPriv || !driReadPriv)
return GL_FALSE;
- draw->context = ctx;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
- read->context = ctx;
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
read->texture_stamp = driReadPriv->lastStamp - 1;
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index 28a33ac7d07..7b8de3174be 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -136,6 +136,7 @@ dri_create_buffer(__DRIscreen * sPriv,
drawable->sPriv = sPriv;
drawable->dPriv = dPriv;
dPriv->driverPrivate = (void *)drawable;
+ p_atomic_set(&drawable->base.stamp, 1);
return GL_TRUE;
fail:
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 7f1aa512ca1..fd3460dd30b 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -42,7 +42,6 @@ struct dri_drawable
struct st_visual stvis;
struct dri_screen *screen;
- struct dri_context *context;
/* dri */
__DRIdrawable *dPriv;
diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript
index b188f76f910..c63918a0e18 100644
--- a/src/gallium/state_trackers/dri/drm/SConscript
+++ b/src/gallium/state_trackers/dri/drm/SConscript
@@ -5,7 +5,7 @@ Import('*')
env = env.Clone()
-env.ParseConfig('pkg-config --cflags --libs libdrm')
+env.PkgUseModules(['DRM'])
env.Append(CPPPATH = [
'#/src/mapi',
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index e471e8e5be2..fe4ddb312be 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -52,13 +52,11 @@ static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
- struct dri_context *ctx = drawable->context;
dri2InvalidateDrawable(dPriv);
drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
- if (ctx)
- ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
+ p_atomic_inc(&drawable->base.stamp);
}
static const __DRI2flushExtension dri2FlushExtension = {
@@ -564,6 +562,24 @@ dri2_query_image(__DRIimage *image, int attrib, int *value)
}
}
+static __DRIimage *
+dri2_dup_image(__DRIimage *image, void *loaderPrivate)
+{
+ __DRIimage *img;
+
+ img = CALLOC_STRUCT(__DRIimageRec);
+ if (!img)
+ return NULL;
+
+ img->texture = NULL;
+ pipe_resource_reference(&img->texture, image->texture);
+ img->level = image->level;
+ img->layer = image->layer;
+ img->loader_private = loaderPrivate;
+
+ return img;
+}
+
static void
dri2_destroy_image(__DRIimage *img)
{
@@ -578,6 +594,7 @@ static struct __DRIimageExtensionRec dri2ImageExtension = {
dri2_destroy_image,
dri2_create_image,
dri2_query_image,
+ dri2_dup_image,
};
/*
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index ac11f7c47f6..a1879a8f46a 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -103,14 +103,11 @@ drisw_present_texture(__DRIdrawable *dPriv,
static INLINE void
drisw_invalidate_drawable(__DRIdrawable *dPriv)
{
- struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
struct dri_drawable *drawable = dri_drawable(dPriv);
drawable->texture_stamp = dPriv->lastStamp - 1;
- /* check if swapping currently bound buffer */
- if (ctx && ctx->dPriv == dPriv)
- ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
+ p_atomic_inc(&drawable->base.stamp);
}
static INLINE void
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 763e7b58a49..1c970222c1f 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -33,7 +33,8 @@ wayland_INCLUDES = \
wayland_SOURCES = $(wildcard wayland/*.c)
wayland_OBJECTS = $(wayland_SOURCES:.c=.o)
-drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm)
+drm_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm) \
+ -I$(TOP)/src/gbm/main -I$(TOP)/src/gallium/state_trackers/gbm
drm_SOURCES = $(wildcard drm/*.c)
drm_OBJECTS = $(drm_SOURCES:.c=.o)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
index 9ade76ecbb2..c04fec637c1 100644
--- a/src/gallium/state_trackers/egl/SConscript
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -40,7 +40,12 @@ else:
env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING'])
sources.append(['#/src/glx/dri2.c'])
if env['drm']:
+ env.PkgUseModules('DRM')
env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND'])
+ env.Append(CPPPATH = [
+ '#/src/gbm/main',
+ '#/src/gallium/state_trackers/gbm',
+ ])
sources.append(['drm/native_drm.c', 'drm/modeset.c'])
st_egl = env.ConvenienceLibrary(
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 29dbbefbf48..6649f02b244 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -31,6 +31,7 @@
#include "util/u_memory.h"
#include "util/u_format.h"
#include "util/u_string.h"
+#include "util/u_atomic.h"
#include "egl_g3d.h"
#include "egl_g3d_api.h"
@@ -45,15 +46,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx;
-
- /*
- * Some functions such as egl_g3d_copy_buffers create a temporary native
- * surface. There is no gsurf associated with it.
- */
- gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
- if (gctx)
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
+
+ if (gsurf && gsurf->stfbi)
+ p_atomic_inc(&gsurf->stfbi->stamp);
}
static struct pipe_screen *
@@ -72,10 +67,26 @@ egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
return gdpy->loader->create_sw_screen(ws);
}
-static struct native_event_handler egl_g3d_native_event_handler = {
+static struct pipe_resource *
+egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct st_egl_image img;
+ struct pipe_resource *resource = NULL;
+
+ memset(&img, 0, sizeof(img));
+ if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
+ resource = img.texture;
+
+ return resource;
+}
+
+static const struct native_event_handler egl_g3d_native_event_handler = {
egl_g3d_invalid_surface,
egl_g3d_new_drm_screen,
- egl_g3d_new_sw_screen
+ egl_g3d_new_sw_screen,
+ egl_g3d_lookup_egl_image
};
/**
@@ -94,40 +105,38 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
case _EGL_PLATFORM_WINDOWS:
plat_name = "Windows";
#ifdef HAVE_GDI_BACKEND
- nplat = native_get_gdi_platform();
+ nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_X11:
plat_name = "X11";
#ifdef HAVE_X11_BACKEND
- nplat = native_get_x11_platform();
+ nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_WAYLAND:
plat_name = "wayland";
#ifdef HAVE_WAYLAND_BACKEND
- nplat = native_get_wayland_platform();
+ nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_DRM:
plat_name = "DRM";
#ifdef HAVE_DRM_BACKEND
- nplat = native_get_drm_platform();
+ nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
#endif
break;
case _EGL_PLATFORM_FBDEV:
plat_name = "FBDEV";
#ifdef HAVE_FBDEV_BACKEND
- nplat = native_get_fbdev_platform();
+ nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
#endif
break;
default:
break;
}
- if (nplat)
- nplat->set_event_handler(&egl_g3d_native_event_handler);
- else
+ if (!nplat)
_eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
gdrv->platforms[plat] = nplat;
@@ -504,13 +513,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
gdpy->loader = gdrv->loader;
dpy->DriverData = gdpy;
- _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
- gdpy->native = nplat->create_display(dpy->PlatformDisplay,
- dpy->Options.UseFallback, (void *) dpy);
+ _eglLog(_EGL_INFO, "use %s for display %p",
+ nplat->name, dpy->PlatformDisplay);
+ gdpy->native =
+ nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
+ gdpy->native->user_data = (void *) dpy;
+ if (!gdpy->native->init_screen(gdpy->native)) {
+ _eglError(EGL_NOT_INITIALIZED,
+ "eglInitialize(failed to initialize screen)");
+ goto fail;
+ }
if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
dpy->ClientAPIs |= EGL_OPENGL_BIT;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 301db3128ff..5989a023573 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -126,4 +126,12 @@ _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
#endif /* EGL_MESA_screen_surface */
+static INLINE struct st_api *
+egl_g3d_get_st_api(_EGLDriver *drv, enum st_api_type api)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+
+ return gdrv->loader->get_st_api(api);
+}
+
#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 8b1821e0055..f897054a540 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -37,7 +37,6 @@
#include "egl_g3d_image.h"
#include "egl_g3d_sync.h"
#include "egl_g3d_st.h"
-#include "egl_g3d_loader.h"
#include "native.h"
/**
@@ -47,7 +46,6 @@ static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
enum st_profile_type *profile)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct st_api *stapi;
EGLint api = -1;
@@ -81,96 +79,66 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx,
break;
}
- switch (api) {
- case ST_API_OPENGL:
- stapi = gdrv->loader->guess_gl_api(*profile);
- break;
- case ST_API_OPENVG:
- stapi = gdrv->loader->get_st_api(api);
- break;
- default:
- stapi = NULL;
- break;
- }
+ stapi = egl_g3d_get_st_api(drv, api);
if (stapi && !(stapi->profile_mask & (1 << *profile)))
stapi = NULL;
return stapi;
}
+struct egl_g3d_choose_config_data {
+ _EGLConfig criteria;
+ enum pipe_format format;
+};
+
static int
egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2,
void *priv_data)
{
- const _EGLConfig *criteria = (const _EGLConfig *) priv_data;
+ struct egl_g3d_choose_config_data *data =
+ (struct egl_g3d_choose_config_data *) priv_data;
+ const _EGLConfig *criteria = &data->criteria;;
/* EGL_NATIVE_VISUAL_TYPE ignored? */
return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
}
static EGLBoolean
-egl_g3d_match_config(const _EGLConfig *conf, const _EGLConfig *criteria)
+egl_g3d_match_config(const _EGLConfig *conf, void *priv_data)
{
- if (!_eglMatchConfig(conf, criteria))
- return EGL_FALSE;
-
- if (criteria->MatchNativePixmap != EGL_NONE &&
- criteria->MatchNativePixmap != EGL_DONT_CARE) {
- struct egl_g3d_display *gdpy = egl_g3d_display(conf->Display);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- EGLNativePixmapType pix =
- (EGLNativePixmapType) criteria->MatchNativePixmap;
+ struct egl_g3d_choose_config_data *data =
+ (struct egl_g3d_choose_config_data *) priv_data;
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
- if (!gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
- return EGL_FALSE;
- }
+ if (data->format != PIPE_FORMAT_NONE &&
+ data->format != gconf->native->color_format)
+ return EGL_FALSE;
- return EGL_TRUE;
+ return _eglMatchConfig(conf, &data->criteria);
}
static EGLBoolean
egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
EGLConfig *configs, EGLint size, EGLint *num_configs)
{
- _EGLConfig **tmp_configs, criteria;
- EGLint tmp_size, i;
-
- if (!num_configs)
- return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
+ struct egl_g3d_choose_config_data data;
- if (!_eglParseConfigAttribList(&criteria, dpy, attribs))
+ if (!_eglParseConfigAttribList(&data.criteria, dpy, attribs))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
- /* get the number of matched configs */
- tmp_size = _eglFilterArray(dpy->Configs, NULL, 0,
- (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
- if (!tmp_size) {
- *num_configs = tmp_size;
- return EGL_TRUE;
- }
-
- tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size);
- if (!tmp_configs)
- return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
+ data.format = PIPE_FORMAT_NONE;
+ if (data.criteria.MatchNativePixmap != EGL_NONE &&
+ data.criteria.MatchNativePixmap != EGL_DONT_CARE) {
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- /* get the matched configs */
- _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size,
- (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
-
- /* perform sorting of configs */
- if (configs && tmp_size) {
- _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
- egl_g3d_compare_config, (void *) &criteria);
- tmp_size = MIN2(tmp_size, size);
- for (i = 0; i < tmp_size; i++)
- configs[i] = _eglGetConfigHandle(tmp_configs[i]);
+ if (!gdpy->native->get_pixmap_format(gdpy->native,
+ (EGLNativePixmapType) data.criteria.MatchNativePixmap,
+ &data.format))
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglChooseConfig");
}
- FREE(tmp_configs);
-
- *num_configs = tmp_size;
-
- return EGL_TRUE;
+ return _eglFilterConfigArray(dpy->Configs, configs, size, num_configs,
+ egl_g3d_match_config, egl_g3d_compare_config, &data);
}
static _EGLContext *
@@ -536,19 +504,12 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
(gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
if (gdraw) {
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
- gdraw->stfbi);
-
if (gdraw->base.Type == EGL_WINDOW_BIT) {
gctx->base.WindowRenderBuffer =
(gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
}
}
- if (gread && gread != gdraw) {
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
- gread->stfbi);
- }
}
}
else if (old_gctx) {
@@ -614,21 +575,6 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
gsurf->base.SwapInterval);
}
-/**
- * Get the pipe surface of the given attachment of the native surface.
- */
-static struct pipe_resource *
-get_pipe_resource(struct native_display *ndpy, struct native_surface *nsurf,
- enum native_attachment natt)
-{
- struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
-
- textures[natt] = NULL;
- nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
-
- return textures[natt];
-}
-
static EGLBoolean
egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLNativePixmapType target)
@@ -636,43 +582,18 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
_EGLContext *ctx = _eglGetCurrentContext();
- struct native_surface *nsurf;
- struct pipe_resource *ptex;
- struct pipe_context *pipe;
if (!gsurf->render_texture)
return EGL_TRUE;
- nsurf = gdpy->native->create_pixmap_surface(gdpy->native, target, NULL);
- 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->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL);
}
- pipe = ndpy_get_copy_context(gdpy->native);
- if (!pipe)
- return EGL_FALSE;
-
- ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
- if (ptex) {
- struct pipe_box src_box;
-
- u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
- pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0,
- gsurf->render_texture, 0, &src_box);
- pipe->flush(pipe, NULL);
- nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
-
- pipe_resource_reference(&ptex, NULL);
- }
-
- nsurf->destroy(nsurf);
-
- return EGL_TRUE;
+ return gdpy->native->copy_to_pixmap(gdpy->native,
+ target, gsurf->render_texture);
}
static EGLBoolean
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index ce72e27c3d5..7e9a29b0284 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -37,9 +37,6 @@
#include "egl_g3d.h"
#include "egl_g3d_image.h"
-/* for struct winsys_handle */
-#include "state_tracker/drm_driver.h"
-
/**
* Reference and return the front left buffer of the native pixmap.
*/
@@ -137,10 +134,9 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
_EGLImage *img, const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct pipe_resource templ;
- struct winsys_handle wsh;
_EGLImageAttribs attrs;
EGLint format;
+ struct native_buffer nbuf;
if (!dpy->Extensions.MESA_drm_image)
return NULL;
@@ -166,21 +162,21 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
break;
}
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.format = format;
- templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
- templ.width0 = attrs.Width;
- templ.height0 = attrs.Height;
- templ.depth0 = 1;
- templ.array_size = 1;
-
- memset(&wsh, 0, sizeof(wsh));
- wsh.handle = (unsigned) name;
- wsh.stride =
- attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format);
-
- return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh);
+ memset(&nbuf, 0, sizeof(nbuf));
+ nbuf.type = NATIVE_BUFFER_DRM;
+ nbuf.u.drm.templ.target = PIPE_TEXTURE_2D;
+ nbuf.u.drm.templ.format = format;
+ nbuf.u.drm.templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ nbuf.u.drm.templ.width0 = attrs.Width;
+ nbuf.u.drm.templ.height0 = attrs.Height;
+ nbuf.u.drm.templ.depth0 = 1;
+ nbuf.u.drm.templ.array_size = 1;
+
+ nbuf.u.drm.name = name;
+ nbuf.u.drm.stride =
+ attrs.DRMBufferStrideMESA * util_format_get_blocksize(format);
+
+ return gdpy->native->buffer->import_buffer(gdpy->native, &nbuf);
}
#endif /* EGL_MESA_drm_image */
@@ -327,35 +323,26 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_image *gimg = egl_g3d_image(img);
- struct winsys_handle wsh;
+ struct native_buffer nbuf;
if (!dpy->Extensions.MESA_drm_image)
return EGL_FALSE;
- /* get shared handle */
- if (name) {
- memset(&handle, 0, sizeof(handle));
- wsh.type = DRM_API_HANDLE_TYPE_SHARED;
- if (!gdpy->native->buffer->export_buffer(gdpy->native,
- gimg->texture, &wsh))
- return EGL_FALSE;
+ memset(&nbuf, 0, sizeof(nbuf));
+ nbuf.type = NATIVE_BUFFER_DRM;
+ if (name)
+ nbuf.u.drm.templ.bind |= PIPE_BIND_SHARED;
- *name = wsh.handle;
- }
+ if (!gdpy->native->buffer->export_buffer(gdpy->native,
+ gimg->texture, &nbuf))
+ return EGL_FALSE;
- /* get KMS handle */
- if (handle || stride) {
- memset(&wsh, 0, sizeof(wsh));
- wsh.type = DRM_API_HANDLE_TYPE_KMS;
- if (!gdpy->native->buffer->export_buffer(gdpy->native,
- gimg->texture, &wsh))
- return EGL_FALSE;
-
- if (handle)
- *handle = wsh.handle;
- if (stride)
- *stride = wsh.stride;
- }
+ if (name)
+ *name = nbuf.u.drm.name;
+ if (handle)
+ *handle = nbuf.u.drm.handle;
+ if (stride)
+ *stride = nbuf.u.drm.stride;
return EGL_TRUE;
}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
index 78bfe2131ef..e9403fa293b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
@@ -39,7 +39,6 @@ struct sw_winsys;
struct egl_g3d_loader {
uint profile_masks[ST_API_COUNT];
struct st_api *(*get_st_api)(enum st_api_type api);
- struct st_api *(*guess_gl_api)(enum st_profile_type profile);
struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index 2b944b521a4..60c3e332ac9 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -292,6 +292,8 @@ egl_g3d_create_st_framebuffer(_EGLSurface *surf)
return NULL;
stfbi->visual = &gsurf->stvis;
+ p_atomic_set(&stfbi->stamp, 1);
+
if (gsurf->base.Type != EGL_PBUFFER_BIT) {
stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
stfbi->validate = egl_g3d_st_framebuffer_validate;
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 8646e52ed7c..fc50ee485fe 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -152,6 +152,11 @@ struct native_display {
*/
void *user_data;
+ /**
+ * Initialize and create the pipe screen.
+ */
+ boolean (*init_screen)(struct native_display *ndpy);
+
void (*destroy)(struct native_display *ndpy);
/**
@@ -170,16 +175,21 @@ struct native_display {
int *num_configs);
/**
- * Test if a pixmap is supported by the given config. Required unless no
- * config has 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.
+ * Get the color format of the pixmap. Required unless no config has
+ * pixmap_bit set.
*/
- boolean (*is_pixmap_supported)(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf);
+ boolean (*get_pixmap_format)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format);
+ /**
+ * Copy the contents of the resource to the pixmap's front-left attachment.
+ * This is used to implement eglCopyBuffers. Required unless no config has
+ * pixmap_bit set.
+ */
+ boolean (*copy_to_pixmap)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src);
/**
* Create a window surface. Required unless no config has window_bit set.
@@ -219,6 +229,9 @@ struct native_event_handler {
const char *name, int fd);
struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy,
struct sw_winsys *ws);
+
+ struct pipe_resource *(*lookup_egl_image)(struct native_display *ndpy,
+ void *egl_image);
};
/**
@@ -256,26 +269,29 @@ ndpy_uninit(struct native_display *ndpy)
struct native_platform {
const char *name;
- void (*set_event_handler)(struct native_event_handler *handler);
- struct native_display *(*create_display)(void *dpy,
- boolean use_sw,
- void *user_data);
+ /**
+ * Create the native display and usually establish a connection to the
+ * display server.
+ *
+ * No event should be generated at this stage.
+ */
+ struct native_display *(*create_display)(void *dpy, boolean use_sw);
};
const struct native_platform *
-native_get_gdi_platform(void);
+native_get_gdi_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_x11_platform(void);
+native_get_x11_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_wayland_platform(void);
+native_get_wayland_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_drm_platform(void);
+native_get_drm_platform(const struct native_event_handler *event_handler);
const struct native_platform *
-native_get_fbdev_platform(void);
+native_get_fbdev_platform(const struct native_event_handler *event_handler);
#ifdef __cplusplus
}
diff --git a/src/gallium/state_trackers/egl/common/native_buffer.h b/src/gallium/state_trackers/egl/common/native_buffer.h
index 5c29ab97411..b8a66d17e12 100644
--- a/src/gallium/state_trackers/egl/common/native_buffer.h
+++ b/src/gallium/state_trackers/egl/common/native_buffer.h
@@ -30,30 +30,43 @@
#define _NATIVE_BUFFER_H_
#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
struct native_display;
-struct pipe_resource;
+
+enum native_buffer_type {
+ NATIVE_BUFFER_DRM,
+
+ NUM_NATIVE_BUFFERS
+};
+
+struct native_buffer {
+ enum native_buffer_type type;
+
+ union {
+ struct {
+ struct pipe_resource templ;
+ unsigned name; /**< the name of the GEM object */
+ unsigned handle; /**< the handle of the GEM object */
+ unsigned stride;
+ } drm;
+ } u;
+};
/**
* Buffer interface of the native display. It allows native buffers to be
* imported and exported.
- *
- * Just like a native window or a native pixmap, a native buffer is another
- * native type. Its definition depends on the native display.
- *
- * For DRM platform, the type of a native buffer is struct winsys_handle.
*/
struct native_display_buffer {
struct pipe_resource *(*import_buffer)(struct native_display *ndpy,
- const struct pipe_resource *templ,
- void *buf);
+ struct native_buffer *buf);
/**
* The resource must be creatred with PIPE_BIND_SHARED.
*/
boolean (*export_buffer)(struct native_display *ndpy,
struct pipe_resource *res,
- void *buf);
+ struct native_buffer *nbuf);
};
#endif /* _NATIVE_BUFFER_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
index ee18cb2025b..cca1e1c6295 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -282,9 +282,9 @@ resource_surface_copy_swap(struct resource_surface *rsurf,
btex, 0, &src_box);
ret = TRUE;
- out_no_ftex:
- pipe_resource_reference(&btex, NULL);
out_no_btex:
+ pipe_resource_reference(&btex, NULL);
+ out_no_ftex:
pipe_resource_reference(&ftex, NULL);
return ret;
@@ -367,3 +367,116 @@ resource_surface_wait(struct resource_surface *rsurf)
{
while (resource_surface_throttle(rsurf));
}
+
+boolean
+native_display_copy_to_pixmap(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src)
+{
+ struct pipe_context *pipe;
+ struct native_surface *nsurf;
+ struct pipe_resource *dst;
+ struct pipe_resource *tmp[NUM_NATIVE_ATTACHMENTS];
+ const enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ pipe = ndpy_get_copy_context(ndpy);
+ if (!pipe)
+ return FALSE;
+
+ nsurf = ndpy->create_pixmap_surface(ndpy, pix, NULL);
+ if (!nsurf)
+ return FALSE;
+
+ /* get the texutre */
+ tmp[natt] = NULL;
+ nsurf->validate(nsurf, 1 << natt, NULL, tmp, NULL, NULL);
+ dst = tmp[natt];
+
+ if (dst && dst->format == src->format) {
+ struct pipe_box src_box;
+
+ u_box_origin_2d(src->width0, src->height0, &src_box);
+ pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &src_box);
+ pipe->flush(pipe, NULL);
+ nsurf->present(nsurf, natt, FALSE, 0);
+ }
+
+ if (dst)
+ pipe_resource_reference(&dst, NULL);
+
+ nsurf->destroy(nsurf);
+
+ return TRUE;
+}
+
+#include "state_tracker/drm_driver.h"
+struct pipe_resource *
+drm_display_import_native_buffer(struct native_display *ndpy,
+ struct native_buffer *nbuf)
+{
+ struct pipe_screen *screen = ndpy->screen;
+ struct pipe_resource *res = NULL;
+
+ switch (nbuf->type) {
+ case NATIVE_BUFFER_DRM:
+ {
+ struct winsys_handle wsh;
+
+ memset(&wsh, 0, sizeof(wsh));
+ wsh.handle = nbuf->u.drm.name;
+ wsh.stride = nbuf->u.drm.stride;
+
+ res = screen->resource_from_handle(screen, &nbuf->u.drm.templ, &wsh);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+boolean
+drm_display_export_native_buffer(struct native_display *ndpy,
+ struct pipe_resource *res,
+ struct native_buffer *nbuf)
+{
+ struct pipe_screen *screen = ndpy->screen;
+ boolean ret = FALSE;
+
+ switch (nbuf->type) {
+ case NATIVE_BUFFER_DRM:
+ {
+ struct winsys_handle wsh;
+
+ if ((nbuf->u.drm.templ.bind & res->bind) != nbuf->u.drm.templ.bind)
+ break;
+
+ memset(&wsh, 0, sizeof(wsh));
+ wsh.type = DRM_API_HANDLE_TYPE_KMS;
+ if (!screen->resource_get_handle(screen, res, &wsh))
+ break;
+
+ nbuf->u.drm.handle = wsh.handle;
+ nbuf->u.drm.stride = wsh.stride;
+
+ /* get the name of the GEM object */
+ if (nbuf->u.drm.templ.bind & PIPE_BIND_SHARED) {
+ memset(&wsh, 0, sizeof(wsh));
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
+ if (!screen->resource_get_handle(screen, res, &wsh))
+ break;
+
+ nbuf->u.drm.name = wsh.handle;
+ }
+
+ nbuf->u.drm.templ = *res;
+ ret = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h
index 39564a04365..e8d91ccb02a 100644
--- a/src/gallium/state_trackers/egl/common/native_helper.h
+++ b/src/gallium/state_trackers/egl/common/native_helper.h
@@ -105,3 +105,17 @@ resource_surface_flush(struct resource_surface *rsurf,
*/
void
resource_surface_wait(struct resource_surface *rsurf);
+
+boolean
+native_display_copy_to_pixmap(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src);
+
+struct pipe_resource *
+drm_display_import_native_buffer(struct native_display *ndpy,
+ struct native_buffer *nbuf);
+
+boolean
+drm_display_export_native_buffer(struct native_display *ndpy,
+ struct pipe_resource *res,
+ struct native_buffer *nbuf);
diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c
index 3fff9540905..73968d1343b 100644
--- a/src/gallium/state_trackers/egl/drm/modeset.c
+++ b/src/gallium/state_trackers/egl/drm/modeset.c
@@ -290,6 +290,42 @@ drm_display_create_surface(struct native_display *ndpy,
return drmsurf;
}
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource)
+{
+ struct drm_display *drmdpy = drm_display(ndpy);
+ struct drm_surface *drmsurf;
+ enum native_attachment natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ drmsurf = CALLOC_STRUCT(drm_surface);
+ if (!drmsurf)
+ return NULL;
+
+ drmsurf->drmdpy = drmdpy;
+ drmsurf->color_format = resource->format;
+ drmsurf->width = resource->width0;
+ drmsurf->height = resource->height0;
+ drmsurf->have_pageflip = FALSE;
+
+ drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
+ drmsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+
+ resource_surface_import_resource(drmsurf->rsurf, natt, resource);
+
+ drmsurf->base.destroy = drm_surface_destroy;
+ drmsurf->base.present = drm_surface_present;
+ drmsurf->base.validate = drm_surface_validate;
+ drmsurf->base.wait = drm_surface_wait;
+
+ return &drmsurf->base;
+}
+
+
/**
* Choose a CRTC that supports all given connectors.
*/
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index 725fe28e4e2..47910de8d3c 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -33,6 +33,8 @@
#include "native_drm.h"
+#include "gbm_gallium_drmint.h"
+
#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif
@@ -125,6 +127,8 @@ drm_display_destroy(struct native_display *ndpy)
drm_display_fini_modeset(&drmdpy->base);
+ /* gbm owns screen */
+ ndpy->screen = NULL;
ndpy_uninit(ndpy);
if (drmdpy->device_name)
@@ -136,54 +140,10 @@ drm_display_destroy(struct native_display *ndpy)
FREE(drmdpy);
}
-/**
- * Initialize KMS and pipe screen.
- */
-static boolean
-drm_display_init_screen(struct native_display *ndpy)
-{
- struct drm_display *drmdpy = drm_display(ndpy);
- drmVersionPtr version;
-
- version = drmGetVersion(drmdpy->fd);
- if (!version) {
- _eglLog(_EGL_WARNING, "invalid fd %d", drmdpy->fd);
- return FALSE;
- }
-
- drmdpy->base.screen =
- drmdpy->event_handler->new_drm_screen(&drmdpy->base, NULL, drmdpy->fd);
- drmFreeVersion(version);
-
- if (!drmdpy->base.screen) {
- _eglLog(_EGL_DEBUG, "failed to create DRM screen");
- return FALSE;
- }
-
- return TRUE;
-}
-
-static struct pipe_resource *
-drm_display_import_buffer(struct native_display *ndpy,
- const struct pipe_resource *templ,
- void *buf)
-{
- return ndpy->screen->resource_from_handle(ndpy->screen,
- templ, (struct winsys_handle *) buf);
-}
-
-static boolean
-drm_display_export_buffer(struct native_display *ndpy,
- struct pipe_resource *res,
- void *buf)
-{
- return ndpy->screen->resource_get_handle(ndpy->screen,
- res, (struct winsys_handle *) buf);
-}
-
static struct native_display_buffer drm_display_buffer = {
- drm_display_import_buffer,
- drm_display_export_buffer
+ /* use the helpers */
+ drm_display_import_native_buffer,
+ drm_display_export_native_buffer
};
static int
@@ -281,9 +241,25 @@ static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
#endif /* HAVE_WAYLAND_BACKEND */
+static struct native_surface *
+drm_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct gbm_gallium_drm_bo *bo = (void *) pix;
+
+ return drm_display_create_surface_from_resource(ndpy, bo->resource);
+}
+
+static boolean
+drm_display_init_screen(struct native_display *ndpy)
+{
+ return TRUE;
+}
+
static struct native_display *
-drm_create_display(int fd, struct native_event_handler *event_handler,
- void *user_data)
+drm_create_display(struct gbm_gallium_drm_device *gbmdrm,
+ const struct native_event_handler *event_handler)
{
struct drm_display *drmdpy;
@@ -291,20 +267,24 @@ drm_create_display(int fd, struct native_event_handler *event_handler,
if (!drmdpy)
return NULL;
- drmdpy->fd = fd;
- drmdpy->device_name = drm_get_device_name(fd);
+ drmdpy->fd = gbmdrm->base.base.fd;
+ drmdpy->device_name = drm_get_device_name(drmdpy->fd);
+
+ gbmdrm->lookup_egl_image = (struct pipe_resource *(*)(void *, void *))
+ event_handler->lookup_egl_image;
+ gbmdrm->lookup_egl_image_data = &drmdpy->base;
+
drmdpy->event_handler = event_handler;
- drmdpy->base.user_data = user_data;
- if (!drm_display_init_screen(&drmdpy->base)) {
- drm_display_destroy(&drmdpy->base);
- return NULL;
- }
+ drmdpy->base.screen = gbmdrm->screen;
+ drmdpy->base.init_screen = drm_display_init_screen;
drmdpy->base.destroy = drm_display_destroy;
drmdpy->base.get_param = drm_display_get_param;
drmdpy->base.get_configs = drm_display_get_configs;
+ drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface;
+
drmdpy->base.buffer = &drm_display_buffer;
#ifdef HAVE_WAYLAND_BACKEND
if (drmdpy->device_name)
@@ -315,39 +295,39 @@ drm_create_display(int fd, struct native_event_handler *event_handler,
return &drmdpy->base;
}
-static struct native_event_handler *drm_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- drm_event_handler = event_handler;
-}
+static const struct native_event_handler *drm_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
+ struct gbm_gallium_drm_device *gbm;
int fd;
- if (dpy) {
- fd = dup((int) pointer_to_intptr(dpy));
- }
- else {
+ gbm = dpy;
+
+ if (gbm == NULL) {
fd = open("/dev/dri/card0", O_RDWR);
+ gbm = gbm_gallium_drm_device(gbm_create_device(fd));
}
- if (fd < 0)
+
+ if (gbm == NULL)
+ return NULL;
+
+ if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 ||
+ gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM)
return NULL;
- return drm_create_display(fd, drm_event_handler, user_data);
+ return drm_create_display(gbm, drm_event_handler);
}
static const struct native_platform drm_platform = {
"DRM", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_drm_platform(void)
+native_get_drm_platform(const struct native_event_handler *event_handler)
{
+ drm_event_handler = event_handler;
return &drm_platform;
}
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 41cdc4f9d04..675a58a1922 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -50,7 +50,7 @@ struct drm_surface;
struct drm_display {
struct native_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
int fd;
char *device_name;
@@ -154,4 +154,8 @@ drm_display_init_modeset(struct native_display *ndpy);
void
drm_display_fini_modeset(struct native_display *ndpy);
+struct native_surface *
+drm_display_create_surface_from_resource(struct native_display *ndpy,
+ struct pipe_resource *resource);
+
#endif /* _NATIVE_DRM_H_ */
diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
index e2fde00e975..6772d379f73 100644
--- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
+++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c
@@ -26,6 +26,21 @@
* Chia-I Wu <olv@lunarg.com>
*/
+/**
+ * Considering fbdev as an in-kernel window system,
+ *
+ * - opening a device opens a connection
+ * - there is only one window: the framebuffer
+ * - fb_var_screeninfo decides window position, size, and even color format
+ * - there is no pixmap
+ *
+ * Now EGL is built on top of this window system. So we should have
+ *
+ * - the fd as the handle of the native display
+ * - reject all but one native window: NULL
+ * - no pixmap support
+ */
+
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -45,16 +60,13 @@ struct fbdev_display {
struct native_display base;
int fd;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct fb_fix_screeninfo finfo;
- struct fb_var_screeninfo vinfo;
-
+ struct fb_var_screeninfo config_vinfo;
struct native_config config;
- struct native_connector connector;
- struct native_mode mode;
- struct fbdev_surface *current_surface;
+ boolean assume_fixed_vinfo;
};
struct fbdev_surface {
@@ -66,7 +78,7 @@ struct fbdev_surface {
unsigned int sequence_number;
- boolean is_current;
+ struct fbdev_sw_drawable drawable;
};
static INLINE struct fbdev_display *
@@ -103,38 +115,70 @@ fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask,
return TRUE;
}
-static boolean
-fbdev_surface_flush_frontbuffer(struct native_surface *nsurf)
+static enum pipe_format
+vinfo_to_format(const struct fb_var_screeninfo *vinfo)
{
- struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
+ enum pipe_format format = PIPE_FORMAT_NONE;
- if (!fbsurf->is_current)
- return TRUE;
+ /* should also check channel offsets... */
+ switch (vinfo->bits_per_pixel) {
+ case 32:
+ if (vinfo->red.length == 8 &&
+ vinfo->green.length == 8 &&
+ vinfo->blue.length == 8) {
+ format = (vinfo->transp.length == 8) ?
+ PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
+ }
+ break;
+ case 16:
+ if (vinfo->red.length == 5 &&
+ vinfo->green.length == 6 &&
+ vinfo->blue.length == 5 &&
+ vinfo->transp.length == 0)
+ format = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ default:
+ break;
+ }
- return resource_surface_present(fbsurf->rsurf,
- NATIVE_ATTACHMENT_FRONT_LEFT, NULL);
+ return format;
}
static boolean
-fbdev_surface_swap_buffers(struct native_surface *nsurf)
+fbdev_surface_update_drawable(struct native_surface *nsurf,
+ const struct fb_var_screeninfo *vinfo)
{
struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
- struct fbdev_display *fbdpy = fbsurf->fbdpy;
- boolean ret = TRUE;
-
- if (fbsurf->is_current) {
- ret = resource_surface_present(fbsurf->rsurf,
- NATIVE_ATTACHMENT_BACK_LEFT, NULL);
+ unsigned x, y, width, height;
+
+ x = vinfo->xoffset;
+ y = vinfo->yoffset;
+ width = MIN2(vinfo->xres, fbsurf->width);
+ height = MIN2(vinfo->yres, fbsurf->height);
+
+ /* sanitize the values */
+ if (x + width > vinfo->xres_virtual) {
+ if (x > vinfo->xres_virtual)
+ width = 0;
+ else
+ width = vinfo->xres_virtual - x;
+ }
+ if (y + height > vinfo->yres_virtual) {
+ if (y > vinfo->yres_virtual)
+ height = 0;
+ else
+ height = vinfo->yres_virtual - y;
}
- resource_surface_swap_buffers(fbsurf->rsurf,
- NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
- /* the front/back textures are swapped */
- fbsurf->sequence_number++;
- fbdpy->event_handler->invalid_surface(&fbdpy->base,
- &fbsurf->base, fbsurf->sequence_number);
+ fbsurf->drawable.format = vinfo_to_format(vinfo);
+ fbsurf->drawable.x = vinfo->xoffset;
+ fbsurf->drawable.y = vinfo->yoffset;
+ fbsurf->drawable.width = vinfo->xres;
+ fbsurf->drawable.height = vinfo->yres;
- return ret;
+ return (fbsurf->drawable.format != PIPE_FORMAT_NONE &&
+ fbsurf->drawable.width &&
+ fbsurf->drawable.height);
}
static boolean
@@ -143,21 +187,43 @@ fbdev_surface_present(struct native_surface *nsurf,
boolean preserve,
uint swap_interval)
{
- boolean ret;
+ struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
+ struct fbdev_display *fbdpy = fbsurf->fbdpy;
+ boolean ret = FALSE;
- if (preserve || swap_interval)
+ if (swap_interval)
+ return FALSE;
+ if (natt != NATIVE_ATTACHMENT_BACK_LEFT)
return FALSE;
- switch (natt) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- ret = fbdev_surface_flush_frontbuffer(nsurf);
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- ret = fbdev_surface_swap_buffers(nsurf);
- break;
- default:
- ret = FALSE;
- break;
+ if (!fbdpy->assume_fixed_vinfo) {
+ struct fb_var_screeninfo vinfo;
+
+ memset(&vinfo, 0, sizeof(vinfo));
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo))
+ return FALSE;
+
+ /* present the surface */
+ if (fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
+ ret = resource_surface_present(fbsurf->rsurf,
+ natt, (void *) &fbsurf->drawable);
+ }
+
+ fbsurf->width = vinfo.xres;
+ fbsurf->height = vinfo.yres;
+
+ if (resource_surface_set_size(fbsurf->rsurf,
+ fbsurf->width, fbsurf->height)) {
+ /* surface resized */
+ fbsurf->sequence_number++;
+ fbdpy->event_handler->invalid_surface(&fbdpy->base,
+ &fbsurf->base, fbsurf->sequence_number);
+ }
+ }
+ else {
+ /* the drawable never changes */
+ ret = resource_surface_present(fbsurf->rsurf,
+ natt, (void *) &fbsurf->drawable);
}
return ret;
@@ -179,26 +245,48 @@ fbdev_surface_destroy(struct native_surface *nsurf)
}
static struct native_surface *
-fbdev_display_create_scanout_surface(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height)
+fbdev_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
struct fbdev_surface *fbsurf;
+ struct fb_var_screeninfo vinfo;
+
+ /* there is only one native window: NULL */
+ if (win)
+ return NULL;
fbsurf = CALLOC_STRUCT(fbdev_surface);
if (!fbsurf)
return NULL;
fbsurf->fbdpy = fbdpy;
- fbsurf->width = width;
- fbsurf->height = height;
+
+ /* get current vinfo */
+ if (fbdpy->assume_fixed_vinfo) {
+ vinfo = fbdpy->config_vinfo;
+ }
+ else {
+ memset(&vinfo, 0, sizeof(vinfo));
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &vinfo)) {
+ FREE(fbsurf);
+ return NULL;
+ }
+ }
+
+ fbsurf->width = vinfo.xres;
+ fbsurf->height = vinfo.yres;
+
+ if (!fbdev_surface_update_drawable(&fbsurf->base, &vinfo)) {
+ FREE(fbsurf);
+ return NULL;
+ }
fbsurf->rsurf = resource_surface_create(fbdpy->base.screen,
nconf->color_format,
PIPE_BIND_RENDER_TARGET |
- PIPE_BIND_DISPLAY_TARGET |
- PIPE_BIND_SCANOUT);
+ PIPE_BIND_DISPLAY_TARGET);
if (!fbsurf->rsurf) {
FREE(fbsurf);
return NULL;
@@ -214,42 +302,43 @@ fbdev_display_create_scanout_surface(struct native_display *ndpy,
return &fbsurf->base;
}
+static struct native_surface *
+fbdev_display_create_scanout_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ return fbdev_display_create_window_surface(ndpy,
+ (EGLNativeWindowType) NULL, nconf);
+}
+
static boolean
fbdev_display_program(struct native_display *ndpy, int crtc_idx,
struct native_surface *nsurf, uint x, uint y,
const struct native_connector **nconns, int num_nconns,
const struct native_mode *nmode)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
-
- if (x || y)
- return FALSE;
-
- if (fbdpy->current_surface) {
- if (fbdpy->current_surface == fbsurf)
- return TRUE;
- fbdpy->current_surface->is_current = FALSE;
- }
-
- if (fbsurf)
- fbsurf->is_current = TRUE;
- fbdpy->current_surface = fbsurf;
-
return TRUE;
}
static const struct native_mode **
fbdev_display_get_modes(struct native_display *ndpy,
- const struct native_connector *nconn,
- int *num_modes)
+ const struct native_connector *nconn,
+ int *num_modes)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ static struct native_mode mode;
const struct native_mode **modes;
+ if (!mode.desc) {
+ struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ mode.desc = "Current Mode";
+ mode.width = fbdpy->config_vinfo.xres;
+ mode.height = fbdpy->config_vinfo.yres;
+ mode.refresh_rate = 60 * 1000; /* dummy */
+ }
+
modes = MALLOC(sizeof(*modes));
if (modes) {
- modes[0] = &fbdpy->mode;
+ modes[0] = &mode;
if (num_modes)
*num_modes = 1;
}
@@ -261,12 +350,12 @@ static const struct native_connector **
fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
int *num_crtc)
{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
+ static struct native_connector connector;
const struct native_connector **connectors;
connectors = MALLOC(sizeof(*connectors));
if (connectors) {
- connectors[0] = &fbdpy->connector;
+ connectors[0] = &connector;
if (num_connectors)
*num_connectors = 1;
}
@@ -274,7 +363,8 @@ fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
return connectors;
}
-static struct native_display_modeset fbdev_display_modeset = {
+/* remove modeset support one day! */
+static const struct native_display_modeset fbdev_display_modeset = {
.get_connectors = fbdev_display_get_connectors,
.get_modes = fbdev_display_get_modes,
.create_scanout_surface = fbdev_display_create_scanout_surface,
@@ -304,8 +394,10 @@ fbdev_display_get_param(struct native_display *ndpy,
int val;
switch (param) {
- case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_PRESERVE_BUFFER:
+ val = 1;
+ break;
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
case NATIVE_PARAM_MAX_SWAP_INTERVAL:
default:
val = 0;
@@ -326,114 +418,55 @@ fbdev_display_destroy(struct native_display *ndpy)
}
static boolean
-fbdev_display_init_modes(struct native_display *ndpy)
+fbdev_display_init_screen(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct native_mode *nmode = &fbdpy->mode;
-
- nmode->desc = "Current Mode";
- nmode->width = fbdpy->vinfo.xres;
- nmode->height = fbdpy->vinfo.yres;
- nmode->refresh_rate = 60 * 1000; /* dummy */
-
- return TRUE;
-}
-
-static boolean
-fbdev_display_init_connectors(struct native_display *ndpy)
-{
- return TRUE;
-}
+ struct sw_winsys *ws;
-static enum pipe_format
-vinfo_to_format(const struct fb_var_screeninfo *vinfo)
-{
- enum pipe_format format = PIPE_FORMAT_NONE;
+ ws = fbdev_create_sw_winsys(fbdpy->fd);
+ if (!ws)
+ return FALSE;
- switch (vinfo->bits_per_pixel) {
- case 32:
- if (vinfo->red.length == 8 &&
- vinfo->green.length == 8 &&
- vinfo->blue.length == 8) {
- format = (vinfo->transp.length == 8) ?
- PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
- }
- break;
- case 16:
- if (vinfo->red.length == 5 &&
- vinfo->green.length == 6 &&
- vinfo->blue.length == 5 &&
- vinfo->transp.length == 0)
- format = PIPE_FORMAT_B5G6R5_UNORM;
- break;
- default:
- break;
+ fbdpy->base.screen = fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
+ if (!fbdpy->base.screen) {
+ if (ws->destroy)
+ ws->destroy(ws);
+ return FALSE;
}
- return format;
-}
-
-static boolean
-fbdev_display_init_configs(struct native_display *ndpy)
-{
- struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct native_config *nconf = &fbdpy->config;
-
- nconf->color_format = vinfo_to_format(&fbdpy->vinfo);
- if (nconf->color_format == PIPE_FORMAT_NONE)
+ if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
+ fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_RENDER_TARGET)) {
+ fbdpy->base.screen->destroy(fbdpy->base.screen);
+ fbdpy->base.screen = NULL;
return FALSE;
-
- nconf->buffer_mask =
- (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
- (1 << NATIVE_ATTACHMENT_BACK_LEFT);
-
- nconf->scanout_bit = TRUE;
+ }
return TRUE;
}
static boolean
-fbdev_display_init(struct native_display *ndpy)
+fbdev_display_init_config(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
- struct sw_winsys *ws;
-
- if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
- return FALSE;
+ struct native_config *nconf = &fbdpy->config;
- if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->vinfo))
+ if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->config_vinfo))
return FALSE;
- if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
- fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
+ nconf->color_format = vinfo_to_format(&fbdpy->config_vinfo);
+ if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
- if (!fbdev_display_init_configs(&fbdpy->base) ||
- !fbdev_display_init_connectors(&fbdpy->base) ||
- !fbdev_display_init_modes(&fbdpy->base))
- return FALSE;
+ nconf->buffer_mask = (1 << NATIVE_ATTACHMENT_BACK_LEFT);
- ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
- if (ws) {
- fbdpy->base.screen =
- fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
- }
+ nconf->window_bit = TRUE;
- if (fbdpy->base.screen) {
- if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
- fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET)) {
- fbdpy->base.screen->destroy(fbdpy->base.screen);
- fbdpy->base.screen = NULL;
- }
- }
-
- return (fbdpy->base.screen != NULL);
+ return TRUE;
}
static struct native_display *
-fbdev_display_create(int fd, struct native_event_handler *event_handler,
- void *user_data)
+fbdev_display_create(int fd, const struct native_event_handler *event_handler)
{
struct fbdev_display *fbdpy;
@@ -443,32 +476,41 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler,
fbdpy->fd = fd;
fbdpy->event_handler = event_handler;
- fbdpy->base.user_data = user_data;
- if (!fbdev_display_init(&fbdpy->base)) {
- FREE(fbdpy);
- return NULL;
- }
+ if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
+ goto fail;
+
+ if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
+ fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
+ goto fail;
+
+ if (!fbdev_display_init_config(&fbdpy->base))
+ goto fail;
+ fbdpy->assume_fixed_vinfo = TRUE;
+
+ fbdpy->base.init_screen = fbdev_display_init_screen;
fbdpy->base.destroy = fbdev_display_destroy;
fbdpy->base.get_param = fbdev_display_get_param;
fbdpy->base.get_configs = fbdev_display_get_configs;
+ fbdpy->base.create_window_surface = fbdev_display_create_window_surface;
+
+ /* we'd like to remove modeset support one day */
+ fbdpy->config.scanout_bit = TRUE;
fbdpy->base.modeset = &fbdev_display_modeset;
return &fbdpy->base;
-}
-static struct native_event_handler *fbdev_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- fbdev_event_handler = event_handler;
+fail:
+ FREE(fbdpy);
+ return NULL;
}
+static const struct native_event_handler *fbdev_event_handler;
+
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy;
int fd;
@@ -483,7 +525,7 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
if (fd < 0)
return NULL;
- ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data);
+ ndpy = fbdev_display_create(fd, fbdev_event_handler);
if (!ndpy)
close(fd);
@@ -492,12 +534,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
static const struct native_platform fbdev_platform = {
"FBDEV", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_fbdev_platform(void)
+native_get_fbdev_platform(const struct native_event_handler *event_handler)
{
+ fbdev_event_handler = event_handler;
return &fbdev_platform;
}
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
index 5d0045f92ee..6bf0d4e4668 100644
--- a/src/gallium/state_trackers/egl/gdi/native_gdi.c
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -41,7 +41,7 @@ struct gdi_display {
struct native_display base;
HDC hDC;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct native_config *configs;
int num_configs;
@@ -368,35 +368,39 @@ gdi_display_destroy(struct native_display *ndpy)
FREE(gdpy);
}
-static struct native_display *
-gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
- void *user_data)
+static boolean
+gdi_display_init_screen(struct native_display *ndpy)
{
- struct gdi_display *gdpy;
+ struct gdi_display *gdpy = gdi_display(ndpy);
struct sw_winsys *winsys;
- gdpy = CALLOC_STRUCT(gdi_display);
- if (!gdpy)
- return NULL;
-
- gdpy->hDC = hDC;
- gdpy->event_handler = event_handler;
- gdpy->base.user_data = user_data;
-
winsys = gdi_create_sw_winsys();
- if (!winsys) {
- FREE(gdpy);
- return NULL;
- }
+ if (!winsys)
+ return FALSE;
gdpy->base.screen = gdpy->event_handler->new_sw_screen(&gdpy->base, winsys);
if (!gdpy->base.screen) {
if (winsys->destroy)
winsys->destroy(winsys);
- FREE(gdpy);
- return NULL;
+ return FALSE;
}
+ return TRUE;
+}
+
+static struct native_display *
+gdi_create_display(HDC hDC, const struct native_event_handler *event_handler)
+{
+ struct gdi_display *gdpy;
+
+ gdpy = CALLOC_STRUCT(gdi_display);
+ if (!gdpy)
+ return NULL;
+
+ gdpy->hDC = hDC;
+ gdpy->event_handler = event_handler;
+
+ gdpy->base.init_screen = gdi_display_init_screen;
gdpy->base.destroy = gdi_display_destroy;
gdpy->base.get_param = gdi_display_get_param;
@@ -406,28 +410,22 @@ gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
return &gdpy->base;
}
-static struct native_event_handler *gdi_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- gdi_event_handler = event_handler;
-}
+static const struct native_event_handler *gdi_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
- return gdi_create_display((HDC) dpy, gdi_event_handler, user_data);
+ return gdi_create_display((HDC) dpy, gdi_event_handler);
}
static const struct native_platform gdi_platform = {
"GDI", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_gdi_platform(void)
+native_get_gdi_platform(const struct native_event_handler *event_handler)
{
+ gdi_event_handler = event_handler;
return &gdi_platform;
}
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index a9fd30319eb..e34b24b58b1 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -51,7 +51,7 @@
struct wayland_drm_display {
struct wayland_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct wl_drm *wl_drm;
struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
@@ -212,27 +212,10 @@ wayland_drm_display_init_screen(struct native_display *ndpy)
return TRUE;
}
-static struct pipe_resource *
-wayland_drm_display_import_buffer(struct native_display *ndpy,
- const struct pipe_resource *templ,
- void *buf)
-{
- return ndpy->screen->resource_from_handle(ndpy->screen,
- templ, (struct winsys_handle *) buf);
-}
-
-static boolean
-wayland_drm_display_export_buffer(struct native_display *ndpy,
- struct pipe_resource *res,
- void *buf)
-{
- return ndpy->screen->resource_get_handle(ndpy->screen,
- res, (struct winsys_handle *) buf);
-}
-
static struct native_display_buffer wayland_drm_display_buffer = {
- wayland_drm_display_import_buffer,
- wayland_drm_display_export_buffer
+ /* use the helpers */
+ drm_display_import_native_buffer,
+ drm_display_export_native_buffer
};
static int
@@ -302,8 +285,7 @@ static struct native_display_wayland_bufmgr wayland_drm_display_wayland_bufmgr =
struct wayland_display *
wayland_create_drm_display(struct wl_display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct wayland_drm_display *drmdpy;
@@ -312,7 +294,6 @@ wayland_create_drm_display(struct wl_display *dpy,
return NULL;
drmdpy->event_handler = event_handler;
- drmdpy->base.base.user_data = user_data;
drmdpy->base.dpy = dpy;
if (!drmdpy->base.dpy) {
@@ -320,10 +301,7 @@ wayland_create_drm_display(struct wl_display *dpy,
return NULL;
}
- if (!wayland_drm_display_init_screen(&drmdpy->base.base)) {
- wayland_drm_display_destroy(&drmdpy->base.base);
- return NULL;
- }
+ drmdpy->base.base.init_screen = wayland_drm_display_init_screen;
drmdpy->base.base.destroy = wayland_drm_display_destroy;
drmdpy->base.base.buffer = &wayland_drm_display_buffer;
drmdpy->base.base.wayland_bufmgr = &wayland_drm_display_wayland_bufmgr;
diff --git a/src/gallium/state_trackers/egl/wayland/native_shm.c b/src/gallium/state_trackers/egl/wayland/native_shm.c
index 8614a761abf..1c0799528fe 100644
--- a/src/gallium/state_trackers/egl/wayland/native_shm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_shm.c
@@ -47,7 +47,7 @@
struct wayland_shm_display {
struct wayland_display base;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct wl_shm *wl_shm;
};
@@ -144,8 +144,7 @@ wayland_shm_display_init_screen(struct native_display *ndpy)
struct wayland_display *
wayland_create_shm_display(struct wl_display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct wayland_shm_display *shmdpy;
@@ -154,7 +153,6 @@ wayland_create_shm_display(struct wl_display *dpy,
return NULL;
shmdpy->event_handler = event_handler;
- shmdpy->base.base.user_data = user_data;
shmdpy->base.dpy = dpy;
if (!shmdpy->base.dpy) {
@@ -162,11 +160,7 @@ wayland_create_shm_display(struct wl_display *dpy,
return NULL;
}
- if (!wayland_shm_display_init_screen(&shmdpy->base.base)) {
- wayland_shm_display_destroy(&shmdpy->base.base);
- return NULL;
- }
-
+ shmdpy->base.base.init_screen = wayland_shm_display_init_screen;
shmdpy->base.base.destroy = wayland_shm_display_destroy;
shmdpy->base.create_buffer = wayland_create_shm_buffer;
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
index 3d1bb6ff8b1..544d4be215a 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -35,7 +35,7 @@
#include "native_wayland.h"
-static struct native_event_handler *wayland_event_handler;
+static const struct native_event_handler *wayland_event_handler;
static void
sync_callback(void *data)
@@ -114,11 +114,12 @@ wayland_display_get_param(struct native_display *ndpy,
}
static boolean
-wayland_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+wayland_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
/* all wl_egl_pixmaps are supported */
+ *format = PIPE_FORMAT_NONE;
return TRUE;
}
@@ -195,13 +196,11 @@ wayland_window_surface_handle_resize(struct wayland_surface *surface)
wl_buffer_destroy(surface->buffer[i]);
surface->buffer[i] = NULL;
}
+
+ surface->dx = surface->win->dx;
+ surface->dy = surface->win->dy;
}
pipe_resource_reference(&front_resource, NULL);
-
- surface->dx = surface->win->dx;
- surface->dy = surface->win->dy;
- surface->win->dx = 0;
- surface->win->dy = 0;
}
static boolean
@@ -449,14 +448,8 @@ wayland_create_window_surface(struct native_display *ndpy,
return &surface->base;
}
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- wayland_event_handler = event_handler;
-}
-
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct wayland_display *display = NULL;
boolean own_dpy = FALSE;
@@ -473,12 +466,10 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
if (use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
display = wayland_create_shm_display((struct wl_display *) dpy,
- wayland_event_handler,
- user_data);
+ wayland_event_handler);
} else {
display = wayland_create_drm_display((struct wl_display *) dpy,
- wayland_event_handler,
- user_data);
+ wayland_event_handler);
}
if (!display)
@@ -486,7 +477,8 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
display->base.get_param = wayland_display_get_param;
display->base.get_configs = wayland_display_get_configs;
- display->base.is_pixmap_supported = wayland_display_is_pixmap_supported;
+ display->base.get_pixmap_format = wayland_display_get_pixmap_format;
+ display->base.copy_to_pixmap = native_display_copy_to_pixmap;
display->base.create_window_surface = wayland_create_window_surface;
display->base.create_pixmap_surface = wayland_create_pixmap_surface;
@@ -497,13 +489,13 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
static const struct native_platform wayland_platform = {
"wayland", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_wayland_platform(void)
+native_get_wayland_platform(const struct native_event_handler *event_handler)
{
+ wayland_event_handler = event_handler;
return &wayland_platform;
}
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.h b/src/gallium/state_trackers/egl/wayland/native_wayland.h
index 81c7a8b4840..5390f2f08c9 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.h
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.h
@@ -103,11 +103,10 @@ wayland_config(const struct native_config *nconf)
struct wayland_display *
wayland_create_shm_display(struct wl_display *display,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
+
struct wayland_display *
wayland_create_drm_display(struct wl_display *display,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
#endif /* _NATIVE_WAYLAND_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index a56d43428fc..4b8be7bc759 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -38,6 +38,7 @@
#include "native_x11.h"
#include "x11_screen.h"
+#include "common/native_helper.h"
#ifdef HAVE_WAYLAND_BACKEND
#include "common/native_wayland_drm_bufmgr_helper.h"
#endif
@@ -49,7 +50,7 @@ struct dri2_display {
Display *dpy;
boolean own_dpy;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct x11_screen *xscr;
int xscr_number;
@@ -682,18 +683,30 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
}
static boolean
-dri2_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+dri2_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
- uint depth, nconf_depth;
+ boolean ret = EGL_TRUE;
+ uint depth;
depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
- nconf_depth = util_format_get_blocksizebits(nconf->color_format);
+ switch (depth) {
+ case 32:
+ case 24:
+ *format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 16:
+ *format = PIPE_FORMAT_B5G6R5_UNORM;
+ break;
+ default:
+ *format = PIPE_FORMAT_NONE;
+ ret = EGL_FALSE;
+ break;
+ }
- /* simple depth match for now */
- return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
+ return ret;
}
static int
@@ -870,8 +883,7 @@ static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = {
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct dri2_display *dri2dpy;
@@ -880,7 +892,6 @@ x11_create_dri2_display(Display *dpy,
return NULL;
dri2dpy->event_handler = event_handler;
- dri2dpy->base.user_data = user_data;
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
@@ -899,11 +910,6 @@ x11_create_dri2_display(Display *dpy,
return NULL;
}
- if (!dri2_display_init_screen(&dri2dpy->base)) {
- dri2_display_destroy(&dri2dpy->base);
- return NULL;
- }
-
dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
dri2_display_hash_table_compare);
if (!dri2dpy->surfaces) {
@@ -911,10 +917,12 @@ x11_create_dri2_display(Display *dpy,
return NULL;
}
+ dri2dpy->base.init_screen = dri2_display_init_screen;
dri2dpy->base.destroy = dri2_display_destroy;
dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
- dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
+ dri2dpy->base.get_pixmap_format = dri2_display_get_pixmap_format;
+ dri2dpy->base.copy_to_pixmap = native_display_copy_to_pixmap;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
#ifdef HAVE_WAYLAND_BACKEND
@@ -928,8 +936,7 @@ x11_create_dri2_display(Display *dpy,
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
return NULL;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index a0bcad4c734..ef038b52152 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -30,16 +30,10 @@
#include "native_x11.h"
-static struct native_event_handler *x11_event_handler;
-
-static void
-native_set_event_handler(struct native_event_handler *event_handler)
-{
- x11_event_handler = event_handler;
-}
+static const struct native_event_handler *x11_event_handler;
static struct native_display *
-native_create_display(void *dpy, boolean use_sw, void *user_data)
+native_create_display(void *dpy, boolean use_sw)
{
struct native_display *ndpy = NULL;
boolean force_sw;
@@ -48,12 +42,10 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
if (force_sw || use_sw) {
_eglLog(_EGL_INFO, "use software fallback");
- ndpy = x11_create_ximage_display((Display *) dpy,
- x11_event_handler, user_data);
+ ndpy = x11_create_ximage_display((Display *) dpy, x11_event_handler);
}
else {
- ndpy = x11_create_dri2_display((Display *) dpy,
- x11_event_handler, user_data);
+ ndpy = x11_create_dri2_display((Display *) dpy, x11_event_handler);
}
return ndpy;
@@ -61,12 +53,12 @@ native_create_display(void *dpy, boolean use_sw, void *user_data)
static const struct native_platform x11_platform = {
"X11", /* name */
- native_set_event_handler,
native_create_display
};
const struct native_platform *
-native_get_x11_platform(void)
+native_get_x11_platform(const struct native_event_handler *event_handler)
{
+ x11_event_handler = event_handler;
return &x11_platform;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 8945117276e..d3c9270a667 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -31,12 +31,10 @@
struct native_display *
x11_create_ximage_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
struct native_display *
x11_create_dri2_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data);
+ const struct native_event_handler *event_handler);
#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 8e32c6ff0c4..e7794f0d3d7 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -43,7 +43,7 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
- struct native_event_handler *event_handler;
+ const struct native_event_handler *event_handler;
struct x11_screen *xscr;
int xscr_number;
@@ -437,14 +437,54 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
}
static boolean
-ximage_display_is_pixmap_supported(struct native_display *ndpy,
- EGLNativePixmapType pix,
- const struct native_config *nconf)
+ximage_display_get_pixmap_format(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ enum pipe_format *format)
{
struct ximage_display *xdpy = ximage_display(ndpy);
- enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
- return (fmt == nconf->color_format);
+ *format = get_pixmap_format(&xdpy->base, pix);
+
+ return (*format != PIPE_FORMAT_NONE);
+}
+
+static boolean
+ximage_display_copy_to_pixmap(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ struct pipe_resource *src)
+{
+ /* fast path to avoid unnecessary allocation and resource_copy_region */
+ if (src->bind & PIPE_BIND_DISPLAY_TARGET) {
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt = get_pixmap_format(&xdpy->base, pix);
+ const struct ximage_config *xconf;
+ struct xlib_drawable xdraw;
+ int i;
+
+ if (fmt == PIPE_FORMAT_NONE || src->format != fmt)
+ return FALSE;
+
+ for (i = 0; i < xdpy->num_configs; i++) {
+ if (xdpy->configs[i].base.color_format == fmt) {
+ xconf = &xdpy->configs[i];
+ break;
+ }
+ }
+ if (!xconf)
+ return FALSE;
+
+ memset(&xdraw, 0, sizeof(xdraw));
+ xdraw.visual = xconf->visual->visual;
+ xdraw.depth = xconf->visual->depth;
+ xdraw.drawable = (Drawable) pix;
+
+ xdpy->base.screen->flush_frontbuffer(xdpy->base.screen,
+ src, 0, 0, &xdraw);
+
+ return TRUE;
+ }
+
+ return native_display_copy_to_pixmap(ndpy, pix, src);
}
static int
@@ -484,13 +524,32 @@ ximage_display_destroy(struct native_display *ndpy)
FREE(xdpy);
}
+static boolean
+ximage_display_init_screen(struct native_display *ndpy)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ struct sw_winsys *winsys;
+
+ winsys = xlib_create_sw_winsys(xdpy->dpy);
+ if (!winsys)
+ return FALSE;
+
+ xdpy->base.screen =
+ xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
+ if (!xdpy->base.screen) {
+ if (winsys->destroy)
+ winsys->destroy(winsys);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
struct native_display *
x11_create_ximage_display(Display *dpy,
- struct native_event_handler *event_handler,
- void *user_data)
+ const struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
- struct sw_winsys *winsys = NULL;
xdpy = CALLOC_STRUCT(ximage_display);
if (!xdpy)
@@ -507,39 +566,25 @@ x11_create_ximage_display(Display *dpy,
}
xdpy->event_handler = event_handler;
- xdpy->base.user_data = user_data;
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
- if (!xdpy->xscr)
- goto fail;
-
- winsys = xlib_create_sw_winsys(xdpy->dpy);
- if (!winsys)
- goto fail;
-
- xdpy->base.screen =
- xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
- if (!xdpy->base.screen)
- goto fail;
+ if (!xdpy->xscr) {
+ if (xdpy->own_dpy)
+ XCloseDisplay(xdpy->dpy);
+ FREE(xdpy);
+ return NULL;
+ }
+ xdpy->base.init_screen = ximage_display_init_screen;
xdpy->base.destroy = ximage_display_destroy;
xdpy->base.get_param = ximage_display_get_param;
xdpy->base.get_configs = ximage_display_get_configs;
- xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
+ xdpy->base.get_pixmap_format = ximage_display_get_pixmap_format;
+ xdpy->base.copy_to_pixmap = ximage_display_copy_to_pixmap;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
return &xdpy->base;
-
-fail:
- if (winsys && winsys->destroy)
- winsys->destroy(winsys);
- if (xdpy->xscr)
- x11_screen_destroy(xdpy->xscr);
- if (xdpy->dpy && xdpy->own_dpy)
- XCloseDisplay(xdpy->dpy);
- FREE(xdpy);
- return NULL;
}
diff --git a/src/gallium/state_trackers/gbm/Makefile b/src/gallium/state_trackers/gbm/Makefile
new file mode 100644
index 00000000000..1d96eb2032d
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/Makefile
@@ -0,0 +1,46 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+gbm_INCLUDES = \
+ -I. \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gbm/main \
+ -I$(TOP)/include
+
+gbm_SOURCES = $(wildcard *.c)
+gbm_OBJECTS = $(gbm_SOURCES:.c=.o)
+
+ALL_INCLUDES = $(gbm_INCLUDES)
+ALL_SOURCES = $(gbm_SOURCES)
+
+GBM_OBJECTS = $(gbm_OBJECTS)
+GBM_CPPFLAGS = $(gbm_INCLUDES)
+
+##### TARGETS #####
+
+default: depend libgbm.a
+
+libgbm.a: $(GBM_OBJECTS) Makefile
+ $(MKLIB) -o gbm -static $(GBM_OBJECTS)
+
+depend:
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+clean:
+ rm -f libgbm.a
+ rm -f $(GBM_OBJECTS)
+ rm -f depend depend.bak
+
+# Dummy target
+install:
+ @echo -n ""
+
+##### RULES #####
+
+$(gbm_OBJECTS): %.o: %.c
+ $(CC) -c $(GBM_CPPFLAGS) $(DEFINES) $(CFLAGS) $< -o $@
+
+sinclude depend
diff --git a/src/gallium/state_trackers/gbm/gbm_drm.c b/src/gallium/state_trackers/gbm/gbm_drm.c
new file mode 100644
index 00000000000..d4baf87096a
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/gbm_drm.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "state_tracker/drm_driver.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "gbm_gallium_drmint.h"
+
+static INLINE enum pipe_format
+gbm_format_to_gallium(enum gbm_bo_format format)
+{
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ case GBM_BO_FORMAT_ARGB8888:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ default:
+ return PIPE_FORMAT_NONE;
+ }
+
+ return PIPE_FORMAT_NONE;
+}
+
+static INLINE uint
+gbm_usage_to_gallium(uint usage)
+{
+ uint resource_usage = 0;
+
+ if (usage & GBM_BO_USE_SCANOUT)
+ resource_usage |= PIPE_BIND_SCANOUT;
+
+ if (usage & GBM_BO_USE_RENDERING)
+ resource_usage |= PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+
+ if (usage & GBM_BO_USE_CURSOR_64X64)
+ resource_usage |= PIPE_BIND_CURSOR;
+
+ return resource_usage;
+}
+
+static int
+gbm_gallium_drm_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage)
+{
+ struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+ enum pipe_format pf;
+
+ pf = gbm_format_to_gallium(format);
+ if (pf == PIPE_FORMAT_NONE)
+ return 0;
+
+ if (!gdrm->screen->is_format_supported(gdrm->screen, PIPE_TEXTURE_2D, pf, 0,
+ gbm_usage_to_gallium(usage)))
+ return 0;
+
+ if (usage & GBM_BO_USE_SCANOUT && format != GBM_BO_FORMAT_XRGB8888)
+ return 0;
+
+ return 1;
+}
+
+static void
+gbm_gallium_drm_bo_destroy(struct gbm_bo *_bo)
+{
+ struct gbm_gallium_drm_bo *bo = gbm_gallium_drm_bo(_bo);
+
+ pipe_resource_reference(&bo->resource, NULL);
+ free(bo);
+}
+
+static struct gbm_bo *
+gbm_gallium_drm_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_image,
+ uint32_t width, uint32_t height,
+ uint32_t usage)
+{
+ struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+ struct gbm_gallium_drm_bo *bo;
+ struct winsys_handle whandle;
+
+ if (!gdrm->lookup_egl_image)
+ return NULL;
+
+ bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->resource = gdrm->lookup_egl_image(gdrm->lookup_egl_image_data,
+ egl_image);
+ if (bo->resource == NULL) {
+ FREE(bo);
+ return NULL;
+ }
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
+
+ bo->base.base.handle.u32 = whandle.handle;
+ bo->base.base.pitch = whandle.stride;
+
+ return &bo->base.base;
+}
+
+static struct gbm_bo *
+gbm_gallium_drm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t usage)
+{
+ struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+ struct gbm_gallium_drm_bo *bo;
+ struct pipe_resource templ;
+ struct winsys_handle whandle;
+ enum pipe_format pf;
+
+ bo = CALLOC_STRUCT(gbm_gallium_drm_bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ pf = gbm_format_to_gallium(format);
+ if (pf == PIPE_FORMAT_NONE)
+ return NULL;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.bind = gbm_usage_to_gallium(usage);
+ templ.format = pf;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+
+ bo->resource = gdrm->screen->resource_create(gdrm->screen, &templ);
+ if (bo->resource == NULL) {
+ FREE(bo);
+ return NULL;
+ }
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+ gdrm->screen->resource_get_handle(gdrm->screen, bo->resource, &whandle);
+
+ bo->base.base.handle.u32 = whandle.handle;
+ bo->base.base.pitch = whandle.stride;
+
+ return &bo->base.base;
+}
+
+static void
+gbm_gallium_drm_destroy(struct gbm_device *gbm)
+{
+ struct gbm_gallium_drm_device *gdrm = gbm_gallium_drm_device(gbm);
+
+ gdrm->screen->destroy(gdrm->screen);
+
+ FREE(gdrm->base.driver_name);
+
+ FREE(gdrm);
+}
+
+struct gbm_device *
+gbm_gallium_drm_device_create(int fd)
+{
+ struct gbm_gallium_drm_device *gdrm;
+ int ret;
+
+ gdrm = calloc(1, sizeof *gdrm);
+
+ gdrm->base.base.fd = fd;
+ gdrm->base.base.bo_create = gbm_gallium_drm_bo_create;
+ gdrm->base.base.bo_create_from_egl_image =
+ gbm_gallium_drm_bo_create_from_egl_image;
+ gdrm->base.base.bo_destroy = gbm_gallium_drm_bo_destroy;
+ gdrm->base.base.is_format_supported = gbm_gallium_drm_is_format_supported;
+ gdrm->base.base.destroy = gbm_gallium_drm_destroy;
+
+ gdrm->base.type = GBM_DRM_DRIVER_TYPE_GALLIUM;
+ gdrm->base.base.name = "drm";
+
+ ret = gallium_screen_create(gdrm);
+ if (ret) {
+ free(gdrm);
+ return NULL;
+ }
+
+ return &gdrm->base.base;
+}
diff --git a/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h
new file mode 100644
index 00000000000..6277b8dba2e
--- /dev/null
+++ b/src/gallium/state_trackers/gbm/gbm_gallium_drmint.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _GBM_GALLIUM_DRMINT_H_
+#define _GBM_GALLIUM_DRMINT_H_
+
+#include "pipe/p_state.h"
+
+#include "gbmint.h"
+
+#include "common.h"
+#include "common_drm.h"
+
+struct gbm_gallium_drm_device {
+ struct gbm_drm_device base;
+
+ struct pipe_screen *screen;
+ void *driver;
+
+ struct pipe_resource *(*lookup_egl_image)(void *data,
+ void *egl_image);
+ void *lookup_egl_image_data;
+
+};
+
+struct gbm_gallium_drm_bo {
+ struct gbm_drm_bo base;
+
+ struct pipe_resource *resource;
+};
+
+static inline struct gbm_gallium_drm_device *
+gbm_gallium_drm_device(struct gbm_device *gbm)
+{
+ return (struct gbm_gallium_drm_device *) gbm;
+}
+
+static inline struct gbm_gallium_drm_bo *
+gbm_gallium_drm_bo(struct gbm_bo *bo)
+{
+ return (struct gbm_gallium_drm_bo *) bo;
+}
+
+struct gbm_device *
+gbm_gallium_drm_device_create(int fd);
+
+int
+gallium_screen_create(struct gbm_gallium_drm_device *gdrm);
+
+#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index ab4f6753e11..8f6406ddaee 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -59,6 +59,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
+#include "util/u_atomic.h"
#include "xm_public.h"
#include <GL/glx.h>
@@ -1113,10 +1114,7 @@ XMesaDestroyBuffer(XMesaBuffer b)
void
xmesa_notify_invalid_buffer(XMesaBuffer b)
{
- XMesaContext xmctx = XMesaGetCurrentContext();
-
- if (xmctx && xmctx->xm_buffer == b)
- xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
+ p_atomic_inc(&b->stfb->stamp);
}
@@ -1126,11 +1124,18 @@ xmesa_notify_invalid_buffer(XMesaBuffer b)
void
xmesa_check_buffer_size(XMesaBuffer b)
{
+ GLuint old_width, old_height;
+
if (b->type == PBUFFER)
return;
+ old_width = b->width;
+ old_height = b->height;
+
xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
- xmesa_notify_invalid_buffer(b);
+
+ if (b->width != old_width || b->height != old_height)
+ xmesa_notify_invalid_buffer(b);
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index 6bfe8b0788c..ec3f531f7df 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -30,6 +30,7 @@
#include "xm_st.h"
#include "util/u_inlines.h"
+#include "util/u_atomic.h"
struct xmesa_st_framebuffer {
XMesaDisplay display;
@@ -302,6 +303,7 @@ xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
stfbi->visual = &xstfb->stvis;
stfbi->flush_front = xmesa_st_framebuffer_flush_front;
stfbi->validate = xmesa_st_framebuffer_validate;
+ p_atomic_set(&stfbi->stamp, 1);
stfbi->st_manager_private = (void *) xstfb;
return stfbi;
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index 71491a5aa22..d91ee9797f1 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -65,6 +65,8 @@ struct st_framebuffer {
enum st_attachment_type strb_att;
void *privateData;
+ int32_t stamp;
+ int32_t iface_stamp;
};
enum vg_object_type {
@@ -105,7 +107,6 @@ struct vg_context
VGErrorCode _error;
struct st_framebuffer *draw_buffer;
- int32_t draw_buffer_invalid;
struct cso_hash *owned_objects[VG_OBJECT_LAST];
@@ -129,6 +130,8 @@ struct vg_context
struct vg_paint *default_paint;
struct blit_state *blit;
+
+ int32_t draw_stamp;
};
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
index eeea68677de..dec1581fb84 100644
--- a/src/gallium/state_trackers/vega/vg_manager.c
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -106,35 +106,38 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
{
struct st_framebuffer *stfb = ctx->draw_buffer;
struct pipe_resource *pt;
+ int32_t new_stamp;
/* no binding surface */
if (!stfb)
return;
- if (!p_atomic_read(&ctx->draw_buffer_invalid))
- return;
+ new_stamp = p_atomic_read(&stfb->iface->stamp);
+ if (stfb->iface_stamp != new_stamp) {
+ do {
+ /* validate the fb */
+ if (!stfb->iface->validate(stfb->iface, &stfb->strb_att,
+ 1, &pt) || !pt)
+ return;
- /* validate the fb */
- if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
- return;
+ stfb->iface_stamp = new_stamp;
+ new_stamp = p_atomic_read(&stfb->iface->stamp);
- p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
+ } while (stfb->iface_stamp != new_stamp);
- if (vg_context_update_color_rb(ctx, pt) ||
- stfb->width != pt->width0 ||
- stfb->height != pt->height0)
- ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+ if (vg_context_update_color_rb(ctx, pt) ||
+ stfb->width != pt->width0 ||
+ stfb->height != pt->height0)
+ ++stfb->stamp;
- stfb->width = pt->width0;
- stfb->height = pt->height0;
-}
+ stfb->width = pt->width0;
+ stfb->height = pt->height0;
+ }
-static void
-vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
- struct st_framebuffer_iface *stfbi)
-{
- struct vg_context *ctx = (struct vg_context *) stctxi;
- p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+ if (ctx->draw_stamp != stfb->stamp) {
+ ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+ ctx->draw_stamp = stfb->stamp;
+ }
}
static void
@@ -187,8 +190,6 @@ vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
ctx->iface.destroy = vg_context_destroy;
- ctx->iface.notify_invalid_framebuffer =
- vg_context_notify_invalid_framebuffer;
ctx->iface.flush = vg_context_flush;
ctx->iface.teximage = NULL;
@@ -266,8 +267,6 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
if (stdrawi != streadi)
return FALSE;
- p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
-
strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
if (ctx->draw_buffer) {
@@ -313,11 +312,14 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
stfb->width = 0;
stfb->height = 0;
stfb->strb_att = strb_att;
+ stfb->stamp = 1;
+ stfb->iface_stamp = p_atomic_read(&stdrawi->stamp) - 1;
ctx->draw_buffer = stfb;
}
ctx->draw_buffer->iface = stdrawi;
+ ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
return TRUE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 5608d4f4ce7..c2839fe815f 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -31,6 +31,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/u_memory.h"
+#include "util/u_atomic.h"
#include "state_tracker/st_api.h"
#include "stw_icd.h"
@@ -361,10 +362,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb )
void
stw_notify_current_locked( struct stw_framebuffer *fb )
{
- struct stw_context *ctx = stw_current_context();
-
- if (ctx && ctx->current_framebuffer == fb)
- ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb);
+ p_atomic_inc(&fb->stfb->stamp);
}
/**
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
index 424d8daccb3..c7273f26545 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -268,7 +268,7 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
*piValue = fb->width;
return TRUE;
case WGL_PBUFFER_HEIGHT_ARB:
- *piValue = fb->width;
+ *piValue = fb->height;
return TRUE;
case WGL_PBUFFER_LOST_ARB:
/* We assume that no content is ever lost due to display mode change */
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index 9174533fc06..28c93f4fb57 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -27,6 +27,7 @@
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_atomic.h"
#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
#include "stw_st.h"
@@ -196,6 +197,7 @@ stw_st_create_framebuffer(struct stw_framebuffer *fb)
stwfb->stvis = fb->pfi->stvis;
stwfb->base.visual = &stwfb->stvis;
+ p_atomic_set(&stwfb->base.stamp, 1);
stwfb->base.flush_front = stw_st_framebuffer_flush_front;
stwfb->base.validate = stw_st_framebuffer_validate;
diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript
index 19315694b7c..4ea4ec4ee8b 100644
--- a/src/gallium/state_trackers/xorg/SConscript
+++ b/src/gallium/state_trackers/xorg/SConscript
@@ -9,10 +9,11 @@ env.Append(CPPPATH = [
'#/src/mesa',
])
-env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server')
+env.PkgUseModules(['DRM', 'XORG'])
-if env['kms']:
+if env['HAVE_KMS']:
env.Append(CPPDEFINES = ['HAVE_LIBKMS'])
+ env.PkgUseModules(['KMS'])
conf = env.Configure()
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index d4dc84a122b..f696b72e1e3 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -237,7 +237,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
boolean swizzle = FALSE;
unsigned ret = 0;
- if (pSrc->picture_format == pSrcPicture->format) {
+ if (pSrc && pSrc->picture_format == pSrcPicture->format) {
if (pSrc->picture_format == PICT_a8) {
if (mask)
return FS_MASK_LUMINANCE;
@@ -252,7 +252,7 @@ picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, bool
return 0;
}
- if (pSrc->picture_format != PICT_a8r8g8b8) {
+ if (pSrc && pSrc->picture_format != PICT_a8r8g8b8) {
assert(!"can not handle formats");
return 0;
}
@@ -355,7 +355,7 @@ bind_samplers(struct exa_context *exa, int op,
struct exa_pixmap_priv *pMask,
struct exa_pixmap_priv *pDst)
{
- struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS] = {0};
struct pipe_sampler_state src_sampler, mask_sampler;
struct pipe_sampler_view view_templ;
struct pipe_sampler_view *src_view;
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 0499ed1ea0b..22e61cf7081 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -122,6 +122,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
drm_mode.hskew = mode->HSkew;
drm_mode.vscan = mode->VScan;
drm_mode.vrefresh = mode->VRefresh;
+ drm_mode.type = 0;
if (!mode->name)
xf86SetModeDefaultName(mode);
strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg
index 47040bb14c8..6fad7109f29 100644
--- a/src/gallium/targets/Makefile.xorg
+++ b/src/gallium/targets/Makefile.xorg
@@ -41,7 +41,7 @@ endif
default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING)
-$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES)
+$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES)
$(MKLIB) -linker '$(CC)' -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS)
depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES)
diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri
index 101863a6848..5ad17f8b3ae 100644
--- a/src/gallium/targets/SConscript.dri
+++ b/src/gallium/targets/SConscript.dri
@@ -29,7 +29,7 @@ drienv.Replace(CPPPATH = [
'#src/egl/drivers/dri',
])
-drienv.ParseConfig('pkg-config --cflags --libs libdrm')
+drienv.PkgUseModules('DRM')
dri_common_utils = drienv.SharedObject(
target = 'utils.o',
diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript
index ab60013830e..b3bd3dd5826 100644
--- a/src/gallium/targets/dri-i915/SConscript
+++ b/src/gallium/targets/dri-i915/SConscript
@@ -2,7 +2,7 @@ Import('*')
env = drienv.Clone()
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+env.PkgUseModules('DRM_INTEL')
env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE', 'GALLIUM_GALAHAD'])
@@ -26,4 +26,4 @@ module = env.LoadableModule(
SHLIBPREFIX = '',
)
-env.Alias('dri-i915', module) \ No newline at end of file
+env.Alias('dri-i915', module)
diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript
index 669f70d6b8d..01a458db228 100644
--- a/src/gallium/targets/dri-i965/SConscript
+++ b/src/gallium/targets/dri-i965/SConscript
@@ -2,7 +2,7 @@ Import('*')
env = drienv.Clone()
-env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+env.PkgUseModules('DRM_INTEL')
env.Append(CPPDEFINES = [
'GALLIUM_SOFTPIPE',
@@ -29,4 +29,4 @@ module = env.LoadableModule(
SHLIBPREFIX = '',
)
-env.Alias('dri-i965', module) \ No newline at end of file
+env.Alias('dri-i965', module)
diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript
index b67483800e4..33acc614e76 100644
--- a/src/gallium/targets/dri-swrast/SConscript
+++ b/src/gallium/targets/dri-swrast/SConscript
@@ -39,4 +39,6 @@ module = env.LoadableModule(
SHLIBPREFIX = '',
)
+module = env.InstallSharedLibrary(module)
+
env.Alias('dri-swrast', module)
diff --git a/src/gallium/targets/egl-static/Makefile b/src/gallium/targets/egl-static/Makefile
new file mode 100644
index 00000000000..832d7ba438f
--- /dev/null
+++ b/src/gallium/targets/egl-static/Makefile
@@ -0,0 +1,201 @@
+# src/gallium/targets/egl-static/Makefile
+#
+# This is Makefile for egl_gallium.so. It is static in that all state trackers
+# and pipe drivers are linked statically when possible.
+#
+# The following variables are examined
+#
+# EGL_PLATFORMS - platforms to support
+# EGL_CLIENT_APIS - state trackers to support
+# GALLIUM_WINSYS_DIRS - pipe drivers to support
+# SHARED_GLAPI - st/mesa can be statically linked or not
+#
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+OUTPUTS := egl_gallium
+
+egl_CPPFLAGS := \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/winsys
+egl_LIBS := \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/rbug/librbug.a \
+ $(GALLIUM_AUXILIARIES)
+egl_SYS :=
+
+egl_SOURCES := \
+ egl.c \
+ egl_pipe.c \
+ egl_st.c
+
+egl_OBJECTS := $(egl_SOURCES:%.c=%.o)
+
+# st/egl
+egl_CPPFLAGS += \
+ -I$(TOP)/src/gallium/state_trackers/egl \
+ -I$(TOP)/src/egl/main \
+ -D_EGL_MAIN=_eglMain
+egl_LIBS += $(TOP)/src/gallium/state_trackers/egl/libegl.a
+egl_SYS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) -lEGL -lm
+
+# EGL platforms
+ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
+egl_CPPFLAGS += $(LIBDRM_CFLAGS)
+egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a
+egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIB)
+endif
+ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
+egl_CPPFLAGS += $(LIBDRM_CFLAGS)
+egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a
+egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
+egl_SYS += $(LIBDRM_LIB) $(WAYLAND_LIBS)
+endif
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
+egl_CPPFLAGS += $(LIBDRM_CFLAGS)
+egl_SYS += $(LIBDRM_LIB) -lgbm
+endif
+ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
+egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a
+endif
+
+# st/mesa
+ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -I$(TOP)/src/mesa $(API_DEFINES)
+# make st/mesa built-in when there is a single glapi provider
+ifeq ($(SHARED_GLAPI),1)
+egl_LIBS += $(TOP)/src/mesa/libmesagallium.a
+egl_SYS += -lm -lpthread $(DLOPEN_LIBS) -l$(GLAPI_LIB)
+else
+egl_CPPFLAGS += -D_EGL_EXTERNAL_GL=1
+OUTPUTS += st_GL
+endif # SHARED_GLAPI
+endif
+
+# st/vega
+ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -I$(TOP)/src/gallium/state_trackers/vega -DFEATURE_VG=1
+egl_LIBS += $(TOP)/src/gallium/state_trackers/vega/libvega.a
+egl_SYS += -lm -l$(VG_LIB)
+endif
+
+# i915
+ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_I915=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
+ $(TOP)/src/gallium/drivers/i915/libi915.a
+egl_SYS += -ldrm_intel
+endif
+
+# i965
+ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_I995=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a
+egl_SYS += -ldrm_intel
+endif
+
+# nouveau
+ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_NOUVEAU=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
+egl_SYS += -ldrm_nouveau
+endif
+
+# r300
+ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_R300=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
+ $(TOP)/src/gallium/drivers/r300/libr300.a
+egl_SYS += -ldrm_radeon
+endif
+
+# r600
+ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_R600=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
+ $(TOP)/src/gallium/drivers/r600/libr600.a
+egl_SYS += -ldrm_radeon
+endif
+
+# vmwgfx
+ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),)
+egl_CPPFLAGS += -D_EGL_PIPE_VMWGFX=1
+egl_LIBS += \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/svga/libsvga.a
+endif
+
+# swrast
+egl_CPPFLAGS += -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
+egl_LIBS += $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+egl_SYS += -lm
+
+# sort to remove duplicates
+egl_CPPFLAGS := $(sort $(egl_CPPFLAGS))
+egl_LIBS := $(sort $(egl_LIBS))
+egl_SYS := $(sort $(egl_SYS))
+
+# st_GL, built only when shared glapi is not enabled
+st_GL_CPPFLAGS := -I $(TOP)/src/mesa -I$(TOP)/src/gallium/include
+st_GL_LIBS := $(TOP)/src/mesa/libmesagallium.a $(GALLIUM_AUXILIARIES)
+st_GL_SYS := -lm -lpthread $(DLOPEN_LIBS)
+
+# LLVM
+ifeq ($(MESA_LLVM),1)
+egl_CPPFLAGS += -DGALLIUM_LLVMPIPE
+egl_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+egl_SYS += $(LLVM_LIBS)
+LDFLAGS += $(LLVM_LDFLAGS)
+
+st_GL_SYS += $(LLVM_LIBS)
+endif
+
+OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl
+OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(addsuffix .so, $(OUTPUTS)))
+
+default: $(OUTPUTS)
+
+$(OUTPUT_PATH)/egl_gallium.so: $(egl_OBJECTS) $(egl_LIBS)
+ $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \
+ -ldflags '-L$(TOP)/$(LIB_DIR) -Wl,--no-undefined $(LDFLAGS)' \
+ -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \
+ $(egl_OBJECTS) -Wl,--start-group $(egl_LIBS) -Wl,--end-group \
+ $(egl_SYS)
+
+$(OUTPUT_PATH)/st_GL.so: st_GL.o $(st_GL_LIBS)
+ $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \
+ -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \
+ -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \
+ $< -Wl,--start-group $(st_GL_LIBS) -Wl,--end-group \
+ $(st_GL_SYS)
+
+$(egl_OBJECTS): %.o: %.c
+ $(CC) -c -o $@ $< $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS)
+
+st_GL.o: st_GL.c
+ $(CC) -c -o $@ $< $(st_GL_CPPFLAGS) $(DEFINES) $(CFLAGS)
+
+install: $(OUTPUTS)
+ $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
+ for out in $(OUTPUTS); do \
+ $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
+ done
+
+clean:
+ rm -f *.o
diff --git a/src/gallium/targets/egl-static/SConscript b/src/gallium/targets/egl-static/SConscript
index cbd98cc416a..dfd05437231 100644
--- a/src/gallium/targets/egl-static/SConscript
+++ b/src/gallium/targets/egl-static/SConscript
@@ -79,21 +79,17 @@ if True:
openvg_name = 'OpenVG' if env['platform'] != 'windows' else 'libOpenVG'
env.Prepend(LIBS = [openvg_name, st_vega])
-if env['x11']:
+if env['HAVE_X11']:
env.Prepend(LIBS = [
ws_xlib,
- env['X11_LIBS'],
])
-
-if env['dri']:
- env.ParseConfig('pkg-config --cflags --libs xfixes')
+ env.PkgUseModules('X11')
# pipe drivers
-if env['drm']:
- env.ParseConfig('pkg-config --cflags --libs libdrm')
+if env['HAVE_DRM']:
+ env.PkgUseModules('DRM')
- if env['drm_intel']:
- env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+ if env['HAVE_DRM_INTEL']:
env.Append(CPPDEFINES = ['_EGL_PIPE_I915', '_EGL_PIPE_I965'])
env.Prepend(LIBS = [
i915drm,
@@ -103,7 +99,7 @@ if env['drm']:
ws_wrapper,
])
- if env['drm_radeon']:
+ if env['HAVE_DRM_RADEON']:
env.Append(CPPDEFINES = ['_EGL_PIPE_R300', '_EGL_PIPE_R600'])
env.Prepend(LIBS = [
radeonwinsys,
diff --git a/src/gallium/targets/egl-static/egl.c b/src/gallium/targets/egl-static/egl.c
index e617ff50208..568f5498dd4 100644
--- a/src/gallium/targets/egl-static/egl.c
+++ b/src/gallium/targets/egl-static/egl.c
@@ -28,6 +28,15 @@
#include "common/egl_g3d_loader.h"
#include "egldriver.h"
+#include "egllog.h"
+
+#ifdef HAVE_LIBUDEV
+#include <stdio.h> /* for sscanf */
+#include <libudev.h>
+#endif
+
+#define DRIVER_MAP_GALLIUM_ONLY
+#include "pci_ids/pci_id_driver_map.h"
#include "egl_pipe.h"
#include "egl_st.h"
@@ -52,15 +61,108 @@ get_st_api(enum st_api_type api)
return stmod->stapi;
}
-static struct st_api *
-guess_gl_api(enum st_profile_type profile)
+#ifdef HAVE_LIBUDEV
+
+static boolean
+drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
{
- return get_st_api(ST_API_OPENGL);
+ struct udev *udev = NULL;
+ struct udev_device *device = NULL, *parent;
+ struct stat buf;
+ const char *pci_id;
+
+ *chip_id = -1;
+
+ udev = udev_new();
+ if (fstat(fd, &buf) < 0) {
+ _eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
+ goto out;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+ if (device == NULL) {
+ _eglLog(_EGL_WARNING,
+ "could not create udev device for fd %d", fd);
+ goto out;
+ }
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ _eglLog(_EGL_WARNING, "could not get parent device");
+ goto out;
+ }
+
+ pci_id = udev_device_get_property_value(parent, "PCI_ID");
+ if (pci_id == NULL ||
+ sscanf(pci_id, "%x:%x", vendor_id, chip_id) != 2) {
+ _eglLog(_EGL_WARNING, "malformed or no PCI ID");
+ *chip_id = -1;
+ goto out;
+ }
+
+out:
+ if (device)
+ udev_device_unref(device);
+ if (udev)
+ udev_unref(udev);
+
+ return (*chip_id >= 0);
+}
+
+#else
+
+static boolean
+drm_fd_get_pci_id(int fd, int *vendor_id, int *chip_id)
+{
+ return FALSE;
+}
+
+#endif /* HAVE_LIBUDEV */
+
+static const char *
+drm_fd_get_screen_name(int fd)
+{
+ int vendor_id, chip_id;
+ int idx, i;
+
+ if (!drm_fd_get_pci_id(fd, &vendor_id, &chip_id)) {
+ _eglLog(_EGL_WARNING, "failed to get driver name for fd %d", fd);
+ return NULL;
+ }
+
+ for (idx = 0; driver_map[idx].driver; idx++) {
+ if (vendor_id != driver_map[idx].vendor_id)
+ continue;
+
+ /* done if no chip id */
+ if (driver_map[idx].num_chips_ids == -1)
+ break;
+
+ for (i = 0; i < driver_map[idx].num_chips_ids; i++) {
+ if (driver_map[idx].chip_ids[i] == chip_id)
+ break;
+ }
+ /* matched! */
+ if (i < driver_map[idx].num_chips_ids)
+ break;
+ }
+
+ _eglLog((driver_map[idx].driver) ? _EGL_INFO : _EGL_WARNING,
+ "pci id for fd %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver_map[idx].driver);
+
+ return driver_map[idx].driver;
}
static struct pipe_screen *
create_drm_screen(const char *name, int fd)
{
+ if (!name) {
+ name = drm_fd_get_screen_name(fd);
+ if (!name)
+ return NULL;
+ }
+
return egl_pipe_create_drm_screen(name, fd);
}
@@ -79,7 +181,6 @@ loader_init(void)
egl_g3d_loader.profile_masks[i] = egl_st_get_profile_mask(i);
egl_g3d_loader.get_st_api = get_st_api;
- egl_g3d_loader.guess_gl_api = guess_gl_api;
egl_g3d_loader.create_drm_screen = create_drm_screen;
egl_g3d_loader.create_sw_screen = create_sw_screen;
@@ -95,7 +196,7 @@ loader_fini(void)
struct st_module *stmod = &st_modules[i];
if (stmod->stapi) {
- stmod->stapi->destroy(stmod->stapi);
+ egl_st_destroy_api(stmod->stapi);
stmod->stapi = NULL;
}
stmod->initialized = FALSE;
diff --git a/src/gallium/targets/egl-static/egl_st.c b/src/gallium/targets/egl-static/egl_st.c
index 3db52621def..81d7bb47568 100644
--- a/src/gallium/targets/egl-static/egl_st.c
+++ b/src/gallium/targets/egl-static/egl_st.c
@@ -29,52 +29,143 @@
#include "state_tracker/st_api.h"
#include "egl_st.h"
-/* for st/mesa */
+#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
#include "state_tracker/st_gl_api.h"
-/* for st/vega */
+#endif
+
+#if FEATURE_VG
#include "vg_api.h"
+#endif
+
+#if _EGL_EXTERNAL_GL
+
+#include "util/u_string.h"
+#include "util/u_dl.h"
+#include "egldriver.h"
+#include "egllog.h"
+
+static struct util_dl_library *egl_st_gl_lib;
+
+static EGLBoolean
+dlopen_gl_lib_cb(const char *dir, size_t len, void *callback_data)
+{
+ const char *name = (const char *) callback_data;
+ char path[1024];
+ int ret;
+
+ if (len) {
+ ret = util_snprintf(path, sizeof(path), "%.*s/%s" UTIL_DL_EXT,
+ len, dir, name);
+ }
+ else {
+ ret = util_snprintf(path, sizeof(path), "%s" UTIL_DL_EXT, name);
+ }
+
+ if (ret > 0 && ret < sizeof(path)) {
+ egl_st_gl_lib = util_dl_open(path);
+ if (egl_st_gl_lib)
+ _eglLog(_EGL_DEBUG, "loaded %s", path);
+ }
+
+ return !egl_st_gl_lib;
+}
static struct st_api *
-st_GL_create_api(void)
+load_gl(const char *name, const char *procname)
{
-#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
- return st_gl_api_create();
-#else
- return NULL;
-#endif
+ struct st_api *(*create_api)(void);
+ struct st_api *stapi = NULL;
+
+ _eglSearchPathForEach(dlopen_gl_lib_cb, (void *) name);
+ if (!egl_st_gl_lib)
+ return NULL;
+
+ create_api = (struct st_api *(*)(void))
+ util_dl_get_proc_address(egl_st_gl_lib, procname);
+ if (create_api)
+ stapi = create_api();
+
+ if (!stapi) {
+ util_dl_close(egl_st_gl_lib);
+ egl_st_gl_lib = NULL;
+ }
+
+ return stapi;
}
static struct st_api *
-st_OpenVG_create_api(void)
+egl_st_load_gl(void)
{
-#if FEATURE_VG
- return (struct st_api *) vg_api_get();
-#else
- return NULL;
-#endif
+ const char module[] = "st_GL";
+ const char symbol[] = "st_api_create_OpenGL";
+ struct st_api *stapi;
+
+ stapi = load_gl(module, symbol);
+
+ /* try again with libglapi.so loaded */
+ if (!stapi) {
+ struct util_dl_library *glapi = util_dl_open("libglapi" UTIL_DL_EXT);
+
+ if (glapi) {
+ _eglLog(_EGL_DEBUG, "retry with libglapi" UTIL_DL_EXT " loaded");
+
+ stapi = load_gl(module, symbol);
+ util_dl_close(glapi);
+ }
+ }
+ if (!stapi)
+ _eglLog(_EGL_WARNING, "unable to load %s" UTIL_DL_EXT, module);
+
+ return stapi;
}
+#endif /* _EGL_EXTERNAL_GL */
+
struct st_api *
egl_st_create_api(enum st_api_type api)
{
- struct st_api *stapi;
+ struct st_api *stapi = NULL;
switch (api) {
case ST_API_OPENGL:
- stapi = st_GL_create_api();
+#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
+#if _EGL_EXTERNAL_GL
+ stapi = egl_st_load_gl();
+#else
+ stapi = st_gl_api_create();
+#endif
+#endif
break;
case ST_API_OPENVG:
- stapi = st_OpenVG_create_api();
+#if FEATURE_VG
+ stapi = (struct st_api *) vg_api_get();
+#endif
break;
default:
assert(!"Unknown API Type\n");
- stapi = NULL;
break;
}
return stapi;
}
+void
+egl_st_destroy_api(struct st_api *stapi)
+{
+#if _EGL_EXTERNAL_GL
+ boolean is_gl = (stapi->api == ST_API_OPENGL);
+
+ stapi->destroy(stapi);
+
+ if (is_gl) {
+ util_dl_close(egl_st_gl_lib);
+ egl_st_gl_lib = NULL;
+ }
+#else
+ stapi->destroy(stapi);
+#endif
+}
+
uint
egl_st_get_profile_mask(enum st_api_type api)
{
diff --git a/src/gallium/targets/egl-static/egl_st.h b/src/gallium/targets/egl-static/egl_st.h
index ba82faf0b0e..7a3773c6ba2 100644
--- a/src/gallium/targets/egl-static/egl_st.h
+++ b/src/gallium/targets/egl-static/egl_st.h
@@ -34,6 +34,9 @@
struct st_api *
egl_st_create_api(enum st_api_type api);
+void
+egl_st_destroy_api(struct st_api *stapi);
+
uint
egl_st_get_profile_mask(enum st_api_type api);
diff --git a/src/gallium/targets/egl/egl.h b/src/gallium/targets/egl-static/st_GL.c
index 5fd06785407..3f4b7a09fa4 100644
--- a/src/gallium/targets/egl/egl.h
+++ b/src/gallium/targets/egl-static/st_GL.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 7.9
+ * Version: 7.10
*
- * Copyright (C) 2010 LunarG Inc.
+ * Copyright (C) 2011 LunarG Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -25,20 +25,14 @@
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
-
-#ifndef _EGL_H_
-#define _EGL_H_
-
+#include "state_tracker/st_gl_api.h"
#include "pipe/p_compiler.h"
-#include "state_tracker/st_api.h"
-
-#define ST_CREATE_OPENGL_SYMBOL "st_api_create_OpenGL"
-#define ST_CREATE_OPENVG_SYMBOL "st_api_create_OpenVG"
PUBLIC struct st_api *
st_api_create_OpenGL(void);
-PUBLIC struct st_api *
-st_api_create_OpenVG(void);
-
-#endif /* _EGL_H_ */
+struct st_api *
+st_api_create_OpenGL(void)
+{
+ return st_gl_api_create();
+}
diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile
deleted file mode 100644
index dd566bd9a06..00000000000
--- a/src/gallium/targets/egl/Makefile
+++ /dev/null
@@ -1,242 +0,0 @@
-# src/gallium/targets/egl/Makefile
-#
-# This is the Makefile for EGL Gallium driver package. The package consists of
-#
-# egl_gallium.so - EGL driver
-# pipe_<HW>.so - pipe drivers
-# st_<API>.so - client API state trackers
-#
-# The following variables are examined
-#
-# EGL_PLATFORMS - platforms to support
-# GALLIUM_WINSYS_DIRS - pipe drivers to support
-# EGL_CLIENT_APIS - state trackers to support
-#
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-ST_PREFIX := st_
-PIPE_PREFIX := pipe_
-
-common_CPPFLAGS := \
- -I$(TOP)/include \
- -I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/winsys \
- $(LIBDRM_CFLAGS)
-
-common_SYS :=
-common_LIBS := \
- $(TOP)/src/gallium/drivers/identity/libidentity.a \
- $(TOP)/src/gallium/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/rbug/librbug.a \
- $(GALLIUM_AUXILIARIES)
-
-# EGL driver
-egl_CPPFLAGS := \
- -I$(TOP)/src/gallium/state_trackers/egl \
- -I$(TOP)/src/egl/main \
- -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" -DST_PREFIX=\"$(ST_PREFIX)\"
-egl_SYS := -lm $(DLOPEN_LIBS) -lEGL
-egl_LIBS := $(TOP)/src/gallium/state_trackers/egl/libegl.a
-
-ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
-egl_SYS += -lX11 -lXext -lXfixes $(LIBDRM_LIB)
-egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a
-endif
-ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
-egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB)
-egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a
-egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
-endif
-ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
-egl_SYS += $(LIBUDEV_LIBS) $(LIBDRM_LIB)
-endif
-ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
-egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a
-endif
-
-# EGL_RENDERABLE_TYPE is a compile time attribute
-ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),)
-egl_CPPFLAGS += $(API_DEFINES)
-endif
-ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),)
-egl_CPPFLAGS += -DFEATURE_VG=1
-endif
-egl_CPPFLAGS := $(sort $(egl_CPPFLAGS))
-
-# i915 pipe driver
-i915_CPPFLAGS :=
-i915_SYS := -ldrm_intel
-i915_LIBS := \
- $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
- $(TOP)/src/gallium/drivers/i915/libi915.a
-
-# i965 pipe driver
-i965_CPPFLAGS :=
-i965_SYS := -ldrm_intel
-i965_LIBS := \
- $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
- $(TOP)/src/gallium/drivers/i965/libi965.a \
- $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a
-
-# nouveau pipe driver
-nouveau_CPPFLAGS :=
-nouveau_SYS := -ldrm_nouveau
-nouveau_LIBS := \
- $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
- $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
- $(TOP)/src/gallium/drivers/nv50/libnv50.a \
- $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
- $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
-
-# r300 pipe driver
-r300_CPPFLAGS :=
-r300_SYS := -ldrm
-r300_LIBS := \
- $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
- $(TOP)/src/gallium/drivers/r300/libr300.a
-
-# r600 pipe driver
-r600_CPPFLAGS :=
-r600_SYS := -ldrm -ldrm_radeon
-r600_LIBS := \
- $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
- $(TOP)/src/gallium/drivers/r600/libr600.a
-
-# vmwgfx pipe driver
-vmwgfx_CPPFLAGS :=
-vmwgfx_SYS :=
-vmwgfx_LIBS := \
- $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
- $(TOP)/src/gallium/drivers/svga/libsvga.a
-
-# swrast (pseudo) pipe driver
-swrast_CPPFLAGS := -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
-swrast_SYS := -lm
-swrast_LIBS := $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-
-# LLVM
-ifeq ($(MESA_LLVM),1)
-common_SYS += $(LLVM_LIBS)
-swrast_CPPFLAGS += -DGALLIUM_LLVMPIPE
-swrast_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
-LDFLAGS += $(LLVM_LDFLAGS)
-endif
-
-# OpenGL state tracker
-GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES)
-ifeq ($(SHARED_GLAPI),1)
-GL_SYS := $(DRI_LIB_DEPS) -l$(GLAPI_LIB)
-else
-# cannot link to $(GL_LIB) as the app might want GL or GLES
-GL_SYS := $(DRI_LIB_DEPS)
-endif
-GL_LIBS := $(TOP)/src/mesa/libmesagallium.a
-
-# OpenVG state tracker
-OpenVG_CPPFLAGS := -I$(TOP)/src/gallium/state_trackers/vega
-OpenVG_SYS := -lm -l$(VG_LIB)
-OpenVG_LIBS := $(TOP)/src/gallium/state_trackers/vega/libvega.a
-
-
-OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl
-
-# determine the outputs
-ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += i915
-endif
-ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += i965
-endif
-ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += nouveau
-endif
-ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += r300
-endif
-ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += r600
-endif
-ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),)
-OUTPUTS += vmwgfx
-endif
-OUTPUTS += swrast
-OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS))
-
-# EGL driver and state trackers
-OUTPUTS += egl_gallium $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS))
-
-OUTPUTS := $(addsuffix .so, $(OUTPUTS))
-OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS))
-
-default: $(OUTPUTS)
-
-define mklib
-$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' \
- -L$(TOP)/$(LIB_DIR) -ldflags '$(LDFLAGS)' \
- -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \
- -Wl,--start-group $(common_LIBS) $($(1)_LIBS) -Wl,--end-group \
- $(common_SYS) $($(1)_SYS)
-endef
-
-define mklib-cxx
-$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CXX)' \
- -L$(TOP)/$(LIB_DIR) -ldflags '$(LDFLAGS)' \
- -cplusplus -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \
- -Wl,--start-group $(common_LIBS) $($(1)_LIBS) -Wl,--end-group \
- $(common_SYS) $($(1)_SYS)
-endef
-
-# EGL driver
-$(OUTPUT_PATH)/egl_gallium.so: egl.o $(egl_LIBS)
- $(call mklib,egl)
-
-# pipe drivers
-$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o $(i915_LIBS)
- $(call mklib,i915)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o $(i965_LIBS)
- $(call mklib,i965)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o $(nouveau_LIBS)
- $(call mklib,nouveau)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)r300.so: pipe_r300.o $(r300_LIBS)
- $(call mklib,r300)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)r600.so: pipe_r600.o $(r600_LIBS)
- $(call mklib,r600)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o $(vmwgfx_LIBS)
- $(call mklib,vmwgfx)
-
-$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o $(swrast_LIBS)
- $(call mklib,swrast)
-
-# state trackers
-$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS)
- $(call mklib-cxx,GL)
-
-$(OUTPUT_PATH)/$(ST_PREFIX)$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS)
- $(call mklib,OpenVG)
-
-egl.o: egl.c
- $(CC) -c -o $@ $< $(common_CPPFLAGS) $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS)
-
-pipe_%.o: pipe_%.c
- $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS)
-
-st_%.o: st_%.c
- $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS)
-
-install: $(OUTPUTS)
- $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
- for out in $(OUTPUTS); do \
- $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
- done
-
-clean:
- rm -f *.o
diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c
deleted file mode 100644
index 3467aea9991..00000000000
--- a/src/gallium/targets/egl/egl.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.9
- *
- * Copyright (C) 2010 LunarG Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Chia-I Wu <olv@lunarg.com>
- */
-
-#include "util/u_debug.h"
-#include "util/u_string.h"
-#include "util/u_memory.h"
-#include "util/u_dl.h"
-#include "egldriver.h"
-#include "egllog.h"
-
-#include "state_tracker/st_api.h"
-#include "state_tracker/drm_driver.h"
-#include "common/egl_g3d_loader.h"
-
-#ifdef HAVE_LIBUDEV
-#include <libudev.h>
-#define DRIVER_MAP_GALLIUM_ONLY
-#include "pci_ids/pci_id_driver_map.h"
-#endif
-
-#include "egl.h"
-
-struct egl_g3d_loader egl_g3d_loader;
-
-static struct st_module {
- boolean initialized;
- char *name;
- struct util_dl_library *lib;
- struct st_api *stapi;
-} st_modules[ST_API_COUNT];
-
-static struct pipe_module {
- boolean initialized;
- char *name;
- struct util_dl_library *lib;
- const struct drm_driver_descriptor *drmdd;
- struct pipe_screen *(*swrast_create_screen)(struct sw_winsys *);
-} pipe_modules[16];
-
-static char *
-loader_strdup(const char *s)
-{
- size_t len = (s) ? strlen(s) : 0;
- char *t = MALLOC(len + 1);
- if (t) {
- memcpy(t, s, len);
- t[len] = '\0';
- }
- return t;
-}
-
-static EGLBoolean
-dlopen_st_module_cb(const char *dir, size_t len, void *callback_data)
-{
- struct st_module *stmod =
- (struct st_module *) callback_data;
- char path[1024];
- int ret;
-
- if (len) {
- ret = util_snprintf(path, sizeof(path),
- "%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name);
- }
- else {
- ret = util_snprintf(path, sizeof(path),
- ST_PREFIX "%s" UTIL_DL_EXT, stmod->name);
- }
-
- if (ret > 0 && ret < sizeof(path)) {
- stmod->lib = util_dl_open(path);
- if (stmod->lib)
- _eglLog(_EGL_DEBUG, "loaded %s", path);
- }
-
- return !(stmod->lib);
-}
-
-static boolean
-load_st_module(struct st_module *stmod,
- const char *name, const char *procname)
-{
- struct st_api *(*create_api)(void);
-
- if (name) {
- _eglLog(_EGL_DEBUG, "searching for st module %s", name);
- stmod->name = loader_strdup(name);
- }
- else {
- stmod->name = NULL;
- }
-
- if (stmod->name)
- _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
- else
- stmod->lib = util_dl_open(NULL);
-
- if (stmod->lib) {
- create_api = (struct st_api *(*)(void))
- util_dl_get_proc_address(stmod->lib, procname);
- if (create_api)
- stmod->stapi = create_api();
-
- if (!stmod->stapi) {
- util_dl_close(stmod->lib);
- stmod->lib = NULL;
- }
- }
-
- if (!stmod->stapi) {
- FREE(stmod->name);
- stmod->name = NULL;
- }
-
- return (stmod->stapi != NULL);
-}
-
-static EGLBoolean
-dlopen_pipe_module_cb(const char *dir, size_t len, void *callback_data)
-{
- struct pipe_module *pmod = (struct pipe_module *) callback_data;
- char path[1024];
- int ret;
-
- if (len) {
- ret = util_snprintf(path, sizeof(path),
- "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, dir, pmod->name);
- }
- else {
- ret = util_snprintf(path, sizeof(path),
- PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name);
- }
- if (ret > 0 && ret < sizeof(path)) {
- pmod->lib = util_dl_open(path);
- if (pmod->lib)
- _eglLog(_EGL_DEBUG, "loaded %s", path);
- }
-
- return !(pmod->lib);
-}
-
-static boolean
-load_pipe_module(struct pipe_module *pmod, const char *name)
-{
- pmod->name = loader_strdup(name);
- if (!pmod->name)
- return FALSE;
-
- _eglLog(_EGL_DEBUG, "searching for pipe module %s", pmod->name);
- _eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod);
- if (pmod->lib) {
- pmod->drmdd = (const struct drm_driver_descriptor *)
- util_dl_get_proc_address(pmod->lib, "driver_descriptor");
-
- /* sanity check on the name */
- if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0)
- pmod->drmdd = NULL;
-
- /* swrast */
- if (pmod->drmdd && !pmod->drmdd->driver_name) {
- pmod->swrast_create_screen =
- (struct pipe_screen *(*)(struct sw_winsys *))
- util_dl_get_proc_address(pmod->lib, "swrast_create_screen");
- if (!pmod->swrast_create_screen)
- pmod->drmdd = NULL;
- }
-
- if (!pmod->drmdd) {
- util_dl_close(pmod->lib);
- pmod->lib = NULL;
- }
- }
-
- return (pmod->drmdd != NULL);
-}
-
-static struct st_api *
-get_st_api_full(enum st_api_type api, enum st_profile_type profile)
-{
- struct st_module *stmod = &st_modules[api];
- const char *names[8], *symbol;
- int i, count = 0;
-
- if (stmod->initialized)
- return stmod->stapi;
-
- switch (api) {
- case ST_API_OPENGL:
- symbol = ST_CREATE_OPENGL_SYMBOL;
- names[count++] = "GL";
- break;
- case ST_API_OPENVG:
- symbol = ST_CREATE_OPENVG_SYMBOL;
- names[count++] = "OpenVG";
- break;
- default:
- symbol = NULL;
- assert(!"Unknown API Type\n");
- break;
- }
-
- /* NULL means the process itself */
- names[count++] = NULL;
-
- for (i = 0; i < count; i++) {
- if (load_st_module(stmod, names[i], symbol))
- break;
- }
-
- /* try again with libGL.so loaded */
- if (!stmod->stapi && api == ST_API_OPENGL) {
- struct util_dl_library *glapi = util_dl_open("libGL" UTIL_DL_EXT);
-
- if (glapi) {
- _eglLog(_EGL_DEBUG, "retry with libGL" UTIL_DL_EXT " loaded");
- /* skip the last name (which is NULL) */
- for (i = 0; i < count - 1; i++) {
- if (load_st_module(stmod, names[i], symbol))
- break;
- }
- util_dl_close(glapi);
- }
- }
-
- if (!stmod->stapi) {
- EGLint level = (egl_g3d_loader.profile_masks[api]) ?
- _EGL_WARNING : _EGL_DEBUG;
- _eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]);
- }
-
- stmod->initialized = TRUE;
-
- return stmod->stapi;
-}
-
-static struct st_api *
-get_st_api(enum st_api_type api)
-{
- enum st_profile_type profile = ST_PROFILE_DEFAULT;
-
- /* determine the profile from the linked libraries */
- if (api == ST_API_OPENGL) {
- struct util_dl_library *self;
-
- self = util_dl_open(NULL);
- if (self) {
- if (util_dl_get_proc_address(self, "glColor4x"))
- profile = ST_PROFILE_OPENGL_ES1;
- else if (util_dl_get_proc_address(self, "glShaderBinary"))
- profile = ST_PROFILE_OPENGL_ES2;
- util_dl_close(self);
- }
- }
-
- return get_st_api_full(api, profile);
-}
-
-static struct st_api *
-guess_gl_api(enum st_profile_type profile)
-{
- return get_st_api_full(ST_API_OPENGL, profile);
-}
-
-static struct pipe_module *
-get_pipe_module(const char *name)
-{
- struct pipe_module *pmod = NULL;
- int i;
-
- if (!name)
- return NULL;
-
- for (i = 0; i < Elements(pipe_modules); i++) {
- if (!pipe_modules[i].initialized ||
- strcmp(pipe_modules[i].name, name) == 0) {
- pmod = &pipe_modules[i];
- break;
- }
- }
- if (!pmod)
- return NULL;
-
- if (!pmod->initialized) {
- load_pipe_module(pmod, name);
- pmod->initialized = TRUE;
- }
-
- return pmod;
-}
-
-static char *
-drm_fd_get_screen_name(int fd)
-{
- char *driver = NULL;
-#ifdef HAVE_LIBUDEV
- struct udev *udev;
- struct udev_device *device, *parent;
- struct stat buf;
- const char *pci_id;
- int vendor_id, chip_id, i, j;
-
- udev = udev_new();
- if (fstat(fd, &buf) < 0) {
- _eglLog(_EGL_WARNING, "failed to stat fd %d", fd);
- return NULL;
- }
-
- device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
- if (device == NULL) {
- _eglLog(_EGL_WARNING,
- "could not create udev device for fd %d", fd);
- return NULL;
- }
-
- parent = udev_device_get_parent(device);
- if (parent == NULL) {
- _eglLog(_EGL_WARNING, "could not get parent device");
- goto out;
- }
-
- pci_id = udev_device_get_property_value(parent, "PCI_ID");
- if (pci_id == NULL ||
- sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
- _eglLog(_EGL_WARNING, "malformed or no PCI ID");
- goto out;
- }
-
- for (i = 0; driver_map[i].driver; i++) {
- if (vendor_id != driver_map[i].vendor_id)
- continue;
- if (driver_map[i].num_chips_ids == -1) {
- driver = strdup(driver_map[i].driver);
- _eglLog(_EGL_WARNING,
- "pci id for %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver);
- goto out;
- }
-
- for (j = 0; j < driver_map[i].num_chips_ids; j++)
- if (driver_map[i].chip_ids[j] == chip_id) {
- driver = strdup(driver_map[i].driver);
- _eglLog(_EGL_WARNING,
- "pci id for %d: %04x:%04x, driver %s",
- fd, vendor_id, chip_id, driver);
- goto out;
- }
- }
-
-out:
- udev_device_unref(device);
- udev_unref(udev);
-
-#endif
- return driver;
-}
-
-static struct pipe_screen *
-create_drm_screen(const char *name, int fd)
-{
- struct pipe_module *pmod;
- const char *screen_name = name;
-
- if (screen_name == NULL)
- if ((screen_name = drm_fd_get_screen_name(fd)) == NULL)
- return NULL;
- pmod = get_pipe_module(screen_name);
-
- return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ?
- pmod->drmdd->create_screen(fd) : NULL;
-}
-
-static struct pipe_screen *
-create_sw_screen(struct sw_winsys *ws)
-{
- struct pipe_module *pmod = get_pipe_module("swrast");
- return (pmod && pmod->swrast_create_screen) ?
- pmod->swrast_create_screen(ws) : NULL;
-}
-
-static const struct egl_g3d_loader *
-loader_init(void)
-{
- /* TODO detect at runtime? */
-#if FEATURE_GL
- egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_DEFAULT_MASK;
-#endif
-#if FEATURE_ES1
- egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES1_MASK;
-#endif
-#if FEATURE_ES2
- egl_g3d_loader.profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES2_MASK;
-#endif
-#if FEATURE_VG
- egl_g3d_loader.profile_masks[ST_API_OPENVG] |= ST_PROFILE_DEFAULT_MASK;
-#endif
-
- egl_g3d_loader.get_st_api = get_st_api;
- egl_g3d_loader.guess_gl_api = guess_gl_api;
- egl_g3d_loader.create_drm_screen = create_drm_screen;
- egl_g3d_loader.create_sw_screen = create_sw_screen;
-
- return &egl_g3d_loader;
-}
-
-static void
-loader_fini(void)
-{
- int i;
-
- for (i = 0; i < ST_API_COUNT; i++) {
- struct st_module *stmod = &st_modules[i];
-
- if (stmod->stapi) {
- stmod->stapi->destroy(stmod->stapi);
- stmod->stapi = NULL;
- }
- if (stmod->lib) {
- util_dl_close(stmod->lib);
- stmod->lib = NULL;
- }
- if (stmod->name) {
- FREE(stmod->name);
- stmod->name = NULL;
- }
- stmod->initialized = FALSE;
- }
- for (i = 0; i < Elements(pipe_modules); i++) {
- struct pipe_module *pmod = &pipe_modules[i];
-
- if (!pmod->initialized)
- break;
-
- pmod->drmdd = NULL;
- pmod->swrast_create_screen = NULL;
- if (pmod->lib) {
- util_dl_close(pmod->lib);
- pmod->lib = NULL;
- }
- if (pmod->name) {
- FREE(pmod->name);
- pmod->name = NULL;
- }
- pmod->initialized = FALSE;
- }
-}
-
-static void
-egl_g3d_unload(_EGLDriver *drv)
-{
- egl_g3d_destroy_driver(drv);
- loader_fini();
-}
-
-_EGLDriver *
-_eglMain(const char *args)
-{
- const struct egl_g3d_loader *loader;
- _EGLDriver *drv;
-
- loader = loader_init();
- drv = egl_g3d_create_driver(loader);
- if (!drv) {
- loader_fini();
- return NULL;
- }
-
- drv->Name = "Gallium";
- drv->Unload = egl_g3d_unload;
-
- return drv;
-}
diff --git a/src/gallium/targets/egl/st_GL.c b/src/gallium/targets/egl/st_GL.c
deleted file mode 100644
index c1df844aa43..00000000000
--- a/src/gallium/targets/egl/st_GL.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "state_tracker/st_gl_api.h"
-#include "egl.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenGL(void)
-{
- return st_gl_api_create();
-}
diff --git a/src/gallium/targets/egl/st_OpenVG.c b/src/gallium/targets/egl/st_OpenVG.c
deleted file mode 100644
index d0bf4dbae91..00000000000
--- a/src/gallium/targets/egl/st_OpenVG.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "vg_api.h"
-#include "egl.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenVG(void)
-{
- return (struct st_api *) vg_api_get();
-}
diff --git a/src/gallium/targets/gbm/Makefile b/src/gallium/targets/gbm/Makefile
new file mode 100644
index 00000000000..53104253d4f
--- /dev/null
+++ b/src/gallium/targets/gbm/Makefile
@@ -0,0 +1,169 @@
+# src/gallium/targets/gbm/Makefile
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+PIPE_PREFIX := pipe_
+
+GBM_BACKEND = gbm_gallium_drm
+GBM_SOURCES = gbm.c pipe_loader.c
+
+GBM_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gallium/state_trackers/gbm \
+ -I$(TOP)/src/gbm/main \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/include \
+
+GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) \
+ $(TOP)/src/gallium/state_trackers/gbm/libgbm.a \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/rbug/librbug.a \
+ $(GALLIUM_AUXILIARIES)
+
+
+GBM_CFLAGS = \
+ -DGBM_BACKEND_SEARCH_DIR=\"$(GBM_BACKEND_INSTALL_DIR)\" \
+ -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" \
+ $(LIBUDEV_CFLAGS) \
+ $(LIBDRM_CFLAGS)
+
+
+pipe_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/winsys
+
+pipe_LIBS = \
+ $(TOP)/src/gallium/drivers/identity/libidentity.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/rbug/librbug.a \
+ $(GALLIUM_AUXILIARIES)
+
+# as if we are DRI modules
+pipe_SYS = $(DRI_LIB_DEPS)
+
+pipe_CLFLAGS = \
+ -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD \
+ $(LIBDRM_CFLAGS)
+
+pipe_LDFLAGS = -Wl,--no-undefined
+
+# i915 pipe driver
+i915_LIBS = \
+ $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
+ $(TOP)/src/gallium/drivers/i915/libi915.a
+i915_SYS = -ldrm_intel
+
+# i965 pipe driver
+i965_LIBS = \
+ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a
+i965_SYS = -ldrm_intel
+
+# nouveau pipe driver
+nouveau_LIBS = \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
+nouveau_SYS = -ldrm_nouveau
+
+# r300 pipe driver
+r300_LIBS = \
+ $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
+ $(TOP)/src/gallium/drivers/r300/libr300.a
+r300_SYS = -ldrm_radeon
+
+# r600 pipe driver
+r600_LIBS = \
+ $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
+ $(TOP)/src/gallium/drivers/r600/libr600.a
+r600_SYS = -ldrm_radeon
+
+# vmwgfx pipe driver
+vmwgfx_LIBS = \
+ $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
+ $(TOP)/src/gallium/drivers/svga/libsvga.a
+
+# LLVM
+ifeq ($(MESA_LLVM),1)
+pipe_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+pipe_SYS += $(LLVM_LIBS)
+pipe_LDFLAGS += $(LLVM_LDFLAGS)
+endif
+
+# determine the targets/sources
+pipe_TARGETS =
+pipe_SOURCES =
+
+ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)i915.so
+pipe_SOURCES += pipe_i915.c
+endif
+
+ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)i965.so
+pipe_SOURCES += pipe_i965.c
+endif
+
+ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)nouveau.so
+pipe_SOURCES += pipe_nouveau.c
+endif
+
+ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)r300.so
+pipe_SOURCES += pipe_r300.c
+endif
+
+ifneq ($(findstring r600/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)r600.so
+pipe_SOURCES += pipe_r600.c
+endif
+
+ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),)
+pipe_TARGETS += $(PIPE_PREFIX)vmwgfx.so
+pipe_SOURCES += pipe_vmwgfx.c
+endif
+
+pipe_OBJECTS = $(pipe_SOURCES:.c=.o)
+
+
+GBM_EXTRA_TARGETS = $(addprefix $(TOP)/$(LIB_DIR)/gbm/, $(pipe_TARGETS))
+GBM_EXTRA_INSTALL = install-pipes
+GBM_EXTRA_CLEAN = clean-pipes
+GBM_EXTRA_SOURCES = $(pipe_SOURCES)
+
+include $(TOP)/src/gbm/backends/Makefile.template
+
+
+$(GBM_EXTRA_TARGETS): $(TOP)/$(LIB_DIR)/gbm/%: %
+ @$(INSTALL) -d $(dir $@)
+ $(INSTALL) $< $(dir $@)
+
+$(pipe_TARGETS): $(PIPE_PREFIX)%.so: pipe_%.o
+ $(MKLIB) -o $@ -noprefix -linker '$(CC)' \
+ -ldflags '-L$(TOP)/$(LIB_DIR) $(pipe_LDFLAGS) $(LDFLAGS)' \
+ $(MKLIB_OPTIONS) $< \
+ -Wl,--start-group $(pipe_LIBS) $($*_LIBS) -Wl,--end-group \
+ $(pipe_SYS) $($*_SYS)
+
+$(pipe_OBJECTS): %.o: %.c
+ $(CC) -c -o $@ $< $(pipe_INCLUDES) $(pipe_CFLAGS) $(CFLAGS)
+
+install-pipes: $(GBM_EXTRA_TARGETS)
+ $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR)
+ for tgt in $(GBM_EXTRA_TARGETS); do \
+ $(MINSTALL) "$$tgt" $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR); \
+ done
+
+clean-pipes:
+ rm -f $(pipe_TARGETS)
+ rm -f $(pipe_OBJECTS)
diff --git a/src/gallium/targets/gbm/gbm.c b/src/gallium/targets/gbm/gbm.c
new file mode 100644
index 00000000000..e840fc5fa1a
--- /dev/null
+++ b/src/gallium/targets/gbm/gbm.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include "util/u_inlines.h"
+
+#include "gbm_gallium_drmint.h"
+#include "pipe_loader.h"
+
+static struct pipe_screen *
+create_drm_screen(const char *name, int fd)
+{
+ struct pipe_module *pmod = get_pipe_module(name);
+
+ return (pmod && pmod->drmdd && pmod->drmdd->create_screen) ?
+ pmod->drmdd->create_screen(fd) : NULL;
+}
+
+int
+gallium_screen_create(struct gbm_gallium_drm_device *gdrm)
+{
+ gdrm->base.driver_name = drm_fd_get_screen_name(gdrm->base.base.fd);
+ if (gdrm->base.driver_name == NULL)
+ return -1;
+
+ gdrm->screen = create_drm_screen(gdrm->base.driver_name, gdrm->base.base.fd);
+ if (gdrm->screen == NULL) {
+ debug_printf("failed to load driver: %s\n", gdrm->base.driver_name);
+ return -1;
+ };
+
+ return 0;
+}
+
+GBM_EXPORT struct gbm_backend gbm_backend = {
+ .backend_name = "gallium_drm",
+ .create_device = gbm_gallium_drm_device_create,
+};
diff --git a/src/gallium/targets/egl/pipe_i915.c b/src/gallium/targets/gbm/pipe_i915.c
index cd74044d8c1..cd74044d8c1 100644
--- a/src/gallium/targets/egl/pipe_i915.c
+++ b/src/gallium/targets/gbm/pipe_i915.c
diff --git a/src/gallium/targets/egl/pipe_i965.c b/src/gallium/targets/gbm/pipe_i965.c
index f810ecffb0a..f810ecffb0a 100644
--- a/src/gallium/targets/egl/pipe_i965.c
+++ b/src/gallium/targets/gbm/pipe_i965.c
diff --git a/src/gallium/targets/gbm/pipe_loader.c b/src/gallium/targets/gbm/pipe_loader.c
new file mode 100644
index 00000000000..6200541dbf0
--- /dev/null
+++ b/src/gallium/targets/gbm/pipe_loader.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Kristian Høgsberg <krh@bitplanet.net>
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include "util/u_string.h"
+#include "util/u_memory.h"
+
+#include <libudev.h>
+
+#include "gbm_gallium_drmint.h"
+#include "pipe_loader.h"
+#define DRIVER_MAP_GALLIUM_ONLY
+#include "pci_ids/pci_id_driver_map.h"
+
+static struct pipe_module pipe_modules[16];
+
+static INLINE char *
+loader_strdup(const char *str)
+{
+ return mem_dup(str, strlen(str) + 1);
+}
+
+char *
+drm_fd_get_screen_name(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device, *parent;
+ const char *pci_id;
+ char *driver = NULL;
+ int vendor_id, chip_id, i, j;
+
+ udev = udev_new();
+ device = _gbm_udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ fprintf(stderr, "gbm: could not get parent device");
+ goto out;
+ }
+
+ pci_id = udev_device_get_property_value(parent, "PCI_ID");
+ if (pci_id == NULL ||
+ sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+ fprintf(stderr, "gbm: malformed or no PCI ID");
+ goto out;
+ }
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (vendor_id != driver_map[i].vendor_id)
+ continue;
+ if (driver_map[i].num_chips_ids == -1) {
+ driver = loader_strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++)
+ if (driver_map[i].chip_ids[j] == chip_id) {
+ driver = loader_strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+ }
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return driver;
+}
+
+static void
+find_pipe_module(struct pipe_module *pmod, const char *name)
+{
+ char *search_paths, *end, *next, *p;
+ char path[PATH_MAX];
+ int ret;
+
+ search_paths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use GBM_BACKENDS_PATH */
+ search_paths = getenv("GBM_BACKENDS_PATH");
+ }
+ if (search_paths == NULL)
+ search_paths = GBM_BACKEND_SEARCH_DIR;
+
+ end = search_paths + strlen(search_paths);
+ for (p = search_paths; p < end && pmod->lib == NULL; p = next + 1) {
+ int len;
+ next = strchr(p, ':');
+ if (next == NULL)
+ next = end;
+
+ len = next - p;
+
+ if (len) {
+ ret = util_snprintf(path, sizeof(path),
+ "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, p, pmod->name);
+ }
+ else {
+ ret = util_snprintf(path, sizeof(path),
+ PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name);
+ }
+ if (ret > 0 && ret < sizeof(path)) {
+ pmod->lib = util_dl_open(path);
+ debug_printf("loaded %s\n", path);
+ }
+
+ }
+}
+
+static boolean
+load_pipe_module(struct pipe_module *pmod, const char *name)
+{
+ pmod->name = loader_strdup(name);
+ if (!pmod->name)
+ return FALSE;
+
+ find_pipe_module(pmod, name);
+
+ if (pmod->lib) {
+ pmod->drmdd = (const struct drm_driver_descriptor *)
+ util_dl_get_proc_address(pmod->lib, "driver_descriptor");
+
+ /* sanity check on the name */
+ if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0)
+ pmod->drmdd = NULL;
+
+ if (!pmod->drmdd) {
+ util_dl_close(pmod->lib);
+ pmod->lib = NULL;
+ }
+ }
+
+ return (pmod->drmdd != NULL);
+}
+
+struct pipe_module *
+get_pipe_module(const char *name)
+{
+ struct pipe_module *pmod = NULL;
+ int i;
+
+ if (!name)
+ return NULL;
+
+ for (i = 0; i < Elements(pipe_modules); i++) {
+ if (!pipe_modules[i].initialized ||
+ strcmp(pipe_modules[i].name, name) == 0) {
+ pmod = &pipe_modules[i];
+ break;
+ }
+ }
+ if (!pmod)
+ return NULL;
+
+ if (!pmod->initialized) {
+ load_pipe_module(pmod, name);
+ pmod->initialized = TRUE;
+ }
+
+ return pmod;
+}
diff --git a/src/gallium/targets/gbm/pipe_loader.h b/src/gallium/targets/gbm/pipe_loader.h
new file mode 100644
index 00000000000..2e4cd9906b7
--- /dev/null
+++ b/src/gallium/targets/gbm/pipe_loader.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _PIPE_LOADER_H_
+#define _PIPE_LOADER_H_
+
+#include "pipe/p_compiler.h"
+#include "util/u_dl.h"
+#include "state_tracker/drm_driver.h"
+
+struct pipe_module {
+ boolean initialized;
+ char *name;
+ struct util_dl_library *lib;
+ const struct drm_driver_descriptor *drmdd;
+};
+
+struct pipe_module *
+get_pipe_module(const char *name);
+
+char *
+drm_fd_get_screen_name(int fd);
+
+#endif
diff --git a/src/gallium/targets/egl/pipe_nouveau.c b/src/gallium/targets/gbm/pipe_nouveau.c
index 0c9081bc713..0c9081bc713 100644
--- a/src/gallium/targets/egl/pipe_nouveau.c
+++ b/src/gallium/targets/gbm/pipe_nouveau.c
diff --git a/src/gallium/targets/egl/pipe_r300.c b/src/gallium/targets/gbm/pipe_r300.c
index 09940f0a194..09940f0a194 100644
--- a/src/gallium/targets/egl/pipe_r300.c
+++ b/src/gallium/targets/gbm/pipe_r300.c
diff --git a/src/gallium/targets/egl/pipe_r600.c b/src/gallium/targets/gbm/pipe_r600.c
index 486a6592585..486a6592585 100644
--- a/src/gallium/targets/egl/pipe_r600.c
+++ b/src/gallium/targets/gbm/pipe_r600.c
diff --git a/src/gallium/targets/egl/pipe_swrast.c b/src/gallium/targets/gbm/pipe_swrast.c
index b2e3289c5d3..b2e3289c5d3 100644
--- a/src/gallium/targets/egl/pipe_swrast.c
+++ b/src/gallium/targets/gbm/pipe_swrast.c
diff --git a/src/gallium/targets/egl/pipe_vmwgfx.c b/src/gallium/targets/gbm/pipe_vmwgfx.c
index 22a28fa858a..22a28fa858a 100644
--- a/src/gallium/targets/egl/pipe_vmwgfx.c
+++ b/src/gallium/targets/gbm/pipe_vmwgfx.c
diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript
index ca15372f1d9..7d5d9bc47a9 100644
--- a/src/gallium/targets/libgl-xlib/SConscript
+++ b/src/gallium/targets/libgl-xlib/SConscript
@@ -54,7 +54,7 @@ libgl = env.SharedLibrary(
source = sources,
)
-if True:
+if False:
# XXX: Only install this libGL.so if DRI not enabled
libgl = env.InstallSharedLibrary(libgl, version=(1, 5))
diff --git a/src/gallium/targets/xorg-nouveau/Makefile b/src/gallium/targets/xorg-nouveau/Makefile
index 5a2cdb1b0ef..755969cae27 100644
--- a/src/gallium/targets/xorg-nouveau/Makefile
+++ b/src/gallium/targets/xorg-nouveau/Makefile
@@ -1,7 +1,7 @@
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = modesetting_drv.so
+LIBNAME = nouveau2_drv.so
C_SOURCES = \
nouveau_target.c \
@@ -23,4 +23,7 @@ DRIVER_PIPES = \
DRIVER_LINKS = \
$(shell pkg-config --libs libdrm libdrm_nouveau)
+DRIVER_INCLUDES = \
+ $(shell pkg-config --cflags-only-I libdrm libdrm_nouveau xf86driproto)
+
include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
index f0d64925c73..43470a1656b 100644
--- a/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
+++ b/src/gallium/targets/xorg-nouveau/nouveau_xorg.c
@@ -29,6 +29,9 @@
*/
#include "../../state_trackers/xorg/xorg_winsys.h"
+#include <nouveau_drmif.h>
+#include <xorg/dri.h>
+#include <xf86drmMode.h>
static void nouveau_xorg_identify(int flags);
static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
@@ -38,23 +41,16 @@ static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
static const struct pci_id_match nouveau_xorg_device_match[] = {
{ 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
0x00030000, 0x00ffffff, 0 },
- { 0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
- 0x00030000, 0x00ffffff, 0 },
{0, 0, 0},
};
-static SymTabRec nouveau_xorg_chipsets[] = {
- {PCI_MATCH_ANY, "NVIDIA Graphics Device"},
- {-1, NULL}
-};
-
static PciChipsets nouveau_xorg_pci_devices[] = {
{PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
{-1, -1, NULL}
};
static XF86ModuleVersionInfo nouveau_xorg_version = {
- "modesetting",
+ "nouveau2",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
@@ -70,9 +66,9 @@ static XF86ModuleVersionInfo nouveau_xorg_version = {
* Xorg driver exported structures
*/
-_X_EXPORT DriverRec modesetting = {
+_X_EXPORT DriverRec nouveau2 = {
1,
- "modesetting",
+ "nouveau2",
nouveau_xorg_identify,
NULL,
xorg_tracker_available_options,
@@ -85,7 +81,7 @@ _X_EXPORT DriverRec modesetting = {
static MODULESETUPPROTO(nouveau_xorg_setup);
-_X_EXPORT XF86ModuleData modesettingModuleData = {
+_X_EXPORT XF86ModuleData nouveau2ModuleData = {
&nouveau_xorg_version,
nouveau_xorg_setup,
NULL
@@ -104,7 +100,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
*/
if (!setupDone) {
setupDone = 1;
- xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+ xf86AddDriver(&nouveau2, module, HaveDriverFuncs);
/*
* The return value must be non-NULL on success even though there
@@ -121,8 +117,7 @@ nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
static void
nouveau_xorg_identify(int flags)
{
- xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
- nouveau_xorg_chipsets);
+ xf86DrvMsg(0, X_INFO, "nouveau2: Gallium3D based 2D driver for NV30+ NVIDIA chipsets\n");
}
static Bool
@@ -131,13 +126,63 @@ nouveau_xorg_pci_probe(DriverPtr driver,
{
ScrnInfoPtr scrn = NULL;
EntityInfoPtr entity;
+ struct nouveau_device *dev = NULL;
+ char *busid;
+ int chipset, ret;
+
+ if (device->vendor_id != 0x10DE)
+ return FALSE;
+
+ if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) {
+ xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n");
+ return FALSE;
+ }
+ busid = DRICreatePCIBusID(device);
+
+ ret = nouveau_device_open(&dev, busid);
+ if (ret) {
+ xf86DrvMsg(-1, X_ERROR, "[drm] failed to open device\n");
+ free(busid);
+ return FALSE;
+ }
+
+ chipset = dev->chipset;
+ nouveau_device_close(&dev);
+
+ ret = drmCheckModesettingSupported(busid);
+ free(busid);
+ if (ret) {
+ xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n");
+ return FALSE;
+ }
+
+ switch (chipset & 0xf0) {
+ case 0x00:
+ case 0x10:
+ case 0x20:
+ xf86DrvMsg(-1, X_NOTICE, "Too old chipset: NV%02x\n", chipset);
+ return FALSE;
+ case 0x30:
+ case 0x40:
+ case 0x60:
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ case 0xc0:
+ xf86DrvMsg(-1, X_INFO, "Detected chipset: NV%02x\n", chipset);
+ break;
+ default:
+ xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset);
+ return FALSE;
+ }
scrn = xf86ConfigPciEntity(scrn, 0, entity_num, nouveau_xorg_pci_devices,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
scrn->driverName = "nouveau";
- scrn->name = "modesetting";
+ scrn->name = "nouveau2";
scrn->Probe = NULL;
entity = xf86GetEntityInfo(entity_num);
diff --git a/src/gallium/targets/xorg-vmwgfx/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript
index 099d49cf1b7..41f4326ee86 100644
--- a/src/gallium/targets/xorg-vmwgfx/SConscript
+++ b/src/gallium/targets/xorg-vmwgfx/SConscript
@@ -4,10 +4,10 @@ Import('*')
env = env.Clone()
-env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server')
+env.PkgUseModules(['DRM', 'XORG'])
if env['kms']:
- env.ParseConfig('pkg-config --cflags --libs libkms')
+ env.PkgUseModules(['KMS'])
env.Prepend(CPPPATH = [
'#/include',
diff --git a/src/gallium/tests/trivial/Makefile b/src/gallium/tests/trivial/Makefile
index 2ed63419c7e..4ddbb0b73dc 100644
--- a/src/gallium/tests/trivial/Makefile
+++ b/src/gallium/tests/trivial/Makefile
@@ -1,4 +1,4 @@
-# progs/gallium/simple/Makefile
+# src/gallium/tests/trivial/Makefile
TOP = ../../../..
include $(TOP)/configs/current
@@ -11,7 +11,12 @@ INCLUDES = \
-I$(TOP)/src/gallium/winsys \
$(PROG_INCLUDES)
-LINKS = \
+ifeq ($(MESA_LLVM),1)
+LINKS = $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+LDFLAGS += $(LLVM_LDFLAGS)
+endif
+
+LINKS += \
$(TOP)/src/gallium/drivers/rbug/librbug.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/galahad/libgalahad.a \
@@ -46,4 +51,4 @@ $(OBJECTS): %.o: %.c
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@
$(PROGS): %: %.o $(LINKS)
- $(CC) $(LDFLAGS) $< $(LINKS) -lm -lpthread -ldl -o $@
+ $(CXX) $(LDFLAGS) $< $(LINKS) $(LLVM_LIBS) -lm -lpthread -ldl -o $@
diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c
index 3a64b1c8d96..6c38b1096c1 100644
--- a/src/gallium/tests/trivial/quad-tex.c
+++ b/src/gallium/tests/trivial/quad-tex.c
@@ -212,7 +212,7 @@ static void init_prog(struct program *p)
p->sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
p->sampler.normalized_coords = 1;
- surf_tmpl.format = templat.format;
+ surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM; /* All drivers support this */
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
surf_tmpl.u.tex.level = 0;
surf_tmpl.u.tex.first_layer = 0;
@@ -329,7 +329,7 @@ static void draw(struct program *p)
/* vertex element data */
cso_set_vertex_elements(p->cso, 2, p->velem);
- util_draw_vertex_buffer(p->pipe,
+ util_draw_vertex_buffer(p->pipe, p->cso,
p->vbuf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c
index bfd2f3ca9a3..656e92ee886 100644
--- a/src/gallium/tests/trivial/tri.c
+++ b/src/gallium/tests/trivial/tri.c
@@ -153,7 +153,7 @@ static void init_prog(struct program *p)
p->rasterizer.cull_face = PIPE_FACE_NONE;
p->rasterizer.gl_rasterization_rules = 1;
- surf_tmpl.format = templat.format;
+ surf_tmpl.format = PIPE_FORMAT_B8G8R8A8_UNORM;
surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
surf_tmpl.u.tex.level = 0;
surf_tmpl.u.tex.first_layer = 0;
@@ -258,7 +258,7 @@ static void draw(struct program *p)
/* vertex element data */
cso_set_vertex_elements(p->cso, 2, p->velem);
- util_draw_vertex_buffer(p->pipe,
+ util_draw_vertex_buffer(p->pipe, p->cso,
p->vbuf, 0,
PIPE_PRIM_TRIANGLES,
3, /* verts */
diff --git a/src/gallium/winsys/i915/drm/SConscript b/src/gallium/winsys/i915/drm/SConscript
index d8f5885b62c..15c97998fd8 100644
--- a/src/gallium/winsys/i915/drm/SConscript
+++ b/src/gallium/winsys/i915/drm/SConscript
@@ -2,7 +2,7 @@ Import('*')
env = env.Clone()
-env.ParseConfig('pkg-config --cflags libdrm')
+env.PkgUseModules('DRM')
i915drm_sources = [
'i915_drm_batchbuffer.c',
diff --git a/src/gallium/winsys/i965/drm/SConscript b/src/gallium/winsys/i965/drm/SConscript
index 785be449f70..a0f32ded402 100644
--- a/src/gallium/winsys/i965/drm/SConscript
+++ b/src/gallium/winsys/i965/drm/SConscript
@@ -2,7 +2,7 @@ Import('*')
env = env.Clone()
-env.ParseConfig('pkg-config --cflags libdrm')
+env.PkgUseModules('DRM')
i965drm_sources = [
'i965_drm_buffer.c',
diff --git a/src/gallium/winsys/r600/drm/SConscript b/src/gallium/winsys/r600/drm/SConscript
index cc9a06a2393..f55bb265226 100644
--- a/src/gallium/winsys/r600/drm/SConscript
+++ b/src/gallium/winsys/r600/drm/SConscript
@@ -13,11 +13,7 @@ r600_sources = [
'r600_bomgr.c',
]
-try:
- env.ParseConfig('pkg-config --cflags libdrm_radeon')
-except OSError:
- print 'warning: not building r600g'
- Return()
+env.PkgUseModules('DRM_RADEON')
env.Append(CPPPATH = '#/src/gallium/drivers/r600')
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 03fe385334c..4602f7f2a4b 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -156,7 +156,20 @@ static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
return -EINVAL;
}
- radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4;
+ switch ((tiling_config & 0xf0) >> 4) {
+ case 0:
+ radeon->tiling_info.num_banks = 4;
+ break;
+ case 1:
+ radeon->tiling_info.num_banks = 8;
+ break;
+ case 2:
+ radeon->tiling_info.num_banks = 16;
+ break;
+ default:
+ return -EINVAL;
+
+ }
switch ((tiling_config & 0xf00) >> 8) {
case 0:
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index f89f24c4d18..19dc729d00a 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -62,6 +62,8 @@ void r600_init_cs(struct r600_context *ctx)
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_CONTEXT_CONTROL, 1, 0);
ctx->pm4[ctx->pm4_cdwords++] = 0x80000000;
ctx->pm4[ctx->pm4_cdwords++] = 0x80000000;
+
+ ctx->init_dwords = ctx->pm4_cdwords;
}
static void INLINE r600_context_update_fenced_list(struct r600_context *ctx)
@@ -1496,7 +1498,7 @@ void r600_context_flush(struct r600_context *ctx)
int r;
struct r600_block *enable_block = NULL;
- if (!ctx->pm4_cdwords)
+ if (ctx->pm4_cdwords == ctx->init_dwords)
return;
/* suspend queries */
diff --git a/src/gallium/winsys/radeon/drm/SConscript b/src/gallium/winsys/radeon/drm/SConscript
index 39a8c711b84..2edb1e94645 100644
--- a/src/gallium/winsys/radeon/drm/SConscript
+++ b/src/gallium/winsys/radeon/drm/SConscript
@@ -8,11 +8,7 @@ radeon_sources = [
'radeon_drm_winsys.c',
]
-try:
- env.ParseConfig('pkg-config --cflags libdrm')
-except:
- print 'warning: not building Gallium Radeon'
- Return()
+env.PkgUseModules('DRM')
radeonwinsys = env.ConvenienceLibrary(
target ='radeonwinsys',
diff --git a/src/gallium/winsys/svga/drm/SConscript b/src/gallium/winsys/svga/drm/SConscript
index b049ea60aa8..3e25c8aa748 100644
--- a/src/gallium/winsys/svga/drm/SConscript
+++ b/src/gallium/winsys/svga/drm/SConscript
@@ -2,7 +2,7 @@ Import('*')
env = env.Clone()
-env.ParseConfig('pkg-config --cflags libdrm')
+env.PkgUseModules('DRM')
if env['gcc']:
env.Append(CCFLAGS = ['-fvisibility=hidden'])
diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
index f4f4cd7969b..38d88f63aa2 100644
--- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
+++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
@@ -54,10 +54,8 @@ struct fbdev_sw_winsys
struct sw_winsys base;
int fd;
- enum pipe_format format;
struct fb_fix_screeninfo finfo;
- void *fbmem;
unsigned rows;
unsigned stride;
};
@@ -77,22 +75,53 @@ fbdev_sw_winsys(struct sw_winsys *ws)
static void
fbdev_displaytarget_display(struct sw_winsys *ws,
struct sw_displaytarget *dt,
- void *context_private)
+ void *winsys_private)
{
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
- struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
- unsigned rows, len, i;
+ struct fbdev_sw_displaytarget *src = fbdev_sw_displaytarget(dt);
+ const struct fbdev_sw_drawable *dst =
+ (const struct fbdev_sw_drawable *) winsys_private;
+ unsigned height, row_offset, row_len, i;
+ void *fbmem;
+
+ /* FIXME format conversion */
+ if (dst->format != src->format) {
+ assert(0);
+ return;
+ }
- rows = MIN2(fbdt->height, fbdev->rows);
- len = util_format_get_stride(fbdt->format, fbdt->width);
- len = MIN2(len, fbdev->stride);
+ height = dst->height;
+ if (dst->y + dst->height > fbdev->rows) {
+ /* nothing to copy */
+ if (dst->y >= fbdev->rows)
+ return;
- for (i = 0; i < rows; i++) {
- void *dst = fbdev->fbmem + fbdev->stride * i;
- void *src = fbdt->data + fbdt->stride * i;
+ height = fbdev->rows - dst->y;
+ }
+
+ row_offset = util_format_get_stride(dst->format, dst->x);
+ row_len = util_format_get_stride(dst->format, dst->width);
+ if (row_offset + row_len > fbdev->stride) {
+ /* nothing to copy */
+ if (row_offset >= fbdev->stride)
+ return;
- memcpy(dst, src, len);
+ row_len = fbdev->stride - row_offset;
}
+
+ fbmem = mmap(0, fbdev->finfo.smem_len,
+ PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
+ if (fbmem == MAP_FAILED)
+ return;
+
+ for (i = 0; i < height; i++) {
+ char *from = (char *) src->data + src->stride * i;
+ char *to = (char *) fbmem + fbdev->stride * (dst->y + i) + row_offset;
+
+ memcpy(to, from, row_len);
+ }
+
+ munmap(fbmem, fbdev->finfo.smem_len);
}
static void
@@ -133,13 +162,9 @@ fbdev_displaytarget_create(struct sw_winsys *ws,
unsigned alignment,
unsigned *stride)
{
- struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
struct fbdev_sw_displaytarget *fbdt;
unsigned nblocksy, size, format_stride;
- if (fbdev->format != format)
- return NULL;
-
fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget);
if (!fbdt)
return NULL;
@@ -170,8 +195,7 @@ fbdev_is_displaytarget_format_supported(struct sw_winsys *ws,
unsigned tex_usage,
enum pipe_format format)
{
- struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
- return (fbdev->format == format);
+ return TRUE;
}
static void
@@ -179,12 +203,11 @@ fbdev_destroy(struct sw_winsys *ws)
{
struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
- munmap(fbdev->fbmem, fbdev->finfo.smem_len);
FREE(fbdev);
}
struct sw_winsys *
-fbdev_create_sw_winsys(int fd, enum pipe_format format)
+fbdev_create_sw_winsys(int fd)
{
struct fbdev_sw_winsys *fbdev;
@@ -193,19 +216,11 @@ fbdev_create_sw_winsys(int fd, enum pipe_format format)
return NULL;
fbdev->fd = fd;
- fbdev->format = format;
if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) {
FREE(fbdev);
return NULL;
}
- fbdev->fbmem = mmap(0, fbdev->finfo.smem_len,
- PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
- if (fbdev->fbmem == MAP_FAILED) {
- FREE(fbdev);
- return NULL;
- }
-
fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length;
fbdev->stride = fbdev->finfo.line_length;
diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h
index d958ab9db3e..59d8a8f5cfe 100644
--- a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h
+++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h
@@ -32,7 +32,14 @@
struct sw_winsys;
enum pipe_format;
+/* for pipe_screen::flush_frontbuffer */
+struct fbdev_sw_drawable {
+ enum pipe_format format;
+ unsigned x, y;
+ unsigned width, height;
+};
+
struct sw_winsys *
-fbdev_create_sw_winsys(int fd, enum pipe_format format);
+fbdev_create_sw_winsys(int fd);
#endif /* FBDEV_SW_WINSYS */
diff --git a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h
index 5e3cfd0bf23..bedd2408f05 100644
--- a/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h
+++ b/src/gallium/winsys/sw/wayland/wayland_sw_winsys.h
@@ -27,6 +27,7 @@
#define WAYLAND_SW_WINSYS
struct sw_winsys;
+struct wl_display;
struct winsys_handle {
int fd;
diff --git a/src/gbm/Makefile b/src/gbm/Makefile
new file mode 100644
index 00000000000..4769a97b699
--- /dev/null
+++ b/src/gbm/Makefile
@@ -0,0 +1,14 @@
+# src/gbm/Makefile
+
+TOP = ../..
+include $(TOP)/configs/current
+
+SUBDIRS = backends main
+
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gbm/backends/Makefile b/src/gbm/backends/Makefile
new file mode 100644
index 00000000000..97eaac496d2
--- /dev/null
+++ b/src/gbm/backends/Makefile
@@ -0,0 +1,14 @@
+# src/gbm/backends/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GBM_BACKEND_DIRS)
+
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir ; $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gbm/backends/Makefile.template b/src/gbm/backends/Makefile.template
new file mode 100644
index 00000000000..851e5c56217
--- /dev/null
+++ b/src/gbm/backends/Makefile.template
@@ -0,0 +1,65 @@
+# src/gbm/backends/Makefile.template
+#
+# Backends should define
+#
+# GBM_BACKEND, the driver name
+# GBM_SOURCES, the driver sources
+# GBM_INCLUDES, the include pathes
+# GBM_CFLAGS, additional CFLAGS
+# GBM_LIBS, additional LIBS
+#
+# before including this template.
+#
+
+
+GBM_BACKEND_PATH = $(TOP)/$(LIB_DIR)/gbm/$(GBM_BACKEND).so
+GBM_OBJECTS = $(GBM_SOURCES:.c=.o)
+
+# built-in or external
+ifeq ($(GBM_BUILTIN), true)
+GBM_TARGET = lib$(GBM_BACKEND).a
+GBM_INSTALL =
+else
+GBM_TARGET = $(GBM_BACKEND_PATH)
+GBM_INSTALL = install-so
+endif
+
+default: depend $(GBM_TARGET) $(GBM_EXTRA_TARGETS)
+
+$(GBM_BACKEND_PATH): $(GBM_BACKEND).so
+ @$(INSTALL) -d $(TOP)/$(LIB_DIR)/gbm
+ $(INSTALL) $< $(TOP)/$(LIB_DIR)/gbm
+
+$(GBM_BACKEND).so: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template
+ @$(MKLIB) -o $(GBM_BACKEND).so -noprefix \
+ -linker '$(CC)' -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \
+ $(MKLIB_OPTIONS) \
+ $(GBM_OBJECTS) $(GBM_LIBS) -l$(GBM_LIB)
+
+lib$(GBM_BACKEND).a: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template
+ @$(MKLIB) -o $(GBM_BACKEND) -static $(GBM_OBJECTS)
+
+.c.o:
+ $(CC) -c $(GBM_INCLUDES) $(CFLAGS) $(GBM_CFLAGS) $< -o $@
+
+install-so: $(GBM_BACKEND_PATH)
+ $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR)
+ $(MINSTALL) $(GBM_BACKEND_PATH) $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR)
+
+install: $(GBM_INSTALL) $(GBM_EXTRA_INSTALL)
+
+clean: $(GBM_EXTRA_CLEAN)
+ rm -f $(GBM_BACKEND).so
+ rm -f lib$(GBM_BACKEND).a
+ rm -f $(GBM_OBJECTS)
+ rm -f depend depend.bak
+
+depend: $(GBM_SOURCES) $(GBM_EXTRA_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(GBM_INCLUDES) $(GBM_SOURCES) \
+ $(GBM_EXTRA_SOURCES) >/dev/null 2>/dev/null
+
+sinclude depend
+# DO NOT DELETE
diff --git a/src/gbm/backends/dri/Makefile b/src/gbm/backends/dri/Makefile
new file mode 100644
index 00000000000..78fb3291227
--- /dev/null
+++ b/src/gbm/backends/dri/Makefile
@@ -0,0 +1,22 @@
+# src/gbm/backends/dri/Makefile
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+GBM_BACKEND = gbm_dri
+GBM_SOURCES = gbm_dri.c driver_name.c
+
+GBM_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gbm/main \
+
+GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) -L$(TOP)/lib -lglapi
+
+GBM_CFLAGS = \
+ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
+ $(LIBUDEV_CFLAGS) \
+ $(LIBDRM_CFLAGS)
+
+GBM_BUILTIN=true
+
+include ../Makefile.template
diff --git a/src/gbm/backends/dri/driver_name.c b/src/gbm/backends/dri/driver_name.c
new file mode 100644
index 00000000000..2ed209fa438
--- /dev/null
+++ b/src/gbm/backends/dri/driver_name.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Kristian Høgsberg <krh@bitplanet.net>
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libudev.h>
+
+#include "gbm_driint.h"
+#define DRIVER_MAP_DRI2_ONLY
+#include "pci_ids/pci_id_driver_map.h"
+
+char *
+dri_fd_get_driver_name(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device, *parent;
+ const char *pci_id;
+ char *driver = NULL;
+ int vendor_id, chip_id, i, j;
+
+ udev = udev_new();
+ device = _gbm_udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ fprintf(stderr, "gbm: could not get parent device");
+ goto out;
+ }
+
+ pci_id = udev_device_get_property_value(parent, "PCI_ID");
+ if (pci_id == NULL ||
+ sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+ fprintf(stderr, "gbm: malformed or no PCI ID");
+ goto out;
+ }
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (vendor_id != driver_map[i].vendor_id)
+ continue;
+ if (driver_map[i].num_chips_ids == -1) {
+ driver = strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++)
+ if (driver_map[i].chip_ids[j] == chip_id) {
+ driver = strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+ }
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return driver;
+}
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
new file mode 100644
index 00000000000..6bb7848d830
--- /dev/null
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include <GL/gl.h> /* dri_interface needs GL types */
+#include <GL/internal/dri_interface.h>
+
+#include "gbm_driint.h"
+
+#include "gbmint.h"
+
+static __DRIimage *
+dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
+{
+ struct gbm_dri_device *dri = data;
+
+ if (dri->lookup_image == NULL)
+ return NULL;
+
+ return dri->lookup_image(screen, image, dri->lookup_user_data);
+}
+
+const __DRIuseInvalidateExtension use_invalidate = {
+ { __DRI_USE_INVALIDATE, 1 }
+};
+
+const __DRIimageLookupExtension image_lookup_extension = {
+ { __DRI_IMAGE_LOOKUP, 1 },
+ dri_lookup_egl_image
+};
+
+struct dri_extension_match {
+ const char *name;
+ int version;
+ int offset;
+};
+
+static struct dri_extension_match dri_core_extensions[] = {
+ { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) },
+ { NULL, 0, 0 }
+};
+
+static struct dri_extension_match gbm_dri_device_extensions[] = {
+ { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) },
+ { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) },
+ { NULL, 0, 0 }
+};
+
+static int
+dri_bind_extensions(struct gbm_dri_device *dri,
+ struct dri_extension_match *matches,
+ const __DRIextension **extensions)
+{
+ int i, j, ret = 0;
+ void *field;
+
+ for (i = 0; extensions[i]; i++) {
+ for (j = 0; matches[j].name; j++) {
+ if (strcmp(extensions[i]->name, matches[j].name) == 0 &&
+ extensions[i]->version >= matches[j].version) {
+ field = ((char *) dri + matches[j].offset);
+ *(const __DRIextension **) field = extensions[i];
+ }
+ }
+ }
+
+ for (j = 0; matches[j].name; j++) {
+ field = ((char *) dri + matches[j].offset);
+ if (*(const __DRIextension **) field == NULL) {
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+static int
+dri_load_driver(struct gbm_dri_device *dri)
+{
+ const __DRIextension **extensions;
+ char path[PATH_MAX], *search_paths, *p, *next, *end;
+
+ search_paths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use GBM_DRIVERS_PATH */
+ search_paths = getenv("GBM_DRIVERS_PATH");
+ }
+ if (search_paths == NULL)
+ search_paths = DEFAULT_DRIVER_DIR;
+
+ dri->driver = NULL;
+ end = search_paths + strlen(search_paths);
+ for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) {
+ int len;
+ next = strchr(p, ':');
+ if (next == NULL)
+ next = end;
+
+ len = next - p;
+#if GLX_USE_TLS
+ snprintf(path, sizeof path,
+ "%.*s/tls/%s_dri.so", len, p, dri->base.driver_name);
+ dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+#endif
+ if (dri->driver == NULL) {
+ snprintf(path, sizeof path,
+ "%.*s/%s_dri.so", len, p, dri->base.driver_name);
+ dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dri->driver == NULL)
+ fprintf(stderr, "failed to open %s: %s\n", path, dlerror());
+ }
+ }
+
+ if (dri->driver == NULL) {
+ fprintf(stderr, "gbm: failed to open any driver (search paths %s)",
+ search_paths);
+ return -1;
+ }
+
+ extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror());
+ dlclose(dri->driver);
+ return -1;
+ }
+
+
+ if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) {
+ dlclose(dri->driver);
+ fprintf(stderr, "failed to bind extensions\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+dri_screen_create(struct gbm_dri_device *dri)
+{
+ const __DRIextension **extensions;
+ int ret = 0;
+
+ dri->base.driver_name = dri_fd_get_driver_name(dri->base.base.fd);
+ if (dri->base.driver_name == NULL)
+ return -1;
+
+ ret = dri_load_driver(dri);
+ if (ret) {
+ fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name);
+ return ret;
+ };
+
+ dri->extensions[0] = &image_lookup_extension.base;
+ dri->extensions[1] = &use_invalidate.base;
+ dri->extensions[2] = NULL;
+
+ if (dri->dri2 == NULL)
+ return -1;
+
+ dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd,
+ dri->extensions,
+ &dri->driver_configs, dri);
+
+ extensions = dri->core->getExtensions(dri->screen);
+ if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) {
+ ret = -1;
+ goto free_screen;
+ }
+
+ dri->lookup_image = NULL;
+ dri->lookup_user_data = NULL;
+
+ return 0;
+
+free_screen:
+ dri->core->destroyScreen(dri->screen);
+
+ return ret;
+}
+
+static int
+gbm_dri_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage)
+{
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ break;
+ case GBM_BO_FORMAT_ARGB8888:
+ if (usage & GBM_BO_USE_SCANOUT)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ if (usage & GBM_BO_USE_CURSOR_64X64 &&
+ usage & GBM_BO_USE_RENDERING)
+ return 0;
+
+ return 1;
+}
+
+static void
+gbm_dri_bo_destroy(struct gbm_bo *_bo)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+ struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+ dri->image->destroyImage(bo->image);
+ free(bo);
+}
+
+static struct gbm_bo *
+gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+ struct gbm_dri_bo *bo;
+
+ (void) egl_dpy;
+
+ if (dri->lookup_image == NULL)
+ return NULL;
+
+ bo = calloc(1, sizeof *bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ __DRIimage *tmp = dri->lookup_image(dri->screen, egl_img,
+ dri->lookup_user_data);
+
+ bo->image = dri->image->dupImage(tmp, bo);
+ if (bo->image == NULL)
+ return NULL;
+
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &bo->base.base.handle.s32);
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
+ (int *) &bo->base.base.pitch);
+
+ return &bo->base.base;
+}
+
+static struct gbm_bo *
+gbm_dri_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t usage)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+ struct gbm_dri_bo *bo;
+ int dri_format;
+ unsigned dri_use = 0;
+
+ bo = calloc(1, sizeof *bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
+ break;
+ case GBM_BO_FORMAT_ARGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ default:
+ return NULL;
+ }
+
+ if (usage & GBM_BO_USE_SCANOUT)
+ dri_use |= __DRI_IMAGE_USE_SCANOUT;
+ if (usage & GBM_BO_USE_CURSOR_64X64)
+ dri_use |= __DRI_IMAGE_USE_CURSOR;
+
+ bo->image =
+ dri->image->createImage(dri->screen,
+ width, height,
+ dri_format, dri_use,
+ bo);
+ if (bo->image == NULL)
+ return NULL;
+
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &bo->base.base.handle.s32);
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
+ (int *) &bo->base.base.pitch);
+
+ return &bo->base.base;
+}
+
+static void
+dri_destroy(struct gbm_device *gbm)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+
+ dri->core->destroyScreen(dri->screen);
+ free(dri->driver_configs);
+ dlclose(dri->driver);
+ free(dri->base.driver_name);
+
+ free(dri);
+}
+
+static struct gbm_device *
+dri_device_create(int fd)
+{
+ struct gbm_dri_device *dri;
+ int ret;
+
+ dri = calloc(1, sizeof *dri);
+
+ dri->base.base.fd = fd;
+ dri->base.base.bo_create = gbm_dri_bo_create;
+ dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image;
+ dri->base.base.is_format_supported = gbm_dri_is_format_supported;
+ dri->base.base.bo_destroy = gbm_dri_bo_destroy;
+ dri->base.base.destroy = dri_destroy;
+
+ dri->base.type = GBM_DRM_DRIVER_TYPE_DRI;
+ dri->base.base.name = "drm";
+
+ ret = dri_screen_create(dri);
+ if (ret) {
+ free(dri);
+ return NULL;
+ }
+
+ return &dri->base.base;
+}
+
+struct gbm_backend gbm_dri_backend = {
+ .backend_name = "dri",
+ .create_device = dri_device_create,
+};
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
new file mode 100644
index 00000000000..c5b5e17a4ee
--- /dev/null
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _GBM_DRI_INTERNAL_H_
+#define _GBM_DRI_INTERNAL_H_
+
+#include "gbmint.h"
+
+#include "common.h"
+#include "common_drm.h"
+
+#include <GL/gl.h> /* dri_interface needs GL types */
+#include "GL/internal/dri_interface.h"
+
+struct gbm_dri_device {
+ struct gbm_drm_device base;
+
+ void *driver;
+
+ __DRIscreen *screen;
+
+ __DRIcoreExtension *core;
+ __DRIdri2Extension *dri2;
+ __DRIimageExtension *image;
+
+ const __DRIconfig **driver_configs;
+ const __DRIextension *extensions[3];
+
+ __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data);
+ void *lookup_user_data;
+};
+
+struct gbm_dri_bo {
+ struct gbm_drm_bo base;
+
+ __DRIimage *image;
+};
+
+static inline struct gbm_dri_device *
+gbm_dri_device(struct gbm_device *gbm)
+{
+ return (struct gbm_dri_device *) gbm;
+}
+
+static inline struct gbm_dri_bo *
+gbm_dri_bo(struct gbm_bo *bo)
+{
+ return (struct gbm_dri_bo *) bo;
+}
+
+char *
+dri_fd_get_driver_name(int fd);
+
+#endif
diff --git a/src/gbm/main/Makefile b/src/gbm/main/Makefile
new file mode 100644
index 00000000000..5130b9b5df2
--- /dev/null
+++ b/src/gbm/main/Makefile
@@ -0,0 +1,90 @@
+# src/gbm/main/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+INCLUDE_DIRS = -I$(TOP)/include
+
+HEADERS = \
+ common.h \
+ backend.h \
+ gbmint.h \
+ gbm.h
+
+SOURCES = \
+ gbm.c \
+ backend.c \
+ common.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+# use dl*() to load drivers
+LOCAL_CFLAGS = $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS) \
+ -D_OS_UNIX=1 -DMODULEDIR='"$(GBM_BACKEND_INSTALL_DIR)"'
+LOCAL_LIBS =
+
+# Builtin backends
+ifeq ($(filter dri, $(GBM_BACKEND_DIRS)),dri)
+LOCAL_LIBS += $(TOP)/src/gbm/backends/dri/libgbm_dri.a
+endif
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
+
+
+default: depend library
+
+
+library: $(TOP)/$(LIB_DIR)/libgbm.so
+
+$(TOP)/$(LIB_DIR)/libgbm.so: $(OBJECTS) $(LOCAL_LIBS)
+ $(MKLIB) -o gbm -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major 1 -minor 0 \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ -L$(TOP)/$(LIB_DIR) $(GBM_LIB_DEPS) \
+ $(OBJECTS) $(LOCAL_LIBS)
+
+install-headers:
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/
+ $(INSTALL) -m 644 $(TOP)/src/gbm/main/gbm.h \
+ $(DESTDIR)$(INSTALL_INC_DIR)
+
+
+PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig
+
+gbm_pcedit = sed \
+ -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+ -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
+ -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
+ -e 's,@VERSION@,0.0.0,' \
+ -e 's,@GBM_PC_REQ_PRIV@,$(GBM_PC_REQ_PRIV),' \
+ -e 's,@GBM_PC_LIB_PRIV@,$(GBM_PC_LIB_PRIV),' \
+ -e 's,@GBM_PC_CFLAGS@,$(GBM_PC_CFLAGS),' \
+ -e 's,@GBM_LIB@,$(GBM_LIB),'
+
+gbm.pc: gbm.pc.in
+ $(gbm_pcedit) $< > $@
+
+install: default install-headers gbm.pc
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libgbm.so* \
+ $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -d $(DESTDIR)$(PKG_CONFIG_DIR)
+ $(INSTALL) -m 644 gbm.pc $(DESTDIR)$(PKG_CONFIG_DIR)
+
+clean:
+ -rm -f *.o
+ -rm -f depend depend.bak
+ -rm -f gbm.pc
+
+
+depend: $(SOURCES) $(HEADERS)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
+ $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null
+
+
+-include depend
+# DO NOT DELETE
diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c
new file mode 100644
index 00000000000..aceb6621f96
--- /dev/null
+++ b/src/gbm/main/backend.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <dlfcn.h>
+
+#include "backend.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+extern const struct gbm_backend gbm_dri_backend;
+
+struct backend_desc {
+ const char *name;
+ const struct gbm_backend *builtin;
+};
+
+static const struct backend_desc backends[] = {
+ { "gbm_dri.so", &gbm_dri_backend },
+ { "gbm_gallium_drm.so", NULL },
+};
+
+static const void *
+load_backend(const struct backend_desc *backend)
+{
+ char path[PATH_MAX];
+ const void *init = NULL;
+ void *module;
+ const char *name;
+ const char *entrypoint = "gbm_backend";
+
+ if (backend == NULL)
+ return NULL;
+
+ name = backend->name;
+
+ if (backend->builtin) {
+ init = backend->builtin;
+ } else {
+ if (name[0] != '/')
+ snprintf(path, sizeof path, MODULEDIR "/%s", name);
+ else
+ snprintf(path, sizeof path, "%s", name);
+
+ module = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (!module) {
+ fprintf(stderr,
+ "failed to load module: %s\n", dlerror());
+ return NULL;
+ }
+
+ init = dlsym(module, entrypoint);
+ if (!init)
+ return NULL;
+ }
+
+ return init;
+}
+
+static const struct backend_desc *
+find_backend(const char *name)
+{
+ const struct backend_desc *backend = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(backends); ++i) {
+ if (strcmp(backends[i].name, name) == 0) {
+ backend = &backends[i];
+ break;
+ }
+ }
+
+ return backend;
+}
+
+struct gbm_device *
+_gbm_create_device(int fd)
+{
+ const struct gbm_backend *backend = NULL;
+ struct gbm_device *dev = NULL;
+ int i;
+ const char *b;
+
+ b = getenv("GBM_BACKEND");
+ if (b)
+ backend = load_backend(find_backend(b));
+
+ if (backend)
+ dev = backend->create_device(fd);
+
+ for (i = 0; i < ARRAY_SIZE(backends) && dev == NULL; ++i) {
+ backend = load_backend(&backends[i]);
+ if (backend == NULL)
+ continue;
+
+ dev = backend->create_device(fd);
+ }
+
+ return dev;
+}
diff --git a/src/gbm/main/backend.h b/src/gbm/main/backend.h
new file mode 100644
index 00000000000..4a643750333
--- /dev/null
+++ b/src/gbm/main/backend.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef MODULE_H_
+#define MODULE_H_
+
+#include "gbmint.h"
+
+struct gbm_device *
+_gbm_create_device(int fd);
+
+#endif
diff --git a/src/gbm/main/common.c b/src/gbm/main/common.c
new file mode 100644
index 00000000000..f02162df292
--- /dev/null
+++ b/src/gbm/main/common.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libudev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "gbmint.h"
+
+GBM_EXPORT struct udev_device *
+_gbm_udev_device_new_from_fd(struct udev *udev, int fd)
+{
+ struct udev_device *device;
+ struct stat buf;
+
+ if (fstat(fd, &buf) < 0) {
+ fprintf(stderr, "gbm: failed to stat fd %d", fd);
+ return NULL;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+ if (device == NULL) {
+ fprintf(stderr,
+ "gbm: could not create udev device for fd %d", fd);
+ return NULL;
+ }
+
+ return device;
+}
+
+GBM_EXPORT char *
+_gbm_fd_get_device_name(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device;
+ const char *const_device_name;
+ char *device_name = NULL;
+
+ udev = udev_new();
+ device = _gbm_udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ const_device_name = udev_device_get_devnode(device);
+ if (!const_device_name)
+ goto out;
+ device_name = strdup(const_device_name);
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return device_name;
+}
+
+GBM_EXPORT void
+_gbm_log(const char *fmt_str, ...)
+{
+}
diff --git a/src/gbm/main/common.h b/src/gbm/main/common.h
new file mode 100644
index 00000000000..1fcdfcac30d
--- /dev/null
+++ b/src/gbm/main/common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <libudev.h>
+
+struct udev_device *
+_gbm_udev_device_new_from_fd(struct udev *udev, int fd);
+
+char *
+_gbm_fd_get_device_name(int fd);
+
+void
+_gbm_log(const char *fmt_str, ...);
+
+#endif
diff --git a/src/gbm/main/common_drm.h b/src/gbm/main/common_drm.h
new file mode 100644
index 00000000000..d28c3f01f48
--- /dev/null
+++ b/src/gbm/main/common_drm.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _COMMON_DRM_H_
+#define _COMMON_DRM_H_
+
+#include "gbmint.h"
+
+enum gbm_drm_driver_type {
+ GBM_DRM_DRIVER_TYPE_DRI,
+ GBM_DRM_DRIVER_TYPE_GALLIUM,
+};
+
+struct gbm_drm_device {
+ struct gbm_device base;
+ enum gbm_drm_driver_type type;
+ char *driver_name;
+};
+
+struct gbm_drm_bo {
+ struct gbm_bo base;
+};
+
+#endif
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
new file mode 100644
index 00000000000..8440b2c6ae3
--- /dev/null
+++ b/src/gbm/main/gbm.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#define _BSD_SOURCE
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "gbm.h"
+#include "gbmint.h"
+#include "common.h"
+#include "backend.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+struct gbm_device *devices[16];
+
+static int device_num = 0;
+
+GBM_EXPORT int
+gbm_device_get_fd(struct gbm_device *gbm)
+{
+ return gbm->fd;
+}
+
+/* FIXME: maybe superfluous, use udev subclass from the fd? */
+GBM_EXPORT const char *
+gbm_device_get_backend_name(struct gbm_device *gbm)
+{
+ return gbm->name;
+}
+
+int
+gbm_device_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage)
+{
+ return gbm->is_format_supported(gbm, format, usage);
+}
+
+GBM_EXPORT void
+gbm_device_destroy(struct gbm_device *gbm)
+{
+ gbm->refcount--;
+ if (gbm->refcount == 0)
+ gbm->destroy(gbm);
+}
+
+GBM_EXPORT struct gbm_device *
+_gbm_mesa_get_device(int fd)
+{
+ struct gbm_device *gbm = NULL;
+ struct stat buf;
+ dev_t dev;
+ int i;
+
+ if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
+ fprintf(stderr, "_gbm_mesa_get_device: invalid fd: %d\n", fd);
+ return NULL;
+ }
+
+ for (i = 0; i < device_num; ++i) {
+ dev = devices[i]->stat.st_rdev;
+ if (major(dev) == major(buf.st_rdev) &&
+ minor(dev) == minor(buf.st_rdev)) {
+ gbm = devices[i];
+ gbm->refcount++;
+ break;
+ }
+ }
+
+ return gbm;
+}
+
+GBM_EXPORT struct gbm_device *
+gbm_create_device(int fd)
+{
+ struct gbm_device *gbm = NULL;
+ struct stat buf;
+
+ if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
+ fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd);
+ return NULL;
+ }
+
+ if (device_num == 0)
+ memset(devices, 0, sizeof devices);
+
+ gbm = _gbm_create_device(fd);
+ if (gbm == NULL)
+ return NULL;
+
+ gbm->dummy = gbm_create_device;
+ gbm->stat = buf;
+ gbm->refcount = 1;
+
+ if (device_num < ARRAY_SIZE(devices)-1)
+ devices[device_num++] = gbm;
+
+ return gbm;
+}
+
+GBM_EXPORT unsigned int
+gbm_bo_get_width(struct gbm_bo *bo)
+{
+ return bo->width;
+}
+
+GBM_EXPORT unsigned int
+gbm_bo_get_height(struct gbm_bo *bo)
+{
+ return bo->height;
+}
+
+GBM_EXPORT uint32_t
+gbm_bo_get_pitch(struct gbm_bo *bo)
+{
+ return bo->pitch;
+}
+
+GBM_EXPORT union gbm_bo_handle
+gbm_bo_get_handle(struct gbm_bo *bo)
+{
+ return bo->handle;
+}
+
+GBM_EXPORT void
+gbm_bo_destroy(struct gbm_bo *bo)
+{
+ bo->gbm->bo_destroy(bo);
+}
+
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t usage)
+{
+ if (width == 0 || height == 0)
+ return NULL;
+
+ if (usage & GBM_BO_USE_CURSOR_64X64 &&
+ (width != 64 || height != 64))
+ return NULL;
+
+ return gbm->bo_create(gbm, width, height, format, usage);
+}
+
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_image,
+ uint32_t width, uint32_t height,
+ uint32_t usage)
+{
+ if (width == 0 || height == 0)
+ return NULL;
+
+ return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image,
+ width, height, usage);
+}
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
new file mode 100644
index 00000000000..d79a03e4b3f
--- /dev/null
+++ b/src/gbm/main/gbm.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef _GBM_H_
+#define _GBM_H_
+
+#define __GBM__ 1
+
+#include <stdint.h>
+
+struct gbm_device;
+struct gbm_bo;
+
+union gbm_bo_handle {
+ void *ptr;
+ int32_t s32;
+ uint32_t u32;
+ int64_t s64;
+ uint64_t u64;
+};
+
+enum gbm_bo_format {
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_FORMAT_ARGB8888,
+};
+
+enum gbm_bo_flags {
+ GBM_BO_USE_SCANOUT = (1 << 0),
+ GBM_BO_USE_CURSOR_64X64 = (1 << 1),
+ GBM_BO_USE_RENDERING = (1 << 2),
+};
+
+int
+gbm_device_get_fd(struct gbm_device *gbm);
+
+const char *
+gbm_device_get_backend_name(struct gbm_device *gbm);
+
+int
+gbm_device_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage);
+
+void
+gbm_device_destroy(struct gbm_device *gbm);
+
+struct gbm_device *
+gbm_create_device(int fd);
+
+struct gbm_bo *
+gbm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t flags);
+
+struct gbm_bo *
+gbm_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage);
+
+uint32_t
+gbm_bo_get_width(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_height(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_pitch(struct gbm_bo *bo);
+
+union gbm_bo_handle
+gbm_bo_get_handle(struct gbm_bo *bo);
+
+void
+gbm_bo_destroy(struct gbm_bo *bo);
+
+#endif
diff --git a/src/gbm/main/gbm.pc.in b/src/gbm/main/gbm.pc.in
new file mode 100644
index 00000000000..76299e77f83
--- /dev/null
+++ b/src/gbm/main/gbm.pc.in
@@ -0,0 +1,12 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: gbm
+Description: Mesa gbm library
+Requires.private: @GBM_PC_REQ_PRIV@
+Version: @VERSION@
+Libs: -L${libdir} -l@GBM_LIB@
+Libs.private: @GBM_PC_LIB_PRIV@
+Cflags: -I${includedir} @GBM_PC_CFLAGS@
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
new file mode 100644
index 00000000000..fb8db804c1b
--- /dev/null
+++ b/src/gbm/main/gbmint.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Benjamin Franzke <benjaminfranzke@googlemail.com>
+ */
+
+#ifndef INTERNAL_H_
+#define INTERNAL_H_
+
+#include "gbm.h"
+#include <sys/stat.h>
+
+/* GCC visibility */
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define GBM_EXPORT __attribute__ ((visibility("default")))
+#else
+#define GBM_EXPORT
+#endif
+
+struct gbm_device {
+ /* Hack to make a gbm_device detectable by its first element. */
+ struct gbm_device *(*dummy)(int);
+
+ int fd;
+ const char *name;
+ unsigned int refcount;
+ struct stat stat;
+
+ void (*destroy)(struct gbm_device *gbm);
+ int (*is_format_supported)(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage);
+
+ struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format,
+ uint32_t usage);
+ struct gbm_bo *(*bo_create_from_egl_image)(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage);
+ void (*bo_destroy)(struct gbm_bo *bo);
+};
+
+struct gbm_bo {
+ struct gbm_device *gbm;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ union gbm_bo_handle handle;
+};
+
+struct gbm_backend {
+ const char *backend_name;
+ struct gbm_device *(*create_device)(int fd);
+};
+
+GBM_EXPORT struct gbm_device *
+_gbm_mesa_get_device(int fd);
+
+#endif
diff --git a/src/glsl/SConscript b/src/glsl/SConscript
index c3255835fb4..1441cc74bd8 100644
--- a/src/glsl/SConscript
+++ b/src/glsl/SConscript
@@ -102,7 +102,7 @@ if env['msvc']:
env.Prepend(CPPPATH = ['#/src/getopt'])
env.PrependUnique(LIBS = [getopt])
-if env['crosscompile'] and env['platform'] != 'embedded':
+if env['crosscompile'] and not env['embedded']:
Import('builtin_glsl_function')
else:
# Copy these files to avoid generation object files into src/mesa/program
@@ -156,7 +156,7 @@ Export('glsl')
# Skip building these programs as they will cause SCons error "Two environments
# with different actions were specified for the same target"
-if env['crosscompile'] or env['platform'] == 'embedded':
+if env['crosscompile'] or env['embedded']:
Return()
env = env.Clone()
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 3ba699ad971..60a2c617f70 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -271,17 +271,36 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
assert(a <= GLSL_TYPE_BOOL);
assert(b <= GLSL_TYPE_BOOL);
- if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
+ if (a == b)
return src;
switch (a) {
case GLSL_TYPE_UINT:
+ switch (b) {
+ case GLSL_TYPE_INT:
+ result = new(ctx) ir_expression(ir_unop_i2u, src);
+ break;
+ case GLSL_TYPE_FLOAT:
+ result = new(ctx) ir_expression(ir_unop_i2u,
+ new(ctx) ir_expression(ir_unop_f2i, src));
+ break;
+ case GLSL_TYPE_BOOL:
+ result = new(ctx) ir_expression(ir_unop_i2u,
+ new(ctx) ir_expression(ir_unop_b2i, src));
+ break;
+ }
+ break;
case GLSL_TYPE_INT:
- if (b == GLSL_TYPE_FLOAT)
- result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
- else {
- assert(b == GLSL_TYPE_BOOL);
- result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
+ switch (b) {
+ case GLSL_TYPE_UINT:
+ result = new(ctx) ir_expression(ir_unop_u2i, src);
+ break;
+ case GLSL_TYPE_FLOAT:
+ result = new(ctx) ir_expression(ir_unop_f2i, src);
+ break;
+ case GLSL_TYPE_BOOL:
+ result = new(ctx) ir_expression(ir_unop_b2i, src);
+ break;
}
break;
case GLSL_TYPE_FLOAT:
@@ -300,6 +319,9 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
case GLSL_TYPE_BOOL:
switch (b) {
case GLSL_TYPE_UINT:
+ result = new(ctx) ir_expression(ir_unop_i2b,
+ new(ctx) ir_expression(ir_unop_u2i, src));
+ break;
case GLSL_TYPE_INT:
result = new(ctx) ir_expression(ir_unop_i2b, desired_type, src, NULL);
break;
@@ -311,6 +333,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
}
assert(result != NULL);
+ assert(result->type == desired_type);
/* Try constant folding; it may fold in the conversion we just added. */
ir_constant *const constant = result->constant_expression_value();
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index 3b87f0d56de..2e54e8c22d8 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -447,9 +447,17 @@ modulus_result_type(const struct glsl_type *type_a,
* integer vectors. The operand types must both be signed or both be
* unsigned."
*/
- if (!type_a->is_integer() || !type_b->is_integer()
- || (type_a->base_type != type_b->base_type)) {
- _mesa_glsl_error(loc, state, "type mismatch");
+ if (!type_a->is_integer()) {
+ _mesa_glsl_error(loc, state, "LHS of operator %% must be an integer.");
+ return glsl_type::error_type;
+ }
+ if (!type_b->is_integer()) {
+ _mesa_glsl_error(loc, state, "RHS of operator %% must be an integer.");
+ return glsl_type::error_type;
+ }
+ if (type_a->base_type != type_b->base_type) {
+ _mesa_glsl_error(loc, state,
+ "operands of %% must have the same base type");
return glsl_type::error_type;
}
@@ -1940,7 +1948,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
break;
case fragment_shader:
- if (!global_scope || (var->mode != ir_var_in)) {
+ if (!global_scope || (var->mode != ir_var_out)) {
fail = true;
string = "output";
}
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index d9aa300bbe4..cc781378d76 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -165,133 +165,242 @@ _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
}
+/**
+ * Enum representing the possible behaviors that can be specified in
+ * an #extension directive.
+ */
+enum ext_behavior {
+ extension_disable,
+ extension_enable,
+ extension_require,
+ extension_warn
+};
+
+/**
+ * Element type for _mesa_glsl_supported_extensions
+ */
+struct _mesa_glsl_extension {
+ /**
+ * Name of the extension when referred to in a GLSL extension
+ * statement
+ */
+ const char *name;
+
+ /** True if this extension is available to vertex shaders */
+ bool avail_in_VS;
+
+ /** True if this extension is available to geometry shaders */
+ bool avail_in_GS;
+
+ /** True if this extension is available to fragment shaders */
+ bool avail_in_FS;
+
+ /** True if this extension is available to desktop GL shaders */
+ bool avail_in_GL;
+
+ /** True if this extension is available to GLES shaders */
+ bool avail_in_ES;
+
+ /**
+ * Flag in the gl_extensions struct indicating whether this
+ * extension is supported by the driver, or
+ * &gl_extensions::dummy_true if supported by all drivers.
+ *
+ * Note: the type (GLboolean gl_extensions::*) is a "pointer to
+ * member" type, the type-safe alternative to the "offsetof" macro.
+ * In a nutshell:
+ *
+ * - foo bar::* p declares p to be an "offset" to a field of type
+ * foo that exists within struct bar
+ * - &bar::baz computes the "offset" of field baz within struct bar
+ * - x.*p accesses the field of x that exists at "offset" p
+ * - x->*p is equivalent to (*x).*p
+ */
+ const GLboolean gl_extensions::* supported_flag;
+
+ /**
+ * Flag in the _mesa_glsl_parse_state struct that should be set
+ * when this extension is enabled.
+ *
+ * See note in _mesa_glsl_extension::supported_flag about "pointer
+ * to member" types.
+ */
+ bool _mesa_glsl_parse_state::* enable_flag;
+
+ /**
+ * Flag in the _mesa_glsl_parse_state struct that should be set
+ * when the shader requests "warn" behavior for this extension.
+ *
+ * See note in _mesa_glsl_extension::supported_flag about "pointer
+ * to member" types.
+ */
+ bool _mesa_glsl_parse_state::* warn_flag;
+
+
+ bool compatible_with_state(const _mesa_glsl_parse_state *state) const;
+ void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
+};
+
+#define EXT(NAME, VS, GS, FS, GL, ES, SUPPORTED_FLAG) \
+ { "GL_" #NAME, VS, GS, FS, GL, ES, &gl_extensions::SUPPORTED_FLAG, \
+ &_mesa_glsl_parse_state::NAME##_enable, \
+ &_mesa_glsl_parse_state::NAME##_warn }
+
+/**
+ * Table of extensions that can be enabled/disabled within a shader,
+ * and the conditions under which they are supported.
+ */
+static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
+ /* target availability API availability */
+ /* name VS GS FS GL ES supported flag */
+ EXT(ARB_draw_buffers, false, false, true, true, false, dummy_true),
+ EXT(ARB_draw_instanced, true, false, false, true, false, ARB_draw_instanced),
+ EXT(ARB_explicit_attrib_location, true, false, true, true, false, ARB_explicit_attrib_location),
+ EXT(ARB_fragment_coord_conventions, true, false, true, true, false, ARB_fragment_coord_conventions),
+ EXT(ARB_texture_rectangle, true, false, true, true, false, dummy_true),
+ EXT(EXT_texture_array, true, false, true, true, false, EXT_texture_array),
+ EXT(ARB_shader_texture_lod, true, false, true, true, false, ARB_shader_texture_lod),
+ EXT(ARB_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
+ EXT(AMD_conservative_depth, true, false, true, true, false, AMD_conservative_depth),
+ EXT(AMD_shader_stencil_export, false, false, true, true, false, ARB_shader_stencil_export),
+ EXT(OES_texture_3D, true, false, true, false, true, EXT_texture3D),
+};
+
+#undef EXT
+
+
+/**
+ * Determine whether a given extension is compatible with the target,
+ * API, and extension information in the current parser state.
+ */
+bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state *
+ state) const
+{
+ /* Check that this extension matches the type of shader we are
+ * compiling to.
+ */
+ switch (state->target) {
+ case vertex_shader:
+ if (!this->avail_in_VS) {
+ return false;
+ }
+ break;
+ case geometry_shader:
+ if (!this->avail_in_GS) {
+ return false;
+ }
+ break;
+ case fragment_shader:
+ if (!this->avail_in_FS) {
+ return false;
+ }
+ break;
+ default:
+ assert (!"Unrecognized shader target");
+ return false;
+ }
+
+ /* Check that this extension matches whether we are compiling
+ * for desktop GL or GLES.
+ */
+ if (state->es_shader) {
+ if (!this->avail_in_ES) return false;
+ } else {
+ if (!this->avail_in_GL) return false;
+ }
+
+ /* Check that this extension is supported by the OpenGL
+ * implementation.
+ *
+ * Note: the ->* operator indexes into state->extensions by the
+ * offset this->supported_flag. See
+ * _mesa_glsl_extension::supported_flag for more info.
+ */
+ return state->extensions->*(this->supported_flag);
+}
+
+/**
+ * Set the appropriate flags in the parser state to establish the
+ * given behavior for this extension.
+ */
+void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state,
+ ext_behavior behavior) const
+{
+ /* Note: the ->* operator indexes into state by the
+ * offsets this->enable_flag and this->warn_flag. See
+ * _mesa_glsl_extension::supported_flag for more info.
+ */
+ state->*(this->enable_flag) = (behavior != extension_disable);
+ state->*(this->warn_flag) = (behavior == extension_warn);
+}
+
+/**
+ * Find an extension by name in _mesa_glsl_supported_extensions. If
+ * the name is not found, return NULL.
+ */
+static const _mesa_glsl_extension *find_extension(const char *name)
+{
+ for (unsigned i = 0; i < Elements(_mesa_glsl_supported_extensions); ++i) {
+ if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) {
+ return &_mesa_glsl_supported_extensions[i];
+ }
+ }
+ return NULL;
+}
+
+
bool
_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
- const char *behavior, YYLTYPE *behavior_locp,
+ const char *behavior_string, YYLTYPE *behavior_locp,
_mesa_glsl_parse_state *state)
{
- enum {
- extension_disable,
- extension_enable,
- extension_require,
- extension_warn
- } ext_mode;
-
- if (strcmp(behavior, "warn") == 0) {
- ext_mode = extension_warn;
- } else if (strcmp(behavior, "require") == 0) {
- ext_mode = extension_require;
- } else if (strcmp(behavior, "enable") == 0) {
- ext_mode = extension_enable;
- } else if (strcmp(behavior, "disable") == 0) {
- ext_mode = extension_disable;
+ ext_behavior behavior;
+ if (strcmp(behavior_string, "warn") == 0) {
+ behavior = extension_warn;
+ } else if (strcmp(behavior_string, "require") == 0) {
+ behavior = extension_require;
+ } else if (strcmp(behavior_string, "enable") == 0) {
+ behavior = extension_enable;
+ } else if (strcmp(behavior_string, "disable") == 0) {
+ behavior = extension_disable;
} else {
_mesa_glsl_error(behavior_locp, state,
"Unknown extension behavior `%s'",
- behavior);
+ behavior_string);
return false;
}
- bool unsupported = false;
-
if (strcmp(name, "all") == 0) {
- if ((ext_mode == extension_enable) || (ext_mode == extension_require)) {
+ if ((behavior == extension_enable) || (behavior == extension_require)) {
_mesa_glsl_error(name_locp, state, "Cannot %s all extensions",
- (ext_mode == extension_enable)
+ (behavior == extension_enable)
? "enable" : "require");
return false;
- }
- } else if (strcmp(name, "GL_ARB_draw_buffers") == 0) {
- /* This extension is only supported in fragment shaders.
- */
- if (state->target != fragment_shader) {
- unsupported = true;
} else {
- state->ARB_draw_buffers_enable = (ext_mode != extension_disable);
- state->ARB_draw_buffers_warn = (ext_mode == extension_warn);
+ for (unsigned i = 0;
+ i < Elements(_mesa_glsl_supported_extensions); ++i) {
+ const _mesa_glsl_extension *extension
+ = &_mesa_glsl_supported_extensions[i];
+ if (extension->compatible_with_state(state)) {
+ _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
+ }
+ }
}
- } else if (strcmp(name, "GL_ARB_draw_instanced") == 0) {
- state->ARB_draw_instanced_enable = (ext_mode != extension_disable);
- state->ARB_draw_instanced_warn = (ext_mode == extension_warn);
-
- /* This extension is only supported in vertex shaders.
- */
- unsupported = (state->target != vertex_shader)
- || !state->extensions->ARB_draw_instanced;
- } else if (strcmp(name, "GL_ARB_explicit_attrib_location") == 0) {
- state->ARB_explicit_attrib_location_enable =
- (ext_mode != extension_disable);
- state->ARB_explicit_attrib_location_warn =
- (ext_mode == extension_warn);
-
- unsupported = !state->extensions->ARB_explicit_attrib_location;
- } else if (strcmp(name, "GL_ARB_fragment_coord_conventions") == 0) {
- state->ARB_fragment_coord_conventions_enable =
- (ext_mode != extension_disable);
- state->ARB_fragment_coord_conventions_warn =
- (ext_mode == extension_warn);
-
- unsupported = !state->extensions->ARB_fragment_coord_conventions;
- } else if (strcmp(name, "GL_ARB_texture_rectangle") == 0) {
- state->ARB_texture_rectangle_enable = (ext_mode != extension_disable);
- state->ARB_texture_rectangle_warn = (ext_mode == extension_warn);
- } else if (strcmp(name, "GL_EXT_texture_array") == 0) {
- state->EXT_texture_array_enable = (ext_mode != extension_disable);
- state->EXT_texture_array_warn = (ext_mode == extension_warn);
-
- unsupported = !state->extensions->EXT_texture_array;
- } else if (strcmp(name, "GL_ARB_shader_texture_lod") == 0) {
- /* Force ARB_texture_rectangle to be on so sampler2DRects are defined */
- state->ARB_texture_rectangle_enable = true;
-
- state->ARB_shader_texture_lod_enable = (ext_mode != extension_disable);
- state->ARB_shader_texture_lod_warn = (ext_mode == extension_warn);
-
- unsupported = !state->extensions->ARB_shader_texture_lod;
- } else if (strcmp(name, "GL_ARB_shader_stencil_export") == 0) {
- state->ARB_shader_stencil_export_enable = (ext_mode != extension_disable);
- state->ARB_shader_stencil_export_warn = (ext_mode == extension_warn);
-
- /* This extension is only supported in fragment shaders.
- */
- unsupported = (state->target != fragment_shader)
- || !state->extensions->ARB_shader_stencil_export;
- } else if (strcmp(name, "GL_AMD_conservative_depth") == 0) {
- /* The AMD_conservative spec does not forbid requiring the extension in
- * the vertex shader.
- */
- state->AMD_conservative_depth_enable = (ext_mode != extension_disable);
- state->AMD_conservative_depth_warn = (ext_mode == extension_warn);
- unsupported = !state->extensions->AMD_conservative_depth;
- } else if (strcmp(name, "GL_AMD_shader_stencil_export") == 0) {
- state->AMD_shader_stencil_export_enable = (ext_mode != extension_disable);
- state->AMD_shader_stencil_export_warn = (ext_mode == extension_warn);
-
- /* This extension is only supported in fragment shaders.
- * Both the ARB and AMD variants share the same ARB flag
- * in gl_extensions.
- */
- unsupported = (state->target != fragment_shader)
- || !state->extensions->ARB_shader_stencil_export;
- } else if (strcmp(name, "GL_OES_texture_3D") == 0 && state->es_shader) {
- state->OES_texture_3D_enable = (ext_mode != extension_disable);
- state->OES_texture_3D_warn = (ext_mode == extension_warn);
-
- unsupported = !state->extensions->EXT_texture3D;
} else {
- unsupported = true;
- }
-
- if (unsupported) {
- static const char *const fmt = "extension `%s' unsupported in %s shader";
-
- if (ext_mode == extension_require) {
- _mesa_glsl_error(name_locp, state, fmt,
- name, _mesa_glsl_shader_target_name(state->target));
- return false;
+ const _mesa_glsl_extension *extension = find_extension(name);
+ if (extension && extension->compatible_with_state(state)) {
+ extension->set_flags(state, behavior);
} else {
- _mesa_glsl_warning(name_locp, state, fmt,
- name, _mesa_glsl_shader_target_name(state->target));
+ static const char *const fmt = "extension `%s' unsupported in %s shader";
+
+ if (behavior == extension_require) {
+ _mesa_glsl_error(name_locp, state, fmt,
+ name, _mesa_glsl_shader_target_name(state->target));
+ return false;
+ } else {
+ _mesa_glsl_warning(name_locp, state, fmt,
+ name, _mesa_glsl_shader_target_name(state->target));
+ }
}
}
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 878d2ae3f4d..2f4d3cba77f 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -156,28 +156,28 @@ struct _mesa_glsl_parse_state {
* \name Enable bits for GLSL extensions
*/
/*@{*/
- unsigned ARB_draw_buffers_enable:1;
- unsigned ARB_draw_buffers_warn:1;
- unsigned ARB_draw_instanced_enable:1;
- unsigned ARB_draw_instanced_warn:1;
- unsigned ARB_explicit_attrib_location_enable:1;
- unsigned ARB_explicit_attrib_location_warn:1;
- unsigned ARB_fragment_coord_conventions_enable:1;
- unsigned ARB_fragment_coord_conventions_warn:1;
- unsigned ARB_texture_rectangle_enable:1;
- unsigned ARB_texture_rectangle_warn:1;
- unsigned EXT_texture_array_enable:1;
- unsigned EXT_texture_array_warn:1;
- unsigned ARB_shader_texture_lod_enable:1;
- unsigned ARB_shader_texture_lod_warn:1;
- unsigned ARB_shader_stencil_export_enable:1;
- unsigned ARB_shader_stencil_export_warn:1;
- unsigned AMD_conservative_depth_enable:1;
- unsigned AMD_conservative_depth_warn:1;
- unsigned AMD_shader_stencil_export_enable:1;
- unsigned AMD_shader_stencil_export_warn:1;
- unsigned OES_texture_3D_enable:1;
- unsigned OES_texture_3D_warn:1;
+ bool ARB_draw_buffers_enable;
+ bool ARB_draw_buffers_warn;
+ bool ARB_draw_instanced_enable;
+ bool ARB_draw_instanced_warn;
+ bool ARB_explicit_attrib_location_enable;
+ bool ARB_explicit_attrib_location_warn;
+ bool ARB_fragment_coord_conventions_enable;
+ bool ARB_fragment_coord_conventions_warn;
+ bool ARB_texture_rectangle_enable;
+ bool ARB_texture_rectangle_warn;
+ bool EXT_texture_array_enable;
+ bool EXT_texture_array_warn;
+ bool ARB_shader_texture_lod_enable;
+ bool ARB_shader_texture_lod_warn;
+ bool ARB_shader_stencil_export_enable;
+ bool ARB_shader_stencil_export_warn;
+ bool AMD_conservative_depth_enable;
+ bool AMD_conservative_depth_warn;
+ bool AMD_shader_stencil_export_enable;
+ bool AMD_shader_stencil_export_warn;
+ bool OES_texture_3D_enable;
+ bool OES_texture_3D_warn;
/*@}*/
/** Extensions supported by the OpenGL implementation. */
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index a3623b31e5d..95689dc10b0 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -272,6 +272,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
case ir_unop_f2i:
case ir_unop_b2i:
+ case ir_unop_u2i:
this->type = glsl_type::get_instance(GLSL_TYPE_INT,
op0->type->vector_elements, 1);
break;
@@ -289,6 +290,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
op0->type->vector_elements, 1);
break;
+ case ir_unop_i2u:
+ this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
+ op0->type->vector_elements, 1);
+ break;
+
case ir_unop_noise:
this->type = glsl_type::float_type;
break;
@@ -419,6 +425,8 @@ static const char *const operator_strs[] = {
"i2b",
"b2i",
"u2f",
+ "i2u",
+ "u2i",
"any",
"trunc",
"ceil",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index a41984310b3..42a3936976a 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -682,7 +682,7 @@ public:
class ir_assignment : public ir_instruction {
public:
- ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
+ ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition = NULL);
/**
* Construct an assignment with an explicit write mask
@@ -789,6 +789,8 @@ enum ir_expression_operation {
ir_unop_i2b, /**< int-to-boolean conversion */
ir_unop_b2i, /**< Boolean-to-int conversion */
ir_unop_u2f, /**< Unsigned-to-float conversion. */
+ ir_unop_i2u, /**< Integer-to-unsigned conversion. */
+ ir_unop_u2i, /**< Unsigned-to-integer conversion. */
ir_unop_any,
/**
diff --git a/src/glsl/ir_constant_expression.cpp b/src/glsl/ir_constant_expression.cpp
index 2a308489656..f0299a2c4a0 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -166,7 +166,18 @@ ir_expression::constant_expression_value()
data.b[c] = op[0]->value.u[c] ? true : false;
}
break;
-
+ case ir_unop_u2i:
+ assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.i[c] = op[0]->value.u[c];
+ }
+ break;
+ case ir_unop_i2u:
+ assert(op[0]->type->base_type == GLSL_TYPE_INT);
+ for (unsigned c = 0; c < op[0]->type->components(); c++) {
+ data.u[c] = op[0]->value.i[c];
+ }
+ break;
case ir_unop_any:
assert(op[0]->type->is_boolean());
data.b[0] = false;
diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp
index caee9296af9..ef8d4fcfcd4 100644
--- a/src/glsl/ir_function.cpp
+++ b/src/glsl/ir_function.cpp
@@ -165,6 +165,7 @@ ir_function_signature *
ir_function::matching_signature(const exec_list *actual_parameters)
{
ir_function_signature *match = NULL;
+ int matched_score;
foreach_iter(exec_list_iterator, iter, signatures) {
ir_function_signature *const sig =
@@ -173,14 +174,14 @@ ir_function::matching_signature(const exec_list *actual_parameters)
const int score = parameter_lists_match(& sig->parameters,
actual_parameters);
+ /* If we found an exact match, simply return it */
if (score == 0)
return sig;
- if (score > 0) {
- if (match != NULL)
- return NULL;
-
+ /* If we found a match with fewer conversions, use that instead */
+ if (score > 0 && (match == NULL || score < matched_score)) {
match = sig;
+ matched_score = score;
}
}
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index 7b1c19d65aa..f3fceb2a57d 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -254,7 +254,7 @@ ir_validate::visit_leave(ir_expression *ir)
case ir_unop_f2i:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
- assert(ir->type->is_integer());
+ assert(ir->type->base_type == GLSL_TYPE_INT);
break;
case ir_unop_i2f:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
@@ -269,17 +269,25 @@ ir_validate::visit_leave(ir_expression *ir)
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
break;
case ir_unop_i2b:
- assert(ir->operands[0]->type->is_integer());
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
assert(ir->type->base_type == GLSL_TYPE_BOOL);
break;
case ir_unop_b2i:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
- assert(ir->type->is_integer());
+ assert(ir->type->base_type == GLSL_TYPE_INT);
break;
case ir_unop_u2f:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
assert(ir->type->base_type == GLSL_TYPE_FLOAT);
break;
+ case ir_unop_i2u:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+ assert(ir->type->base_type == GLSL_TYPE_UINT);
+ break;
+ case ir_unop_u2i:
+ assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+ assert(ir->type->base_type == GLSL_TYPE_INT);
+ break;
case ir_unop_any:
assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 255edc6a76f..b6479e7a3a4 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1405,8 +1405,9 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
}
-void
-assign_varying_locations(struct gl_shader_program *prog,
+bool
+assign_varying_locations(struct gl_context *ctx,
+ struct gl_shader_program *prog,
gl_shader *producer, gl_shader *consumer)
{
/* FINISHME: Set dynamically when geometry shader support is added. */
@@ -1462,6 +1463,8 @@ assign_varying_locations(struct gl_shader_program *prog,
}
}
+ unsigned varying_vectors = 0;
+
foreach_list(node, consumer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
@@ -1492,8 +1495,32 @@ assign_varying_locations(struct gl_shader_program *prog,
* value is written by the previous stage.
*/
var->mode = ir_var_auto;
+ } else {
+ /* The packing rules are used for vertex shader inputs are also used
+ * for fragment shader inputs.
+ */
+ varying_vectors += count_attribute_slots(var->type);
}
}
+
+ if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
+ if (varying_vectors > ctx->Const.MaxVarying) {
+ linker_error_printf(prog, "shader uses too many varying vectors "
+ "(%u > %u)\n",
+ varying_vectors, ctx->Const.MaxVarying);
+ return false;
+ }
+ } else {
+ const unsigned float_components = varying_vectors * 4;
+ if (float_components > ctx->Const.MaxVarying * 4) {
+ linker_error_printf(prog, "shader uses too many varying components "
+ "(%u > %u)\n",
+ float_components, ctx->Const.MaxVarying * 4);
+ return false;
+ }
+ }
+
+ return true;
}
@@ -1666,9 +1693,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
- assign_varying_locations(prog,
- prog->_LinkedShaders[prev],
- prog->_LinkedShaders[i]);
+ if (!assign_varying_locations(ctx, prog,
+ prog->_LinkedShaders[prev],
+ prog->_LinkedShaders[i])) {
+ prog->LinkStatus = false;
+ goto done;
+ }
+
prev = i;
}
diff --git a/src/glsl/lower_if_to_cond_assign.cpp b/src/glsl/lower_if_to_cond_assign.cpp
index e3a1065d996..b637eb4fe1d 100644
--- a/src/glsl/lower_if_to_cond_assign.cpp
+++ b/src/glsl/lower_if_to_cond_assign.cpp
@@ -149,11 +149,9 @@ ir_visitor_status
ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
{
/* Only flatten when beyond the GPU's maximum supported nesting depth. */
- if (this->depth <= this->max_depth)
+ if (this->depth-- <= this->max_depth)
return visit_continue;
- this->depth--;
-
bool found_control_flow = false;
ir_variable *cond_var;
ir_assignment *assign;
diff --git a/src/glsl/lower_instructions.cpp b/src/glsl/lower_instructions.cpp
index a5f61f213d0..806f8639959 100644
--- a/src/glsl/lower_instructions.cpp
+++ b/src/glsl/lower_instructions.cpp
@@ -168,8 +168,13 @@ lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir)
op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1);
- ir->operation = ir_unop_f2i;
- ir->operands[0] = op0;
+ if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) {
+ ir->operation = ir_unop_f2i;
+ ir->operands[0] = op0;
+ } else {
+ ir->operation = ir_unop_i2u;
+ ir->operands[0] = new(ir) ir_expression(ir_unop_f2i, op0);
+ }
ir->operands[1] = NULL;
}
@@ -271,7 +276,7 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
break;
case ir_binop_mod:
- if (lowering(MOD_TO_FRACT))
+ if (lowering(MOD_TO_FRACT) && ir->type->is_float())
mod_to_fract(ir);
break;
diff --git a/src/glsl/lower_mat_op_to_vec.cpp b/src/glsl/lower_mat_op_to_vec.cpp
index 8cbbfa713c9..a371afc14c2 100644
--- a/src/glsl/lower_mat_op_to_vec.cpp
+++ b/src/glsl/lower_mat_op_to_vec.cpp
@@ -45,19 +45,19 @@ public:
ir_visitor_status visit_leave(ir_assignment *);
- ir_dereference *get_column(ir_variable *var, int col);
- ir_rvalue *get_element(ir_variable *var, int col, int row);
-
- void do_mul_mat_mat(ir_variable *result_var,
- ir_variable *a_var, ir_variable *b_var);
- void do_mul_mat_vec(ir_variable *result_var,
- ir_variable *a_var, ir_variable *b_var);
- void do_mul_vec_mat(ir_variable *result_var,
- ir_variable *a_var, ir_variable *b_var);
- void do_mul_mat_scalar(ir_variable *result_var,
- ir_variable *a_var, ir_variable *b_var);
- void do_equal_mat_mat(ir_variable *result_var, ir_variable *a_var,
- ir_variable *b_var, bool test_equal);
+ ir_dereference *get_column(ir_dereference *val, int col);
+ ir_rvalue *get_element(ir_dereference *val, int col, int row);
+
+ void do_mul_mat_mat(ir_dereference *result,
+ ir_dereference *a, ir_dereference *b);
+ void do_mul_mat_vec(ir_dereference *result,
+ ir_dereference *a, ir_dereference *b);
+ void do_mul_vec_mat(ir_dereference *result,
+ ir_dereference *a, ir_dereference *b);
+ void do_mul_mat_scalar(ir_dereference *result,
+ ir_dereference *a, ir_dereference *b);
+ void do_equal_mat_mat(ir_dereference *result, ir_dereference *a,
+ ir_dereference *b, bool test_equal);
void *mem_ctx;
bool made_progress;
@@ -97,182 +97,137 @@ do_mat_op_to_vec(exec_list *instructions)
}
ir_rvalue *
-ir_mat_op_to_vec_visitor::get_element(ir_variable *var, int col, int row)
+ir_mat_op_to_vec_visitor::get_element(ir_dereference *val, int col, int row)
{
- ir_dereference *deref;
+ val = get_column(val, col);
- deref = new(mem_ctx) ir_dereference_variable(var);
-
- if (var->type->is_matrix()) {
- deref = new(mem_ctx) ir_dereference_array(var,
- new(mem_ctx) ir_constant(col));
- } else {
- assert(col == 0);
- }
-
- return new(mem_ctx) ir_swizzle(deref, row, 0, 0, 0, 1);
+ return new(mem_ctx) ir_swizzle(val, row, 0, 0, 0, 1);
}
ir_dereference *
-ir_mat_op_to_vec_visitor::get_column(ir_variable *var, int row)
+ir_mat_op_to_vec_visitor::get_column(ir_dereference *val, int row)
{
- ir_dereference *deref;
-
- if (!var->type->is_matrix()) {
- deref = new(mem_ctx) ir_dereference_variable(var);
- } else {
- deref = new(mem_ctx) ir_dereference_variable(var);
- deref = new(mem_ctx) ir_dereference_array(deref,
- new(mem_ctx) ir_constant(row));
+ val = val->clone(mem_ctx, NULL);
+
+ if (val->type->is_matrix()) {
+ val = new(mem_ctx) ir_dereference_array(val,
+ new(mem_ctx) ir_constant(row));
}
- return deref;
+ return val;
}
void
-ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_variable *result_var,
- ir_variable *a_var,
- ir_variable *b_var)
+ir_mat_op_to_vec_visitor::do_mul_mat_mat(ir_dereference *result,
+ ir_dereference *a,
+ ir_dereference *b)
{
int b_col, i;
ir_assignment *assign;
ir_expression *expr;
- for (b_col = 0; b_col < b_var->type->matrix_columns; b_col++) {
- ir_rvalue *a = get_column(a_var, 0);
- ir_rvalue *b = get_element(b_var, b_col, 0);
-
+ for (b_col = 0; b_col < b->type->matrix_columns; b_col++) {
/* first column */
expr = new(mem_ctx) ir_expression(ir_binop_mul,
- a->type,
- a,
- b);
+ get_column(a, 0),
+ get_element(b, b_col, 0));
/* following columns */
- for (i = 1; i < a_var->type->matrix_columns; i++) {
+ for (i = 1; i < a->type->matrix_columns; i++) {
ir_expression *mul_expr;
- a = get_column(a_var, i);
- b = get_element(b_var, b_col, i);
-
mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
- a->type,
- a,
- b);
+ get_column(a, i),
+ get_element(b, b_col, i));
expr = new(mem_ctx) ir_expression(ir_binop_add,
- a->type,
expr,
mul_expr);
}
- ir_rvalue *result = get_column(result_var, b_col);
- assign = new(mem_ctx) ir_assignment(result,
- expr,
- NULL);
+ assign = new(mem_ctx) ir_assignment(get_column(result, b_col), expr);
base_ir->insert_before(assign);
}
}
void
-ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_variable *result_var,
- ir_variable *a_var,
- ir_variable *b_var)
+ir_mat_op_to_vec_visitor::do_mul_mat_vec(ir_dereference *result,
+ ir_dereference *a,
+ ir_dereference *b)
{
int i;
- ir_rvalue *a = get_column(a_var, 0);
- ir_rvalue *b = get_element(b_var, 0, 0);
ir_assignment *assign;
ir_expression *expr;
/* first column */
expr = new(mem_ctx) ir_expression(ir_binop_mul,
- result_var->type,
- a,
- b);
+ get_column(a, 0),
+ get_element(b, 0, 0));
/* following columns */
- for (i = 1; i < a_var->type->matrix_columns; i++) {
+ for (i = 1; i < a->type->matrix_columns; i++) {
ir_expression *mul_expr;
- a = get_column(a_var, i);
- b = get_element(b_var, 0, i);
-
mul_expr = new(mem_ctx) ir_expression(ir_binop_mul,
- result_var->type,
- a,
- b);
- expr = new(mem_ctx) ir_expression(ir_binop_add,
- result_var->type,
- expr,
- mul_expr);
+ get_column(a, i),
+ get_element(b, 0, i));
+ expr = new(mem_ctx) ir_expression(ir_binop_add, expr, mul_expr);
}
- ir_rvalue *result = new(mem_ctx) ir_dereference_variable(result_var);
- assign = new(mem_ctx) ir_assignment(result,
- expr,
- NULL);
+ result = result->clone(mem_ctx, NULL);
+ assign = new(mem_ctx) ir_assignment(result, expr);
base_ir->insert_before(assign);
}
void
-ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_variable *result_var,
- ir_variable *a_var,
- ir_variable *b_var)
+ir_mat_op_to_vec_visitor::do_mul_vec_mat(ir_dereference *result,
+ ir_dereference *a,
+ ir_dereference *b)
{
int i;
- for (i = 0; i < b_var->type->matrix_columns; i++) {
- ir_rvalue *a = new(mem_ctx) ir_dereference_variable(a_var);
- ir_rvalue *b = get_column(b_var, i);
- ir_rvalue *result;
+ for (i = 0; i < b->type->matrix_columns; i++) {
+ ir_rvalue *column_result;
ir_expression *column_expr;
ir_assignment *column_assign;
- result = new(mem_ctx) ir_dereference_variable(result_var);
- result = new(mem_ctx) ir_swizzle(result, i, 0, 0, 0, 1);
+ column_result = result->clone(mem_ctx, NULL);
+ column_result = new(mem_ctx) ir_swizzle(column_result, i, 0, 0, 0, 1);
column_expr = new(mem_ctx) ir_expression(ir_binop_dot,
- result->type,
- a,
- b);
+ a->clone(mem_ctx, NULL),
+ get_column(b, i));
- column_assign = new(mem_ctx) ir_assignment(result,
- column_expr,
- NULL);
+ column_assign = new(mem_ctx) ir_assignment(column_result,
+ column_expr);
base_ir->insert_before(column_assign);
}
}
void
-ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_variable *result_var,
- ir_variable *a_var,
- ir_variable *b_var)
+ir_mat_op_to_vec_visitor::do_mul_mat_scalar(ir_dereference *result,
+ ir_dereference *a,
+ ir_dereference *b)
{
int i;
- for (i = 0; i < a_var->type->matrix_columns; i++) {
- ir_rvalue *a = get_column(a_var, i);
- ir_rvalue *b = new(mem_ctx) ir_dereference_variable(b_var);
- ir_rvalue *result = get_column(result_var, i);
+ for (i = 0; i < a->type->matrix_columns; i++) {
ir_expression *column_expr;
ir_assignment *column_assign;
column_expr = new(mem_ctx) ir_expression(ir_binop_mul,
- result->type,
- a,
- b);
+ get_column(a, i),
+ b->clone(mem_ctx, NULL));
- column_assign = new(mem_ctx) ir_assignment(result,
- column_expr,
- NULL);
+ column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
+ column_expr);
base_ir->insert_before(column_assign);
}
}
void
-ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var,
- ir_variable *a_var,
- ir_variable *b_var,
+ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result,
+ ir_dereference *a,
+ ir_dereference *b,
bool test_equal)
{
/* This essentially implements the following GLSL:
@@ -293,7 +248,7 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var,
* a[3] != b[3]);
* }
*/
- const unsigned columns = a_var->type->matrix_columns;
+ const unsigned columns = a->type->matrix_columns;
const glsl_type *const bvec_type =
glsl_type::get_instance(GLSL_TYPE_BOOL, columns, 1);
@@ -303,12 +258,10 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var,
this->base_ir->insert_before(tmp_bvec);
for (unsigned i = 0; i < columns; i++) {
- ir_dereference *const op0 = get_column(a_var, i);
- ir_dereference *const op1 = get_column(b_var, i);
-
ir_expression *const cmp =
new(this->mem_ctx) ir_expression(ir_binop_any_nequal,
- glsl_type::bool_type, op0, op1);
+ get_column(a, i),
+ get_column(b, i));
ir_dereference *const lhs =
new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
@@ -319,23 +272,14 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_variable *result_var,
this->base_ir->insert_before(assign);
}
- ir_rvalue *const val =
- new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
-
- ir_expression *any =
- new(this->mem_ctx) ir_expression(ir_unop_any, glsl_type::bool_type,
- val, NULL);
+ ir_rvalue *const val = new(this->mem_ctx) ir_dereference_variable(tmp_bvec);
+ ir_expression *any = new(this->mem_ctx) ir_expression(ir_unop_any, val);
if (test_equal)
- any = new(this->mem_ctx) ir_expression(ir_unop_logic_not,
- glsl_type::bool_type,
- any, NULL);
-
- ir_rvalue *const result =
- new(this->mem_ctx) ir_dereference_variable(result_var);
+ any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any);
ir_assignment *const assign =
- new(mem_ctx) ir_assignment(result, any, NULL);
+ new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any);
base_ir->insert_before(assign);
}
@@ -358,7 +302,7 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
{
ir_expression *orig_expr = orig_assign->rhs->as_expression();
unsigned int i, matrix_columns = 1;
- ir_variable *op_var[2];
+ ir_dereference *op[2];
if (!orig_expr)
return visit_continue;
@@ -370,51 +314,53 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
mem_ctx = ralloc_parent(orig_assign);
- ir_dereference_variable *lhs_deref =
+ ir_dereference_variable *result =
orig_assign->lhs->as_dereference_variable();
- assert(lhs_deref);
-
- ir_variable *result_var = lhs_deref->var;
+ assert(result);
/* Store the expression operands in temps so we can use them
* multiple times.
*/
for (i = 0; i < orig_expr->get_num_operands(); i++) {
ir_assignment *assign;
+ ir_dereference *deref = orig_expr->operands[i]->as_dereference();
- op_var[i] = new(mem_ctx) ir_variable(orig_expr->operands[i]->type,
- "mat_op_to_vec",
- ir_var_temporary);
- base_ir->insert_before(op_var[i]);
+ /* Avoid making a temporary if we don't need to to avoid aliasing. */
+ if (deref &&
+ deref->variable_referenced() != result->variable_referenced()) {
+ op[i] = deref;
+ continue;
+ }
- lhs_deref = new(mem_ctx) ir_dereference_variable(op_var[i]);
- assign = new(mem_ctx) ir_assignment(lhs_deref,
- orig_expr->operands[i],
- NULL);
+ /* Otherwise, store the operand in a temporary generally if it's
+ * not a dereference.
+ */
+ ir_variable *var = new(mem_ctx) ir_variable(orig_expr->operands[i]->type,
+ "mat_op_to_vec",
+ ir_var_temporary);
+ base_ir->insert_before(var);
+
+ /* Note that we use this dereference for the assignment. That means
+ * that others that want to use op[i] have to clone the deref.
+ */
+ op[i] = new(mem_ctx) ir_dereference_variable(var);
+ assign = new(mem_ctx) ir_assignment(op[i], orig_expr->operands[i]);
base_ir->insert_before(assign);
}
/* OK, time to break down this matrix operation. */
switch (orig_expr->operation) {
case ir_unop_neg: {
- const unsigned mask = (1U << result_var->type->vector_elements) - 1;
-
/* Apply the operation to each column.*/
for (i = 0; i < matrix_columns; i++) {
- ir_rvalue *op0 = get_column(op_var[0], i);
- ir_dereference *result = get_column(result_var, i);
ir_expression *column_expr;
ir_assignment *column_assign;
column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
- result->type,
- op0,
- NULL);
-
- column_assign = new(mem_ctx) ir_assignment(result,
- column_expr,
- NULL,
- mask);
+ get_column(op[0], i));
+
+ column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
+ column_expr);
assert(column_assign->write_mask != 0);
base_ir->insert_before(column_assign);
}
@@ -424,57 +370,49 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
case ir_binop_sub:
case ir_binop_div:
case ir_binop_mod: {
- const unsigned mask = (1U << result_var->type->vector_elements) - 1;
-
/* For most operations, the matrix version is just going
* column-wise through and applying the operation to each column
* if available.
*/
for (i = 0; i < matrix_columns; i++) {
- ir_rvalue *op0 = get_column(op_var[0], i);
- ir_rvalue *op1 = get_column(op_var[1], i);
- ir_dereference *result = get_column(result_var, i);
ir_expression *column_expr;
ir_assignment *column_assign;
column_expr = new(mem_ctx) ir_expression(orig_expr->operation,
- result->type,
- op0,
- op1);
-
- column_assign = new(mem_ctx) ir_assignment(result,
- column_expr,
- NULL,
- mask);
+ get_column(op[0], i),
+ get_column(op[1], i));
+
+ column_assign = new(mem_ctx) ir_assignment(get_column(result, i),
+ column_expr);
assert(column_assign->write_mask != 0);
base_ir->insert_before(column_assign);
}
break;
}
case ir_binop_mul:
- if (op_var[0]->type->is_matrix()) {
- if (op_var[1]->type->is_matrix()) {
- do_mul_mat_mat(result_var, op_var[0], op_var[1]);
- } else if (op_var[1]->type->is_vector()) {
- do_mul_mat_vec(result_var, op_var[0], op_var[1]);
+ if (op[0]->type->is_matrix()) {
+ if (op[1]->type->is_matrix()) {
+ do_mul_mat_mat(result, op[0], op[1]);
+ } else if (op[1]->type->is_vector()) {
+ do_mul_mat_vec(result, op[0], op[1]);
} else {
- assert(op_var[1]->type->is_scalar());
- do_mul_mat_scalar(result_var, op_var[0], op_var[1]);
+ assert(op[1]->type->is_scalar());
+ do_mul_mat_scalar(result, op[0], op[1]);
}
} else {
- assert(op_var[1]->type->is_matrix());
- if (op_var[0]->type->is_vector()) {
- do_mul_vec_mat(result_var, op_var[0], op_var[1]);
+ assert(op[1]->type->is_matrix());
+ if (op[0]->type->is_vector()) {
+ do_mul_vec_mat(result, op[0], op[1]);
} else {
- assert(op_var[0]->type->is_scalar());
- do_mul_mat_scalar(result_var, op_var[1], op_var[0]);
+ assert(op[0]->type->is_scalar());
+ do_mul_mat_scalar(result, op[1], op[0]);
}
}
break;
case ir_binop_all_equal:
case ir_binop_any_nequal:
- do_equal_mat_mat(result_var, op_var[1], op_var[0],
+ do_equal_mat_mat(result, op[1], op[0],
(orig_expr->operation == ir_binop_all_equal));
break;
diff --git a/src/glsl/main.cpp b/src/glsl/main.cpp
index 096da93dcef..7952bb1a3e3 100644
--- a/src/glsl/main.cpp
+++ b/src/glsl/main.cpp
@@ -76,6 +76,7 @@ initialize_context(struct gl_context *ctx, gl_api api)
ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
ctx->Extensions.EXT_texture_array = GL_TRUE;
ctx->Extensions.NV_texture_rectangle = GL_TRUE;
+ ctx->Extensions.EXT_texture3D = GL_TRUE;
/* GLSL 1.30 isn't fully supported, but we need to advertise 1.30 so that
* the built-in functions for 1.30 can be built.
diff --git a/src/glw/GLwDrawA.h b/src/glw/GLwDrawA.h
index cd631b4fb57..b9711c216bc 100644
--- a/src/glw/GLwDrawA.h
+++ b/src/glw/GLwDrawA.h
@@ -136,7 +136,7 @@
typedef struct _GLwMDrawingAreaClassRec *GLwMDrawingAreaWidgetClass;
typedef struct _GLwMDrawingAreaRec *GLwMDrawingAreaWidget;
-extern WidgetClass glwMDrawingAreaWidgetClass;
+GLAPI WidgetClass glwMDrawingAreaWidgetClass;
#else
@@ -144,7 +144,7 @@ extern WidgetClass glwMDrawingAreaWidgetClass;
typedef struct _GLwDrawingAreaClassRec *GLwDrawingAreaWidgetClass;
typedef struct _GLwDrawingAreaRec *GLwDrawingAreaWidget;
-extern WidgetClass glwDrawingAreaWidgetClass;
+GLAPI WidgetClass glwDrawingAreaWidgetClass;
#endif
@@ -177,8 +177,8 @@ extern "C" {
#endif
/* front ends to glXMakeCurrent and glXSwapBuffers */
-extern void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx);
-extern void GLwDrawingAreaSwapBuffers(Widget w);
+GLAPI void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx);
+GLAPI void GLwDrawingAreaSwapBuffers(Widget w);
#ifdef __GLX_MOTIF
#ifdef _NO_PROTO
diff --git a/src/glw/GLwDrawAP.h b/src/glw/GLwDrawAP.h
index f1217019541..4ff21b426dd 100644
--- a/src/glw/GLwDrawAP.h
+++ b/src/glw/GLwDrawAP.h
@@ -59,7 +59,7 @@ typedef struct _GLwMDrawingAreaClassRec {
} GLwMDrawingAreaClassRec;
-extern GLwMDrawingAreaClassRec glwMDrawingAreaClassRec;
+GLAPI GLwMDrawingAreaClassRec glwMDrawingAreaClassRec;
/* XT */
@@ -70,7 +70,7 @@ typedef struct _GLwDrawingAreaClassRec {
GLwDrawingAreaClassPart glwDrawingArea_class;
} GLwDrawingAreaClassRec;
-extern GLwDrawingAreaClassRec glwDrawingAreaClassRec;
+GLAPI GLwDrawingAreaClassRec glwDrawingAreaClassRec;
#endif
diff --git a/src/glx/SConscript b/src/glx/SConscript
new file mode 100644
index 00000000000..afef33727df
--- /dev/null
+++ b/src/glx/SConscript
@@ -0,0 +1,85 @@
+Import('*')
+
+if env['platform'] == 'windows':
+ Return()
+
+env = env.Clone()
+
+env.Prepend(CPPPATH = [
+ '#include',
+ '#include/GL/internal',
+ '#src/mesa',
+ '#src/mapi',
+ '#src/mapi/glapi',
+ #$(LIBDRM_CFLAGS)
+ #$(DRI2PROTO_CFLAGS)
+ #$(GLPROTO_CFLAGS)
+ #$(X11_INCLUDES)
+])
+
+env.Append(CPPDEFINES = [
+ '_REENTRANT',
+ #('DEFAULT_DRIVER_DIR', 'DRI_DRIVER_SEARCH_DIR')
+])
+
+env.Prepend(LIBS = [
+ glapi
+])
+
+env.PkgUseModules('X11')
+env.PkgUseModules('DRM')
+
+if env['HAVE_XF86VIDMODE']:
+ env.Append(CPPDEFINES = ['XF86VIDMODE'])
+ env.PkgUseModules('XF86VIDMODE')
+
+if False: # XXX: SHARED_GLAPI
+ env.Append(CPPDEFINES = ['GLX_SHARED_GLAPI'])
+
+sources = [
+ 'clientattrib.c',
+ 'compsize.c',
+ 'eval.c',
+ 'glxconfig.c',
+ 'glxcmds.c',
+ 'glxcurrent.c',
+ 'glxext.c',
+ 'glxextensions.c',
+ 'indirect_glx.c',
+ 'indirect.c',
+ 'indirect_init.c',
+ 'indirect_size.c',
+ 'indirect_window_pos.c',
+ 'indirect_texture_compression.c',
+ 'indirect_transpose_matrix.c',
+ 'indirect_vertex_array.c',
+ 'indirect_vertex_program.c',
+ 'pixel.c',
+ 'pixelstore.c',
+ 'render2.c',
+ 'renderpix.c',
+ 'single2.c',
+ 'singlepix.c',
+ 'vertarr.c',
+ 'xfont.c',
+ 'glx_pbuffer.c',
+ 'glx_query.c',
+ 'drisw_glx.c',
+ 'dri_common.c',
+ 'dri_glx.c',
+ 'XF86dri.c',
+ 'glxhash.c',
+ 'dri2_glx.c',
+ 'dri2.c',
+ 'applegl_glx.c',
+]
+
+libgl = env.SharedLibrary(
+ target ='GL',
+ source = sources,
+)
+
+libgl = env.InstallSharedLibrary(libgl, version=(1, 2))
+
+env.Alias('glx', libgl)
+env.Alias('libgl', libgl)
diff --git a/src/glx/apple/apple_glapi.c b/src/glx/apple/apple_glapi.c
index 0c89f46779c..34f726efb64 100644
--- a/src/glx/apple/apple_glapi.c
+++ b/src/glx/apple/apple_glapi.c
@@ -44,38 +44,18 @@
#include "apple_glx.h"
#include "apple_xgl_api.h"
-
-#ifndef OPENGL_FRAMEWORK_PATH
-#define OPENGL_FRAMEWORK_PATH "/System/Library/Frameworks/OpenGL.framework/OpenGL"
-#endif
+#include "apple_cgl.h"
struct _glapi_table * __ogl_framework_api = NULL;
struct _glapi_table * __applegl_api = NULL;
void apple_glapi_set_dispatch(void) {
- static void *handle;
- const char *opengl_framework_path;
-
if(__applegl_api) {
_glapi_set_dispatch(__applegl_api);
return;
}
- opengl_framework_path = getenv("OPENGL_FRAMEWORK_PATH");
- if (!opengl_framework_path) {
- opengl_framework_path = OPENGL_FRAMEWORK_PATH;
- }
-
- (void) dlerror(); /*drain dlerror */
- handle = dlopen(opengl_framework_path, RTLD_LOCAL);
-
- if (!handle) {
- fprintf(stderr, "error: unable to dlopen %s : %s\n",
- opengl_framework_path, dlerror());
- abort();
- }
-
- __ogl_framework_api = _glapi_create_table_from_handle(handle, "gl");
+ __ogl_framework_api = _glapi_create_table_from_handle(apple_cgl_get_dl_handle(), "gl");
assert(__ogl_framework_api);
__applegl_api = malloc(sizeof(struct _glapi_table));
diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c
index 4bf4672cede..8766c88a136 100644
--- a/src/glx/applegl_glx.c
+++ b/src/glx/applegl_glx.c
@@ -34,10 +34,12 @@
#if defined(GLX_USE_APPLEGL)
#include <stdbool.h>
+#include <dlfcn.h>
#include "glxclient.h"
#include "apple_glx_context.h"
#include "apple_glx.h"
+#include "apple_cgl.h"
#include "glx_error.h"
static void
@@ -82,6 +84,12 @@ applegl_wait_x(struct glx_context *gc)
apple_glx_waitx(dpy, gc->driContext);
}
+static void *
+applegl_get_proc_address(const char *symbol)
+{
+ return dlsym(apple_cgl_get_dl_handle(), symbol);
+}
+
static const struct glx_context_vtable applegl_context_vtable = {
applegl_destroy_context,
applegl_bind_context,
@@ -91,6 +99,7 @@ static const struct glx_context_vtable applegl_context_vtable = {
DRI_glXUseXFont,
NULL, /* bind_tex_image, */
NULL, /* release_tex_image, */
+ applegl_get_proc_address,
};
struct glx_context *
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 506754ccc1f..80e4da30beb 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -143,6 +143,8 @@ dri2_bind_context(struct glx_context *context, struct glx_context *old,
pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw);
pread = (struct dri2_drawable *) driFetchDrawable(context, read);
+ driReleaseDrawables(&pcp->base);
+
if (pdraw == NULL || pread == NULL)
return GLXBadDrawable;
@@ -170,9 +172,6 @@ dri2_unbind_context(struct glx_context *context, struct glx_context *new)
struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
(*psc->core->unbindContext) (pcp->driContext);
-
- if (context == new)
- driReleaseDrawables(&pcp->base);
}
static struct glx_context *
@@ -768,6 +767,7 @@ static const struct glx_context_vtable dri2_context_vtable = {
DRI_glXUseXFont,
dri2_bind_tex_image,
dri2_release_tex_image,
+ NULL, /* get_proc_address */
};
static void
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 06a73e4a6b2..bac0c9e5911 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -369,8 +369,10 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
if (priv->drawHash == NULL)
return NULL;
- if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0)
+ if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) {
+ pdraw->refcount ++;
return pdraw;
+ }
pdraw = psc->driScreen->createDrawable(psc, glxDrawable,
glxDrawable, gc->config);
@@ -378,6 +380,7 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
(*pdraw->destroyDrawable) (pdraw);
return NULL;
}
+ pdraw->refcount = 1;
return pdraw;
}
@@ -394,19 +397,28 @@ driReleaseDrawables(struct glx_context *gc)
if (__glxHashLookup(priv->drawHash,
gc->currentDrawable, (void *) &pdraw) == 0) {
if (pdraw->drawable == pdraw->xDrawable) {
- (*pdraw->destroyDrawable)(pdraw);
- __glxHashDelete(priv->drawHash, gc->currentDrawable);
+ pdraw->refcount --;
+ if (pdraw->refcount == 0) {
+ (*pdraw->destroyDrawable)(pdraw);
+ __glxHashDelete(priv->drawHash, gc->currentDrawable);
+ }
}
}
- if (gc->currentDrawable != gc->currentReadable &&
- __glxHashLookup(priv->drawHash,
+ if (__glxHashLookup(priv->drawHash,
gc->currentReadable, (void *) &pdraw) == 0) {
if (pdraw->drawable == pdraw->xDrawable) {
- (*pdraw->destroyDrawable)(pdraw);
- __glxHashDelete(priv->drawHash, gc->currentReadable);
+ pdraw->refcount --;
+ if (pdraw->refcount == 0) {
+ (*pdraw->destroyDrawable)(pdraw);
+ __glxHashDelete(priv->drawHash, gc->currentReadable);
+ }
}
}
+
+ gc->currentDrawable = None;
+ gc->currentReadable = None;
+
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index ff027dc9e9c..6f3b2b8900c 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -503,6 +503,8 @@ dri_destroy_context(struct glx_context * context)
struct dri_context *pcp = (struct dri_context *) context;
struct dri_screen *psc = (struct dri_screen *) context->psc;
+ driReleaseDrawables(&pcp->base);
+
if (context->xid)
glx_send_destroy_context(psc->base.dpy, context->xid);
@@ -526,6 +528,8 @@ dri_bind_context(struct glx_context *context, struct glx_context *old,
pdraw = (struct dri_drawable *) driFetchDrawable(context, draw);
pread = (struct dri_drawable *) driFetchDrawable(context, read);
+ driReleaseDrawables(&pcp->base);
+
if (pdraw == NULL || pread == NULL)
return GLXBadDrawable;
@@ -543,8 +547,6 @@ dri_unbind_context(struct glx_context *context, struct glx_context *new)
struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
(*psc->core->unbindContext) (pcp->driContext);
-
- driReleaseDrawables(&pcp->base);
}
static const struct glx_context_vtable dri_context_vtable = {
@@ -556,6 +558,7 @@ static const struct glx_context_vtable dri_context_vtable = {
DRI_glXUseXFont,
NULL,
NULL,
+ NULL, /* get_proc_address */
};
static struct glx_context *
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index 2eaa3c59348..d63f6e8d5ff 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -242,6 +242,8 @@ drisw_destroy_context(struct glx_context *context)
struct drisw_context *pcp = (struct drisw_context *) context;
struct drisw_screen *psc = (struct drisw_screen *) context->psc;
+ driReleaseDrawables(&pcp->base);
+
if (context->xid)
glx_send_destroy_context(psc->base.dpy, context->xid);
@@ -264,6 +266,8 @@ drisw_bind_context(struct glx_context *context, struct glx_context *old,
pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw);
pread = (struct drisw_drawable *) driFetchDrawable(context, read);
+ driReleaseDrawables(&pcp->base);
+
if (pdraw == NULL || pread == NULL)
return GLXBadDrawable;
@@ -281,8 +285,6 @@ drisw_unbind_context(struct glx_context *context, struct glx_context *new)
struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
(*psc->core->unbindContext) (pcp->driContext);
-
- driReleaseDrawables(&pcp->base);
}
static const struct glx_context_vtable drisw_context_vtable = {
@@ -294,6 +296,7 @@ static const struct glx_context_vtable drisw_context_vtable = {
DRI_glXUseXFont,
NULL,
NULL,
+ NULL, /* get_proc_address */
};
static struct glx_context *
@@ -359,10 +362,6 @@ driswCreateDrawable(struct glx_screen *base, XID xDrawable,
const __DRIswrastExtension *swrast = psc->swrast;
- /* Old dri can't handle GLX 1.3+ drawable constructors. */
- if (xDrawable != drawable)
- return NULL;
-
pdp = Xmalloc(sizeof(*pdp));
if (!pdp)
return NULL;
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 1f4c0f309fc..0e74e7ccd0e 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -187,7 +187,7 @@ determineTextureFormat(const int *attribs, int numAttribs)
return 0;
}
-static void
+static GLboolean
CreateDRIDrawable(Display *dpy, struct glx_config *config,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
@@ -198,22 +198,24 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config,
psc = priv->screens[config->screen];
if (psc->driScreen == NULL)
- return;
+ return GL_TRUE;
pdraw = psc->driScreen->createDrawable(psc, drawable,
glxdrawable, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n");
- return;
+ return GL_FALSE;
}
if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
- return; /* FIXME: Check what we're supposed to do here... */
+ return GL_FALSE;
}
pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
+
+ return GL_TRUE;
}
static void
@@ -234,11 +236,12 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
#else
-static void
+static GLboolean
CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig,
XID drawable, XID glxdrawable,
const int *attrib_list, size_t num_attribs)
{
+ return GL_FALSE;
}
static void
@@ -364,6 +367,27 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
return 0;
}
+static void
+protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
+{
+ xGLXDestroyPbufferReq *req;
+ CARD8 opcode;
+
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode)
+ return;
+
+ LockDisplay(dpy);
+
+ GetReq(GLXDestroyPbuffer, req);
+ req->reqType = opcode;
+ req->glxCode = glxCode;
+ req->pbuffer = (GLXPbuffer) drawable;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
/**
* Create a non-pbuffer GLX drawable.
*/
@@ -405,7 +429,14 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
SyncHandle();
- CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i);
+ if (!CreateDRIDrawable(dpy, config, drawable, xid, attrib_list, i)) {
+ if (glxCode == X_GLXCreatePixmap)
+ glxCode = X_GLXDestroyPixmap;
+ else
+ glxCode = X_GLXDestroyWindow;
+ protocolDestroyDrawable(dpy, xid, glxCode);
+ xid = None;
+ }
return xid;
}
@@ -417,27 +448,11 @@ CreateDrawable(Display *dpy, struct glx_config *config,
static void
DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
{
- xGLXDestroyPbufferReq *req;
- CARD8 opcode;
-
if ((dpy == NULL) || (drawable == 0)) {
return;
}
-
- opcode = __glXSetupForCommand(dpy);
- if (!opcode)
- return;
-
- LockDisplay(dpy);
-
- GetReq(GLXDestroyPbuffer, req);
- req->reqType = opcode;
- req->glxCode = glxCode;
- req->pbuffer = (GLXPbuffer) drawable;
-
- UnlockDisplay(dpy);
- SyncHandle();
+ protocolDestroyDrawable(dpy, drawable, glxCode);
DestroyDRIDrawable(dpy, drawable, GL_FALSE);
@@ -466,6 +481,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
CARD8 opcode;
unsigned int i;
Pixmap pixmap;
+ GLboolean glx_1_3 = GL_FALSE;
i = 0;
if (attrib_list) {
@@ -484,6 +500,8 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
xGLXCreatePbufferReq *req;
unsigned int extra = (size_in_attribs) ? 0 : 2;
+ glx_1_3 = GL_TRUE;
+
GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
data = (CARD32 *) (req + 1);
@@ -528,7 +546,12 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
width, height, config->rgbBits);
- CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i);
+ if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) {
+ CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX;
+ XFreePixmap(dpy, pixmap);
+ protocolDestroyDrawable(dpy, id, o);
+ id = None;
+ }
return id;
}
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index fa2e2d360ca..06415288165 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -138,6 +138,7 @@ struct __GLXDRIdrawableRec
GLenum textureTarget;
GLenum textureFormat; /* EXT_texture_from_pixmap support */
unsigned long eventMask;
+ int refcount;
};
/*
@@ -223,7 +224,7 @@ struct glx_context_vtable {
GLXDrawable drawable,
int buffer, const int *attrib_list);
void (*release_tex_image)(Display * dpy, GLXDrawable drawable, int buffer);
-
+ void * (*get_proc_address)(const char *symbol);
};
extern void
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index cd8bc97b192..191b321ce32 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -354,8 +354,9 @@ glx_send_destroy_context(Display *dpy, XID xid)
/*
** Destroy the named context
*/
-static void
-DestroyContext(Display * dpy, GLXContext ctx)
+
+_X_EXPORT void
+glXDestroyContext(Display * dpy, GLXContext ctx)
{
struct glx_context *gc = (struct glx_context *) ctx;
@@ -380,12 +381,6 @@ DestroyContext(Display * dpy, GLXContext ctx)
gc->vtable->destroy(gc);
}
-_X_EXPORT void
-glXDestroyContext(Display * dpy, GLXContext gc)
-{
- DestroyContext(dpy, gc);
-}
-
/*
** Return the major and minor version #s for the GLX extension
*/
@@ -645,19 +640,33 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
psc = priv->screens[vis->screen];
if (psc->driScreen == NULL)
- break;
+ return xid;
+
config = glx_config_find_visual(psc->visuals, vis->visualid);
pdraw = psc->driScreen->createDrawable(psc, pixmap, xid, config);
if (pdraw == NULL) {
fprintf(stderr, "failed to create pixmap\n");
+ xid = None;
break;
}
if (__glxHashInsert(priv->drawHash, xid, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
- return None; /* FIXME: Check what we're supposed to do here... */
+ xid = None;
+ break;
}
} while (0);
+
+ if (xid == None) {
+ xGLXDestroyGLXPixmapReq *dreq;
+ LockDisplay(dpy);
+ GetReq(GLXDestroyGLXPixmap, dreq);
+ dreq->reqType = opcode;
+ dreq->glxCode = X_GLXDestroyGLXPixmap;
+ dreq->glxpixmap = xid;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
#endif
return xid;
@@ -1479,12 +1488,9 @@ _X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user)
return ctx->xid;
}
-_X_EXPORT void
-glXFreeContextEXT(Display * dpy, GLXContext ctx)
-{
- DestroyContext(dpy, ctx);
-}
-
+_X_EXPORT
+GLX_ALIAS_VOID(glXFreeContextEXT, (Display *dpy, GLXContext ctx), (dpy, ctx),
+ glXDestroyContext);
_X_EXPORT GLXFBConfig *
glXChooseFBConfig(Display * dpy, int screen,
@@ -2521,6 +2527,12 @@ _X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
#endif
if (!f)
f = (gl_function) _glapi_get_proc_address((const char *) procName);
+ if (!f) {
+ struct glx_context *gc = __glXGetCurrentContext();
+
+ if (gc != NULL && gc->vtable->get_proc_address != NULL)
+ f = gc->vtable->get_proc_address((const char *) procName);
+ }
}
return f;
}
diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c
index 064fd71ae6e..c92a2fd3cc2 100644
--- a/src/glx/glxcurrent.c
+++ b/src/glx/glxcurrent.c
@@ -212,7 +212,6 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
{
struct glx_context *gc = (struct glx_context *) gc_user;
struct glx_context *oldGC = __glXGetCurrentContext();
- int ret = Success;
/* XXX: If this is left out, then libGL ends up not having this
* symbol, and drivers using it fail to load. Compare the
@@ -255,37 +254,45 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
if (--oldGC->thread_refcount == 0) {
oldGC->vtable->unbind(oldGC, gc);
oldGC->currentDpy = 0;
- oldGC->currentDrawable = None;
- oldGC->currentReadable = None;
-
- if (oldGC->xid == None && oldGC != gc) {
- /* We are switching away from a context that was
- * previously destroyed, so we need to free the memory
- * for the old handle. */
- oldGC->vtable->destroy(oldGC);
- }
}
}
if (gc) {
- if (gc->thread_refcount++ == 0) {
- gc->currentDpy = dpy;
- gc->currentDrawable = draw;
- gc->currentReadable = read;
+ /* Attempt to bind the context. We do this before mucking with
+ * gc and __glXSetCurrentContext to properly handle our state in
+ * case of an error.
+ *
+ * If an error occurs, set the Null context since we've already
+ * blown away our old context. The caller is responsible for
+ * figuring out how to handle setting a valid context.
+ */
+ if (gc->vtable->bind(gc, oldGC, draw, read) != Success) {
+ __glXSetCurrentContextNull();
+ __glXUnlock();
+ __glXGenerateError(dpy, None, GLXBadContext, X_GLXMakeContextCurrent);
+ return GL_FALSE;
}
+
+ if (gc->thread_refcount == 0) {
+ gc->currentDpy = dpy;
+ gc->currentDrawable = draw;
+ gc->currentReadable = read;
+ }
+ gc->thread_refcount++;
__glXSetCurrentContext(gc);
- ret = gc->vtable->bind(gc, oldGC, draw, read);
} else {
__glXSetCurrentContextNull();
}
- __glXUnlock();
-
- if (ret) {
- __glXGenerateError(dpy, None, ret, X_GLXMakeContextCurrent);
- return GL_FALSE;
+ if (oldGC->thread_refcount == 0 && oldGC != &dummyContext && oldGC->xid == None) {
+ /* We are switching away from a context that was
+ * previously destroyed, so we need to free the memory
+ * for the old handle. */
+ oldGC->vtable->destroy(oldGC);
}
+ __glXUnlock();
+
return GL_TRUE;
}
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index b4f16c72536..7b542dd159c 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -335,6 +335,7 @@ static const struct glx_context_vtable indirect_context_vtable = {
indirect_use_x_font,
indirect_bind_tex_image,
indirect_release_tex_image,
+ NULL, /* get_proc_address */
};
/**
diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript
index 276b2160246..a7764745eda 100644
--- a/src/mapi/glapi/SConscript
+++ b/src/mapi/glapi/SConscript
@@ -52,30 +52,23 @@ if env['platform'] != 'winddk':
if env['gcc'] and env['platform'] != 'windows':
if env['machine'] == 'x86':
env.Append(CPPDEFINES = [
- 'USE_X86_ASM',
- 'USE_MMX_ASM',
- 'USE_3DNOW_ASM',
- 'USE_SSE_ASM',
+ 'USE_X86_ASM',
])
glapi_sources += [
'glapi_x86.S',
]
elif env['machine'] == 'x86_64':
env.Append(CPPDEFINES = [
- 'USE_X86_64_ASM',
+ 'USE_X86_64_ASM',
])
glapi_sources += [
'glapi_x86-64.S'
]
- elif env['machine'] == 'ppc':
+ elif env['machine'] == 'sparc':
env.Append(CPPDEFINES = [
- 'USE_PPC_ASM',
- 'USE_VMX_ASM',
+ 'USE_SPARC_ASM',
])
glapi_sources += [
- ]
- elif env['machine'] == 'sparc':
- glapi_sources += [
'glapi_sparc.S'
]
else:
diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
index ca9a101a0ee..d9e540fc94d 100644
--- a/src/mapi/glapi/gen/ARB_geometry_shader4.xml
+++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
@@ -38,7 +38,7 @@
<param name="texture" type="GLuint"/>
<param name="level" type="GLint"/>
</function>
- <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayer">
+ <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayerEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="texture" type="GLuint"/>
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 08ea2870aa0..584df82b50c 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -31,8 +31,10 @@
#include "intel_regions.h"
#include "intel_tris.h"
#include "intel_fbo.h"
+#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
+#include "swrast_setup/swrast_setup.h"
#define FILE_DEBUG_FLAG DEBUG_STATE
@@ -715,6 +717,12 @@ i830_assert_not_dirty( struct intel_context *intel )
static void
i830_invalidate_state(struct intel_context *intel, GLuint new_state)
{
+ struct gl_context *ctx = &intel->ctx;
+
+ _swsetup_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+ _tnl_invalidate_vertex_state(ctx, new_state);
+
if (new_state & _NEW_LIGHT)
i830_update_provoking_vertex(&intel->ctx);
}
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index baff49bb2f5..9721a1c0e4d 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -33,8 +33,10 @@
#include "main/macros.h"
#include "main/colormac.h"
+#include "tnl/tnl.h"
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
+#include "swrast_setup/swrast_setup.h"
#include "intel_batchbuffer.h"
#include "intel_regions.h"
@@ -703,6 +705,16 @@ i915_is_hiz_depth_format(struct intel_context *intel,
return false;
}
+static void
+i915_invalidate_state(struct intel_context *intel, GLuint new_state)
+{
+ struct gl_context *ctx = &intel->ctx;
+
+ _swsetup_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+ _tnl_invalidate_vertex_state(ctx, new_state);
+}
+
void
i915InitVtbl(struct i915_context *i915)
{
@@ -717,6 +729,7 @@ i915InitVtbl(struct i915_context *i915)
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
i915->intel.vtbl.assert_not_dirty = i915_assert_not_dirty;
i915->intel.vtbl.finish_batch = intel_finish_vb;
+ i915->intel.vtbl.invalidate_state = i915_invalidate_state;
i915->intel.vtbl.render_target_supported = i915_render_target_supported;
i915->intel.vtbl.is_hiz_depth_format = i915_is_hiz_depth_format;
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index c7d428ba48d..d82206bae52 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -146,15 +146,12 @@ static void compile_clip_prog( struct brw_context *brw,
printf("\n");
}
- /* Upload
- */
- drm_intel_bo_unreference(brw->clip.prog_bo);
- brw->clip.prog_bo = brw_upload_cache(&brw->cache,
- BRW_CLIP_PROG,
- &c.key, sizeof(c.key),
- program, program_size,
- &c.prog_data, sizeof(c.prog_data),
- &brw->clip.prog_data);
+ brw_upload_cache(&brw->cache,
+ BRW_CLIP_PROG,
+ &c.key, sizeof(c.key),
+ program, program_size,
+ &c.prog_data, sizeof(c.prog_data),
+ &brw->clip.prog_offset, &brw->clip.prog_data);
ralloc_free(mem_ctx);
}
@@ -271,12 +268,11 @@ static void upload_clip_prog(struct brw_context *brw)
}
}
- drm_intel_bo_unreference(brw->clip.prog_bo);
- brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG,
- &key, sizeof(key),
- &brw->clip.prog_data);
- if (brw->clip.prog_bo == NULL)
+ if (!brw_search_cache(&brw->cache, BRW_CLIP_PROG,
+ &key, sizeof(key),
+ &brw->clip.prog_offset, &brw->clip.prog_data)) {
compile_clip_prog( brw, &key );
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index 6015c8cbe9f..b9efbb74c87 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -43,11 +43,15 @@ brw_prepare_clip_unit(struct brw_context *brw)
clip = brw_state_batch(brw, sizeof(*clip), 32, &brw->clip.state_offset);
memset(clip, 0, sizeof(*clip));
- /* CACHE_NEW_CLIP_PROG */
+ /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_CLIP_PROG */
clip->thread0.grf_reg_count = (ALIGN(brw->clip.prog_data->total_grf, 16) /
16 - 1);
- /* reloc */
- clip->thread0.kernel_start_pointer = brw->clip.prog_bo->offset >> 6;
+ clip->thread0.kernel_start_pointer =
+ brw_program_reloc(brw,
+ brw->clip.state_offset +
+ offsetof(struct brw_clip_unit_state, thread0),
+ brw->clip.prog_offset +
+ (clip->thread0.grf_reg_count << 1)) >> 6;
clip->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
clip->thread1.single_program_flow = 1;
@@ -110,14 +114,6 @@ brw_prepare_clip_unit(struct brw_context *brw)
clip->viewport_ymin = -1;
clip->viewport_ymax = 1;
- /* Emit clip program relocation */
- assert(brw->clip.prog_bo);
- drm_intel_bo_emit_reloc(intel->batch.bo,
- (brw->clip.state_offset +
- offsetof(struct brw_clip_unit_state, thread0)),
- brw->clip.prog_bo, clip->thread0.grf_reg_count << 1,
- I915_GEM_DOMAIN_INSTRUCTION, 0);
-
brw->state.dirty.cache |= CACHE_NEW_CLIP_UNIT;
}
@@ -125,6 +121,7 @@ const struct brw_tracked_state brw_clip_unit = {
.dirty = {
.mesa = _NEW_TRANSFORM,
.brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_URB_FENCE),
.cache = CACHE_NEW_CLIP_PROG
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index d6a99ab06e2..636821839a1 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -240,6 +240,8 @@ GLboolean brwCreateContext( int api,
brw->emit_state_always = 0;
+ intel->batch.need_workaround_flush = true;
+
ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 621b6f8990b..a8e2b802803 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -142,7 +142,9 @@ enum brw_state_id {
BRW_STATE_NR_VS_SURFACES,
BRW_STATE_INDEX_BUFFER,
BRW_STATE_VS_CONSTBUF,
- BRW_STATE_WM_CONSTBUF
+ BRW_STATE_WM_CONSTBUF,
+ BRW_STATE_PROGRAM_CACHE,
+ BRW_STATE_STATE_BASE_ADDRESS,
};
#define BRW_NEW_URB_FENCE (1 << BRW_STATE_URB_FENCE)
@@ -172,6 +174,8 @@ enum brw_state_id {
#define BRW_NEW_INDEX_BUFFER (1 << BRW_STATE_INDEX_BUFFER)
#define BRW_NEW_VS_CONSTBUF (1 << BRW_STATE_VS_CONSTBUF)
#define BRW_NEW_WM_CONSTBUF (1 << BRW_STATE_WM_CONSTBUF)
+#define BRW_NEW_PROGRAM_CACHE (1 << BRW_STATE_PROGRAM_CACHE)
+#define BRW_NEW_STATE_BASE_ADDRESS (1 << BRW_STATE_STATE_BASE_ADDRESS)
struct brw_state_flags {
/** State update flags signalled by mesa internals */
@@ -363,9 +367,11 @@ struct brw_cache_item {
/** 32-bit hash of the key data */
GLuint hash;
GLuint key_size; /* for variable-sized keys */
+ GLuint aux_size;
const void *key;
- drm_intel_bo *bo;
+ uint32_t offset;
+ uint32_t size;
struct brw_cache_item *next;
};
@@ -376,14 +382,11 @@ struct brw_cache {
struct brw_context *brw;
struct brw_cache_item **items;
+ drm_intel_bo *bo;
GLuint size, n_items;
- char *name[BRW_MAX_CACHE];
-
- /* Record of the last BOs chosen for each cache_id. Used to set
- * brw->state.dirty.cache when a new cache item is chosen.
- */
- drm_intel_bo *last_bo[BRW_MAX_CACHE];
+ uint32_t next_offset;
+ bool bo_used_by_gpu;
};
@@ -634,8 +637,9 @@ struct brw_context
struct brw_vs_prog_data *prog_data;
int8_t *constant_map; /* variable array following prog_data */
- drm_intel_bo *prog_bo;
drm_intel_bo *const_bo;
+ /** Offset in the program cache to the VS program */
+ uint32_t prog_offset;
uint32_t state_offset;
/** Binding table of pointers to surf_bo entries */
@@ -651,14 +655,16 @@ struct brw_context
struct brw_gs_prog_data *prog_data;
GLboolean prog_active;
+ /** Offset in the program cache to the CLIP program pre-gen6 */
+ uint32_t prog_offset;
uint32_t state_offset;
- drm_intel_bo *prog_bo;
} gs;
struct {
struct brw_clip_prog_data *prog_data;
- drm_intel_bo *prog_bo;
+ /** Offset in the program cache to the CLIP program pre-gen6 */
+ uint32_t prog_offset;
/* Offset in the batch to the CLIP state on pre-gen6. */
uint32_t state_offset;
@@ -673,7 +679,8 @@ struct brw_context
struct {
struct brw_sf_prog_data *prog_data;
- drm_intel_bo *prog_bo;
+ /** Offset in the program cache to the CLIP program pre-gen6 */
+ uint32_t prog_offset;
uint32_t state_offset;
uint32_t vp_offset;
} sf;
@@ -700,12 +707,14 @@ struct brw_context
GLuint sampler_count;
uint32_t sampler_offset;
+ /** Offset in the program cache to the WM program */
+ uint32_t prog_offset;
+
/** Binding table of pointers to surf_bo entries */
uint32_t bind_bo_offset;
uint32_t surf_offset[BRW_WM_MAX_SURF];
uint32_t state_offset; /* offset in batchbuffer to pre-gen6 WM state */
- drm_intel_bo *prog_bo;
drm_intel_bo *const_bo; /* pull constant buffer. */
/**
* This is offset in the batch to the push constants on gen6.
@@ -717,9 +726,6 @@ struct brw_context
struct {
- /* gen4 */
- drm_intel_bo *prog_bo;
-
uint32_t state_offset;
uint32_t blend_state_offset;
uint32_t depth_stencil_state_offset;
@@ -874,6 +880,26 @@ brw_register_blocks(int reg_count)
return ALIGN(reg_count, 16) / 16 - 1;
}
+static inline uint32_t
+brw_program_reloc(struct brw_context *brw, uint32_t state_offset,
+ uint32_t prog_offset)
+{
+ struct intel_context *intel = &brw->intel;
+
+ if (intel->gen >= 5) {
+ /* Using state base address. */
+ return prog_offset;
+ }
+
+ drm_intel_bo_emit_reloc(intel->batch.bo,
+ state_offset,
+ brw->cache.bo,
+ prog_offset,
+ I915_GEM_DOMAIN_INSTRUCTION, 0);
+
+ return brw->cache.bo->offset + prog_offset;
+}
+
GLboolean brw_do_cubemap_normalize(struct exec_list *instructions);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 6144f0a2bce..bdb5b672899 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -177,6 +177,8 @@ static void brw_emit_prim(struct brw_context *brw,
OUT_BATCH(base_vertex_location);
ADVANCE_BATCH();
+ intel->batch.need_workaround_flush = true;
+
if (intel->always_flush_cache) {
intel_batchbuffer_emit_mi_flush(intel);
}
@@ -434,6 +436,7 @@ void brw_draw_prims( struct gl_context *ctx,
*/
if (!retval) {
_swsetup_Wakeup(ctx);
+ _tnl_wakeup(ctx);
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
}
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index c6e53951069..32a1d297479 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -278,6 +278,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
{
struct gl_context *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
+ /* CACHE_NEW_VS_PROG */
GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
const unsigned char *ptr = NULL;
GLuint interleaved = 0, total_size = 0;
@@ -499,6 +500,8 @@ static void brw_prepare_vertices(struct brw_context *brw)
break;
d = brw->vb.buffers[i].offset - brw->vb.current_buffers[i].offset;
+ if (d < 0)
+ break;
if (i == 0)
delta = d / brw->vb.current_buffers[i].stride;
if (delta * brw->vb.current_buffers[i].stride != d)
@@ -646,7 +649,7 @@ const struct brw_tracked_state brw_vertices = {
.dirty = {
.mesa = 0,
.brw = BRW_NEW_BATCH | BRW_NEW_VERTICES,
- .cache = 0,
+ .cache = CACHE_NEW_VS_PROG,
},
.prepare = brw_prepare_vertices,
.emit = brw_emit_vertices,
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 7c73a8fbf02..b5ea943387d 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1533,6 +1533,8 @@ fs_visitor::run()
this->result = reg_undef;
ir->accept(this);
}
+ if (failed)
+ return false;
emit_fb_writes();
@@ -1684,6 +1686,9 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
key.clamp_fragment_color = true;
for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+ if (fp->Base.ShadowSamplers & (1 << i))
+ key.compare_funcs[i] = GL_LESS;
+
/* FINISHME: depth compares might use (0,0,0,W) for example */
key.tex_swizzles[i] = SWIZZLE_XYZW;
}
@@ -1697,14 +1702,12 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
key.program_string_id = bfp->id;
- drm_intel_bo *old_prog_bo = brw->wm.prog_bo;
+ uint32_t old_prog_offset = brw->wm.prog_offset;
struct brw_wm_prog_data *old_prog_data = brw->wm.prog_data;
- brw->wm.prog_bo = NULL;
bool success = do_wm_prog(brw, prog, bfp, &key);
- drm_intel_bo_unreference(brw->wm.prog_bo);
- brw->wm.prog_bo = old_prog_bo;
+ brw->wm.prog_offset = old_prog_offset;
brw->wm.prog_data = old_prog_data;
return success;
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 7570dda1024..2bf850e5dea 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -441,6 +441,8 @@ public:
void visit(ir_function *ir);
void visit(ir_function_signature *ir);
+ void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler);
+
fs_inst *emit(fs_inst inst);
fs_inst *emit(int opcode)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
index 7f3f52854d2..46677a6f2ef 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_channel_expressions.cpp
@@ -191,6 +191,8 @@ ir_channel_expressions_visitor::visit_leave(ir_assignment *ir)
case ir_unop_log:
case ir_unop_exp2:
case ir_unop_log2:
+ case ir_unop_i2u:
+ case ir_unop_u2i:
case ir_unop_f2i:
case ir_unop_i2f:
case ir_unop_f2b:
diff --git a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
index 6b7c434949c..1d89b8f1d11 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_emit.cpp
@@ -273,7 +273,8 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
}
break;
case FS_OPCODE_TXD:
- assert(!"TXD isn't supported on gen5+ yet.");
+ /* There is no sample_d_c message; comparisons are done manually */
+ msg_type = GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS;
break;
}
} else {
@@ -311,7 +312,9 @@ fs_visitor::generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src)
}
break;
case FS_OPCODE_TXD:
- assert(!"TXD isn't supported on gen4 yet.");
+ /* There is no sample_d_c message; comparisons are done manually */
+ assert(inst->mlen == 7 || inst->mlen == 10);
+ msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS;
break;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
index f88b1316775..b4689d2c293 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_reg_allocate.cpp
@@ -101,7 +101,6 @@ fs_visitor::assign_regs()
* for reg_width == 2.
*/
int reg_width = c->dispatch_width / 8;
- int last_grf = 0;
int hw_reg_mapping[this->virtual_grf_next + 1];
int first_assigned_grf = ALIGN(this->first_non_payload_grf, reg_width);
int base_reg_count = (BRW_MAX_GRF - first_assigned_grf) / reg_width;
@@ -263,6 +262,7 @@ fs_visitor::assign_regs()
* regs in the register classes back down to real hardware reg
* numbers.
*/
+ this->grf_used = first_assigned_grf;
hw_reg_mapping[0] = 0; /* unused */
for (int i = 1; i < this->virtual_grf_next; i++) {
int reg = ra_get_node_reg(g, i);
@@ -278,8 +278,9 @@ fs_visitor::assign_regs()
assert(hw_reg >= 0);
hw_reg_mapping[i] = first_assigned_grf + hw_reg * reg_width;
- last_grf = MAX2(last_grf,
- hw_reg_mapping[i] + this->virtual_grf_sizes[i] - 1);
+ this->grf_used = MAX2(this->grf_used,
+ hw_reg_mapping[i] + this->virtual_grf_sizes[i] *
+ reg_width);
}
foreach_iter(exec_list_iterator, iter, this->instructions) {
@@ -290,8 +291,6 @@ fs_visitor::assign_regs()
assign_reg(hw_reg_mapping, &inst->src[1], reg_width);
}
- this->grf_used = last_grf + reg_width;
-
ralloc_free(g);
ralloc_free(regs);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index b4857871c78..9091014976b 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -349,6 +349,14 @@ fs_visitor::visit(ir_expression *ir)
emit_math(FS_OPCODE_RSQ, this->result, op[0]);
break;
+ case ir_unop_i2u:
+ op[0].type = BRW_REGISTER_TYPE_UD;
+ this->result = op[0];
+ break;
+ case ir_unop_u2i:
+ op[0].type = BRW_REGISTER_TYPE_D;
+ this->result = op[0];
+ break;
case ir_unop_i2f:
case ir_unop_b2f:
case ir_unop_b2i:
@@ -549,7 +557,7 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
/* g0 header. */
mlen = 1;
- if (ir->shadow_comparitor) {
+ if (ir->shadow_comparitor && ir->op != ir_txd) {
for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
fs_inst *inst = emit(BRW_OPCODE_MOV,
fs_reg(MRF, base_mrf + mlen + i), coordinate);
@@ -595,7 +603,42 @@ fs_visitor::emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate,
/* gen4's SIMD8 sampler always has the slots for u,v,r present. */
mlen += 3;
} else if (ir->op == ir_txd) {
- assert(!"TXD isn't supported on gen4 yet.");
+ ir->lod_info.grad.dPdx->accept(this);
+ fs_reg dPdx = this->result;
+
+ ir->lod_info.grad.dPdy->accept(this);
+ fs_reg dPdy = this->result;
+
+ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen + i), coordinate);
+ coordinate.reg_offset++;
+ }
+ /* the slots for u and v are always present, but r is optional */
+ mlen += MAX2(ir->coordinate->type->vector_elements, 2);
+
+ /* P = u, v, r
+ * dPdx = dudx, dvdx, drdx
+ * dPdy = dudy, dvdy, drdy
+ *
+ * 2-arg: dudx dvdx dudy dvdy
+ * dPdx.x dPdx.y dPdy.x dPdy.y
+ * m4 m5 m6 m7
+ *
+ * 3-arg: dudx dvdx drdx dudy dvdy drdy
+ * dPdx.x dPdx.y dPdx.z dPdy.x dPdy.y dPdy.z
+ * m5 m6 m7 m8 m9 m10
+ */
+ for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+ dPdx.reg_offset++;
+ mlen++;
+ }
+
+ for (int i = 0; i < ir->lod_info.grad.dPdy->type->vector_elements; i++) {
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+ dPdy.reg_offset++;
+ mlen++;
+ }
} else {
/* Oh joy. gen4 doesn't have SIMD8 non-shadow-compare bias/lod
* instructions. We'll need to do SIMD16 here.
@@ -709,7 +752,7 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
}
mlen += ir->coordinate->type->vector_elements * reg_width;
- if (ir->shadow_comparitor) {
+ if (ir->shadow_comparitor && ir->op != ir_txd) {
mlen = MAX2(mlen, header_present + 4 * reg_width);
this->result = reg_undef;
@@ -742,7 +785,37 @@ fs_visitor::emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate,
inst = emit(FS_OPCODE_TXL, dst);
break;
- case ir_txd:
+ case ir_txd: {
+ ir->lod_info.grad.dPdx->accept(this);
+ fs_reg dPdx = this->result;
+
+ ir->lod_info.grad.dPdy->accept(this);
+ fs_reg dPdy = this->result;
+
+ mlen = MAX2(mlen, header_present + 4 * reg_width); /* skip over 'ai' */
+
+ /**
+ * P = u, v, r
+ * dPdx = dudx, dvdx, drdx
+ * dPdy = dudy, dvdy, drdy
+ *
+ * Load up these values:
+ * - dudx dudy dvdx dvdy drdx drdy
+ * - dPdx.x dPdy.x dPdx.y dPdy.y dPdx.z dPdy.z
+ */
+ for (int i = 0; i < ir->lod_info.grad.dPdx->type->vector_elements; i++) {
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+ dPdx.reg_offset++;
+ mlen += reg_width;
+
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+ dPdy.reg_offset++;
+ mlen += reg_width;
+ }
+
+ inst = emit(FS_OPCODE_TXD, dst);
+ break;
+ }
case ir_txf:
assert(!"GLSL 1.30 features unsupported");
break;
@@ -776,7 +849,7 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
base_mrf--;
}
- if (ir->shadow_comparitor) {
+ if (ir->shadow_comparitor && ir->op != ir_txd) {
ir->shadow_comparitor->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen += reg_width;
@@ -796,20 +869,52 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen += reg_width;
break;
- case ir_txd:
+ case ir_txd: {
+ if (c->dispatch_width == 16)
+ fail("Gen7 does not support sample_d/sample_d_c in SIMD16 mode.");
+
+ ir->lod_info.grad.dPdx->accept(this);
+ fs_reg dPdx = this->result;
+
+ ir->lod_info.grad.dPdy->accept(this);
+ fs_reg dPdy = this->result;
+
+ /* Load dPdx and the coordinate together:
+ * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
+ */
+ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
+ coordinate);
+ if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+ inst->saturate = true;
+ coordinate.reg_offset++;
+ mlen += reg_width;
+
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdx);
+ dPdx.reg_offset++;
+ mlen += reg_width;
+
+ emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), dPdy);
+ dPdy.reg_offset++;
+ mlen += reg_width;
+ }
+ break;
+ }
case ir_txf:
assert(!"GLSL 1.30 features unsupported");
break;
}
- /* Set up the coordinate */
- for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
- fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
- coordinate);
- if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
- inst->saturate = true;
- coordinate.reg_offset++;
- mlen += reg_width;
+ /* Set up the coordinate (except for TXD where it was done earlier) */
+ if (ir->op != ir_txd) {
+ for (int i = 0; i < ir->coordinate->type->vector_elements; i++) {
+ fs_inst *inst = emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen),
+ coordinate);
+ if (i < 3 && c->key.gl_clamp_mask[i] & (1 << sampler))
+ inst->saturate = true;
+ coordinate.reg_offset++;
+ mlen += reg_width;
+ }
}
/* Generate the SEND */
@@ -835,9 +940,24 @@ fs_visitor::emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
void
fs_visitor::visit(ir_texture *ir)
{
- int sampler;
fs_inst *inst = NULL;
+ int sampler = _mesa_get_sampler_uniform_value(ir->sampler, prog, &fp->Base);
+ sampler = fp->Base.SamplerUnits[sampler];
+
+ /* Our hardware doesn't have a sample_d_c message, so shadow compares
+ * for textureGrad/TXD need to be emulated with instructions.
+ */
+ bool hw_compare_supported = ir->op != ir_txd;
+ if (ir->shadow_comparitor && !hw_compare_supported) {
+ assert(c->key.compare_funcs[sampler] != GL_NONE);
+ /* No need to even sample for GL_ALWAYS or GL_NEVER...bail early */
+ if (c->key.compare_funcs[sampler] == GL_ALWAYS)
+ return swizzle_result(ir, fs_reg(1.0f), sampler);
+ else if (c->key.compare_funcs[sampler] == GL_NEVER)
+ return swizzle_result(ir, fs_reg(0.0f), sampler);
+ }
+
this->result = reg_undef;
ir->coordinate->accept(this);
fs_reg coordinate = this->result;
@@ -876,11 +996,6 @@ fs_visitor::visit(ir_texture *ir)
/* Should be lowered by do_lower_texture_projection */
assert(!ir->projector);
- sampler = _mesa_get_sampler_uniform_value(ir->sampler,
- prog,
- &fp->Base);
- sampler = fp->Base.SamplerUnits[sampler];
-
/* The 965 requires the EU to do the normalization of GL rectangle
* texture coordinates. We use the program parameter state
* tracking to get the scaling factor.
@@ -951,20 +1066,69 @@ fs_visitor::visit(ir_texture *ir)
inst->sampler = sampler;
- this->result = dst;
+ if (ir->shadow_comparitor) {
+ if (hw_compare_supported) {
+ inst->shadow_compare = true;
+ } else {
+ ir->shadow_comparitor->accept(this);
+ fs_reg ref = this->result;
+
+ fs_reg value = dst;
+ dst = fs_reg(this, glsl_type::vec4_type);
+
+ /* FINISHME: This needs to be done pre-filtering. */
+
+ uint32_t conditional = 0;
+ switch (c->key.compare_funcs[sampler]) {
+ /* GL_ALWAYS and GL_NEVER were handled at the top of the function */
+ case GL_LESS: conditional = BRW_CONDITIONAL_L; break;
+ case GL_GREATER: conditional = BRW_CONDITIONAL_G; break;
+ case GL_LEQUAL: conditional = BRW_CONDITIONAL_LE; break;
+ case GL_GEQUAL: conditional = BRW_CONDITIONAL_GE; break;
+ case GL_EQUAL: conditional = BRW_CONDITIONAL_EQ; break;
+ case GL_NOTEQUAL: conditional = BRW_CONDITIONAL_NEQ; break;
+ default: assert(!"Should not get here: bad shadow compare function");
+ }
+
+ /* Use conditional moves to load 0 or 1 as the result */
+ this->current_annotation = "manual shadow comparison";
+ for (int i = 0; i < 4; i++) {
+ inst = emit(BRW_OPCODE_MOV, dst, fs_reg(0.0f));
+
+ inst = emit(BRW_OPCODE_CMP, reg_null_f, ref, value);
+ inst->conditional_mod = conditional;
+
+ inst = emit(BRW_OPCODE_MOV, dst, fs_reg(1.0f));
+ inst->predicated = true;
- if (ir->shadow_comparitor)
- inst->shadow_compare = true;
+ dst.reg_offset++;
+ value.reg_offset++;
+ }
+ dst.reg_offset = 0;
+ }
+ }
+
+ swizzle_result(ir, dst, sampler);
+}
+
+/**
+ * Swizzle the result of a texture result. This is necessary for
+ * EXT_texture_swizzle as well as DEPTH_TEXTURE_MODE for shadow comparisons.
+ */
+void
+fs_visitor::swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler)
+{
+ this->result = orig_val;
if (ir->type == glsl_type::float_type) {
/* Ignore DEPTH_TEXTURE_MODE swizzling. */
assert(ir->sampler->type->sampler_shadow);
- } else if (c->key.tex_swizzles[inst->sampler] != SWIZZLE_NOOP) {
- fs_reg swizzle_dst = fs_reg(this, glsl_type::vec4_type);
+ } else if (c->key.tex_swizzles[sampler] != SWIZZLE_NOOP) {
+ fs_reg swizzled_result = fs_reg(this, glsl_type::vec4_type);
for (int i = 0; i < 4; i++) {
- int swiz = GET_SWZ(c->key.tex_swizzles[inst->sampler], i);
- fs_reg l = swizzle_dst;
+ int swiz = GET_SWZ(c->key.tex_swizzles[sampler], i);
+ fs_reg l = swizzled_result;
l.reg_offset += i;
if (swiz == SWIZZLE_ZERO) {
@@ -972,12 +1136,12 @@ fs_visitor::visit(ir_texture *ir)
} else if (swiz == SWIZZLE_ONE) {
emit(BRW_OPCODE_MOV, l, fs_reg(1.0f));
} else {
- fs_reg r = dst;
- r.reg_offset += GET_SWZ(c->key.tex_swizzles[inst->sampler], i);
+ fs_reg r = orig_val;
+ r.reg_offset += GET_SWZ(c->key.tex_swizzles[sampler], i);
emit(BRW_OPCODE_MOV, l, r);
}
}
- this->result = swizzle_dst;
+ this->result = swizzled_result;
}
}
@@ -1466,7 +1630,7 @@ fs_visitor::emit_dummy_fs()
fs_inst *write;
write = emit(FS_OPCODE_FB_WRITE, fs_reg(0), fs_reg(0));
- write->base_mrf = 0;
+ write->base_mrf = 2;
}
/* The register location here is relative to the start of the URB
@@ -1627,7 +1791,7 @@ fs_visitor::emit_fb_writes()
{
this->current_annotation = "FB write header";
GLboolean header_present = GL_TRUE;
- int nr = 0;
+ int nr = 2;
int reg_width = c->dispatch_width / 8;
if (intel->gen >= 6 &&
@@ -1637,7 +1801,7 @@ fs_visitor::emit_fb_writes()
}
if (header_present) {
- /* m0, m1 header */
+ /* m2, m3 header */
nr += 2;
}
@@ -1706,7 +1870,7 @@ fs_visitor::emit_fb_writes()
fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
inst->target = target;
- inst->base_mrf = 0;
+ inst->base_mrf = 2;
inst->mlen = nr;
if (target == c->key.nr_color_regions - 1)
inst->eot = true;
@@ -1724,7 +1888,7 @@ fs_visitor::emit_fb_writes()
}
fs_inst *inst = emit(FS_OPCODE_FB_WRITE);
- inst->base_mrf = 0;
+ inst->base_mrf = 2;
inst->mlen = nr;
inst->eot = true;
inst->header_present = header_present;
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 001cd62f8ca..3171e97d7af 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -121,14 +121,11 @@ static void compile_gs_prog( struct brw_context *brw,
printf("\n");
}
- /* Upload
- */
- drm_intel_bo_unreference(brw->gs.prog_bo);
- brw->gs.prog_bo = brw_upload_cache(&brw->cache, BRW_GS_PROG,
- &c.key, sizeof(c.key),
- program, program_size,
- &c.prog_data, sizeof(c.prog_data),
- &brw->gs.prog_data);
+ brw_upload_cache(&brw->cache, BRW_GS_PROG,
+ &c.key, sizeof(c.key),
+ program, program_size,
+ &c.prog_data, sizeof(c.prog_data),
+ &brw->gs.prog_offset, &brw->gs.prog_data);
ralloc_free(mem_ctx);
}
@@ -189,15 +186,12 @@ static void prepare_gs_prog(struct brw_context *brw)
brw->gs.prog_active = key.need_gs_prog;
}
- drm_intel_bo_unreference(brw->gs.prog_bo);
- brw->gs.prog_bo = NULL;
-
if (brw->gs.prog_active) {
- brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG,
- &key, sizeof(key),
- &brw->gs.prog_data);
- if (brw->gs.prog_bo == NULL)
+ if (!brw_search_cache(&brw->cache, BRW_GS_PROG,
+ &key, sizeof(key),
+ &brw->gs.prog_offset, &brw->gs.prog_data)) {
compile_gs_prog( brw, &key );
+ }
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index 542874b7706..bbfefcd816a 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -45,12 +45,17 @@ brw_prepare_gs_unit(struct brw_context *brw)
memset(gs, 0, sizeof(*gs));
- /* CACHE_NEW_GS_PROG */
+ /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_GS_PROG */
if (brw->gs.prog_active) {
gs->thread0.grf_reg_count = (ALIGN(brw->gs.prog_data->total_grf, 16) /
16 - 1);
- /* reloc */
- gs->thread0.kernel_start_pointer = brw->gs.prog_bo->offset >> 6;
+
+ gs->thread0.kernel_start_pointer =
+ brw_program_reloc(brw,
+ brw->gs.state_offset +
+ offsetof(struct brw_gs_unit_state, thread0),
+ brw->gs.prog_offset +
+ (gs->thread0.grf_reg_count << 1)) >> 6;
gs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
gs->thread1.single_program_flow = 1;
@@ -69,13 +74,6 @@ brw_prepare_gs_unit(struct brw_context *brw)
gs->thread4.max_threads = 1;
else
gs->thread4.max_threads = 0;
-
- /* Emit GS program relocation */
- drm_intel_bo_emit_reloc(intel->batch.bo,
- (brw->gs.state_offset +
- offsetof(struct brw_gs_unit_state, thread0)),
- brw->gs.prog_bo, gs->thread0.grf_reg_count << 1,
- I915_GEM_DOMAIN_INSTRUCTION, 0);
}
if (intel->gen == 5)
@@ -91,6 +89,7 @@ const struct brw_tracked_state brw_gs_unit = {
.dirty = {
.mesa = 0,
.brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_URB_FENCE),
.cache = CACHE_NEW_GS_PROG
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 2b5ec8ac677..033c77cd321 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -87,10 +87,11 @@ static void upload_binding_table_pointers(struct brw_context *brw)
const struct brw_tracked_state brw_binding_table_pointers = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH
- | BRW_NEW_VS_BINDING_TABLE
- | BRW_NEW_GS_BINDING_TABLE
- | BRW_NEW_PS_BINDING_TABLE,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS |
+ BRW_NEW_VS_BINDING_TABLE |
+ BRW_NEW_GS_BINDING_TABLE |
+ BRW_NEW_PS_BINDING_TABLE),
.cache = 0,
},
.emit = upload_binding_table_pointers,
@@ -122,10 +123,11 @@ static void upload_gen6_binding_table_pointers(struct brw_context *brw)
const struct brw_tracked_state gen6_binding_table_pointers = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH
- | BRW_NEW_VS_BINDING_TABLE
- | BRW_NEW_GS_BINDING_TABLE
- | BRW_NEW_PS_BINDING_TABLE,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS |
+ BRW_NEW_VS_BINDING_TABLE |
+ BRW_NEW_GS_BINDING_TABLE |
+ BRW_NEW_PS_BINDING_TABLE),
.cache = 0,
},
.emit = upload_gen6_binding_table_pointers,
@@ -180,7 +182,9 @@ static void upload_psp_urb_cbs(struct brw_context *brw )
const struct brw_tracked_state brw_psp_urb_cbs = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_URB_FENCE | BRW_NEW_BATCH,
+ .brw = (BRW_NEW_URB_FENCE |
+ BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS),
.cache = (CACHE_NEW_VS_UNIT |
CACHE_NEW_GS_UNIT |
CACHE_NEW_GS_PROG |
@@ -219,6 +223,12 @@ static void emit_depthbuffer(struct brw_context *brw)
struct intel_region *hiz_region = depth_irb ? depth_irb->hiz_region : NULL;
unsigned int len;
+ /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both
+ * non-pipelined state that will need the PIPE_CONTROL workaround.
+ */
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
/*
* If either depth or stencil buffer has packed depth/stencil format,
* then don't use separate stencil. Emit only a depth buffer.
@@ -355,26 +365,48 @@ static void emit_depthbuffer(struct brw_context *brw)
ADVANCE_BATCH();
}
- /* Emit hiz buffer. */
if (hiz_region || stencil_irb) {
- BEGIN_BATCH(3);
- OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
- OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1);
- OUT_RELOC(hiz_region->buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- 0);
- ADVANCE_BATCH();
- }
+ /*
+ * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate
+ * stencil enable' and 'hiz enable' bits were set. Therefore we must
+ * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if
+ * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted;
+ * failure to do so causes hangs on gen5 and a stall on gen6.
+ */
- /* Emit stencil buffer. */
- if (hiz_region || stencil_irb) {
- BEGIN_BATCH(3);
- OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
- OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1);
- OUT_RELOC(stencil_irb->region->buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- 0);
- ADVANCE_BATCH();
+ /* Emit hiz buffer. */
+ if (hiz_region) {
+ BEGIN_BATCH(3);
+ OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
+ OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1);
+ OUT_RELOC(hiz_region->buffer,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+ 0);
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(3);
+ OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
+
+ /* Emit stencil buffer. */
+ if (stencil_irb) {
+ BEGIN_BATCH(3);
+ OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
+ OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1);
+ OUT_RELOC(stencil_irb->region->buffer,
+ I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+ 0);
+ ADVANCE_BATCH();
+ } else {
+ BEGIN_BATCH(3);
+ OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ }
}
/*
@@ -386,6 +418,9 @@ static void emit_depthbuffer(struct brw_context *brw)
* when HiZ is enabled and the DEPTH_BUFFER_STATE changes.
*/
if (intel->gen >= 6 || hiz_region) {
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | (2 - 2));
OUT_BATCH(0);
@@ -418,6 +453,9 @@ static void upload_polygon_stipple(struct brw_context *brw)
if (!ctx->Polygon.StippleFlag)
return;
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
BEGIN_BATCH(33);
OUT_BATCH(_3DSTATE_POLY_STIPPLE_PATTERN << 16 | (33 - 2));
@@ -461,6 +499,9 @@ static void upload_polygon_stipple_offset(struct brw_context *brw)
if (!ctx->Polygon.StippleFlag)
return;
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_POLY_STIPPLE_OFFSET << 16 | (2-2));
@@ -501,6 +542,9 @@ static void upload_aa_line_parameters(struct brw_context *brw)
if (!ctx->Line.SmoothFlag || !brw->has_aa_line_parameters)
return;
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
OUT_BATCH(_3DSTATE_AA_LINE_PARAMETERS << 16 | (3 - 2));
/* use legacy aa line coverage computation */
OUT_BATCH(0);
@@ -531,6 +575,9 @@ static void upload_line_stipple(struct brw_context *brw)
if (!ctx->Line.StippleFlag)
return;
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
BEGIN_BATCH(3);
OUT_BATCH(_3DSTATE_LINE_STIPPLE_PATTERN << 16 | (3 - 2));
OUT_BATCH(ctx->Line.StipplePattern);
@@ -558,6 +605,10 @@ static void upload_invarient_state( struct brw_context *brw )
{
struct intel_context *intel = &brw->intel;
+ /* 3DSTATE_SIP, 3DSTATE_MULTISAMPLE, etc. are nonpipelined. */
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
{
/* 0x61040000 Pipeline Select */
/* PipelineSelect : 0 */
@@ -621,6 +672,7 @@ static void upload_invarient_state( struct brw_context *brw )
sip.header.length = 0;
sip.bits0.pad = 0;
sip.bits0.system_instruction_pointer = 0;
+
BRW_BATCH_STRUCT(brw, &sip);
}
@@ -660,7 +712,19 @@ static void upload_state_base_address( struct brw_context *brw )
{
struct intel_context *intel = &brw->intel;
+ /* FINISHME: According to section 3.6.1 "STATE_BASE_ADDRESS" of
+ * vol1a of the G45 PRM, MI_FLUSH with the ISC invalidate should be
+ * programmed prior to STATE_BASE_ADDRESS.
+ *
+ * However, given that the instruction SBA (general state base
+ * address) on this chipset is always set to 0 across X and GL,
+ * maybe this isn't required for us in particular.
+ */
+
if (intel->gen >= 6) {
+ if (intel->gen == 6)
+ intel_emit_post_sync_nonzero_flush(intel);
+
BEGIN_BATCH(10);
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (10 - 2));
/* General state base address: stateless DP read/write requests */
@@ -684,7 +748,9 @@ static void upload_state_base_address( struct brw_context *brw )
I915_GEM_DOMAIN_INSTRUCTION), 0, 1);
OUT_BATCH(1); /* Indirect object base address: MEDIA_OBJECT data */
- OUT_BATCH(1); /* Instruction base address: shader kernels (incl. SIP) */
+ OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
+ 1); /* Instruction base address: shader kernels (incl. SIP) */
+
OUT_BATCH(1); /* General state upper bound */
OUT_BATCH(1); /* Dynamic state upper bound */
OUT_BATCH(1); /* Indirect object upper bound */
@@ -697,7 +763,8 @@ static void upload_state_base_address( struct brw_context *brw )
OUT_RELOC(intel->batch.bo, I915_GEM_DOMAIN_SAMPLER, 0,
1); /* Surface state base address */
OUT_BATCH(1); /* Indirect object base address */
- OUT_BATCH(1); /* Instruction base address */
+ OUT_RELOC(brw->cache.bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
+ 1); /* Instruction base address */
OUT_BATCH(1); /* General state upper bound */
OUT_BATCH(1); /* Indirect object upper bound */
OUT_BATCH(1); /* Instruction access upper bound */
@@ -713,12 +780,37 @@ static void upload_state_base_address( struct brw_context *brw )
OUT_BATCH(1); /* Indirect object upper bound */
ADVANCE_BATCH();
}
+
+ /* According to section 3.6.1 of VOL1 of the 965 PRM,
+ * STATE_BASE_ADDRESS updates require a reissue of:
+ *
+ * 3DSTATE_PIPELINE_POINTERS
+ * 3DSTATE_BINDING_TABLE_POINTERS
+ * MEDIA_STATE_POINTERS
+ *
+ * and this continues through Ironlake. The Sandy Bridge PRM, vol
+ * 1 part 1 says that the folowing packets must be reissued:
+ *
+ * 3DSTATE_CC_POINTERS
+ * 3DSTATE_BINDING_TABLE_POINTERS
+ * 3DSTATE_SAMPLER_STATE_POINTERS
+ * 3DSTATE_VIEWPORT_STATE_POINTERS
+ * MEDIA_STATE_POINTERS
+ *
+ * Those are always reissued following SBA updates anyway (new
+ * batch time), except in the case of the program cache BO
+ * changing. Having a separate state flag makes the sequence more
+ * obvious.
+ */
+
+ brw->state.dirty.brw |= BRW_NEW_STATE_BASE_ADDRESS;
}
const struct brw_tracked_state brw_state_base_address = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE),
.cache = 0,
},
.emit = upload_state_base_address
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index c2227777cfb..fca30a74aaf 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -120,14 +120,11 @@ static void compile_sf_prog( struct brw_context *brw,
printf("\n");
}
- /* Upload
- */
- drm_intel_bo_unreference(brw->sf.prog_bo);
- brw->sf.prog_bo = brw_upload_cache(&brw->cache, BRW_SF_PROG,
- &c.key, sizeof(c.key),
- program, program_size,
- &c.prog_data, sizeof(c.prog_data),
- &brw->sf.prog_data);
+ brw_upload_cache(&brw->cache, BRW_SF_PROG,
+ &c.key, sizeof(c.key),
+ program, program_size,
+ &c.prog_data, sizeof(c.prog_data),
+ &brw->sf.prog_offset, &brw->sf.prog_data);
ralloc_free(mem_ctx);
}
@@ -191,12 +188,11 @@ static void upload_sf_prog(struct brw_context *brw)
key.frontface_ccw = (ctx->Polygon.FrontFace == GL_CCW) ^ (ctx->DrawBuffer->Name != 0);
}
- drm_intel_bo_unreference(brw->sf.prog_bo);
- brw->sf.prog_bo = brw_search_cache(&brw->cache, BRW_SF_PROG,
- &key, sizeof(key),
- &brw->sf.prog_data);
- if (brw->sf.prog_bo == NULL)
+ if (!brw_search_cache(&brw->cache, BRW_SF_PROG,
+ &key, sizeof(key),
+ &brw->sf.prog_offset, &brw->sf.prog_data)) {
compile_sf_prog( brw, &key );
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index 78b22c4df3d..eb3d103099b 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -133,9 +133,14 @@ static void upload_sf_unit( struct brw_context *brw )
memset(sf, 0, sizeof(*sf));
- /* CACHE_NEW_SF_PROG */
+ /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_SF_PROG */
sf->thread0.grf_reg_count = ALIGN(brw->sf.prog_data->total_grf, 16) / 16 - 1;
- sf->thread0.kernel_start_pointer = brw->sf.prog_bo->offset >> 6; /* reloc */
+ sf->thread0.kernel_start_pointer =
+ brw_program_reloc(brw,
+ brw->sf.state_offset +
+ offsetof(struct brw_sf_unit_state, thread0),
+ brw->sf.prog_offset +
+ (sf->thread0.grf_reg_count << 1)) >> 6;
sf->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
@@ -282,11 +287,6 @@ static void upload_sf_unit( struct brw_context *brw )
/* STATE_PREFETCH command description describes this state as being
* something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
*/
- /* Emit SF program relocation */
- drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
- offsetof(struct brw_sf_unit_state, thread0)),
- brw->sf.prog_bo, sf->thread0.grf_reg_count << 1,
- I915_GEM_DOMAIN_INSTRUCTION, 0);
/* Emit SF viewport relocation */
drm_intel_bo_emit_reloc(bo, (brw->sf.state_offset +
@@ -308,6 +308,7 @@ const struct brw_tracked_state brw_sf_unit = {
_NEW_SCISSOR |
_NEW_BUFFERS),
.brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE |
BRW_NEW_URB_FENCE),
.cache = (CACHE_NEW_SF_VP |
CACHE_NEW_SF_PROG)
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 544ef7d47e6..b384651d8d0 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -145,21 +145,21 @@ void brw_clear_validated_bos(struct brw_context *brw);
* brw_state_cache.c
*/
-drm_intel_bo *brw_upload_cache(struct brw_cache *cache,
- enum brw_cache_id cache_id,
- const void *key,
- GLuint key_sz,
- const void *data,
- GLuint data_sz,
- const void *aux,
- GLuint aux_sz,
- void *aux_return);
-
-drm_intel_bo *brw_search_cache( struct brw_cache *cache,
- enum brw_cache_id cache_id,
- const void *key,
- GLuint key_size,
- void *aux_return);
+void brw_upload_cache(struct brw_cache *cache,
+ enum brw_cache_id cache_id,
+ const void *key,
+ GLuint key_sz,
+ const void *data,
+ GLuint data_sz,
+ const void *aux,
+ GLuint aux_sz,
+ uint32_t *out_offset, void *out_aux);
+
+bool brw_search_cache(struct brw_cache *cache,
+ enum brw_cache_id cache_id,
+ const void *key,
+ GLuint key_size,
+ uint32_t *inout_offset, void *out_aux);
void brw_state_cache_check_size( struct brw_context *brw );
void brw_init_caches( struct brw_context *brw );
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index f13a41fa7cc..3988625ea91 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -45,6 +45,7 @@
*/
#include "main/imports.h"
+#include "intel_batchbuffer.h"
#include "brw_state.h"
#define FILE_DEBUG_FLAG DEBUG_STATE
@@ -67,23 +68,6 @@ hash_key(struct brw_cache_item *item)
return hash;
}
-
-/**
- * Marks a new buffer as being chosen for the given cache id.
- */
-static void
-update_cache_last(struct brw_cache *cache, enum brw_cache_id cache_id,
- drm_intel_bo *bo)
-{
- if (bo == cache->last_bo[cache_id])
- return; /* no change */
-
- drm_intel_bo_unreference(cache->last_bo[cache_id]);
- cache->last_bo[cache_id] = bo;
- drm_intel_bo_reference(cache->last_bo[cache_id]);
- cache->brw->state.dirty.cache |= 1 << cache_id;
-}
-
static int
brw_cache_item_equals(const struct brw_cache_item *a,
const struct brw_cache_item *b)
@@ -145,12 +129,13 @@ rehash(struct brw_cache *cache)
/**
* Returns the buffer object matching cache_id and key, or NULL.
*/
-drm_intel_bo *
+bool
brw_search_cache(struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *key, GLuint key_size,
- void *aux_return)
+ uint32_t *inout_offset, void *out_aux)
{
+ struct brw_context *brw = cache->brw;
struct brw_cache_item *item;
struct brw_cache_item lookup;
GLuint hash;
@@ -164,19 +149,116 @@ brw_search_cache(struct brw_cache *cache,
item = search_cache(cache, hash, &lookup);
if (item == NULL)
- return NULL;
+ return false;
- if (aux_return)
- *(void **)aux_return = (void *)((char *)item->key + item->key_size);
+ *(void **)out_aux = ((char *)item->key + item->key_size);
- update_cache_last(cache, cache_id, item->bo);
+ if (item->offset != *inout_offset) {
+ brw->state.dirty.cache |= (1 << cache_id);
+ *inout_offset = item->offset;
+ }
- drm_intel_bo_reference(item->bo);
- return item->bo;
+ return true;
}
+static void
+brw_cache_new_bo(struct brw_cache *cache, uint32_t new_size)
+{
+ struct brw_context *brw = cache->brw;
+ struct intel_context *intel = &brw->intel;
+ drm_intel_bo *new_bo;
+
+ new_bo = drm_intel_bo_alloc(intel->bufmgr, "program cache", new_size, 64);
+
+ /* Copy any existing data that needs to be saved. */
+ if (cache->next_offset != 0) {
+ drm_intel_bo_map(cache->bo, false);
+ drm_intel_bo_subdata(new_bo, 0, cache->next_offset, cache->bo->virtual);
+ drm_intel_bo_unmap(cache->bo);
+ }
+
+ drm_intel_bo_unreference(cache->bo);
+ cache->bo = new_bo;
+ cache->bo_used_by_gpu = false;
+
+ /* Since we have a new BO in place, we need to signal the units
+ * that depend on it (state base address on gen5+, or unit state before).
+ */
+ brw->state.dirty.brw |= BRW_NEW_PROGRAM_CACHE;
+}
+
+/**
+ * Attempts to find an item in the cache with identical data and aux
+ * data to use
+ */
+static bool
+brw_try_upload_using_copy(struct brw_cache *cache,
+ struct brw_cache_item *result_item,
+ const void *data,
+ const void *aux)
+{
+ int i;
+ struct brw_cache_item *item;
+
+ for (i = 0; i < cache->size; i++) {
+ for (item = cache->items[i]; item; item = item->next) {
+ const void *item_aux = item->key + item->key_size;
+ int ret;
+
+ if (item->cache_id != result_item->cache_id ||
+ item->size != result_item->size ||
+ item->aux_size != result_item->aux_size) {
+ continue;
+ }
+
+ if (memcmp(item_aux, aux, item->aux_size) != 0) {
+ continue;
+ }
+
+ drm_intel_bo_map(cache->bo, false);
+ ret = memcmp(cache->bo->virtual + item->offset, data, item->size);
+ drm_intel_bo_unmap(cache->bo);
+ if (ret)
+ continue;
+
+ result_item->offset = item->offset;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void
+brw_upload_item_data(struct brw_cache *cache,
+ struct brw_cache_item *item,
+ const void *data)
+{
+ /* Allocate space in the cache BO for our new program. */
+ if (cache->next_offset + item->size > cache->bo->size) {
+ uint32_t new_size = cache->bo->size * 2;
+
+ while (cache->next_offset + item->size > new_size)
+ new_size *= 2;
+
+ brw_cache_new_bo(cache, new_size);
+ }
+
+ /* If we would block on writing to an in-use program BO, just
+ * recreate it.
+ */
+ if (cache->bo_used_by_gpu) {
+ brw_cache_new_bo(cache, cache->bo->size);
+ }
+
+ item->offset = cache->next_offset;
+
+ /* Programs are always 64-byte aligned, so set up the next one now */
+ cache->next_offset = ALIGN(item->offset + item->size, 64);
+}
-drm_intel_bo *
+void
brw_upload_cache(struct brw_cache *cache,
enum brw_cache_id cache_id,
const void *key,
@@ -185,23 +267,31 @@ brw_upload_cache(struct brw_cache *cache,
GLuint data_size,
const void *aux,
GLuint aux_size,
- void *aux_return)
+ uint32_t *out_offset,
+ void *out_aux)
{
struct brw_cache_item *item = CALLOC_STRUCT(brw_cache_item);
GLuint hash;
void *tmp;
- drm_intel_bo *bo;
item->cache_id = cache_id;
+ item->size = data_size;
item->key = key;
item->key_size = key_size;
+ item->aux_size = aux_size;
hash = hash_key(item);
item->hash = hash;
- /* Create the buffer object to contain the data */
- bo = drm_intel_bo_alloc(cache->brw->intel.bufmgr,
- cache->name[cache_id], data_size, 1 << 6);
-
+ /* If we can find a matching prog/prog_data combo in the cache
+ * already, then reuse the existing stuff. This will mean not
+ * flagging CACHE_NEW_* when transitioning between the two
+ * equivalent hash keys. This is notably useful for programs
+ * generating shaders at runtime, where multiple shaders may
+ * compile to the thing in our backend.
+ */
+ if (!brw_try_upload_using_copy(cache, item, data, aux)) {
+ brw_upload_item_data(cache, item, data);
+ }
/* Set up the memory containing the key and aux_data */
tmp = malloc(key_size + aux_size);
@@ -211,9 +301,6 @@ brw_upload_cache(struct brw_cache *cache,
item->key = tmp;
- item->bo = bo;
- drm_intel_bo_reference(bo);
-
if (cache->n_items > cache->size * 1.5)
rehash(cache);
@@ -222,34 +309,18 @@ brw_upload_cache(struct brw_cache *cache,
cache->items[hash] = item;
cache->n_items++;
- if (aux_return) {
- *(void **)aux_return = (void *)((char *)item->key + item->key_size);
- }
-
- DBG("upload %s: %d bytes to cache id %d\n",
- cache->name[cache_id],
- data_size, cache_id);
-
/* Copy data to the buffer */
- drm_intel_bo_subdata(bo, 0, data_size, data);
-
- update_cache_last(cache, cache_id, bo);
+ drm_intel_bo_subdata(cache->bo, item->offset, data_size, data);
- return bo;
-}
-
-static void
-brw_init_cache_id(struct brw_cache *cache,
- const char *name,
- enum brw_cache_id id)
-{
- cache->name[id] = strdup(name);
+ *out_offset = item->offset;
+ *(void **)out_aux = (void *)((char *)item->key + item->key_size);
+ cache->brw->state.dirty.cache |= 1 << cache_id;
}
-
void
brw_init_caches(struct brw_context *brw)
{
+ struct intel_context *intel = &brw->intel;
struct brw_cache *cache = &brw->cache;
cache->brw = brw;
@@ -259,36 +330,15 @@ brw_init_caches(struct brw_context *brw)
cache->items = (struct brw_cache_item **)
calloc(1, cache->size * sizeof(struct brw_cache_item));
- brw_init_cache_id(cache, "CC_VP", BRW_CC_VP);
- brw_init_cache_id(cache, "CC_UNIT", BRW_CC_UNIT);
- brw_init_cache_id(cache, "WM_PROG", BRW_WM_PROG);
- brw_init_cache_id(cache, "SAMPLER", BRW_SAMPLER);
- brw_init_cache_id(cache, "WM_UNIT", BRW_WM_UNIT);
- brw_init_cache_id(cache, "SF_PROG", BRW_SF_PROG);
- brw_init_cache_id(cache, "SF_VP", BRW_SF_VP);
-
- brw_init_cache_id(cache, "SF_UNIT", BRW_SF_UNIT);
-
- brw_init_cache_id(cache, "VS_UNIT", BRW_VS_UNIT);
-
- brw_init_cache_id(cache, "VS_PROG", BRW_VS_PROG);
-
- brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT);
-
- brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG);
- brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP);
-
- brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
-
- brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
- brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
- brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE);
- brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
+ cache->bo = drm_intel_bo_alloc(intel->bufmgr,
+ "program cache",
+ 4096, 64);
}
static void
brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
{
+ struct intel_context *intel = &brw->intel;
struct brw_cache_item *c, *next;
GLuint i;
@@ -297,7 +347,6 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
for (i = 0; i < cache->size; i++) {
for (c = cache->items[i]; c; c = next) {
next = c->next;
- drm_intel_bo_unreference(c->bo);
free((void *)c->key);
free(c);
}
@@ -306,9 +355,18 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
cache->n_items = 0;
+ /* Start putting programs into the start of the BO again, since
+ * we'll never find the old results.
+ */
+ cache->next_offset = 0;
+
+ /* We need to make sure that the programs get regenerated, since
+ * any offsets leftover in brw_context will no longer be valid.
+ */
brw->state.dirty.mesa |= ~0;
brw->state.dirty.brw |= ~0;
brw->state.dirty.cache |= ~0;
+ intel_batchbuffer_flush(intel);
}
void
@@ -325,15 +383,10 @@ brw_state_cache_check_size(struct brw_context *brw)
static void
brw_destroy_cache(struct brw_context *brw, struct brw_cache *cache)
{
- GLuint i;
DBG("%s\n", __FUNCTION__);
brw_clear_cache(brw, cache);
- for (i = 0; i < BRW_MAX_CACHE; i++) {
- drm_intel_bo_unreference(cache->last_bo[i]);
- free(cache->name[i]);
- }
free(cache->items);
cache->items = NULL;
cache->size = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_state_dump.c b/src/mesa/drivers/dri/i965/brw_state_dump.c
index ff06cb3a91e..7a3a88f04f5 100644
--- a/src/mesa/drivers/dri/i965/brw_state_dump.c
+++ b/src/mesa/drivers/dri/i965/brw_state_dump.c
@@ -459,21 +459,19 @@ static void dump_blend_state(struct brw_context *brw)
}
-static void brw_debug_prog(const char *name, drm_intel_bo *prog)
+static void brw_debug_prog(struct brw_context *brw,
+ const char *name, uint32_t prog_offset)
{
unsigned int i;
uint32_t *data;
- if (prog == NULL)
- return;
-
- drm_intel_bo_map(prog, GL_FALSE);
+ drm_intel_bo_map(brw->cache.bo, false);
- data = prog->virtual;
+ data = brw->cache.bo->virtual + prog_offset;
- for (i = 0; i < prog->size / 4 / 4; i++) {
+ for (i = 0; i < brw->cache.bo->size / 4 / 4; i++) {
fprintf(stderr, "%8s: 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- name, (unsigned int)prog->offset + i * 4 * 4,
+ name, (unsigned int)brw->cache.bo->offset + i * 4 * 4,
data[i * 4], data[i * 4 + 1], data[i * 4 + 2], data[i * 4 + 3]);
/* Stop at the end of the program. It'd be nice to keep track of the actual
* intended program size instead of guessing like this.
@@ -485,7 +483,7 @@ static void brw_debug_prog(const char *name, drm_intel_bo *prog)
break;
}
- drm_intel_bo_unmap(prog);
+ drm_intel_bo_unmap(brw->cache.bo);
}
@@ -518,17 +516,19 @@ void brw_debug_batch(struct intel_context *intel)
if (intel->gen < 6)
state_struct_out("VS", intel->batch.bo, brw->vs.state_offset,
sizeof(struct brw_vs_unit_state));
- brw_debug_prog("VS prog", brw->vs.prog_bo);
+ brw_debug_prog(brw, "VS prog", brw->vs.prog_offset);
if (intel->gen < 6)
state_struct_out("GS", intel->batch.bo, brw->gs.state_offset,
sizeof(struct brw_gs_unit_state));
- brw_debug_prog("GS prog", brw->gs.prog_bo);
+ if (brw->gs.prog_active) {
+ brw_debug_prog(brw, "GS prog", brw->gs.prog_offset);
+ }
if (intel->gen < 6) {
state_struct_out("SF", intel->batch.bo, brw->sf.state_offset,
sizeof(struct brw_sf_unit_state));
- brw_debug_prog("SF prog", brw->sf.prog_bo);
+ brw_debug_prog(brw, "SF prog", brw->sf.prog_offset);
}
if (intel->gen >= 7)
dump_sf_clip_viewport_state(brw);
@@ -540,7 +540,7 @@ void brw_debug_batch(struct intel_context *intel)
if (intel->gen < 6)
state_struct_out("WM", intel->batch.bo, brw->wm.state_offset,
sizeof(struct brw_wm_unit_state));
- brw_debug_prog("WM prog", brw->wm.prog_bo);
+ brw_debug_prog(brw, "WM prog", brw->wm.prog_offset);
if (intel->gen >= 6) {
dump_cc_viewport_state(brw);
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 6a4c112dcf5..76ffa0daefe 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -47,11 +47,11 @@ static const struct brw_tracked_state *gen4_atoms[] =
&brw_check_fallback,
&brw_wm_input_sizes,
- &brw_vs_prog,
- &brw_gs_prog,
- &brw_clip_prog,
- &brw_sf_prog,
- &brw_wm_prog,
+ &brw_vs_prog, /* must do before GS prog, state base address. */
+ &brw_gs_prog, /* must do before state base address */
+ &brw_clip_prog, /* must do before state base address */
+ &brw_sf_prog, /* must do before state base address */
+ &brw_wm_prog, /* must do before state base address */
/* Once all the programs are done, we know how large urb entry
* sizes need to be and can decide if we need to change the urb
@@ -110,9 +110,9 @@ static const struct brw_tracked_state *gen6_atoms[] =
&brw_check_fallback,
&brw_wm_input_sizes,
- &brw_vs_prog,
- &brw_gs_prog,
- &brw_wm_prog,
+ &brw_vs_prog, /* must do before state base address */
+ &brw_gs_prog, /* must do before state base address */
+ &brw_wm_prog, /* must do before state base address */
&gen6_clip_vp,
&gen6_sf_vp,
@@ -365,6 +365,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_PRIMITIVE),
DEFINE_BIT(BRW_NEW_CONTEXT),
DEFINE_BIT(BRW_NEW_WM_INPUT_DIMENSIONS),
+ DEFINE_BIT(BRW_NEW_PROGRAM_CACHE),
DEFINE_BIT(BRW_NEW_PSP),
DEFINE_BIT(BRW_NEW_WM_SURFACES),
DEFINE_BIT(BRW_NEW_INDICES),
@@ -378,6 +379,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_VS_BINDING_TABLE),
DEFINE_BIT(BRW_NEW_GS_BINDING_TABLE),
DEFINE_BIT(BRW_NEW_PS_BINDING_TABLE),
+ DEFINE_BIT(BRW_NEW_STATE_BASE_ADDRESS),
{0, 0, 0}
};
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 80d5e78ed0b..a9ad5311fe3 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -105,12 +105,11 @@ static void do_vs_prog( struct brw_context *brw,
/* constant_map */
aux_size += c.vp->program.Base.Parameters->NumParameters;
- drm_intel_bo_unreference(brw->vs.prog_bo);
- brw->vs.prog_bo = brw_upload_cache(&brw->cache, BRW_VS_PROG,
- &c.key, sizeof(c.key),
- program, program_size,
- &c.prog_data, aux_size,
- &brw->vs.prog_data);
+ brw_upload_cache(&brw->cache, BRW_VS_PROG,
+ &c.key, sizeof(c.key),
+ program, program_size,
+ &c.prog_data, aux_size,
+ &brw->vs.prog_offset, &brw->vs.prog_data);
ralloc_free(mem_ctx);
}
@@ -153,14 +152,11 @@ static void brw_upload_vs_prog(struct brw_context *brw)
}
}
- /* Make an early check for the key.
- */
- drm_intel_bo_unreference(brw->vs.prog_bo);
- brw->vs.prog_bo = brw_search_cache(&brw->cache, BRW_VS_PROG,
- &key, sizeof(key),
- &brw->vs.prog_data);
- if (brw->vs.prog_bo == NULL)
+ if (!brw_search_cache(&brw->cache, BRW_VS_PROG,
+ &key, sizeof(key),
+ &brw->vs.prog_offset, &brw->vs.prog_data)) {
do_vs_prog(brw, vp, &key);
+ }
brw->vs.constant_map = ((int8_t *)brw->vs.prog_data +
sizeof(*brw->vs.prog_data));
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index b6c9e5a1ceb..9d733344a26 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1635,7 +1635,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
else
m = brw_message_reg(4);
- brw_DP4(p, brw_writemask(m, (1 << (i & 7))),pos, c->userplane[i]);
+ brw_DP4(p, brw_writemask(m, (1 << (i & 3))),pos, c->userplane[i]);
}
}
} else if ((c->prog_data.outputs_written &
diff --git a/src/mesa/drivers/dri/i965/brw_vs_state.c b/src/mesa/drivers/dri/i965/brw_vs_state.c
index 1eee5b7e5de..d5010a21e80 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_state.c
@@ -36,18 +36,6 @@
#include "brw_defines.h"
#include "main/macros.h"
-struct brw_vs_unit_key {
- unsigned int total_grf;
- unsigned int urb_entry_read_length;
- unsigned int curb_entry_read_length;
-
- unsigned int curbe_offset;
-
- unsigned int nr_urb_entries, urb_size;
-
- unsigned int nr_surfaces;
-};
-
static void
brw_prepare_vs_unit(struct brw_context *brw)
{
@@ -58,8 +46,14 @@ brw_prepare_vs_unit(struct brw_context *brw)
vs = brw_state_batch(brw, sizeof(*vs), 32, &brw->vs.state_offset);
memset(vs, 0, sizeof(*vs));
- /* CACHE_NEW_VS_PROG */
- vs->thread0.kernel_start_pointer = brw->vs.prog_bo->offset >> 6; /* reloc */
+ /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_VS_PROG */
+ vs->thread0.kernel_start_pointer =
+ brw_program_reloc(brw,
+ brw->vs.state_offset +
+ offsetof(struct brw_vs_unit_state, thread0),
+ brw->vs.prog_offset +
+ (vs->thread0.grf_reg_count << 1)) >> 6;
+
vs->thread0.grf_reg_count = ALIGN(brw->vs.prog_data->total_grf, 16) / 16 - 1;
vs->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
/* Choosing multiple program flow means that we may get 2-vertex threads,
@@ -152,13 +146,6 @@ brw_prepare_vs_unit(struct brw_context *brw)
*/
vs->vs6.vs_enable = 1;
- /* Emit VS program relocation */
- drm_intel_bo_emit_reloc(intel->batch.bo, (brw->vs.state_offset +
- offsetof(struct brw_vs_unit_state,
- thread0)),
- brw->vs.prog_bo, vs->thread0.grf_reg_count << 1,
- I915_GEM_DOMAIN_INSTRUCTION, 0);
-
brw->state.dirty.cache |= CACHE_NEW_VS_UNIT;
}
@@ -166,6 +153,7 @@ const struct brw_tracked_state brw_vs_unit = {
.dirty = {
.mesa = _NEW_TRANSFORM,
.brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_NR_VS_SURFACES |
BRW_NEW_URB_FENCE),
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index 69650e1df77..8612e743265 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -69,14 +69,8 @@ static void brw_destroy_context( struct intel_context *intel )
ralloc_free(brw->wm.compile_data);
dri_bo_release(&brw->curbe.curbe_bo);
- dri_bo_release(&brw->vs.prog_bo);
dri_bo_release(&brw->vs.const_bo);
- dri_bo_release(&brw->gs.prog_bo);
- dri_bo_release(&brw->clip.prog_bo);
- dri_bo_release(&brw->sf.prog_bo);
- dri_bo_release(&brw->wm.prog_bo);
dri_bo_release(&brw->wm.const_bo);
- dri_bo_release(&brw->cc.prog_bo);
free(brw->curbe.last_buf);
free(brw->curbe.next_buf);
@@ -122,13 +116,20 @@ static void brw_new_batch( struct intel_context *intel )
* This is probably not as severe as on 915, since almost all of our state
* is just in referenced buffers.
*/
- brw->state.dirty.brw |= BRW_NEW_CONTEXT;
+ brw->state.dirty.brw |= BRW_NEW_CONTEXT | BRW_NEW_BATCH;
- brw->state.dirty.mesa |= ~0;
- brw->state.dirty.brw |= ~0;
- brw->state.dirty.cache |= ~0;
+ /* Assume that the last command before the start of our batch was a
+ * primitive, for safety.
+ */
+ intel->batch.need_workaround_flush = true;
brw->vb.nr_current_buffers = 0;
+
+ /* Mark that the current program cache BO has been used by the GPU.
+ * It will be reallocated if we need to put new programs in for the
+ * next batch.
+ */
+ brw->cache.bo_used_by_gpu = true;
}
static void brw_invalidate_state( struct intel_context *intel, GLuint new_state )
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 1aebd12df49..b0dfdd536aa 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -273,12 +273,11 @@ bool do_wm_prog(struct brw_context *brw,
*/
program = brw_get_program(&c->func, &program_size);
- drm_intel_bo_unreference(brw->wm.prog_bo);
- brw->wm.prog_bo = brw_upload_cache(&brw->cache, BRW_WM_PROG,
- &c->key, sizeof(c->key),
- program, program_size,
- &c->prog_data, sizeof(c->prog_data),
- &brw->wm.prog_data);
+ brw_upload_cache(&brw->cache, BRW_WM_PROG,
+ &c->key, sizeof(c->key),
+ program, program_size,
+ &c->prog_data, sizeof(c->prog_data),
+ &brw->wm.prog_offset, &brw->wm.prog_data);
return true;
}
@@ -389,6 +388,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
* all 4 channels.
*/
if (sampler->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ key->compare_funcs[i] = sampler->CompareFunc;
+
if (sampler->DepthMode == GL_ALPHA) {
swizzles[0] = SWIZZLE_ZERO;
swizzles[1] = SWIZZLE_ZERO;
@@ -477,13 +478,9 @@ static void brw_prepare_wm_prog(struct brw_context *brw)
brw_wm_populate_key(brw, &key);
- /* Make an early check for the key.
- */
- drm_intel_bo_unreference(brw->wm.prog_bo);
- brw->wm.prog_bo = brw_search_cache(&brw->cache, BRW_WM_PROG,
- &key, sizeof(key),
- &brw->wm.prog_data);
- if (brw->wm.prog_bo == NULL) {
+ if (!brw_search_cache(&brw->cache, BRW_WM_PROG,
+ &key, sizeof(key),
+ &brw->wm.prog_offset, &brw->wm.prog_data)) {
bool success = do_wm_prog(brw, ctx->Shader.CurrentFragmentProgram, fp,
&key);
assert(success);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index e244b55a083..29082c19088 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -68,6 +68,18 @@ struct brw_wm_prog_key {
GLuint clamp_fragment_color:1;
GLuint line_aa:2;
+ /**
+ * Per-sampler comparison functions:
+ *
+ * If comparison mode is GL_COMPARE_R_TO_TEXTURE, then this is set to one
+ * of GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL,
+ * GL_GEQUAL, or GL_ALWAYS. Otherwise (comparison mode is GL_NONE), this
+ * field is irrelevant so it's left as GL_NONE (0).
+ *
+ * While this is a GLenum, all possible values fit in 16-bits.
+ */
+ uint16_t compare_funcs[BRW_MAX_TEX_UNIT];
+
GLbitfield proj_attrib_mask; /**< one bit per fragment program attribute */
GLuint yuvtex_mask:16;
GLuint yuvtex_swap_mask:16; /* UV swaped */
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index ef98f8126dc..506e2bdff5b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -90,13 +90,25 @@ brw_prepare_wm_unit(struct brw_context *brw)
brw->wm.prog_data->first_curbe_grf_16);
}
- /* CACHE_NEW_WM_PROG */
+ /* BRW_NEW_PROGRAM_CACHE | CACHE_NEW_WM_PROG */
wm->thread0.grf_reg_count = brw->wm.prog_data->reg_blocks;
wm->wm9.grf_reg_count_2 = brw->wm.prog_data->reg_blocks_16;
- wm->thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
- /* reloc */
- wm->wm9.kernel_start_pointer_2 = (brw->wm.prog_bo->offset +
- brw->wm.prog_data->prog_offset_16) >> 6;
+
+ wm->thread0.kernel_start_pointer =
+ brw_program_reloc(brw,
+ brw->wm.state_offset +
+ offsetof(struct brw_wm_unit_state, thread0),
+ brw->wm.prog_offset +
+ (wm->thread0.grf_reg_count << 1)) >> 6;
+
+ wm->wm9.kernel_start_pointer_2 =
+ brw_program_reloc(brw,
+ brw->wm.state_offset +
+ offsetof(struct brw_wm_unit_state, wm9),
+ brw->wm.prog_offset +
+ brw->wm.prog_data->prog_offset_16 +
+ (wm->wm9.grf_reg_count_2 << 1)) >> 6;
+
wm->thread1.depth_coef_urb_read_offset = 1;
wm->thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
@@ -214,23 +226,6 @@ brw_prepare_wm_unit(struct brw_context *brw)
if (unlikely(INTEL_DEBUG & DEBUG_STATS) || intel->stats_wm)
wm->wm4.stats_enable = 1;
- /* Emit WM program relocation */
- drm_intel_bo_emit_reloc(intel->batch.bo,
- brw->wm.state_offset +
- offsetof(struct brw_wm_unit_state, thread0),
- brw->wm.prog_bo, wm->thread0.grf_reg_count << 1,
- I915_GEM_DOMAIN_INSTRUCTION, 0);
-
- if (brw->wm.prog_data->prog_offset_16) {
- drm_intel_bo_emit_reloc(intel->batch.bo,
- brw->wm.state_offset +
- offsetof(struct brw_wm_unit_state, wm9),
- brw->wm.prog_bo,
- ((wm->wm9.grf_reg_count_2 << 1) +
- brw->wm.prog_data->prog_offset_16),
- I915_GEM_DOMAIN_INSTRUCTION, 0);
- }
-
/* Emit scratch space relocation */
if (brw->wm.prog_data->total_scratch != 0) {
drm_intel_bo_emit_reloc(intel->batch.bo,
@@ -265,6 +260,7 @@ const struct brw_tracked_state brw_wm_unit = {
_NEW_BUFFERS),
.brw = (BRW_NEW_BATCH |
+ BRW_NEW_PROGRAM_CACHE |
BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_CURBE_OFFSETS |
BRW_NEW_NR_WM_SURFACES),
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index ac8005dc6c2..89fea9cc952 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -73,7 +73,7 @@ translate_tex_target(GLenum target)
uint32_t
brw_format_for_mesa_format(gl_format mesa_format)
{
- uint32_t table[MESA_FORMAT_COUNT] =
+ static const uint32_t table[MESA_FORMAT_COUNT] =
{
[MESA_FORMAT_L8] = BRW_SURFACEFORMAT_L8_UNORM,
[MESA_FORMAT_I8] = BRW_SURFACEFORMAT_I8_UNORM,
diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c
index 2b16d6cdc01..294d5a5e644 100644
--- a/src/mesa/drivers/dri/i965/gen6_cc.c
+++ b/src/mesa/drivers/dri/i965/gen6_cc.c
@@ -183,7 +183,8 @@ static void upload_cc_state_pointers(struct brw_context *brw)
const struct brw_tracked_state gen6_cc_state_pointers = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS),
.cache = (CACHE_NEW_BLEND_STATE |
CACHE_NEW_COLOR_CALC_STATE |
CACHE_NEW_DEPTH_STENCIL_STATE)
diff --git a/src/mesa/drivers/dri/i965/gen6_gs_state.c b/src/mesa/drivers/dri/i965/gen6_gs_state.c
index c1d0a739394..d29f0290727 100644
--- a/src/mesa/drivers/dri/i965/gen6_gs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_gs_state.c
@@ -45,7 +45,7 @@ upload_gs_state(struct brw_context *brw)
ADVANCE_BATCH();
// GS should never be used on Gen6. Disable it.
- assert(brw->gs.prog_bo == NULL);
+ assert(!brw->gs.prog_active);
BEGIN_BATCH(7);
OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2));
OUT_BATCH(0); /* prog_bo */
@@ -65,8 +65,7 @@ upload_gs_state(struct brw_context *brw)
const struct brw_tracked_state gen6_gs_state = {
.dirty = {
.mesa = _NEW_TRANSFORM,
- .brw = (BRW_NEW_CURBE_OFFSETS |
- BRW_NEW_URB_FENCE |
+ .brw = (BRW_NEW_URB_FENCE |
BRW_NEW_CONTEXT),
.cache = CACHE_NEW_GS_PROG
},
diff --git a/src/mesa/drivers/dri/i965/gen6_sampler_state.c b/src/mesa/drivers/dri/i965/gen6_sampler_state.c
index 4cdec699df6..89326872faa 100644
--- a/src/mesa/drivers/dri/i965/gen6_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_sampler_state.c
@@ -50,7 +50,8 @@ upload_sampler_state_pointers(struct brw_context *brw)
const struct brw_tracked_state gen6_sampler_state = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS),
.cache = CACHE_NEW_SAMPLER
},
.emit = upload_sampler_state_pointers,
diff --git a/src/mesa/drivers/dri/i965/gen6_scissor_state.c b/src/mesa/drivers/dri/i965/gen6_scissor_state.c
index fad3ca0dd04..7492e508864 100644
--- a/src/mesa/drivers/dri/i965/gen6_scissor_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_scissor_state.c
@@ -31,7 +31,7 @@
#include "intel_batchbuffer.h"
static void
-gen6_prepare_scissor_state(struct brw_context *brw)
+gen6_upload_scissor_state(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
struct gl_context *ctx = &intel->ctx;
@@ -89,5 +89,5 @@ const struct brw_tracked_state gen6_scissor_state = {
.brw = BRW_NEW_BATCH,
.cache = 0,
},
- .prepare = gen6_prepare_scissor_state,
+ .emit = gen6_upload_scissor_state,
};
diff --git a/src/mesa/drivers/dri/i965/gen6_urb.c b/src/mesa/drivers/dri/i965/gen6_urb.c
index 62645a6a30f..b4105111c8c 100644
--- a/src/mesa/drivers/dri/i965/gen6_urb.c
+++ b/src/mesa/drivers/dri/i965/gen6_urb.c
@@ -64,7 +64,7 @@ upload_urb(struct brw_context *brw)
assert(brw->urb.nr_vs_entries % 4 == 0);
assert(brw->urb.nr_gs_entries % 4 == 0);
/* GS requirement */
- assert(!brw->gs.prog_bo || brw->urb.vs_size < 5);
+ assert(!brw->gs.prog_active || brw->urb.vs_size < 5);
BEGIN_BATCH(3);
OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
diff --git a/src/mesa/drivers/dri/i965/gen6_viewport_state.c b/src/mesa/drivers/dri/i965/gen6_viewport_state.c
index 4116bdb96de..c6c55c926c7 100644
--- a/src/mesa/drivers/dri/i965/gen6_viewport_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_viewport_state.c
@@ -122,7 +122,8 @@ static void upload_viewport_state_pointers(struct brw_context *brw)
const struct brw_tracked_state gen6_viewport_state = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH,
+ .brw = (BRW_NEW_BATCH |
+ BRW_NEW_STATE_BASE_ADDRESS),
.cache = (CACHE_NEW_CLIP_VP |
CACHE_NEW_SF_VP |
CACHE_NEW_CC_VP)
diff --git a/src/mesa/drivers/dri/i965/gen6_vs_state.c b/src/mesa/drivers/dri/i965/gen6_vs_state.c
index b46368e36e2..022e23e12b0 100644
--- a/src/mesa/drivers/dri/i965/gen6_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_vs_state.c
@@ -110,7 +110,7 @@ const struct brw_tracked_state gen6_vs_constants = {
.mesa = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS,
.brw = (BRW_NEW_BATCH |
BRW_NEW_VERTEX_PROGRAM),
- .cache = 0,
+ .cache = CACHE_NEW_VS_PROG,
},
.prepare = gen6_prepare_vs_push_constants,
};
@@ -147,7 +147,7 @@ upload_vs_state(struct brw_context *brw)
BEGIN_BATCH(6);
OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2));
- OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+ OUT_BATCH(brw->vs.prog_offset);
OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) |
GEN6_VS_FLOATING_POINT_MODE_ALT |
(brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
@@ -165,8 +165,7 @@ upload_vs_state(struct brw_context *brw)
const struct brw_tracked_state gen6_vs_state = {
.dirty = {
.mesa = _NEW_TRANSFORM | _NEW_PROGRAM_CONSTANTS,
- .brw = (BRW_NEW_CURBE_OFFSETS |
- BRW_NEW_NR_VS_SURFACES |
+ .brw = (BRW_NEW_NR_VS_SURFACES |
BRW_NEW_URB_FENCE |
BRW_NEW_CONTEXT |
BRW_NEW_VERTEX_PROGRAM |
diff --git a/src/mesa/drivers/dri/i965/gen6_wm_state.c b/src/mesa/drivers/dri/i965/gen6_wm_state.c
index 43e651db3ef..9ef6133e2b9 100644
--- a/src/mesa/drivers/dri/i965/gen6_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_wm_state.c
@@ -39,6 +39,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
struct gl_context *ctx = &intel->ctx;
+ /* BRW_NEW_FRAGMENT_PROGRAM */
const struct brw_fragment_program *fp =
brw_fragment_program_const(brw->fragment_program);
@@ -48,6 +49,7 @@ gen6_prepare_wm_push_constants(struct brw_context *brw)
/* XXX: Should this happen somewhere before to get our state flag set? */
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
+ /* CACHE_NEW_VS_PROG */
if (brw->wm.prog_data->nr_params != 0) {
float *constants;
unsigned int i;
@@ -83,7 +85,7 @@ const struct brw_tracked_state gen6_wm_constants = {
.mesa = _NEW_PROGRAM_CONSTANTS,
.brw = (BRW_NEW_BATCH |
BRW_NEW_FRAGMENT_PROGRAM),
- .cache = 0,
+ .cache = CACHE_NEW_VS_PROG,
},
.prepare = gen6_prepare_wm_push_constants,
};
@@ -97,7 +99,7 @@ upload_wm_state(struct brw_context *brw)
brw_fragment_program_const(brw->fragment_program);
uint32_t dw2, dw4, dw5, dw6;
- /* CACHE_NEW_WM_PROG */
+ /* CACHE_NEW_WM_PROG */
if (brw->wm.prog_data->nr_params == 0) {
/* Disable the push constant buffers. */
BEGIN_BATCH(5);
@@ -157,7 +159,7 @@ upload_wm_state(struct brw_context *brw)
if (ctx->Line.StippleFlag)
dw5 |= GEN6_WM_LINE_STIPPLE_ENABLE;
- /* _NEW_POLYGONSTIPPLE */
+ /* _NEW_POLYGON */
if (ctx->Polygon.StippleFlag)
dw5 |= GEN6_WM_POLYGON_STIPPLE_ENABLE;
@@ -183,7 +185,7 @@ upload_wm_state(struct brw_context *brw)
BEGIN_BATCH(9);
OUT_BATCH(_3DSTATE_WM << 16 | (9 - 2));
- OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+ OUT_BATCH(brw->wm.prog_offset);
OUT_BATCH(dw2);
if (brw->wm.prog_data->total_scratch) {
OUT_RELOC(brw->wm.scratch_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
@@ -195,21 +197,19 @@ upload_wm_state(struct brw_context *brw)
OUT_BATCH(dw5);
OUT_BATCH(dw6);
OUT_BATCH(0); /* kernel 1 pointer */
- if (brw->wm.prog_data->prog_offset_16) {
- OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
- brw->wm.prog_data->prog_offset_16);
- } else {
- OUT_BATCH(0); /* kernel 2 pointer */
- }
+ /* kernel 2 pointer */
+ OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16);
ADVANCE_BATCH();
}
const struct brw_tracked_state gen6_wm_state = {
.dirty = {
- .mesa = (_NEW_LINE | _NEW_POLYGONSTIPPLE | _NEW_COLOR | _NEW_BUFFERS |
- _NEW_PROGRAM_CONSTANTS | _NEW_POLYGON),
- .brw = (BRW_NEW_CURBE_OFFSETS |
- BRW_NEW_FRAGMENT_PROGRAM |
+ .mesa = (_NEW_LINE |
+ _NEW_COLOR |
+ _NEW_BUFFERS |
+ _NEW_PROGRAM_CONSTANTS |
+ _NEW_POLYGON),
+ .brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_NR_WM_SURFACES |
BRW_NEW_URB_FENCE |
BRW_NEW_BATCH),
diff --git a/src/mesa/drivers/dri/i965/gen7_disable.c b/src/mesa/drivers/dri/i965/gen7_disable.c
index 4e9461739d0..a44d31596b9 100644
--- a/src/mesa/drivers/dri/i965/gen7_disable.c
+++ b/src/mesa/drivers/dri/i965/gen7_disable.c
@@ -31,7 +31,7 @@ disable_stages(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
- assert(brw->gs.prog_bo == NULL);
+ assert(!brw->gs.prog_active);
/* Disable the Geometry Shader (GS) Unit */
BEGIN_BATCH(7);
diff --git a/src/mesa/drivers/dri/i965/gen7_urb.c b/src/mesa/drivers/dri/i965/gen7_urb.c
index 3a614693dfc..2b650e9bc45 100644
--- a/src/mesa/drivers/dri/i965/gen7_urb.c
+++ b/src/mesa/drivers/dri/i965/gen7_urb.c
@@ -78,7 +78,7 @@ upload_urb(struct brw_context *brw)
assert(brw->urb.nr_vs_entries % 8 == 0);
assert(brw->urb.nr_gs_entries % 8 == 0);
/* GS requirement */
- assert(!brw->gs.prog_bo);
+ assert(!brw->gs.prog_active);
BEGIN_BATCH(2);
OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2));
diff --git a/src/mesa/drivers/dri/i965/gen7_vs_state.c b/src/mesa/drivers/dri/i965/gen7_vs_state.c
index ae7a1d6c35c..0fad3d2fb68 100644
--- a/src/mesa/drivers/dri/i965/gen7_vs_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_vs_state.c
@@ -67,7 +67,7 @@ upload_vs_state(struct brw_context *brw)
BEGIN_BATCH(6);
OUT_BATCH(_3DSTATE_VS << 16 | (6 - 2));
- OUT_RELOC(brw->vs.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+ OUT_BATCH(brw->vs.prog_offset);
OUT_BATCH((0 << GEN6_VS_SAMPLER_COUNT_SHIFT) |
GEN6_VS_FLOATING_POINT_MODE_ALT |
(brw->vs.nr_surfaces << GEN6_VS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_state.c b/src/mesa/drivers/dri/i965/gen7_wm_state.c
index 6a64eb8a2d3..17f75354f1d 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_state.c
@@ -36,6 +36,7 @@ gen7_prepare_wm_constants(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
struct gl_context *ctx = &intel->ctx;
+ /* BRW_NEW_FRAGMENT_PROGRAM */
const struct brw_fragment_program *fp =
brw_fragment_program_const(brw->fragment_program);
@@ -45,7 +46,7 @@ gen7_prepare_wm_constants(struct brw_context *brw)
/* XXX: Should this happen somewhere before to get our state flag set? */
_mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
- /* BRW_NEW_FRAGMENT_PROGRAM */
+ /* CACHE_NEW_WM_PROG */
if (brw->wm.prog_data->nr_params != 0) {
float *constants;
unsigned int i;
@@ -80,7 +81,7 @@ const struct brw_tracked_state gen7_wm_constants = {
.dirty = {
.mesa = _NEW_PROGRAM_CONSTANTS,
.brw = (BRW_NEW_BATCH | BRW_NEW_FRAGMENT_PROGRAM),
- .cache = 0,
+ .cache = CACHE_NEW_WM_PROG,
},
.prepare = gen7_prepare_wm_constants,
};
@@ -104,7 +105,7 @@ upload_wm_state(struct brw_context *brw)
if (ctx->Line.StippleFlag)
dw1 |= GEN7_WM_LINE_STIPPLE_ENABLE;
- /* _NEW_POLYGONSTIPPLE */
+ /* _NEW_POLYGON */
if (ctx->Polygon.StippleFlag)
dw1 |= GEN7_WM_POLYGON_STIPPLE_ENABLE;
@@ -227,24 +228,21 @@ upload_ps_state(struct brw_context *brw)
BEGIN_BATCH(8);
OUT_BATCH(_3DSTATE_PS << 16 | (8 - 2));
- OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
+ OUT_BATCH(brw->wm.prog_offset);
OUT_BATCH(dw2);
OUT_BATCH(0); /* scratch space base offset */
OUT_BATCH(dw4);
OUT_BATCH(dw5);
OUT_BATCH(0); /* kernel 1 pointer */
- if (brw->wm.prog_data->prog_offset_16) {
- OUT_RELOC(brw->wm.prog_bo, I915_GEM_DOMAIN_INSTRUCTION, 0,
- brw->wm.prog_data->prog_offset_16);
- } else {
- OUT_BATCH(0); /* kernel 2 pointer */
- }
+ OUT_BATCH(brw->wm.prog_offset + brw->wm.prog_data->prog_offset_16);
ADVANCE_BATCH();
}
const struct brw_tracked_state gen7_ps_state = {
.dirty = {
- .mesa = (_NEW_LINE | _NEW_POLYGON | _NEW_POLYGONSTIPPLE |
+ .mesa = (_NEW_LINE |
+ _NEW_POLYGON |
+ _NEW_POLYGONSTIPPLE |
_NEW_PROGRAM_CONSTANTS),
.brw = (BRW_NEW_CURBE_OFFSETS |
BRW_NEW_FRAGMENT_PROGRAM |
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 77edc3a6bfe..735382902d1 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -53,6 +53,22 @@ static void clear_cache( struct intel_context *intel )
}
void
+intel_batchbuffer_init(struct intel_context *intel)
+{
+ intel_batchbuffer_reset(intel);
+
+ if (intel->gen == 6) {
+ /* We can't just use brw_state_batch to get a chunk of space for
+ * the gen6 workaround because it involves actually writing to
+ * the buffer, and the kernel doesn't let us write to the batch.
+ */
+ intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr,
+ "gen6 workaround",
+ 4096, 4096);
+ }
+}
+
+void
intel_batchbuffer_reset(struct intel_context *intel)
{
if (intel->batch.last_bo != NULL) {
@@ -76,6 +92,7 @@ intel_batchbuffer_free(struct intel_context *intel)
{
drm_intel_bo_unreference(intel->batch.last_bo);
drm_intel_bo_unreference(intel->batch.bo);
+ drm_intel_bo_unreference(intel->batch.workaround_bo);
clear_cache(intel);
}
@@ -276,6 +293,43 @@ emit:
item->header = intel->batch.emit;
}
+/**
+ * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
+ * implementing two workarounds on gen6. From section 1.4.7.1
+ * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
+ *
+ * [DevSNB-C+{W/A}] Before any depth stall flush (including those
+ * produced by non-pipelined state commands), software needs to first
+ * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
+ * 0.
+ *
+ * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
+ * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
+ *
+ * XXX: There is also a workaround that would appear to apply to this
+ * workaround, but it doesn't appear to be necessary so far:
+ *
+ * Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
+ * BEFORE the pipe-control with a post-sync op and no write-cache
+ * flushes.
+ */
+void
+intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
+{
+ if (!intel->batch.need_workaround_flush)
+ return;
+
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+ OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+ OUT_RELOC(intel->batch.workaround_bo,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+
+ intel->batch.need_workaround_flush = false;
+}
+
/* Emit a pipelined flush to either flush render and texture cache for
* reading from a FBO-drawn texture, or flush so that frontbuffer
* render appears on the screen in DRI1.
@@ -294,15 +348,17 @@ intel_batchbuffer_emit_mi_flush(struct intel_context *intel)
OUT_BATCH(0);
ADVANCE_BATCH();
} else {
- BEGIN_BATCH(8);
- /* XXX workaround: issue any post sync != 0 before write
- * cache flush = 1
- */
- OUT_BATCH(_3DSTATE_PIPE_CONTROL);
- OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
- OUT_BATCH(0); /* write address */
- OUT_BATCH(0); /* write data */
+ if (intel->gen == 6) {
+ /* Hardware workaround: SNB B-Spec says:
+ *
+ * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
+ * Flush Enable =1, a PIPE_CONTROL with any non-zero
+ * post-sync-op is required.
+ */
+ intel_emit_post_sync_nonzero_flush(intel);
+ }
+ BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_PIPE_CONTROL);
OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
PIPE_CONTROL_WRITE_FLUSH |
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.h b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
index a0a5c9841c6..fb4134d889e 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.h
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.h
@@ -9,6 +9,7 @@
#define BATCH_RESERVED 16
+void intel_batchbuffer_init(struct intel_context *intel);
void intel_batchbuffer_reset(struct intel_context *intel);
void intel_batchbuffer_free(struct intel_context *intel);
@@ -38,6 +39,7 @@ GLboolean intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
uint32_t write_domain,
uint32_t offset);
void intel_batchbuffer_emit_mi_flush(struct intel_context *intel);
+void intel_emit_post_sync_nonzero_flush(struct intel_context *intel);
static INLINE uint32_t float_as_int(float f)
{
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
index 7eb50edc6b4..a52a07cd93a 100644
--- a/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -28,7 +28,9 @@
#include "intel_context.h"
#include "intel_buffers.h"
#include "intel_fbo.h"
+
#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
/**
* Return pointer to current color drawing region, or NULL.
@@ -100,6 +102,28 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
return;
}
+ /*
+ * If intel_context is using separate stencil, but the depth attachment
+ * (gl_framebuffer.Attachment[BUFFER_DEPTH]) has a packed depth/stencil
+ * format, then we must install the real depth buffer at fb->_DepthBuffer
+ * and set fb->_DepthBuffer->Wrapped before calling _mesa_update_framebuffer.
+ * Otherwise, _mesa_update_framebuffer will create and install a swras
+ * depth wrapper instead.
+ *
+ * Ditto for stencil.
+ */
+ irbDepth = intel_get_renderbuffer(fb, BUFFER_DEPTH);
+ if (irbDepth && irbDepth->Base.Format == MESA_FORMAT_X8_Z24) {
+ _mesa_reference_renderbuffer(&fb->_DepthBuffer, &irbDepth->Base);
+ irbDepth->Base.Wrapped = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ }
+
+ irbStencil = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+ if (irbStencil && irbStencil->Base.Format == MESA_FORMAT_S8) {
+ _mesa_reference_renderbuffer(&fb->_StencilBuffer, &irbStencil->Base);
+ irbStencil->Base.Wrapped = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ }
+
/* Do this here, not core Mesa, since this function is called from
* many places within the driver.
*/
@@ -165,47 +189,33 @@ intel_draw_buffer(struct gl_context * ctx, struct gl_framebuffer *fb)
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
}
- /***
- *** Get depth buffer region and check if we need a software fallback.
- ***/
- if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
- irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
- if (irbDepth && irbDepth->region) {
- assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
- FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
- depthRegion = irbDepth->region;
- }
- else {
- FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
- depthRegion = NULL;
- }
- }
- else {
- /* not using depth buffer */
+ /* Check for depth fallback. */
+ if (irbDepth && irbDepth->region) {
+ assert(!fb_has_hiz || irbDepth->Base.Format != MESA_FORMAT_S8_Z24);
+ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
+ depthRegion = irbDepth->region;
+ } else if (irbDepth && !irbDepth->region) {
+ FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
+ depthRegion = NULL;
+ } else { /* !irbDepth */
+ /* No fallback is needed because there is no depth buffer. */
FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
depthRegion = NULL;
}
- /***
- *** Stencil buffer
- ***/
- if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
- irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
- if (irbStencil && irbStencil->region) {
- if (!intel->has_separate_stencil)
- assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
- if (fb_has_hiz || intel->must_use_separate_stencil)
- assert(irbStencil->Base.Format == MESA_FORMAT_S8);
- if (irbStencil->Base.Format == MESA_FORMAT_S8)
- assert(intel->has_separate_stencil);
- FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
- }
- else {
- FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
- }
- }
- else {
- /* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */
+ /* Check for stencil fallback. */
+ if (irbStencil && irbStencil->region) {
+ if (!intel->has_separate_stencil)
+ assert(irbStencil->Base.Format == MESA_FORMAT_S8_Z24);
+ if (fb_has_hiz || intel->must_use_separate_stencil)
+ assert(irbStencil->Base.Format == MESA_FORMAT_S8);
+ if (irbStencil->Base.Format == MESA_FORMAT_S8)
+ assert(intel->has_separate_stencil);
+ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
+ } else if (irbStencil && !irbStencil->region) {
+ FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
+ } else { /* !irbStencil */
+ /* No fallback is needed because there is no stencil buffer. */
FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
}
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 0c2ba413ad7..70aee52bd14 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -504,10 +504,7 @@ intelInvalidateState(struct gl_context * ctx, GLuint new_state)
struct intel_context *intel = intel_context(ctx);
_swrast_InvalidateState(ctx, new_state);
- _swsetup_InvalidateState(ctx, new_state);
_vbo_InvalidateState(ctx, new_state);
- _tnl_InvalidateState(ctx, new_state);
- _tnl_invalidate_vertex_state(ctx, new_state);
intel->NewGLState |= new_state;
@@ -663,7 +660,7 @@ intelInitContext(struct intel_context *intel,
ctx->TextureFormatSupported[MESA_FORMAT_AL1616] = GL_TRUE;
/* Depth and stencil */
- ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = !intel->must_use_separate_stencil;
+ ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = GL_TRUE;
ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = intel->has_separate_stencil;
ctx->TextureFormatSupported[MESA_FORMAT_S8] = intel->has_separate_stencil;
@@ -854,7 +851,7 @@ intelInitContext(struct intel_context *intel,
if (INTEL_DEBUG & DEBUG_BUFMGR)
dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE);
- intel_batchbuffer_reset(intel);
+ intel_batchbuffer_init(intel);
intel_fbo_init(intel);
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 80dee4ef38e..148fb0c2c9a 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -181,6 +181,9 @@ struct intel_context
drm_intel_bo *bo;
/** Last BO submitted to the hardware. Used for glFinish(). */
drm_intel_bo *last_bo;
+ /** BO for post-sync nonzero writes for gen6 workaround. */
+ drm_intel_bo *workaround_bo;
+ bool need_workaround_flush;
struct cached_batch_item *cached_items;
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 3fd987abd8c..64c996ca5cd 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -172,6 +172,7 @@ static const struct dri_extension brw_extensions[] = {
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
{ "GL_ARB_point_sprite", NULL },
{ "GL_ARB_seamless_cube_map", NULL },
+ { "GL_ARB_shader_texture_lod", NULL },
{ "GL_ARB_shadow", NULL },
#ifdef TEXTURE_FLOAT_ENABLED
{ "GL_ARB_texture_float", NULL },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index e7c23f02f65..90c3909d1d8 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -82,6 +82,12 @@ intel_delete_renderbuffer(struct gl_renderbuffer *rb)
if (intel && irb->hiz_region) {
intel_region_release(&irb->hiz_region);
}
+ if (intel && irb->wrapped_depth) {
+ _mesa_reference_renderbuffer(&irb->wrapped_depth, NULL);
+ }
+ if (intel && irb->wrapped_stencil) {
+ _mesa_reference_renderbuffer(&irb->wrapped_stencil, NULL);
+ }
free(irb);
}
@@ -105,7 +111,7 @@ intel_get_pointer(struct gl_context * ctx, struct gl_renderbuffer *rb,
* Called via glRenderbufferStorageEXT() to set the format and allocate
* storage for a user-created renderbuffer.
*/
-static GLboolean
+GLboolean
intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
GLenum internalFormat,
GLuint width, GLuint height)
@@ -141,6 +147,8 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
break;
}
+ rb->Width = width;
+ rb->Height = height;
rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
rb->DataType = intel_mesa_format_to_rb_datatype(rb->Format);
cpp = _mesa_get_format_bytes(rb->Format);
@@ -190,32 +198,63 @@ intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer
width,
height / 2,
GL_TRUE);
+ if (!irb->region)
+ return false;
+
+ } else if (irb->Base.Format == MESA_FORMAT_S8_Z24
+ && intel->must_use_separate_stencil) {
+
+ bool ok = true;
+ struct gl_renderbuffer *depth_rb;
+ struct gl_renderbuffer *stencil_rb;
+
+ depth_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
+ MESA_FORMAT_X8_Z24);
+ stencil_rb = intel_create_wrapped_renderbuffer(ctx, width, height,
+ MESA_FORMAT_S8);
+ ok = depth_rb && stencil_rb;
+ ok = ok && intel_alloc_renderbuffer_storage(ctx, depth_rb,
+ depth_rb->InternalFormat,
+ width, height);
+ ok = ok && intel_alloc_renderbuffer_storage(ctx, stencil_rb,
+ stencil_rb->InternalFormat,
+ width, height);
+
+ if (!ok) {
+ if (depth_rb) {
+ intel_delete_renderbuffer(depth_rb);
+ }
+ if (stencil_rb) {
+ intel_delete_renderbuffer(stencil_rb);
+ }
+ return false;
+ }
+
+ depth_rb->Wrapped = rb;
+ stencil_rb->Wrapped = rb;
+ _mesa_reference_renderbuffer(&irb->wrapped_depth, depth_rb);
+ _mesa_reference_renderbuffer(&irb->wrapped_stencil, stencil_rb);
+
} else {
irb->region = intel_region_alloc(intel->intelScreen, tiling, cpp,
width, height, GL_TRUE);
- }
-
- if (!irb->region)
- return GL_FALSE; /* out of memory? */
-
- ASSERT(irb->region->buffer);
-
- if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
- irb->hiz_region = intel_region_alloc(intel->intelScreen,
- I915_TILING_Y,
- irb->region->cpp,
- irb->region->width,
- irb->region->height,
- GL_TRUE);
- if (!irb->hiz_region) {
- intel_region_release(&irb->region);
- return GL_FALSE;
+ if (!irb->region)
+ return false;
+
+ if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
+ irb->hiz_region = intel_region_alloc(intel->intelScreen,
+ I915_TILING_Y,
+ irb->region->cpp,
+ irb->region->width,
+ irb->region->height,
+ GL_TRUE);
+ if (!irb->hiz_region) {
+ intel_region_release(&irb->region);
+ return false;
+ }
}
}
- rb->Width = width;
- rb->Height = height;
-
return GL_TRUE;
}
@@ -366,6 +405,37 @@ intel_create_renderbuffer(gl_format format)
}
+struct gl_renderbuffer*
+intel_create_wrapped_renderbuffer(struct gl_context * ctx,
+ int width, int height,
+ gl_format format)
+{
+ /*
+ * The name here is irrelevant, as long as its nonzero, because the
+ * renderbuffer never gets entered into Mesa's renderbuffer hash table.
+ */
+ GLuint name = ~0;
+
+ struct intel_renderbuffer *irb = CALLOC_STRUCT(intel_renderbuffer);
+ if (!irb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
+ return NULL;
+ }
+
+ struct gl_renderbuffer *rb = &irb->Base;
+ _mesa_init_renderbuffer(rb, name);
+ rb->ClassID = INTEL_RB_CLASS;
+ rb->_BaseFormat = _mesa_get_format_base_format(format);
+ rb->Format = format;
+ rb->InternalFormat = rb->_BaseFormat;
+ rb->DataType = intel_mesa_format_to_rb_datatype(format);
+ rb->Width = width;
+ rb->Height = height;
+
+ return rb;
+}
+
+
/**
* Create a new renderbuffer object.
* Typically called via glBindRenderbufferEXT().
@@ -427,6 +497,10 @@ intel_framebuffer_renderbuffer(struct gl_context * ctx,
intel_draw_buffer(ctx, fb);
}
+static bool
+intel_update_tex_wrapper_regions(struct intel_context *intel,
+ struct intel_renderbuffer *irb,
+ struct intel_texture_image *intel_image);
static GLboolean
intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
@@ -453,6 +527,49 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
irb->Base.Delete = intel_delete_renderbuffer;
irb->Base.AllocStorage = intel_nop_alloc_storage;
+ if (intel_image->stencil_rb) {
+ /* The tex image has packed depth/stencil format, but is using separate
+ * stencil. */
+
+ bool ok;
+ struct intel_renderbuffer *depth_irb =
+ intel_renderbuffer(intel_image->depth_rb);
+
+ /* Update the hiz region if necessary. */
+ ok = intel_update_tex_wrapper_regions(intel, depth_irb, intel_image);
+ if (!ok) {
+ return false;
+ }
+
+ /* The tex image shares its embedded depth and stencil renderbuffers with
+ * the renderbuffer wrapper. */
+ if (irb->wrapped_depth != intel_image->depth_rb) {
+ _mesa_reference_renderbuffer(&irb->wrapped_depth,
+ intel_image->depth_rb);
+ }
+ if (irb->wrapped_stencil != intel_image->stencil_rb) {
+ _mesa_reference_renderbuffer(&irb->wrapped_stencil,
+ intel_image->stencil_rb);
+ }
+
+ return true;
+
+ } else {
+ return intel_update_tex_wrapper_regions(intel, irb, intel_image);
+ }
+}
+
+/**
+ * FIXME: The handling of the hiz region is broken for mipmapped depth textures
+ * FIXME: because intel_finalize_mipmap_tree is unaware of it.
+ */
+static bool
+intel_update_tex_wrapper_regions(struct intel_context *intel,
+ struct intel_renderbuffer *irb,
+ struct intel_texture_image *intel_image)
+{
+ struct gl_renderbuffer *rb = &irb->Base;
+
/* Point the renderbuffer's region to the texture's region. */
if (irb->region != intel_image->mt->region) {
intel_region_release(&irb->region);
@@ -460,14 +577,14 @@ intel_update_wrapper(struct gl_context *ctx, struct intel_renderbuffer *irb,
}
/* Allocate the texture's hiz region if necessary. */
- if (intel->vtbl.is_hiz_depth_format(intel, texImage->TexFormat)
+ if (intel->vtbl.is_hiz_depth_format(intel, rb->Format)
&& !intel_image->mt->hiz_region) {
intel_image->mt->hiz_region =
intel_region_alloc(intel->intelScreen,
I915_TILING_Y,
- _mesa_get_format_bytes(texImage->TexFormat),
- texImage->Width,
- texImage->Height,
+ _mesa_get_format_bytes(rb->Format),
+ rb->Width,
+ rb->Height,
GL_TRUE);
if (!intel_image->mt->hiz_region)
return GL_FALSE;
@@ -512,7 +629,7 @@ intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
return irb;
}
-static void
+void
intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
struct intel_texture_image *intel_image,
int zoffset)
@@ -719,16 +836,9 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
else
depth_stencil_are_same = false;
- bool fb_has_combined_depth_stencil_format =
- (depthRb && depthRb->Base.Format == MESA_FORMAT_S8_Z24) ||
- (stencilRb && stencilRb->Base.Format == MESA_FORMAT_S8_Z24);
-
- bool fb_has_hiz = intel_framebuffer_has_hiz(fb);
-
- if ((intel->must_use_separate_stencil || fb_has_hiz)
- && (depth_stencil_are_same || fb_has_combined_depth_stencil_format)) {
- fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
- } else if (!intel->has_separate_stencil && depthRb && stencilRb && !depth_stencil_are_same) {
+ if (!intel->has_separate_stencil
+ && depthRb && stencilRb
+ && !depth_stencil_are_same) {
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
}
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
index 509f5887225..cbf29c86257 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.h
+++ b/src/mesa/drivers/dri/intel/intel_fbo.h
@@ -33,6 +33,7 @@
#include "intel_screen.h"
struct intel_context;
+struct intel_texture_image;
/**
* Intel renderbuffer, derived from gl_renderbuffer.
@@ -45,6 +46,18 @@ struct intel_renderbuffer
/** Only used by depth renderbuffers for which HiZ is enabled. */
struct intel_region *hiz_region;
+ /**
+ * \name Packed depth/stencil unwrappers
+ *
+ * If the intel_context is using separate stencil and this renderbuffer has
+ * a a packed depth/stencil format, then wrapped_depth and wrapped_stencil
+ * are the real renderbuffers.
+ */
+ struct gl_renderbuffer *wrapped_depth;
+ struct gl_renderbuffer *wrapped_stencil;
+
+ /** \} */
+
GLuint draw_offset; /**< Offset of drawing address within the region */
GLuint draw_x, draw_y; /**< Offset of drawing within the region */
};
@@ -76,15 +89,47 @@ intel_renderbuffer(struct gl_renderbuffer *rb)
/**
- * Return a framebuffer's renderbuffer, named by a BUFFER_x index.
+ * \brief Return the framebuffer attachment specified by attIndex.
+ *
+ * If the framebuffer lacks the specified attachment, then return null.
+ *
+ * If the attached renderbuffer is a wrapper, then return wrapped
+ * renderbuffer.
*/
static INLINE struct intel_renderbuffer *
-intel_get_renderbuffer(struct gl_framebuffer *fb, int attIndex)
+intel_get_renderbuffer(struct gl_framebuffer *fb, gl_buffer_index attIndex)
{
- if (attIndex >= 0)
- return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
- else
+ struct gl_renderbuffer *rb;
+ struct intel_renderbuffer *irb;
+
+ /* XXX: Who passes -1 to intel_get_renderbuffer? */
+ if (attIndex < 0)
return NULL;
+
+ rb = fb->Attachment[attIndex].Renderbuffer;
+ if (!rb)
+ return NULL;
+
+ irb = intel_renderbuffer(rb);
+ if (!irb)
+ return NULL;
+
+ switch (attIndex) {
+ case BUFFER_DEPTH:
+ if (irb->wrapped_depth) {
+ irb = intel_renderbuffer(irb->wrapped_depth);
+ }
+ break;
+ case BUFFER_STENCIL:
+ if (irb->wrapped_stencil) {
+ irb = intel_renderbuffer(irb->wrapped_stencil);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return irb;
}
/**
@@ -125,6 +170,16 @@ intel_renderbuffer_set_hiz_region(struct intel_context *intel,
extern struct intel_renderbuffer *
intel_create_renderbuffer(gl_format format);
+struct gl_renderbuffer*
+intel_create_wrapped_renderbuffer(struct gl_context * ctx,
+ int width, int height,
+ gl_format format);
+
+GLboolean
+intel_alloc_renderbuffer_storage(struct gl_context * ctx,
+ struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height);
extern void
intel_fbo_init(struct intel_context *intel);
@@ -133,6 +188,11 @@ intel_fbo_init(struct intel_context *intel);
extern void
intel_flip_renderbuffers(struct gl_framebuffer *fb);
+void
+intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
+ struct intel_texture_image *intel_image,
+ int zoffset);
+
uint32_t
intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
uint32_t *tile_x,
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e915ca04fe0..2a3a601ddba 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -282,13 +282,38 @@ intel_query_image(__DRIimage *image, int attrib, int *value)
}
}
+static __DRIimage *
+intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = CALLOC(sizeof *image);
+ if (image == NULL)
+ return NULL;
+
+ image->region = NULL;
+ intel_region_reference(&image->region, orig_image->region);
+ if (image->region == NULL) {
+ FREE(image);
+ return NULL;
+ }
+
+ image->internal_format = orig_image->internal_format;
+ image->format = orig_image->format;
+ image->data_type = orig_image->data_type;
+ image->data = loaderPrivate;
+
+ return image;
+}
+
static struct __DRIimageExtensionRec intelImageExtension = {
{ __DRI_IMAGE, __DRI_IMAGE_VERSION },
intel_create_image_from_name,
intel_create_image_from_renderbuffer,
intel_destroy_image,
intel_create_image,
- intel_query_image
+ intel_query_image,
+ intel_dup_image
};
static const __DRIextension *intelScreenExtensions[] = {
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 9343f40eef0..153803fba09 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -148,7 +148,7 @@ intel_set_span_functions(struct intel_context *intel,
* x | y | byte offset
* --------------------------
* 0 | 0 | 0
- * 0 | 0 | 1
+ * 0 | 1 | 1
* 1 | 0 | 2
* 1 | 1 | 3
* ... | ... | ...
@@ -177,7 +177,15 @@ intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
{
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
- if (irb == NULL || irb->region == NULL)
+ if (!irb)
+ return;
+
+ if (irb->wrapped_depth)
+ intel_renderbuffer_map(intel, irb->wrapped_depth);
+ if (irb->wrapped_stencil)
+ intel_renderbuffer_map(intel, irb->wrapped_stencil);
+
+ if (!irb->region)
return;
drm_intel_gem_bo_map_gtt(irb->region->buffer);
@@ -206,7 +214,15 @@ intel_renderbuffer_unmap(struct intel_context *intel,
{
struct intel_renderbuffer *irb = intel_renderbuffer(rb);
- if (irb == NULL || irb->region == NULL)
+ if (!irb)
+ return;
+
+ if (irb->wrapped_depth)
+ intel_renderbuffer_unmap(intel, irb->wrapped_depth);
+ if (irb->wrapped_stencil)
+ intel_renderbuffer_unmap(intel, irb->wrapped_stencil);
+
+ if (!irb->region)
return;
drm_intel_gem_bo_unmap_gtt(irb->region->buffer);
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
index 32e1fb7397a..21c4a1dddba 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -1,4 +1,5 @@
#include "swrast/swrast.h"
+#include "main/renderbuffer.h"
#include "main/texobj.h"
#include "main/teximage.h"
#include "main/mipmap.h"
@@ -59,6 +60,14 @@ intelFreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texI
_mesa_free_texmemory(texImage->Data);
texImage->Data = NULL;
}
+
+ if (intelImage->depth_rb) {
+ _mesa_reference_renderbuffer(&intelImage->depth_rb, NULL);
+ }
+
+ if (intelImage->stencil_rb) {
+ _mesa_reference_renderbuffer(&intelImage->stencil_rb, NULL);
+ }
}
/**
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 90d4117ec8f..269faefa1c0 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -8,6 +8,7 @@
#include "main/context.h"
#include "main/formats.h"
#include "main/pbo.h"
+#include "main/renderbuffer.h"
#include "main/texcompress.h"
#include "main/texstore.h"
#include "main/texgetimage.h"
@@ -21,6 +22,7 @@
#include "intel_tex.h"
#include "intel_blit.h"
#include "intel_fbo.h"
+#include "intel_span.h"
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
@@ -277,6 +279,130 @@ try_pbo_zcopy(struct intel_context *intel,
return GL_TRUE;
}
+/**
+ * \param scatter Scatter if true. Gather if false.
+ *
+ * \see intel_tex_image_x8z24_scatter
+ * \see intel_tex_image_x8z24_gather
+ */
+static void
+intel_tex_image_s8z24_scattergather(struct intel_context *intel,
+ struct intel_texture_image *intel_image,
+ bool scatter)
+{
+ struct gl_context *ctx = &intel->ctx;
+ struct gl_renderbuffer *depth_rb = intel_image->depth_rb;
+ struct gl_renderbuffer *stencil_rb = intel_image->stencil_rb;
+
+ int w = intel_image->base.Width;
+ int h = intel_image->base.Height;
+
+ uint32_t depth_row[w];
+ uint8_t stencil_row[w];
+
+ intel_renderbuffer_map(intel, depth_rb);
+ intel_renderbuffer_map(intel, stencil_rb);
+
+ if (scatter) {
+ for (int y = 0; y < h; ++y) {
+ depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
+ for (int x = 0; x < w; ++x) {
+ stencil_row[x] = depth_row[x] >> 24;
+ }
+ stencil_rb->PutRow(ctx, stencil_rb, w, 0, y, stencil_row, NULL);
+ }
+ } else { /* gather */
+ for (int y = 0; y < h; ++y) {
+ depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
+ stencil_rb->GetRow(ctx, stencil_rb, w, 0, y, stencil_row);
+ for (int x = 0; x < w; ++x) {
+ uint32_t s8_x24 = stencil_row[x] << 24;
+ uint32_t x8_z24 = depth_row[x] & 0x00ffffff;
+ depth_row[x] = s8_x24 | x8_z24;
+ }
+ depth_rb->PutRow(ctx, depth_rb, w, 0, y, depth_row, NULL);
+ }
+ }
+
+ intel_renderbuffer_unmap(intel, depth_rb);
+ intel_renderbuffer_unmap(intel, stencil_rb);
+}
+
+/**
+ * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb.
+ */
+static void
+intel_tex_image_s8z24_scatter(struct intel_context *intel,
+ struct intel_texture_image *intel_image)
+{
+ intel_tex_image_s8z24_scattergather(intel, intel_image, true);
+}
+
+/**
+ * Copy the data in intel_image->stencil_rb to the x8 bits in
+ * intel_image->depth_rb.
+ */
+static void
+intel_tex_image_s8z24_gather(struct intel_context *intel,
+ struct intel_texture_image *intel_image)
+{
+ intel_tex_image_s8z24_scattergather(intel, intel_image, false);
+}
+
+static bool
+intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel,
+ struct intel_texture_image *image)
+{
+ struct gl_context *ctx = &intel->ctx;
+
+ bool ok = true;
+ int width = image->base.Width;
+ int height = image->base.Height;
+ struct gl_renderbuffer *drb;
+ struct gl_renderbuffer *srb;
+ struct intel_renderbuffer *idrb;
+ struct intel_renderbuffer *isrb;
+
+ assert(intel->has_separate_stencil);
+ assert(image->base.TexFormat == MESA_FORMAT_S8_Z24);
+ assert(image->mt != NULL);
+
+ drb = intel_create_wrapped_renderbuffer(ctx, width, height,
+ MESA_FORMAT_X8_Z24);
+ srb = intel_create_wrapped_renderbuffer(ctx, width, height,
+ MESA_FORMAT_S8);
+
+ if (!drb || !srb) {
+ if (drb) {
+ drb->Delete(drb);
+ }
+ if (srb) {
+ srb->Delete(srb);
+ }
+ return false;
+ }
+
+ idrb = intel_renderbuffer(drb);
+ isrb = intel_renderbuffer(srb);
+
+ intel_region_reference(&idrb->region, image->mt->region);
+ ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8,
+ width, height);
+
+ if (!ok) {
+ drb->Delete(drb);
+ srb->Delete(srb);
+ return false;
+ }
+
+ intel_renderbuffer_set_draw_offset(idrb, image, 0);
+ intel_renderbuffer_set_draw_offset(isrb, image, 0);
+
+ _mesa_reference_renderbuffer(&image->depth_rb, drb);
+ _mesa_reference_renderbuffer(&image->stencil_rb, srb);
+
+ return true;
+}
static void
intelTexImage(struct gl_context * ctx,
@@ -314,18 +440,7 @@ intelTexImage(struct gl_context * ctx,
}
}
- /* Release the reference to a potentially orphaned buffer.
- * Release any old malloced memory.
- */
- if (intelImage->mt) {
- intel_miptree_release(intel, &intelImage->mt);
- assert(!texImage->Data);
- }
- else if (texImage->Data) {
- _mesa_free_texmemory(texImage->Data);
- texImage->Data = NULL;
- }
-
+ ctx->Driver.FreeTexImageData(ctx, texImage);
assert(!intelImage->mt);
if (intelObj->mt &&
@@ -484,6 +599,12 @@ intelTexImage(struct gl_context * ctx,
_mesa_unmap_teximage_pbo(ctx, unpack);
+ if (intel->must_use_separate_stencil
+ && texImage->TexFormat == MESA_FORMAT_S8_Z24) {
+ intel_tex_image_s8z24_create_renderbuffers(intel, intelImage);
+ intel_tex_image_s8z24_scatter(intel, intelImage);
+ }
+
if (intelImage->mt) {
if (pixels != NULL)
intel_miptree_image_unmap(intel, intelImage->mt);
@@ -600,6 +721,14 @@ intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level,
assert(intelImage->base.Data);
}
+ if (intelImage->stencil_rb) {
+ /*
+ * The texture has packed depth/stencil format, but uses separate
+ * stencil. The texture's embedded stencil buffer contains the real
+ * stencil data, so copy that into the miptree.
+ */
+ intel_tex_image_s8z24_gather(intel, intelImage);
+ }
if (compressed) {
_mesa_get_compressed_teximage(ctx, target, level, pixels,
diff --git a/src/mesa/drivers/dri/intel/intel_tex_obj.h b/src/mesa/drivers/dri/intel/intel_tex_obj.h
index e93ef4a4727..a9ae2ec5429 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_obj.h
+++ b/src/mesa/drivers/dri/intel/intel_tex_obj.h
@@ -63,6 +63,36 @@ struct intel_texture_image
*/
struct intel_mipmap_tree *mt;
GLboolean used_as_render_target;
+
+ /**
+ * \name Renderbuffers for faking packed depth/stencil
+ *
+ * These renderbuffers are non-null only if the intel_context is using
+ * separate stencil and this texture has a packed depth/stencil format. When
+ * glFramebufferTexture is called on this image, the resultant renderbuffer
+ * wrapper reuses these renderbuffers as its own.
+ *
+ * \see intel_wrap_texture
+ * \see intel_tex_image_s8z24_create_renderbuffers
+ * \see intel_tex_image_s8z24_scatter
+ * \see intel_tex_image_s8z24_gather
+ *
+ * \{
+ */
+
+ /**
+ * The depth buffer has format X8_Z24. The x8 bits are undefined unless
+ * intel_tex_image_s8z24_gather has been immediately called. The depth buffer
+ * resuses the image miptree's region and hiz_region as its own.
+ */
+ struct gl_renderbuffer *depth_rb;
+
+ /**
+ * The stencil buffer has format S8 and keeps its data in its own region.
+ */
+ struct gl_renderbuffer *stencil_rb;
+
+ /** \} */
};
static INLINE struct intel_texture_object *
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index 931a9ecf8fe..a512c9d112a 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -47,9 +47,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define insert_at_tail_if(atom_list, atom) \
do { \
- struct radeon_state_atom* __atom = (atom); \
- if (__atom->check) \
- insert_at_tail((atom_list), __atom); \
+ struct radeon_state_atom* current_atom = (atom); \
+ if (current_atom->check) \
+ insert_at_tail((atom_list), current_atom); \
} while(0)
void r200SetUpAtomList( r200ContextPtr rmesa )
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index 2bd3b62bfdb..0f7a7a46b71 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -329,7 +329,7 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start,
{
context_t *context = R700_CONTEXT(ctx);
BATCH_LOCALS(&context->radeon);
- int type, i;
+ int type;
uint32_t num_indices, total_emit = 0;
uint32_t vgt_draw_initiator = 0;
uint32_t vgt_index_type = 0;
@@ -370,22 +370,7 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start,
vgt_num_indices = num_indices;
SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
- if (start == 0)
- {
- SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
- }
- else
- {
- if (num_indices > 0xffff)
- {
- total_emit += num_indices;
- }
- else
- {
- total_emit += (num_indices + 1) / 2;
- }
- SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
- }
+ SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
total_emit += 3 /* VGT_PRIMITIVE_TYPE */
+ 2 /* VGT_INDEX_TYPE */
@@ -406,45 +391,13 @@ static void r700RunRenderPrimitiveImmediate(struct gl_context * ctx, int start,
/* offset */
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2));
R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
- R600_OUT_BATCH(0); //VTX_BASE_VTX_LOC
+ R600_OUT_BATCH(start); //VTX_BASE_VTX_LOC
R600_OUT_BATCH(0); //VTX_START_INST_LOC
// draw packet
- if(start == 0)
- {
- R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
- R600_OUT_BATCH(vgt_num_indices);
- R600_OUT_BATCH(vgt_draw_initiator);
- }
- else
- {
- if (num_indices > 0xffff)
- {
- R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
- R600_OUT_BATCH(vgt_num_indices);
- R600_OUT_BATCH(vgt_draw_initiator);
- for (i = start; i < (start + num_indices); i++)
- {
- R600_OUT_BATCH(i);
- }
- }
- else
- {
- R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (((num_indices + 1) / 2) + 1)));
- R600_OUT_BATCH(vgt_num_indices);
- R600_OUT_BATCH(vgt_draw_initiator);
- for (i = start; i < (start + num_indices); i += 2)
- {
- if ((i + 1) == (start + num_indices))
- {
- R600_OUT_BATCH(i);
- }
- else
- {
- R600_OUT_BATCH(((i + 1) << 16) | (i));
- }
- }
- }
- }
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
END_BATCH();
COMMIT_BATCH();
@@ -469,12 +422,7 @@ static GLuint r700PredictRenderSize(struct gl_context* ctx,
else {
for (i = 0; i < nr_prims; ++i)
{
- if (prim[i].start == 0)
- dwords += 14;
- else if (prim[i].count > 0xffff)
- dwords += prim[i].count + 14;
- else
- dwords += ((prim[i].count + 1) / 2) + 14;
+ dwords += 14;
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index c5ddb6d3ebe..676fafd4560 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -1739,6 +1739,9 @@ radeonCreateScreen2(__DRIscreen *sPriv)
case 1:
screen->num_banks = 8;
break;
+ case 2:
+ screen->num_banks = 16;
+ break;
default:
fprintf(stderr, "bad banks\n");
break;
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
index 63f53e2b080..a75c9c2e782 100644
--- a/src/mesa/main/buffers.c
+++ b/src/mesa/main/buffers.c
@@ -462,6 +462,27 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
/**
+ * Update the current drawbuffer's _ColorDrawBufferIndex[] list, etc.
+ * from the context's Color.DrawBuffer[] state.
+ * Use when changing contexts.
+ */
+void
+_mesa_update_draw_buffers(struct gl_context *ctx)
+{
+ GLenum buffers[MAX_DRAW_BUFFERS];
+ GLuint i;
+
+ /* should be a window system FBO */
+ assert(ctx->DrawBuffer->Name == 0);
+
+ for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
+ buffers[i] = ctx->Color.DrawBuffer[i];
+
+ _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers, buffers, NULL);
+}
+
+
+/**
* Like \sa _mesa_drawbuffers(), this is a helper function for setting
* GL_READ_BUFFER state in the context and current FBO.
* \param ctx the rendering context
diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h
index 1404112c411..8083bc3d353 100644
--- a/src/mesa/main/buffers.h
+++ b/src/mesa/main/buffers.h
@@ -50,6 +50,10 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
extern void
_mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex);
+extern void
+_mesa_update_draw_buffers(struct gl_context *ctx);
+
+
extern void GLAPIENTRY
_mesa_ReadBuffer( GLenum mode );
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index ea13bdd6835..b83a5d621fa 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1430,7 +1430,8 @@ _mesa_make_current( struct gl_context *newCtx,
}
if (curCtx &&
- (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */
+ (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) &&
+ /* make sure this context is valid for flushing */
curCtx != newCtx)
_mesa_flush(curCtx);
@@ -1445,8 +1446,6 @@ _mesa_make_current( struct gl_context *newCtx,
_glapi_set_dispatch(newCtx->CurrentDispatch);
if (drawBuffer && readBuffer) {
- /* TODO: check if newCtx and buffer's visual match??? */
-
ASSERT(drawBuffer->Name == 0);
ASSERT(readBuffer->Name == 0);
_mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);
@@ -1457,23 +1456,12 @@ _mesa_make_current( struct gl_context *newCtx,
* or not bound to a user-created FBO.
*/
if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {
- /* KW: merge conflict here, revisit.
- */
- /* fix up the fb fields - these will end up wrong otherwise
- * if the DRIdrawable changes, and everything relies on them.
- * This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
- */
- unsigned int i;
- GLenum buffers[MAX_DRAW_BUFFERS];
-
_mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
-
- for(i = 0; i < newCtx->Const.MaxDrawBuffers; i++) {
- buffers[i] = newCtx->Color.DrawBuffer[i];
- }
-
- _mesa_drawbuffers(newCtx, newCtx->Const.MaxDrawBuffers,
- buffers, NULL);
+ /* Update the FBO's list of drawbuffers/renderbuffers.
+ * For winsys FBOs this comes from the GL state (which may have
+ * changed since the last time this FBO was bound).
+ */
+ _mesa_update_draw_buffers(newCtx);
}
if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {
_mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 2230b262336..8cc3fd49a34 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -78,9 +78,32 @@ static struct gl_renderbuffer DummyRenderbuffer;
static struct gl_framebuffer IncompleteFramebuffer;
-#define IS_CUBE_FACE(TARGET) \
- ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
- (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
+static INLINE GLboolean
+is_cube_face(GLenum target)
+{
+ return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+}
+
+
+/**
+ * Is the given FBO a user-created FBO?
+ */
+static INLINE GLboolean
+is_user_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name != 0;
+}
+
+
+/**
+ * Is the given FBO a window system FBO (like an X window)?
+ */
+static INLINE GLboolean
+is_winsys_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name == 0;
+}
static void
@@ -196,7 +219,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
{
GLuint i;
- assert(fb->Name > 0);
+ assert(is_user_fbo(fb));
switch (attachment) {
case GL_COLOR_ATTACHMENT0_EXT:
@@ -244,7 +267,7 @@ static struct gl_renderbuffer_attachment *
_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
GLenum attachment)
{
- assert(fb->Name == 0);
+ assert(is_winsys_fbo(fb));
switch (attachment) {
case GL_FRONT_LEFT:
@@ -669,7 +692,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
GLint i;
GLuint j;
- assert(fb->Name != 0);
+ assert(is_user_fbo(fb));
numImages = 0;
fb->Width = 0;
@@ -968,10 +991,11 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- if (ctx->DrawBuffer->Name) {
+ if (is_user_fbo(ctx->DrawBuffer)) {
detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
}
- if (ctx->ReadBuffer->Name && ctx->ReadBuffer != ctx->DrawBuffer) {
+ if (is_user_fbo(ctx->ReadBuffer)
+ && ctx->ReadBuffer != ctx->DrawBuffer) {
detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
@@ -1203,7 +1227,7 @@ invalidate_rb(GLuint key, void *data, void *userData)
struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
/* If this is a user-created FBO */
- if (fb->Name) {
+ if (is_user_fbo(fb)) {
GLuint i;
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
@@ -1532,7 +1556,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
GLuint i;
ASSERT(ctx->Driver.RenderTexture);
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
for (i = 0; i < BUFFER_COUNT; i++) {
@@ -1552,7 +1576,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
static void
check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (fb->Name == 0)
+ if (is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
if (ctx->Driver.FinishRenderTexture) {
@@ -1805,7 +1829,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
return 0;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* The window system / default framebuffer is always complete */
return GL_FRAMEBUFFER_COMPLETE_EXT;
}
@@ -1843,7 +1867,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
/* check framebuffer binding */
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture%sEXT", caller);
return;
@@ -1866,7 +1890,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
else {
err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
- ? !IS_CUBE_FACE(textarget)
+ ? !is_cube_face(textarget)
: (texObj->Target != textarget);
}
}
@@ -1970,7 +1994,7 @@ _mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
if ((texture != 0) &&
(textarget != GL_TEXTURE_2D) &&
(textarget != GL_TEXTURE_RECTANGLE_ARB) &&
- (!IS_CUBE_FACE(textarget))) {
+ (!is_cube_face(textarget))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture2DEXT(textarget=0x%x)", textarget);
return;
@@ -2034,7 +2058,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
return;
}
- if (fb->Name == 0) {
+ if (is_winsys_fbo(fb)) {
/* Can't attach new renderbuffers to a window system framebuffer */
_mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
return;
@@ -2111,7 +2135,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
return;
}
- if (buffer->Name == 0) {
+ if (is_winsys_fbo(buffer)) {
/* the default / window-system FBO */
att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
}
@@ -2143,7 +2167,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index eb2efc89aed..f018c75cc6a 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1435,8 +1435,7 @@ struct gl_texgen
/**
* Texture unit state. Contains enable flags, texture environment/function/
- * combiners, texgen state, pointers to current texture objects and
- * post-filter color tables.
+ * combiners, texgen state, and pointers to current texture objects.
*/
struct gl_texture_unit
{
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index d6470e351b8..a232a51c355 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -4683,7 +4683,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking )
{
- GLfloat *depthTemp, *depthValues;
+ GLfloat *depthTemp = NULL, *depthValues;
GLboolean needClamp = GL_FALSE;
/* Look for special cases first.
@@ -4729,16 +4729,16 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
/* general case path follows */
- depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
- if (!depthTemp) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
- return;
- }
-
if (dstType == GL_FLOAT) {
depthValues = (GLfloat *) dest;
}
else {
+ depthTemp = (GLfloat *) malloc(n * sizeof(GLfloat));
+ if (!depthTemp) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+ return;
+ }
+
depthValues = depthTemp;
}
@@ -4782,6 +4782,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
}
zValues[i] = value & 0xffffff00;
}
+ free(depthTemp);
return;
}
else {
diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c
index fa884c0de93..c36175c60e7 100644
--- a/src/mesa/main/renderbuffer.c
+++ b/src/mesa/main/renderbuffer.c
@@ -2567,26 +2567,3 @@ _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
*ptr = rb;
}
}
-
-
-/**
- * Create a new combined depth/stencil renderbuffer for implementing
- * the GL_EXT_packed_depth_stencil extension.
- * \return new depth/stencil renderbuffer
- */
-struct gl_renderbuffer *
-_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name)
-{
- struct gl_renderbuffer *dsrb;
-
- dsrb = _mesa_new_renderbuffer(ctx, name);
- if (!dsrb)
- return NULL;
-
- /* init fields not covered by _mesa_new_renderbuffer() */
- dsrb->InternalFormat = GL_DEPTH24_STENCIL8_EXT;
- dsrb->Format = MESA_FORMAT_Z24_S8;
- dsrb->AllocStorage = _mesa_soft_renderbuffer_storage;
-
- return dsrb;
-}
diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h
index 39d9b3035e6..53da5b03385 100644
--- a/src/mesa/main/renderbuffer.h
+++ b/src/mesa/main/renderbuffer.h
@@ -108,8 +108,5 @@ extern void
_mesa_reference_renderbuffer(struct gl_renderbuffer **ptr,
struct gl_renderbuffer *rb);
-extern struct gl_renderbuffer *
-_mesa_new_depthstencil_renderbuffer(struct gl_context *ctx, GLuint name);
-
#endif /* RENDERBUFFER_H */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 4696dbb526f..7ad50bcaddc 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -192,7 +192,10 @@ update_arrays( struct gl_context *ctx )
static void
update_program_enables(struct gl_context *ctx)
{
- /* These _Enabled flags indicate if the program is enabled AND valid. */
+ /* These _Enabled flags indicate if the user-defined ARB/NV vertex/fragment
+ * program is enabled AND valid. Similarly for ATI fragment shaders.
+ * GLSL shaders not relevant here.
+ */
ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
&& ctx->VertexProgram.Current->Base.Instructions;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
@@ -203,11 +206,12 @@ update_program_enables(struct gl_context *ctx)
/**
- * Update vertex/fragment program state. In particular, update these fields:
- * ctx->VertexProgram._Current
- * ctx->VertexProgram._TnlProgram,
- * These point to the highest priority enabled vertex/fragment program or are
- * NULL if fixed-function processing is to be done.
+ * Update the ctx->Vertex/Geometry/FragmentProgram._Current pointers to point
+ * to the current/active programs. Then call ctx->Driver.BindProgram() to
+ * tell the driver which programs to use.
+ *
+ * Programs may come from 3 sources: GLSL shaders, ARB/NV_vertex/fragment
+ * programs or programs derived from fixed-function state.
*
* This function needs to be called after texture state validation in case
* we're generating a fragment program from fixed-function texture state.
@@ -243,34 +247,33 @@ update_program(struct gl_context *ctx)
*/
if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) {
- /* Use shader programs */
+ /* Use GLSL fragment shader */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
fsProg->FragmentProgram);
}
else if (ctx->FragmentProgram._Enabled) {
- /* use user-defined vertex program */
+ /* Use user-defined fragment program */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
ctx->FragmentProgram.Current);
}
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
- /* Use fragment program generated from fixed-function state.
- */
+ /* Use fragment program generated from fixed-function state */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
_mesa_get_fixed_func_fragment_program(ctx));
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram,
ctx->FragmentProgram._Current);
}
else {
- /* no fragment program */
+ /* No fragment program */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) {
- /* Use shader programs */
+ /* Use GLSL geometry shader */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
gsProg->GeometryProgram);
} else {
- /* no fragment program */
+ /* No geometry program */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
}
@@ -279,18 +282,17 @@ update_program(struct gl_context *ctx)
* fragprog inputs.
*/
if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) {
- /* Use shader programs */
+ /* Use GLSL vertex shader */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- vsProg->VertexProgram);
+ vsProg->VertexProgram);
}
else if (ctx->VertexProgram._Enabled) {
- /* use user-defined vertex program */
+ /* Use user-defined vertex program */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
ctx->VertexProgram.Current);
}
else if (ctx->VertexProgram._MaintainTnlProgram) {
- /* Use vertex program generated from fixed-function state.
- */
+ /* Use vertex program generated from fixed-function state */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
_mesa_get_fixed_func_vertex_program(ctx));
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram,
@@ -416,29 +418,44 @@ update_color(struct gl_context *ctx)
ctx->Color._LogicOpEnabled = _mesa_rgba_logicop_enabled(ctx);
}
+
+/**
+ * Update the ctx->Color._ClampFragmentColor field
+ */
static void
update_clamp_fragment_color(struct gl_context *ctx)
{
- if(ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampFragmentColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
+ if (ctx->Color.ClampFragmentColor == GL_FIXED_ONLY_ARB)
+ ctx->Color._ClampFragmentColor =
+ !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
else
ctx->Color._ClampFragmentColor = ctx->Color.ClampFragmentColor;
}
+
+/**
+ * Update the ctx->Color._ClampVertexColor field
+ */
static void
update_clamp_vertex_color(struct gl_context *ctx)
{
- if(ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB)
- ctx->Light._ClampVertexColor = !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
+ if (ctx->Light.ClampVertexColor == GL_FIXED_ONLY_ARB)
+ ctx->Light._ClampVertexColor =
+ !ctx->DrawBuffer || !ctx->DrawBuffer->Visual.floatMode;
else
ctx->Light._ClampVertexColor = ctx->Light.ClampVertexColor;
}
+
+/**
+ * Update the ctx->Color._ClampReadColor field
+ */
static void
update_clamp_read_color(struct gl_context *ctx)
{
- if(ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
- ctx->Color._ClampReadColor = !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
+ if (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB)
+ ctx->Color._ClampReadColor =
+ !ctx->ReadBuffer || !ctx->ReadBuffer->Visual.floatMode;
else
ctx->Color._ClampReadColor = ctx->Color.ClampReadColor;
}
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 0827cb883e8..6f53686e7ff 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1685,11 +1685,15 @@ texture_error_check( struct gl_context *ctx,
/* additional checks for depth textures */
if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
- /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
+ /* Only 1D, 2D, rect and array textures supported, not 3D or cubes */
if (target != GL_TEXTURE_1D &&
target != GL_PROXY_TEXTURE_1D &&
target != GL_TEXTURE_2D &&
target != GL_PROXY_TEXTURE_2D &&
+ target != GL_TEXTURE_1D_ARRAY &&
+ target != GL_PROXY_TEXTURE_1D_ARRAY &&
+ target != GL_TEXTURE_2D_ARRAY &&
+ target != GL_PROXY_TEXTURE_2D_ARRAY &&
target != GL_TEXTURE_RECTANGLE_ARB &&
target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
if (!isProxy)
@@ -3270,7 +3274,7 @@ compressedteximage(struct gl_context *ctx, GLuint dims,
border, imageSize, &reason);
if (error) {
- _mesa_error(ctx, error, "glTexImage2D(%s)", reason);
+ _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason);
return;
}
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index fdf12817c9a..565a3a2d8df 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -879,6 +879,8 @@ unbind_texobj_from_fbo(struct gl_context *ctx,
for (j = 0; j < BUFFER_COUNT; j++) {
if (fb->Attachment[j].Type == GL_TEXTURE &&
fb->Attachment[j].Texture == texObj) {
+ /* Vertices are already flushed by _mesa_DeleteTextures */
+ ctx->NewState |= _NEW_BUFFERS;
_mesa_remove_attachment(ctx, fb->Attachment + j);
}
}
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 6da3e4eb7b4..5c925a3d314 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -3308,10 +3308,12 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
GLint img, row;
ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
- ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
+ ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
+ srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX);
ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
- if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f &&
+ if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
ctx->Pixel.DepthBias == 0.0f &&
!srcPacking->SwapBytes) {
/* simple path */
@@ -3322,7 +3324,8 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
- else if (srcFormat == GL_DEPTH_COMPONENT) {
+ else if (srcFormat == GL_DEPTH_COMPONENT ||
+ srcFormat == GL_STENCIL_INDEX) {
/* In case we only upload depth we need to preserve the stencil */
for (img = 0; img < srcDepth; img++) {
GLuint *dstRow = (GLuint *) dstAddr
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index 2e6335846e3..0a0512c339d 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -33,9 +33,9 @@ struct gl_context;
/* Mesa version */
#define MESA_MAJOR 7
-#define MESA_MINOR 11
+#define MESA_MINOR 12
#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.11-devel"
+#define MESA_VERSION_STRING "7.12-devel"
/* To make version comparison easy */
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 00869979dd8..67adb8f3dcd 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1296,8 +1296,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
emit_scalar(ir, OPCODE_RSQ, result_dst, op[0]);
break;
case ir_unop_i2f:
+ case ir_unop_u2f:
case ir_unop_b2f:
case ir_unop_b2i:
+ case ir_unop_i2u:
+ case ir_unop_u2i:
/* Mesa IR lacks types, ints are stored as truncated floats. */
result_src = op[0];
break;
@@ -1335,7 +1338,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
break;
case ir_unop_bit_not:
- case ir_unop_u2f:
case ir_binop_lshift:
case ir_binop_rshift:
case ir_binop_bit_and:
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 95b706cb96c..1f833d28212 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx)
const uint texSize = 256; /* simple, and usually perfect */
/* find an RGBA texture format */
- format = st_choose_format(pipe->screen, GL_RGBA,
+ format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE,
PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
/* create texture for color map/table */
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 965fbcd1d9e..d61d7ac22be 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
/* can we write to stencil if not fallback */
if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT))
goto stencil_fallback;
-
+
tex_format = st_choose_format(st->pipe->screen, base_format(format),
+ GL_NONE, GL_NONE,
PIPE_TEXTURE_2D,
0, PIPE_BIND_SAMPLER_VIEW);
if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
@@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
/* srcFormat can't be used as a texture format */
if (type == GL_DEPTH) {
texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
- st->internal_target, sample_count,
- PIPE_BIND_DEPTH_STENCIL);
+ GL_NONE, GL_NONE, st->internal_target,
+ sample_count, PIPE_BIND_DEPTH_STENCIL);
assert(texFormat != PIPE_FORMAT_NONE);
}
else {
/* default color format */
- texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
+ texFormat = st_choose_format(screen, GL_RGBA,
+ GL_NONE, GL_NONE, st->internal_target,
sample_count, PIPE_BIND_SAMPLER_VIEW);
assert(texFormat != PIPE_FORMAT_NONE);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 88f62902b25..6907cfc03cf 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -842,7 +842,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
else {
/* format translation via floats */
GLuint row;
- enum pipe_format format = util_format_linear(dst_texture->format);
+ enum pipe_format pformat = util_format_linear(dst_texture->format);
for (row = 0; row < height; row++) {
const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */
GLfloat rgba[4 * MAX_WIDTH];
@@ -854,7 +854,7 @@ decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level,
/* get float[4] rgba row from surface */
pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1,
- format, rgba);
+ pformat, rgba);
_mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
type, dest, &ctx->Pack, transferOps);
@@ -1241,7 +1241,8 @@ fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level,
src_trans = pipe_get_transfer(pipe,
strb->texture,
- 0, 0,
+ strb->rtt_level,
+ strb->rtt_face + strb->rtt_slice,
PIPE_TRANSFER_READ,
srcX, srcY,
width, height);
diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
index 049755e45c0..d4742eb897d 100644
--- a/src/mesa/state_tracker/st_cb_viewport.c
+++ b/src/mesa/state_tracker/st_cb_viewport.c
@@ -56,13 +56,20 @@ static void st_viewport(struct gl_context * ctx, GLint x, GLint y,
if (!st->invalidate_on_gl_viewport)
return;
+ /*
+ * Normally we'd want the state tracker manager to mark the drawables
+ * invalid only when needed. This will force the state tracker manager
+ * to revalidate the drawable, rather than just update the context with
+ * the latest cached drawable info.
+ */
+
stdraw = st_ws_framebuffer(st->ctx->DrawBuffer);
stread = st_ws_framebuffer(st->ctx->ReadBuffer);
- if (stdraw)
- p_atomic_set(&stdraw->revalidate, TRUE);
- if (stread && stread != stdraw)
- p_atomic_set(&stread->revalidate, TRUE);
+ if (stdraw && stdraw->iface)
+ stdraw->iface_stamp = p_atomic_read(&stdraw->iface->stamp) - 1;
+ if (stread && stread != stdraw && stread->iface)
+ stread->iface_stamp = p_atomic_read(&stread->iface->stamp) - 1;
}
void st_init_viewport_functions(struct dd_function_table *functions)
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index ff207039d78..0a322022149 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -204,6 +204,9 @@ struct st_context
/* Active render condition. */
struct pipe_query *render_condition;
unsigned condition_mode;
+
+ int32_t draw_stamp;
+ int32_t read_stamp;
};
@@ -227,7 +230,8 @@ struct st_framebuffer
struct st_framebuffer_iface *iface;
enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
unsigned num_statts;
- int32_t revalidate;
+ int32_t stamp;
+ int32_t iface_stamp;
};
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index fac0ab7a1f7..5040c6fa5ab 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -233,6 +233,22 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format,
}
+/**
+ * This is very similar to vbo_all_varyings_in_vbos() but we test
+ * the stride. See bug 38626.
+ */
+static GLboolean
+all_varyings_in_vbos(const struct gl_client_array *arrays[])
+{
+ GLuint i;
+
+ for (i = 0; i < VERT_ATTRIB_MAX; i++)
+ if (arrays[i]->StrideB && !_mesa_is_bufferobj(arrays[i]->BufferObj))
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
/**
* Examine the active arrays to determine if we have interleaved
@@ -648,7 +664,7 @@ st_draw_vbo(struct gl_context *ctx,
if (ib) {
/* Gallium probably doesn't want this in some cases. */
if (!index_bounds_valid)
- if (!vbo_all_varyings_in_vbos(arrays))
+ if (!all_varyings_in_vbos(arrays))
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
for (i = 0; i < nr_prims; i++) {
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 35835712547..fa5d8f5050a 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -608,7 +608,7 @@ struct format_mapping
* Multiple GL enums might map to multiple pipe_formats.
* The first pipe format in the list that's supported is the one that's chosen.
*/
-static struct format_mapping format_map[] = {
+static const struct format_mapping format_map[] = {
/* Basic RGB, RGBA formats */
{
{ GL_RGB10, GL_RGB10_A2, 0 },
@@ -616,7 +616,7 @@ static struct format_mapping format_map[] = {
},
{
{ 4, GL_RGBA, GL_RGBA8, 0 },
- { DEFAULT_RGBA_FORMATS, 0 }
+ { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS }
},
{
{ GL_BGRA, 0 },
@@ -624,7 +624,7 @@ static struct format_mapping format_map[] = {
},
{
{ 3, GL_RGB, GL_RGB8, 0 },
- { DEFAULT_RGB_FORMATS, 0 }
+ { DEFAULT_RGB_FORMATS }
},
{
{ GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 },
@@ -1108,7 +1108,7 @@ static struct format_mapping format_map[] = {
* Return first supported format from the given list.
*/
static enum pipe_format
-find_supported_format(struct pipe_screen *screen,
+find_supported_format(struct pipe_screen *screen,
const enum pipe_format formats[],
enum pipe_texture_target target,
unsigned sample_count,
@@ -1124,6 +1124,91 @@ find_supported_format(struct pipe_screen *screen,
return PIPE_FORMAT_NONE;
}
+struct exact_format_mapping
+{
+ GLenum format;
+ GLenum type;
+ enum pipe_format pformat;
+};
+
+static const struct exact_format_mapping rgba8888_tbl[] =
+{
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM },
+ { 0, 0, 0 }
+};
+
+static const struct exact_format_mapping rgbx8888_tbl[] =
+{
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_UNORM },
+ { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM },
+ /* No Mesa formats for these Gallium formats:
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM },
+ { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM },
+ */
+ { 0, 0, 0 }
+};
+
+static const struct exact_format_mapping rgba1010102_tbl[] =
+{
+ { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM },
+ /* No Mesa formats for these Gallium formats:
+ { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2, PIPE_FORMAT_R10G10B10A2_UNORM },
+ { GL_ABGR_EXT, GL_UNSIGNED_INT, PIPE_FORMAT_R10G10B10A2_UNORM },
+ */
+ { 0, 0, 0 }
+};
+
+/**
+ * If there is an exact pipe_format match for {internalFormat, format, type}
+ * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching.
+ */
+static enum pipe_format
+find_exact_format(GLint internalFormat, GLenum format, GLenum type)
+{
+ uint i;
+ const struct exact_format_mapping* tbl;
+
+ if (format == GL_NONE || type == GL_NONE)
+ return PIPE_FORMAT_NONE;
+
+ switch (internalFormat) {
+ case 4:
+ case GL_RGBA:
+ case GL_RGBA8:
+ tbl = rgba8888_tbl;
+ break;
+ case 3:
+ case GL_RGB:
+ case GL_RGB8:
+ tbl = rgbx8888_tbl;
+ break;
+ case GL_RGB10_A2:
+ tbl = rgba1010102_tbl;
+ break;
+ default:
+ return PIPE_FORMAT_NONE;
+ }
+
+ for (i = 0; tbl[i].format; i++)
+ if (tbl[i].format == format && tbl[i].type == type)
+ return tbl[i].pformat;
+
+ return PIPE_FORMAT_NONE;
+}
/**
* Given an OpenGL internalFormat value for a texture or surface, return
@@ -1140,11 +1225,13 @@ find_supported_format(struct pipe_screen *screen,
*/
enum pipe_format
st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
+ GLenum format, GLenum type,
enum pipe_texture_target target, unsigned sample_count,
unsigned bindings)
{
GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */
int i, j;
+ enum pipe_format pf;
/* can't render to compressed formats at this time */
if (_mesa_is_compressed_format(ctx, internalFormat)
@@ -1152,6 +1239,13 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
return PIPE_FORMAT_NONE;
}
+ /* search for exact matches */
+ pf = find_exact_format(internalFormat, format, type);
+ if (pf != PIPE_FORMAT_NONE &&
+ screen->is_format_supported(screen, pf,
+ target, sample_count, bindings))
+ return pf;
+
/* search table for internalFormat */
for (i = 0; i < Elements(format_map); i++) {
const struct format_mapping *mapping = &format_map[i];
@@ -1183,14 +1277,11 @@ st_choose_renderbuffer_format(struct pipe_screen *screen,
usage = PIPE_BIND_DEPTH_STENCIL;
else
usage = PIPE_BIND_RENDER_TARGET;
- return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D,
+ return st_choose_format(screen, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D,
sample_count, usage);
}
-/**
- * Called via ctx->Driver.chooseTextureFormat().
- */
gl_format
st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
GLenum format, GLenum type, GLboolean renderable)
@@ -1206,20 +1297,19 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
* that in advance. Specify potential render target flags now.
*/
bindings = PIPE_BIND_SAMPLER_VIEW;
- if (renderable == GL_TRUE) {
- if (_mesa_is_depth_format(internalFormat) ||
- _mesa_is_depth_or_stencil_format(internalFormat))
+ if (renderable) {
+ if (_mesa_is_depth_or_stencil_format(internalFormat))
bindings |= PIPE_BIND_DEPTH_STENCIL;
- else
+ else
bindings |= PIPE_BIND_RENDER_TARGET;
}
- pFormat = st_choose_format(screen, internalFormat,
+ pFormat = st_choose_format(screen, internalFormat, format, type,
PIPE_TEXTURE_2D, 0, bindings);
if (pFormat == PIPE_FORMAT_NONE) {
/* try choosing format again, this time without render target bindings */
- pFormat = st_choose_format(screen, internalFormat,
+ pFormat = st_choose_format(screen, internalFormat, format, type,
PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
}
@@ -1231,6 +1321,10 @@ st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
return st_pipe_format_to_mesa_format(pFormat);
}
+
+/**
+ * Called via ctx->Driver.ChooseTextureFormat().
+ */
gl_format
st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
GLenum format, GLenum type)
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 0fb570f6ee4..1c1f5965f66 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -52,8 +52,9 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat);
extern enum pipe_format
st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
+ GLenum format, GLenum type,
enum pipe_texture_target target, unsigned sample_count,
- unsigned tex_usage);
+ unsigned bindings);
extern enum pipe_format
st_choose_renderbuffer_format(struct pipe_screen *screen,
diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
index a68544ddac7..a8c4b5c3f49 100644
--- a/src/mesa/state_tracker/st_manager.c
+++ b/src/mesa/state_tracker/st_manager.c
@@ -139,23 +139,64 @@ buffer_index_to_attachment(gl_buffer_index index)
}
/**
+ * Make sure a context picks up the latest cached state of the
+ * drawables it binds to.
+ */
+static void
+st_context_validate(struct st_context *st,
+ struct st_framebuffer *stdraw,
+ struct st_framebuffer *stread)
+{
+ if (stdraw && stdraw->stamp != st->draw_stamp) {
+ st->dirty.st |= ST_NEW_FRAMEBUFFER;
+ _mesa_resize_framebuffer(st->ctx, &stdraw->Base,
+ stdraw->Base.Width,
+ stdraw->Base.Height);
+ st->draw_stamp = stdraw->stamp;
+ }
+
+ if (stread && stread->stamp != st->read_stamp) {
+ if (stread != stdraw) {
+ st->dirty.st |= ST_NEW_FRAMEBUFFER;
+ _mesa_resize_framebuffer(st->ctx, &stread->Base,
+ stread->Base.Width,
+ stread->Base.Height);
+ }
+ st->read_stamp = stread->stamp;
+ }
+}
+
+/**
* Validate a framebuffer to make sure up-to-date pipe_textures are used.
+ * The context we need to pass in is s dummy context needed only to be
+ * able to get a pipe context to create pipe surfaces, and to have a
+ * context to call _mesa_resize_framebuffer():
+ * (That should probably be rethought, since those surfaces become
+ * drawable state, not context state, and can be freed by another pipe
+ * context).
*/
static void
-st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
+st_framebuffer_validate(struct st_framebuffer *stfb,
+ struct st_context *st)
{
- struct pipe_context *pipe = st->pipe;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
uint width, height;
unsigned i;
boolean changed = FALSE;
+ int32_t new_stamp = p_atomic_read(&stfb->iface->stamp);
- if (!p_atomic_read(&stfb->revalidate))
+ if (stfb->iface_stamp == new_stamp)
return;
/* validate the fb */
- if (!stfb->iface->validate(stfb->iface, stfb->statts, stfb->num_statts, textures))
- return;
+ do {
+ if (!stfb->iface->validate(stfb->iface, stfb->statts,
+ stfb->num_statts, textures))
+ return;
+
+ stfb->iface_stamp = new_stamp;
+ new_stamp = p_atomic_read(&stfb->iface->stamp);
+ } while(stfb->iface_stamp != new_stamp);
width = stfb->Base.Width;
height = stfb->Base.Height;
@@ -184,7 +225,7 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
memset(&surf_tmpl, 0, sizeof(surf_tmpl));
u_surface_default_template(&surf_tmpl, textures[i],
PIPE_BIND_RENDER_TARGET);
- ps = pipe->create_surface(pipe, textures[i], &surf_tmpl);
+ ps = st->pipe->create_surface(st->pipe, textures[i], &surf_tmpl);
if (ps) {
pipe_surface_reference(&strb->surface, ps);
pipe_resource_reference(&strb->texture, ps->texture);
@@ -204,14 +245,9 @@ st_framebuffer_validate(struct st_framebuffer *stfb, struct st_context *st)
}
if (changed) {
- st->dirty.st |= ST_NEW_FRAMEBUFFER;
+ ++stfb->stamp;
_mesa_resize_framebuffer(st->ctx, &stfb->Base, width, height);
-
- assert(stfb->Base.Width == width);
- assert(stfb->Base.Height == height);
}
-
- p_atomic_set(&stfb->revalidate, FALSE);
}
/**
@@ -236,8 +272,7 @@ st_framebuffer_update_attachments(struct st_framebuffer *stfb)
st_visual_have_buffers(stfb->iface->visual, 1 << statt))
stfb->statts[stfb->num_statts++] = statt;
}
-
- p_atomic_set(&stfb->revalidate, TRUE);
+ stfb->stamp++;
}
/**
@@ -443,6 +478,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
&stfb->Base._ColorReadBufferIndex);
stfb->iface = stfbi;
+ stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1;
/* add the color buffer */
idx = stfb->Base._ColorDrawBufferIndexes[0];
@@ -454,6 +490,7 @@ st_framebuffer_create(struct st_framebuffer_iface *stfbi)
st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH);
st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM);
+ stfb->stamp = 0;
st_framebuffer_update_attachments(stfb);
stfb->Base.Initialized = GL_TRUE;
@@ -473,31 +510,6 @@ st_framebuffer_reference(struct st_framebuffer **ptr,
}
static void
-st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
- struct st_framebuffer_iface *stfbi)
-{
- struct st_context *st = (struct st_context *) stctxi;
- struct st_framebuffer *stfb;
-
- /* either draw or read winsys fb */
- stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer);
- if (!stfb || stfb->iface != stfbi)
- stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer);
-
- if (stfb && stfb->iface == stfbi) {
- p_atomic_set(&stfb->revalidate, TRUE);
- }
- else {
- /* This function is probably getting called when we've detected a
- * change in a window's size but the currently bound context is
- * not bound to that window.
- * If the st_framebuffer_iface structure had a pointer to the
- * corresponding st_framebuffer we'd be able to handle this.
- */
- }
-}
-
-static void
st_context_flush(struct st_context_iface *stctxi, unsigned flags,
struct pipe_fence_handle **fence)
{
@@ -696,8 +708,6 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
smapi->get_param(smapi, ST_MANAGER_BROKEN_INVALIDATE);
st->iface.destroy = st_context_destroy;
- st->iface.notify_invalid_framebuffer =
- st_context_notify_invalid_framebuffer;
st->iface.flush = st_context_flush;
st->iface.teximage = st_context_teximage;
st->iface.copy = st_context_copy;
@@ -707,38 +717,58 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
return &st->iface;
}
+static struct st_context_iface *
+st_api_get_current(struct st_api *stapi)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct st_context *st = (ctx) ? ctx->st : NULL;
+
+ return (st) ? &st->iface : NULL;
+}
+
+static struct st_framebuffer *
+st_framebuffer_reuse_or_create(struct gl_framebuffer *fb,
+ struct st_framebuffer_iface *stfbi)
+{
+ struct st_framebuffer *cur = st_ws_framebuffer(fb), *stfb = NULL;
+
+ if (cur && cur->iface == stfbi) {
+ /* reuse the current stfb */
+ st_framebuffer_reference(&stfb, cur);
+ }
+ else {
+ /* create a new one */
+ stfb = st_framebuffer_create(stfbi);
+ }
+
+ return stfb;
+}
+
static boolean
st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
struct st_framebuffer_iface *stdrawi,
struct st_framebuffer_iface *streadi)
{
struct st_context *st = (struct st_context *) stctxi;
- struct st_framebuffer *stdraw, *stread, *stfb;
+ struct st_framebuffer *stdraw, *stread;
boolean ret;
_glapi_check_multithread();
if (st) {
- /* reuse/create the draw fb */
- stfb = st_ws_framebuffer(st->ctx->WinSysDrawBuffer);
- if (stfb && stfb->iface == stdrawi) {
- stdraw = NULL;
- st_framebuffer_reference(&stdraw, stfb);
+ /* reuse or create the draw fb */
+ stdraw = st_framebuffer_reuse_or_create(st->ctx->WinSysDrawBuffer,
+ stdrawi);
+ if (streadi != stdrawi) {
+ /* do the same for the read fb */
+ stread = st_framebuffer_reuse_or_create(st->ctx->WinSysReadBuffer,
+ streadi);
}
else {
- stdraw = st_framebuffer_create(stdrawi);
- }
-
- /* reuse/create the read fb */
- stfb = st_ws_framebuffer(st->ctx->WinSysReadBuffer);
- if (!stfb || stfb->iface != streadi)
- stfb = stdraw;
- if (stfb && stfb->iface == streadi) {
stread = NULL;
- st_framebuffer_reference(&stread, stfb);
- }
- else {
- stread = st_framebuffer_create(streadi);
+ /* reuse the draw fb for the read fb */
+ if (stdraw)
+ st_framebuffer_reference(&stread, stdraw);
}
if (stdraw && stread) {
@@ -757,6 +787,10 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
}
ret = _mesa_make_current(st->ctx, &stdraw->Base, &stread->Base);
+
+ st->draw_stamp = stdraw->stamp - 1;
+ st->read_stamp = stread->stamp - 1;
+ st_context_validate(st, stdraw, stread);
}
else {
struct gl_framebuffer *incomplete = _mesa_get_incomplete_framebuffer();
@@ -773,15 +807,6 @@ st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
return ret;
}
-static struct st_context_iface *
-st_api_get_current(struct st_api *stapi)
-{
- GET_CURRENT_CONTEXT(ctx);
- struct st_context *st = (ctx) ? ctx->st : NULL;
-
- return (st) ? &st->iface : NULL;
-}
-
static st_proc_t
st_api_get_proc_address(struct st_api *stapi, const char *procname)
{
@@ -857,6 +882,8 @@ st_manager_validate_framebuffers(struct st_context *st)
st_framebuffer_validate(stdraw, st);
if (stread && stread != stdraw)
st_framebuffer_validate(stread, st);
+
+ st_context_validate(st, stdraw, stread);
}
/**
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index 9068ae240a6..1de290ff602 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -78,8 +78,7 @@ GLboolean vbo_all_varyings_in_vbos( const struct gl_client_array *arrays[] )
GLuint i;
for (i = 0; i < VERT_ATTRIB_MAX; i++)
- if (arrays[i]->StrideB &&
- arrays[i]->BufferObj->Name == 0)
+ if (arrays[i]->BufferObj->Name == 0)
return GL_FALSE;
return GL_TRUE;
@@ -90,8 +89,7 @@ GLboolean vbo_any_varyings_in_vbos( const struct gl_client_array *arrays[] )
GLuint i;
for (i = 0; i < VERT_ATTRIB_MAX; i++)
- if (arrays[i]->StrideB &&
- arrays[i]->BufferObj->Name != 0)
+ if (arrays[i]->BufferObj->Name != 0)
return GL_TRUE;
return GL_FALSE;