summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--SConstruct14
-rw-r--r--common.py38
-rw-r--r--configs/linux-dri4
-rw-r--r--configs/linux-egl65
-rw-r--r--include/EGL/eglplatform.h62
-rw-r--r--include/GLES/egl.h523
-rw-r--r--include/GLES/eglext.h186
-rw-r--r--include/GLES/egltypes.h100
-rw-r--r--progs/egl/Makefile18
-rw-r--r--progs/egl/demo1.c5
-rw-r--r--progs/egl/demo2.c57
-rw-r--r--progs/egl/demo3.c3
-rw-r--r--progs/egl/eglgears.c7
-rw-r--r--progs/egl/eglinfo.c5
-rw-r--r--progs/egl/xeglgears.c606
-rw-r--r--scons/evc.py108
-rw-r--r--scons/mslib_sa.py49
-rw-r--r--scons/mslink_sa.py211
-rw-r--r--scons/msvc_sa.py (renamed from winddk.py)77
-rw-r--r--scons/winddk.py114
-rw-r--r--src/egl/drivers/demo/demo.c12
-rw-r--r--src/egl/drivers/dri/Makefile6
-rw-r--r--src/egl/drivers/dri/egldri.c94
-rw-r--r--src/egl/drivers/dri/egldri.h9
-rw-r--r--src/egl/main/Makefile26
-rw-r--r--src/egl/main/eglapi.c182
-rw-r--r--src/egl/main/eglapi.h11
-rw-r--r--src/egl/main/eglconfig.c265
-rw-r--r--src/egl/main/eglconfig.h17
-rw-r--r--src/egl/main/eglconfigutil.c260
-rw-r--r--src/egl/main/eglconfigutil.h23
-rw-r--r--src/egl/main/eglcontext.c59
-rw-r--r--src/egl/main/eglcontext.h12
-rw-r--r--src/egl/main/egldefines.h (renamed from src/gallium/winsys/dri/intel/intel_batchpool.h)24
-rw-r--r--src/egl/main/egldisplay.c81
-rw-r--r--src/egl/main/egldisplay.h19
-rw-r--r--src/egl/main/egldriver.c246
-rw-r--r--src/egl/main/egldriver.h47
-rw-r--r--src/egl/main/eglglobals.c5
-rw-r--r--src/egl/main/eglglobals.h11
-rw-r--r--src/egl/main/eglmisc.c129
-rw-r--r--src/egl/main/eglmisc.h47
-rw-r--r--src/egl/main/eglmode.h3
-rw-r--r--src/egl/main/eglstring.c24
-rw-r--r--src/egl/main/eglstring.h9
-rw-r--r--src/egl/main/eglsurface.c34
-rw-r--r--src/egl/main/eglsurface.h4
-rw-r--r--src/egl/main/egltypedefs.h6
-rw-r--r--src/egl/main/eglx.c49
-rw-r--r--src/egl/main/eglx.h12
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c35
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aapoint.c27
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c27
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c15
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_decompose.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_elts.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c124
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c10
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp10
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_cpu.c4
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.c6
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_x86sse.h6
-rw-r--r--src/gallium/auxiliary/tgsi/exec/tgsi_exec.c10
-rwxr-xr-xsrc/gallium/auxiliary/tgsi/exec/tgsi_sse2.c48
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_build.c134
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_build.h19
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c58
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_parse.c17
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_parse.h9
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_scan.c4
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_util.c2
-rw-r--r--src/gallium/auxiliary/translate/translate.c3
-rw-r--r--src/gallium/auxiliary/translate/translate_generic.c236
-rw-r--r--src/gallium/auxiliary/translate/translate_sse.c5
-rw-r--r--src/gallium/auxiliary/util/p_debug.c13
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c33
-rw-r--r--src/gallium/auxiliary/util/u_time.c74
-rw-r--r--src/gallium/auxiliary/util/u_time.h2
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c10
-rw-r--r--src/gallium/drivers/i915simple/i915_batch.h82
-rw-r--r--src/gallium/drivers/i915simple/i915_blit.c5
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c32
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h6
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.c5
-rw-r--r--src/gallium/drivers/i915simple/i915_flush.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc_translate.c10
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c307
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c26
-rw-r--r--src/gallium/drivers/i915simple/i915_state_emit.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_state_immediate.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c160
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h22
-rw-r--r--src/gallium/drivers/i965simple/brw_sf.c10
-rw-r--r--src/gallium/drivers/i965simple/brw_shader_info.c4
-rw-r--r--src/gallium/drivers/i965simple/brw_vs_emit.c8
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_decl.c8
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c1
-rw-r--r--src/gallium/include/pipe/p_compiler.h76
-rw-r--r--src/gallium/include/pipe/p_config.h56
-rw-r--r--src/gallium/include/pipe/p_debug.h11
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h35
-rw-r--r--src/gallium/include/pipe/p_util.h17
-rw-r--r--src/gallium/winsys/SConscript9
-rw-r--r--src/gallium/winsys/dri/SConscript101
-rw-r--r--src/gallium/winsys/dri/intel/Makefile9
-rw-r--r--src/gallium/winsys/dri/intel/SConscript76
-rw-r--r--src/gallium/winsys/dri/intel/intel_batchbuffer.c514
-rw-r--r--src/gallium/winsys/dri/intel/intel_batchbuffer.h121
-rw-r--r--src/gallium/winsys/dri/intel/intel_batchpool.c427
-rw-r--r--src/gallium/winsys/dri/intel/intel_context.c8
-rw-r--r--src/gallium/winsys/dri/intel/intel_context.h2
-rw-r--r--src/gallium/winsys/dri/intel/intel_screen.c57
-rw-r--r--src/gallium/winsys/dri/intel/intel_screen.h10
-rw-r--r--src/gallium/winsys/dri/intel/intel_swapbuffers.c5
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys.h4
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys_i915.c59
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys_pipe.c185
-rw-r--r--src/gallium/winsys/dri/intel/server/i830_common.h46
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_bufmgr.c953
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_bufmgr.h138
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_bufpool.h102
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_drmpool.c268
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_fencemgr.c377
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_fencemgr.h115
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_mallocpool.c162
-rw-r--r--src/gallium/winsys/dri/intel/ws_dri_slabpool.c968
-rw-r--r--src/gallium/winsys/egl_drm/Makefile38
-rw-r--r--src/gallium/winsys/egl_drm/Makefile.template116
-rw-r--r--src/gallium/winsys/egl_drm/intel/Makefile40
-rw-r--r--src/gallium/winsys/egl_drm/intel/SConscript39
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c465
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h133
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.c366
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.h162
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.c621
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.h42
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_lock.c102
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_reg.h53
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_screen.c680
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_screen.h133
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c327
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h47
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_winsys.h73
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c184
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c338
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c82
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c953
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h138
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h102
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c268
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c377
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h115
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c162
-rw-r--r--src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c970
-rw-r--r--src/gallium/winsys/egl_xlib/Makefile87
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c559
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c281
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.h40
-rw-r--r--src/gallium/winsys/gdi/SConscript33
-rw-r--r--src/gallium/winsys/gdi/colors.h29
-rw-r--r--src/gallium/winsys/gdi/opengl32.def859
-rw-r--r--src/gallium/winsys/gdi/wgl.c703
-rw-r--r--src/gallium/winsys/gdi/wmesa.c890
-rw-r--r--src/gallium/winsys/gdi/wmesadef.h40
-rw-r--r--src/gallium/winsys/xlib/SConscript50
-rw-r--r--src/mesa/SConscript604
-rw-r--r--src/mesa/glapi/glthread.h48
-rw-r--r--src/mesa/main/api_arrayelt.c96
-rw-r--r--src/mesa/main/api_validate.c2
-rwxr-xr-xsrc/mesa/main/context.c2
-rw-r--r--src/mesa/main/dlist.c2
-rw-r--r--src/mesa/main/drawpix.c2
-rw-r--r--src/mesa/main/framebuffer.c2
-rw-r--r--src/mesa/main/get.c4
-rw-r--r--src/mesa/main/image.c6
-rw-r--r--src/mesa/main/light.c4
-rw-r--r--src/mesa/main/mipmap.c2
-rw-r--r--src/mesa/main/pixel.c4
-rw-r--r--src/mesa/main/queryobj.c4
-rw-r--r--src/mesa/main/rastpos.c2
-rw-r--r--src/mesa/main/texenvprogram.c10
-rw-r--r--src/mesa/shader/prog_execute.c6
-rw-r--r--src/mesa/shader/prog_statevars.c10
-rw-r--r--src/mesa/shader/prog_uniform.c2
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/state_tracker/st_atom_pixeltransfer.c2
-rw-r--r--src/mesa/state_tracker/st_atom_scissor.c8
-rw-r--r--src/mesa/state_tracker/st_atom_viewport.c12
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c38
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c28
-rw-r--r--src/mesa/vbo/vbo_exec_array.c2
-rw-r--r--src/mesa/vbo/vbo_save_api.c3
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c2
202 files changed, 18996 insertions, 3176 deletions
diff --git a/Makefile b/Makefile
index 1ec8ce7cba..9b3be43d50 100644
--- a/Makefile
+++ b/Makefile
@@ -108,6 +108,7 @@ linux-dri-x86 \
linux-dri-x86-64 \
linux-dri-ppc \
linux-dri-xcb \
+linux-egl \
linux-indirect \
linux-fbdev \
linux-glide \
diff --git a/SConstruct b/SConstruct
index e7c10fcf52..549ff647ea 100644
--- a/SConstruct
+++ b/SConstruct
@@ -30,14 +30,15 @@ import common
# Configuration options
if common.default_platform in ('linux', 'freebsd', 'darwin'):
- default_statetrackers = 'mesa'
+ default_statetrackers = 'all'
default_drivers = 'softpipe,failover,i915simple,i965simple'
default_winsys = 'xlib'
elif common.default_platform in ('winddk',):
- default_statetrackers = 'none'
+ default_statetrackers = 'all'
default_drivers = 'softpipe,i915simple'
- default_winsys = 'none'
+ default_winsys = 'all'
else:
+ default_statetrackers = 'all'
default_drivers = 'all'
default_winsys = 'all'
@@ -48,7 +49,7 @@ opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetra
opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers,
['softpipe', 'failover', 'i915simple', 'i965simple', 'cell']))
opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys,
- ['xlib', 'intel']))
+ ['xlib', 'intel', 'gdi']))
env = Environment(
options = opts,
@@ -85,7 +86,7 @@ Export([
# TODO: auto-detect as much as possible
if platform == 'winddk':
- env.Tool('winddk', ['.'])
+ env.Tool('winddk', ['scons'])
env.Append(CPPPATH = [
env['SDK_INC_PATH'],
@@ -94,6 +95,9 @@ if platform == 'winddk':
env['CRT_INC_PATH'],
])
+if platform == 'wince':
+ env.Tool('evc', ['scons'])
+
common.generate(env)
diff --git a/common.py b/common.py
index d3c0261d71..b6251d3960 100644
--- a/common.py
+++ b/common.py
@@ -34,7 +34,7 @@ default_machine = _machine_map.get(default_machine, 'generic')
if default_platform in ('linux', 'freebsd', 'darwin'):
default_dri = 'yes'
-elif default_platform in ('winddk', 'windows'):
+elif default_platform in ('winddk', 'windows', 'wince'):
default_dri = 'no'
else:
default_dri = 'no'
@@ -58,7 +58,7 @@ def AddOptions(opts):
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', default_platform,
- allowed_values=('linux', 'cell', 'windows', 'winddk')))
+ allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince')))
opts.Add(BoolOption('llvm', 'use LLVM', 'no'))
opts.Add(BoolOption('dri', 'build DRI drivers', default_dri))
@@ -149,7 +149,7 @@ def generate(env):
platform = env['platform']
x86 = env['machine'] == 'x86'
gcc = env['platform'] in ('linux', 'freebsd', 'darwin')
- msvc = env['platform'] in ('windows', 'winddk')
+ msvc = env['platform'] in ('windows', 'winddk', 'wince')
# C preprocessor options
cppdefines = []
@@ -196,10 +196,25 @@ def generate(env):
]
if debug:
cppdefines += [('DBG', 1)]
+ if platform == 'wince':
+ cppdefines += [
+ ('_WIN32_WCE', '500'),
+ 'WCE_PLATFORM_STANDARDSDK_500',
+ '_i386_',
+ ('UNDER_CE', '500'),
+ 'UNICODE',
+ '_UNICODE',
+ '_X86_',
+ 'x86',
+ '_USRDLL',
+ 'TEST_EXPORTS' ,
+ ]
if platform == 'windows':
- cppdefines += ['PIPE_SUBSYSTEM_USER']
+ cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_USER']
if platform == 'winddk':
- cppdefines += ['PIPE_SUBSYSTEM_KERNEL']
+ cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_DISPLAY']
+ if platform == 'wince':
+ cppdefines += ['PIPE_SUBSYSTEM_WINDOWS_CE']
env.Append(CPPDEFINES = cppdefines)
# C compiler options
@@ -240,10 +255,13 @@ def generate(env):
'/Gh', # enable _penter hook function
'/GH', # enable _pexit hook function
]
+ cflags += [
+ '/W3', # warning level
+ #'/Wp64', # enable 64 bit porting warnings
+ ]
if platform == 'windows':
cflags += [
# TODO
- #'/Wp64', # enable 64 bit porting warnings
]
if platform == 'winddk':
cflags += [
@@ -251,7 +269,6 @@ def generate(env):
'/Zp8', # 8bytes struct member alignment
'/Gy', # separate functions for linker
'/Gm-', # disable minimal rebuild
- '/W3', # warning level
'/WX', # treat warnings as errors
'/Gz', # __stdcall Calling convention
'/GX-', # disable C++ EH
@@ -264,8 +281,13 @@ def generate(env):
'/hotpatch', # prepares an image for hotpatching.
#'/Z7', #enable old-style debug info
]
+ if platform == 'wince':
+ cflags += [
+ '/Gs8192',
+ '/GF', # enable read-only string pooling
+ ]
# Put debugging information in a separate .pdb file for each object file as
- # descrived in the scons manpage
+ # described in the scons manpage
env['CCPDBFLAGS'] = '/Zi /Fd${TARGET}.pdb'
env.Append(CFLAGS = cflags)
env.Append(CXXFLAGS = cflags)
diff --git a/configs/linux-dri b/configs/linux-dri
index 67e60cbd4c..cd82c571c7 100644
--- a/configs/linux-dri
+++ b/configs/linux-dri
@@ -59,8 +59,10 @@ SRC_DIRS := egl $(SRC_DIRS)
PROGRAM_DIRS = egl
endif
+
+
DRIVER_DIRS = dri
-WINDOW_SYSTEM=dri
+WINDOW_SYSTEM = dri
GALLIUM_WINSYS_DIRS = dri
# gamma are missing because they have not been converted to use the new
diff --git a/configs/linux-egl b/configs/linux-egl
new file mode 100644
index 0000000000..e906806f4b
--- /dev/null
+++ b/configs/linux-egl
@@ -0,0 +1,65 @@
+# -*-makefile-*-
+# Configuration for linux-dri: Linux DRI hardware drivers for XFree86 & others
+
+include $(TOP)/configs/default
+
+CONFIG_NAME = linux-dri
+
+# Compiler and flags
+CC = gcc
+CXX = g++
+
+#MKDEP = /usr/X11R6/bin/makedepend
+#MKDEP = gcc -M
+#MKDEP_OPTIONS = -MF depend
+
+OPT_FLAGS = -O -g
+PIC_FLAGS = -fPIC
+
+# Add '-DGLX_USE_TLS' to ARCH_FLAGS to enable TLS support.
+ARCH_FLAGS ?=
+
+DEFINES = -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE \
+ -D_BSD_SOURCE -D_GNU_SOURCE \
+ -DPTHREADS -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER \
+ -DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING \
+ -DHAVE_ALIAS -DHAVE_POSIX_MEMALIGN
+
+X11_INCLUDES = -I/usr/X11R6/include
+
+CFLAGS = -Wall -Wmissing-prototypes -std=c99 -ffast-math \
+ $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES) $(ASM_FLAGS)
+
+CXXFLAGS = -Wall $(OPT_FLAGS) $(PIC_FLAGS) $(ARCH_FLAGS) $(DEFINES)
+
+
+MESA_ASM_SOURCES =
+
+# Library/program dependencies
+EXTRA_LIB_PATH=-L/usr/X11R6/lib
+
+LIBDRM_CFLAGS = $(shell pkg-config --cflags libdrm)
+LIBDRM_LIB = $(shell pkg-config --libs libdrm)
+DRI_LIB_DEPS = $(EXTRA_LIB_PATH) -lm -lpthread -lexpat -ldl $(LIBDRM_LIB)
+GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
+ -lm -lpthread -ldl \
+ $(LIBDRM_LIB)
+
+
+# This is now 0 by default since it seems to confuse the hell out of people
+# and generate a lot of extra noise on bugzilla. If you need to build with
+# EGL, do 'make linux-dri USING_EGL=1'
+
+USING_EGL=0
+
+# Directories
+SRC_DIRS = gallium mesa gallium/winsys glu egl
+PROGRAM_DIRS = egl
+
+DRIVER_DIRS = dri
+WINDOW_SYSTEM = dri
+GALLIUM_WINSYS_DIRS = egl_drm
+
+# gamma are missing because they have not been converted to use the new
+# interface.
+DRI_DIRS = intel
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
new file mode 100644
index 0000000000..3d71910e5f
--- /dev/null
+++ b/include/EGL/eglplatform.h
@@ -0,0 +1,62 @@
+/* -*- mode: c; tab-width: 8; -*- */
+/* vi: set sw=4 ts=8: */
+/* Platform-specific types and definitions for egl.h */
+
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/* Windows calling convention boilerplate */
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#include <sys/types.h>
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * On Windows, EGLAPIENTRY can be defined like APIENTRY.
+ * On most other platforms, it should be empty.
+ */
+
+#ifndef EGLAPIENTRY
+#define EGLAPIENTRY
+#endif
+#ifndef EGLAPIENTRYP
+#define EGLAPIENTRYP EGLAPIENTRY *
+#endif
+#ifndef EGLAPI
+#define EGLAPI extern
+#endif
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ */
+
+/* Unix (tentative)
+ #include <X headers>
+ typedef Display *NativeDisplayType;
+ - or maybe, if encoding "hostname:display.head"
+ typedef const char *NativeWindowType;
+ etc.
+ */
+
+/** BEGIN Added for X (Mesa) **/
+#include <X11/Xlib.h>
+typedef Display *NativeDisplayType;
+typedef Window NativeWindowType;
+typedef Pixmap NativePixmapType;
+/** END Added for X (Mesa) **/
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef NativeDisplayType EGLNativeDisplayType;
+typedef NativePixmapType EGLNativePixmapType;
+typedef NativeWindowType EGLNativeWindowType;
+
+#endif /* __eglplatform_h */
diff --git a/include/GLES/egl.h b/include/GLES/egl.h
index a211bbc3be..e33a315723 100644
--- a/include/GLES/egl.h
+++ b/include/GLES/egl.h
@@ -1,265 +1,300 @@
+/* -*- mode: c; tab-width: 8; -*- */
+/* vi: set sw=4 ts=8: */
+/* Reference version of egl.h for EGL 1.4.
+ * Last modified 2008/05/02
+ */
+
#ifndef __egl_h_
#define __egl_h_
-/*
-** Copyright 2002-2003 Promoters of the Khronos Group (3Dlabs, ARM Ltd.,
-** ATI Technologies, Inc., Discreet, Ericsson Mobile, Imagination
-** Technologies Group plc, Motorola, Inc., Nokia, Silicon Graphics, Inc.,
-** SK Telecom, and Sun Microsystems).
-**
-** This document is protected by copyright, and contains information
-** proprietary to The Khronos Group. Any copying, adaptation, distribution,
-** public performance, or public display of this document without the
-** express written consent of the copyright holders is strictly prohibited.
-** The receipt or possession of this document does not convey any rights to
-** reproduce, disclose, or distribute its contents, or to manufacture, use,
-** or sell anything that it may describe, in whole or in part.
-*/
-
-#include <GLES/gl.h>
-#include <GLES/egltypes.h>
-
-
-/*
-** Versioning and extensions
-*/
-#define EGL_VERSION_1_0 1
-#define EGL_VERSION_1_1 1
-
-/*
-** Boolean
-*/
-#define EGL_FALSE 0
-#define EGL_TRUE 1
-
-/*
-** Errors
-*/
-#define EGL_SUCCESS 0x3000
-#define EGL_NOT_INITIALIZED 0x3001
-#define EGL_BAD_ACCESS 0x3002
-#define EGL_BAD_ALLOC 0x3003
-#define EGL_BAD_ATTRIBUTE 0x3004
-#define EGL_BAD_CONFIG 0x3005
-#define EGL_BAD_CONTEXT 0x3006
-#define EGL_BAD_CURRENT_SURFACE 0x3007
-#define EGL_BAD_DISPLAY 0x3008
-#define EGL_BAD_MATCH 0x3009
-#define EGL_BAD_NATIVE_PIXMAP 0x300A
-#define EGL_BAD_NATIVE_WINDOW 0x300B
-#define EGL_BAD_PARAMETER 0x300C
-#define EGL_BAD_SURFACE 0x300D
-#define EGL_CONTEXT_LOST 0x300E
-/* 0x300F - 0x301F reserved for additional errors. */
-
-/*
-** Config attributes
-*/
-#define EGL_BUFFER_SIZE 0x3020
-#define EGL_ALPHA_SIZE 0x3021
-#define EGL_BLUE_SIZE 0x3022
-#define EGL_GREEN_SIZE 0x3023
-#define EGL_RED_SIZE 0x3024
-#define EGL_DEPTH_SIZE 0x3025
-#define EGL_STENCIL_SIZE 0x3026
-#define EGL_CONFIG_CAVEAT 0x3027
-#define EGL_CONFIG_ID 0x3028
-#define EGL_LEVEL 0x3029
-#define EGL_MAX_PBUFFER_HEIGHT 0x302A
-#define EGL_MAX_PBUFFER_PIXELS 0x302B
-#define EGL_MAX_PBUFFER_WIDTH 0x302C
-#define EGL_NATIVE_RENDERABLE 0x302D
-#define EGL_NATIVE_VISUAL_ID 0x302E
-#define EGL_NATIVE_VISUAL_TYPE 0x302F
-/*#define EGL_PRESERVED_RESOURCES 0x3030*/
-#define EGL_SAMPLES 0x3031
-#define EGL_SAMPLE_BUFFERS 0x3032
-#define EGL_SURFACE_TYPE 0x3033
-#define EGL_TRANSPARENT_TYPE 0x3034
-#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
-#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
-#define EGL_TRANSPARENT_RED_VALUE 0x3037
-#define EGL_NONE 0x3038 /* Also a config value */
-#define EGL_BIND_TO_TEXTURE_RGB 0x3039
-#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
-#define EGL_MIN_SWAP_INTERVAL 0x303B
-#define EGL_MAX_SWAP_INTERVAL 0x303C
-
-/*
-** Config values
-*/
-#define EGL_DONT_CARE ((EGLint) -1)
-
-#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
-#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* " */
-#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
-#define EGL_NO_TEXTURE 0x305C /* EGL_TEXTURE_FORMAT/TARGET value */
-#define EGL_TEXTURE_RGB 0x305D /* EGL_TEXTURE_FORMAT value */
-#define EGL_TEXTURE_RGBA 0x305E /* " */
-#define EGL_TEXTURE_2D 0x305F /* EGL_TEXTURE_TARGET value */
-
-/*
-** Config attribute mask bits
-*/
-#define EGL_PBUFFER_BIT 0x01 /* EGL_SURFACE_TYPE mask bit */
-#define EGL_PIXMAP_BIT 0x02 /* " */
-#define EGL_WINDOW_BIT 0x04 /* " */
-
-/*
-** String names
-*/
-#define EGL_VENDOR 0x3053 /* eglQueryString target */
-#define EGL_VERSION 0x3054 /* " */
-#define EGL_EXTENSIONS 0x3055 /* " */
-
-/*
-** Surface attributes
-*/
-#define EGL_HEIGHT 0x3056
-#define EGL_WIDTH 0x3057
-#define EGL_LARGEST_PBUFFER 0x3058
-#define EGL_TEXTURE_FORMAT 0x3080 /* For pbuffers bound as textures */
-#define EGL_TEXTURE_TARGET 0x3081 /* " */
-#define EGL_MIPMAP_TEXTURE 0x3082 /* " */
-#define EGL_MIPMAP_LEVEL 0x3083 /* " */
-
-/*
-** BindTexImage / ReleaseTexImage buffer target
-*/
-#define EGL_BACK_BUFFER 0x3084
-
-/*
-** Current surfaces
-*/
-#define EGL_DRAW 0x3059
-#define EGL_READ 0x305A
-
-/*
-** Engines
-*/
-#define EGL_CORE_NATIVE_ENGINE 0x305B
-
-/* 0x305C-0x3FFFF reserved for future use */
-
-/*
-** Functions
-*/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-GLAPI EGLint APIENTRY eglGetError (void);
-
-GLAPI EGLDisplay APIENTRY eglGetDisplay (NativeDisplayType display);
-GLAPI EGLBoolean APIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
-GLAPI EGLBoolean APIENTRY eglTerminate (EGLDisplay dpy);
-GLAPI const char * APIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
-GLAPI void (APIENTRY * eglGetProcAddress (const char *procname))();
-
-GLAPI EGLBoolean APIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-GLAPI EGLBoolean APIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-GLAPI EGLBoolean APIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
-
-GLAPI EGLSurface APIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-GLAPI EGLSurface APIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-GLAPI EGLSurface APIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-GLAPI EGLBoolean APIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
-GLAPI EGLBoolean APIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
-
-/* EGL 1.1 render-to-texture APIs */
-GLAPI EGLBoolean APIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-GLAPI EGLBoolean APIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-GLAPI EGLBoolean APIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
-/* EGL 1.1 swap control API */
-GLAPI EGLBoolean APIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
-
-GLAPI EGLContext APIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-GLAPI EGLBoolean APIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
-GLAPI EGLBoolean APIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-GLAPI EGLContext APIENTRY eglGetCurrentContext (void);
-GLAPI EGLSurface APIENTRY eglGetCurrentSurface (EGLint readdraw);
-GLAPI EGLDisplay APIENTRY eglGetCurrentDisplay (void);
-GLAPI EGLBoolean APIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
-
-GLAPI EGLBoolean APIENTRY eglWaitGL (void);
-GLAPI EGLBoolean APIENTRY eglWaitNative (EGLint engine);
-GLAPI EGLBoolean APIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface draw);
-GLAPI EGLBoolean APIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+/* All platform-dependent types and macro boilerplate (such as EGLAPI
+ * and EGLAPIENTRY) should go in eglplatform.h.
+ */
+#include <EGL/eglplatform.h>
#ifdef __cplusplus
-}
+extern "C" {
#endif
-#endif /* ___egl_h_ */
-
-
+/* EGL Types */
+typedef int32_t EGLint;
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+
+/* EGL Versioning */
+#define EGL_VERSION_1_0 1
+#define EGL_VERSION_1_1 1
+#define EGL_VERSION_1_2 1
+#define EGL_VERSION_1_3 1
+#define EGL_VERSION_1_4 1
+
+/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
+ * enums are assigned unique values starting at 0x3000.
+ */
+
+/* EGL aliases */
+#define EGL_FALSE 0
+#define EGL_TRUE 1
+
+/* Out-of-band handle values */
+#define EGL_DEFAULT_DISPLAY ((void *)0)
+#define EGL_NO_CONTEXT ((EGLContext)0)
+#define EGL_NO_DISPLAY ((EGLDisplay)0)
+#define EGL_NO_SURFACE ((EGLSurface)0)
+
+/* Out-of-band attribute value */
+#define EGL_DONT_CARE ((EGLint)-1)
+
+/* Errors / GetError return values */
+#define EGL_SUCCESS 0x3000
+#define EGL_NOT_INITIALIZED 0x3001
+#define EGL_BAD_ACCESS 0x3002
+#define EGL_BAD_ALLOC 0x3003
+#define EGL_BAD_ATTRIBUTE 0x3004
+#define EGL_BAD_CONFIG 0x3005
+#define EGL_BAD_CONTEXT 0x3006
+#define EGL_BAD_CURRENT_SURFACE 0x3007
+#define EGL_BAD_DISPLAY 0x3008
+#define EGL_BAD_MATCH 0x3009
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
+#define EGL_BAD_NATIVE_WINDOW 0x300B
+#define EGL_BAD_PARAMETER 0x300C
+#define EGL_BAD_SURFACE 0x300D
+#define EGL_CONTEXT_LOST 0x300E /* EGL 1.1 - IMG_power_management */
+
+/* Reserved 0x300F-0x301F for additional errors */
+
+/* Config attributes */
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_RED_SIZE 0x3024
+#define EGL_DEPTH_SIZE 0x3025
+#define EGL_STENCIL_SIZE 0x3026
+#define EGL_CONFIG_CAVEAT 0x3027
+#define EGL_CONFIG_ID 0x3028
+#define EGL_LEVEL 0x3029
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
+#define EGL_NATIVE_RENDERABLE 0x302D
+#define EGL_NATIVE_VISUAL_ID 0x302E
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
+#define EGL_PRESERVED_RESOURCES 0x3030
+#define EGL_SAMPLES 0x3031
+#define EGL_SAMPLE_BUFFERS 0x3032
+#define EGL_SURFACE_TYPE 0x3033
+#define EGL_TRANSPARENT_TYPE 0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
+#define EGL_NONE 0x3038 /* Attrib list terminator */
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
+#define EGL_MIN_SWAP_INTERVAL 0x303B
+#define EGL_MAX_SWAP_INTERVAL 0x303C
+#define EGL_LUMINANCE_SIZE 0x303D
+#define EGL_ALPHA_MASK_SIZE 0x303E
+#define EGL_COLOR_BUFFER_TYPE 0x303F
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */
+#define EGL_CONFORMANT 0x3042
+
+/* Reserved 0x3041-0x304F for additional config attributes */
+
+/* Config attribute values */
+#define EGL_SLOW_CONFIG 0x3050 /* EGL_CONFIG_CAVEAT value */
+#define EGL_NON_CONFORMANT_CONFIG 0x3051 /* EGL_CONFIG_CAVEAT value */
+#define EGL_TRANSPARENT_RGB 0x3052 /* EGL_TRANSPARENT_TYPE value */
+#define EGL_RGB_BUFFER 0x308E /* EGL_COLOR_BUFFER_TYPE value */
+#define EGL_LUMINANCE_BUFFER 0x308F /* EGL_COLOR_BUFFER_TYPE value */
+
+/* More config attribute values, for EGL_TEXTURE_FORMAT */
+#define EGL_NO_TEXTURE 0x305C
+#define EGL_TEXTURE_RGB 0x305D
+#define EGL_TEXTURE_RGBA 0x305E
+#define EGL_TEXTURE_2D 0x305F
+
+/* Config attribute mask bits */
+#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */
+
+#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */
+
+/* QueryString targets */
+#define EGL_VENDOR 0x3053
+#define EGL_VERSION 0x3054
+#define EGL_EXTENSIONS 0x3055
+#define EGL_CLIENT_APIS 0x308D
+
+/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
+#define EGL_HEIGHT 0x3056
+#define EGL_WIDTH 0x3057
+#define EGL_LARGEST_PBUFFER 0x3058
+#define EGL_TEXTURE_FORMAT 0x3080
+#define EGL_TEXTURE_TARGET 0x3081
+#define EGL_MIPMAP_TEXTURE 0x3082
+#define EGL_MIPMAP_LEVEL 0x3083
+#define EGL_RENDER_BUFFER 0x3086
+#define EGL_VG_COLORSPACE 0x3087
+#define EGL_VG_ALPHA_FORMAT 0x3088
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
+#define EGL_VERTICAL_RESOLUTION 0x3091
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
+#define EGL_SWAP_BEHAVIOR 0x3093
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
+
+/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_SINGLE_BUFFER 0x3085
+
+/* OpenVG color spaces */
+#define EGL_VG_COLORSPACE_sRGB 0x3089 /* EGL_VG_COLORSPACE value */
+#define EGL_VG_COLORSPACE_LINEAR 0x308A /* EGL_VG_COLORSPACE value */
+
+/* OpenVG alpha formats */
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B /* EGL_ALPHA_FORMAT value */
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C /* EGL_ALPHA_FORMAT value */
+
+/* Constant scale factor by which fractional display resolutions &
+ * aspect ratio are scaled when queried as integer values.
+ */
+#define EGL_DISPLAY_SCALING 10000
+
+/* Unknown display resolution/aspect ratio */
+#define EGL_UNKNOWN ((EGLint)-1)
+
+/* Back buffer swap behaviors */
+#define EGL_BUFFER_PRESERVED 0x3094 /* EGL_SWAP_BEHAVIOR value */
+#define EGL_BUFFER_DESTROYED 0x3095 /* EGL_SWAP_BEHAVIOR value */
+
+/* CreatePbufferFromClientBuffer buffer types */
+#define EGL_OPENVG_IMAGE 0x3096
+
+/* QueryContext targets */
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
+
+/* CreateContext attributes */
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+
+/* Multisample resolution behaviors */
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A /* EGL_MULTISAMPLE_RESOLVE value */
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B /* EGL_MULTISAMPLE_RESOLVE value */
+
+/* BindAPI/QueryAPI targets */
+#define EGL_OPENGL_ES_API 0x30A0
+#define EGL_OPENVG_API 0x30A1
+#define EGL_OPENGL_API 0x30A2
+
+/* GetCurrentSurface targets */
+#define EGL_DRAW 0x3059
+#define EGL_READ 0x305A
+
+/* WaitNative engines */
+#define EGL_CORE_NATIVE_ENGINE 0x305B
+
+/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
+#define EGL_COLORSPACE EGL_VG_COLORSPACE
+#define EGL_ALPHA_FORMAT EGL_VG_ALPHA_FORMAT
+#define EGL_COLORSPACE_sRGB EGL_VG_COLORSPACE_sRGB
+#define EGL_COLORSPACE_LINEAR EGL_VG_COLORSPACE_LINEAR
+#define EGL_ALPHA_FORMAT_NONPRE EGL_VG_ALPHA_FORMAT_NONPRE
+#define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE
+
+/* EGL extensions must request enum blocks from the Khronos
+ * API Registrar, who maintains the enumerant registry. Submit
+ * a bug in Khronos Bugzilla against task "Registry".
+ */
+
+
+
+/* EGL Functions */
+
+EGLAPI EGLint EGLAPIENTRY eglGetError(void);
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
+
+EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value);
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value);
-/* usage
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
- // ----------------------------------------------------------------------
- // Initialization
- // ----------------------------------------------------------------------
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
- HDC hdc = GetDC(0); // the screen or window device context, for example
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
- EGLDisplay display = eglGetDisplay(hdc);
-
- EGLint major, minor;
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
+ EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list);
- if (!eglInitialize(display, &major, &minor)) {
- // could not initialize display
- }
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
- EGLConfig configs[10];
- EGLint matchingConfigs;
- EGLint attribList[] = { 0 }; // extend this
- if (!eglChooseConfig(display, attribList, &configs, 10, &matchingConfigs)) {
- // could not choose config
- }
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
- if (matchingConfigs < 1) {
- // did not find a suitable configuration
- }
- EGLConfig config = configs[0]; // pick any
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
- EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
-
- // test for error
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value);
- EGLContext context = eglCreateContext(display, config, 0, attribList);
-
- // test for error
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target);
- // ----------------------------------------------------------------------
- // Rendering Loop
- // ----------------------------------------------------------------------
+EGLAPI void (* EGLAPIENTRY eglGetProcAddress(const char *procname))(void);
- eglMakeCurrent(display, surface, surface, context);
-
- // actual GL rendering goes here
-
- eglWait();
- eglSwapBuffers(display, surface);
-
- // ----------------------------------------------------------------------
- // Cleanup
- // ----------------------------------------------------------------------
-
-
- if (!eglDestoyContext(display, context)) {
- // error deallocating context
- }
-
- if (!eglDestroySurface(display, surface)) {
- // error deallocating surface
- }
-
- if (!eglTerminate(display)) {
- // error while cleaning up display
- }
+#ifdef __cplusplus
+}
+#endif
-
-*/
+#endif /* __egl_h_ */
diff --git a/include/GLES/eglext.h b/include/GLES/eglext.h
new file mode 100644
index 0000000000..a4698ccd16
--- /dev/null
+++ b/include/GLES/eglext.h
@@ -0,0 +1,186 @@
+#ifndef __eglext_h_
+#define __eglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#include <EGL/eglplatform.h>
+
+/*************************************************************/
+
+/* Header file version number */
+/* eglext.h last updated 2007/11/20 */
+/* Current version at http://www.khronos.org/registry/egl/ */
+#define EGL_EGLEXT_VERSION 1
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR 0x3042 /* EGLConfig attribute */
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 /* EGL_SURFACE_TYPE bitfield */
+#endif
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR 0x0001 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 /* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_LOCK_SURFACE_BIT_KHR 0x0080 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100 /* EGL_SURFACE_TYPE bitfield */
+#define EGL_MATCH_FORMAT_KHR 0x3043 /* EGLConfig attribute */
+#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGB_565_KHR 0x30C1 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_KHR 0x30C3 /* EGL_MATCH_FORMAT_KHR value */
+#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 /* eglLockSurfaceKHR attribute */
+#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 /* eglLockSurfaceKHR attribute */
+#define EGL_BITMAP_POINTER_KHR 0x30C6 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PITCH_KHR 0x30C7 /* eglQuerySurface attribute */
+#define EGL_BITMAP_ORIGIN_KHR 0x30C8 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9 /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC /* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD /* eglQuerySurface attribute */
+#define EGL_LOWER_LEFT_KHR 0x30CE /* EGL_BITMAP_ORIGIN_KHR value */
+#define EGL_UPPER_LEFT_KHR 0x30CF /* EGL_BITMAP_ORIGIN_KHR value */
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
+#endif
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0 /* eglCreateImageKHR target */
+typedef void *EGLImageKHR;
+extern const EGLImageKHR EGL_NO_IMAGE_KHR;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, EGLint *attr_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, EGLint *attr_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#endif
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR 0x30BA /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC /* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8 /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR 0x30B2 /* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD /* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */
+#endif
+
+
+/* EGL_MESA_screen extension >>> PRELIMINARY <<< */
+#ifndef EGL_MESA_screen_surface
+#define EGL_MESA_screen_surface 1
+
+#define EGL_BAD_SCREEN_MESA 0x4000
+#define EGL_BAD_MODE_MESA 0x4001
+#define EGL_SCREEN_COUNT_MESA 0x4002
+#define EGL_SCREEN_POSITION_MESA 0x4003
+#define EGL_SCREEN_POSITION_GRANULARITY_MESA 0x4004
+#define EGL_MODE_ID_MESA 0x4005
+#define EGL_REFRESH_RATE_MESA 0x4006
+#define EGL_OPTIMAL_MESA 0x4007
+#define EGL_INTERLACED_MESA 0x4008
+#define EGL_SCREEN_BIT_MESA 0x08
+
+typedef u_int32_t EGLScreenMESA;
+typedef u_int32_t EGLModeMESA;
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode);
+
+#endif /* EGL_MESA_screen_surface */
+
+
+#ifndef EGL_MESA_copy_context
+#define EGL_MESA_copy_context 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+
+#endif /* EGL_MESA_copy_context */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/GLES/egltypes.h b/include/GLES/egltypes.h
deleted file mode 100644
index ca1f5a9cb3..0000000000
--- a/include/GLES/egltypes.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __egl_types_h_
-#define __egl_types_h_
-
-/*
-** egltypes.h is platform dependent. It defines:
-**
-** - EGL types and resources
-** - Native types
-** - EGL and native handle values
-**
-** EGL types and resources are to be typedef'ed with appropriate platform
-** dependent resource handle types. EGLint must be an integer of at least
-** 32-bit.
-**
-** NativeDisplayType, NativeWindowType and NativePixmapType are to be
-** replaced with corresponding types of the native window system in egl.h.
-**
-** EGL and native handle values must match their types.
-*/
-
-#if (defined(WIN32) || defined(_WIN32_WCE))
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-#endif
-
-// Windows Header Files:
-#include <windows.h>
-
-typedef HDC NativeDisplayType;
-typedef HWND NativeWindowType;
-typedef HBITMAP NativePixmapType;
-
-#define EGL_DEFAULT_DISPLAY GetDC(0)
-
-#elif defined(__SYMBIAN32__)
-
-#include <e32def.h>
-
-class RWindow;
-class CWindowGc;
-class CFbsBitmap;
-
-typedef CWindowGc * NativeDisplayType;
-typedef RWindow * NativeWindowType;
-typedef CFbsBitmap * NativePixmapType;
-
-#define EGL_DEFAULT_DISPLAY ((NativeDisplayType) 0)
-
-#elif defined(__gnu_linux__)
-
-typedef void * NativeDisplayType;
-typedef void * NativeWindowType;
-typedef void * NativePixmapType;
-
-#define EGL_DEFAULT_DISPLAY ((NativeDisplayType) 0)
-
-#else
-
-# error "Unsupported Operating System"
-
-#endif
-
-#ifdef __cplusplus
-
-namespace EGL {
- class Context;
- class Config;
- class Surface;
-}
-
-typedef const EGL::Config * EGLConfig;
-typedef EGL::Surface * EGLSurface;
-typedef EGL::Context * EGLContext;
-
-#else
-
-typedef void * EGLConfig;
-typedef void * EGLSurface;
-typedef void * EGLContext;
-
-#endif
-
-
-/*
-** Types and resources
-*/
-typedef int EGLBoolean;
-typedef int EGLint;
-typedef void * EGLDisplay;
-
-/*
-** EGL and native handle values
-*/
-#define EGL_NO_CONTEXT ((EGLContext)0)
-#define EGL_NO_DISPLAY ((EGLDisplay)0)
-#define EGL_NO_SURFACE ((EGLSurface)0)
-
-
-#endif //ndef __egl_types_h_
diff --git a/progs/egl/Makefile b/progs/egl/Makefile
index 33447a9d57..ae2267f38f 100644
--- a/progs/egl/Makefile
+++ b/progs/egl/Makefile
@@ -13,7 +13,8 @@ PROGRAMS = \
demo2 \
demo3 \
eglinfo \
- eglgears
+ eglgears \
+ xeglgears
.c.o:
@@ -46,7 +47,7 @@ demo3.o: demo3.c $(HEADERS)
eglinfo: eglinfo.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
+ $(CC) $(CFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lGL -lEGL $(LIBDRM_LIB) -o $@
eglinfo.o: eglinfo.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglinfo.c
@@ -59,7 +60,20 @@ eglgears.o: eglgears.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c
+xeglgears: xeglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
+ $(CC) $(CFLAGS) xeglgears.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+
+xeglgears.o: xeglgears.c $(HEADERS)
+ $(CC) -c $(CFLAGS) -I$(TOP)/include xeglgears.c
+
+
clean:
rm -f *.o *~
rm -f *.so
rm -f $(PROGRAMS)
+
+run:
+ LD_LIBRARY_PATH=$(TOP)/lib ./eglgears
+
+debug:
+ LD_LIBRARY_PATH=$(TOP)/lib gdb ./eglgears
diff --git a/progs/egl/demo1.c b/progs/egl/demo1.c
index 9ef17e38b7..52673187c4 100644
--- a/progs/egl/demo1.c
+++ b/progs/egl/demo1.c
@@ -2,7 +2,10 @@
* Exercise EGL API functions
*/
+#define EGL_EGLEXT_PROTOTYPES
+
#include <GLES/egl.h>
+#include <GLES/eglext.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -102,7 +105,7 @@ main(int argc, char *argv[])
/*
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
*/
- EGLDisplay d = eglGetDisplay("!fb_dri");
+ EGLDisplay d = eglGetDisplay((EGLNativeDisplayType) "!EGL_i915");
assert(d);
if (!eglInitialize(d, &maj, &min)) {
diff --git a/progs/egl/demo2.c b/progs/egl/demo2.c
index 17bbca6158..c95aaafa13 100644
--- a/progs/egl/demo2.c
+++ b/progs/egl/demo2.c
@@ -2,35 +2,54 @@
* Exercise EGL API functions
*/
+#define EGL_EGLEXT_PROTOTYPES
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <GLES/egl.h>
+#include <GLES/eglext.h>
+#include <GLES/gl.h>
/*#define FRONTBUFFER*/
-static void _subset_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+static void _subset_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
+ GLfloat r, GLfloat g, GLfloat b)
{
- glBegin( GL_QUADS );
- glVertex2f( x1, y1 );
- glVertex2f( x2, y1 );
- glVertex2f( x2, y2 );
- glVertex2f( x1, y2 );
- glEnd();
+ GLfloat v[4][2], c[4][4];
+ int i;
+
+ v[0][0] = x1; v[0][1] = y1;
+ v[1][0] = x2; v[1][1] = y1;
+ v[2][0] = x2; v[2][1] = y2;
+ v[3][0] = x1; v[3][1] = y2;
+
+ for (i = 0; i < 4; i++) {
+ c[i][0] = r;
+ c[i][1] = g;
+ c[i][2] = b;
+ c[i][3] = 1.0;
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, v);
+ glColorPointer(4, GL_FLOAT, 0, v);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
}
static void redraw(EGLDisplay dpy, EGLSurface surf, int rot)
{
- printf("Redraw event\n");
+ GLfloat r, g, b;
-#ifdef FRONTBUFFER
- glDrawBuffer( GL_FRONT );
-#else
- glDrawBuffer( GL_BACK );
-#endif
+ printf("Redraw event\n");
glClearColor( rand()/(float)RAND_MAX,
rand()/(float)RAND_MAX,
@@ -39,13 +58,14 @@ static void redraw(EGLDisplay dpy, EGLSurface surf, int rot)
glClear( GL_COLOR_BUFFER_BIT );
- glColor3f( rand()/(float)RAND_MAX,
- rand()/(float)RAND_MAX,
- rand()/(float)RAND_MAX );
+ r = rand()/(float)RAND_MAX;
+ g = rand()/(float)RAND_MAX;
+ b = rand()/(float)RAND_MAX;
+
glPushMatrix();
glRotatef(rot, 0, 0, 1);
glScalef(.5, .5, .5);
- _subset_Rectf( -1, -1, 1, 1 );
+ _subset_Rectf( -1, -1, 1, 1, r, g, b );
glPopMatrix();
#ifdef FRONTBUFFER
@@ -102,7 +122,7 @@ main(int argc, char *argv[])
/*
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
*/
- EGLDisplay d = eglGetDisplay("!fb_dri");
+ EGLDisplay d = eglGetDisplay((EGLNativeDisplayType) "!EGL_i915");
assert(d);
if (!eglInitialize(d, &maj, &min)) {
@@ -161,7 +181,6 @@ main(int argc, char *argv[])
}
glViewport(0, 0, 1024, 768);
- glDrawBuffer( GL_FRONT );
glClearColor( 0,
1.0,
diff --git a/progs/egl/demo3.c b/progs/egl/demo3.c
index 9edf7c952b..6ea7578793 100644
--- a/progs/egl/demo3.c
+++ b/progs/egl/demo3.c
@@ -3,6 +3,7 @@
*/
#include <GLES/egl.h>
+#include <GL/gl.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -576,7 +577,7 @@ main(int argc, char *argv[])
/*
EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
*/
- EGLDisplay d = eglGetDisplay(":0");
+ EGLDisplay d = eglGetDisplay("!EGL_i915");
assert(d);
if (!eglInitialize(d, &maj, &min)) {
diff --git a/progs/egl/eglgears.c b/progs/egl/eglgears.c
index 9feee20d88..a004cb7e86 100644
--- a/progs/egl/eglgears.c
+++ b/progs/egl/eglgears.c
@@ -27,13 +27,16 @@
* Program runs for 5 seconds then exits, outputing framerate to console
*/
+#define EGL_EGLEXT_PROTOTYPES
+
+#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/gl.h>
#include <GLES/egl.h>
-#include <assert.h>
+#include <GLES/eglext.h>
#define MAX_CONFIGS 10
#define MAX_MODES 100
@@ -385,7 +388,7 @@ main(int argc, char *argv[])
}
/* DBR : Create EGL context/surface etc */
- d = eglGetDisplay(":0");
+ d = eglGetDisplay((EGLNativeDisplayType)"!EGL_i915");
assert(d);
if (!eglInitialize(d, &maj, &min)) {
diff --git a/progs/egl/eglinfo.c b/progs/egl/eglinfo.c
index f9c2475445..442de5d63f 100644
--- a/progs/egl/eglinfo.c
+++ b/progs/egl/eglinfo.c
@@ -140,7 +140,7 @@ main(int argc, char *argv[])
{
int maj, min;
/*EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);*/
- EGLDisplay d = eglGetDisplay(":0");
+ EGLDisplay d = eglGetDisplay("!EGL_i915");
if (!eglInitialize(d, &maj, &min)) {
printf("eglinfo: eglInitialize failed\n");
@@ -150,6 +150,9 @@ main(int argc, char *argv[])
printf("EGL API version: %d.%d\n", maj, min);
printf("EGL vendor string: %s\n", eglQueryString(d, EGL_VENDOR));
printf("EGL version string: %s\n", eglQueryString(d, EGL_VERSION));
+#ifdef EGL_VERSION_1_2
+ printf("EGL client APIs: %s\n", eglQueryString(d, EGL_CLIENT_APIS));
+#endif
printf("EGL extensions string:\n");
printf(" %s\n", eglQueryString(d, EGL_EXTENSIONS));
printf("\n");
diff --git a/progs/egl/xeglgears.c b/progs/egl/xeglgears.c
new file mode 100644
index 0000000000..519d4bb692
--- /dev/null
+++ b/progs/egl/xeglgears.c
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Ported to X/EGL/GLES. XXX Actually, uses full OpenGL ATM.
+ * Brian Paul
+ * 30 May 2008
+ */
+
+/*
+ * Command line options:
+ * -info print GL implementation information
+ *
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <GL/gl.h>
+#include <GLES/egl.h>
+
+
+#define BENCHMARK
+
+#ifdef BENCHMARK
+
+/* XXX this probably isn't very portable */
+
+#include <sys/time.h>
+#include <unistd.h>
+
+/* return current time (in seconds) */
+static double
+current_time(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+#else /*BENCHMARK*/
+
+/* dummy */
+static double
+current_time(void)
+{
+ /* update this function for other platforms! */
+ static double t = 0.0;
+ static int warn = 1;
+ if (warn) {
+ fprintf(stderr, "Warning: current_time() not implemented!!\n");
+ warn = 0;
+ }
+ return t += 1.0;
+}
+
+#endif /*BENCHMARK*/
+
+
+
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+
+static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
+static GLint gear1, gear2, gear3;
+static GLfloat angle = 0.0;
+
+static GLboolean fullscreen = GL_FALSE; /* Create a single fullscreen window */
+
+
+/*
+ *
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void
+gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ da = 2.0 * M_PI / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ u = r2 * cos(angle + da) - r1 * cos(angle);
+ v = r2 * sin(angle + da) - r1 * sin(angle);
+ len = sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+ v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+
+ glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
+ glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
+
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ }
+ glEnd();
+}
+
+
+static void
+draw(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ glPushMatrix();
+ glTranslatef(-3.0, -2.0, 0.0);
+ glRotatef(angle, 0.0, 0.0, 1.0);
+ glCallList(gear1);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(3.1, -2.0, 0.0);
+ glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
+ glCallList(gear2);
+ glPopMatrix();
+
+ glPushMatrix();
+ glTranslatef(-3.1, 4.2, 0.0);
+ glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
+ glCallList(gear3);
+ glPopMatrix();
+
+ glPopMatrix();
+}
+
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+ GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+}
+
+
+
+static void
+init(void)
+{
+ static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
+ static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
+ static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
+ static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ /* make the gears */
+ gear1 = glGenLists(1);
+ glNewList(gear1, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1.0, 4.0, 1.0, 20, 0.7);
+ glEndList();
+
+ gear2 = glGenLists(1);
+ glNewList(gear2, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(0.5, 2.0, 2.0, 10, 0.7);
+ glEndList();
+
+ gear3 = glGenLists(1);
+ glNewList(gear3, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
+ gear(1.3, 2.0, 0.5, 10, 0.7);
+ glEndList();
+
+ glEnable(GL_NORMALIZE);
+
+ glClearColor(0.2, 0.2, 0.2, 0.0);
+}
+
+
+/*
+ * Create an RGB, double-buffered X window.
+ * Return the window and context handles.
+ */
+static void
+make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
+ const char *name,
+ int x, int y, int width, int height,
+ Window *winRet,
+ EGLContext *ctxRet,
+ EGLSurface *surfRet)
+{
+ static const EGLint attribs[] = {
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ /*EGL_DOUBLEBUFFER,*/
+ EGL_DEPTH_SIZE, 1,
+ EGL_NONE
+ };
+
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ XVisualInfo *visInfo, visTemplate;
+ int num_visuals;
+ EGLContext ctx;
+ EGLConfig config;
+ EGLint num_configs;
+
+ scrnum = DefaultScreen( x_dpy );
+ root = RootWindow( x_dpy, scrnum );
+
+ if (fullscreen) {
+ x = 0; y = 0;
+ width = DisplayWidth( x_dpy, scrnum );
+ height = DisplayHeight( x_dpy, scrnum );
+ }
+
+ if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+ printf("Error: couldn't get an EGL visual config\n");
+ exit(1);
+ }
+
+ /* choose X window visual similar to EGL config */
+ visTemplate.screen = DefaultScreen(x_dpy);
+ visTemplate.depth = 32; /* 24? */
+ visInfo = XGetVisualInfo(x_dpy,
+ (VisualDepthMask | VisualScreenMask),
+ &visTemplate, &num_visuals);
+ if (!visInfo) {
+ printf("Error: couldn't get X visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ attr.override_redirect = fullscreen;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
+
+ win = XCreateWindow( x_dpy, root, 0, 0, width, height,
+ 0, visInfo->depth, InputOutput,
+ visInfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(x_dpy, win, &sizehints);
+ XSetStandardProperties(x_dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ eglBindAPI(EGL_OPENGL_API);
+
+ ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
+ if (!ctx) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
+
+ XFree(visInfo);
+
+ *winRet = win;
+ *ctxRet = ctx;
+}
+
+
+static void
+event_loop(Display *dpy, Window win,
+ EGLDisplay egl_dpy, EGLSurface egl_surf)
+{
+ while (1) {
+ while (XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+ switch (event.type) {
+ case Expose:
+ /* we'll redraw below */
+ break;
+ case ConfigureNotify:
+ reshape(event.xconfigure.width, event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ {
+ static int frames = 0;
+ static double tRot0 = -1.0, tRate0 = -1.0;
+ double dt, t = current_time();
+ if (tRot0 < 0.0)
+ tRot0 = t;
+ dt = t - tRot0;
+ tRot0 = t;
+
+ /* advance rotation for next frame */
+ angle += 70.0 * dt; /* 70 degrees per second */
+ if (angle > 3600.0)
+ angle -= 3600.0;
+
+ draw();
+ eglSwapBuffers(egl_dpy, egl_surf);
+
+ frames++;
+
+ if (tRate0 < 0.0)
+ tRate0 = t;
+ if (t - tRate0 >= 5.0) {
+ GLfloat seconds = t - tRate0;
+ GLfloat fps = frames / seconds;
+ printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
+ fps);
+ tRate0 = t;
+ frames = 0;
+ }
+ }
+ }
+}
+
+
+static void
+usage(void)
+{
+ printf("Usage:\n");
+ printf(" -display <displayname> set the display to run on\n");
+ printf(" -fullscreen run in fullscreen mode\n");
+ printf(" -info display OpenGL renderer info\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ const int winWidth = 300, winHeight = 300;
+ Display *x_dpy;
+ Window win;
+ EGLSurface egl_surf;
+ EGLContext egl_ctx;
+ EGLDisplay egl_dpy;
+ char *dpyName = NULL;
+ GLboolean printInfo = GL_FALSE;
+ EGLint egl_major, egl_minor;
+ int i;
+ const char *s;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0) {
+ dpyName = argv[i+1];
+ i++;
+ }
+ else if (strcmp(argv[i], "-info") == 0) {
+ printInfo = GL_TRUE;
+ }
+ else if (strcmp(argv[i], "-fullscreen") == 0) {
+ fullscreen = GL_TRUE;
+ }
+ else {
+ usage();
+ return -1;
+ }
+ }
+
+ x_dpy = XOpenDisplay(dpyName);
+ if (!x_dpy) {
+ printf("Error: couldn't open display %s\n",
+ dpyName ? dpyName : getenv("DISPLAY"));
+ return -1;
+ }
+
+ egl_dpy = eglGetDisplay(x_dpy);
+ if (!egl_dpy) {
+ printf("Error: eglGetDisplay() failed\n");
+ return -1;
+ }
+
+ if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
+ printf("Error: eglInitialize() failed\n");
+ return -1;
+ }
+
+ s = eglQueryString(egl_dpy, EGL_VERSION);
+ printf("EGL_VERSION = %s\n", s);
+
+ make_x_window(x_dpy, egl_dpy,
+ "glxgears", 0, 0, winWidth, winHeight,
+ &win, &egl_ctx, &egl_surf);
+
+ XMapWindow(x_dpy, win);
+ eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
+
+ if (printInfo) {
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+ }
+
+ init();
+
+ /* Set initial projection/viewing transformation.
+ * We can't be sure we'll get a ConfigureNotify event when the window
+ * first appears.
+ */
+ reshape(winWidth, winHeight);
+
+ event_loop(x_dpy, win, egl_dpy, egl_surf);
+
+ glDeleteLists(gear1, 1);
+ glDeleteLists(gear2, 1);
+ glDeleteLists(gear3, 1);
+
+ eglDestroyContext(egl_dpy, egl_ctx);
+ eglDestroySurface(egl_dpy, egl_surf);
+ eglTerminate(egl_dpy);
+
+
+ XDestroyWindow(x_dpy, win);
+ XCloseDisplay(x_dpy);
+
+ return 0;
+}
diff --git a/scons/evc.py b/scons/evc.py
new file mode 100644
index 0000000000..22a92607e5
--- /dev/null
+++ b/scons/evc.py
@@ -0,0 +1,108 @@
+"""evc
+
+Tool-specific initialization for Microsoft eMbedded Visual C++.
+
+"""
+
+#
+# Copyright (c) 2001-2007 The SCons Foundation
+# Copyright (c) 2008 Tungsten Graphics, 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.
+#
+
+import os.path
+import re
+import string
+
+import SCons.Action
+import SCons.Builder
+import SCons.Errors
+import SCons.Platform.win32
+import SCons.Tool
+import SCons.Util
+import SCons.Warnings
+
+import msvc_sa
+import mslib_sa
+import mslink_sa
+
+def get_evc_paths(env, version=None):
+ """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
+ of those three environment variables that should be set
+ in order to execute the MSVC tools properly."""
+
+ exe_paths = []
+ lib_paths = []
+ include_paths = []
+
+ # mymic the batch files located in Microsoft eMbedded C++ 4.0\EVC\WCExxx\BIN
+ os_version = os.environ.get('OSVERSION', 'WCE500')
+ platform = os.environ.get('PLATFORM', 'STANDARDSDK_500')
+ wce_root = os.environ.get('WCEROOT', 'C:\\Program Files\\Microsoft eMbedded C++ 4.0')
+ sdk_root = os.environ.get('SDKROOT', 'C:\\Windows CE Tools')
+
+ target_cpu = 'x86'
+ cfg = 'none'
+
+ exe_paths.append( os.path.join(wce_root, 'COMMON', 'EVC', 'bin') )
+ exe_paths.append( os.path.join(wce_root, 'EVC', os_version, 'bin') )
+ include_paths.append( os.path.join(sdk_root, os_version, platform, 'include', target_cpu) )
+ include_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'include') )
+ include_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'include') )
+ lib_paths.append( os.path.join(sdk_root, os_version, platform, 'lib', target_cpu) )
+ lib_paths.append( os.path.join(sdk_root, os_version, platform, 'MFC', 'lib', target_cpu) )
+ lib_paths.append( os.path.join(sdk_root, os_version, platform, 'ATL', 'lib', target_cpu) )
+
+ include_path = string.join( include_paths, os.pathsep )
+ lib_path = string.join(lib_paths, os.pathsep )
+ exe_path = string.join(exe_paths, os.pathsep )
+ return (include_path, lib_path, exe_path)
+
+def generate(env):
+
+ msvc_sa.generate(env)
+ mslib_sa.generate(env)
+ mslink_sa.generate(env)
+
+ if not env.has_key('ENV'):
+ env['ENV'] = {}
+
+ try:
+ include_path, lib_path, exe_path = get_evc_paths(env)
+
+ # since other tools can set these, we just make sure that the
+ # relevant stuff from WINDDK is in there somewhere.
+ env.PrependENVPath('INCLUDE', include_path)
+ env.PrependENVPath('LIB', lib_path)
+ env.PrependENVPath('PATH', exe_path)
+ except (SCons.Util.RegError, SCons.Errors.InternalError):
+ pass
+
+def exists(env):
+ if not msvc_sa.exits(env):
+ return 0
+ if not mslib_sa.exits(env):
+ return 0
+ if not mslink_sa.exits(env):
+ return 0
+ return 1
+
+# vim:set ts=4 sw=4 et:
diff --git a/scons/mslib_sa.py b/scons/mslib_sa.py
new file mode 100644
index 0000000000..da51c574b6
--- /dev/null
+++ b/scons/mslib_sa.py
@@ -0,0 +1,49 @@
+"""mslib_sa
+
+Tool-specific initialization for lib (MicroSoft library archiver).
+
+Based on SCons.Tool.mslib, without the MSVC detection.
+
+"""
+
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
+#
+# 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.
+#
+
+import SCons.Defaults
+import SCons.Tool
+import SCons.Util
+
+def generate(env):
+ """Add Builders and construction variables for lib to an Environment."""
+ SCons.Tool.createStaticLibBuilder(env)
+
+ env['AR'] = 'lib'
+ env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
+ env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
+ env['LIBPREFIX'] = ''
+ env['LIBSUFFIX'] = '.lib'
+
+def exists(env):
+ return env.Detect('lib')
+
+# vim:set ts=4 sw=4 et:
diff --git a/scons/mslink_sa.py b/scons/mslink_sa.py
new file mode 100644
index 0000000000..53331def1a
--- /dev/null
+++ b/scons/mslink_sa.py
@@ -0,0 +1,211 @@
+"""mslink_sa
+
+Tool-specific initialization for the Microsoft linker.
+
+Based on SCons.Tool.mslink, without the MSVS detection.
+
+"""
+
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
+#
+# 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.
+#
+
+import os.path
+
+import SCons.Action
+import SCons.Defaults
+import SCons.Errors
+import SCons.Platform.win32
+import SCons.Tool
+import SCons.Tool.msvc
+import SCons.Util
+
+def pdbGenerator(env, target, source, for_signature):
+ try:
+ return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG']
+ except (AttributeError, IndexError):
+ return None
+
+def windowsShlinkTargets(target, source, env, for_signature):
+ listCmd = []
+ dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
+ if dll: listCmd.append("/out:%s"%dll.get_string(for_signature))
+
+ implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX')
+ if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature))
+
+ return listCmd
+
+def windowsShlinkSources(target, source, env, for_signature):
+ listCmd = []
+
+ deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")
+ for src in source:
+ if src == deffile:
+ # Treat this source as a .def file.
+ listCmd.append("/def:%s" % src.get_string(for_signature))
+ else:
+ # Just treat it as a generic source file.
+ listCmd.append(src)
+ return listCmd
+
+def windowsLibEmitter(target, source, env):
+ SCons.Tool.msvc.validate_vars(env)
+
+ extratargets = []
+ extrasources = []
+
+ dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX")
+ no_import_lib = env.get('no_import_lib', 0)
+
+ if not dll:
+ raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
+
+ insert_def = env.subst("$WINDOWS_INSERT_DEF")
+ if not insert_def in ['', '0', 0] and \
+ not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"):
+
+ # append a def file to the list of sources
+ extrasources.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
+
+ if env.has_key('PDB') and env['PDB']:
+ pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
+ extratargets.append(pdb)
+ target[0].attributes.pdb = pdb
+
+ if not no_import_lib and \
+ not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"):
+ # Append an import library to the list of targets.
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "LIBPREFIX", "LIBSUFFIX"))
+ # and .exp file is created if there are exports from a DLL
+ extratargets.append(
+ env.ReplaceIxes(dll,
+ "SHLIBPREFIX", "SHLIBSUFFIX",
+ "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
+
+ return (target+extratargets, source+extrasources)
+
+def prog_emitter(target, source, env):
+ SCons.Tool.msvc.validate_vars(env)
+
+ extratargets = []
+
+ exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX")
+ if not exe:
+ raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")
+
+ if env.has_key('PDB') and env['PDB']:
+ pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
+ extratargets.append(pdb)
+ target[0].attributes.pdb = pdb
+
+ return (target+extratargets,source)
+
+def RegServerFunc(target, source, env):
+ if env.has_key('register') and env['register']:
+ ret = regServerAction([target[0]], [source[0]], env)
+ if ret:
+ raise SCons.Errors.UserError, "Unable to register %s" % target[0]
+ else:
+ print "Registered %s sucessfully" % target[0]
+ return ret
+ return 0
+
+regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR")
+regServerCheck = SCons.Action.Action(RegServerFunc, None)
+shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}')
+compositeLinkAction = shlibLinkAction + regServerCheck
+
+def generate(env):
+ """Add Builders and construction variables for ar to an Environment."""
+ SCons.Tool.createSharedLibBuilder(env)
+ SCons.Tool.createProgBuilder(env)
+
+ env['SHLINK'] = '$LINK'
+ env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
+ env['_SHLINK_TARGETS'] = windowsShlinkTargets
+ env['_SHLINK_SOURCES'] = windowsShlinkSources
+ env['SHLINKCOM'] = compositeLinkAction
+ env.Append(SHLIBEMITTER = [windowsLibEmitter])
+ env['LINK'] = 'link'
+ env['LINKFLAGS'] = SCons.Util.CLVar('/nologo')
+ env['_PDB'] = pdbGenerator
+ env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $SOURCES.windows")}'
+ env.Append(PROGEMITTER = [prog_emitter])
+ env['LIBDIRPREFIX']='/LIBPATH:'
+ env['LIBDIRSUFFIX']=''
+ env['LIBLINKPREFIX']=''
+ env['LIBLINKSUFFIX']='$LIBSUFFIX'
+
+ env['WIN32DEFPREFIX'] = ''
+ env['WIN32DEFSUFFIX'] = '.def'
+ env['WIN32_INSERT_DEF'] = 0
+ env['WINDOWSDEFPREFIX'] = '${WIN32DEFPREFIX}'
+ env['WINDOWSDEFSUFFIX'] = '${WIN32DEFSUFFIX}'
+ env['WINDOWS_INSERT_DEF'] = '${WIN32_INSERT_DEF}'
+
+ env['WIN32EXPPREFIX'] = ''
+ env['WIN32EXPSUFFIX'] = '.exp'
+ env['WINDOWSEXPPREFIX'] = '${WIN32EXPPREFIX}'
+ env['WINDOWSEXPSUFFIX'] = '${WIN32EXPSUFFIX}'
+
+ env['WINDOWSSHLIBMANIFESTPREFIX'] = ''
+ env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest'
+ env['WINDOWSPROGMANIFESTPREFIX'] = ''
+ env['WINDOWSPROGMANIFESTSUFFIX'] = '${PROGSUFFIX}.manifest'
+
+ env['REGSVRACTION'] = regServerCheck
+ env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32')
+ env['REGSVRFLAGS'] = '/s '
+ env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}'
+
+ # For most platforms, a loadable module is the same as a shared
+ # library. Platforms which are different can override these, but
+ # setting them the same means that LoadableModule works everywhere.
+ SCons.Tool.createLoadableModuleBuilder(env)
+ env['LDMODULE'] = '$SHLINK'
+ env['LDMODULEPREFIX'] = '$SHLIBPREFIX'
+ env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'
+ env['LDMODULEFLAGS'] = '$SHLINKFLAGS'
+ # We can't use '$SHLINKCOM' here because that will stringify the
+ # action list on expansion, and will then try to execute expanded
+ # strings, with the upshot that it would try to execute RegServerFunc
+ # as a command.
+ env['LDMODULECOM'] = compositeLinkAction
+
+def exists(env):
+ platform = env.get('PLATFORM', '')
+ if platform in ('win32', 'cygwin'):
+ # Only explicitly search for a 'link' executable on Windows
+ # systems. Some other systems (e.g. Ubuntu Linux) have an
+ # executable named 'link' and we don't want that to make SCons
+ # think Visual Studio is installed.
+ return env.Detect('link')
+ return None
+
+# vim:set ts=4 sw=4 et:
diff --git a/winddk.py b/scons/msvc_sa.py
index 58de183857..136d305265 100644
--- a/winddk.py
+++ b/scons/msvc_sa.py
@@ -1,18 +1,13 @@
-"""winddk
+"""msvc_sa
-Tool-specific initialization for Microsoft Windows DDK.
+Tool-specific initialization for Microsoft Visual C/C++.
-Based on engine.SCons.Tool.msvc.
-
-There normally shouldn't be any need to import this module directly.
-It will usually be imported through the generic SCons.Tool.Tool()
-selection method.
+Based on SCons.Tool.msvc, without the MSVS detection.
"""
#
-# Copyright (c) 2001-2007 The SCons Foundation
-# Copyright (c) 2008 Tungsten Graphics, Inc.
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -43,52 +38,12 @@ import SCons.Builder
import SCons.Errors
import SCons.Platform.win32
import SCons.Tool
-import SCons.Tool.mslib
-import SCons.Tool.mslink
import SCons.Util
import SCons.Warnings
CSuffixes = ['.c', '.C']
CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
-def get_winddk_paths(env, version=None):
- """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
- of those three environment variables that should be set
- in order to execute the MSVC tools properly."""
-
- WINDDKdir = None
- exe_paths = []
- lib_paths = []
- include_paths = []
-
- if 'BASEDIR' in os.environ:
- WINDDKdir = os.environ['BASEDIR']
- else:
- WINDDKdir = "C:\\WINDDK\\3790.1830"
-
- exe_paths.append( os.path.join(WINDDKdir, 'bin') )
- exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') )
- include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') )
- lib_paths.append( os.path.join(WINDDKdir, 'lib') )
-
- target_os = 'wxp'
- target_cpu = 'i386'
-
- env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os)
- env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt')
- env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os)
- env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os)
-
- env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
- env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu)
- env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
- env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
-
- include_path = string.join( include_paths, os.pathsep )
- lib_path = string.join(lib_paths, os.pathsep )
- exe_path = string.join(exe_paths, os.pathsep )
- return (include_path, lib_path, exe_path)
-
def validate_vars(env):
"""Validate the PCH and PCHSTOP construction variables."""
if env.has_key('PCH') and env['PCH']:
@@ -207,30 +162,12 @@ def generate(env):
env['PCHCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Fo${TARGETS[1]} /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
env['BUILDERS']['PCH'] = pch_builder
- env['AR'] = 'lib'
- env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
- env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
- env['LIBPREFIX'] = ''
- env['LIBSUFFIX'] = '.lib'
-
- SCons.Tool.mslink.generate(env)
-
if not env.has_key('ENV'):
env['ENV'] = {}
-
- try:
- include_path, lib_path, exe_path = get_winddk_paths(env)
-
- # since other tools can set these, we just make sure that the
- # relevant stuff from WINDDK is in there somewhere.
- env.PrependENVPath('INCLUDE', include_path)
- env.PrependENVPath('LIB', lib_path)
- env.PrependENVPath('PATH', exe_path)
- except (SCons.Util.RegError, SCons.Errors.InternalError):
- pass
-
+ if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
+ env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
def exists(env):
return env.Detect('cl')
-# vim:set sw=4 et:
+# vim:set ts=4 sw=4 et:
diff --git a/scons/winddk.py b/scons/winddk.py
new file mode 100644
index 0000000000..be81d12ea9
--- /dev/null
+++ b/scons/winddk.py
@@ -0,0 +1,114 @@
+"""winddk
+
+Tool-specific initialization for Microsoft Windows DDK.
+
+"""
+
+#
+# Copyright (c) 2001-2007 The SCons Foundation
+# Copyright (c) 2008 Tungsten Graphics, 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.
+#
+
+import os.path
+import re
+import string
+
+import SCons.Action
+import SCons.Builder
+import SCons.Errors
+import SCons.Platform.win32
+import SCons.Tool
+import SCons.Util
+import SCons.Warnings
+
+import msvc_sa
+import mslib_sa
+import mslink_sa
+
+def get_winddk_paths(env, version=None):
+ """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
+ of those three environment variables that should be set
+ in order to execute the MSVC tools properly."""
+
+ WINDDKdir = None
+ exe_paths = []
+ lib_paths = []
+ include_paths = []
+
+ if 'BASEDIR' in os.environ:
+ WINDDKdir = os.environ['BASEDIR']
+ else:
+ WINDDKdir = "C:\\WINDDK\\3790.1830"
+
+ exe_paths.append( os.path.join(WINDDKdir, 'bin') )
+ exe_paths.append( os.path.join(WINDDKdir, 'bin', 'x86') )
+ include_paths.append( os.path.join(WINDDKdir, 'inc', 'wxp') )
+ lib_paths.append( os.path.join(WINDDKdir, 'lib') )
+
+ target_os = 'wxp'
+ target_cpu = 'i386'
+
+ env['SDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', target_os)
+ env['CRT_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'crt')
+ env['DDK_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', target_os)
+ env['WDM_INC_PATH'] = os.path.join(WINDDKdir, 'inc', 'ddk', 'wdm', target_os)
+
+ env['SDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
+ env['CRT_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', 'crt', target_cpu)
+ env['DDK_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
+ env['WDM_LIB_PATH'] = os.path.join(WINDDKdir, 'lib', target_os, target_cpu)
+
+ include_path = string.join( include_paths, os.pathsep )
+ lib_path = string.join(lib_paths, os.pathsep )
+ exe_path = string.join(exe_paths, os.pathsep )
+ return (include_path, lib_path, exe_path)
+
+def generate(env):
+
+ msvc_sa.generate(env)
+ mslib_sa.generate(env)
+ mslink_sa.generate(env)
+
+ if not env.has_key('ENV'):
+ env['ENV'] = {}
+
+ try:
+ include_path, lib_path, exe_path = get_winddk_paths(env)
+
+ # since other tools can set these, we just make sure that the
+ # relevant stuff from WINDDK is in there somewhere.
+ env.PrependENVPath('INCLUDE', include_path)
+ env.PrependENVPath('LIB', lib_path)
+ env.PrependENVPath('PATH', exe_path)
+ except (SCons.Util.RegError, SCons.Errors.InternalError):
+ pass
+
+def exists(env):
+ if not msvc_sa.exits(env):
+ return 0
+ if not mslib_sa.exits(env):
+ return 0
+ if not mslink_sa.exits(env):
+ return 0
+ return 1
+
+# vim:set ts=4 sw=4 et:
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c
index 45545755c0..6b8b71d16b 100644
--- a/src/egl/drivers/demo/demo.c
+++ b/src/egl/drivers/demo/demo.c
@@ -21,7 +21,7 @@
typedef struct demo_driver
{
_EGLDriver Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoDriver;
#define DEMO_DRIVER(D) ((DemoDriver *) (D))
@@ -33,7 +33,7 @@ typedef struct demo_driver
typedef struct demo_surface
{
_EGLSurface Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoSurface;
@@ -43,7 +43,7 @@ typedef struct demo_surface
typedef struct demo_context
{
_EGLContext Base; /* base class/object */
- GLuint DemoStuff;
+ unsigned DemoStuff;
} DemoContext;
@@ -152,9 +152,9 @@ demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
- assert(c->Base.Handle);
+ assert(_eglGetContextHandle(&c->Base));
- return c->Base.Handle;
+ return _eglGetContextHandle(&c->Base);
}
@@ -286,7 +286,7 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy)
+_eglMain(_EGLDisplay *dpy, const char *args)
{
DemoDriver *demo;
diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile
index fa3720a16b..bdc683a0c1 100644
--- a/src/egl/drivers/dri/Makefile
+++ b/src/egl/drivers/dri/Makefile
@@ -29,6 +29,8 @@ SOURCES = egldri.c
OBJECTS = $(SOURCES:.c=.o)
+DRM_LIB = `pkg-config --libs libdrm`
+
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -43,7 +45,7 @@ library: $(TOP)/$(LIB_DIR)/libEGLdri.so
$(TOP)/$(LIB_DIR)/libEGLdri.so: $(OBJECTS)
$(TOP)/bin/mklib -o EGLdri -major 1 -minor 0 \
- -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS)
+ -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS) $(DRM_LIB)
clean:
@@ -55,7 +57,7 @@ depend: $(SOURCES) $(HEADERS)
@ rm -f depend
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
- $(SOURCES) $(HEADERS) > /dev/null
+ $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null
include depend
# DO NOT DELETE
diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c
index cab0be2bd1..1a922a7471 100644
--- a/src/egl/drivers/dri/egldri.c
+++ b/src/egl/drivers/dri/egldri.c
@@ -1,5 +1,6 @@
/**
- * Generic EGL driver for DRI.
+ * Generic EGL driver for DRI. This is basically an "adaptor" driver
+ * that allows libEGL to load/use regular DRI drivers.
*
* This file contains all the code needed to interface DRI-based drivers
* with libEGL.
@@ -23,6 +24,7 @@
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
+#include "eglconfigutil.h"
#include "eglsurface.h"
#include "eglscreen.h"
#include "eglglobals.h"
@@ -32,18 +34,72 @@
#include "egldri.h"
const char *sysfs = "/sys/class";
-#define None 0
+
static const int empty_attribute_list[1] = { None };
+
+/**
+ * Given a card number, return the name of the DRI driver to use.
+ * This generally means reading the contents of
+ * /sys/class/drm/cardX/dri_library_name, where X is the card number
+ */
+static EGLBoolean
+driver_name_from_card_number(int card, char *driverName, int maxDriverName)
+{
+ char path[2000];
+ FILE *f;
+ int length;
+
+ snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", sysfs, card);
+
+ f = fopen(path, "r");
+ if (!f)
+ return EGL_FALSE;
+
+ fgets(driverName, maxDriverName, f);
+ fclose(f);
+
+ if ((length = strlen(driverName)) > 1) {
+ /* remove the trailing newline from sysfs */
+ driverName[length - 1] = '\0';
+ strncat(driverName, "_dri", maxDriverName);
+ return EGL_TRUE;
+ }
+ else {
+ return EGL_FALSE;
+ }
+}
+
+
+
/**
* The bootstrap function.
* Return a new driDriver object and plug in API functions.
* This function, in turn, loads a specific DRI driver (ex: r200_dri.so).
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy)
+_eglMain(_EGLDisplay *dpy, const char *args)
{
+#if 1
+ const int card = atoi(args);
+ _EGLDriver *driver = NULL;
+ char driverName[1000];
+
+ if (!driver_name_from_card_number(card, driverName, sizeof(driverName))) {
+ _eglLog(_EGL_WARNING,
+ "Unable to determine driver name for card %d\n", card);
+ return NULL;
+ }
+
+ _eglLog(_EGL_DEBUG, "Driver name: %s\n", driverName);
+
+ driver = _eglOpenDriver(dpy, driverName, args);
+
+ return driver;
+
+#else
+
int length;
char path[NAME_MAX];
struct dirent *dirent;
@@ -58,14 +114,19 @@ _eglMain(_EGLDisplay *dpy)
_eglLog(_EGL_WARNING, "%s DRM devices not found.", path);
return EGL_FALSE;
}
+
+ /* loop over dir entries looking for cardX where "X" is in the
+ * dpy->DriverName ":X" string.
+ */
while ((dirent = readdir(dir))) {
if (strncmp(&dirent->d_name[0], "card", 4) != 0)
continue;
- if (strcmp(&dirent->d_name[4], &dpy->Name[1]) != 0)
+ if (strcmp(&dirent->d_name[4], &driverName[1]) != 0)
continue;
- snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name", sysfs, &dpy->Name[1]);
+ snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name",
+ sysfs, &driverName[1]);
_eglLog(_EGL_INFO, "Opening %s", path);
#if 1
file = fopen(path, "r");
@@ -89,6 +150,7 @@ _eglMain(_EGLDisplay *dpy)
closedir(dir);
return driver;
+#endif
}
@@ -141,7 +203,7 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
- return c->Base.Handle;
+ return _eglGetContextHandle(&c->Base);
}
@@ -152,13 +214,15 @@ _eglDRIMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw,
driDisplay *disp = Lookup_driDisplay(dpy);
driContext *ctx = Lookup_driContext(context);
EGLBoolean b;
+ __DRIid drawBuf = (__DRIid) draw;
+ __DRIid readBuf = (__DRIid) read;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
if (ctx) {
- ctx->driContext.bindContext(disp, 0, read, draw, &ctx->driContext);
+ ctx->driContext.bindContext(disp, 0, drawBuf, readBuf, &ctx->driContext);
}
else {
/* what's this??? */
@@ -190,7 +254,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
#if 0
GLcontext *ctx = NULL; /* this _should_ be OK */
#endif
- GLvisual visMode;
+ __GLcontextModes visMode;
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
assert(conf); /* bad config should be caught earlier */
_eglConfigToContextModesRec(conf, &visMode);
@@ -267,7 +331,8 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
_EGLConfig *config = _eglLookupConfig(drv, dpy, cfg);
driDisplay *disp = Lookup_driDisplay(dpy);
driSurface *surface;
- GLvisual visMode;
+ __GLcontextModes visMode;
+ __DRIid drawBuf;
surface = (driSurface *) calloc(1, sizeof(*surface));
if (!surface) {
@@ -292,8 +357,10 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
/* convert EGLConfig to GLvisual */
_eglConfigToContextModesRec(config, &visMode);
+ drawBuf = (__DRIid) _eglGetSurfaceHandle(&surface->Base);
+
/* Create a new DRI drawable */
- if (!disp->driScreen.createNewDrawable(disp, &visMode, surface->Base.Handle,
+ if (!disp->driScreen.createNewDrawable(disp, &visMode, drawBuf,
&surface->drawable, GLX_WINDOW_BIT,
empty_attribute_list)) {
_eglRemoveSurface(&surface->Base);
@@ -715,7 +782,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable,
{
__DRIscreen *pDRIScreen;
__DRIscreenPrivate *psp;
- driSurface *surf = Lookup_driSurface(drawable);
+ driSurface *surf = Lookup_driSurface((EGLSurface) drawable);
pDRIScreen = __eglFindDRIScreen(ndpy, screen);
@@ -1080,6 +1147,7 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy,
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
driDisplay *display;
+ const char *driverName = (const char *) disp->NativeDisplay;
assert(disp);
@@ -1088,13 +1156,13 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy,
*/
display = calloc(1, sizeof(*display));
display->Base = *disp;
- _eglHashInsert(_eglGlobal.Displays, disp->Handle, display);
+ _eglSaveDisplay(&display->Base);
free(disp);
*major = 1;
*minor = 0;
- sscanf(&disp->Name[1], "%d", &display->minor);
+ sscanf(driverName + 1, "%d", &display->minor);
drv->Initialized = EGL_TRUE;
return EGL_TRUE;
diff --git a/src/egl/drivers/dri/egldri.h b/src/egl/drivers/dri/egldri.h
index 34b12d64fc..54a9a4ea26 100644
--- a/src/egl/drivers/dri/egldri.h
+++ b/src/egl/drivers/dri/egldri.h
@@ -1,11 +1,14 @@
#ifndef EGLDRI_INCLUDED
#define EGLDRI_INCLUDED
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
#include "egldisplay.h"
#include "eglscreen.h"
#include "eglsurface.h"
#include "eglcontext.h"
-#include "mtypes.h"
+
#include "dri_util.h"
#include "drm_sarea.h"
@@ -14,7 +17,7 @@
*/
typedef struct dri_display
{
- _EGLDisplay Base; /* base class/object */
+ _EGLDisplay Base; /**< base class */
void *pFB;
int drmFD; /**< \brief DRM device file descriptor */
int minor;
@@ -32,7 +35,7 @@ typedef struct dri_display
unsigned long FBStart; /**< \brief physical address of the framebuffer */
void *driverClientMsg;
int driverClientMsgSize;
- int chipset;
+ unsigned chipset;
void *driverPrivate;
drm_magic_t magic;
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index e6844d4852..96742bb4bc 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -8,34 +8,49 @@ INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
HEADERS = \
eglconfig.h \
+ eglconfigutil.h \
eglcontext.h \
+ egldefines.h \
egldisplay.h \
egldriver.h \
eglglobals.h \
egllog.h \
eglhash.h \
+ eglmisc.h \
eglmode.h \
eglscreen.h \
- eglsurface.h
+ eglstring.h \
+ eglsurface.h \
+ eglx.h
SOURCES = \
eglapi.c \
eglconfig.c \
+ eglconfigutil.c \
eglcontext.c \
egldisplay.c \
egldriver.c \
eglglobals.c \
egllog.c \
eglhash.c \
+ eglmisc.c \
eglmode.c \
eglscreen.c \
- eglsurface.c
+ eglstring.c \
+ eglsurface.c \
+ eglx.c
OBJECTS = $(SOURCES:.c=.o)
+# Undefined for now
+LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1
+
+LIBS = -lX11
+
+
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
@@ -47,7 +62,7 @@ library: $(TOP)/$(LIB_DIR)/libEGL.so
$(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS)
$(TOP)/bin/mklib -o EGL -major 1 -minor 0 \
- -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS)
+ -install $(TOP)/$(LIB_DIR) -ldl $(OBJECTS) $(LIBS)
@@ -61,7 +76,8 @@ depend: $(SOURCES) $(HEADERS)
@ rm -f depend
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
- $(SOURCES) $(HEADERS) > /dev/null
+ $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null
+
include depend
# DO NOT DELETE
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index bfa580e6c3..49d1f3d0eb 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -43,36 +43,54 @@
/**
- * NOTE: displayName is treated as a string in _eglChooseDriver()!!!
- * This will probably change!
- * See _eglChooseDriver() for details!
+ * This is typically the first EGL function that an application calls.
+ * We initialize our global vars and create a private _EGLDisplay object.
*/
-EGLDisplay APIENTRY
-eglGetDisplay(NativeDisplayType displayName)
+EGLDisplay EGLAPIENTRY
+eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
_eglInitGlobals();
- dpy = _eglNewDisplay(displayName);
- if (dpy)
- return dpy->Handle;
- else
- return EGL_NO_DISPLAY;
+ dpy = _eglNewDisplay(nativeDisplay);
+ return _eglGetDisplayHandle(dpy);
}
-EGLBoolean APIENTRY
+/**
+ * This is typically the second EGL function that an application calls.
+ * Here we load/initialize the actual hardware driver.
+ */
+EGLBoolean EGLAPIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
if (dpy) {
- _EGLDriver *drv = _eglChooseDriver(dpy);
- if (drv)
- return drv->API.Initialize(drv, dpy, major, minor);
+ EGLBoolean retVal;
+ _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
+ if (!dpyPriv) {
+ return EGL_FALSE;
+ }
+ dpyPriv->Driver = _eglOpenDriver(dpyPriv,
+ dpyPriv->DriverName,
+ dpyPriv->DriverArgs);
+ if (!dpyPriv->Driver) {
+ return EGL_FALSE;
+ }
+ /* Initialize the particular driver now */
+ retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
+ major, minor);
+
+ dpyPriv->Driver->APImajor = *major;
+ dpyPriv->Driver->APIminor = *minor;
+ snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
+ "%d.%d (%s)", *major, *minor, dpyPriv->Driver->Name);
+
+ return retVal;
}
return EGL_FALSE;
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglTerminate(EGLDisplay dpy)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -83,7 +101,7 @@ eglTerminate(EGLDisplay dpy)
}
-const char * APIENTRY
+const char * EGLAPIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -94,7 +112,7 @@ eglQueryString(EGLDisplay dpy, EGLint name)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -103,7 +121,7 @@ eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *nu
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -111,7 +129,7 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, E
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -119,7 +137,7 @@ eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *v
}
-EGLContext APIENTRY
+EGLContext EGLAPIENTRY
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -127,7 +145,7 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -135,7 +153,7 @@ eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -143,7 +161,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -151,7 +169,7 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
}
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -159,7 +177,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window
}
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -167,7 +185,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap
}
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -175,7 +193,7 @@ eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_l
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -183,7 +201,7 @@ eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -191,7 +209,7 @@ eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *va
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -199,7 +217,7 @@ eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint va
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -207,7 +225,7 @@ eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -215,7 +233,7 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -223,7 +241,7 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -231,7 +249,7 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -239,7 +257,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
EGLDisplay dpy = eglGetCurrentDisplay();
@@ -252,7 +270,7 @@ eglWaitGL(void)
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
EGLDisplay dpy = eglGetCurrentDisplay();
@@ -265,40 +283,31 @@ eglWaitNative(EGLint engine)
}
-EGLDisplay APIENTRY
+EGLDisplay EGLAPIENTRY
eglGetCurrentDisplay(void)
{
_EGLDisplay *dpy = _eglGetCurrentDisplay();
- if (dpy)
- return dpy->Handle;
- else
- return EGL_NO_DISPLAY;
+ return _eglGetDisplayHandle(dpy);
}
-EGLContext APIENTRY
+EGLContext EGLAPIENTRY
eglGetCurrentContext(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
- if (ctx)
- return ctx->Handle;
- else
- return EGL_NO_CONTEXT;
+ return _eglGetContextHandle(ctx);
}
-EGLSurface APIENTRY
+EGLSurface EGLAPIENTRY
eglGetCurrentSurface(EGLint readdraw)
{
_EGLSurface *s = _eglGetCurrentSurface(readdraw);
- if (s)
- return s->Handle;
- else
- return EGL_NO_SURFACE;
+ return _eglGetSurfaceHandle(s);
}
-EGLint APIENTRY
+EGLint EGLAPIENTRY
eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
@@ -308,7 +317,7 @@ eglGetError(void)
}
-void (* APIENTRY eglGetProcAddress(const char *procname))()
+void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()
{
typedef void (*genericFunc)();
struct name_function {
@@ -376,12 +385,15 @@ void (* APIENTRY eglGetProcAddress(const char *procname))()
return (genericFunc) egl_functions[i].function;
}
}
-#if 0
- /* XXX enable this code someday */
- return (genericFunc) _glapi_get_proc_address(procname);
-#else
+
+ /* now loop over drivers to query their procs */
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname);
+ if (p)
+ return p;
+ }
+
return NULL;
-#endif
}
@@ -389,7 +401,7 @@ void (* APIENTRY eglGetProcAddress(const char *procname))()
* EGL_MESA_screen extension
*/
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
@@ -402,7 +414,7 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -413,7 +425,7 @@ eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -424,7 +436,7 @@ eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint
}
-EGLBoolean APIENTRY
+EGLBoolean EGLAPIENTRY
eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
@@ -508,21 +520,42 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
#ifdef EGL_VERSION_1_2
+
+/**
+ * Specify the client API to use for subsequent calls including:
+ * eglCreateContext()
+ * eglGetCurrentContext()
+ * eglGetCurrentDisplay()
+ * eglGetCurrentSurface()
+ * eglMakeCurrent(when the ctx parameter is EGL NO CONTEXT)
+ * eglWaitClient()
+ * eglWaitNative()
+ * See section 3.7 "Rendering Context" in the EGL specification for details.
+ */
EGLBoolean
eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
switch (api) {
+#ifdef EGL_VERSION_1_4
+ case EGL_OPENGL_API:
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
+ t->CurrentAPI = api;
+ return EGL_TRUE;
+ }
+ _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
+ return EGL_FALSE;
+#endif
case EGL_OPENGL_ES_API:
- if (_eglGlobal.OpenGLESAPISupported) {
+ if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
t->CurrentAPI = api;
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
case EGL_OPENVG_API:
- if (_eglGlobal.OpenVGAPISupported) {
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
t->CurrentAPI = api;
return EGL_TRUE;
}
@@ -535,6 +568,18 @@ eglBindAPI(EGLenum api)
}
+/**
+ * Return the last value set with eglBindAPI().
+ */
+EGLenum
+eglQueryAPI(void)
+{
+ /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
+ _EGLThreadInfo *t = _eglGetCurrentThread();
+ return t->CurrentAPI;
+}
+
+
EGLSurface
eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLClientBuffer buffer, EGLConfig config,
@@ -546,15 +591,6 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
}
-EGLenum
-eglQueryAPI(void)
-{
- /* returns one of EGL_OPENGL_ES_API or EGL_OPENVG_API */
- _EGLThreadInfo *t = _eglGetCurrentThread();
- return t->CurrentAPI;
-}
-
-
EGLBoolean
eglReleaseThread(void)
{
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index 555aa5dd9e..f6163a0c7a 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -2,10 +2,15 @@
#define EGLAPI_INCLUDED
/**
- * Typedefs for all EGL API entrypoint functions.
+ * A generic function ptr type
*/
+typedef void (*_EGLProc)();
+/**
+ * Typedefs for all EGL API entrypoint functions.
+ */
+
/* driver funcs */
typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
@@ -39,6 +44,9 @@ typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint nam
typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+typedef _EGLProc (*GetProcAddress_t)(const char *procname);
+
+
#ifdef EGL_MESA_screen_surface
typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
@@ -95,6 +103,7 @@ struct _egl_api
QueryString_t QueryString;
WaitGL_t WaitGL;
WaitNative_t WaitNative;
+ GetProcAddress_t GetProcAddress;
/* EGL_MESA_screen extension */
ChooseModeMESA_t ChooseModeMESA;
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index c180e30d7f..c6369e7adf 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -17,48 +17,6 @@
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
-/**
- * Convert an _EGLConfig to a __GLcontextModes object.
- * NOTE: This routine may be incomplete - we're only making sure that
- * the fields needed by Mesa (for _mesa_create_context/framebuffer) are
- * set correctly.
- */
-void
-_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode)
-{
- memset(mode, 0, sizeof(*mode));
-
- mode->rgbMode = GL_TRUE; /* no color index */
- mode->colorIndexMode = GL_FALSE;
- mode->doubleBufferMode = GL_TRUE; /* always DB for now */
- mode->stereoMode = GL_FALSE;
-
- mode->redBits = GET_CONFIG_ATTRIB(config, EGL_RED_SIZE);
- mode->greenBits = GET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE);
- mode->blueBits = GET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE);
- mode->alphaBits = GET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE);
- mode->rgbBits = GET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE);
-
- /* no rgba masks - fix? */
-
- mode->depthBits = GET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE);
- mode->haveDepthBuffer = mode->depthBits > 0;
-
- mode->stencilBits = GET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE);
- mode->haveStencilBuffer = mode->stencilBits > 0;
-
- /* no accum */
-
- mode->level = GET_CONFIG_ATTRIB(config, EGL_LEVEL);
- mode->samples = GET_CONFIG_ATTRIB(config, EGL_SAMPLES);
- mode->sampleBuffers = GET_CONFIG_ATTRIB(config, EGL_SAMPLE_BUFFERS);
-
- /* surface type - not really needed */
- mode->visualType = GLX_TRUE_COLOR;
- mode->renderType = GLX_RGBA_BIT;
-}
-
-
void
_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val)
{
@@ -76,7 +34,7 @@ void
_eglInitConfig(_EGLConfig *config, EGLint id)
{
memset(config, 0, sizeof(*config));
- config->Handle = id;
+ config->Handle = (EGLConfig) id;
_eglSetConfigAttrib(config, EGL_CONFIG_ID, id);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
@@ -100,7 +58,19 @@ _eglInitConfig(_EGLConfig *config, EGLint id)
/**
+ * Return the public handle for an internal _EGLConfig.
+ * This is the inverse of _eglLookupConfig().
+ */
+EGLConfig
+_eglGetConfigHandle(_EGLConfig *config)
+{
+ return config ? config->Handle : 0;
+}
+
+
+/**
* Given an EGLConfig handle, return the corresponding _EGLConfig object.
+ * This is the inverse of _eglGetConfigHandle().
*/
_EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
@@ -132,7 +102,7 @@ _eglAddConfig(_EGLDisplay *display, const _EGLConfig *config)
if (newConfigs) {
display->Configs = newConfigs;
display->Configs[n] = *config; /* copy struct */
- display->Configs[n].Handle = n;
+ display->Configs[n].Handle = (EGLConfig) n;
display->NumConfigs++;
return display->Configs + n;
}
@@ -429,210 +399,3 @@ _eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
return EGL_TRUE;
}
-
-
-/**
- * Creates a set of \c __GLcontextModes that a driver will expose.
- *
- * A set of \c __GLcontextModes will be created based on the supplied
- * parameters. The number of modes processed will be 2 *
- * \c num_depth_stencil_bits * \c num_db_modes.
- *
- * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
- * \c db_modes, and \c visType into each \c __GLcontextModes element.
- * However, the meanings of \c fb_format and \c fb_type require further
- * explanation. The \c fb_format specifies which color components are in
- * each pixel and what the default order is. For example, \c GL_RGB specifies
- * that red, green, blue are available and red is in the "most significant"
- * position and blue is in the "least significant". The \c fb_type specifies
- * the bit sizes of each component and the actual ordering. For example, if
- * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
- * are the blue value, bits [10:5] are the green value, and bits [4:0] are
- * the red value.
- *
- * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
- * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
- * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
- * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
- * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
- * still uses 32-bits.
- *
- * If in doubt, look at the tables used in the function.
- *
- * \param ptr_to_modes Pointer to a pointer to a linked list of
- * \c __GLcontextModes. Upon completion, a pointer to
- * the next element to be process will be stored here.
- * If the function fails and returns \c GL_FALSE, this
- * value will be unmodified, but some elements in the
- * linked list may be modified.
- * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
- * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
- * \param fb_type Type of the pixels in the framebuffer. Currently only
- * \c GL_UNSIGNED_SHORT_5_6_5,
- * \c GL_UNSIGNED_SHORT_5_6_5_REV,
- * \c GL_UNSIGNED_INT_8_8_8_8, and
- * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
- * \param depth_bits Array of depth buffer sizes to be exposed.
- * \param stencil_bits Array of stencil buffer sizes to be exposed.
- * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
- * \c stencil_bits.
- * \param db_modes Array of buffer swap modes. If an element has a
- * value of \c GLX_NONE, then it represents a
- * single-buffered mode. Other valid values are
- * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
- * \c GLX_SWAP_UNDEFINED_OML. See the
- * GLX_OML_swap_method extension spec for more details.
- * \param num_db_modes Number of entries in \c db_modes.
- * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
- * \c GLX_DIRECT_COLOR.
- *
- * \returns
- * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
- * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
- * \c fb_type).
- *
- * \todo
- * There is currently no way to support packed RGB modes (i.e., modes with
- * exactly 3 bytes per pixel) or floating-point modes. This could probably
- * be done by creating some new, private enums with clever names likes
- * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
- * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
- */
-GLboolean
-_eglFillInConfigs(_EGLConfig * configs,
- GLenum fb_format, GLenum fb_type,
- const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- int visType)
-{
- static const u_int8_t bits_table[3][4] = {
- /* R G B A */
- { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
- { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
- { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
- };
-
- /* The following arrays are all indexed by the fb_type masked with 0x07.
- * Given the four supported fb_type values, this results in valid array
- * indices of 3, 4, 5, and 7.
- */
- static const u_int32_t masks_table_rgb[8][4] = {
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
- {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
- {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
- };
-
- static const u_int32_t masks_table_rgba[8][4] = {
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
- {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
- {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
- };
-
- static const u_int32_t masks_table_bgr[8][4] = {
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
- {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
- {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
- };
-
- static const u_int32_t masks_table_bgra[8][4] = {
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
- {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
- {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
- {0x00000000, 0x00000000, 0x00000000, 0x00000000},
- {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
- };
-
- static const u_int8_t bytes_per_pixel[8] = {
- 0, 0, 0, 2, 2, 4, 0, 4
- };
-
- const u_int8_t * bits;
- const u_int32_t * masks;
- const int index = fb_type & 0x07;
- _EGLConfig *config;
- unsigned i;
- unsigned j;
- unsigned k;
-
- if ( bytes_per_pixel[index] == 0 ) {
- _eglLog(_EGL_INFO,
- "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
- __FUNCTION__, __LINE__, fb_type);
- return GL_FALSE;
- }
-
- /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
- * the _REV versions.
- *
- * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
- */
- switch ( fb_format ) {
- case GL_RGB:
- bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
- masks = masks_table_rgb[index];
- break;
-
- case GL_RGBA:
- bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
- masks = masks_table_rgba[index];
- break;
-
- case GL_BGR:
- bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
- masks = masks_table_bgr[index];
- break;
-
- case GL_BGRA:
- bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
- masks = masks_table_bgra[index];
- break;
-
- default:
- _eglLog(_EGL_WARNING,
- "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
- __FUNCTION__, __LINE__, fb_format);
- return GL_FALSE;
- }
-
- config = configs;
- for (k = 0; k < num_depth_stencil_bits; k++) {
- for (i = 0; i < num_db_modes; i++) {
- for (j = 0; j < 2; j++) {
- _eglSetConfigAttrib(config, EGL_RED_SIZE, bits[0]);
- _eglSetConfigAttrib(config, EGL_GREEN_SIZE, bits[1]);
- _eglSetConfigAttrib(config, EGL_BLUE_SIZE, bits[2]);
- _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, bits[3]);
- _eglSetConfigAttrib(config, EGL_BUFFER_SIZE,
- bits[0] + bits[1] + bits[2] + bits[3]);
-
- _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, stencil_bits[k]);
- _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, depth_bits[i]);
-
- _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_SCREEN_BIT_MESA |
- EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT);
-
- config++;
- }
- }
- }
- return GL_TRUE;
-}
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 1fb976e5b4..b10a61985d 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -3,7 +3,7 @@
#include "egltypedefs.h"
-#include "GL/internal/glcore.h"
+#include <GLES/gl.h>
#define MAX_ATTRIBS 100
@@ -25,6 +25,10 @@ extern void
_eglInitConfig(_EGLConfig *config, EGLint id);
+extern EGLConfig
+_eglGetConfigHandle(_EGLConfig *config);
+
+
extern _EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
@@ -52,16 +56,5 @@ _eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint confi
extern void
_eglSetConfigAttrib(_EGLConfig *config, EGLint attr, EGLint val);
-extern GLboolean
-_eglFillInConfigs( _EGLConfig *configs,
- GLenum fb_format, GLenum fb_type,
- const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- int visType );
-
-extern void
-_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode);
-
#endif /* EGLCONFIG_INCLUDED */
diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c
new file mode 100644
index 0000000000..b6585619a5
--- /dev/null
+++ b/src/egl/main/eglconfigutil.c
@@ -0,0 +1,260 @@
+/**
+ * Extra utility functions related to EGL configs.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "eglconfigutil.h"
+#include "egllog.h"
+
+
+/**
+ * Convert an _EGLConfig to a __GLcontextModes object.
+ * NOTE: This routine may be incomplete - we're only making sure that
+ * the fields needed by Mesa (for _mesa_create_context/framebuffer) are
+ * set correctly.
+ */
+void
+_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode)
+{
+ memset(mode, 0, sizeof(*mode));
+
+ mode->rgbMode = GL_TRUE; /* no color index */
+ mode->colorIndexMode = GL_FALSE;
+ mode->doubleBufferMode = GL_TRUE; /* always DB for now */
+ mode->stereoMode = GL_FALSE;
+
+ mode->redBits = GET_CONFIG_ATTRIB(config, EGL_RED_SIZE);
+ mode->greenBits = GET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE);
+ mode->blueBits = GET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE);
+ mode->alphaBits = GET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE);
+ mode->rgbBits = GET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE);
+
+ /* no rgba masks - fix? */
+
+ mode->depthBits = GET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE);
+ mode->haveDepthBuffer = mode->depthBits > 0;
+
+ mode->stencilBits = GET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE);
+ mode->haveStencilBuffer = mode->stencilBits > 0;
+
+ /* no accum */
+
+ mode->level = GET_CONFIG_ATTRIB(config, EGL_LEVEL);
+ mode->samples = GET_CONFIG_ATTRIB(config, EGL_SAMPLES);
+ mode->sampleBuffers = GET_CONFIG_ATTRIB(config, EGL_SAMPLE_BUFFERS);
+
+ /* surface type - not really needed */
+ mode->visualType = GLX_TRUE_COLOR;
+ mode->renderType = GLX_RGBA_BIT;
+}
+
+
+
+/**
+ * Creates a set of \c _EGLConfigs that a driver will expose.
+ *
+ * A set of \c __GLcontextModes will be created based on the supplied
+ * parameters. The number of modes processed will be 2 *
+ * \c num_depth_stencil_bits * \c num_db_modes.
+ *
+ * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
+ * \c db_modes, and \c visType into each \c __GLcontextModes element.
+ * However, the meanings of \c fb_format and \c fb_type require further
+ * explanation. The \c fb_format specifies which color components are in
+ * each pixel and what the default order is. For example, \c GL_RGB specifies
+ * that red, green, blue are available and red is in the "most significant"
+ * position and blue is in the "least significant". The \c fb_type specifies
+ * the bit sizes of each component and the actual ordering. For example, if
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
+ * are the blue value, bits [10:5] are the green value, and bits [4:0] are
+ * the red value.
+ *
+ * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
+ * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
+ * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
+ * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
+ * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
+ * still uses 32-bits.
+ *
+ * If in doubt, look at the tables used in the function.
+ *
+ * \param configs the array of configs generated
+ * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
+ * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
+ * \param fb_type Type of the pixels in the framebuffer. Currently only
+ * \c GL_UNSIGNED_SHORT_5_6_5,
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV,
+ * \c GL_UNSIGNED_INT_8_8_8_8, and
+ * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
+ * \param depth_bits Array of depth buffer sizes to be exposed.
+ * \param stencil_bits Array of stencil buffer sizes to be exposed.
+ * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
+ * \c stencil_bits.
+ * \param db_modes Array of buffer swap modes. If an element has a
+ * value of \c GLX_NONE, then it represents a
+ * single-buffered mode. Other valid values are
+ * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
+ * \c GLX_SWAP_UNDEFINED_OML. See the
+ * GLX_OML_swap_method extension spec for more details.
+ * \param num_db_modes Number of entries in \c db_modes.
+ * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
+ * \c GLX_DIRECT_COLOR.
+ *
+ * \returns
+ * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
+ * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
+ * \c fb_type).
+ *
+ * \todo
+ * There is currently no way to support packed RGB modes (i.e., modes with
+ * exactly 3 bytes per pixel) or floating-point modes. This could probably
+ * be done by creating some new, private enums with clever names likes
+ * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
+ * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
+ */
+EGLBoolean
+_eglFillInConfigs(_EGLConfig * configs,
+ GLenum fb_format, GLenum fb_type,
+ const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes,
+ int visType)
+{
+#if 0
+ static const u_int8_t bits_table[3][4] = {
+ /* R G B A */
+ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
+ { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
+ { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
+ };
+
+ /* The following arrays are all indexed by the fb_type masked with 0x07.
+ * Given the four supported fb_type values, this results in valid array
+ * indices of 3, 4, 5, and 7.
+ */
+ static const u_int32_t masks_table_rgb[8][4] = {
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
+ {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
+ {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_rgba[8][4] = {
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
+ {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
+ {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_bgr[8][4] = {
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
+ {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
+ {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_bgra[8][4] = {
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
+ {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
+ {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
+ };
+
+ static const u_int8_t bytes_per_pixel[8] = {
+ 0, 0, 0, 2, 2, 4, 0, 4
+ };
+
+ const u_int8_t * bits;
+ const u_int32_t * masks;
+ const int index = fb_type & 0x07;
+ _EGLConfig *config;
+ unsigned i;
+ unsigned j;
+ unsigned k;
+
+ if ( bytes_per_pixel[index] == 0 ) {
+ _eglLog(_EGL_INFO,
+ "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
+ __FUNCTION__, __LINE__, fb_type);
+ return GL_FALSE;
+ }
+
+ /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
+ * the _REV versions.
+ *
+ * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
+ */
+ switch ( fb_format ) {
+ case GL_RGB:
+ bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
+ masks = masks_table_rgb[index];
+ break;
+
+ case GL_RGBA:
+ bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
+ masks = masks_table_rgba[index];
+ break;
+
+ case GL_BGR:
+ bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[1];
+ masks = masks_table_bgr[index];
+ break;
+
+ case GL_BGRA:
+ bits = (bytes_per_pixel[index] == 2) ? bits_table[0] : bits_table[2];
+ masks = masks_table_bgra[index];
+ break;
+
+ default:
+ _eglLog(_EGL_WARNING,
+ "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
+ __FUNCTION__, __LINE__, fb_format);
+ return GL_FALSE;
+ }
+
+ config = configs;
+ for (k = 0; k < num_depth_stencil_bits; k++) {
+ for (i = 0; i < num_db_modes; i++) {
+ for (j = 0; j < 2; j++) {
+ _eglSetConfigAttrib(config, EGL_RED_SIZE, bits[0]);
+ _eglSetConfigAttrib(config, EGL_GREEN_SIZE, bits[1]);
+ _eglSetConfigAttrib(config, EGL_BLUE_SIZE, bits[2]);
+ _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, bits[3]);
+ _eglSetConfigAttrib(config, EGL_BUFFER_SIZE,
+ bits[0] + bits[1] + bits[2] + bits[3]);
+
+ _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, stencil_bits[k]);
+ _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, depth_bits[i]);
+
+ _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_SCREEN_BIT_MESA |
+ EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT);
+
+ config++;
+ }
+ }
+ }
+ return GL_TRUE;
+#else
+ return GL_FALSE;
+#endif
+}
+
diff --git a/src/egl/main/eglconfigutil.h b/src/egl/main/eglconfigutil.h
new file mode 100644
index 0000000000..5db906db65
--- /dev/null
+++ b/src/egl/main/eglconfigutil.h
@@ -0,0 +1,23 @@
+
+#ifndef EGLCONFIGUTIL_INCLUDED
+#define EGLCONFIGUTIL_INCLUDED
+
+#include "eglconfig.h"
+#include "GL/internal/glcore.h"
+
+
+extern void
+_eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode);
+
+
+extern EGLBoolean
+_eglFillInConfigs( _EGLConfig *configs,
+ EGLenum fb_format, EGLenum fb_type,
+ const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const EGLenum * db_modes, unsigned num_db_modes,
+ int visType );
+
+
+
+#endif /* EGLCONFIGUTIL_INCLUDED */
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 374c006dae..bf1addf241 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -6,12 +6,12 @@
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "eglsurface.h"
/**
- * Initialize the given _EGLContext object to defaults.
+ * Initialize the given _EGLContext object to defaults and/or the values
+ * in the attrib_list.
*/
EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
@@ -20,19 +20,28 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
_EGLConfig *conf;
_EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint i;
+ const EGLenum api = eglQueryAPI();
+
+ if (api == EGL_NONE) {
+ _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
+ return EGL_FALSE;
+ }
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
+ _eglError(EGL_BAD_CONFIG, "_eglInitContext");
return EGL_FALSE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
- /* no attribs defined for now */
+ case EGL_CONTEXT_CLIENT_VERSION:
+ i++;
+ ctx->ClientVersion = attrib_list[i];
+ break;
default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
- return EGL_NO_CONTEXT;
+ _eglError(EGL_BAD_ATTRIBUTE, "_eglInitContext");
+ return EGL_FALSE;
}
}
@@ -41,21 +50,21 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
ctx->Config = conf;
ctx->DrawSurface = EGL_NO_SURFACE;
ctx->ReadSurface = EGL_NO_SURFACE;
+ ctx->ClientAPI = api;
return EGL_TRUE;
}
-/*
- * Assign an EGLContext handle to the _EGLContext object then put it into
- * the hash table.
+/**
+ * Save a new _EGLContext into the hash table.
*/
void
_eglSaveContext(_EGLContext *ctx)
{
- assert(ctx);
- ctx->Handle = _eglHashGenKey(_eglGlobal.Contexts);
- _eglHashInsert(_eglGlobal.Contexts, ctx->Handle, ctx);
+ /* no-op.
+ * Public EGLContext handle and private _EGLContext are the same.
+ */
}
@@ -65,19 +74,34 @@ _eglSaveContext(_EGLContext *ctx)
void
_eglRemoveContext(_EGLContext *ctx)
{
- _eglHashRemove(_eglGlobal.Contexts, ctx->Handle);
+ /* no-op.
+ * Public EGLContext handle and private _EGLContext are the same.
+ */
+}
+
+
+/**
+ * Return the public handle for the given private context ptr.
+ * This is the inverse of _eglLookupContext().
+ */
+EGLContext
+_eglGetContextHandle(_EGLContext *ctx)
+{
+ /* just a cast! */
+ return (EGLContext) ctx;
}
/**
* Return the _EGLContext object that corresponds to the given
* EGLContext handle.
+ * This is the inverse of _eglGetContextHandle().
*/
_EGLContext *
_eglLookupContext(EGLContext ctx)
{
- _EGLContext *c = (_EGLContext *) _eglHashLookup(_eglGlobal.Contexts, ctx);
- return c;
+ /* just a cast since EGLContext is just a void ptr */
+ return (_EGLContext *) ctx;
}
@@ -112,7 +136,7 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
}
_eglSaveContext(context);
- return context->Handle;
+ return (EGLContext) context;
#endif
return EGL_NO_CONTEXT;
}
@@ -126,7 +150,6 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
- _eglHashRemove(_eglGlobal.Contexts, ctx);
if (context->IsBound) {
context->DeletePending = EGL_TRUE;
}
@@ -239,7 +262,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
ctx = NULL;
}
/* really delete context now */
- drv->API.DestroyContext(drv, dpy, oldContext->Handle);
+ drv->API.DestroyContext(drv, dpy, _eglGetContextHandle(oldContext));
}
}
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 82bfde151f..34fee9c637 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -11,8 +11,6 @@
*/
struct _egl_context
{
- EGLContext Handle; /* The public/opaque handle which names this object */
-
_EGLDisplay *Display; /* who do I belong to? */
_EGLConfig *Config;
@@ -22,9 +20,9 @@ struct _egl_context
EGLBoolean IsBound;
EGLBoolean DeletePending;
-#ifdef EGL_VERSION_1_2
- EGLint ClientAPI; /* Either EGL_OPENGL_ES_API or EGL_OPENVG_API */
-#endif /* EGL_VERSION_1_2 */
+
+ EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
+ EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
};
@@ -41,6 +39,10 @@ extern void
_eglRemoveContext(_EGLContext *ctx);
+extern EGLContext
+_eglGetContextHandle(_EGLContext *ctx);
+
+
extern _EGLContext *
_eglLookupContext(EGLContext ctx);
diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.h b/src/egl/main/egldefines.h
index f6a95723bc..8fc2301b79 100644
--- a/src/gallium/winsys/dri/intel/intel_batchpool.h
+++ b/src/egl/main/egldefines.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,13 +25,21 @@
*
**************************************************************************/
-#ifndef INTEL_BATCHPOOL_H
-#define INTEL_BATCHPOOL_H
-extern struct _DriBufferPool *driBatchPoolInit(int fd, unsigned flags,
- unsigned long bufSize,
- unsigned numBufs,
- unsigned checkDelayed);
+/**
+ * Internal EGL defines
+ */
-#endif /* INTEL_BATCHPOOL_H */
+
+#ifndef EGLDEFINES_INCLUDED
+#define EGLDEFINES_INCLUDED
+
+
+#define _EGL_MAX_EXTENSIONS_LEN 1000
+
+#define _EGL_VENDOR_STRING "Mesa Project"
+
+
+
+#endif /* EGLDEFINES_INCLUDED */
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 074a85bf26..8fd29b8421 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -1,55 +1,90 @@
+
+/**
+ * Functions related to EGLDisplay.
+ */
+
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "egldisplay.h"
+#include "egldriver.h"
#include "eglglobals.h"
#include "eglhash.h"
-
-
-static char *
-my_strdup(const char *s)
-{
- int l = strlen(s);
- char *s2 = malloc(l + 1);
- strcpy(s2, s);
- return s2;
-}
+#include "eglstring.h"
/**
- * We're assuming that the NativeDisplayType parameter is actually
- * a string.
- * Return a new _EGLDisplay object for the given displayName
+ * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
+ * We'll also try to determine the device driver name at this time.
+ *
+ * Note that nativeDisplay may be an X Display ptr, or a string.
*/
_EGLDisplay *
-_eglNewDisplay(NativeDisplayType displayName)
+_eglNewDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
if (dpy) {
- dpy->Handle = _eglHashGenKey(_eglGlobal.Displays);
- _eglHashInsert(_eglGlobal.Displays, dpy->Handle, dpy);
- if (displayName)
- dpy->Name = my_strdup(displayName);
- else
- dpy->Name = NULL;
- dpy->Driver = NULL; /* this gets set later */
+ EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
+
+ dpy->Handle = (EGLDisplay) key;
+ _eglHashInsert(_eglGlobal.Displays, key, dpy);
+
+ dpy->NativeDisplay = nativeDisplay;
+#if defined(_EGL_PLATFORM_X)
+ dpy->Xdpy = (Display *) nativeDisplay;
+#endif
+
+ dpy->DriverName = _eglChooseDriver(dpy);
+ if (!dpy->DriverName) {
+ free(dpy);
+ return NULL;
+ }
}
return dpy;
}
/**
+ * Return the public handle for an internal _EGLDisplay.
+ * This is the inverse of _eglLookupDisplay().
+ */
+EGLDisplay
+_eglGetDisplayHandle(_EGLDisplay *display)
+{
+ if (display)
+ return display->Handle;
+ else
+ return EGL_NO_DISPLAY;
+}
+
+
+/**
* Return the _EGLDisplay object that corresponds to the given public/
* opaque display handle.
+ * This is the inverse of _eglGetDisplayHandle().
*/
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
- _EGLDisplay *d = (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, dpy);
+ EGLuint key = (EGLuint) dpy;
+ _EGLDisplay *d = (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
return d;
}
+void
+_eglSaveDisplay(_EGLDisplay *dpy)
+{
+ EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
+ assert(dpy);
+ assert(!dpy->Handle);
+ dpy->Handle = (EGLDisplay) key;
+ assert(dpy->Handle);
+ _eglHashInsert(_eglGlobal.Displays, key, dpy);
+}
+
+
_EGLDisplay *
_eglGetCurrentDisplay(void)
{
@@ -66,6 +101,6 @@ _eglCleanupDisplay(_EGLDisplay *disp)
{
/* XXX incomplete */
free(disp->Configs);
- free(disp->Name);
+ free((void *) disp->DriverName);
/* driver deletes _EGLDisplay */
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 1a03fdd4ad..e2ebab0b21 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -1,15 +1,20 @@
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
+#ifdef _EGL_PLATFORM_X
+#include <X11/Xlib.h>
+#endif
#include "egltypedefs.h"
struct _egl_display
{
+ EGLNativeDisplayType NativeDisplay;
EGLDisplay Handle;
- char *Name;
+ const char *DriverName;
+ const char *DriverArgs;
_EGLDriver *Driver;
EGLint NumScreens;
@@ -17,6 +22,10 @@ struct _egl_display
EGLint NumConfigs;
_EGLConfig *Configs; /* array [NumConfigs] */
+
+#ifdef _EGL_PLATFORM_X
+ Display *Xdpy;
+#endif
};
@@ -24,10 +33,18 @@ extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
+EGLDisplay
+_eglGetDisplayHandle(_EGLDisplay *display);
+
+
extern _EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy);
+extern void
+_eglSaveDisplay(_EGLDisplay *dpy);
+
+
extern _EGLDisplay *
_eglGetCurrentDisplay(void);
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index bda06dd827..80fa49b7ab 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -1,82 +1,175 @@
+/**
+ * Functions for choosing and opening/loading device drivers.
+ */
+
+
#include <assert.h>
+#include <string.h>
#include <dlfcn.h>
#include <stdio.h>
-#include <string.h>
+#include <stdlib.h>
#include "eglconfig.h"
#include "eglcontext.h"
+#include "egldefines.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "egllog.h"
+#include "eglmisc.h"
#include "eglmode.h"
#include "eglscreen.h"
+#include "eglstring.h"
#include "eglsurface.h"
+#if defined(_EGL_PLATFORM_X)
+#include "eglx.h"
+#elif defined(_EGL_PLATFORM_WINDOWS)
+/* XXX to do */
+#elif defined(_EGL_PLATFORM_WINCE)
+/* XXX to do */
+#endif
+
+
+static const char *DefaultDriverName = ":0";
+static const char *SysFS = "/sys/class";
+
+
+
+
+/**
+ * Given a card number, use sysfs to determine the DRI driver name.
+ */
+static const char *
+_eglChooseDRMDriver(int card)
+{
+#if 0
+ return _eglstrdup("libEGLdri");
+#else
+ char path[2000], driverName[2000];
+ FILE *f;
+ int length;
+
+ snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
+
+ f = fopen(path, "r");
+ if (!f)
+ return NULL;
+
+ fgets(driverName, sizeof(driverName), f);
+ fclose(f);
-const char *DefaultDriverName = "demodriver";
+ if ((length = strlen(driverName)) > 1) {
+ /* remove the trailing newline from sysfs */
+ driverName[length - 1] = '\0';
+ strncat(driverName, "_dri", sizeof(driverName));
+ return _eglstrdup(driverName);
+ }
+ else {
+ return NULL;
+ }
+#endif
+}
/**
- * Choose and open/init the hardware driver for the given EGLDisplay.
- * Previously, the EGLDisplay was created with _eglNewDisplay() where
- * we recorded the user's NativeDisplayType parameter.
+ * XXX this function is totally subject change!!!
*
- * Now we'll use the NativeDisplayType value.
*
- * Currently, the native display value is treated as a string.
+ * Determine/return the name of the driver to use for the given _EGLDisplay.
+ *
+ * Try to be clever and determine if nativeDisplay is an Xlib Display
+ * ptr or a string (naming a driver or screen number, etc).
+ *
* If the first character is ':' we interpret it as a screen or card index
* number (i.e. ":0" or ":1", etc)
* Else if the first character is '!' we interpret it as specific driver name
* (i.e. "!r200" or "!i830".
+ *
+ * Whatever follows ':' is copied and put into dpy->DriverArgs.
+ *
+ * The caller may free() the returned string.
*/
-_EGLDriver *
-_eglChooseDriver(EGLDisplay display)
+const char *
+_eglChooseDriver(_EGLDisplay *dpy)
{
- _EGLDisplay *dpy = _eglLookupDisplay(display);
- _EGLDriver *drv;
- const char *driverName = DefaultDriverName;
- const char *name;
+ const char *displayString = (const char *) dpy->NativeDisplay;
+ const char *driverName = NULL;
+
+ (void) DefaultDriverName;
- assert(dpy);
+ /* First, if the EGL_DRIVER env var is set, use that */
+ driverName = getenv("EGL_DRIVER");
+ if (driverName)
+ return _eglstrdup(driverName);
- name = dpy->Name;
- if (!name) {
- /* use default */
+#if 0
+ if (!displayString) {
+ /* choose a default */
+ displayString = DefaultDriverName;
+ }
+#endif
+ /* extract default DriverArgs = whatever follows ':' */
+ if (displayString &&
+ (displayString[0] == '!' ||
+ displayString[0] == ':')) {
+ const char *args = strchr(displayString, ':');
+ if (args)
+ dpy->DriverArgs = _eglstrdup(args + 1);
}
- else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) {
- /* XXX probe hardware here to determine which driver to open */
- driverName = "libEGLdri";
+
+ /* determine driver name now */
+ if (displayString && displayString[0] == ':' &&
+ (displayString[1] >= '0' && displayString[1] <= '9') &&
+ !displayString[2]) {
+ int card = atoi(displayString + 1);
+ driverName = _eglChooseDRMDriver(card);
}
- else if (name[0] == '!') {
- /* use specified driver name */
- driverName = name + 1;
+ else if (displayString && displayString[0] == '!') {
+ /* use user-specified driver name */
+ driverName = _eglstrdup(displayString + 1);
+ /* truncate driverName at ':' if present */
+ {
+ char *args = strchr(driverName, ':');
+ if (args) {
+ *args = 0;
+ }
+ }
}
else {
- /* Maybe display was returned by XOpenDisplay? */
- _eglLog(_EGL_FATAL, "eglChooseDriver() bad name");
+ /* NativeDisplay is not a string! */
+#if defined(_EGL_PLATFORM_X)
+ driverName = _xeglChooseDriver(dpy);
+#elif defined(_EGL_PLATFORM_WINDOWS)
+ /* XXX to do */
+ driverName = _weglChooseDriver(dpy);
+#elif defined(_EGL_PLATFORM_WINCE)
+ /* XXX to do */
+#else
+ driverName = DefaultDriverName;
+#endif
}
- _eglLog(_EGL_INFO, "eglChooseDriver() choosing %s", driverName);
-
- drv = _eglOpenDriver(dpy, driverName);
- dpy->Driver = drv;
-
- return drv;
+ return driverName;
}
/**
* Open/load the named driver and call its bootstrap function: _eglMain().
+ * By the time this function is called, the dpy->DriverName should have
+ * been determined.
+ *
* \return new _EGLDriver object.
*/
_EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
+_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
{
_EGLDriver *drv;
_EGLMain_t mainFunc;
void *lib;
char driverFilename[1000];
+ assert(driverName);
+
/* XXX also prepend a directory path??? */
sprintf(driverFilename, "%s.so", driverName);
@@ -95,7 +188,7 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
return NULL;
}
- drv = mainFunc(dpy);
+ drv = mainFunc(dpy, args);
if (!drv) {
dlclose(lib);
return NULL;
@@ -106,7 +199,11 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
else
dlclose(lib);
- drv->Display = dpy;
+ /* update the global notion of supported APIs */
+ _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
+
+ _eglSaveDriver(drv);
+
return drv;
}
@@ -130,6 +227,16 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
/**
+ * Save the given driver pointer in the list of all known drivers.
+ */
+void
+_eglSaveDriver(_EGLDriver *drv)
+{
+ _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
+}
+
+
+/**
* Given a display handle, return the _EGLDriver for that display.
*/
_EGLDriver *
@@ -199,74 +306,3 @@ _eglInitDriverFallbacks(_EGLDriver *drv)
drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
#endif /* EGL_VERSION_1_2 */
}
-
-
-/**
- * Examine the individual extension enable/disable flags and recompute
- * the driver's Extensions string.
- */
-static void
-_eglUpdateExtensionsString(_EGLDriver *drv)
-{
- drv->Extensions.String[0] = 0;
-
- if (drv->Extensions.MESA_screen_surface)
- strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
- if (drv->Extensions.MESA_copy_context)
- strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
- assert(strlen(drv->Extensions.String) < MAX_EXTENSIONS_LEN);
-}
-
-
-
-const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
-{
- (void) drv;
- (void) dpy;
- switch (name) {
- case EGL_VENDOR:
- return "Mesa Project";
- case EGL_VERSION:
- return "1.0";
- case EGL_EXTENSIONS:
- _eglUpdateExtensionsString(drv);
- return drv->Extensions.String;
-#ifdef EGL_VERSION_1_2
- case EGL_CLIENT_APIS:
- /* XXX need to initialize somewhere */
- return drv->ClientAPIs;
-#endif
- default:
- _eglError(EGL_BAD_PARAMETER, "eglQueryString");
- return NULL;
- }
-}
-
-
-EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
-{
- /* just a placeholder */
- (void) drv;
- (void) dpy;
- return EGL_TRUE;
-}
-
-
-EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
-{
- /* just a placeholder */
- (void) drv;
- (void) dpy;
- switch (engine) {
- case EGL_CORE_NATIVE_ENGINE:
- break;
- default:
- _eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)");
- return EGL_FALSE;
- }
-
- return EGL_TRUE;
-}
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 88526e973d..af028eaf22 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -4,9 +4,7 @@
#include "egltypedefs.h"
#include "eglapi.h"
-
-/* should probably use a dynamic-length string, but this will do */
-#define MAX_EXTENSIONS_LEN 1000
+#include "egldefines.h"
/**
@@ -17,7 +15,7 @@ struct _egl_extensions
EGLBoolean MESA_screen_surface;
EGLBoolean MESA_copy_context;
- char String[MAX_EXTENSIONS_LEN];
+ char String[_EGL_MAX_EXTENSIONS_LEN];
};
@@ -26,37 +24,43 @@ struct _egl_extensions
*/
struct _egl_driver
{
- EGLBoolean Initialized; /* set by driver after initialized */
+ EGLBoolean Initialized; /**< set by driver after initialized */
+
+ void *LibHandle; /**< dlopen handle */
- void *LibHandle; /* dlopen handle */
+ const char *Name; /**< name of this driver */
- _EGLDisplay *Display;
+ int APImajor, APIminor; /**< as returned by eglInitialize() */
+ char Version[1000]; /**< initialized from APImajor/minor, Name */
- int ABIversion;
- int APImajor, APIminor; /* returned through eglInitialize */
- const char *ClientAPIs;
+ /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
+ EGLint ClientAPIsMask;
- _EGLAPI API;
+ _EGLAPI API; /**< EGL API dispatch table */
_EGLExtensions Extensions;
};
-extern _EGLDriver *_eglMain(_EGLDisplay *dpy);
+extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
-extern _EGLDriver *
-_eglChooseDriver(EGLDisplay dpy);
+extern const char *
+_eglChooseDriver(_EGLDisplay *dpy);
extern _EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName);
+_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args);
extern EGLBoolean
_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
+extern void
+_eglSaveDriver(_EGLDriver *drv);
+
+
extern _EGLDriver *
_eglLookupDriver(EGLDisplay d);
@@ -65,17 +69,4 @@ extern void
_eglInitDriverFallbacks(_EGLDriver *drv);
-extern const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
-
-
-extern EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
-
-
-extern EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
-
-
-
#endif /* EGLDRIVER_INCLUDED */
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index 608311d749..9a077edbd7 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -15,13 +15,11 @@ _eglInitGlobals(void)
{
if (!_eglGlobal.Initialized) {
_eglGlobal.Displays = _eglNewHashTable();
- _eglGlobal.Contexts = _eglNewHashTable();
_eglGlobal.Surfaces = _eglNewHashTable();
_eglGlobal.FreeScreenHandle = 1;
_eglGlobal.Initialized = EGL_TRUE;
- _eglGlobal.OpenGLESAPISupported = EGL_TRUE;
- _eglGlobal.OpenVGAPISupported = EGL_FALSE;
+ _eglGlobal.ClientAPIsMask = 0x0;
/* XXX temporary */
_eglGlobal.ThreadInfo = _eglNewThreadInfo();
@@ -37,7 +35,6 @@ _eglDestroyGlobals(void)
{
/* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays);
- _eglDeleteHashTable(_eglGlobal.Contexts);
_eglDeleteHashTable(_eglGlobal.Surfaces);
}
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index c16baa2d6b..14d8ea487a 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -24,17 +24,20 @@ struct _egl_global
EGLBoolean Initialized;
_EGLHashtable *Displays;
- _EGLHashtable *Contexts;
_EGLHashtable *Surfaces;
EGLScreenMESA FreeScreenHandle;
- /* XXX these may be temporary */
- EGLBoolean OpenGLESAPISupported;
- EGLBoolean OpenVGAPISupported;
+ /* bitmaks of supported APIs (supported by _some_ driver) */
+ EGLint ClientAPIsMask;
+
+ char ClientAPIs[1000]; /**< updated by eglQueryString */
/* XXX temporary - should be thread-specific data (TSD) */
_EGLThreadInfo *ThreadInfo;
+
+ EGLint NumDrivers;
+ _EGLDriver *Drivers[10];
};
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
new file mode 100644
index 0000000000..b5bdc3ea4b
--- /dev/null
+++ b/src/egl/main/eglmisc.c
@@ -0,0 +1,129 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * Small/misc EGL functions
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include "eglglobals.h"
+#include "eglmisc.h"
+
+
+/**
+ * Examine the individual extension enable/disable flags and recompute
+ * the driver's Extensions string.
+ */
+static void
+_eglUpdateExtensionsString(_EGLDriver *drv)
+{
+ drv->Extensions.String[0] = 0;
+
+ if (drv->Extensions.MESA_screen_surface)
+ strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
+ if (drv->Extensions.MESA_copy_context)
+ strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
+ assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN);
+}
+
+
+static void
+_eglUpdateAPIsString(_EGLDriver *drv)
+{
+ _eglGlobal.ClientAPIs[0] = 0;
+
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT)
+ strcat(_eglGlobal.ClientAPIs, "OpenGL ");
+
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT)
+ strcat(_eglGlobal.ClientAPIs, "OpenGL_ES ");
+
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT)
+ strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 ");
+
+ if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT)
+ strcat(_eglGlobal.ClientAPIs, "OpenVG ");
+
+ assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs));
+}
+
+
+
+const char *
+_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
+{
+ (void) drv;
+ (void) dpy;
+ switch (name) {
+ case EGL_VENDOR:
+ return _EGL_VENDOR_STRING;
+ case EGL_VERSION:
+ return drv->Version;
+ case EGL_EXTENSIONS:
+ _eglUpdateExtensionsString(drv);
+ return drv->Extensions.String;
+#ifdef EGL_VERSION_1_2
+ case EGL_CLIENT_APIS:
+ _eglUpdateAPIsString(drv);
+ return _eglGlobal.ClientAPIs;
+#endif
+ default:
+ _eglError(EGL_BAD_PARAMETER, "eglQueryString");
+ return NULL;
+ }
+}
+
+
+EGLBoolean
+_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
+{
+ /* just a placeholder */
+ (void) drv;
+ (void) dpy;
+ return EGL_TRUE;
+}
+
+
+EGLBoolean
+_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
+{
+ /* just a placeholder */
+ (void) drv;
+ (void) dpy;
+ switch (engine) {
+ case EGL_CORE_NATIVE_ENGINE:
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)");
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h
new file mode 100644
index 0000000000..4e2a40ea99
--- /dev/null
+++ b/src/egl/main/eglmisc.h
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef EGLMISC_INCLUDED
+#define EGLMISC_INCLUDED
+
+#include "egldriver.h"
+
+
+extern const char *
+_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
+
+
+extern EGLBoolean
+_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
+
+
+extern EGLBoolean
+_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+
+
+#endif /* EGLMISC_INCLUDED */
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index e70da85759..52d4875676 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -4,6 +4,9 @@
#include "egltypedefs.h"
+#define EGL_NO_MODE_MESA 0
+
+
/**
* Data structure which corresponds to an EGLModeMESA.
*/
diff --git a/src/egl/main/eglstring.c b/src/egl/main/eglstring.c
new file mode 100644
index 0000000000..ba7406158c
--- /dev/null
+++ b/src/egl/main/eglstring.c
@@ -0,0 +1,24 @@
+/**
+ * String utils.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "eglstring.h"
+
+
+char *
+_eglstrdup(const char *s)
+{
+ if (s) {
+ int l = strlen(s);
+ char *s2 = malloc(l + 1);
+ if (s2)
+ strcpy(s2, s);
+ return s2;
+ }
+ return NULL;
+}
+
+
+
diff --git a/src/egl/main/eglstring.h b/src/egl/main/eglstring.h
new file mode 100644
index 0000000000..10468636e8
--- /dev/null
+++ b/src/egl/main/eglstring.h
@@ -0,0 +1,9 @@
+#ifndef EGLSTRING_INCLUDED
+#define EGLSTRING_INCLUDED
+
+
+extern char *
+_eglstrdup(const char *s);
+
+
+#endif /* EGLSTRING_INCLUDED */
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 874f318e96..796d62f2b9 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -175,7 +175,7 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
}
}
- if (width <= 0 || height <= 0) {
+ if (width < 0 || height < 0) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
@@ -207,25 +207,47 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
void
_eglSaveSurface(_EGLSurface *surf)
{
+ EGLuint key = _eglHashGenKey(_eglGlobal.Surfaces);
assert(surf);
assert(!surf->Handle);
- surf->Handle = _eglHashGenKey(_eglGlobal.Contexts);
+ surf->Handle = (EGLSurface) key;
assert(surf->Handle);
- _eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf);
+ _eglHashInsert(_eglGlobal.Surfaces, key, surf);
}
void
_eglRemoveSurface(_EGLSurface *surf)
{
- _eglHashRemove(_eglGlobal.Surfaces, surf->Handle);
+ _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
}
+
+/**
+ * Return the public handle for an internal _EGLSurface.
+ * This is the inverse of _eglLookupSurface().
+ */
+EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surface)
+{
+ if (surface)
+ return surface->Handle;
+ else
+ return EGL_NO_SURFACE;
+}
+
+
+/**
+ * Return the private _EGLSurface which corresponds to a public EGLSurface
+ * handle.
+ * This is the inverse of _eglGetSurfaceHandle().
+ */
_EGLSurface *
_eglLookupSurface(EGLSurface surf)
{
- _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, surf);
+ _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
+ (EGLuint) surf);
return c;
}
@@ -439,7 +461,7 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
_EGLSurface *surf = _eglLookupSurface(surface);
if (surf) {
- _eglHashRemove(_eglGlobal.Surfaces, surface);
+ _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
if (surf->IsBound) {
surf->DeletePending = EGL_TRUE;
}
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 79abeca0b2..df1e70122e 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -51,6 +51,10 @@ extern void
_eglRemoveSurface(_EGLSurface *surf);
+extern EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surface);
+
+
extern _EGLSurface *
_eglLookupSurface(EGLSurface surf);
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index fa8cb496f8..efbb17a4dc 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -1,8 +1,10 @@
#ifndef EGLTYPEDEFS_INCLUDED
#define EGLTYPEDEFS_INCLUDED
+#define EGL_EGLEXT_PROTOTYPES
#include <GLES/egl.h>
+#include <GLES/eglext.h>
typedef struct _egl_api _EGLAPI;
@@ -26,9 +28,7 @@ typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo;
-typedef void (*_EGLProc)();
-
-typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy);
+typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args);
#endif /* EGLTYPEDEFS_INCLUDED */
diff --git a/src/egl/main/eglx.c b/src/egl/main/eglx.c
new file mode 100644
index 0000000000..085da33e7d
--- /dev/null
+++ b/src/egl/main/eglx.c
@@ -0,0 +1,49 @@
+
+/**
+ * X-specific EGL code.
+ *
+ * Any glue code needed to make EGL work with X is placed in this file.
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include "eglx.h"
+
+
+static const char *DefaultXDriver = "softpipe_egl";
+
+
+/**
+ * Given an X Display ptr (at dpy->Xdpy) try to determine the appropriate
+ * device driver. Return its name.
+ */
+const char *
+_xeglChooseDriver(_EGLDisplay *dpy)
+{
+#ifdef _EGL_PLATFORM_X
+ _XPrivDisplay xdpy;
+
+ assert(dpy);
+
+ if (!dpy->Xdpy) {
+ dpy->Xdpy = XOpenDisplay(NULL);
+ if (!dpy->Xdpy) {
+ /* can't open X display -> can't use X-based driver */
+ return NULL;
+ }
+ }
+ xdpy = (_XPrivDisplay) dpy->Xdpy;
+
+ assert(dpy->Xdpy);
+
+ printf("%s\n", xdpy->display_name);
+
+ return DefaultXDriver; /* XXX temporary */
+#else
+ return NULL;
+#endif
+}
+
+
diff --git a/src/egl/main/eglx.h b/src/egl/main/eglx.h
new file mode 100644
index 0000000000..4323d55838
--- /dev/null
+++ b/src/egl/main/eglx.h
@@ -0,0 +1,12 @@
+#ifndef EGLX_INCLUDED
+#define EGLX_INCLUDED
+
+
+#include "egldisplay.h"
+
+
+extern const char *
+_xeglChooseDriver(_EGLDisplay *dpy);
+
+
+#endif /* EGLX_INCLUDED */
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 1d26706dee..3355c871ee 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -255,7 +255,8 @@ void draw_pipeline_run( struct draw_context *draw,
char *verts = (char *)vertices; \
boolean flatfirst = (draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first); \
- unsigned i, flags
+ unsigned i; \
+ ushort flags
#define FLUSH
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index fd48b224b4..634bf067f1 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -141,18 +141,18 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
decl->Semantic.SemanticIndex == 0) {
- aactx->colorOutput = decl->u.DeclarationRange.First;
+ aactx->colorOutput = decl->DeclarationRange.First;
}
else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
aactx->samplersUsed |= 1 << i;
}
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
- aactx->maxInput = decl->u.DeclarationRange.Last;
+ if ((int) decl->DeclarationRange.Last > aactx->maxInput)
+ aactx->maxInput = decl->DeclarationRange.Last;
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
(int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
aactx->maxGeneric = decl->Semantic.SemanticIndex;
@@ -160,8 +160,8 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
aactx->tempsUsed |= (1 << i);
}
}
@@ -225,34 +225,33 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
/* declare new generic input/texcoord */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
+ /* XXX this could be linear... */
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
- decl.Declaration.Interpolate = 1;
- /* XXX this could be linear... */
- decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->maxInput + 1;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->maxInput + 1;
ctx->emit_declaration(ctx, &decl);
/* declare new sampler */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->freeSampler;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->freeSampler;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->texTemp;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->texTemp;
ctx->emit_declaration(ctx, &decl);
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->colorTemp;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->colorTemp;
ctx->emit_declaration(ctx, &decl);
aactx->firstInstruction = FALSE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 97d74ad693..96dcdb43d5 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -131,11 +131,11 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
decl->Semantic.SemanticIndex == 0) {
- aactx->colorOutput = decl->u.DeclarationRange.First;
+ aactx->colorOutput = decl->DeclarationRange.First;
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
- aactx->maxInput = decl->u.DeclarationRange.Last;
+ if ((int) decl->DeclarationRange.Last > aactx->maxInput)
+ aactx->maxInput = decl->DeclarationRange.Last;
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
(int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
aactx->maxGeneric = decl->Semantic.SemanticIndex;
@@ -143,8 +143,8 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
aactx->tempsUsed |= (1 << i);
}
}
@@ -193,27 +193,26 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
/* declare new generic input/texcoord */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
+ /* XXX this could be linear... */
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
- decl.Declaration.Interpolate = 1;
- /* XXX this could be linear... */
- decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = texInput;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = texInput;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = tmp0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = tmp0;
ctx->emit_declaration(ctx, &decl);
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->colorTemp;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->colorTemp;
ctx->emit_declaration(ctx, &decl);
aactx->firstInstruction = FALSE;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 4c92416eb1..4087cf7a49 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -132,20 +132,20 @@ pstip_transform_decl(struct tgsi_transform_context *ctx,
if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
pctx->samplersUsed |= 1 << i;
}
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
+ pctx->maxInput = MAX2(pctx->maxInput, (int) decl->DeclarationRange.Last);
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION)
- pctx->wincoordInput = (int) decl->u.DeclarationRange.First;
+ pctx->wincoordInput = (int) decl->DeclarationRange.First;
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
pctx->tempsUsed |= (1 << i);
}
}
@@ -223,28 +223,27 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
/* declare new position input reg */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
decl.Semantic.SemanticIndex = 0;
- decl.Declaration.Interpolate = 1;
- decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = wincoordInput;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = wincoordInput;
ctx->emit_declaration(ctx, &decl);
}
/* declare new sampler */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = pctx->freeSampler;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = pctx->freeSampler;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = pctx->texTemp;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = pctx->texTemp;
ctx->emit_declaration(ctx, &decl);
/* emit immediate = {1/32, 1/32, 1, 1}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 4f8cceee1e..423f64262b 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -193,7 +193,7 @@ struct draw_context
const float (*aligned_constants)[4];
- const float (*aligned_constant_storage)[4];
+ float (*aligned_constant_storage)[4];
unsigned const_storage_size;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 723077159b..f0d7b51ad7 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -35,6 +35,10 @@
#include "draw/draw_private.h"
#include "draw/draw_pt.h"
+static unsigned trim( unsigned count, unsigned first, unsigned incr )
+{
+ return count - (count - first) % incr;
+}
@@ -54,6 +58,17 @@ draw_pt_arrays(struct draw_context *draw,
struct draw_pt_middle_end *middle = NULL;
unsigned opt = 0;
+ /* Sanitize primitive length:
+ */
+ {
+ unsigned first, incr;
+ draw_pt_split_prim(prim, &first, &incr);
+ count = trim(count, first, incr);
+ if (count < first)
+ return TRUE;
+ }
+
+
if (!draw->render) {
opt |= PT_PIPELINE;
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h
index dccfde99dd..3fb0695687 100644
--- a/src/gallium/auxiliary/draw/draw_pt_decompose.h
+++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h
@@ -118,9 +118,9 @@ static void FUNC( ARGS,
/* These bitflags look a little odd because we submit the
* vertices as (1,2,0) to satisfy flatshade requirements.
*/
- const unsigned edge_first = DRAW_PIPE_EDGE_FLAG_2;
- const unsigned edge_middle = DRAW_PIPE_EDGE_FLAG_0;
- const unsigned edge_last = DRAW_PIPE_EDGE_FLAG_1;
+ const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2;
+ const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0;
+ const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1;
flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
diff --git a/src/gallium/auxiliary/draw/draw_pt_elts.c b/src/gallium/auxiliary/draw/draw_pt_elts.c
index 2094c081ed..b7780fb507 100644
--- a/src/gallium/auxiliary/draw/draw_pt_elts.c
+++ b/src/gallium/auxiliary/draw/draw_pt_elts.c
@@ -60,10 +60,10 @@ static unsigned elt_vert( const void *elts, unsigned idx )
pt_elt_func draw_pt_elt_func( struct draw_context *draw )
{
switch (draw->pt.user.eltSize) {
- case 0: return elt_vert;
- case 1: return elt_ubyte;
- case 2: return elt_ushort;
- case 4: return elt_uint;
+ case 0: return &elt_vert;
+ case 1: return &elt_ubyte;
+ case 2: return &elt_ushort;
+ case 4: return &elt_uint;
default: return NULL;
}
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index 260f28f284..f19e8850b3 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -109,9 +109,9 @@ static INLINE void fetch_init(struct varray_frontend *varray,
static INLINE void add_draw_el(struct varray_frontend *varray,
- int idx)
+ unsigned idx)
{
- varray->draw_elts[varray->draw_count++] = idx;
+ varray->draw_elts[varray->draw_count++] = (ushort)idx;
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 9ffc99abf9..ad86ab4292 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -201,39 +201,74 @@ static void vcache_ef_quad( struct vcache_frontend *vcache,
#define FUNC vcache_run
#include "draw_pt_vcache_tmp.h"
+static void rebase_uint_elts( const unsigned *src,
+ unsigned count,
+ int delta,
+ ushort *dest )
+{
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ dest[i] = (ushort)(src[i] + delta);
+}
+
+static void rebase_ushort_elts( const ushort *src,
+ unsigned count,
+ int delta,
+ ushort *dest )
+{
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ dest[i] = (ushort)(src[i] + delta);
+}
+
+static void rebase_ubyte_elts( const ubyte *src,
+ unsigned count,
+ int delta,
+ ushort *dest )
+{
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ dest[i] = (ushort)(src[i] + delta);
+}
+
+
+
static void translate_uint_elts( const unsigned *src,
unsigned count,
- int delta,
ushort *dest )
{
unsigned i;
for (i = 0; i < count; i++)
- dest[i] = (ushort)(src[i] + delta);
+ dest[i] = (ushort)(src[i]);
}
static void translate_ushort_elts( const ushort *src,
unsigned count,
- int delta,
ushort *dest )
{
unsigned i;
for (i = 0; i < count; i++)
- dest[i] = (ushort)(src[i] + delta);
+ dest[i] = (ushort)(src[i]);
}
static void translate_ubyte_elts( const ubyte *src,
unsigned count,
- int delta,
ushort *dest )
{
unsigned i;
for (i = 0; i < count; i++)
- dest[i] = (ushort)(src[i] + delta);
+ dest[i] = (ushort)(src[i]);
}
+
+
+
#if 0
static enum pipe_format format_from_get_elt( pt_elt_func get_elt )
{
@@ -282,31 +317,58 @@ static void vcache_check_run( struct draw_pt_front_end *frontend,
if (!storage)
goto fail;
- switch(index_size) {
- case 1:
- translate_ubyte_elts( (const ubyte *)elts,
- draw_count,
- 0 - (int)min_index,
- storage );
- break;
-
- case 2:
- translate_ushort_elts( (const ushort *)elts,
- draw_count,
- 0 - (int)min_index,
- storage );
- break;
-
- case 4:
- translate_uint_elts( (const uint *)elts,
- draw_count,
- 0 - (int)min_index,
- storage );
- break;
-
- default:
- assert(0);
- return;
+ if (min_index == 0) {
+ switch(index_size) {
+ case 1:
+ translate_ubyte_elts( (const ubyte *)elts,
+ draw_count,
+ storage );
+ break;
+
+ case 2:
+ translate_ushort_elts( (const ushort *)elts,
+ draw_count,
+ storage );
+ break;
+
+ case 4:
+ translate_uint_elts( (const uint *)elts,
+ draw_count,
+ storage );
+ break;
+
+ default:
+ assert(0);
+ return;
+ }
+ }
+ else {
+ switch(index_size) {
+ case 1:
+ rebase_ubyte_elts( (const ubyte *)elts,
+ draw_count,
+ 0 - (int)min_index,
+ storage );
+ break;
+
+ case 2:
+ rebase_ushort_elts( (const ushort *)elts,
+ draw_count,
+ 0 - (int)min_index,
+ storage );
+ break;
+
+ case 4:
+ rebase_uint_elts( (const uint *)elts,
+ draw_count,
+ 0 - (int)min_index,
+ storage );
+ break;
+
+ default:
+ assert(0);
+ return;
+ }
}
transformed_elts = storage;
}
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index ce35112fc1..979f9864fd 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -49,10 +49,10 @@ void draw_vs_set_constants( struct draw_context *draw,
if (((unsigned)constants) & 0xf) {
if (size > draw->vs.const_storage_size) {
if (draw->vs.aligned_constant_storage)
- align_free(draw->vs.aligned_constant_storage);
+ align_free((void *)draw->vs.aligned_constant_storage);
draw->vs.aligned_constant_storage = align_malloc( size, 16 );
}
- memcpy( draw->vs.aligned_constant_storage,
+ memcpy( (void*)draw->vs.aligned_constant_storage,
constants,
size );
constants = draw->vs.aligned_constant_storage;
@@ -174,7 +174,7 @@ draw_vs_destroy( struct draw_context *draw )
draw_vs_aos_machine_destroy(draw->vs.aos_machine);
if (draw->vs.aligned_constant_storage)
- align_free(draw->vs.aligned_constant_storage);
+ align_free((void*)draw->vs.aligned_constant_storage);
tgsi_exec_machine_free_data(&draw->vs.machine);
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 3cf4a4d125..45f36cff2a 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.c
@@ -492,7 +492,7 @@ static struct x86_reg fetch_src( struct aos_compilation *cp,
src->SrcRegister.File,
src->SrcRegister.Index);
unsigned i;
- unsigned swz = 0;
+ ubyte swz = 0;
unsigned negs = 0;
unsigned abs = 0;
@@ -703,7 +703,7 @@ static void store_dest( struct aos_compilation *cp,
static void inject_scalar( struct aos_compilation *cp,
struct x86_reg dst,
struct x86_reg result,
- unsigned swizzle )
+ ubyte swizzle )
{
sse_shufps(cp->func, dst, dst, swizzle);
sse_movss(cp->func, dst, result);
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index 45e2092209..b720185709 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -118,7 +118,7 @@ static void get_src_ptr( struct aos_compilation *cp,
static void emit_swizzle( struct aos_compilation *cp,
struct x86_reg dest,
struct x86_reg src,
- unsigned shuffle )
+ ubyte shuffle )
{
sse_shufps(cp->func, dest, src, shuffle);
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index 24f619a278..0aa0c9a76b 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -31,9 +31,11 @@
* Brian Paul
*/
+#include "pipe/p_config.h"
+
#include "draw_vs.h"
-#if defined(__i386__) || defined(__386__)
+#if defined(PIPE_ARCH_X86)
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
@@ -48,7 +50,7 @@
#define SSE_MAX_VERTICES 4
-typedef void (XSTDCALL *codegen_function) (
+typedef void (PIPE_CDECL *codegen_function) (
const struct tgsi_exec_vector *input, /* 1 */
struct tgsi_exec_vector *output, /* 2 */
float (*constant)[4], /* 3 */
@@ -128,7 +130,7 @@ vs_sse_delete( struct draw_vertex_shader *base )
x86_release_func( &shader->sse2_program );
- align_free(shader->base.immediates);
+ align_free( (void *) shader->base.immediates );
FREE( (void*) shader->base.state.tokens );
FREE( shader );
@@ -183,7 +185,7 @@ draw_create_vs_sse(struct draw_context *draw,
return &vs->base;
fail:
- fprintf(stderr, "tgsi_emit_sse2() failed, falling back to interpreter\n");
+ debug_error("tgsi_emit_sse2() failed, falling back to interpreter\n");
x86_release_func( &vs->sse2_program );
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 9695358ab8..98014bdaa1 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -96,10 +96,8 @@ translate_declaration(struct gallivm_ir *prog,
unsigned first, last, mask;
uint interp_method;
- assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE);
-
- first = decl->u.DeclarationRange.First;
- last = decl->u.DeclarationRange.Last;
+ first = decl->DeclarationRange.First;
+ last = decl->DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
/* Do not touch WPOS.xy */
@@ -113,7 +111,7 @@ translate_declaration(struct gallivm_ir *prog,
}
}
- interp_method = decl->Interpolation.Interpolate;
+ interp_method = decl->Declaration.Interpolate;
if (mask == TGSI_WRITEMASK_XYZW) {
unsigned i, j;
@@ -153,7 +151,7 @@ translate_declarationir(struct gallivm_ir *,
struct tgsi_full_declaration *)
{
if (decl->Declaration.File == TGSI_FILE_ADDRESS) {
- int idx = decl->u.DeclarationRange.First;
+ int idx = decl->DeclarationRange.First;
storage->addAddress(idx);
}
}
diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
index f01e12faa0..5499018b21 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
@@ -47,7 +47,7 @@ static boolean rtasm_sse_enabled(void)
int rtasm_cpu_has_sse(void)
{
/* FIXME: actually detect this at run-time */
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#if defined(PIPE_ARCH_X86)
return rtasm_sse_enabled();
#else
return 0;
@@ -57,7 +57,7 @@ int rtasm_cpu_has_sse(void)
int rtasm_cpu_has_sse2(void)
{
/* FIXME: actually detect this at run-time */
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#if defined(PIPE_ARCH_X86)
return rtasm_sse_enabled();
#else
return 0;
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
index 672d2ff554..f4ca282dd9 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.c
@@ -21,7 +21,9 @@
*
**************************************************************************/
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#include "pipe/p_config.h"
+
+#if defined(PIPE_ARCH_X86)
#include "pipe/p_compiler.h"
#include "pipe/p_debug.h"
@@ -886,7 +888,7 @@ void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg sr
void sse_cmpps( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src,
- unsigned char cc)
+ enum sse_cc cc)
{
DUMP_RRI( dst, src, cc );
emit_2ub(p, X86_TWOB, 0xC2);
diff --git a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
index 63e812fac9..af94577aab 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_x86sse.h
@@ -24,7 +24,9 @@
#ifndef _RTASM_X86SSE_H_
#define _RTASM_X86SSE_H_
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#include "pipe/p_config.h"
+
+#if defined(PIPE_ARCH_X86)
/* It is up to the caller to ensure that instructions issued are
* suitable for the host cpu. There are no checks made in this module
@@ -189,7 +191,7 @@ void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src )
void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src,
- unsigned char cc );
+ enum sse_cc cc );
void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
index 826b432f09..6689c3f1fb 100644
--- a/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
@@ -1411,13 +1411,11 @@ exec_declaration(
unsigned first, last, mask;
eval_coef_func eval;
- assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE );
-
- first = decl->u.DeclarationRange.First;
- last = decl->u.DeclarationRange.Last;
+ first = decl->DeclarationRange.First;
+ last = decl->DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
- switch( decl->Interpolation.Interpolate ) {
+ switch( decl->Declaration.Interpolate ) {
case TGSI_INTERPOLATE_CONSTANT:
eval = eval_constant_coef;
break;
@@ -1479,7 +1477,7 @@ exec_instruction(
break;
case TGSI_OPCODE_MOV:
- /* TGSI_OPCODE_SWZ */
+ case TGSI_OPCODE_SWZ:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
STORE( &r[0], 0, chan_index );
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
index 189dc6024d..cdbdf5c882 100755
--- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
@@ -194,22 +194,12 @@ get_coef(
}
-#ifdef WIN32
-static void
-emit_retw(
- struct x86_function *func,
- unsigned short size )
-{
- x86_retw( func, size );
-}
-#else
static void
emit_ret(
struct x86_function *func )
{
x86_ret( func );
}
-#endif
/**
@@ -475,7 +465,7 @@ static void
emit_func_call_dst(
struct x86_function *func,
unsigned xmm_dst,
- void (*code)() )
+ void (PIPE_CDECL *code)() )
{
sse_movaps(
func,
@@ -496,9 +486,7 @@ emit_func_call_dst(
x86_push( func, ecx );
x86_mov_reg_imm( func, ecx, (unsigned long) code );
x86_call( func, ecx );
-#ifndef WIN32
x86_pop(func, ecx );
-#endif
}
@@ -516,7 +504,7 @@ emit_func_call_dst_src(
struct x86_function *func,
unsigned xmm_dst,
unsigned xmm_src,
- void (*code)() )
+ void (PIPE_CDECL *code)() )
{
sse_movaps(
func,
@@ -558,7 +546,7 @@ emit_add(
make_xmm( xmm_src ) );
}
-static void XSTDCALL
+static void PIPE_CDECL
cos4f(
float *store )
{
@@ -581,7 +569,7 @@ emit_cos(
cos4f );
}
-static void XSTDCALL
+static void PIPE_CDECL
ex24f(
float *store )
{
@@ -615,7 +603,7 @@ emit_f2it(
make_xmm( xmm ) );
}
-static void XSTDCALL
+static void PIPE_CDECL
flr4f(
float *store )
{
@@ -638,7 +626,7 @@ emit_flr(
flr4f );
}
-static void XSTDCALL
+static void PIPE_CDECL
frc4f(
float *store )
{
@@ -661,7 +649,7 @@ emit_frc(
frc4f );
}
-static void XSTDCALL
+static void PIPE_CDECL
lg24f(
float *store )
{
@@ -720,7 +708,7 @@ emit_neg(
TGSI_EXEC_TEMP_80000000_C ) );
}
-static void XSTDCALL
+static void PIPE_CDECL
pow4f(
float *store )
{
@@ -820,7 +808,7 @@ emit_setsign(
TGSI_EXEC_TEMP_80000000_C ) );
}
-static void XSTDCALL
+static void PIPE_CDECL
sin4f(
float *store )
{
@@ -1190,7 +1178,7 @@ emit_instruction(
break;
case TGSI_OPCODE_MOV:
- /* TGSI_OPCODE_SWZ */
+ case TGSI_OPCODE_SWZ:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
STORE( func, *inst, 0, 0, chan_index );
@@ -1736,11 +1724,7 @@ emit_instruction(
break;
case TGSI_OPCODE_RET:
-#ifdef WIN32
- emit_retw( func, 16 );
-#else
emit_ret( func );
-#endif
break;
case TGSI_OPCODE_END:
@@ -1923,16 +1907,14 @@ emit_declaration(
unsigned first, last, mask;
unsigned i, j;
- assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE );
-
- first = decl->u.DeclarationRange.First;
- last = decl->u.DeclarationRange.Last;
+ first = decl->DeclarationRange.First;
+ last = decl->DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
for( i = first; i <= last; i++ ) {
for( j = 0; j < NUM_CHANNELS; j++ ) {
if( mask & (1 << j) ) {
- switch( decl->Interpolation.Interpolate ) {
+ switch( decl->Declaration.Interpolate ) {
case TGSI_INTERPOLATE_CONSTANT:
emit_coef_a0( func, 0, i, j );
emit_inputs( func, 0, i, j );
@@ -2283,11 +2265,7 @@ tgsi_emit_sse2(
func,
get_immediate_base() );
-#ifdef WIN32
- emit_retw( func, 16 );
-#else
emit_ret( func );
-#endif
tgsi_parse_free( &parse );
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.c b/src/gallium/auxiliary/tgsi/util/tgsi_build.c
index 9c883ab704..18e44b38c2 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.c
@@ -90,9 +90,8 @@ tgsi_default_declaration( void )
declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
declaration.Size = 1;
declaration.File = TGSI_FILE_NULL;
- declaration.Declare = TGSI_DECLARE_RANGE;
declaration.UsageMask = TGSI_WRITEMASK_XYZW;
- declaration.Interpolate = 0;
+ declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT;
declaration.Semantic = 0;
declaration.Padding = 0;
declaration.Extended = 0;
@@ -103,7 +102,6 @@ tgsi_default_declaration( void )
struct tgsi_declaration
tgsi_build_declaration(
unsigned file,
- unsigned declare,
unsigned usage_mask,
unsigned interpolate,
unsigned semantic,
@@ -112,11 +110,10 @@ tgsi_build_declaration(
struct tgsi_declaration declaration;
assert( file <= TGSI_FILE_IMMEDIATE );
- assert( declare <= TGSI_DECLARE_MASK );
+ assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE );
declaration = tgsi_default_declaration();
declaration.File = file;
- declaration.Declare = declare;
declaration.UsageMask = usage_mask;
declaration.Interpolate = interpolate;
declaration.Semantic = semantic;
@@ -144,7 +141,7 @@ tgsi_default_full_declaration( void )
struct tgsi_full_declaration full_declaration;
full_declaration.Declaration = tgsi_default_declaration();
- full_declaration.Interpolation = tgsi_default_declaration_interpolation();
+ full_declaration.DeclarationRange = tgsi_default_declaration_range();
full_declaration.Semantic = tgsi_default_declaration_semantic();
return full_declaration;
@@ -159,6 +156,7 @@ tgsi_build_full_declaration(
{
unsigned size = 0;
struct tgsi_declaration *declaration;
+ struct tgsi_declaration_range *dr;
if( maxsize <= size )
return 0;
@@ -167,63 +165,21 @@ tgsi_build_full_declaration(
*declaration = tgsi_build_declaration(
full_decl->Declaration.File,
- full_decl->Declaration.Declare,
full_decl->Declaration.UsageMask,
full_decl->Declaration.Interpolate,
full_decl->Declaration.Semantic,
header );
- switch( full_decl->Declaration.Declare ) {
- case TGSI_DECLARE_RANGE:
- {
- struct tgsi_declaration_range *dr;
-
- if( maxsize <= size )
- return 0;
- dr = (struct tgsi_declaration_range *) &tokens[size];
- size++;
-
- *dr = tgsi_build_declaration_range(
- full_decl->u.DeclarationRange.First,
- full_decl->u.DeclarationRange.Last,
- declaration,
- header );
- break;
- }
-
- case TGSI_DECLARE_MASK:
- {
- struct tgsi_declaration_mask *dm;
-
- if( maxsize <= size )
- return 0;
- dm = (struct tgsi_declaration_mask *) &tokens[size];
- size++;
-
- *dm = tgsi_build_declaration_mask(
- full_decl->u.DeclarationMask.Mask,
- declaration,
- header );
- break;
- }
-
- default:
- assert( 0 );
- }
-
- if( full_decl->Declaration.Interpolate ) {
- struct tgsi_declaration_interpolation *di;
-
- if( maxsize <= size )
- return 0;
- di = (struct tgsi_declaration_interpolation *) &tokens[size];
- size++;
+ if (maxsize <= size)
+ return 0;
+ dr = (struct tgsi_declaration_range *) &tokens[size];
+ size++;
- *di = tgsi_build_declaration_interpolation(
- full_decl->Interpolation.Interpolate,
- declaration,
- header );
- }
+ *dr = tgsi_build_declaration_range(
+ full_decl->DeclarationRange.First,
+ full_decl->DeclarationRange.Last,
+ declaration,
+ header );
if( full_decl->Declaration.Semantic ) {
struct tgsi_declaration_semantic *ds;
@@ -244,6 +200,17 @@ tgsi_build_full_declaration(
}
struct tgsi_declaration_range
+tgsi_default_declaration_range( void )
+{
+ struct tgsi_declaration_range dr;
+
+ dr.First = 0;
+ dr.Last = 0;
+
+ return dr;
+}
+
+struct tgsi_declaration_range
tgsi_build_declaration_range(
unsigned first,
unsigned last,
@@ -255,6 +222,7 @@ tgsi_build_declaration_range(
assert( last >= first );
assert( last <= 0xFFFF );
+ declaration_range = tgsi_default_declaration_range();
declaration_range.First = first;
declaration_range.Last = last;
@@ -263,50 +231,6 @@ tgsi_build_declaration_range(
return declaration_range;
}
-struct tgsi_declaration_mask
-tgsi_build_declaration_mask(
- unsigned mask,
- struct tgsi_declaration *declaration,
- struct tgsi_header *header )
-{
- struct tgsi_declaration_mask declaration_mask;
-
- declaration_mask.Mask = mask;
-
- declaration_grow( declaration, header );
-
- return declaration_mask;
-}
-
-struct tgsi_declaration_interpolation
-tgsi_default_declaration_interpolation( void )
-{
- struct tgsi_declaration_interpolation di;
-
- di.Interpolate = TGSI_INTERPOLATE_CONSTANT;
- di.Padding = 0;
-
- return di;
-}
-
-struct tgsi_declaration_interpolation
-tgsi_build_declaration_interpolation(
- unsigned interpolate,
- struct tgsi_declaration *declaration,
- struct tgsi_header *header )
-{
- struct tgsi_declaration_interpolation di;
-
- assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE );
-
- di = tgsi_default_declaration_interpolation();
- di.Interpolate = interpolate;
-
- declaration_grow( declaration, header );
-
- return di;
-}
-
struct tgsi_declaration_semantic
tgsi_default_declaration_semantic( void )
{
@@ -704,6 +628,14 @@ tgsi_build_full_instruction(
tgsi_default_src_register_ext_swz() ) ) {
struct tgsi_src_register_ext_swz *src_register_ext_swz;
+ /* Use of the extended swizzle requires the simple swizzle to be identity.
+ */
+ assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X );
+ assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y );
+ assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z );
+ assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W );
+ assert( reg->SrcRegister.Negate == FALSE );
+
if( maxsize <= size )
return 0;
src_register_ext_swz =
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_build.h b/src/gallium/auxiliary/tgsi/util/tgsi_build.h
index 80bffc4ae7..423cf141f5 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_build.h
@@ -37,7 +37,6 @@ tgsi_default_declaration( void );
struct tgsi_declaration
tgsi_build_declaration(
unsigned file,
- unsigned declare,
unsigned usage_mask,
unsigned interpolate,
unsigned semantic,
@@ -54,27 +53,15 @@ tgsi_build_full_declaration(
unsigned maxsize );
struct tgsi_declaration_range
+tgsi_default_declaration_range( void );
+
+struct tgsi_declaration_range
tgsi_build_declaration_range(
unsigned first,
unsigned last,
struct tgsi_declaration *declaration,
struct tgsi_header *header );
-struct tgsi_declaration_mask
-tgsi_build_declaration_mask(
- unsigned mask,
- struct tgsi_declaration *declaration,
- struct tgsi_header *header );
-
-struct tgsi_declaration_interpolation
-tgsi_default_declaration_interpolation( void );
-
-struct tgsi_declaration_interpolation
-tgsi_build_declaration_interpolation(
- unsigned interpolate,
- struct tgsi_declaration *declaration,
- struct tgsi_header *header );
-
struct tgsi_declaration_semantic
tgsi_default_declaration_semantic( void );
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index b018ea9fa1..d1a3dfd9c7 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -546,19 +546,13 @@ tgsi_dump_declaration(
TXT( "\nDCL " );
ENM( decl->Declaration.File, TGSI_FILES_SHORT );
- switch( decl->Declaration.Declare ) {
- case TGSI_DECLARE_RANGE:
- CHR( '[' );
- UID( decl->u.DeclarationRange.First );
- if( decl->u.DeclarationRange.First != decl->u.DeclarationRange.Last ) {
- TXT( ".." );
- UID( decl->u.DeclarationRange.Last );
- }
- CHR( ']' );
- break;
- default:
- assert( 0 );
+ CHR( '[' );
+ UID( decl->DeclarationRange.First );
+ if (decl->DeclarationRange.First != decl->DeclarationRange.Last) {
+ TXT( ".." );
+ UID( decl->DeclarationRange.Last );
}
+ CHR( ']' );
if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) {
CHR( '.' );
@@ -586,10 +580,8 @@ tgsi_dump_declaration(
}
}
- if (decl->Declaration.Interpolate) {
- TXT( ", " );
- ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT );
- }
+ TXT( ", " );
+ ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES_SHORT );
}
static void
@@ -601,8 +593,6 @@ dump_declaration_verbose(
{
TXT( "\nFile : " );
ENM( decl->Declaration.File, TGSI_FILES );
- TXT( "\nDeclare : " );
- ENM( decl->Declaration.Declare, TGSI_DECLARES );
if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) {
TXT( "\nUsageMask : " );
if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) {
@@ -620,7 +610,7 @@ dump_declaration_verbose(
}
if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) {
TXT( "\nInterpolate: " );
- UID( decl->Declaration.Interpolate );
+ ENM( decl->Declaration.Interpolate, TGSI_INTERPOLATES );
}
if( deflt || fd->Declaration.Semantic != decl->Declaration.Semantic ) {
TXT( "\nSemantic : " );
@@ -632,32 +622,10 @@ dump_declaration_verbose(
}
EOL();
- switch( decl->Declaration.Declare ) {
- case TGSI_DECLARE_RANGE:
- TXT( "\nFirst: " );
- UID( decl->u.DeclarationRange.First );
- TXT( "\nLast : " );
- UID( decl->u.DeclarationRange.Last );
- break;
-
- case TGSI_DECLARE_MASK:
- TXT( "\nMask: " );
- UIX( decl->u.DeclarationMask.Mask );
- break;
-
- default:
- assert( 0 );
- }
-
- if( decl->Declaration.Interpolate ) {
- EOL();
- TXT( "\nInterpolate: " );
- ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES );
- if( ignored ) {
- TXT( "\nPadding : " );
- UIX( decl->Interpolation.Padding );
- }
- }
+ TXT( "\nFirst: " );
+ UID( decl->DeclarationRange.First );
+ TXT( "\nLast : " );
+ UID( decl->DeclarationRange.Last );
if( decl->Declaration.Semantic ) {
EOL();
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
index 5c0b0bfd61..d16f0cdcad 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
@@ -118,22 +118,7 @@ tgsi_parse_token(
*decl = tgsi_default_full_declaration();
decl->Declaration = *(struct tgsi_declaration *) &token;
- switch( decl->Declaration.Type ) {
- case TGSI_DECLARE_RANGE:
- next_token( ctx, &decl->u.DeclarationRange );
- break;
-
- case TGSI_DECLARE_MASK:
- next_token( ctx, &decl->u.DeclarationMask );
- break;
-
- default:
- assert (0);
- }
-
- if( decl->Declaration.Interpolate ) {
- next_token( ctx, &decl->Interpolation );
- }
+ next_token( ctx, &decl->DeclarationRange );
if( decl->Declaration.Semantic ) {
next_token( ctx, &decl->Semantic );
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
index 4102101093..054350712d 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
@@ -65,13 +65,8 @@ struct tgsi_full_src_register
struct tgsi_full_declaration
{
struct tgsi_declaration Declaration;
- union
- {
- struct tgsi_declaration_range DeclarationRange;
- struct tgsi_declaration_mask DeclarationMask;
- } u;
- struct tgsi_declaration_interpolation Interpolation;
- struct tgsi_declaration_semantic Semantic;
+ struct tgsi_declaration_range DeclarationRange;
+ struct tgsi_declaration_semantic Semantic;
};
struct tgsi_full_immediate
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c
index 65650ed22a..bda7bc2e2e 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_scan.c
@@ -93,8 +93,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
= &parse.FullToken.FullDeclaration;
uint file = fulldecl->Declaration.File;
uint i;
- for (i = fulldecl->u.DeclarationRange.First;
- i <= fulldecl->u.DeclarationRange.Last;
+ for (i = fulldecl->DeclarationRange.First;
+ i <= fulldecl->DeclarationRange.Last;
i++) {
/* only first 32 regs will appear in this bitfield */
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_util.c b/src/gallium/auxiliary/tgsi/util/tgsi_util.c
index 4cdd89182a..56a50d3b21 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_util.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_util.c
@@ -8,7 +8,7 @@
union pointer_hack
{
void *pointer;
- unsigned long long uint64;
+ uint64_t uint64;
};
void *
diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c
index b04bc6eefd..b93fbf9033 100644
--- a/src/gallium/auxiliary/translate/translate.c
+++ b/src/gallium/auxiliary/translate/translate.c
@@ -30,6 +30,7 @@
* Keith Whitwell <keith@tungstengraphics.com>
*/
+#include "pipe/p_config.h"
#include "pipe/p_util.h"
#include "pipe/p_state.h"
#include "translate.h"
@@ -38,7 +39,7 @@ struct translate *translate_create( const struct translate_key *key )
{
struct translate *translate = NULL;
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#if defined(PIPE_ARCH_X86)
translate = translate_sse2_create( key );
if (translate)
return translate;
diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c
index a25d94f2ca..3fec89b36e 100644
--- a/src/gallium/auxiliary/translate/translate_generic.c
+++ b/src/gallium/auxiliary/translate/translate_generic.c
@@ -255,140 +255,140 @@ static fetch_func get_fetch_func( enum pipe_format format )
{
switch (format) {
case PIPE_FORMAT_R64_FLOAT:
- return fetch_R64_FLOAT;
+ return &fetch_R64_FLOAT;
case PIPE_FORMAT_R64G64_FLOAT:
- return fetch_R64G64_FLOAT;
+ return &fetch_R64G64_FLOAT;
case PIPE_FORMAT_R64G64B64_FLOAT:
- return fetch_R64G64B64_FLOAT;
+ return &fetch_R64G64B64_FLOAT;
case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return fetch_R64G64B64A64_FLOAT;
+ return &fetch_R64G64B64A64_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
- return fetch_R32_FLOAT;
+ return &fetch_R32_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
- return fetch_R32G32_FLOAT;
+ return &fetch_R32G32_FLOAT;
case PIPE_FORMAT_R32G32B32_FLOAT:
- return fetch_R32G32B32_FLOAT;
+ return &fetch_R32G32B32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return fetch_R32G32B32A32_FLOAT;
+ return &fetch_R32G32B32A32_FLOAT;
case PIPE_FORMAT_R32_UNORM:
- return fetch_R32_UNORM;
+ return &fetch_R32_UNORM;
case PIPE_FORMAT_R32G32_UNORM:
- return fetch_R32G32_UNORM;
+ return &fetch_R32G32_UNORM;
case PIPE_FORMAT_R32G32B32_UNORM:
- return fetch_R32G32B32_UNORM;
+ return &fetch_R32G32B32_UNORM;
case PIPE_FORMAT_R32G32B32A32_UNORM:
- return fetch_R32G32B32A32_UNORM;
+ return &fetch_R32G32B32A32_UNORM;
case PIPE_FORMAT_R32_USCALED:
- return fetch_R32_USCALED;
+ return &fetch_R32_USCALED;
case PIPE_FORMAT_R32G32_USCALED:
- return fetch_R32G32_USCALED;
+ return &fetch_R32G32_USCALED;
case PIPE_FORMAT_R32G32B32_USCALED:
- return fetch_R32G32B32_USCALED;
+ return &fetch_R32G32B32_USCALED;
case PIPE_FORMAT_R32G32B32A32_USCALED:
- return fetch_R32G32B32A32_USCALED;
+ return &fetch_R32G32B32A32_USCALED;
case PIPE_FORMAT_R32_SNORM:
- return fetch_R32_SNORM;
+ return &fetch_R32_SNORM;
case PIPE_FORMAT_R32G32_SNORM:
- return fetch_R32G32_SNORM;
+ return &fetch_R32G32_SNORM;
case PIPE_FORMAT_R32G32B32_SNORM:
- return fetch_R32G32B32_SNORM;
+ return &fetch_R32G32B32_SNORM;
case PIPE_FORMAT_R32G32B32A32_SNORM:
- return fetch_R32G32B32A32_SNORM;
+ return &fetch_R32G32B32A32_SNORM;
case PIPE_FORMAT_R32_SSCALED:
- return fetch_R32_SSCALED;
+ return &fetch_R32_SSCALED;
case PIPE_FORMAT_R32G32_SSCALED:
- return fetch_R32G32_SSCALED;
+ return &fetch_R32G32_SSCALED;
case PIPE_FORMAT_R32G32B32_SSCALED:
- return fetch_R32G32B32_SSCALED;
+ return &fetch_R32G32B32_SSCALED;
case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return fetch_R32G32B32A32_SSCALED;
+ return &fetch_R32G32B32A32_SSCALED;
case PIPE_FORMAT_R16_UNORM:
- return fetch_R16_UNORM;
+ return &fetch_R16_UNORM;
case PIPE_FORMAT_R16G16_UNORM:
- return fetch_R16G16_UNORM;
+ return &fetch_R16G16_UNORM;
case PIPE_FORMAT_R16G16B16_UNORM:
- return fetch_R16G16B16_UNORM;
+ return &fetch_R16G16B16_UNORM;
case PIPE_FORMAT_R16G16B16A16_UNORM:
- return fetch_R16G16B16A16_UNORM;
+ return &fetch_R16G16B16A16_UNORM;
case PIPE_FORMAT_R16_USCALED:
- return fetch_R16_USCALED;
+ return &fetch_R16_USCALED;
case PIPE_FORMAT_R16G16_USCALED:
- return fetch_R16G16_USCALED;
+ return &fetch_R16G16_USCALED;
case PIPE_FORMAT_R16G16B16_USCALED:
- return fetch_R16G16B16_USCALED;
+ return &fetch_R16G16B16_USCALED;
case PIPE_FORMAT_R16G16B16A16_USCALED:
- return fetch_R16G16B16A16_USCALED;
+ return &fetch_R16G16B16A16_USCALED;
case PIPE_FORMAT_R16_SNORM:
- return fetch_R16_SNORM;
+ return &fetch_R16_SNORM;
case PIPE_FORMAT_R16G16_SNORM:
- return fetch_R16G16_SNORM;
+ return &fetch_R16G16_SNORM;
case PIPE_FORMAT_R16G16B16_SNORM:
- return fetch_R16G16B16_SNORM;
+ return &fetch_R16G16B16_SNORM;
case PIPE_FORMAT_R16G16B16A16_SNORM:
- return fetch_R16G16B16A16_SNORM;
+ return &fetch_R16G16B16A16_SNORM;
case PIPE_FORMAT_R16_SSCALED:
- return fetch_R16_SSCALED;
+ return &fetch_R16_SSCALED;
case PIPE_FORMAT_R16G16_SSCALED:
- return fetch_R16G16_SSCALED;
+ return &fetch_R16G16_SSCALED;
case PIPE_FORMAT_R16G16B16_SSCALED:
- return fetch_R16G16B16_SSCALED;
+ return &fetch_R16G16B16_SSCALED;
case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return fetch_R16G16B16A16_SSCALED;
+ return &fetch_R16G16B16A16_SSCALED;
case PIPE_FORMAT_R8_UNORM:
- return fetch_R8_UNORM;
+ return &fetch_R8_UNORM;
case PIPE_FORMAT_R8G8_UNORM:
- return fetch_R8G8_UNORM;
+ return &fetch_R8G8_UNORM;
case PIPE_FORMAT_R8G8B8_UNORM:
- return fetch_R8G8B8_UNORM;
+ return &fetch_R8G8B8_UNORM;
case PIPE_FORMAT_R8G8B8A8_UNORM:
- return fetch_R8G8B8A8_UNORM;
+ return &fetch_R8G8B8A8_UNORM;
case PIPE_FORMAT_R8_USCALED:
- return fetch_R8_USCALED;
+ return &fetch_R8_USCALED;
case PIPE_FORMAT_R8G8_USCALED:
- return fetch_R8G8_USCALED;
+ return &fetch_R8G8_USCALED;
case PIPE_FORMAT_R8G8B8_USCALED:
- return fetch_R8G8B8_USCALED;
+ return &fetch_R8G8B8_USCALED;
case PIPE_FORMAT_R8G8B8A8_USCALED:
- return fetch_R8G8B8A8_USCALED;
+ return &fetch_R8G8B8A8_USCALED;
case PIPE_FORMAT_R8_SNORM:
- return fetch_R8_SNORM;
+ return &fetch_R8_SNORM;
case PIPE_FORMAT_R8G8_SNORM:
- return fetch_R8G8_SNORM;
+ return &fetch_R8G8_SNORM;
case PIPE_FORMAT_R8G8B8_SNORM:
- return fetch_R8G8B8_SNORM;
+ return &fetch_R8G8B8_SNORM;
case PIPE_FORMAT_R8G8B8A8_SNORM:
- return fetch_R8G8B8A8_SNORM;
+ return &fetch_R8G8B8A8_SNORM;
case PIPE_FORMAT_R8_SSCALED:
- return fetch_R8_SSCALED;
+ return &fetch_R8_SSCALED;
case PIPE_FORMAT_R8G8_SSCALED:
- return fetch_R8G8_SSCALED;
+ return &fetch_R8G8_SSCALED;
case PIPE_FORMAT_R8G8B8_SSCALED:
- return fetch_R8G8B8_SSCALED;
+ return &fetch_R8G8B8_SSCALED;
case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return fetch_R8G8B8A8_SSCALED;
+ return &fetch_R8G8B8A8_SSCALED;
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return fetch_A8R8G8B8_UNORM;
+ return &fetch_A8R8G8B8_UNORM;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- return fetch_B8G8R8A8_UNORM;
+ return &fetch_B8G8R8A8_UNORM;
default:
assert(0);
- return fetch_NULL;
+ return &fetch_NULL;
}
}
@@ -399,140 +399,140 @@ static emit_func get_emit_func( enum pipe_format format )
{
switch (format) {
case PIPE_FORMAT_R64_FLOAT:
- return emit_R64_FLOAT;
+ return &emit_R64_FLOAT;
case PIPE_FORMAT_R64G64_FLOAT:
- return emit_R64G64_FLOAT;
+ return &emit_R64G64_FLOAT;
case PIPE_FORMAT_R64G64B64_FLOAT:
- return emit_R64G64B64_FLOAT;
+ return &emit_R64G64B64_FLOAT;
case PIPE_FORMAT_R64G64B64A64_FLOAT:
- return emit_R64G64B64A64_FLOAT;
+ return &emit_R64G64B64A64_FLOAT;
case PIPE_FORMAT_R32_FLOAT:
- return emit_R32_FLOAT;
+ return &emit_R32_FLOAT;
case PIPE_FORMAT_R32G32_FLOAT:
- return emit_R32G32_FLOAT;
+ return &emit_R32G32_FLOAT;
case PIPE_FORMAT_R32G32B32_FLOAT:
- return emit_R32G32B32_FLOAT;
+ return &emit_R32G32B32_FLOAT;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
- return emit_R32G32B32A32_FLOAT;
+ return &emit_R32G32B32A32_FLOAT;
case PIPE_FORMAT_R32_UNORM:
- return emit_R32_UNORM;
+ return &emit_R32_UNORM;
case PIPE_FORMAT_R32G32_UNORM:
- return emit_R32G32_UNORM;
+ return &emit_R32G32_UNORM;
case PIPE_FORMAT_R32G32B32_UNORM:
- return emit_R32G32B32_UNORM;
+ return &emit_R32G32B32_UNORM;
case PIPE_FORMAT_R32G32B32A32_UNORM:
- return emit_R32G32B32A32_UNORM;
+ return &emit_R32G32B32A32_UNORM;
case PIPE_FORMAT_R32_USCALED:
- return emit_R32_USCALED;
+ return &emit_R32_USCALED;
case PIPE_FORMAT_R32G32_USCALED:
- return emit_R32G32_USCALED;
+ return &emit_R32G32_USCALED;
case PIPE_FORMAT_R32G32B32_USCALED:
- return emit_R32G32B32_USCALED;
+ return &emit_R32G32B32_USCALED;
case PIPE_FORMAT_R32G32B32A32_USCALED:
- return emit_R32G32B32A32_USCALED;
+ return &emit_R32G32B32A32_USCALED;
case PIPE_FORMAT_R32_SNORM:
- return emit_R32_SNORM;
+ return &emit_R32_SNORM;
case PIPE_FORMAT_R32G32_SNORM:
- return emit_R32G32_SNORM;
+ return &emit_R32G32_SNORM;
case PIPE_FORMAT_R32G32B32_SNORM:
- return emit_R32G32B32_SNORM;
+ return &emit_R32G32B32_SNORM;
case PIPE_FORMAT_R32G32B32A32_SNORM:
- return emit_R32G32B32A32_SNORM;
+ return &emit_R32G32B32A32_SNORM;
case PIPE_FORMAT_R32_SSCALED:
- return emit_R32_SSCALED;
+ return &emit_R32_SSCALED;
case PIPE_FORMAT_R32G32_SSCALED:
- return emit_R32G32_SSCALED;
+ return &emit_R32G32_SSCALED;
case PIPE_FORMAT_R32G32B32_SSCALED:
- return emit_R32G32B32_SSCALED;
+ return &emit_R32G32B32_SSCALED;
case PIPE_FORMAT_R32G32B32A32_SSCALED:
- return emit_R32G32B32A32_SSCALED;
+ return &emit_R32G32B32A32_SSCALED;
case PIPE_FORMAT_R16_UNORM:
- return emit_R16_UNORM;
+ return &emit_R16_UNORM;
case PIPE_FORMAT_R16G16_UNORM:
- return emit_R16G16_UNORM;
+ return &emit_R16G16_UNORM;
case PIPE_FORMAT_R16G16B16_UNORM:
- return emit_R16G16B16_UNORM;
+ return &emit_R16G16B16_UNORM;
case PIPE_FORMAT_R16G16B16A16_UNORM:
- return emit_R16G16B16A16_UNORM;
+ return &emit_R16G16B16A16_UNORM;
case PIPE_FORMAT_R16_USCALED:
- return emit_R16_USCALED;
+ return &emit_R16_USCALED;
case PIPE_FORMAT_R16G16_USCALED:
- return emit_R16G16_USCALED;
+ return &emit_R16G16_USCALED;
case PIPE_FORMAT_R16G16B16_USCALED:
- return emit_R16G16B16_USCALED;
+ return &emit_R16G16B16_USCALED;
case PIPE_FORMAT_R16G16B16A16_USCALED:
- return emit_R16G16B16A16_USCALED;
+ return &emit_R16G16B16A16_USCALED;
case PIPE_FORMAT_R16_SNORM:
- return emit_R16_SNORM;
+ return &emit_R16_SNORM;
case PIPE_FORMAT_R16G16_SNORM:
- return emit_R16G16_SNORM;
+ return &emit_R16G16_SNORM;
case PIPE_FORMAT_R16G16B16_SNORM:
- return emit_R16G16B16_SNORM;
+ return &emit_R16G16B16_SNORM;
case PIPE_FORMAT_R16G16B16A16_SNORM:
- return emit_R16G16B16A16_SNORM;
+ return &emit_R16G16B16A16_SNORM;
case PIPE_FORMAT_R16_SSCALED:
- return emit_R16_SSCALED;
+ return &emit_R16_SSCALED;
case PIPE_FORMAT_R16G16_SSCALED:
- return emit_R16G16_SSCALED;
+ return &emit_R16G16_SSCALED;
case PIPE_FORMAT_R16G16B16_SSCALED:
- return emit_R16G16B16_SSCALED;
+ return &emit_R16G16B16_SSCALED;
case PIPE_FORMAT_R16G16B16A16_SSCALED:
- return emit_R16G16B16A16_SSCALED;
+ return &emit_R16G16B16A16_SSCALED;
case PIPE_FORMAT_R8_UNORM:
- return emit_R8_UNORM;
+ return &emit_R8_UNORM;
case PIPE_FORMAT_R8G8_UNORM:
- return emit_R8G8_UNORM;
+ return &emit_R8G8_UNORM;
case PIPE_FORMAT_R8G8B8_UNORM:
- return emit_R8G8B8_UNORM;
+ return &emit_R8G8B8_UNORM;
case PIPE_FORMAT_R8G8B8A8_UNORM:
- return emit_R8G8B8A8_UNORM;
+ return &emit_R8G8B8A8_UNORM;
case PIPE_FORMAT_R8_USCALED:
- return emit_R8_USCALED;
+ return &emit_R8_USCALED;
case PIPE_FORMAT_R8G8_USCALED:
- return emit_R8G8_USCALED;
+ return &emit_R8G8_USCALED;
case PIPE_FORMAT_R8G8B8_USCALED:
- return emit_R8G8B8_USCALED;
+ return &emit_R8G8B8_USCALED;
case PIPE_FORMAT_R8G8B8A8_USCALED:
- return emit_R8G8B8A8_USCALED;
+ return &emit_R8G8B8A8_USCALED;
case PIPE_FORMAT_R8_SNORM:
- return emit_R8_SNORM;
+ return &emit_R8_SNORM;
case PIPE_FORMAT_R8G8_SNORM:
- return emit_R8G8_SNORM;
+ return &emit_R8G8_SNORM;
case PIPE_FORMAT_R8G8B8_SNORM:
- return emit_R8G8B8_SNORM;
+ return &emit_R8G8B8_SNORM;
case PIPE_FORMAT_R8G8B8A8_SNORM:
- return emit_R8G8B8A8_SNORM;
+ return &emit_R8G8B8A8_SNORM;
case PIPE_FORMAT_R8_SSCALED:
- return emit_R8_SSCALED;
+ return &emit_R8_SSCALED;
case PIPE_FORMAT_R8G8_SSCALED:
- return emit_R8G8_SSCALED;
+ return &emit_R8G8_SSCALED;
case PIPE_FORMAT_R8G8B8_SSCALED:
- return emit_R8G8B8_SSCALED;
+ return &emit_R8G8B8_SSCALED;
case PIPE_FORMAT_R8G8B8A8_SSCALED:
- return emit_R8G8B8A8_SSCALED;
+ return &emit_R8G8B8A8_SSCALED;
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return emit_A8R8G8B8_UNORM;
+ return &emit_A8R8G8B8_UNORM;
case PIPE_FORMAT_B8G8R8A8_UNORM:
- return emit_B8G8R8A8_UNORM;
+ return &emit_B8G8R8A8_UNORM;
default:
assert(0);
- return emit_NULL;
+ return &emit_NULL;
}
}
diff --git a/src/gallium/auxiliary/translate/translate_sse.c b/src/gallium/auxiliary/translate/translate_sse.c
index be48a14737..18a212ac1c 100644
--- a/src/gallium/auxiliary/translate/translate_sse.c
+++ b/src/gallium/auxiliary/translate/translate_sse.c
@@ -26,6 +26,7 @@
*/
+#include "pipe/p_config.h"
#include "pipe/p_compiler.h"
#include "pipe/p_util.h"
#include "util/u_simple_list.h"
@@ -33,7 +34,7 @@
#include "translate.h"
-#if defined(__i386__) || defined(__386__) || defined(i386)
+#if defined(PIPE_ARCH_X86)
#include "rtasm/rtasm_cpu.h"
#include "rtasm/rtasm_x86sse.h"
@@ -605,7 +606,7 @@ struct translate *translate_sse2_create( const struct translate_key *key )
#else
-void translate_create_sse( const struct translate_key *key )
+struct translate *translate_sse2_create( const struct translate_key *key )
{
return NULL;
}
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index ce7fb58956..d1dfc377f8 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -153,7 +153,9 @@ const char *
debug_get_option(const char *name, const char *dfault)
{
const char *result;
-#ifdef PIPE_SUBSYSTEM_WINDOWS_DISPLAY
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+ /* EngMapFile creates the file if it does not exists, so it must either be
+ * disabled on release versions (or put in a less conspicuous place). */
#ifdef DEBUG
ULONG_PTR iFile = 0;
const void *pMap = NULL;
@@ -161,9 +163,6 @@ debug_get_option(const char *name, const char *dfault)
static char output[1024];
result = dfault;
- /* XXX: this creates the file if it does not exists, so it must either be
- * disabled on release versions, or put in a less conspicuous place.
- */
pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile);
if(pMap) {
sol = (const char *)pMap;
@@ -187,13 +186,15 @@ debug_get_option(const char *name, const char *dfault)
#else
result = dfault;
#endif
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ /* TODO: implement */
+ result = dfault;
#else
-
result = getenv(name);
if(!result)
result = dfault;
#endif
-
+
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)");
return result;
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 5f8d12191d..505d93d727 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -92,8 +92,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
decl.Semantic.SemanticName = semantic_names[i];
decl.Semantic.SemanticIndex = semantic_indexes[i];
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = i;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -107,8 +107,8 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = semantic_names[i];
decl.Semantic.SemanticIndex = semantic_indexes[i];
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = i;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = i;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -190,14 +190,13 @@ util_make_fragment_tex_shader(struct pipe_context *pipe,
/* declare TEX[0] input */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
+ /* XXX this could be linear... */
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
decl.Semantic.SemanticIndex = 0;
- /* XXX this could be linear... */
- decl.Declaration.Interpolate = 1;
- decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = 0;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -209,8 +208,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe,
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
decl.Semantic.SemanticIndex = 0;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = 0;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -219,8 +218,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe,
/* declare sampler */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = 0;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -303,8 +302,8 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe,
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
decl.Semantic.SemanticIndex = 0;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = 0;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
@@ -316,8 +315,8 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe,
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
decl.Semantic.SemanticIndex = 0;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = 0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = 0;
ti += tgsi_build_full_declaration(&decl,
&tokens[ti],
header,
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 9b97050d51..49dce75289 100644
--- a/src/gallium/auxiliary/util/u_time.c
+++ b/src/gallium/auxiliary/util/u_time.c
@@ -33,26 +33,44 @@
*/
-#include "util/u_time.h"
+#include "pipe/p_config.h"
#if defined(PIPE_OS_LINUX)
#include <sys/time.h>
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
#include <windows.h>
#include <winddi.h>
-#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+#include <windows.h>
+extern VOID KeQuerySystemTime(PLARGE_INTEGER);
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
#include <windows.h>
#else
#error Unsupported OS
#endif
+#include "util/u_time.h"
+
-#if defined(PIPE_OS_WINDOWS)
-static LONGLONG frequency = 0;
-#if !defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
-#define EngQueryPerformanceFrequency(p) QueryPerformanceFrequency((LARGE_INTEGER*)(p))
-#define EngQueryPerformanceCounter(p) QueryPerformanceCounter((LARGE_INTEGER*)(p))
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+
+static int64_t frequency = 0;
+
+static INLINE void
+util_time_get_frequency(void)
+{
+ if(!frequency) {
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+ LONGLONG temp;
+ EngQueryPerformanceFrequency(&temp);
+ frequency = temp;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ LARGE_INTEGER temp;
+ QueryPerformanceFrequency(&temp);
+ frequency = temp.QuadPart;
#endif
+ }
+}
#endif
@@ -61,8 +79,20 @@ util_time_get(struct util_time *t)
{
#if defined(PIPE_OS_LINUX)
gettimeofday(&t->tv, NULL);
-#elif defined(PIPE_OS_WINDOWS)
- EngQueryPerformanceCounter(&t->counter);
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+ LONGLONG temp;
+ EngQueryPerformanceCounter(&temp);
+ t->counter = temp;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+ /* Updated every 10 miliseconds, measured in units of 100 nanoseconds.
+ * http://msdn.microsoft.com/en-us/library/ms801642.aspx */
+ LARGE_INTEGER temp;
+ KeQuerySystemTime(&temp);
+ t->counter = temp.QuadPart;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ LARGE_INTEGER temp;
+ QueryPerformanceCounter(&temp);
+ t->counter = temp.QuadPart;
#endif
}
@@ -75,10 +105,17 @@ util_time_add(const struct util_time *t1,
#if defined(PIPE_OS_LINUX)
t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000;
t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000;
-#elif defined(PIPE_OS_WINDOWS)
- if(!frequency)
- EngQueryPerformanceFrequency(&frequency);
- t2->counter = t1->counter + (usecs * frequency + 999999LL)/1000000LL;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ util_time_get_frequency();
+ t2->counter = t1->counter + (usecs * frequency + INT64_C(999999))/INT64_C(1000000);
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+ /* 1 tick = 100 nano seconds. */
+ t2->counter = t1->counter + usecs * 10;
+#elif
+ LARGE_INTEGER temp;
+ LONGLONG freq;
+ freq = temp.QuadPart;
+ t2->counter = t1->counter + (usecs * freq)/1000000L;
#endif
}
@@ -90,10 +127,11 @@ util_time_diff(const struct util_time *t1,
#if defined(PIPE_OS_LINUX)
return (t2->tv.tv_usec - t1->tv.tv_usec) +
(t2->tv.tv_sec - t1->tv.tv_sec)*1000000;
-#elif defined(PIPE_OS_WINDOWS)
- if(!frequency)
- EngQueryPerformanceFrequency(&frequency);
- return (t2->counter - t1->counter)*1000000LL/frequency;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+ util_time_get_frequency();
+ return (t2->counter - t1->counter)*INT64_C(1000000)/frequency;
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+ return (t2->counter - t1->counter)/10;
#endif
}
@@ -142,7 +180,7 @@ util_time_timeout(const struct util_time *start,
}
-#if defined(PIPE_OS_WINDOWS)
+#if defined(PIPE_SUBSYSYEM_WINDOWS_DISPLAY)
void util_time_sleep(unsigned usecs)
{
LONGLONG start, curr, end;
diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h
index 48ec7a4a96..f9963ce0e2 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -61,7 +61,7 @@ struct util_time
#if defined(PIPE_OS_LINUX)
struct timeval tv;
#else
- long long counter;
+ int64_t counter;
#endif
};
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index 48edc62f49..3a80df427d 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -830,13 +830,11 @@ exec_declaration(struct spu_exec_machine *mach,
unsigned first, last, mask;
interpolation_func interp;
- assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE );
-
- first = decl->u.DeclarationRange.First;
- last = decl->u.DeclarationRange.Last;
+ first = decl->DeclarationRange.First;
+ last = decl->DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
- switch( decl->Interpolation.Interpolate ) {
+ switch( decl->Declaration.Interpolate ) {
case TGSI_INTERPOLATE_CONSTANT:
interp = constant_interpolation;
break;
@@ -898,7 +896,7 @@ exec_instruction(
break;
case TGSI_OPCODE_MOV:
- /* TGSI_OPCODE_SWZ */
+ case TGSI_OPCODE_SWZ:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
STORE( &r[0], 0, chan_index );
diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h
index 4ea06ce02b..45bf4f4028 100644
--- a/src/gallium/drivers/i915simple/i915_batch.h
+++ b/src/gallium/drivers/i915simple/i915_batch.h
@@ -29,26 +29,88 @@
#define I915_BATCH_H
#include "i915_winsys.h"
-#include "i915_debug.h"
-#define BATCH_LOCALS
+struct i915_batchbuffer
+{
+ struct pipe_buffer *buffer;
+ struct i915_winsys *winsys;
+
+ unsigned char *map;
+ unsigned char *ptr;
+
+ size_t size;
+ size_t actual_size;
+
+ size_t relocs;
+ size_t max_relocs;
+};
+
+static INLINE boolean
+i915_batchbuffer_check( struct i915_batchbuffer *batch,
+ size_t dwords,
+ size_t relocs )
+{
+ /** TODO JB: Check relocs */
+ return dwords * 4 <= batch->size - (batch->ptr - batch->map);
+}
+
+static INLINE size_t
+i915_batchbuffer_space( struct i915_batchbuffer *batch )
+{
+ return batch->size - (batch->ptr - batch->map);
+}
+
+static INLINE void
+i915_batchbuffer_dword( struct i915_batchbuffer *batch,
+ unsigned dword )
+{
+ if (i915_batchbuffer_space(batch) < 4)
+ return;
+
+ *(unsigned *)batch->ptr = dword;
+ batch->ptr += 4;
+}
+
+static INLINE void
+i915_batchbuffer_write( struct i915_batchbuffer *batch,
+ void *data,
+ size_t size )
+{
+ if (i915_batchbuffer_space(batch) < size)
+ return;
+
+ memcpy(data, batch->ptr, size);
+ batch->ptr += size;
+}
+
+static INLINE void
+i915_batchbuffer_reloc( struct i915_batchbuffer *batch,
+ struct pipe_buffer *buffer,
+ size_t flags,
+ size_t offset )
+{
+ batch->winsys->batch_reloc( batch->winsys, buffer, flags, offset );
+}
+
+static INLINE void
+i915_batchbuffer_flush( struct i915_batchbuffer *batch,
+ struct pipe_fence_handle **fence )
+{
+ batch->winsys->batch_flush( batch->winsys, fence );
+}
#define BEGIN_BATCH( dwords, relocs ) \
- (i915->batch_start = i915->winsys->batch_start( i915->winsys, dwords, relocs ))
+ (i915_batchbuffer_check( i915->batch, dwords, relocs ))
#define OUT_BATCH( dword ) \
- i915->winsys->batch_dword( i915->winsys, dword )
+ i915_batchbuffer_dword( i915->batch, dword )
#define OUT_RELOC( buf, flags, delta ) \
- i915->winsys->batch_reloc( i915->winsys, buf, flags, delta )
-
-#define ADVANCE_BATCH()
+ i915_batchbuffer_reloc( i915->batch, buf, flags, delta )
#define FLUSH_BATCH(fence) do { \
- if (0) i915_dump_batchbuffer( i915 ); \
i915->winsys->batch_flush( i915->winsys, fence ); \
- i915->batch_start = NULL; \
i915->hardware_dirty = ~0; \
} while (0)
-#endif
+#endif
diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c
index 24449e3fb3..22f91fab92 100644
--- a/src/gallium/drivers/i915simple/i915_blit.c
+++ b/src/gallium/drivers/i915simple/i915_blit.c
@@ -31,6 +31,7 @@
#include "i915_blit.h"
#include "i915_reg.h"
#include "i915_batch.h"
+#include "i915_debug.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -45,7 +46,6 @@ i915_fill_blit(struct i915_context *i915,
unsigned color)
{
unsigned BR13, CMD;
- BATCH_LOCALS;
dst_pitch *= (short) cpp;
@@ -79,7 +79,6 @@ i915_fill_blit(struct i915_context *i915,
OUT_BATCH(((y + h) << 16) | (x + w));
OUT_RELOC( dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset);
OUT_BATCH(color);
- ADVANCE_BATCH();
}
@@ -100,7 +99,6 @@ i915_copy_blit( struct i915_context *i915,
unsigned CMD, BR13;
int dst_y2 = dst_y + h;
int dst_x2 = dst_x + w;
- BATCH_LOCALS;
I915_DBG(i915,
@@ -156,7 +154,6 @@ i915_copy_blit( struct i915_context *i915,
OUT_BATCH((src_y << 16) | src_x);
OUT_BATCH(((int) src_pitch & 0xffff));
OUT_RELOC(src_buffer, I915_BUFFER_ACCESS_READ, src_offset);
- ADVANCE_BATCH();
}
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index c609d16a5a..243b4a6852 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -50,10 +50,12 @@ static void i915_destroy( struct pipe_context *pipe )
static boolean
-i915_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned prim, unsigned start, unsigned count)
+i915_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned prim, unsigned start, unsigned count)
{
struct i915_context *i915 = i915_context( pipe );
struct draw_context *draw = i915->draw;
@@ -77,7 +79,10 @@ i915_draw_elements( struct pipe_context *pipe,
void *mapped_indexes
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
+ draw_set_mapped_element_buffer_range(draw, indexSize,
+ min_index,
+ max_index,
+ mapped_indexes);
}
else {
/* no index/element buffer */
@@ -102,12 +107,23 @@ i915_draw_elements( struct pipe_context *pipe,
}
if (indexBuffer) {
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
- draw_set_mapped_element_buffer(draw, 0, NULL);
+ draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL);
}
return TRUE;
}
+static boolean
+i915_draw_elements( struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned prim, unsigned start, unsigned count)
+{
+ return i915_draw_range_elements( pipe, indexBuffer,
+ indexSize,
+ 0, 0xffffffff,
+ prim, start, count );
+}
static boolean i915_draw_arrays( struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
@@ -138,6 +154,7 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
i915->pipe.draw_arrays = i915_draw_arrays;
i915->pipe.draw_elements = i915_draw_elements;
+ i915->pipe.draw_range_elements = i915_draw_range_elements;
/*
* Create drawing context and plug our rendering stage into it.
@@ -164,7 +181,8 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
/* Batch stream debugging is a bit hacked up at the moment:
*/
- i915->batch_start = NULL;
+ i915->batch = i915_winsys->batch_get(i915_winsys);
+ i915->batch->winsys = i915_winsys;
return &i915->pipe;
}
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 53fc5ed079..2ee0381648 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -209,6 +209,8 @@ struct i915_texture {
struct pipe_buffer *buffer;
};
+struct i915_batchbuffer;
+
struct i915_context
{
struct pipe_context pipe;
@@ -241,10 +243,12 @@ struct i915_context
unsigned num_vertex_elements;
unsigned num_vertex_buffers;
- unsigned *batch_start;
+ struct i915_batchbuffer *batch;
/** Vertex buffer */
struct pipe_buffer *vbo;
+ size_t vbo_offset;
+ unsigned vbo_flushed;
struct i915_state current;
unsigned hardware_dirty;
diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c
index 9b9111167f..5e26d1b905 100644
--- a/src/gallium/drivers/i915simple/i915_debug.c
+++ b/src/gallium/drivers/i915simple/i915_debug.c
@@ -861,8 +861,9 @@ void
i915_dump_batchbuffer( struct i915_context *i915 )
{
struct debug_stream stream;
- unsigned *start = i915->batch_start;
- unsigned *end = i915->winsys->batch_start( i915->winsys, 0, 0 );
+ /* TODO fix me */
+ unsigned *start = 0;/*i915->batch_start;*/
+ unsigned *end = 0;/*i915->winsys->batch_start( i915->winsys, 0, 0 );*/
unsigned long bytes = (unsigned long) (end - start) * 4;
boolean done = FALSE;
diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c
index 7d23e6b6b9..472e0ab774 100644
--- a/src/gallium/drivers/i915simple/i915_flush.c
+++ b/src/gallium/drivers/i915simple/i915_flush.c
@@ -62,12 +62,12 @@ static void i915_flush( struct pipe_context *pipe,
assert(BEGIN_BATCH(1, 0));
}
OUT_BATCH( flush );
- ADVANCE_BATCH();
}
/* If there are no flags, just flush pending commands to hardware:
*/
FLUSH_BATCH(fence);
+ i915->vbo_flushed = 1;
}
diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c
index 3ccf74c72c..23cd909337 100644
--- a/src/gallium/drivers/i915simple/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c
@@ -676,7 +676,7 @@ i915_translate_instruction(struct i915_fp_compile *p,
break;
case TGSI_OPCODE_MOV:
- /* aka TGSI_OPCODE_SWZ */
+ case TGSI_OPCODE_SWZ:
emit_simple_arith(p, inst, A0_MOV, 1);
break;
@@ -943,8 +943,8 @@ i915_translate_instructions(struct i915_fp_compile *p,
if (parse.FullToken.FullDeclaration.Declaration.File
== TGSI_FILE_CONSTANT) {
uint i;
- for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+ for (i = parse.FullToken.FullDeclaration.DeclarationRange.First;
+ i <= parse.FullToken.FullDeclaration.DeclarationRange.Last;
i++) {
assert(ifs->constant_flags[i] == 0x0);
ifs->constant_flags[i] = I915_CONSTFLAG_USER;
@@ -954,8 +954,8 @@ i915_translate_instructions(struct i915_fp_compile *p,
else if (parse.FullToken.FullDeclaration.Declaration.File
== TGSI_FILE_TEMPORARY) {
uint i;
- for (i = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- i <= parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+ for (i = parse.FullToken.FullDeclaration.DeclarationRange.First;
+ i <= parse.FullToken.FullDeclaration.DeclarationRange.Last;
i++) {
assert(i < I915_MAX_TEMPORARY);
/* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index 7fb2adbb53..adfb16fbc5 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -38,6 +38,7 @@
*/
+#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
#include "pipe/p_debug.h"
#include "pipe/p_util.h"
@@ -62,8 +63,21 @@ struct i915_vbuf_render {
/** Vertex size in bytes */
unsigned vertex_size;
+ /** Software primitive */
+ unsigned prim;
+
/** Hardware primitive */
unsigned hwprim;
+
+ /** Genereate a vertex list */
+ unsigned fallback;
+
+ /* Stuff for the vbo */
+ struct pipe_buffer *vbo;
+ size_t vbo_size;
+ size_t vbo_offset;
+ void *vbo_ptr;
+ size_t vbo_alloc_size;
};
@@ -95,8 +109,8 @@ i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
static void *
i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
- ushort vertex_size,
- ushort nr_vertices )
+ ushort vertex_size,
+ ushort nr_vertices )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@@ -105,14 +119,31 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
/* FIXME: handle failure */
assert(!i915->vbo);
- i915->vbo = winsys->buffer_create(winsys, 64, I915_BUFFER_USAGE_LIT_VERTEX,
- size);
-
+
+ if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
+ } else {
+ i915->vbo_flushed = 0;
+ pipe_buffer_reference(winsys, &i915_render->vbo, NULL);
+ }
+
+ if (!i915_render->vbo) {
+ i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
+ i915_render->vbo_offset = 0;
+ i915_render->vbo = winsys->buffer_create(winsys,
+ 64,
+ I915_BUFFER_USAGE_LIT_VERTEX,
+ i915_render->vbo_size);
+ i915_render->vbo_ptr = winsys->buffer_map(winsys,
+ i915_render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ winsys->buffer_unmap(winsys, i915_render->vbo);
+ }
+
+ i915->vbo = i915_render->vbo;
+ i915->vbo_offset = i915_render->vbo_offset;
i915->dirty |= I915_NEW_VBO;
-
- return winsys->buffer_map(winsys,
- i915->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
}
@@ -121,16 +152,36 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
unsigned prim )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
-
+ i915_render->prim = prim;
+
switch(prim) {
case PIPE_PRIM_POINTS:
i915_render->hwprim = PRIM3D_POINTLIST;
+ i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_LINES:
i915_render->hwprim = PRIM3D_LINELIST;
+ i915_render->fallback = 0;
+ return TRUE;
+ case PIPE_PRIM_LINE_STRIP:
+ i915_render->hwprim = PRIM3D_LINESTRIP;
+ i915_render->fallback = 0;
return TRUE;
case PIPE_PRIM_TRIANGLES:
i915_render->hwprim = PRIM3D_TRILIST;
+ i915_render->fallback = 0;
+ return TRUE;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ i915_render->hwprim = PRIM3D_TRISTRIP;
+ i915_render->fallback = 0;
+ return TRUE;
+ case PIPE_PRIM_QUADS:
+ i915_render->hwprim = PRIM3D_TRILIST;
+ i915_render->fallback = PIPE_PRIM_QUADS;
+ return TRUE;
+ case PIPE_PRIM_QUAD_STRIP:
+ i915_render->hwprim = PRIM3D_TRILIST;
+ i915_render->fallback = PIPE_PRIM_QUAD_STRIP;
return TRUE;
default:
/* Actually, can handle a lot more just fine... Fixme.
@@ -140,6 +191,179 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
}
+
+/**
+ * Used for fallbacks in draw_arrays
+ */
+static void
+draw_arrays_generate_indices( struct vbuf_render *render,
+ unsigned start, uint nr,
+ unsigned type )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ unsigned i;
+ unsigned end = start + nr;
+ switch(type) {
+ case 0:
+ for (i = start; i+1 < end; i += 2)
+ OUT_BATCH( (i+0) | (i+1) << 16 );
+ if (i < end)
+ OUT_BATCH( i );
+ break;
+ case PIPE_PRIM_QUADS:
+ for (i = start; i + 3 < end; i += 4) {
+ OUT_BATCH( (i+0) | (i+1) << 16 );
+ OUT_BATCH( (i+3) | (i+1) << 16 );
+ OUT_BATCH( (i+2) | (i+3) << 16 );
+ }
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ for (i = start; i + 3 < end; i += 2) {
+ OUT_BATCH( (i+0) | (i+1) << 16 );
+ OUT_BATCH( (i+3) | (i+2) << 16 );
+ OUT_BATCH( (i+0) | (i+3) << 16 );
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+static unsigned
+draw_arrays_calc_nr_indices( uint nr, unsigned type )
+{
+ switch (type) {
+ case 0:
+ return nr;
+ case PIPE_PRIM_QUADS:
+ return (nr / 4) * 6;
+ case PIPE_PRIM_QUAD_STRIP:
+ return ((nr - 2) / 2) * 6;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void
+draw_arrays_fallback( struct vbuf_render *render,
+ unsigned start,
+ uint nr )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ unsigned nr_indices;
+
+ if (i915->dirty)
+ i915_update_derived( i915 );
+
+ if (i915->hardware_dirty)
+ i915_emit_hardware_state( i915 );
+
+ nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
+
+ if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+ FLUSH_BATCH(NULL);
+
+ /* Make sure state is re-emitted after a flush:
+ */
+ i915_update_derived( i915 );
+ i915_emit_hardware_state( i915 );
+ i915->vbo_flushed = 1;
+
+ if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+ assert(0);
+ goto out;
+ }
+ }
+ OUT_BATCH( _3DPRIMITIVE |
+ PRIM_INDIRECT |
+ i915_render->hwprim |
+ PRIM_INDIRECT_ELTS |
+ nr_indices );
+
+ draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
+
+out:
+ return;
+}
+
+static void
+i915_vbuf_render_draw_arrays( struct vbuf_render *render,
+ unsigned start,
+ uint nr )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+
+ if (i915_render->fallback) {
+ draw_arrays_fallback( render, start, nr );
+ return;
+ }
+
+ /* JB: TODO submit direct cmds */
+ draw_arrays_fallback( render, start, nr );
+}
+
+/**
+ * Used for normal and fallback emitting of indices
+ * If type is zero normal operation assumed.
+ */
+static void
+draw_generate_indices( struct vbuf_render *render,
+ const ushort *indices,
+ uint nr_indices,
+ unsigned type )
+{
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ unsigned i;
+
+ switch(type) {
+ case 0:
+ for (i = 0; i + 1 < nr_indices; i += 2) {
+ OUT_BATCH( indices[i] | indices[i+1] << 16 );
+ }
+ if (i < nr_indices) {
+ OUT_BATCH( indices[i] );
+ }
+ break;
+ case PIPE_PRIM_QUADS:
+ for (i = 0; i + 3 < nr_indices; i += 4) {
+ OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
+ OUT_BATCH( indices[i+3] | indices[i+1] << 16 );
+ OUT_BATCH( indices[i+2] | indices[i+3] << 16 );
+ }
+ break;
+ case PIPE_PRIM_QUAD_STRIP:
+ for (i = 0; i + 3 < nr_indices; i += 2) {
+ OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
+ OUT_BATCH( indices[i+3] | indices[i+2] << 16 );
+ OUT_BATCH( indices[i+0] | indices[i+3] << 16 );
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
+
+static unsigned
+draw_calc_nr_indices( uint nr_indices, unsigned type )
+{
+ switch (type) {
+ case 0:
+ return nr_indices;
+ case PIPE_PRIM_QUADS:
+ return (nr_indices / 4) * 6;
+ case PIPE_PRIM_QUAD_STRIP:
+ return ((nr_indices - 2) / 2) * 6;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
static void
i915_vbuf_render_draw( struct vbuf_render *render,
const ushort *indices,
@@ -147,13 +371,13 @@ i915_vbuf_render_draw( struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- unsigned i;
+ unsigned save_nr_indices;
+
+ save_nr_indices = nr_indices;
+ nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
assert(nr_indices);
- /* this seems to be bogus, since we validate state right after this */
- /*assert((i915->dirty & ~I915_NEW_VBO) == 0);*/
-
if (i915->dirty)
i915_update_derived( i915 );
@@ -167,25 +391,26 @@ i915_vbuf_render_draw( struct vbuf_render *render,
*/
i915_update_derived( i915 );
i915_emit_hardware_state( i915 );
+ i915->vbo_flushed = 1;
if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
assert(0);
- return;
+ goto out;
}
}
OUT_BATCH( _3DPRIMITIVE |
- PRIM_INDIRECT |
- i915_render->hwprim |
- PRIM_INDIRECT_ELTS |
- nr_indices );
- for (i = 0; i + 1 < nr_indices; i += 2) {
- OUT_BATCH( indices[i] |
- (indices[i + 1] << 16) );
- }
- if (i < nr_indices) {
- OUT_BATCH( indices[i] );
- }
+ PRIM_INDIRECT |
+ i915_render->hwprim |
+ PRIM_INDIRECT_ELTS |
+ nr_indices );
+ draw_generate_indices( render,
+ indices,
+ save_nr_indices,
+ i915_render->fallback );
+
+out:
+ return;
}
@@ -197,11 +422,13 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render,
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct pipe_winsys *winsys = i915->pipe.winsys;
+ size_t size = (size_t)vertex_size * (size_t)vertices_used;
assert(i915->vbo);
- winsys->buffer_unmap(winsys, i915->vbo);
- pipe_buffer_reference(winsys, &i915->vbo, NULL);
+
+ i915_render->vbo_offset += size;
+ i915->vbo = NULL;
+ i915->dirty |= I915_NEW_VBO;
}
@@ -220,6 +447,7 @@ static struct vbuf_render *
i915_vbuf_render_create( struct i915_context *i915 )
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
+ struct pipe_winsys *winsys = i915->pipe.winsys;
i915_render->i915 = i915;
@@ -229,14 +457,27 @@ i915_vbuf_render_create( struct i915_context *i915 )
* batch buffer.
*/
i915_render->base.max_indices = 16*1024;
-
+
i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;
i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
i915_render->base.draw = i915_vbuf_render_draw;
+ i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
i915_render->base.destroy = i915_vbuf_render_destroy;
-
+
+ i915_render->vbo_alloc_size = 128 * 4096;
+ i915_render->vbo_size = i915_render->vbo_alloc_size;
+ i915_render->vbo_offset = 0;
+ i915_render->vbo = winsys->buffer_create(winsys,
+ 64,
+ I915_BUFFER_USAGE_LIT_VERTEX,
+ i915_render->vbo_size);
+ i915_render->vbo_ptr = winsys->buffer_map(winsys,
+ i915_render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ winsys->buffer_unmap(winsys, i915_render->vbo);
+
return &i915_render->base;
}
@@ -258,6 +499,8 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
render->destroy(render);
return NULL;
}
-
+ /** TODO JB: this shouldn't be here */
+ draw_set_render(i915->draw, render);
+
return stage;
}
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index e09c225900..39d5d5e9d6 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -41,7 +41,6 @@
#include "i915_state_inlines.h"
#include "i915_fpc.h"
-
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
* Intel drivers for "other operating systems" implement GL_CLAMP as
* GL_CLAMP_TO_EDGE, so the same is done here.
@@ -178,6 +177,7 @@ static void i915_bind_blend_state(struct pipe_context *pipe,
void *blend)
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
i915->blend = (struct i915_blend_state*)blend;
@@ -194,6 +194,7 @@ static void i915_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
i915->blend_color = *blend_color;
@@ -280,6 +281,8 @@ static void i915_bind_sampler_states(struct pipe_context *pipe,
!memcmp(i915->sampler, sampler, num * sizeof(void *)))
return;
+ draw_flush(i915->draw);
+
for (i = 0; i < num; ++i)
i915->sampler[i] = sampler[i];
for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
@@ -398,6 +401,7 @@ static void i915_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil;
@@ -415,6 +419,7 @@ static void i915_set_scissor_state( struct pipe_context *pipe,
const struct pipe_scissor_state *scissor )
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
memcpy( &i915->scissor, scissor, sizeof(*scissor) );
i915->dirty |= I915_NEW_SCISSOR;
@@ -451,6 +456,7 @@ static void
i915_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
i915->fs = (struct i915_fragment_shader*) shader;
@@ -506,6 +512,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
{
struct i915_context *i915 = i915_context(pipe);
struct pipe_winsys *ws = pipe->winsys;
+ draw_flush(i915->draw);
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
@@ -574,6 +581,7 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
i915->framebuffer = *fb; /* struct copy */
@@ -586,6 +594,7 @@ static void i915_set_clip_state( struct pipe_context *pipe,
const struct pipe_clip_state *clip )
{
struct i915_context *i915 = i915_context(pipe);
+ draw_flush(i915->draw);
draw_set_clip_state(i915->draw, clip);
@@ -698,6 +707,10 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
const struct pipe_vertex_buffer *buffers)
{
struct i915_context *i915 = i915_context(pipe);
+ /* Because we change state before the draw_set_vertex_buffers call
+ * we need a flush here, just to be sure.
+ */
+ draw_flush(i915->draw);
memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0]));
i915->num_vertex_buffers = count;
@@ -711,16 +724,27 @@ static void i915_set_vertex_elements(struct pipe_context *pipe,
const struct pipe_vertex_element *elements)
{
struct i915_context *i915 = i915_context(pipe);
+ /* Because we change state before the draw_set_vertex_buffers call
+ * we need a flush here, just to be sure.
+ */
+ draw_flush(i915->draw);
+
i915->num_vertex_elements = count;
/* pass-through to draw module */
draw_set_vertex_elements(i915->draw, count, elements);
}
+static void i915_set_edgeflags(struct pipe_context *pipe,
+ const unsigned *bitfield)
+{
+ /* TODO do something here */
+}
void
i915_init_state_functions( struct i915_context *i915 )
{
+ i915->pipe.set_edgeflags = i915_set_edgeflags;
i915->pipe.create_blend_state = i915_create_blend_state;
i915->pipe.bind_blend_state = i915_bind_blend_state;
i915->pipe.delete_blend_state = i915_delete_blend_state;
diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c
index 6f947d4346..de0c1a787a 100644
--- a/src/gallium/drivers/i915simple/i915_state_emit.c
+++ b/src/gallium/drivers/i915simple/i915_state_emit.c
@@ -217,6 +217,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(BUF_3D_ID_COLOR_BACK |
BUF_3D_PITCH(pitch) | /* pitch in bytes */
+// BUF_3D_TILED_SURFACE); /* JB: Used to force tileing */
BUF_3D_USE_FENCE);
OUT_RELOC(cbuf_surface->buffer,
@@ -376,6 +377,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
{
uint w, h;
boolean k = framebuffer_size(&i915->framebuffer, &w, &h);
+ (void)k;
assert(k);
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
diff --git a/src/gallium/drivers/i915simple/i915_state_immediate.c b/src/gallium/drivers/i915simple/i915_state_immediate.c
index dfbbcab624..704ea4d838 100644
--- a/src/gallium/drivers/i915simple/i915_state_immediate.c
+++ b/src/gallium/drivers/i915simple/i915_state_immediate.c
@@ -54,7 +54,7 @@ static void upload_S0S1(struct i915_context *i915)
/* INTEL_NEW_VBO */
/* TODO: re-use vertex buffers here? */
- LIS0 = 0;
+ LIS0 = i915->vbo_offset;
/* INTEL_NEW_VERTEX_SIZE -- do this where the vertex size is calculated!
*/
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index 3e23e540f9..16354dce50 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -104,52 +104,52 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
*/
}
+#if 0
+static unsigned
+power_of_two(unsigned x)
+{
+ int value = 1;
+ while (value <= x)
+ value = value << 1;
+ return value;
+}
+#endif
+
+static unsigned
+round_up(unsigned n, unsigned multiple)
+{
+ return (n + multiple - 1) & ~(multiple - 1);
+}
-/* Hack it up to use the old winsys->surface_alloc_storage()
- * method for now:
+/**
+ * Special case to deal with display targets.
*/
static boolean
i915_displaytarget_layout(struct pipe_screen *screen,
struct i915_texture *tex)
{
- struct pipe_winsys *ws = screen->winsys;
- struct pipe_surface surf;
- unsigned flags = (PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
-
- memset(&surf, 0, sizeof(surf));
-
- ws->surface_alloc_storage( ws,
- &surf,
- tex->base.width[0],
- tex->base.height[0],
- tex->base.format,
- flags,
- tex->base.tex_usage);
-
- /* Now extract the goodies:
- */
- i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
- i915_miptree_set_level_info( tex, 0, 0, 0, 0,
+ struct pipe_texture *pt = &tex->base;
+
+ if (pt->last_level > 0 || pt->cpp != 4)
+ return 0;
+
+ i915_miptree_set_level_info( tex, 0, 1, 0, 0,
tex->base.width[0],
tex->base.height[0],
1 );
+ i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
- tex->buffer = surf.buffer;
- tex->pitch = surf.pitch;
- tex->total_height = 0;
-
+#if 0
+ tex->pitch = MAX2(512, power_of_two(tex->base.width[0] * pt->cpp)) / pt->cpp;
+ tex->total_height = round_up(tex->base.height[0], 8);
+#else
+ tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp);
+ tex->total_height = tex->base.height[0];
+#endif
- return tex->buffer != NULL;
+ return 1;
}
-
-
-
-
static void
i945_miptree_layout_2d( struct i915_texture *tex )
{
@@ -179,7 +179,7 @@ i945_miptree_layout_2d( struct i915_texture *tex )
/* Pitch must be a whole number of dwords, even though we
* express it in texels.
*/
- tex->pitch = align_int(tex->pitch * pt->cpp, 4) / pt->cpp;
+ tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp;
tex->total_height = 0;
for (level = 0; level <= pt->last_level; level++) {
@@ -525,54 +525,47 @@ i945_miptree_layout(struct i915_texture * tex)
static struct pipe_texture *
-i915_texture_create_screen(struct pipe_screen *screen,
- const struct pipe_texture *templat)
+i915_texture_create(struct pipe_screen *screen,
+ const struct pipe_texture *templat)
{
struct i915_screen *i915screen = i915_screen(screen);
struct pipe_winsys *ws = screen->winsys;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
- if (!tex)
+ if (!tex)
return NULL;
tex->base = *templat;
tex->base.refcount = 1;
tex->base.screen = screen;
- if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- if (!i915_displaytarget_layout(screen, tex))
- goto fail;
- }
- else {
- if (i915screen->is_i945) {
- if (!i945_miptree_layout(tex))
- goto fail;
- }
- else {
- if (!i915_miptree_layout(tex))
- goto fail;
- }
-
- tex->buffer = ws->buffer_create(ws, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
-
- if (!tex->buffer)
- goto fail;
+ if (i915screen->is_i945) {
+ if (!i945_miptree_layout(tex))
+ goto fail;
+ } else {
+ if (!i915_miptree_layout(tex))
+ goto fail;
}
+ tex->buffer = ws->buffer_create(ws, 64,
+ PIPE_BUFFER_USAGE_PIXEL,
+ tex->pitch * tex->base.cpp *
+ tex->total_height);
+
+ if (!tex->buffer)
+ goto fail;
+
return &tex->base;
- fail:
+fail:
FREE(tex);
return NULL;
}
static void
-i915_texture_release_screen(struct pipe_screen *screen,
- struct pipe_texture **pt)
+i915_texture_release(struct pipe_screen *screen,
+ struct pipe_texture **pt)
{
if (!*pt)
return;
@@ -606,10 +599,10 @@ i915_texture_release_screen(struct pipe_screen *screen,
* XXX note: same as code in sp_surface.c
*/
static struct pipe_surface *
-i915_get_tex_surface_screen(struct pipe_screen *screen,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- unsigned flags)
+i915_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned flags)
{
struct i915_texture *tex = (struct i915_texture *)pt;
struct pipe_winsys *ws = screen->winsys;
@@ -629,10 +622,11 @@ i915_get_tex_surface_screen(struct pipe_screen *screen,
assert(zslice == 0);
}
- ps = ws->surface_alloc(ws);
+ ps = CALLOC_STRUCT(pipe_surface);//ws->surface_alloc(ws);
if (ps) {
- assert(ps->refcount);
- assert(ps->winsys);
+ ps->refcount = 1;
+ ps->winsys = ws;
+ pipe_texture_reference(&ps->texture, pt);
pipe_buffer_reference(ws, &ps->buffer, tex->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
@@ -652,11 +646,35 @@ i915_init_texture_functions(struct i915_context *i915)
// i915->pipe.texture_update = i915_texture_update;
}
+static void
+i915_tex_surface_release(struct pipe_screen *screen,
+ struct pipe_surface **surface)
+{
+ struct pipe_surface *surf = *surface;
+
+ if (--surf->refcount == 0) {
+
+ /* This really should not be possible, but it's actually
+ * happening quite a bit... Will fix.
+ */
+ if (surf->status == PIPE_SURFACE_STATUS_CLEAR) {
+ debug_printf("XXX destroying a surface with pending clears...\n");
+ assert(0);
+ }
+
+ pipe_texture_reference(&surf->texture, NULL);
+ pipe_buffer_reference(screen->winsys, &surf->buffer, NULL);
+ FREE(surf);
+ }
+
+ *surface = NULL;
+}
void
i915_init_screen_texture_functions(struct pipe_screen *screen)
{
- screen->texture_create = i915_texture_create_screen;
- screen->texture_release = i915_texture_release_screen;
- screen->get_tex_surface = i915_get_tex_surface_screen;
+ screen->texture_create = i915_texture_create;
+ screen->texture_release = i915_texture_release;
+ screen->get_tex_surface = i915_get_tex_surface;
+ screen->tex_surface_release = i915_tex_surface_release;
}
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index 5e16543f4e..9afaa16a62 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -55,6 +55,7 @@ extern "C" {
* etc.
*/
+struct i915_batchbuffer;
struct pipe_buffer;
struct pipe_fence_handle;
struct pipe_winsys;
@@ -75,20 +76,10 @@ struct pipe_screen;
struct i915_winsys {
/**
- * Reserve space on batch buffer.
- *
- * Returns a null pointer if there is insufficient space in the batch buffer
- * to hold the requested number of dwords and relocations.
- *
- * The number of dwords should also include the number of relocations.
+ * Get the current batch buffer from the winsys.
*/
- unsigned *(*batch_start)( struct i915_winsys *sws,
- unsigned dwords,
- unsigned relocs );
-
- void (*batch_dword)( struct i915_winsys *sws,
- unsigned dword );
-
+ struct i915_batchbuffer *(*batch_get)( struct i915_winsys *sws );
+
/**
* Emit a relocation to a buffer.
*
@@ -103,7 +94,10 @@ struct i915_winsys {
struct pipe_buffer *buf,
unsigned access_flags,
unsigned delta );
-
+
+ /**
+ * Flush the batch.
+ */
void (*batch_flush)( struct i915_winsys *sws,
struct pipe_fence_handle **fence );
};
diff --git a/src/gallium/drivers/i965simple/brw_sf.c b/src/gallium/drivers/i965simple/brw_sf.c
index c3b815a82b..96f8fb87a3 100644
--- a/src/gallium/drivers/i965simple/brw_sf.c
+++ b/src/gallium/drivers/i965simple/brw_sf.c
@@ -169,9 +169,9 @@ static void upload_sf_prog( struct brw_context *brw )
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
{
- int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
- int interp_mode = parse.FullToken.FullDeclaration.Interpolation.Interpolate;
+ int first = parse.FullToken.FullDeclaration.DeclarationRange.First;
+ int last = parse.FullToken.FullDeclaration.DeclarationRange.Last;
+ int interp_mode = parse.FullToken.FullDeclaration.Declaration.Interpolate;
//int semantic = parse.FullToken.FullDeclaration.Semantic.SemanticName;
//int semantic_index = parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
@@ -291,8 +291,8 @@ static void update_sf_linkage( struct brw_context *brw )
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
{
- int first = parse.FullToken.FullDeclaration.u.DeclarationRange.First;
- int last = parse.FullToken.FullDeclaration.u.DeclarationRange.Last;
+ int first = parse.FullToken.FullDeclaration.DeclarationRange.First;
+ int last = parse.FullToken.FullDeclaration.DeclarationRange.Last;
for (i = first; i < last; i++) {
vp_semantic[i].semantic =
diff --git a/src/gallium/drivers/i965simple/brw_shader_info.c b/src/gallium/drivers/i965simple/brw_shader_info.c
index f4694a4433..fb3da92421 100644
--- a/src/gallium/drivers/i965simple/brw_shader_info.c
+++ b/src/gallium/drivers/i965simple/brw_shader_info.c
@@ -26,9 +26,7 @@ void brw_shader_info(const struct tgsi_token *tokens,
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
- unsigned last = decl->u.DeclarationRange.Last;
-
- assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE );
+ unsigned last = decl->DeclarationRange.Last;
// Broken by crazy wpos init:
//assert( info->nr_regs[decl->Declaration.File] <= last);
diff --git a/src/gallium/drivers/i965simple/brw_vs_emit.c b/src/gallium/drivers/i965simple/brw_vs_emit.c
index 9020fcc001..81423e2d7d 100644
--- a/src/gallium/drivers/i965simple/brw_vs_emit.c
+++ b/src/gallium/drivers/i965simple/brw_vs_emit.c
@@ -988,10 +988,8 @@ post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
static void process_declaration(const struct tgsi_full_declaration *decl,
struct brw_prog_info *info)
{
- int first = decl->u.DeclarationRange.First;
- int last = decl->u.DeclarationRange.Last;
-
- assert (decl->Declaration.Declare != TGSI_DECLARE_MASK);
+ int first = decl->DeclarationRange.First;
+ int last = decl->DeclarationRange.Last;
switch(decl->Declaration.File) {
case TGSI_FILE_CONSTANT:
@@ -1137,8 +1135,8 @@ static void process_instruction(struct brw_vs_compile *c,
emit_min(p, dst, args[0], args[1]);
break;
case TGSI_OPCODE_MOV:
-#if 0
case TGSI_OPCODE_SWZ:
+#if 0
/* The args[0] value can't be used here as it won't have
* correctly encoded the full swizzle:
*/
diff --git a/src/gallium/drivers/i965simple/brw_wm_decl.c b/src/gallium/drivers/i965simple/brw_wm_decl.c
index 74ccfd494a..bf1b4d961a 100644
--- a/src/gallium/drivers/i965simple/brw_wm_decl.c
+++ b/src/gallium/drivers/i965simple/brw_wm_decl.c
@@ -351,18 +351,16 @@ void brw_wm_emit_decls(struct brw_wm_compile *c)
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *decl = &parse.FullToken.FullDeclaration;
- unsigned first = decl->u.DeclarationRange.First;
- unsigned last = decl->u.DeclarationRange.Last;
+ unsigned first = decl->DeclarationRange.First;
+ unsigned last = decl->DeclarationRange.Last;
unsigned mask = decl->Declaration.UsageMask; /* ? */
unsigned i;
if (decl->Declaration.File != TGSI_FILE_INPUT)
break;
- assert(decl->Declaration.Interpolate);
-
for( i = first; i <= last; i++ ) {
- switch (decl->Interpolation.Interpolate) {
+ switch (decl->Declaration.Interpolate) {
case TGSI_INTERPOLATE_CONSTANT:
emit_cinterp(c, i, mask);
break;
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index 55741cc1df..69f7f960aa 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -46,7 +46,7 @@
/* Surely this should be defined somewhere in a tgsi header:
*/
-typedef void (XSTDCALL *codegen_function)(
+typedef void (PIPE_CDECL *codegen_function)(
const struct tgsi_exec_vector *input,
struct tgsi_exec_vector *output,
const float (*constant)[4],
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index a1859f9883..33888abcc5 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -230,7 +230,7 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
int x = quad->x0 % TILE_SIZE + (j & 1);
int y = quad->y0 % TILE_SIZE + (j >> 1);
uint z24s8 = tile->data.depth32[y][x];
- z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 24);
+ z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8);
tile->data.depth32[y][x] = z24s8;
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 28c29da87c..0e4c8c41ee 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -169,6 +169,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
PIPE_BUFFER_USAGE_CPU_WRITE);
tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
+ ps->format == PIPE_FORMAT_Z24S8_UNORM ||
ps->format == PIPE_FORMAT_Z16_UNORM ||
ps->format == PIPE_FORMAT_Z32_UNORM ||
ps->format == PIPE_FORMAT_S8_UNORM);
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 01d1807b1c..b14260dd90 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -52,39 +52,61 @@
#endif /* __MSC__ */
-typedef unsigned int uint;
-typedef unsigned char ubyte;
-typedef unsigned char boolean;
-typedef unsigned short ushort;
-typedef unsigned long long uint64;
-
-
#if defined(__MSC__)
-typedef char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef long int32_t;
-typedef unsigned long uint32_t;
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
+typedef __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
#if defined(_WIN64)
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
+typedef __int32 intptr_t;
+typedef unsigned __int32 uintptr_t;
#endif
+#define INT64_C(__val) __val##i64
+#define UINT64_C(__val) __val##ui64
+
+#ifndef __cplusplus
+#define false 0
+#define true 1
+#define bool _Bool
+typedef int _Bool;
+#define __bool_true_false_are_defined 1
+#endif /* !__cplusplus */
+
#else
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
#include <stdint.h>
+#include <stdbool.h>
#endif
-#define TRUE 1
-#define FALSE 0
+typedef unsigned int uint;
+typedef unsigned char ubyte;
+typedef unsigned short ushort;
+typedef uint64_t uint64;
+
+#if 0
+#define boolean bool
+#else
+typedef unsigned char boolean;
+#endif
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
/* Function inlining */
@@ -106,7 +128,7 @@ typedef unsigned int uintptr_t;
/* This should match linux gcc cdecl semantics everywhere, so that we
* just codegen one calling convention on all platforms.
*/
-#ifdef WIN32
+#ifdef _MSC_VER
#define PIPE_CDECL __cdecl
#else
#define PIPE_CDECL
@@ -126,18 +148,4 @@ typedef unsigned int uintptr_t;
-/**
- * For calling code-gen'd functions, phase out in favor of
- * PIPE_CDECL, above, which really means cdecl on all platforms, not
- * like the below...
- */
-#if !defined(XSTDCALL)
-#if defined(WIN32)
-#define XSTDCALL __stdcall /* phase this out */
-#else
-#define XSTDCALL /* XXX: NOTE! not STDCALL! */
-#endif
-#endif
-
-
#endif /* P_COMPILER_H */
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index 5c030bdfff..af3746c026 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -33,7 +33,12 @@
* architecture, and operating system being used. These defines should be used
* throughout the code to facilitate porting to new platforms. It is likely that
* this file is auto-generated by an autoconf-like tool at some point, as some
- * things cannot be determined by existing defines alone.
+ * things cannot be determined by pre-defined environment alone.
+ *
+ * See also:
+ * - http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
+ * - echo | gcc -dM -E - | sort
+ * - http://msdn.microsoft.com/en-us/library/b0084kay.aspx
*
* @author José Fonseca <jrfonseca@tungstengraphics.com>
*/
@@ -50,6 +55,15 @@
#define PIPE_CC_GCC
#endif
+/*
+ * Meaning of _MSC_VER value:
+ * - 1400: Visual C++ 2005
+ * - 1310: Visual C++ .NET 2003
+ * - 1300: Visual C++ .NET 2002
+ *
+ * __MSC__ seems to be an old macro -- it is not pre-defined on recent MSVC
+ * versions.
+ */
#if defined(_MSC_VER) || defined(__MSC__)
#define PIPE_CC_MSVC
#endif
@@ -63,11 +77,11 @@
* Processor architecture
*/
-#if defined(_X86_) || defined(__i386__) || defined(__386__) || defined(i386)
+#if defined(__i386__) /* gcc */ || defined(_M_IX86) /* msvc */ || defined(_X86_) || defined(__386__) || defined(i386)
#define PIPE_ARCH_X86
#endif
-#if 0 /* FIXME */
+#if defined(__x86_64__) /* gcc */ || defined(_M_X64) /* msvc */ || defined(_M_AMD64) /* msvc */
#define PIPE_ARCH_X86_64
#endif
@@ -77,7 +91,9 @@
/*
- * Operating system
+ * Operating system family.
+ *
+ * See subsystem below for a more fine-grained distinction.
*/
#if defined(__linux__)
@@ -90,30 +106,30 @@
/*
- * Subsystem
+ * Subsystem.
*
- * XXX: There is no way to autodetect this.
+ * NOTE: There is no way to auto-detect most of these.
*/
#if defined(PIPE_OS_LINUX)
#define PIPE_SUBSYSTEM_DRI
-#endif
+#endif /* PIPE_OS_LINUX */
#if defined(PIPE_OS_WINDOWS)
-#if !defined(PIPE_SUBSYSTEM_USER) && !defined(PIPE_SUBSYSTEM_KERNEL)
-#error Neither PIPE_SUBSYSTEM_USER or PIPE_SUBSYSTEM_KERNEL defined.
-#endif
-#if defined(PIPE_SUBSYSTEM_KERNEL)
-#define PIPE_SUBSYSTEM_WINDOWS_DISPLAY
-#endif
-#if 0 /* FIXME */
-#define PIPE_SUBSYSTEM_WINDOWS_MINIPORT
-#endif
-#if 0 /* FIXME */
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
+/* Windows 2000/XP Display Driver */
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
+/* Windows 2000/XP Miniport Driver */
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+/* Windows User-space Library */
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_CE)
+/* Windows CE 5.0/6.0 */
+#else
+#ifdef _WIN32_WCE
#define PIPE_SUBSYSTEM_WINDOWS_CE
-#endif
-#if defined(PIPE_SUBSYSTEM_USER)
-#define PIPE_SUBSYSTEM_WINDOWS_USER
+#else /* !_WIN32_WCE */
+#error No PIPE_SUBSYSTEM_WINDOWS_xxx subsystem defined.
+#endif /* !_WIN32_WCE */
#endif
#endif /* PIPE_OS_WINDOWS */
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index 0af635be57..05eca75201 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -59,6 +59,13 @@ extern "C" {
#endif
#endif
+
+/* MSVC bebore VC7 does not have the __FUNCTION__ macro */
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define __FUNCTION__ "???"
+#endif
+
+
void _debug_vprintf(const char *format, va_list ap);
@@ -127,8 +134,8 @@ void _debug_break(void);
#ifdef DEBUG
#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
#define debug_break() __asm("int3")
-#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__)
-#define debug_break() _asm {int 3}
+#elif defined(_M_IX86) && defined(_MSC_VER)
+#define debug_break() do { _asm {int 3} } while(0)
#else
#define debug_break() _debug_break()
#endif
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index f05e1a34b3..84e5096418 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -55,9 +55,6 @@ enum tgsi_file_type {
};
-#define TGSI_DECLARE_RANGE 0
-#define TGSI_DECLARE_MASK 1
-
#define TGSI_WRITEMASK_NONE 0x00
#define TGSI_WRITEMASK_X 0x01
#define TGSI_WRITEMASK_Y 0x02
@@ -75,16 +72,19 @@ enum tgsi_file_type {
#define TGSI_WRITEMASK_YZW 0x0E
#define TGSI_WRITEMASK_XYZW 0x0F
+#define TGSI_INTERPOLATE_CONSTANT 0
+#define TGSI_INTERPOLATE_LINEAR 1
+#define TGSI_INTERPOLATE_PERSPECTIVE 2
+
struct tgsi_declaration
{
unsigned Type : 4; /* TGSI_TOKEN_TYPE_DECLARATION */
unsigned Size : 8; /* UINT */
unsigned File : 4; /* one of TGSI_FILE_x */
- unsigned Declare : 4; /* one of TGSI_DECLARE_x */
unsigned UsageMask : 4; /* bitmask of TGSI_WRITEMASK_x flags */
- unsigned Interpolate : 1; /* BOOL, any interpolation info? */
+ unsigned Interpolate : 4; /* TGSI_INTERPOLATE_ */
unsigned Semantic : 1; /* BOOL, any semantic info? */
- unsigned Padding : 5;
+ unsigned Padding : 6;
unsigned Extended : 1; /* BOOL */
};
@@ -94,21 +94,6 @@ struct tgsi_declaration_range
unsigned Last : 16; /* UINT */
};
-struct tgsi_declaration_mask
-{
- unsigned Mask : 32; /* UINT */
-};
-
-#define TGSI_INTERPOLATE_CONSTANT 0
-#define TGSI_INTERPOLATE_LINEAR 1
-#define TGSI_INTERPOLATE_PERSPECTIVE 2
-
-struct tgsi_declaration_interpolation
-{
- unsigned Interpolate : 4; /* TGSI_INTERPOLATE_ */
- unsigned Padding : 28;
-};
-
#define TGSI_SEMANTIC_POSITION 0
#define TGSI_SEMANTIC_COLOR 1
#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */
@@ -247,7 +232,7 @@ struct tgsi_immediate_float32
/*
* GL_ARB_vertex_program
*/
-#define TGSI_OPCODE_SWZ TGSI_OPCODE_MOV
+#define TGSI_OPCODE_SWZ 118
#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT
/*
@@ -403,7 +388,7 @@ struct tgsi_immediate_float32
#define TGSI_OPCODE_KIL 116 /* unpredicated kill */
#define TGSI_OPCODE_END 117 /* aka HALT */
-#define TGSI_OPCODE_LAST 118
+#define TGSI_OPCODE_LAST 119
#define TGSI_SAT_NONE 0 /* do not saturate */
#define TGSI_SAT_ZERO_ONE 1 /* clamp to [0,1] */
@@ -636,6 +621,10 @@ struct tgsi_src_register_ext
*
* NegateX, NegateY, NegateZ and NegateW negate individual components of the
* source register.
+ *
+ * NOTE: To simplify matter, if this token is present, the corresponding Swizzle
+ * and Negate fields in tgsi_src_register should be set to X,Y,Z,W
+ * and FALSE, respectively.
*/
struct tgsi_src_register_ext_swz
diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h
index 3d8ad48d4f..5547e57833 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -207,7 +207,6 @@ mem_dup(const void *src, uint size)
#ifndef Elements
#define Elements(x) (sizeof(x)/sizeof((x)[0]))
#endif
-
#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER))
/**
@@ -411,10 +410,9 @@ extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch,
-#ifdef WIN32
-
-#if !defined(_INC_MATH) || !defined(__cplusplus)
-
+#if defined(_MSC_VER)
+#if _MSC_VER < 1400 && !defined(__cplusplus)
+
static INLINE float cosf( float f )
{
return (float) cos( (double) f );
@@ -454,8 +452,15 @@ static INLINE float logf( float f )
{
return (float) log( (double) f );
}
-#endif /* _INC_MATH */
+
+#else
+/* Work-around an extra semi-colon in VS 2005 logf definition */
+#ifdef logf
+#undef logf
+#define logf(x) ((float)log((double)(x)))
+#endif /* logf */
#endif
+#endif /* _MSC_VER */
#ifdef __cplusplus
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
index e8a581adb2..bf1718e7a5 100644
--- a/src/gallium/winsys/SConscript
+++ b/src/gallium/winsys/SConscript
@@ -1,11 +1,16 @@
Import('*')
-if 'intel' in env['winsys'] and dri:
+if env['dri']:
SConscript([
'dri/SConscript',
])
-if 'xlib' in env['winsys'] and not dri:
+if 'xlib' in env['winsys']:
SConscript([
'xlib/SConscript',
])
+
+if 'gdi' in env['winsys']:
+ SConscript([
+ 'gdi/SConscript',
+ ])
diff --git a/src/gallium/winsys/dri/SConscript b/src/gallium/winsys/dri/SConscript
index 8c56ce917c..aef5210a32 100644
--- a/src/gallium/winsys/dri/SConscript
+++ b/src/gallium/winsys/dri/SConscript
@@ -1,51 +1,54 @@
Import('*')
-drienv = env.Clone()
-
-drienv.Replace(CPPPATH = [
- '#src/mesa/drivers/dri/common',
- '#include',
- '#include/GL/internal',
- '#src/gallium/include',
- '#src/gallium/auxiliary',
- '#src/gallium/drivers',
- '#src/mesa',
- '#src/mesa/main',
- '#src/mesa/glapi',
- '#src/mesa/math',
- '#src/mesa/transform',
- '#src/mesa/shader',
- '#src/mesa/swrast',
- '#src/mesa/swrast_setup',
- '#src/egl/main',
- '#src/egl/drivers/dri',
-])
-
-drienv.ParseConfig('pkg-config --cflags --libs libdrm')
-
-COMMON_GALLIUM_SOURCES = [
- '#src/mesa/drivers/dri/common/utils.c',
- '#src/mesa/drivers/dri/common/vblank.c',
- '#src/mesa/drivers/dri/common/dri_util.c',
- '#src/mesa/drivers/dri/common/xmlconfig.c',
-]
-
-COMMON_BM_SOURCES = [
- '#src/mesa/drivers/dri/common/dri_bufmgr.c',
- '#src/mesa/drivers/dri/common/dri_drmpool.c',
-]
-
-Export([
- 'drienv',
- 'COMMON_GALLIUM_SOURCES',
- 'COMMON_BM_SOURCES',
-])
-
-# TODO: Installation
-#install: $(LIBNAME)
-# $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
-# $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
-
-SConscript([
- 'intel/SConscript',
-])
+if env['dri']:
+
+ drienv = env.Clone()
+
+ drienv.Replace(CPPPATH = [
+ '#src/mesa/drivers/dri/common',
+ '#include',
+ '#include/GL/internal',
+ '#src/gallium/include',
+ '#src/gallium/auxiliary',
+ '#src/gallium/drivers',
+ '#src/mesa',
+ '#src/mesa/main',
+ '#src/mesa/glapi',
+ '#src/mesa/math',
+ '#src/mesa/transform',
+ '#src/mesa/shader',
+ '#src/mesa/swrast',
+ '#src/mesa/swrast_setup',
+ '#src/egl/main',
+ '#src/egl/drivers/dri',
+ ])
+
+ drienv.ParseConfig('pkg-config --cflags --libs libdrm')
+
+ COMMON_GALLIUM_SOURCES = [
+ '#src/mesa/drivers/dri/common/utils.c',
+ '#src/mesa/drivers/dri/common/vblank.c',
+ '#src/mesa/drivers/dri/common/dri_util.c',
+ '#src/mesa/drivers/dri/common/xmlconfig.c',
+ ]
+
+ COMMON_BM_SOURCES = [
+ '#src/mesa/drivers/dri/common/dri_bufmgr.c',
+ '#src/mesa/drivers/dri/common/dri_drmpool.c',
+ ]
+
+ Export([
+ 'drienv',
+ 'COMMON_GALLIUM_SOURCES',
+ 'COMMON_BM_SOURCES',
+ ])
+
+ # TODO: Installation
+ #install: $(LIBNAME)
+ # $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
+ # $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
+
+ if 'intel' in env['winsys']:
+ SConscript([
+ 'intel/SConscript',
+ ])
diff --git a/src/gallium/winsys/dri/intel/Makefile b/src/gallium/winsys/dri/intel/Makefile
index 40654bb2ac..c0ce2f927b 100644
--- a/src/gallium/winsys/dri/intel/Makefile
+++ b/src/gallium/winsys/dri/intel/Makefile
@@ -2,7 +2,7 @@
TOP = ../../../../..
include $(TOP)/configs/current
-LIBNAME = i915tex_dri.so
+LIBNAME = i915_dri.so
MINIGLX_SOURCES = server/intel_dri.c
@@ -19,11 +19,14 @@ DRIVER_SOURCES = \
intel_context.c \
intel_lock.c \
intel_screen.c \
- intel_batchpool.c
+ ws_dri_bufmgr.c \
+ ws_dri_drmpool.c \
+ ws_dri_fencemgr.c \
+ ws_dri_mallocpool.c \
+ ws_dri_slabpool.c
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
- $(COMMON_BM_SOURCES) \
$(DRIVER_SOURCES)
ASM_SOURCES =
diff --git a/src/gallium/winsys/dri/intel/SConscript b/src/gallium/winsys/dri/intel/SConscript
index 0ad19d42a8..6a4f50afcc 100644
--- a/src/gallium/winsys/dri/intel/SConscript
+++ b/src/gallium/winsys/dri/intel/SConscript
@@ -1,39 +1,41 @@
Import('*')
-env = drienv.Clone()
-
-env.Append(CPPPATH = [
- '../intel',
- 'server'
-])
-
-#MINIGLX_SOURCES = server/intel_dri.c
-
-DRIVER_SOURCES = [
- 'intel_winsys_pipe.c',
- 'intel_winsys_softpipe.c',
- 'intel_winsys_i915.c',
- 'intel_batchbuffer.c',
- 'intel_swapbuffers.c',
- 'intel_context.c',
- 'intel_lock.c',
- 'intel_screen.c',
- 'intel_batchpool.c',
-]
-
-sources = \
- COMMON_GALLIUM_SOURCES + \
- COMMON_BM_SOURCES + \
- DRIVER_SOURCES
-
-drivers = [
- softpipe,
- i915simple
-]
-
-# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
-env.SharedLibrary(
- target ='i915tex_dri.so',
- source = sources,
- LIBS = drivers + mesa + auxiliaries + env['LIBS'],
-) \ No newline at end of file
+if 'mesa' in env['statetrackers']:
+
+ env = drienv.Clone()
+
+ env.Append(CPPPATH = [
+ '../intel',
+ 'server'
+ ])
+
+ #MINIGLX_SOURCES = server/intel_dri.c
+
+ DRIVER_SOURCES = [
+ 'intel_winsys_pipe.c',
+ 'intel_winsys_softpipe.c',
+ 'intel_winsys_i915.c',
+ 'intel_batchbuffer.c',
+ 'intel_swapbuffers.c',
+ 'intel_context.c',
+ 'intel_lock.c',
+ 'intel_screen.c',
+ 'intel_batchpool.c',
+ ]
+
+ sources = \
+ COMMON_GALLIUM_SOURCES + \
+ COMMON_BM_SOURCES + \
+ DRIVER_SOURCES
+
+ drivers = [
+ softpipe,
+ i915simple
+ ]
+
+ # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+ env.SharedLibrary(
+ target ='i915tex_dri.so',
+ source = sources,
+ LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+ )
diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.c b/src/gallium/winsys/dri/intel/intel_batchbuffer.c
index 5830b88b37..aa33c12045 100644
--- a/src/gallium/winsys/dri/intel/intel_batchbuffer.c
+++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.c
@@ -25,108 +25,97 @@
*
**************************************************************************/
-#include <errno.h>
-#include <stdio.h>
#include "intel_batchbuffer.h"
#include "intel_context.h"
-#include "intel_screen.h"
-#include "intel_reg.h"
-#include "drm.h"
-
-/* Relocations in kernel space:
- * - pass dma buffer seperately
- * - memory manager knows how to patch
- * - pass list of dependent buffers
- * - pass relocation list
- *
- * Either:
- * - get back an offset for buffer to fire
- * - memory manager knows how to fire buffer
- *
- * Really want the buffer to be AGP and pinned.
- *
- */
-
-/* Cliprect fence: The highest fence protecting a dma buffer
- * containing explicit cliprect information. Like the old drawable
- * lock but irq-driven. X server must wait for this fence to expire
- * before changing cliprects [and then doing sw rendering?]. For
- * other dma buffers, the scheduler will grab current cliprect info
- * and mix into buffer. X server must hold the lock while changing
- * cliprects??? Make per-drawable. Need cliprects in shared memory
- * -- beats storing them with every cmd buffer in the queue.
- *
- * ==> X server must wait for this fence to expire before touching the
- * framebuffer with new cliprects.
- *
- * ==> Cliprect-dependent buffers associated with a
- * cliprect-timestamp. All of the buffers associated with a timestamp
- * must go to hardware before any buffer with a newer timestamp.
- *
- * ==> Dma should be queued per-drawable for correct X/GL
- * synchronization. Or can fences be used for this?
- *
- * Applies to: Blit operations, metaops, X server operations -- X
- * server automatically waits on its own dma to complete before
- * modifying cliprects ???
- */
+#include <errno.h>
+#if 0
static void
-intel_dump_batchbuffer(uint offset, uint * ptr, uint count)
+intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count)
{
int i;
- printf("\n\n\nSTART BATCH (%d dwords):\n", count / 4);
- for (i = 0; i < count / 4; i += 1)
- printf("\t0x%08x\n", ptr[i]);
- printf("END BATCH\n\n\n");
+ fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4);
+ for (i = 0; i < count / 4; i += 4)
+ fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n",
+ offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]);
+ fprintf(stderr, "END BATCH\n\n\n");
+}
+#endif
+
+static void
+intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs)
+{
+ unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER;
+
+ size *= sizeof(uint32_t);
+ batch->reloc = realloc(batch->reloc, size);
+ batch->reloc_size = num_relocs;
}
void
intel_batchbuffer_reset(struct intel_batchbuffer *batch)
{
- int i;
-
- if (batch->map) {
- driBOUnmap(batch->buffer);
- batch->map = NULL;
- }
-
/*
* Get a new, free batchbuffer.
*/
- batch->size = BATCH_SZ;
- driBOData(batch->buffer, batch->size, NULL, 0);
+ drmBO *bo;
+ struct drm_bo_info_req *req;
+
+ driBOUnrefUserList(batch->list);
+ driBOResetList(batch->list);
- driBOResetList(&batch->list);
+ /* base.size is the size available to the i915simple driver */
+ batch->base.size = batch->intel->intelScreen->max_batch_size - BATCH_RESERVED;
+ batch->base.actual_size = batch->intel->intelScreen->max_batch_size;
+ driBOData(batch->buffer, batch->base.actual_size, NULL, NULL, 0);
/*
- * Unreference buffers previously on the relocation list.
+ * Add the batchbuffer to the validate list.
*/
- for (i = 0; i < batch->nr_relocs; i++) {
- struct buffer_reloc *r = &batch->reloc[i];
- driBOUnReference(r->buf);
- }
- batch->list_count = 0;
- batch->nr_relocs = 0;
- batch->flags = 0;
+ driBOAddListItem(batch->list, batch->buffer,
+ DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM,
+ &batch->dest_location, &batch->node);
+
+ req = &batch->node->bo_arg.d.req.bo_req;
/*
- * We don't refcount the batchbuffer itself since we can't destroy it
- * while it's on the list.
+ * Set up information needed for us to make relocations
+ * relative to the underlying drm buffer objects.
*/
- driBOAddListItem(&batch->list, batch->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_EXE);
+ driReadLockKernelBO();
+ bo = driBOKernel(batch->buffer);
+ req->presumed_offset = (uint64_t) bo->offset;
+ req->hint = DRM_BO_HINT_PRESUMED_OFFSET;
+ batch->drmBOVirtual = (uint8_t *) bo->virtual;
+ driReadUnlockKernelBO();
+ /*
+ * Adjust the relocation buffer size.
+ */
- batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
- batch->ptr = batch->map;
+ if (batch->reloc_size > INTEL_MAX_RELOCS ||
+ batch->reloc == NULL)
+ intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS);
+
+ assert(batch->reloc != NULL);
+ batch->reloc[0] = 0; /* No relocs yet. */
+ batch->reloc[1] = 1; /* Reloc type 1 */
+ batch->reloc[2] = 0; /* Only a single relocation list. */
+ batch->reloc[3] = 0; /* Only a single relocation list. */
+
+ batch->base.map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
+ batch->poolOffset = driBOPoolOffset(batch->buffer);
+ batch->base.ptr = batch->base.map;
+ batch->dirty_state = ~0;
+ batch->nr_relocs = 0;
+ batch->flags = 0;
+ batch->id = 0;//batch->intel->intelScreen->batch_id++;
}
-
/*======================================================================
* Public functions
*/
@@ -141,121 +130,253 @@ intel_batchbuffer_alloc(struct intel_context *intel)
&batch->buffer, 4096,
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0);
batch->last_fence = NULL;
- driBOCreateList(20, &batch->list);
+ batch->list = driBOCreateList(20);
+ batch->reloc = NULL;
intel_batchbuffer_reset(batch);
return batch;
}
-
void
intel_batchbuffer_free(struct intel_batchbuffer *batch)
{
if (batch->last_fence) {
driFenceFinish(batch->last_fence,
- DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW,
- GL_FALSE);
- driFenceUnReference(batch->last_fence);
- batch->last_fence = NULL;
+ DRM_FENCE_TYPE_EXE, GL_FALSE);
+ driFenceUnReference(&batch->last_fence);
}
- if (batch->map) {
+ if (batch->base.map) {
driBOUnmap(batch->buffer);
- batch->map = NULL;
+ batch->base.map = NULL;
}
driBOUnReference(batch->buffer);
+ driBOFreeList(batch->list);
+ if (batch->reloc)
+ free(batch->reloc);
batch->buffer = NULL;
free(batch);
}
+void
+intel_offset_relocation(struct intel_batchbuffer *batch,
+ unsigned pre_add,
+ struct _DriBufferObject *driBO,
+ uint64_t val_flags,
+ uint64_t val_mask)
+{
+ int itemLoc;
+ struct _drmBONode *node;
+ uint32_t *reloc;
+ struct drm_bo_info_req *req;
+
+ driBOAddListItem(batch->list, driBO, val_flags, val_mask,
+ &itemLoc, &node);
+ req = &node->bo_arg.d.req.bo_req;
+
+ if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) {
+
+ /*
+ * Stop other threads from tampering with the underlying
+ * drmBO while we're reading its offset.
+ */
+
+ driReadLockKernelBO();
+ req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset;
+ driReadUnlockKernelBO();
+ req->hint = DRM_BO_HINT_PRESUMED_OFFSET;
+ }
+
+ pre_add += driBOPoolOffset(driBO);
+
+ if (batch->nr_relocs == batch->reloc_size)
+ intel_realloc_relocs(batch, batch->reloc_size * 2);
+
+ reloc = batch->reloc +
+ (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE);
+
+ reloc[0] = ((uint8_t *)batch->base.ptr - batch->drmBOVirtual);
+ intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add);
+ reloc[1] = pre_add;
+ reloc[2] = itemLoc;
+ reloc[3] = batch->dest_location;
+ batch->nr_relocs++;
+}
static void
-intel_batch_ioctl(struct intel_context *intel,
- uint start_offset, uint used, boolean allow_unlock)
+i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf)
{
- drmI830BatchBuffer batch;
-
- batch.start = start_offset;
- batch.used = used;
- batch.cliprects = NULL; /* unused */
- batch.num_cliprects = 0;
- batch.DR1 = 0;
- batch.DR4 = 0; /* still need this ? */
-
- DBG(IOCTL, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
- __FUNCTION__,
- batch.start,
- batch.start + batch.used * 4, batch.DR4, batch.num_cliprects);
-
- if (drmCommandWrite(intel->driFd, DRM_I830_BATCHBUFFER, &batch,
- sizeof(batch))) {
- printf("DRM_I830_BATCHBUFFER: %d\n", -errno);
- UNLOCK_HARDWARE(intel);
- exit(1);
- }
+ buf->handle = rep->handle;
+ buf->flags = rep->flags;
+ buf->size = rep->size;
+ buf->offset = rep->offset;
+ buf->mapHandle = rep->arg_handle;
+ buf->proposedFlags = rep->proposed_flags;
+ buf->start = rep->buffer_start;
+ buf->fenceFlags = rep->fence_flags;
+ buf->replyFlags = rep->rep_flags;
+ buf->pageAlignment = rep->page_alignment;
}
+static int
+i915_execbuf(struct intel_batchbuffer *batch,
+ GLuint used,
+ GLboolean ignore_cliprects,
+ drmBOList *list,
+ struct drm_i915_execbuffer *ea)
+{
+ struct intel_context *intel = batch->intel;
+ drmBONode *node;
+ drmMMListHead *l;
+ struct drm_i915_op_arg *arg, *first;
+ struct drm_bo_op_req *req;
+ struct drm_bo_info_rep *rep;
+ uint64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret = 0;
+ uint32_t count = 0;
+
+ first = NULL;
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long)arg;
+
+ prevNext = &arg->next;
+ req->bo_req.handle = node->buf->handle;
+ req->op = drm_bo_validate;
+ req->bo_req.flags = node->arg0;
+ req->bo_req.mask = node->arg1;
+ req->bo_req.hint |= 0;
+ count++;
+ }
+
+ memset(ea, 0, sizeof(*ea));
+ ea->num_buffers = count;
+ ea->batch.start = batch->poolOffset;
+ ea->batch.used = used;
+#if 0 /* ZZZ JB: no cliprects used */
+ ea->batch.cliprects = intel->pClipRects;
+ ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+ ea->batch.DR1 = 0;
+ ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) |
+ (((GLuint) intel->drawY) << 16));
+#else
+ ea->batch.cliprects = NULL;
+ ea->batch.num_cliprects = 0;
+ ea->batch.DR1 = 0;
+ ea->batch.DR4 = 0;
+#endif
+ ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED;
+ ea->ops_list = (unsigned long) first;
+ first->reloc_ptr = (unsigned long) batch->reloc;
+ batch->reloc[0] = batch->nr_relocs;
+
+ //return -EFAULT;
+ do {
+ ret = drmCommandWriteRead(intel->driFd, DRM_I915_EXECBUFFER, ea,
+ sizeof(*ea));
+ } while (ret == -EAGAIN);
+
+ if (ret != 0)
+ return ret;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ arg = &node->bo_arg;
+ rep = &arg->d.rep.bo_info;
+
+ if (!arg->handled) {
+ return -EFAULT;
+ }
+ if (arg->d.rep.ret)
+ return arg->d.rep.ret;
+
+ buf = node->buf;
+ i915_drm_copy_reply(rep, buf);
+ }
+ return 0;
+}
/* TODO: Push this whole function into bufmgr.
*/
-static void
+static struct _DriFenceObject *
do_flush_locked(struct intel_batchbuffer *batch,
- uint used, boolean allow_unlock)
+ GLuint used,
+ GLboolean ignore_cliprects, GLboolean allow_unlock)
{
- uint *ptr;
- uint i, fenceFlags;
+ struct intel_context *intel = batch->intel;
struct _DriFenceObject *fo;
+ drmFence fence;
+ drmBOList *boList;
+ struct drm_i915_execbuffer ea;
+ int ret = 0;
+
+ driBOValidateUserList(batch->list);
+ boList = driGetdrmBOList(batch->list);
+
+#if 0 /* ZZZ JB Allways run */
+ if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
+#else
+ if (1) {
+#endif
+ ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea);
+ } else {
+ driPutdrmBOList(batch->list);
+ fo = NULL;
+ goto out;
+ }
+ driPutdrmBOList(batch->list);
+ if (ret)
+ abort();
- driBOValidateList(batch->intel->driFd, &batch->list);
-
- /* Apply the relocations. This nasty map indicates to me that the
- * whole task should be done internally by the memory manager, and
- * that dma buffers probably need to be pinned within agp space.
- */
- ptr = (uint *) driBOMap(batch->buffer, DRM_BO_FLAG_WRITE,
- DRM_BO_HINT_ALLOW_UNFENCED_MAP);
+ if (ea.fence_arg.error != 0) {
- for (i = 0; i < batch->nr_relocs; i++) {
- struct buffer_reloc *r = &batch->reloc[i];
+ /*
+ * The hardware has been idled by the kernel.
+ * Don't fence the driBOs.
+ */
- ptr[r->offset / 4] = driBOOffset(r->buf) + r->delta;
+ if (batch->last_fence)
+ driFenceUnReference(&batch->last_fence);
+#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */
+ _mesa_printf("fence error\n");
+#endif
+ batch->last_fence = NULL;
+ fo = NULL;
+ goto out;
}
- if (0)
- intel_dump_batchbuffer(0, ptr, used);
-
- driBOUnmap(batch->buffer);
- batch->map = NULL;
+ fence.handle = ea.fence_arg.handle;
+ fence.fence_class = ea.fence_arg.fence_class;
+ fence.type = ea.fence_arg.type;
+ fence.flags = ea.fence_arg.flags;
+ fence.signaled = ea.fence_arg.signaled;
- intel_batch_ioctl(batch->intel,
- driBOOffset(batch->buffer),
- used, allow_unlock);
+ fo = driBOFenceUserList(batch->intel->intelScreen->mgr, batch->list,
+ "SuperFence", &fence);
+ if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) {
+ if (batch->last_fence)
+ driFenceUnReference(&batch->last_fence);
/*
- * Kernel fencing. The flags tells the kernel that we've
- * programmed an MI_FLUSH.
- */
- fenceFlags = DRM_I915_FENCE_FLAG_FLUSHED;
- fo = driFenceBuffers(batch->intel->driFd, "Batch fence", fenceFlags);
-
- /*
- * User space fencing.
- */
- driBOFence(batch->buffer, fo);
-
- if (driFenceType(fo) == DRM_FENCE_TYPE_EXE) {
- /*
- * Oops. We only validated a batch buffer. This means we
- * didn't do any proper rendering. Discard this fence object.
- */
- driFenceUnReference(fo);
- }
- else {
- driFenceUnReference(batch->last_fence);
- batch->last_fence = fo;
- for (i = 0; i < batch->nr_relocs; i++) {
- struct buffer_reloc *r = &batch->reloc[i];
- driBOFence(r->buf, fo);
- }
- }
+ * FIXME: Context last fence??
+ */
+ batch->last_fence = fo;
+ driFenceReference(fo);
+ }
+ out:
+#if 0 /* ZZZ JB: fix this */
+ intel->vtbl.lost_hardware(intel);
+#else
+ (void)intel;
+#endif
+ return fo;
}
@@ -263,32 +384,46 @@ struct _DriFenceObject *
intel_batchbuffer_flush(struct intel_batchbuffer *batch)
{
struct intel_context *intel = batch->intel;
- uint used = batch->ptr - batch->map;
- const boolean was_locked = intel->locked;
+ GLuint used = batch->base.ptr - batch->base.map;
+ GLboolean was_locked = intel->locked;
+ struct _DriFenceObject *fence;
- if (used == 0)
+ if (used == 0) {
+ driFenceReference(batch->last_fence);
return batch->last_fence;
-
-#define MI_FLUSH ((0 << 29) | (4 << 23))
+ }
/* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a
* performance drain that we would like to avoid.
*/
+#if 0 /* ZZZ JB: what should we do here? */
if (used & 4) {
- ((int *) batch->ptr)[0] = MI_FLUSH;
- ((int *) batch->ptr)[1] = 0;
- ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END;
+ ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd();
+ ((int *) batch->base.ptr)[1] = 0;
+ ((int *) batch->base.ptr)[2] = MI_BATCH_BUFFER_END;
used += 12;
}
else {
- ((int *) batch->ptr)[0] = MI_FLUSH;
- ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END;
+ ((int *) batch->base.ptr)[0] = intel->vtbl.flush_cmd();
+ ((int *) batch->base.ptr)[1] = MI_BATCH_BUFFER_END;
used += 8;
}
-
+#else
+ if (used & 4) {
+ ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((int *) batch->base.ptr)[1] = 0;
+ ((int *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ used += 12;
+ }
+ else {
+ ((int *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((int *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ used += 8;
+ }
+#endif
driBOUnmap(batch->buffer);
- batch->ptr = NULL;
- batch->map = NULL;
+ batch->base.ptr = NULL;
+ batch->base.map = NULL;
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
@@ -296,7 +431,8 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
if (!was_locked)
LOCK_HARDWARE(intel);
- do_flush_locked(batch, used, GL_FALSE);
+ fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
+ GL_FALSE);
if (!was_locked)
UNLOCK_HARDWARE(intel);
@@ -304,55 +440,23 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
/* Reset the buffer:
*/
intel_batchbuffer_reset(batch);
- return batch->last_fence;
+ return fence;
}
-
void
intel_batchbuffer_finish(struct intel_batchbuffer *batch)
{
struct _DriFenceObject *fence = intel_batchbuffer_flush(batch);
- if (fence) {
- driFenceReference(fence);
- driFenceFinish(fence,
- DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW,
- GL_FALSE);
- driFenceUnReference(fence);
- }
+ driFenceFinish(fence, driFenceType(fence), GL_FALSE);
+ driFenceUnReference(&fence);
}
-
-/* This is the only way buffers get added to the validate list.
- */
-boolean
-intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
- struct _DriBufferObject *buffer,
- uint flags, uint mask, uint delta)
-{
- assert(batch->nr_relocs < MAX_RELOCS);
-
- driBOAddListItem(&batch->list, buffer, flags, mask);
-
- {
- struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
- driBOReference(buffer);
- r->buf = buffer;
- r->offset = batch->ptr - batch->map;
- r->delta = delta;
- *(uint *) batch->ptr = 0x12345678;
- }
-
- batch->ptr += 4;
- return GL_TRUE;
-}
-
-
void
intel_batchbuffer_data(struct intel_batchbuffer *batch,
- const void *data, uint bytes, uint flags)
+ const void *data, GLuint bytes, GLuint flags)
{
assert((bytes & 3) == 0);
intel_batchbuffer_require_space(batch, bytes, flags);
- memcpy(batch->ptr, data, bytes);
- batch->ptr += bytes;
+ memcpy(batch->base.ptr, data, bytes);
+ batch->base.ptr += bytes;
}
diff --git a/src/gallium/winsys/dri/intel/intel_batchbuffer.h b/src/gallium/winsys/dri/intel/intel_batchbuffer.h
index caf6870a3c..abb7a624f5 100644
--- a/src/gallium/winsys/dri/intel/intel_batchbuffer.h
+++ b/src/gallium/winsys/dri/intel/intel_batchbuffer.h
@@ -1,74 +1,49 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
#ifndef INTEL_BATCHBUFFER_H
#define INTEL_BATCHBUFFER_H
-#include "pipe/p_debug.h"
-#include "pipe/p_compiler.h"
-#include "dri_bufmgr.h"
+#include "mtypes.h"
+#include "ws_dri_bufmgr.h"
+#include "i915simple/i915_batch.h"
struct intel_context;
#define BATCH_SZ 16384
#define BATCH_RESERVED 16
-#define MAX_RELOCS 4096
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
#define INTEL_BATCH_NO_CLIPRECTS 0x1
#define INTEL_BATCH_CLIPRECTS 0x2
-struct buffer_reloc
-{
- struct _DriBufferObject *buf;
- uint offset;
- uint delta; /* not needed? */
-};
-
struct intel_batchbuffer
{
- struct bufmgr *bm;
+ struct i915_batchbuffer base;
+
struct intel_context *intel;
struct _DriBufferObject *buffer;
struct _DriFenceObject *last_fence;
- uint flags;
+ GLuint flags;
+
+ struct _DriBufferList *list;
+ GLuint list_count;
- drmBOList list;
- uint list_count;
- ubyte *map;
- ubyte *ptr;
+ uint32_t *reloc;
+ GLuint reloc_size;
+ GLuint nr_relocs;
- struct buffer_reloc reloc[MAX_RELOCS];
- uint nr_relocs;
- uint size;
+ GLuint dirty_state;
+ GLuint id;
+
+ uint32_t poolOffset;
+ uint8_t *drmBOVirtual;
+ struct _drmBONode *node; /* Validation list node for this buffer */
+ int dest_location; /* Validation list sequence for this buffer */
};
-struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel);
+struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context
+ *intel);
void intel_batchbuffer_free(struct intel_batchbuffer *batch);
@@ -82,68 +57,80 @@ void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
/* Unlike bmBufferData, this currently requires the buffer be mapped.
- * Consider it a convenience function wrapping multiple
+ * Consider it a convenience function wrapping multple
* intel_buffer_dword() calls.
*/
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
- const void *data, uint bytes, uint flags);
+ const void *data, GLuint bytes, GLuint flags);
void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
- uint bytes);
+ GLuint bytes);
-boolean intel_batchbuffer_emit_reloc(struct intel_batchbuffer *batch,
- struct _DriBufferObject *buffer,
- uint flags,
- uint mask, uint offset);
+void
+intel_offset_relocation(struct intel_batchbuffer *batch,
+ unsigned pre_add,
+ struct _DriBufferObject *driBO,
+ uint64_t val_flags,
+ uint64_t val_mask);
/* Inline functions - might actually be better off with these
* non-inlined. Certainly better off switching all command packets to
* be passed as structs rather than dwords, but that's a little bit of
* work...
*/
-static INLINE uint
+static INLINE GLuint
intel_batchbuffer_space(struct intel_batchbuffer *batch)
{
- return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+ return (batch->base.size - BATCH_RESERVED) - (batch->base.ptr - batch->base.map);
}
static INLINE void
-intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, uint dword)
+intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
{
- assert(batch->map);
+ assert(batch->base.map);
assert(intel_batchbuffer_space(batch) >= 4);
- *(uint *) (batch->ptr) = dword;
- batch->ptr += 4;
+ *(GLuint *) (batch->base.ptr) = dword;
+ batch->base.ptr += 4;
}
static INLINE void
intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
- uint sz, uint flags)
+ GLuint sz, GLuint flags)
{
- assert(sz < batch->size - 8);
+ struct _DriFenceObject *fence;
+
+ assert(sz < batch->base.size - 8);
if (intel_batchbuffer_space(batch) < sz ||
- (batch->flags != 0 && flags != 0 && batch->flags != flags))
- intel_batchbuffer_flush(batch);
+ (batch->flags != 0 && flags != 0 && batch->flags != flags)) {
+ fence = intel_batchbuffer_flush(batch);
+ driFenceUnReference(&fence);
+ }
batch->flags |= flags;
}
/* Here are the crusty old macros, to be removed:
*/
+#undef BATCH_LOCALS
#define BATCH_LOCALS
+#undef BEGIN_BATCH
#define BEGIN_BATCH(n, flags) do { \
+ assert(!intel->prim.flush); \
intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \
} while (0)
+#undef OUT_BATCH
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
+#undef OUT_RELOC
#define OUT_RELOC(buf,flags,mask,delta) do { \
- assert((delta) >= 0); \
- intel_batchbuffer_emit_reloc(intel->batch, buf, flags, mask, delta); \
+ assert((delta) >= 0); \
+ intel_offset_relocation(intel->batch, delta, buf, flags, mask); \
} while (0)
+#undef ADVANCE_BATCH
#define ADVANCE_BATCH() do { } while(0)
diff --git a/src/gallium/winsys/dri/intel/intel_batchpool.c b/src/gallium/winsys/dri/intel/intel_batchpool.c
deleted file mode 100644
index ce154c7b88..0000000000
--- a/src/gallium/winsys/dri/intel/intel_batchpool.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-/**
- * XXX NOTE: there are no intel dependencies in this file.
- * Rename to dri_batchpool.c?
- */
-
-#include <xf86drm.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_thread.h"
-
-#include "dri_bufpool.h"
-#include "dri_bufmgr.h"
-#include "intel_batchpool.h"
-
-
-typedef struct
-{
- drmMMListHead head;
- struct _BPool *parent;
- struct _DriFenceObject *fence;
- unsigned long start;
- int unfenced;
- int mapped;
-} BBuf;
-
-typedef struct _BPool
-{
- _glthread_Mutex mutex;
- unsigned long bufSize;
- unsigned poolSize;
- unsigned numFree;
- unsigned numTot;
- unsigned numDelayed;
- unsigned checkDelayed;
- drmMMListHead free;
- drmMMListHead delayed;
- drmMMListHead head;
- drmBO kernelBO;
- void *virtual;
- BBuf *bufs;
-} BPool;
-
-
-static BPool *
-createBPool(int fd, unsigned long bufSize, unsigned numBufs, unsigned flags,
- unsigned checkDelayed)
-{
- BPool *p = (BPool *) malloc(sizeof(*p));
- BBuf *buf;
- int i;
-
- if (!p)
- return NULL;
-
- p->bufs = (BBuf *) malloc(numBufs * sizeof(*p->bufs));
- if (!p->bufs) {
- free(p);
- return NULL;
- }
-
- DRMINITLISTHEAD(&p->free);
- DRMINITLISTHEAD(&p->head);
- DRMINITLISTHEAD(&p->delayed);
-
- p->numTot = numBufs;
- p->numFree = numBufs;
- p->bufSize = bufSize;
- p->numDelayed = 0;
- p->checkDelayed = checkDelayed;
-
- _glthread_INIT_MUTEX(p->mutex);
-
- if (drmBOCreate(fd, 0, numBufs * bufSize, 0, NULL, drm_bo_type_dc,
- flags, DRM_BO_HINT_DONT_FENCE, &p->kernelBO)) {
- free(p->bufs);
- free(p);
- return NULL;
- }
- if (drmBOMap(fd, &p->kernelBO, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0,
- &p->virtual)) {
- drmBODestroy(fd, &p->kernelBO);
- free(p->bufs);
- free(p);
- return NULL;
- }
-
- /*
- * We unmap the buffer so that we can validate it later. Note that this is
- * just a synchronizing operation. The buffer will have a virtual mapping
- * until it is destroyed.
- */
-
- drmBOUnmap(fd, &p->kernelBO);
-
- buf = p->bufs;
- for (i = 0; i < numBufs; ++i) {
- buf->parent = p;
- buf->fence = NULL;
- buf->start = i * bufSize;
- buf->mapped = 0;
- buf->unfenced = 0;
- DRMLISTADDTAIL(&buf->head, &p->free);
- buf++;
- }
-
- return p;
-}
-
-
-static void
-pool_checkFree(BPool * p, int wait)
-{
- drmMMListHead *list, *prev;
- BBuf *buf;
- int signaled = 0;
- int i;
-
- list = p->delayed.next;
-
- if (p->numDelayed > 3) {
- for (i = 0; i < p->numDelayed; i += 3) {
- list = list->next;
- }
- }
-
- prev = list->prev;
- for (; list != &p->delayed; list = prev, prev = list->prev) {
-
- buf = DRMLISTENTRY(BBuf, list, head);
-
- if (!signaled) {
- if (wait) {
- driFenceFinish(buf->fence, DRM_FENCE_TYPE_EXE, 1);
- signaled = 1;
- }
- else {
- signaled = driFenceSignaled(buf->fence, DRM_FENCE_TYPE_EXE);
- }
- }
-
- if (!signaled)
- break;
-
- driFenceUnReference(buf->fence);
- buf->fence = NULL;
- DRMLISTDEL(list);
- p->numDelayed--;
- DRMLISTADD(list, &p->free);
- p->numFree++;
- }
-}
-
-static void *
-pool_create(struct _DriBufferPool *pool,
- unsigned long size, unsigned flags, unsigned hint,
- unsigned alignment)
-{
- BPool *p = (BPool *) pool->data;
-
- drmMMListHead *item;
-
- if (alignment && (alignment != 4096))
- return NULL;
-
- _glthread_LOCK_MUTEX(p->mutex);
-
- if (p->numFree == 0)
- pool_checkFree(p, TRUE);
-
- if (p->numFree == 0) {
- fprintf(stderr, "Out of fixed size buffer objects\n");
- BM_CKFATAL(-ENOMEM);
- }
-
- item = p->free.next;
-
- if (item == &p->free) {
- fprintf(stderr, "Fixed size buffer pool corruption\n");
- }
-
- DRMLISTDEL(item);
- --p->numFree;
-
- _glthread_UNLOCK_MUTEX(p->mutex);
- return (void *) DRMLISTENTRY(BBuf, item, head);
-}
-
-
-static int
-pool_destroy(struct _DriBufferPool *pool, void *private)
-{
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
-
- _glthread_LOCK_MUTEX(p->mutex);
-
- if (buf->fence) {
- DRMLISTADDTAIL(&buf->head, &p->delayed);
- p->numDelayed++;
- }
- else {
- buf->unfenced = 0;
- DRMLISTADD(&buf->head, &p->free);
- p->numFree++;
- }
-
- if ((p->numDelayed % p->checkDelayed) == 0)
- pool_checkFree(p, 0);
-
- _glthread_UNLOCK_MUTEX(p->mutex);
- return 0;
-}
-
-
-static int
-pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
- int hint, void **virtual)
-{
-
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
-
- _glthread_LOCK_MUTEX(p->mutex);
-
- /*
- * Currently Mesa doesn't have any condition variables to resolve this
- * cleanly in a multithreading environment.
- * We bail out instead.
- */
-
- if (buf->mapped) {
- fprintf(stderr, "Trying to map already mapped buffer object\n");
- BM_CKFATAL(-EINVAL);
- }
-
-#if 0
- if (buf->unfenced && !(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) {
- fprintf(stderr, "Trying to map an unfenced buffer object 0x%08x"
- " 0x%08x %d\n", hint, flags, buf->start);
- BM_CKFATAL(-EINVAL);
- }
-
-#endif
-
- if (buf->fence) {
- _glthread_UNLOCK_MUTEX(p->mutex);
- return -EBUSY;
- }
-
- buf->mapped = TRUE;
- *virtual = (unsigned char *) p->virtual + buf->start;
- _glthread_UNLOCK_MUTEX(p->mutex);
- return 0;
-}
-
-static int
-pool_waitIdle(struct _DriBufferPool *pool, void *private, int lazy)
-{
- BBuf *buf = (BBuf *) private;
- driFenceFinish(buf->fence, 0x0, lazy);
- return 0;
-}
-
-static int
-pool_unmap(struct _DriBufferPool *pool, void *private)
-{
- BBuf *buf = (BBuf *) private;
-
- buf->mapped = 0;
- return 0;
-}
-
-static unsigned long
-pool_offset(struct _DriBufferPool *pool, void *private)
-{
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
-
- return p->kernelBO.offset + buf->start;
-}
-
-static unsigned
-pool_flags(struct _DriBufferPool *pool, void *private)
-{
- BPool *p = (BPool *) pool->data;
-
- return p->kernelBO.flags;
-}
-
-static unsigned long
-pool_size(struct _DriBufferPool *pool, void *private)
-{
- BPool *p = (BPool *) pool->data;
-
- return p->bufSize;
-}
-
-
-static int
-pool_fence(struct _DriBufferPool *pool, void *private,
- struct _DriFenceObject *fence)
-{
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
-
- _glthread_LOCK_MUTEX(p->mutex);
- if (buf->fence) {
- driFenceUnReference(buf->fence);
- }
- buf->fence = fence;
- buf->unfenced = 0;
- driFenceReference(buf->fence);
- _glthread_UNLOCK_MUTEX(p->mutex);
-
- return 0;
-}
-
-static drmBO *
-pool_kernel(struct _DriBufferPool *pool, void *private)
-{
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
-
- return &p->kernelBO;
-}
-
-static int
-pool_validate(struct _DriBufferPool *pool, void *private)
-{
- BBuf *buf = (BBuf *) private;
- BPool *p = buf->parent;
- _glthread_LOCK_MUTEX(p->mutex);
- buf->unfenced = TRUE;
- _glthread_UNLOCK_MUTEX(p->mutex);
- return 0;
-}
-
-static void
-pool_takedown(struct _DriBufferPool *pool)
-{
- BPool *p = (BPool *) pool->data;
-
- /*
- * Wait on outstanding fences.
- */
-
- _glthread_LOCK_MUTEX(p->mutex);
- while ((p->numFree < p->numTot) && p->numDelayed) {
- _glthread_UNLOCK_MUTEX(p->mutex);
- sched_yield();
- pool_checkFree(p, TRUE);
- _glthread_LOCK_MUTEX(p->mutex);
- }
-
- drmBODestroy(pool->fd, &p->kernelBO);
- free(p->bufs);
- _glthread_UNLOCK_MUTEX(p->mutex);
- free(p);
- free(pool);
-}
-
-
-struct _DriBufferPool *
-driBatchPoolInit(int fd, unsigned flags,
- unsigned long bufSize,
- unsigned numBufs, unsigned checkDelayed)
-{
- struct _DriBufferPool *pool;
-
- pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
- if (!pool)
- return NULL;
-
- pool->data = createBPool(fd, bufSize, numBufs, flags, checkDelayed);
- if (!pool->data)
- return NULL;
-
- pool->fd = fd;
- pool->map = &pool_map;
- pool->unmap = &pool_unmap;
- pool->destroy = &pool_destroy;
- pool->offset = &pool_offset;
- pool->flags = &pool_flags;
- pool->size = &pool_size;
- pool->create = &pool_create;
- pool->fence = &pool_fence;
- pool->kernel = &pool_kernel;
- pool->validate = &pool_validate;
- pool->waitIdle = &pool_waitIdle;
- pool->setstatic = NULL;
- pool->takeDown = &pool_takedown;
- return pool;
-}
diff --git a/src/gallium/winsys/dri/intel/intel_context.c b/src/gallium/winsys/dri/intel/intel_context.c
index 8eba33c313..6a0c381849 100644
--- a/src/gallium/winsys/dri/intel/intel_context.c
+++ b/src/gallium/winsys/dri/intel/intel_context.c
@@ -35,6 +35,7 @@
#include "intel_batchbuffer.h"
#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
@@ -162,6 +163,7 @@ intelCreateContext(const __GLcontextModes * visual,
* memory pools
*/
DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
+ // ZZZ JB should be per screen and not be done per context
havePools = intelCreatePools(sPriv);
DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
if (!havePools)
@@ -217,6 +219,8 @@ intelCreateContext(const __GLcontextModes * visual,
intel->st = st_create_context(pipe, visual, st_share);
+ driInitExtensions( intel->st->ctx, card_extensions, GL_TRUE );
+
return GL_TRUE;
}
@@ -234,12 +238,12 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
if (intel->last_swap_fence) {
driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
- driFenceUnReference(intel->last_swap_fence);
+ driFenceUnReference(&intel->last_swap_fence);
intel->last_swap_fence = NULL;
}
if (intel->first_swap_fence) {
driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
- driFenceUnReference(intel->first_swap_fence);
+ driFenceUnReference(&intel->first_swap_fence);
intel->first_swap_fence = NULL;
}
diff --git a/src/gallium/winsys/dri/intel/intel_context.h b/src/gallium/winsys/dri/intel/intel_context.h
index 45430984d8..597dc13830 100644
--- a/src/gallium/winsys/dri/intel/intel_context.h
+++ b/src/gallium/winsys/dri/intel/intel_context.h
@@ -28,7 +28,7 @@
#ifndef INTEL_CONTEXT_H
#define INTEL_CONTEXT_H
-
+#include <stdint.h>
#include "drm.h"
#include "pipe/p_debug.h"
diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c
index 9e31c013a9..0be88974f4 100644
--- a/src/gallium/winsys/dri/intel/intel_screen.c
+++ b/src/gallium/winsys/dri/intel/intel_screen.c
@@ -32,12 +32,12 @@
#include "intel_context.h"
#include "intel_screen.h"
#include "intel_batchbuffer.h"
-#include "intel_batchpool.h"
+//#include "intel_batchpool.h"
#include "intel_swapbuffers.h"
#include "intel_winsys.h"
#include "i830_dri.h"
-#include "dri_bufpool.h"
+#include "ws_dri_bufpool.h"
#include "pipe/p_context.h"
#include "state_tracker/st_public.h"
@@ -50,11 +50,11 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
- DRI_CONF_FORCE_S3TC_ENABLE(false)
+// DRI_CONF_FORCE_S3TC_ENABLE(false)
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
-const uint __driNConfigOptions = 4;
+const uint __driNConfigOptions = 3;
#ifdef USE_NEW_INTERFACE
static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
@@ -132,6 +132,7 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea)
assert( sarea->front_size >=
intelScreen->front.pitch * intelScreen->front.height );
+#if 0 /* JB not important */
if (!sarea->front_handle)
return;
@@ -142,30 +143,41 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea)
fprintf(stderr, "drmMap(frontbuffer) failed!\n");
return;
}
+#endif
+#if 0 /* JB */
if (intelScreen->staticPool) {
driGenBuffers(intelScreen->staticPool, "static region", 1,
&intelScreen->front.buffer, 64,
DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE |
DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0);
-
+
driBOSetStatic(intelScreen->front.buffer,
intelScreen->front.offset,
intelScreen->front.pitch * intelScreen->front.height,
intelScreen->front.map, 0);
}
+#else
+ if (intelScreen->staticPool) {
+ if (intelScreen->front.buffer)
+ driBOUnReference(intelScreen->front.buffer);
+ driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
+ driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle);
+ }
+#endif
}
boolean
intelCreatePools(__DRIscreenPrivate * sPriv)
{
- unsigned batchPoolSize = 1024*1024;
+ //unsigned batchPoolSize = 1024*1024;
struct intel_screen *intelScreen = intel_screen(sPriv);
if (intelScreen->havePools)
return GL_TRUE;
+#if 0 /* ZZZ JB fix this */
intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd);
if (!intelScreen->staticPool)
return GL_FALSE;
@@ -181,7 +193,17 @@ intelCreatePools(__DRIscreenPrivate * sPriv)
fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n");
return GL_FALSE;
}
-
+#else
+ intelScreen->staticPool = driDRMPoolInit(sPriv->fd);
+ intelScreen->batchPool = driSlabPoolInit(sPriv->fd,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ intelScreen->max_batch_size,
+ 1, 40, intelScreen->max_batch_size * 16, 0,
+ intelScreen->fMan);
+#endif
intelScreen->havePools = GL_TRUE;
intelUpdateScreenRotation(sPriv, intelScreen->sarea);
@@ -240,7 +262,26 @@ intelInitDriver(__DRIscreenPrivate * sPriv)
(*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
}
- intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd);
+ intelScreen->max_batch_size = 16 * 4096;
+
+#if 1 // ZZZ JB
+ intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd);
+ if (!intelScreen->mgr) {
+ fprintf(stderr, "Failed to create fence manager.\n");
+ return GL_FALSE;
+ }
+
+ intelScreen->fMan = driInitFreeSlabManager(10, 10);
+ if (!intelScreen->fMan) {
+ fprintf(stderr, "Failed to create free slab manager.\n");
+ return GL_FALSE;
+ }
+
+ if (!intelCreatePools(sPriv))
+ return GL_FALSE;
+#endif
+
+ intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan);
return GL_TRUE;
}
diff --git a/src/gallium/winsys/dri/intel/intel_screen.h b/src/gallium/winsys/dri/intel/intel_screen.h
index 3396f9e564..1db0502b13 100644
--- a/src/gallium/winsys/dri/intel/intel_screen.h
+++ b/src/gallium/winsys/dri/intel/intel_screen.h
@@ -31,7 +31,7 @@
#include "dri_util.h"
#include "i830_common.h"
#include "xmlconfig.h"
-#include "dri_bufpool.h"
+#include "ws_dri_bufpool.h"
#include "pipe/p_compiler.h"
@@ -74,6 +74,14 @@ struct intel_screen
*/
struct intel_context *dummyContext;
+ /*
+ * New stuff form the i915tex integration
+ */
+ struct _DriFenceMgr *mgr;
+ struct _DriFreeSlabManager *fMan;
+ unsigned batch_id;
+ unsigned max_batch_size;
+
struct pipe_winsys *winsys;
};
diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c
index 56b86d6a63..923b542771 100644
--- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c
+++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c
@@ -63,7 +63,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv,
if (intel->last_swap_fence) {
driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE);
- driFenceUnReference(intel->last_swap_fence);
+ driFenceUnReference(&intel->last_swap_fence);
intel->last_swap_fence = NULL;
}
intel->last_swap_fence = intel->first_swap_fence;
@@ -178,9 +178,8 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv,
}
if (intel->first_swap_fence)
- driFenceUnReference(intel->first_swap_fence);
+ driFenceUnReference(&intel->first_swap_fence);
intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
- driFenceReference(intel->first_swap_fence);
}
UNLOCK_HARDWARE(intel);
diff --git a/src/gallium/winsys/dri/intel/intel_winsys.h b/src/gallium/winsys/dri/intel/intel_winsys.h
index ffc40782be..3d32db10a4 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys.h
+++ b/src/gallium/winsys/dri/intel/intel_winsys.h
@@ -37,7 +37,7 @@ struct pipe_buffer;
struct _DriBufferObject;
struct pipe_winsys *
-intel_create_pipe_winsys( int fd );
+intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan );
void
intel_destroy_pipe_winsys( struct pipe_winsys *winsys );
@@ -53,6 +53,7 @@ intel_create_i915simple( struct intel_context *intel,
struct intel_buffer {
struct pipe_buffer base;
+ struct _DriBufferPool *pool;
struct _DriBufferObject *driBO;
};
@@ -69,5 +70,4 @@ dri_bo( struct pipe_buffer *buf )
}
-
#endif
diff --git a/src/gallium/winsys/dri/intel/intel_winsys_i915.c b/src/gallium/winsys/dri/intel/intel_winsys_i915.c
index 4d183db7c3..013291364a 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys_i915.c
+++ b/src/gallium/winsys/dri/intel/intel_winsys_i915.c
@@ -31,8 +31,8 @@
#include <stdlib.h>
#include <xf86drm.h>
-#include "dri_bufpool.h"
-#include "dri_bufmgr.h"
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
@@ -63,28 +63,11 @@ intel_i915_winsys( struct i915_winsys *sws )
/* Simple batchbuffer interface:
*/
-static unsigned *intel_i915_batch_start( struct i915_winsys *sws,
- unsigned dwords,
- unsigned relocs )
+static struct i915_batchbuffer*
+intel_i915_batch_get( struct i915_winsys *sws )
{
struct intel_context *intel = intel_i915_winsys(sws)->intel;
-
- /* XXX: check relocs.
- */
- if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) {
- /* XXX: Hmm, the driver can't really do much with this pointer:
- */
- return (unsigned *)intel->batch->ptr;
- }
- else
- return NULL;
-}
-
-static void intel_i915_batch_dword( struct i915_winsys *sws,
- unsigned dword )
-{
- struct intel_context *intel = intel_i915_winsys(sws)->intel;
- intel_batchbuffer_emit_dword( intel->batch, dword );
+ return &intel->batch->base;
}
static void intel_i915_batch_reloc( struct i915_winsys *sws,
@@ -106,14 +89,13 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws,
mask |= DRM_BO_FLAG_READ;
}
- intel_batchbuffer_emit_reloc( intel->batch,
- dri_bo( buf ),
- flags, mask,
- delta );
+ intel_offset_relocation( intel->batch,
+ delta,
+ dri_bo( buf ),
+ flags,
+ mask );
}
-
-
static void intel_i915_batch_flush( struct i915_winsys *sws,
struct pipe_fence_handle **fence )
{
@@ -124,12 +106,24 @@ static void intel_i915_batch_flush( struct i915_winsys *sws,
struct pipe_fence_handle *pipe;
} fu;
+ if (fence)
+ assert(!*fence);
+
fu.dri = intel_batchbuffer_flush( intel->batch );
- if (fu.dri)
- iws->pws->fence_reference(iws->pws, fence, fu.pipe);
+ if (!fu.dri) {
+ assert(0);
+ *fence = NULL;
+ return;
+ }
+
+ if (fu.dri) {
+ if (fence)
+ *fence = fu.pipe;
+ else
+ driFenceUnReference(&fu.dri);
+ }
-// if (0) intel_i915_batch_wait_idle( sws );
}
@@ -146,8 +140,7 @@ intel_create_i915simple( struct intel_context *intel,
/* Fill in this struct with callbacks that i915simple will need to
* communicate with the window system, buffer manager, etc.
*/
- iws->winsys.batch_start = intel_i915_batch_start;
- iws->winsys.batch_dword = intel_i915_batch_dword;
+ iws->winsys.batch_get = intel_i915_batch_get;
iws->winsys.batch_reloc = intel_i915_batch_reloc;
iws->winsys.batch_flush = intel_i915_batch_flush;
iws->pws = winsys;
diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
index d15143acfd..51a79ca535 100644
--- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
+++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c
@@ -31,8 +31,6 @@
#include <stdlib.h>
#include <xf86drm.h>
-#include "dri_bufpool.h"
-#include "dri_bufmgr.h"
#include "intel_context.h"
#include "intel_winsys.h"
@@ -45,15 +43,15 @@
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
-
-
struct intel_pipe_winsys {
struct pipe_winsys winsys;
struct _DriBufferPool *regionPool;
+ struct _DriBufferPool *mallocPool;
+ struct _DriBufferPool *vertexPool;
+ struct _DriFreeSlabManager *fMan; /** shared between all pipes */
};
-
/* Turn a pipe winsys into an intel/pipe winsys:
*/
static inline struct intel_pipe_winsys *
@@ -63,8 +61,12 @@ intel_pipe_winsys( struct pipe_winsys *winsys )
}
-/* Most callbacks map direcly onto dri_bufmgr operations:
+/*
+ * Buffer functions.
+ *
+ * Most callbacks map direcly onto dri_bufmgr operations:
*/
+
static void *intel_buffer_map(struct pipe_winsys *winsys,
struct pipe_buffer *buf,
unsigned flags )
@@ -86,19 +88,14 @@ static void intel_buffer_unmap(struct pipe_winsys *winsys,
driBOUnmap( dri_bo(buf) );
}
-
static void
intel_buffer_destroy(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
driBOUnReference( dri_bo(buf) );
+ FREE(buf);
}
-
-/* Pipe has no concept of pools. We choose the tex/region pool
- * for all buffers.
- * Grabs the hardware lock!
- */
static struct pipe_buffer *
intel_buffer_create(struct pipe_winsys *winsys,
unsigned alignment,
@@ -108,16 +105,23 @@ intel_buffer_create(struct pipe_winsys *winsys,
struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
unsigned flags = 0;
+ struct _DriBufferPool *pool;
buffer->base.refcount = 1;
buffer->base.alignment = alignment;
buffer->base.usage = usage;
buffer->base.size = size;
- if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) {
+ if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
+ pool = iws->mallocPool;
+ } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
+ /* For vertex buffers */
+ flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
+ pool = iws->vertexPool;
} else {
flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
+ pool = iws->regionPool;
}
if (usage & PIPE_BUFFER_USAGE_GPU_READ)
@@ -139,10 +143,11 @@ intel_buffer_create(struct pipe_winsys *winsys,
flags |= DRM_BO_FLAG_CACHED;
#endif
- driGenBuffers( iws->regionPool,
+ buffer->pool = pool;
+ driGenBuffers( buffer->pool,
"pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
- driBOData( buffer->driBO, size, NULL, 0 );
+ driBOData( buffer->driBO, size, NULL, buffer->pool, 0 );
return &buffer->base;
}
@@ -155,52 +160,27 @@ intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
driGenUserBuffer( iws->regionPool,
- "pipe user buffer", &buffer->driBO, ptr, bytes);
+ "pipe user buffer", &buffer->driBO, ptr, bytes );
+
+ buffer->base.refcount = 1;
return &buffer->base;
}
-/* The state tracker (should!) keep track of whether the fake
- * frontbuffer has been touched by any rendering since the last time
- * we copied its contents to the real frontbuffer. Our task is easy:
+/*
+ * Surface functions.
+ *
+ * Deprecated!
*/
-static void
-intel_flush_frontbuffer( struct pipe_winsys *winsys,
- struct pipe_surface *surf,
- void *context_private)
-{
- struct intel_context *intel = (struct intel_context *) context_private;
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
-
- intelDisplaySurface(dPriv, surf, NULL);
-}
-
static struct pipe_surface *
intel_i915_surface_alloc(struct pipe_winsys *winsys)
{
- struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
- if (surf) {
- surf->refcount = 1;
- surf->winsys = winsys;
- }
- return surf;
-}
-
-
-/**
- * Round n up to next multiple.
- */
-static INLINE unsigned
-round_up(unsigned n, unsigned multiple)
-{
- return (n + multiple - 1) & ~(multiple - 1);
+ assert("intel_i915_surface_alloc is deprecated" & 0);
+ return NULL;
}
-/**
- * Copied from xm_winsys.c
- */
static int
intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
struct pipe_surface *surf,
@@ -209,50 +189,77 @@ intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
unsigned flags,
unsigned tex_usage)
{
- const unsigned alignment = 64;
- int ret;
-
- surf->width = width;
- surf->height = height;
- surf->format = format;
- surf->cpp = pf_get_size(format);
- surf->pitch = round_up(width, alignment / surf->cpp);
-
- assert(!surf->buffer);
- surf->buffer = winsys->buffer_create(winsys, alignment,
- PIPE_BUFFER_USAGE_PIXEL,
- surf->pitch * surf->cpp * height);
- if(!surf->buffer)
- return -1;
-
- return 0;
+ assert("intel_i915_surface_alloc_storage is deprecated" & 0);
+ return -1;
}
-
static void
intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
{
- struct pipe_surface *surf = *s;
- surf->refcount--;
- if (surf->refcount == 0) {
- if (surf->buffer)
- pipe_buffer_reference(winsys, &surf->buffer, NULL);
- free(surf);
- }
- *s = NULL;
+ assert("intel_i915_surface_release is deprecated" & 0);
}
+/*
+ * Fence functions
+ */
+
+static void
+intel_fence_reference( struct pipe_winsys *sws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence )
+{
+ if (*ptr)
+ driFenceUnReference((struct _DriFenceObject **)ptr);
+
+ if (fence)
+ *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence);
+}
+
+static int
+intel_fence_signalled( struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ return driFenceSignaled((struct _DriFenceObject *)fence, flag);
+}
+
+static int
+intel_fence_finish( struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
+}
+/*
+ * Mixed functions
+ */
+
static const char *
intel_get_name( struct pipe_winsys *winsys )
{
return "Intel/DRI/ttm";
}
+/*
+ * The state tracker (should!) keep track of whether the fake
+ * frontbuffer has been touched by any rendering since the last time
+ * we copied its contents to the real frontbuffer. Our task is easy:
+ */
+static void
+intel_flush_frontbuffer( struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+ struct intel_context *intel = (struct intel_context *) context_private;
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+
+ intelDisplaySurface(dPriv, surf, NULL);
+}
struct pipe_winsys *
-intel_create_pipe_winsys( int fd )
+intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
{
struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys );
@@ -274,13 +281,29 @@ intel_create_pipe_winsys( int fd )
iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;
iws->winsys.surface_release = intel_i915_surface_release;
- if (fd)
- iws->regionPool = driDRMPoolInit(fd);
+ iws->winsys.fence_reference = intel_fence_reference;
+ iws->winsys.fence_signalled = intel_fence_signalled;
+ iws->winsys.fence_finish = intel_fence_finish;
+
+ if (fd) {
+ iws->regionPool = driDRMPoolInit(fd);
+ iws->vertexPool = driSlabPoolInit(fd,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT,
+ 128 * 4096,
+ 1, 120, 128 * 4096 * 4, 0,
+ fMan);
+ }
+
+ iws->mallocPool = driMallocPoolInit();
return &iws->winsys;
}
-
void
intel_destroy_pipe_winsys( struct pipe_winsys *winsys )
{
@@ -288,6 +311,8 @@ intel_destroy_pipe_winsys( struct pipe_winsys *winsys )
if (iws->regionPool) {
driPoolTakeDown(iws->regionPool);
}
+ if (iws->mallocPool) {
+ driPoolTakeDown(iws->mallocPool);
+ }
free(iws);
}
-
diff --git a/src/gallium/winsys/dri/intel/server/i830_common.h b/src/gallium/winsys/dri/intel/server/i830_common.h
index 50bb751709..f84f453309 100644
--- a/src/gallium/winsys/dri/intel/server/i830_common.h
+++ b/src/gallium/winsys/dri/intel/server/i830_common.h
@@ -53,6 +53,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DRM_I830_DESTROY_HEAP 0x0c
#define DRM_I830_SET_VBLANK_PIPE 0x0d
#define DRM_I830_GET_VBLANK_PIPE 0x0e
+#define DRM_I830_MMIO 0x10
typedef struct {
enum {
@@ -84,6 +85,7 @@ typedef struct {
int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
int ctxOwner; /* last context to upload state */
+ /** Last context that used the buffer manager. */
int texAge;
int pf_enabled; /* is pageflipping allowed? */
int pf_active;
@@ -120,20 +122,29 @@ typedef struct {
unsigned int rotated_tiled;
unsigned int rotated2_tiled;
- int pipeA_x;
- int pipeA_y;
- int pipeA_w;
- int pipeA_h;
- int pipeB_x;
- int pipeB_y;
- int pipeB_w;
- int pipeB_h;
+ int planeA_x;
+ int planeA_y;
+ int planeA_w;
+ int planeA_h;
+ int planeB_x;
+ int planeB_y;
+ int planeB_w;
+ int planeB_h;
/* Triple buffering */
drm_handle_t third_handle;
int third_offset;
int third_size;
unsigned int third_tiled;
+
+ /* buffer object handles for the static buffers. May change
+ * over the lifetime of the client, though it doesn't in our current
+ * implementation.
+ */
+ unsigned int front_bo_handle;
+ unsigned int back_bo_handle;
+ unsigned int third_bo_handle;
+ unsigned int depth_bo_handle;
} drmI830Sarea;
/* Flags for perf_boxes
@@ -222,4 +233,23 @@ typedef struct {
int pipe;
} drmI830VBlankPipe;
+#define MMIO_READ 0
+#define MMIO_WRITE 1
+
+#define MMIO_REGS_IA_PRIMATIVES_COUNT 0
+#define MMIO_REGS_IA_VERTICES_COUNT 1
+#define MMIO_REGS_VS_INVOCATION_COUNT 2
+#define MMIO_REGS_GS_PRIMITIVES_COUNT 3
+#define MMIO_REGS_GS_INVOCATION_COUNT 4
+#define MMIO_REGS_CL_PRIMITIVES_COUNT 5
+#define MMIO_REGS_CL_INVOCATION_COUNT 6
+#define MMIO_REGS_PS_INVOCATION_COUNT 7
+#define MMIO_REGS_PS_DEPTH_COUNT 8
+
+typedef struct {
+ unsigned int read_write:1;
+ unsigned int reg:31;
+ void __user *data;
+} drmI830MMIO;
+
#endif /* _I830_DRM_H_ */
diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c
new file mode 100644
index 0000000000..1bc1089352
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.c
@@ -0,0 +1,953 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include "glthread.h"
+#include "errno.h"
+#include "ws_dri_bufmgr.h"
+#include "string.h"
+#include "imports.h"
+#include "ws_dri_bufpool.h"
+#include "ws_dri_fencemgr.h"
+
+/*
+ * This lock is here to protect drmBO structs changing underneath us during a
+ * validate list call, since validatelist cannot take individiual locks for
+ * each drmBO. Validatelist takes this lock in write mode. Any access to an
+ * individual drmBO should take this lock in read mode, since in that case, the
+ * driBufferObject mutex will protect the access. Locking order is
+ * driBufferObject mutex - > this rw lock.
+ */
+
+_glthread_DECLARE_STATIC_MUTEX(bmMutex);
+_glthread_DECLARE_STATIC_COND(bmCond);
+
+static int kernelReaders = 0;
+static int num_buffers = 0;
+static int num_user_buffers = 0;
+
+static drmBO *drmBOListBuf(void *iterator)
+{
+ drmBONode *node;
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ node = DRMLISTENTRY(drmBONode, l, head);
+ return node->buf;
+}
+
+static void *drmBOListIterator(drmBOList *list)
+{
+ void *ret = list->list.next;
+
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+static void *drmBOListNext(drmBOList *list, void *iterator)
+{
+ void *ret;
+
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ ret = l->next;
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
+ uint64_t arg0,
+ uint64_t arg1)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->free.next;
+ if (l == &list->free) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ return NULL;
+ }
+ list->numCurrent++;
+ }
+ else {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ }
+ node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
+ DRMLISTADD(&node->head, &list->list);
+ list->numOnList++;
+ return node;
+}
+
+static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags,
+ uint64_t mask, int *newItem)
+{
+ drmBONode *node, *cur;
+ drmMMListHead *l;
+
+ *newItem = 0;
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ }
+ if (!cur) {
+ cur = drmAddListItem(list, buf, flags, mask);
+ if (!cur) {
+ return -ENOMEM;
+ }
+ *newItem = 1;
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ }
+ else {
+ uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
+ uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
+
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ return -EINVAL;
+ }
+
+ cur->arg1 |= mask;
+ cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
+
+ if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
+ (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void drmBOFreeList(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->list.next;
+ while(l != &list->list) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->list.next;
+ list->numCurrent--;
+ list->numOnList--;
+ }
+
+ l = list->free.next;
+ while(l != &list->free) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->free.next;
+ list->numCurrent--;
+ }
+}
+
+static int drmAdjustListNodes(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+ int ret = 0;
+
+ while(list->numCurrent < list->numTarget) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ ret = -ENOMEM;
+ break;
+ }
+ list->numCurrent++;
+ DRMLISTADD(&node->head, &list->free);
+ }
+
+ while(list->numCurrent > list->numTarget) {
+ l = list->free.next;
+ if (l == &list->free)
+ break;
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ list->numCurrent--;
+ }
+ return ret;
+}
+
+static int drmBOCreateList(int numTarget, drmBOList *list)
+{
+ DRMINITLISTHEAD(&list->list);
+ DRMINITLISTHEAD(&list->free);
+ list->numTarget = numTarget;
+ list->numCurrent = 0;
+ list->numOnList = 0;
+ return drmAdjustListNodes(list);
+}
+
+static int drmBOResetList(drmBOList *list)
+{
+ drmMMListHead *l;
+ int ret;
+
+ ret = drmAdjustListNodes(list);
+ if (ret)
+ return ret;
+
+ l = list->list.next;
+ while (l != &list->list) {
+ DRMLISTDEL(l);
+ DRMLISTADD(l, &list->free);
+ list->numOnList--;
+ l = list->list.next;
+ }
+ return drmAdjustListNodes(list);
+}
+
+void driWriteLockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ while(kernelReaders != 0)
+ _glthread_COND_WAIT(bmCond, bmMutex);
+}
+
+void driWriteUnlockKernelBO(void)
+{
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+void driReadLockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ kernelReaders++;
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+void driReadUnlockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ if (--kernelReaders == 0)
+ _glthread_COND_BROADCAST(bmCond);
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+
+
+
+/*
+ * TODO: Introduce fence pools in the same way as
+ * buffer object pools.
+ */
+
+typedef struct _DriBufferObject
+{
+ DriBufferPool *pool;
+ _glthread_Mutex mutex;
+ int refCount;
+ const char *name;
+ uint64_t flags;
+ unsigned hint;
+ unsigned alignment;
+ unsigned createdByReference;
+ void *private;
+ /* user-space buffer: */
+ unsigned userBuffer;
+ void *userData;
+ unsigned userSize;
+} DriBufferObject;
+
+typedef struct _DriBufferList {
+ drmBOList drmBuffers; /* List of kernel buffers needing validation */
+ drmBOList driBuffers; /* List of user-space buffers needing validation */
+} DriBufferList;
+
+
+void
+bmError(int val, const char *file, const char *function, int line)
+{
+ _mesa_printf("Fatal video memory manager error \"%s\".\n"
+ "Check kernel logs or set the LIBGL_DEBUG\n"
+ "environment variable to \"verbose\" for more info.\n"
+ "Detected in file %s, line %d, function %s.\n",
+ strerror(-val), file, line, function);
+#ifndef NDEBUG
+ abort();
+#else
+ abort();
+#endif
+}
+
+extern drmBO *
+driBOKernel(struct _DriBufferObject *buf)
+{
+ drmBO *ret;
+
+ driReadLockKernelBO();
+ _glthread_LOCK_MUTEX(buf->mutex);
+ assert(buf->private != NULL);
+ ret = buf->pool->kernel(buf->pool, buf->private);
+ if (!ret)
+ BM_CKFATAL(-EINVAL);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+void
+driBOWaitIdle(struct _DriBufferObject *buf, int lazy)
+{
+
+ /*
+ * This function may block. Is it sane to keep the mutex held during
+ * that time??
+ */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void *
+driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint)
+{
+ void *virtual;
+ int retval;
+
+ if (buf->userBuffer) {
+ return buf->userData;
+ }
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ assert(buf->private != NULL);
+ retval = buf->pool->map(buf->pool, buf->private, flags, hint,
+ &buf->mutex, &virtual);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return retval == 0 ? virtual : NULL;
+}
+
+void
+driBOUnmap(struct _DriBufferObject *buf)
+{
+ if (buf->userBuffer)
+ return;
+
+ assert(buf->private != NULL);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+unsigned long
+driBOOffset(struct _DriBufferObject *buf)
+{
+ unsigned long ret;
+
+ assert(buf->private != NULL);
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->offset(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return ret;
+}
+
+unsigned long
+driBOPoolOffset(struct _DriBufferObject *buf)
+{
+ unsigned long ret;
+
+ assert(buf->private != NULL);
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->poolOffset(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return ret;
+}
+
+uint64_t
+driBOFlags(struct _DriBufferObject *buf)
+{
+ uint64_t ret;
+
+ assert(buf->private != NULL);
+
+ driReadLockKernelBO();
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->flags(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+struct _DriBufferObject *
+driBOReference(struct _DriBufferObject *buf)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (++buf->refCount == 1) {
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(-EINVAL);
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return buf;
+}
+
+void
+driBOUnReference(struct _DriBufferObject *buf)
+{
+ int tmp;
+
+ if (!buf)
+ return;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ tmp = --buf->refCount;
+ if (!tmp) {
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ if (buf->private) {
+ if (buf->createdByReference)
+ buf->pool->unreference(buf->pool, buf->private);
+ else
+ buf->pool->destroy(buf->pool, buf->private);
+ }
+ if (buf->userBuffer)
+ num_user_buffers--;
+ else
+ num_buffers--;
+ free(buf);
+ } else
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+}
+
+
+int
+driBOData(struct _DriBufferObject *buf,
+ unsigned size, const void *data,
+ DriBufferPool *newPool,
+ uint64_t flags)
+{
+ void *virtual = NULL;
+ int newBuffer;
+ int retval = 0;
+ struct _DriBufferPool *pool;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ pool = buf->pool;
+
+ if (pool == NULL && newPool != NULL) {
+ buf->pool = newPool;
+ pool = newPool;
+ }
+ if (newPool == NULL)
+ newPool = pool;
+
+ if (!pool->create) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "driBOData called on invalid buffer\n");
+ BM_CKFATAL(-EINVAL);
+ }
+
+ newBuffer = (!buf->private || pool != newPool ||
+ pool->size(pool, buf->private) < size);
+
+ if (!flags)
+ flags = buf->flags;
+
+ if (newBuffer) {
+
+ if (buf->createdByReference) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "driBOData requiring resizing called on "
+ "shared buffer.\n");
+ BM_CKFATAL(-EINVAL);
+ }
+
+ if (buf->private)
+ buf->pool->destroy(buf->pool, buf->private);
+
+ pool = newPool;
+ buf->pool = newPool;
+ buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
+ buf->alignment);
+ if (!buf->private)
+ retval = -ENOMEM;
+
+ if (retval == 0)
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE,
+ DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual);
+ } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE,
+ DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) {
+ /*
+ * Buffer is busy. need to create a new one.
+ */
+
+ void *newBuf;
+
+ newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
+ buf->alignment);
+ if (newBuf) {
+ buf->pool->destroy(buf->pool, buf->private);
+ buf->private = newBuf;
+ }
+
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
+ } else {
+ uint64_t flag_diff = flags ^ buf->flags;
+
+ /*
+ * We might need to change buffer flags.
+ */
+
+ if (flag_diff){
+ assert(pool->setStatus != NULL);
+ BM_CKFATAL(pool->unmap(pool, buf->private));
+ BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff,
+ buf->flags));
+ if (!data)
+ goto out;
+
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
+ }
+ }
+
+ if (retval == 0) {
+ if (data)
+ memcpy(virtual, data, size);
+
+ BM_CKFATAL(pool->unmap(pool, buf->private));
+ }
+
+ out:
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return retval;
+}
+
+void
+driBOSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size, const void *data)
+{
+ void *virtual;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (size && data) {
+ BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex,
+ &virtual));
+ memcpy((unsigned char *) virtual + offset, data, size);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void
+driBOGetSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size, void *data)
+{
+ void *virtual;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (size && data) {
+ BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
+ DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual));
+ memcpy(data, (unsigned char *) virtual + offset, size);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void
+driBOSetReferenced(struct _DriBufferObject *buf,
+ unsigned long handle)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->private != NULL) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "Invalid buffer for setReferenced\n");
+ BM_CKFATAL(-EINVAL);
+
+ }
+ if (buf->pool->reference == NULL) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "Invalid buffer pool for setReferenced\n");
+ BM_CKFATAL(-EINVAL);
+ }
+ buf->private = buf->pool->reference(buf->pool, handle);
+ if (!buf->private) {
+ _mesa_error(NULL, GL_OUT_OF_MEMORY,
+ "Invalid buffer pool for setStatic\n");
+ BM_CKFATAL(-ENOMEM);
+ }
+ buf->createdByReference = GL_TRUE;
+ buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags;
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+int
+driGenBuffers(struct _DriBufferPool *pool,
+ const char *name,
+ unsigned n,
+ struct _DriBufferObject *buffers[],
+ unsigned alignment, uint64_t flags, unsigned hint)
+{
+ struct _DriBufferObject *buf;
+ int i;
+
+ flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
+
+ ++num_buffers;
+
+ assert(pool);
+
+ for (i = 0; i < n; ++i) {
+ buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf));
+ if (!buf)
+ return -ENOMEM;
+
+ _glthread_INIT_MUTEX(buf->mutex);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ buf->refCount = 1;
+ buf->flags = flags;
+ buf->hint = hint;
+ buf->name = name;
+ buf->alignment = alignment;
+ buf->pool = pool;
+ buf->createdByReference = 0;
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ buffers[i] = buf;
+ }
+ return 0;
+}
+
+void
+driGenUserBuffer(struct _DriBufferPool *pool,
+ const char *name,
+ struct _DriBufferObject **buffers,
+ void *ptr, unsigned bytes)
+{
+ const unsigned alignment = 1, flags = 0, hint = 0;
+
+ --num_buffers; /* JB: is inced in GenBuffes */
+ driGenBuffers(pool, name, 1, buffers, alignment, flags, hint);
+ ++num_user_buffers;
+
+ (*buffers)->userBuffer = 1;
+ (*buffers)->userData = ptr;
+ (*buffers)->userSize = bytes;
+}
+
+void
+driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[])
+{
+ int i;
+
+ for (i = 0; i < n; ++i) {
+ driBOUnReference(buffers[i]);
+ }
+}
+
+
+void
+driInitBufMgr(int fd)
+{
+ ;
+}
+
+/*
+ * Note that lists are per-context and don't need mutex protection.
+ */
+
+struct _DriBufferList *
+driBOCreateList(int target)
+{
+ struct _DriBufferList *list = calloc(sizeof(*list), 1);
+
+ BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers));
+ BM_CKFATAL(drmBOCreateList(target, &list->driBuffers));
+ return list;
+}
+
+int
+driBOResetList(struct _DriBufferList * list)
+{
+ int ret;
+ ret = drmBOResetList(&list->drmBuffers);
+ if (ret)
+ return ret;
+ ret = drmBOResetList(&list->driBuffers);
+ return ret;
+}
+
+void
+driBOFreeList(struct _DriBufferList * list)
+{
+ drmBOFreeList(&list->drmBuffers);
+ drmBOFreeList(&list->driBuffers);
+ free(list);
+}
+
+
+/*
+ * Copied from libdrm, because it is needed by driAddValidateItem.
+ */
+
+static drmBONode *
+driAddListItem(drmBOList * list, drmBO * item,
+ uint64_t arg0, uint64_t arg1)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->free.next;
+ if (l == &list->free) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ return NULL;
+ }
+ list->numCurrent++;
+ } else {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ }
+ memset(&node->bo_arg, 0, sizeof(node->bo_arg));
+ node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
+ DRMLISTADDTAIL(&node->head, &list->list);
+ list->numOnList++;
+ return node;
+}
+
+/*
+ * Slightly modified version compared to the libdrm version.
+ * This one returns the list index of the buffer put on the list.
+ */
+
+static int
+driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags,
+ uint64_t mask, int *itemLoc,
+ struct _drmBONode **pnode)
+{
+ drmBONode *node, *cur;
+ drmMMListHead *l;
+ int count = 0;
+
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ count++;
+ }
+ if (!cur) {
+ cur = driAddListItem(list, buf, flags, mask);
+ if (!cur)
+ return -ENOMEM;
+
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ } else {
+ uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
+ uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
+
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ return -EINVAL;
+ }
+
+ cur->arg1 |= mask;
+ cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
+
+ if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
+ (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
+ return -EINVAL;
+ }
+ }
+ *itemLoc = count;
+ *pnode = cur;
+ return 0;
+}
+
+
+void
+driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf,
+ uint64_t flags, uint64_t mask, int *itemLoc,
+ struct _drmBONode **node)
+{
+ int newItem;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(driAddValidateItem(&list->drmBuffers,
+ buf->pool->kernel(buf->pool, buf->private),
+ flags, mask, itemLoc, node));
+ BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf,
+ flags, mask, &newItem));
+ if (newItem)
+ buf->refCount++;
+
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+drmBOList *driGetdrmBOList(struct _DriBufferList *list)
+{
+ driWriteLockKernelBO();
+ return &list->drmBuffers;
+}
+
+void driPutdrmBOList(struct _DriBufferList *list)
+{
+ driWriteUnlockKernelBO();
+}
+
+
+void
+driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->pool->fence)
+ BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+}
+
+void
+driBOUnrefUserList(struct _DriBufferList *list)
+{
+ struct _DriBufferObject *buf;
+ void *curBuf;
+
+ curBuf = drmBOListIterator(&list->driBuffers);
+ while (curBuf) {
+ buf = (struct _DriBufferObject *)drmBOListBuf(curBuf);
+ driBOUnReference(buf);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+}
+
+struct _DriFenceObject *
+driBOFenceUserList(struct _DriFenceMgr *mgr,
+ struct _DriBufferList *list, const char *name,
+ drmFence *kFence)
+{
+ struct _DriFenceObject *fence;
+ struct _DriBufferObject *buf;
+ void *curBuf;
+
+ fence = driFenceCreate(mgr, kFence->fence_class, kFence->type,
+ kFence, sizeof(*kFence));
+ curBuf = drmBOListIterator(&list->driBuffers);
+
+ /*
+ * User-space fencing callbacks.
+ */
+
+ while (curBuf) {
+ buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
+ driBOFence(buf, fence);
+ driBOUnReference(buf);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+
+ driBOResetList(list);
+ return fence;
+}
+
+void
+driBOValidateUserList(struct _DriBufferList * list)
+{
+ void *curBuf;
+ struct _DriBufferObject *buf;
+
+ curBuf = drmBOListIterator(&list->driBuffers);
+
+ /*
+ * User-space validation callbacks.
+ */
+
+ while (curBuf) {
+ buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->pool->validate)
+ BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+}
+
+
+void
+driPoolTakeDown(struct _DriBufferPool *pool)
+{
+ pool->takeDown(pool);
+
+}
+
+unsigned long
+driBOSize(struct _DriBufferObject *buf)
+{
+ unsigned long size;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ size = buf->pool->size(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return size;
+
+}
+
+drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list)
+{
+ return &list->drmBuffers;
+}
+
+drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list)
+{
+ return &list->driBuffers;
+}
+
diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h
new file mode 100644
index 0000000000..fdaf5ee93a
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_bufmgr.h
@@ -0,0 +1,138 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _PSB_BUFMGR_H_
+#define _PSB_BUFMGR_H_
+#include <xf86mm.h>
+#include "i915_drm.h"
+#include "ws_dri_fencemgr.h"
+
+typedef struct _drmBONode
+{
+ drmMMListHead head;
+ drmBO *buf;
+ struct drm_i915_op_arg bo_arg;
+ uint64_t arg0;
+ uint64_t arg1;
+} drmBONode;
+
+typedef struct _drmBOList {
+ unsigned numTarget;
+ unsigned numCurrent;
+ unsigned numOnList;
+ drmMMListHead list;
+ drmMMListHead free;
+} drmBOList;
+
+
+struct _DriFenceObject;
+struct _DriBufferObject;
+struct _DriBufferPool;
+struct _DriBufferList;
+
+/*
+ * Return a pointer to the libdrm buffer object this DriBufferObject
+ * uses.
+ */
+
+extern drmBO *driBOKernel(struct _DriBufferObject *buf);
+extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags,
+ unsigned hint);
+extern void driBOUnmap(struct _DriBufferObject *buf);
+extern unsigned long driBOOffset(struct _DriBufferObject *buf);
+extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf);
+
+extern uint64_t driBOFlags(struct _DriBufferObject *buf);
+extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf);
+extern void driBOUnReference(struct _DriBufferObject *buf);
+
+extern int driBOData(struct _DriBufferObject *r_buf,
+ unsigned size, const void *data,
+ struct _DriBufferPool *pool, uint64_t flags);
+
+extern void driBOSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size,
+ const void *data);
+extern void driBOGetSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size,
+ void *data);
+extern int driGenBuffers(struct _DriBufferPool *pool,
+ const char *name,
+ unsigned n,
+ struct _DriBufferObject *buffers[],
+ unsigned alignment, uint64_t flags, unsigned hint);
+extern void driGenUserBuffer(struct _DriBufferPool *pool,
+ const char *name,
+ struct _DriBufferObject *buffers[],
+ void *ptr, unsigned bytes);
+extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]);
+extern void driInitBufMgr(int fd);
+extern struct _DriBufferList *driBOCreateList(int target);
+extern int driBOResetList(struct _DriBufferList * list);
+extern void driBOAddListItem(struct _DriBufferList * list,
+ struct _DriBufferObject *buf,
+ uint64_t flags, uint64_t mask, int *itemLoc,
+ struct _drmBONode **node);
+
+extern void driBOValidateList(int fd, struct _DriBufferList * list);
+extern void driBOFreeList(struct _DriBufferList * list);
+extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr,
+ struct _DriBufferList *list,
+ const char *name,
+ drmFence *kFence);
+extern void driBOUnrefUserList(struct _DriBufferList *list);
+extern void driBOValidateUserList(struct _DriBufferList * list);
+extern drmBOList *driGetdrmBOList(struct _DriBufferList *list);
+extern void driPutdrmBOList(struct _DriBufferList *list);
+
+extern void driBOFence(struct _DriBufferObject *buf,
+ struct _DriFenceObject *fence);
+
+extern void driPoolTakeDown(struct _DriBufferPool *pool);
+extern void driBOSetReferenced(struct _DriBufferObject *buf,
+ unsigned long handle);
+unsigned long driBOSize(struct _DriBufferObject *buf);
+extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy);
+extern void driPoolTakeDown(struct _DriBufferPool *pool);
+
+extern void driReadLockKernelBO(void);
+extern void driReadUnlockKernelBO(void);
+extern void driWriteLockKernelBO(void);
+extern void driWriteUnlockKernelBO(void);
+
+/*
+ * For debugging purposes.
+ */
+
+extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list);
+extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list);
+#endif
diff --git a/src/gallium/winsys/dri/intel/ws_dri_bufpool.h b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h
new file mode 100644
index 0000000000..3a302e13d3
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_bufpool.h
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _PSB_BUFPOOL_H_
+#define _PSB_BUFPOOL_H_
+
+#include <xf86drm.h>
+#include <glthread.h>
+struct _DriFenceObject;
+
+typedef struct _DriBufferPool
+{
+ int fd;
+ int (*map) (struct _DriBufferPool * pool, void *private,
+ unsigned flags, int hint, _glthread_Mutex *mutex,
+ void **virtual);
+ int (*unmap) (struct _DriBufferPool * pool, void *private);
+ int (*destroy) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*offset) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private);
+ uint64_t (*flags) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*size) (struct _DriBufferPool * pool, void *private);
+ void *(*create) (struct _DriBufferPool * pool, unsigned long size,
+ uint64_t flags, unsigned hint, unsigned alignment);
+ void *(*reference) (struct _DriBufferPool * pool, unsigned handle);
+ int (*unreference) (struct _DriBufferPool * pool, void *private);
+ int (*fence) (struct _DriBufferPool * pool, void *private,
+ struct _DriFenceObject * fence);
+ drmBO *(*kernel) (struct _DriBufferPool * pool, void *private);
+ int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex);
+ int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex,
+ int lazy);
+ int (*setStatus) (struct _DriBufferPool *pool, void *private,
+ uint64_t flag_diff, uint64_t old_flags);
+ void (*takeDown) (struct _DriBufferPool * pool);
+ void *data;
+} DriBufferPool;
+
+extern void bmError(int val, const char *file, const char *function,
+ int line);
+#define BM_CKFATAL(val) \
+ do{ \
+ int tstVal = (val); \
+ if (tstVal) \
+ bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \
+ } while(0);
+
+
+/*
+ * Builtin pools.
+ */
+
+/*
+ * Kernel buffer objects. Size in multiples of page size. Page size aligned.
+ */
+
+extern struct _DriBufferPool *driDRMPoolInit(int fd);
+extern struct _DriBufferPool *driMallocPoolInit(void);
+
+struct _DriFreeSlabManager;
+extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags,
+ uint64_t validMask,
+ uint32_t smallestSize,
+ uint32_t numSizes,
+ uint32_t desiredNumBuffers,
+ uint32_t maxSlabSize,
+ uint32_t pageAlignment,
+ struct _DriFreeSlabManager *fMan);
+extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan);
+extern struct _DriFreeSlabManager *
+driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec);
+
+
+#endif
diff --git a/src/gallium/winsys/dri/intel/ws_dri_drmpool.c b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c
new file mode 100644
index 0000000000..7c55dbc674
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_drmpool.c
@@ -0,0 +1,268 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
+#include "assert.h"
+
+/*
+ * Buffer pool implementation using DRM buffer objects as DRI buffer objects.
+ */
+
+static void *
+pool_create(struct _DriBufferPool *pool,
+ unsigned long size, uint64_t flags, unsigned hint,
+ unsigned alignment)
+{
+ drmBO *buf = (drmBO *) malloc(sizeof(*buf));
+ int ret;
+ unsigned pageSize = getpagesize();
+
+ if (!buf)
+ return NULL;
+
+ if ((alignment > pageSize) && (alignment % pageSize)) {
+ free(buf);
+ return NULL;
+ }
+
+ ret = drmBOCreate(pool->fd, size, alignment / pageSize,
+ NULL,
+ flags, hint, buf);
+ if (ret) {
+ free(buf);
+ return NULL;
+ }
+
+ return (void *) buf;
+}
+
+static void *
+pool_reference(struct _DriBufferPool *pool, unsigned handle)
+{
+ drmBO *buf = (drmBO *) malloc(sizeof(*buf));
+ int ret;
+
+ if (!buf)
+ return NULL;
+
+ ret = drmBOReference(pool->fd, handle, buf);
+
+ if (ret) {
+ free(buf);
+ return NULL;
+ }
+
+ return (void *) buf;
+}
+
+static int
+pool_destroy(struct _DriBufferPool *pool, void *private)
+{
+ int ret;
+ drmBO *buf = (drmBO *) private;
+ driReadLockKernelBO();
+ ret = drmBOUnreference(pool->fd, buf);
+ free(buf);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_unreference(struct _DriBufferPool *pool, void *private)
+{
+ int ret;
+ drmBO *buf = (drmBO *) private;
+ driReadLockKernelBO();
+ ret = drmBOUnreference(pool->fd, buf);
+ free(buf);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOMap(pool->fd, buf, flags, hint, virtual);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOUnmap(pool->fd, buf);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ unsigned long offset;
+
+ driReadLockKernelBO();
+ assert(buf->flags & DRM_BO_FLAG_NO_MOVE);
+ offset = buf->offset;
+ driReadUnlockKernelBO();
+
+ return buf->offset;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ return 0;
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ uint64_t flags;
+
+ driReadLockKernelBO();
+ flags = buf->flags;
+ driReadUnlockKernelBO();
+
+ return flags;
+}
+
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ unsigned long size;
+
+ driReadLockKernelBO();
+ size = buf->size;
+ driReadUnlockKernelBO();
+
+ return buf->size;
+}
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ /*
+ * Noop. The kernel handles all fencing.
+ */
+
+ return 0;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ return (drmBO *) private;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex,
+ int lazy)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+
+static void
+pool_takedown(struct _DriBufferPool *pool)
+{
+ free(pool);
+}
+
+/*static int
+pool_setStatus(struct _DriBufferPool *pool, void *private,
+ uint64_t flag_diff, uint64_t old_flags)
+{
+ drmBO *buf = (drmBO *) private;
+ uint64_t new_flags = old_flags ^ flag_diff;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff,
+ 0, 0, 0);
+ driReadUnlockKernelBO();
+ return ret;
+}*/
+
+struct _DriBufferPool *
+driDRMPoolInit(int fd)
+{
+ struct _DriBufferPool *pool;
+
+ pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
+
+ if (!pool)
+ return NULL;
+
+ pool->fd = fd;
+ pool->map = &pool_map;
+ pool->unmap = &pool_unmap;
+ pool->destroy = &pool_destroy;
+ pool->offset = &pool_offset;
+ pool->poolOffset = &pool_poolOffset;
+ pool->flags = &pool_flags;
+ pool->size = &pool_size;
+ pool->create = &pool_create;
+ pool->fence = &pool_fence;
+ pool->kernel = &pool_kernel;
+ pool->validate = NULL;
+ pool->waitIdle = &pool_waitIdle;
+ pool->takeDown = &pool_takedown;
+ pool->reference = &pool_reference;
+ pool->unreference = &pool_unreference;
+ pool->data = NULL;
+ return pool;
+}
diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c
new file mode 100644
index 0000000000..1f893b47ce
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.c
@@ -0,0 +1,377 @@
+#include "ws_dri_fencemgr.h"
+#include "glthread.h"
+#include <xf86mm.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Note: Locking order is
+ * _DriFenceObject::mutex
+ * _DriFenceMgr::mutex
+ */
+
+struct _DriFenceMgr {
+ /*
+ * Constant members. Need no mutex protection.
+ */
+ struct _DriFenceMgrCreateInfo info;
+ void *private;
+
+ /*
+ * These members are protected by this->mutex
+ */
+ _glthread_Mutex mutex;
+ int refCount;
+ drmMMListHead *heads;
+ int num_fences;
+};
+
+struct _DriFenceObject {
+
+ /*
+ * These members are constant and need no mutex protection.
+ */
+ struct _DriFenceMgr *mgr;
+ uint32_t fence_class;
+ uint32_t fence_type;
+
+ /*
+ * These members are protected by mgr->mutex.
+ */
+ drmMMListHead head;
+ int refCount;
+
+ /*
+ * These members are protected by this->mutex.
+ */
+ _glthread_Mutex mutex;
+ uint32_t signaled_type;
+ void *private;
+};
+
+uint32_t
+driFenceType(struct _DriFenceObject *fence)
+{
+ return fence->fence_type;
+}
+
+struct _DriFenceMgr *
+driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info)
+{
+ struct _DriFenceMgr *tmp;
+ uint32_t i;
+
+ tmp = calloc(1, sizeof(*tmp));
+ if (!tmp)
+ return NULL;
+
+ _glthread_INIT_MUTEX(tmp->mutex);
+ _glthread_LOCK_MUTEX(tmp->mutex);
+ tmp->refCount = 1;
+ tmp->info = *info;
+ tmp->num_fences = 0;
+ tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads));
+ if (!tmp->heads)
+ goto out_err;
+
+ for (i=0; i<tmp->info.num_classes; ++i) {
+ DRMINITLISTHEAD(&tmp->heads[i]);
+ }
+ _glthread_UNLOCK_MUTEX(tmp->mutex);
+ return tmp;
+
+ out_err:
+ if (tmp)
+ free(tmp);
+ return NULL;
+}
+
+static void
+driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr)
+{
+ struct _DriFenceMgr *mgr = *pMgr;
+
+ *pMgr = NULL;
+ if (--mgr->refCount == 0)
+ free(mgr);
+ else
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+}
+
+void
+driFenceMgrUnReference(struct _DriFenceMgr **pMgr)
+{
+ _glthread_LOCK_MUTEX((*pMgr)->mutex);
+ driFenceMgrUnrefUnlock(pMgr);
+}
+
+static void
+driFenceUnReferenceLocked(struct _DriFenceObject **pFence)
+{
+ struct _DriFenceObject *fence = *pFence;
+ struct _DriFenceMgr *mgr = fence->mgr;
+
+ *pFence = NULL;
+ if (--fence->refCount == 0) {
+ DRMLISTDELINIT(&fence->head);
+ if (fence->private)
+ mgr->info.unreference(mgr, &fence->private);
+ --mgr->num_fences;
+ fence->mgr = NULL;
+ --mgr->refCount;
+ free(fence);
+
+ }
+}
+
+
+static void
+driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr,
+ drmMMListHead *list,
+ uint32_t fence_class,
+ uint32_t fence_type)
+{
+ struct _DriFenceObject *entry;
+ drmMMListHead *prev;
+
+ while(list != &mgr->heads[fence_class]) {
+ entry = DRMLISTENTRY(struct _DriFenceObject, list, head);
+
+ /*
+ * Up refcount so that entry doesn't disappear from under us
+ * when we unlock-relock mgr to get the correct locking order.
+ */
+
+ ++entry->refCount;
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ _glthread_LOCK_MUTEX(entry->mutex);
+ _glthread_LOCK_MUTEX(mgr->mutex);
+
+ prev = list->prev;
+
+
+
+ if (list->prev == list) {
+
+ /*
+ * Somebody else removed the entry from the list.
+ */
+
+ _glthread_UNLOCK_MUTEX(entry->mutex);
+ driFenceUnReferenceLocked(&entry);
+ return;
+ }
+
+ entry->signaled_type |= (fence_type & entry->fence_type);
+ if (entry->signaled_type == entry->fence_type) {
+ DRMLISTDELINIT(list);
+ mgr->info.unreference(mgr, &entry->private);
+ }
+ _glthread_UNLOCK_MUTEX(entry->mutex);
+ driFenceUnReferenceLocked(&entry);
+ list = prev;
+ }
+}
+
+
+int
+driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type,
+ int lazy_hint)
+{
+ struct _DriFenceMgr *mgr = fence->mgr;
+ int ret = 0;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+
+ if ((fence->signaled_type & fence_type) == fence_type)
+ goto out0;
+
+ ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint);
+ if (ret)
+ goto out0;
+
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class,
+ fence_type);
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ return 0;
+
+ out0:
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return ret;
+}
+
+uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence)
+{
+ uint32_t ret;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+ ret = fence->signaled_type;
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ return ret;
+}
+
+int
+driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type,
+ uint32_t *signaled)
+{
+ int ret = 0;
+ struct _DriFenceMgr *mgr;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+ mgr = fence->mgr;
+ *signaled = fence->signaled_type;
+ if ((fence->signaled_type & flush_type) == flush_type)
+ goto out0;
+
+ ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled);
+ if (ret) {
+ *signaled = fence->signaled_type;
+ goto out0;
+ }
+
+ if ((fence->signaled_type | *signaled) == fence->signaled_type)
+ goto out0;
+
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class,
+ *signaled);
+
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ return 0;
+ out0:
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return ret;
+}
+
+struct _DriFenceObject *
+driFenceReference(struct _DriFenceObject *fence)
+{
+ _glthread_LOCK_MUTEX(fence->mgr->mutex);
+ ++fence->refCount;
+ _glthread_UNLOCK_MUTEX(fence->mgr->mutex);
+ return fence;
+}
+
+void
+driFenceUnReference(struct _DriFenceObject **pFence)
+{
+ struct _DriFenceMgr *mgr;
+
+ if (*pFence == NULL)
+ return;
+
+ mgr = (*pFence)->mgr;
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ ++mgr->refCount;
+ driFenceUnReferenceLocked(pFence);
+ driFenceMgrUnrefUnlock(&mgr);
+}
+
+struct _DriFenceObject
+*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class,
+ uint32_t fence_type, void *private, size_t private_size)
+{
+ struct _DriFenceObject *fence;
+ size_t fence_size = sizeof(*fence);
+
+ if (private_size)
+ fence_size = ((fence_size + 15) & ~15);
+
+ fence = calloc(1, fence_size + private_size);
+
+ if (!fence) {
+ int ret = mgr->info.finish(mgr, private, fence_type, 0);
+
+ if (ret)
+ usleep(10000000);
+
+ return NULL;
+ }
+
+ _glthread_INIT_MUTEX(fence->mutex);
+ _glthread_LOCK_MUTEX(fence->mutex);
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ fence->refCount = 1;
+ DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]);
+ fence->mgr = mgr;
+ ++mgr->refCount;
+ ++mgr->num_fences;
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ fence->fence_class = fence_class;
+ fence->fence_type = fence_type;
+ fence->signaled_type = 0;
+ fence->private = private;
+ if (private_size) {
+ fence->private = (void *)(((uint8_t *) fence) + fence_size);
+ memcpy(fence->private, private, private_size);
+ }
+
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return fence;
+}
+
+
+static int
+tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type,
+ uint32_t *signaled_type)
+{
+ long fd = (long) mgr->private;
+ int dummy;
+ drmFence *fence = (drmFence *) private;
+ int ret;
+
+ *signaled_type = 0;
+ ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy);
+ if (ret)
+ return ret;
+
+ *signaled_type = fence->signaled;
+
+ return 0;
+}
+
+static int
+tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type,
+ int lazy_hint)
+{
+ long fd = (long) mgr->private;
+ unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0;
+
+ return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type);
+}
+
+static int
+tUnref(struct _DriFenceMgr *mgr, void **private)
+{
+ long fd = (long) mgr->private;
+ drmFence *fence = (drmFence *) *private;
+ *private = NULL;
+
+ return drmFenceUnreference(fd, fence);
+}
+
+struct _DriFenceMgr *driFenceMgrTTMInit(int fd)
+{
+ struct _DriFenceMgrCreateInfo info;
+ struct _DriFenceMgr *mgr;
+
+ info.flags = DRI_FENCE_CLASS_ORDERED;
+ info.num_classes = 4;
+ info.signaled = tSignaled;
+ info.finish = tFinish;
+ info.unreference = tUnref;
+
+ mgr = driFenceMgrCreate(&info);
+ if (mgr == NULL)
+ return NULL;
+
+ mgr->private = (void *) (long) fd;
+ return mgr;
+}
+
diff --git a/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h
new file mode 100644
index 0000000000..4ea58dfe18
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_fencemgr.h
@@ -0,0 +1,115 @@
+#ifndef DRI_FENCEMGR_H
+#define DRI_FENCEMGR_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+struct _DriFenceObject;
+struct _DriFenceMgr;
+
+/*
+ * Do a quick check to see if the fence manager has registered the fence
+ * object as signaled. Note that this function may return a false negative
+ * answer.
+ */
+extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence);
+
+/*
+ * Check if the fence object is signaled. This function can be substantially
+ * more expensive to call than the above function, but will not return a false
+ * negative answer. The argument "flush_type" sets the types that the
+ * underlying mechanism must make sure will eventually signal.
+ */
+extern int driFenceSignaledType(struct _DriFenceObject *fence,
+ uint32_t flush_type, uint32_t *signaled);
+
+/*
+ * Convenience functions.
+ */
+
+static inline int driFenceSignaled(struct _DriFenceObject *fence,
+ uint32_t flush_type)
+{
+ uint32_t signaled_types;
+ int ret = driFenceSignaledType(fence, flush_type, &signaled_types);
+ if (ret)
+ return 0;
+ return ((signaled_types & flush_type) == flush_type);
+}
+
+static inline int driFenceSignaledCached(struct _DriFenceObject *fence,
+ uint32_t flush_type)
+{
+ uint32_t signaled_types =
+ driFenceSignaledTypeCached(fence);
+
+ return ((signaled_types & flush_type) == flush_type);
+}
+
+/*
+ * Reference a fence object.
+ */
+extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence);
+
+/*
+ * Unreference a fence object. The fence object pointer will be reset to NULL.
+ */
+
+extern void driFenceUnReference(struct _DriFenceObject **pFence);
+
+
+/*
+ * Wait for a fence to signal the indicated fence_type.
+ * If "lazy_hint" is true, it indicates that the wait may sleep to avoid
+ * busy-wait polling.
+ */
+extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type,
+ int lazy_hint);
+
+/*
+ * Create a DriFenceObject for manager "mgr".
+ *
+ * "private" is a pointer that should be used for the callbacks in
+ * struct _DriFenceMgrCreateInfo.
+ *
+ * if private_size is nonzero, then the info stored at *private, with size
+ * private size will be copied and the fence manager will instead use a
+ * pointer to the copied data for the callbacks in
+ * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by
+ * "private" may be destroyed after the call to driFenceCreate.
+ */
+extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr,
+ uint32_t fence_class,
+ uint32_t fence_type,
+ void *private,
+ size_t private_size);
+
+extern uint32_t driFenceType(struct _DriFenceObject *fence);
+
+/*
+ * Fence creations are ordered. If a fence signals a fence_type,
+ * it is safe to assume that all fences of the same class that was
+ * created before that fence has signaled the same type.
+ */
+
+#define DRI_FENCE_CLASS_ORDERED (1 << 0)
+
+struct _DriFenceMgrCreateInfo {
+ uint32_t flags;
+ uint32_t num_classes;
+ int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type,
+ uint32_t *signaled_type);
+ int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint);
+ int (*unreference) (struct _DriFenceMgr *mgr, void **private);
+};
+
+extern struct _DriFenceMgr *
+driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info);
+
+void
+driFenceMgrUnReference(struct _DriFenceMgr **pMgr);
+
+extern struct _DriFenceMgr *
+driFenceMgrTTMInit(int fd);
+
+#endif
diff --git a/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c
new file mode 100644
index 0000000000..bf97d7e440
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_mallocpool.c
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "imports.h"
+#include "glthread.h"
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
+#include "intel_screen.h"
+
+static void *
+pool_create(struct _DriBufferPool *pool,
+ unsigned long size, uint64_t flags, unsigned hint,
+ unsigned alignment)
+{
+ unsigned long *private = malloc(size + 2*sizeof(unsigned long));
+ if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL)
+ abort();
+
+ *private = size;
+ return (void *)private;
+}
+
+
+static int
+pool_destroy(struct _DriBufferPool *pool, void *private)
+{
+ free(private);
+ return 0;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *pool, void *private,
+ _glthread_Mutex *mutex, int lazy)
+{
+ return 0;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ *virtual = (void *)((unsigned long *)private + 2);
+ return 0;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ return 0;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ /*
+ * BUG
+ */
+ abort();
+ return 0UL;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ /*
+ * BUG
+ */
+ abort();
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
+}
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ return *(unsigned long *) private;
+}
+
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ abort();
+ return 0UL;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ abort();
+ return NULL;
+}
+
+static void
+pool_takedown(struct _DriBufferPool *pool)
+{
+ free(pool);
+}
+
+
+struct _DriBufferPool *
+driMallocPoolInit(void)
+{
+ struct _DriBufferPool *pool;
+
+ pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
+ if (!pool)
+ return NULL;
+
+ pool->data = NULL;
+ pool->fd = -1;
+ pool->map = &pool_map;
+ pool->unmap = &pool_unmap;
+ pool->destroy = &pool_destroy;
+ pool->offset = &pool_offset;
+ pool->poolOffset = &pool_poolOffset;
+ pool->flags = &pool_flags;
+ pool->size = &pool_size;
+ pool->create = &pool_create;
+ pool->fence = &pool_fence;
+ pool->kernel = &pool_kernel;
+ pool->validate = NULL;
+ pool->waitIdle = &pool_waitIdle;
+ pool->takeDown = &pool_takedown;
+ return pool;
+}
diff --git a/src/gallium/winsys/dri/intel/ws_dri_slabpool.c b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c
new file mode 100644
index 0000000000..62d82bbd94
--- /dev/null
+++ b/src/gallium/winsys/dri/intel/ws_dri_slabpool.c
@@ -0,0 +1,968 @@
+/**************************************************************************
+ *
+ * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include "ws_dri_bufpool.h"
+#include "ws_dri_fencemgr.h"
+#include "ws_dri_bufmgr.h"
+#include "glthread.h"
+
+#define DRI_SLABPOOL_ALLOC_RETRIES 100
+
+struct _DriSlab;
+
+struct _DriSlabBuffer {
+ int isSlabBuffer;
+ drmBO *bo;
+ struct _DriFenceObject *fence;
+ struct _DriSlab *parent;
+ drmMMListHead head;
+ uint32_t mapCount;
+ uint32_t start;
+ uint32_t fenceType;
+ int unFenced;
+ _glthread_Cond event;
+};
+
+struct _DriKernelBO {
+ int fd;
+ drmBO bo;
+ drmMMListHead timeoutHead;
+ drmMMListHead head;
+ struct timeval timeFreed;
+ uint32_t pageAlignment;
+ void *virtual;
+};
+
+struct _DriSlab{
+ drmMMListHead head;
+ drmMMListHead freeBuffers;
+ uint32_t numBuffers;
+ uint32_t numFree;
+ struct _DriSlabBuffer *buffers;
+ struct _DriSlabSizeHeader *header;
+ struct _DriKernelBO *kbo;
+};
+
+
+struct _DriSlabSizeHeader {
+ drmMMListHead slabs;
+ drmMMListHead freeSlabs;
+ drmMMListHead delayedBuffers;
+ uint32_t numDelayed;
+ struct _DriSlabPool *slabPool;
+ uint32_t bufSize;
+ _glthread_Mutex mutex;
+};
+
+struct _DriFreeSlabManager {
+ struct timeval slabTimeout;
+ struct timeval checkInterval;
+ struct timeval nextCheck;
+ drmMMListHead timeoutList;
+ drmMMListHead unCached;
+ drmMMListHead cached;
+ _glthread_Mutex mutex;
+};
+
+
+struct _DriSlabPool {
+
+ /*
+ * The data of this structure remains constant after
+ * initialization and thus needs no mutex protection.
+ */
+
+ struct _DriFreeSlabManager *fMan;
+ uint64_t proposedFlags;
+ uint64_t validMask;
+ uint32_t *bucketSizes;
+ uint32_t numBuckets;
+ uint32_t pageSize;
+ int fd;
+ int pageAlignment;
+ int maxSlabSize;
+ int desiredNumBuffers;
+ struct _DriSlabSizeHeader *headers;
+};
+
+/*
+ * FIXME: Perhaps arrange timeout slabs in size buckets for fast
+ * retreival??
+ */
+
+
+static inline int
+driTimeAfterEq(struct timeval *arg1, struct timeval *arg2)
+{
+ return ((arg1->tv_sec > arg2->tv_sec) ||
+ ((arg1->tv_sec == arg2->tv_sec) &&
+ (arg1->tv_usec > arg2->tv_usec)));
+}
+
+static inline void
+driTimeAdd(struct timeval *arg, struct timeval *add)
+{
+ unsigned int sec;
+
+ arg->tv_sec += add->tv_sec;
+ arg->tv_usec += add->tv_usec;
+ sec = arg->tv_usec / 1000000;
+ arg->tv_sec += sec;
+ arg->tv_usec -= sec*1000000;
+}
+
+static void
+driFreeKernelBO(struct _DriKernelBO *kbo)
+{
+ if (!kbo)
+ return;
+
+ (void) drmBOUnreference(kbo->fd, &kbo->bo);
+ free(kbo);
+}
+
+
+static void
+driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan,
+ struct timeval *time)
+{
+ drmMMListHead *list, *next;
+ struct _DriKernelBO *kbo;
+
+ if (!driTimeAfterEq(time, &fMan->nextCheck))
+ return;
+
+ for (list = fMan->timeoutList.next, next = list->next;
+ list != &fMan->timeoutList;
+ list = next, next = list->next) {
+
+ kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead);
+
+ if (!driTimeAfterEq(time, &kbo->timeFreed))
+ break;
+
+ DRMLISTDELINIT(&kbo->timeoutHead);
+ DRMLISTDELINIT(&kbo->head);
+ driFreeKernelBO(kbo);
+ }
+
+ fMan->nextCheck = *time;
+ driTimeAdd(&fMan->nextCheck, &fMan->checkInterval);
+}
+
+
+/*
+ * Add a _DriKernelBO to the free slab manager.
+ * This means that it is available for reuse, but if it's not
+ * reused in a while, it will be freed.
+ */
+
+static void
+driSetKernelBOFree(struct _DriFreeSlabManager *fMan,
+ struct _DriKernelBO *kbo)
+{
+ struct timeval time;
+
+ _glthread_LOCK_MUTEX(fMan->mutex);
+ gettimeofday(&time, NULL);
+ driTimeAdd(&time, &fMan->slabTimeout);
+
+ kbo->timeFreed = time;
+
+ if (kbo->bo.flags & DRM_BO_FLAG_CACHED)
+ DRMLISTADD(&kbo->head, &fMan->cached);
+ else
+ DRMLISTADD(&kbo->head, &fMan->unCached);
+
+ DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList);
+ driFreeTimeoutKBOsLocked(fMan, &time);
+
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+}
+
+/*
+ * Get a _DriKernelBO for us to use as storage for a slab.
+ *
+ */
+
+static struct _DriKernelBO *
+driAllocKernelBO(struct _DriSlabSizeHeader *header)
+
+{
+ struct _DriSlabPool *slabPool = header->slabPool;
+ struct _DriFreeSlabManager *fMan = slabPool->fMan;
+ drmMMListHead *list, *next, *head;
+ uint32_t size = header->bufSize * slabPool->desiredNumBuffers;
+ struct _DriKernelBO *kbo;
+ struct _DriKernelBO *kboTmp;
+ int ret;
+
+ /*
+ * FIXME: We should perhaps allow some variation in slabsize in order
+ * to efficiently reuse slabs.
+ */
+
+ size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize;
+ size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1);
+ _glthread_LOCK_MUTEX(fMan->mutex);
+
+ kbo = NULL;
+
+ retry:
+ head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ?
+ &fMan->cached : &fMan->unCached;
+
+ for (list = head->next, next = list->next;
+ list != head;
+ list = next, next = list->next) {
+
+ kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head);
+
+ if ((kboTmp->bo.size == size) &&
+ (slabPool->pageAlignment == 0 ||
+ (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) {
+
+ if (!kbo)
+ kbo = kboTmp;
+
+ if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0)
+ break;
+
+ }
+ }
+
+ if (kbo) {
+ DRMLISTDELINIT(&kbo->head);
+ DRMLISTDELINIT(&kbo->timeoutHead);
+ }
+
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+
+ if (kbo) {
+ uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags;
+
+ ret = 0;
+ if (new_mask) {
+ ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags,
+ new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0);
+ }
+ if (ret == 0)
+ return kbo;
+
+ driFreeKernelBO(kbo);
+ kbo = NULL;
+ goto retry;
+ }
+
+ kbo = calloc(1, sizeof(struct _DriKernelBO));
+ if (!kbo)
+ return NULL;
+
+ kbo->fd = slabPool->fd;
+ DRMINITLISTHEAD(&kbo->head);
+ DRMINITLISTHEAD(&kbo->timeoutHead);
+ ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL,
+ slabPool->proposedFlags,
+ DRM_BO_HINT_DONT_FENCE, &kbo->bo);
+ if (ret)
+ goto out_err0;
+
+ ret = drmBOMap(kbo->fd, &kbo->bo,
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+ 0, &kbo->virtual);
+
+ if (ret)
+ goto out_err1;
+
+ ret = drmBOUnmap(kbo->fd, &kbo->bo);
+ if (ret)
+ goto out_err1;
+
+ return kbo;
+
+ out_err1:
+ drmBOUnreference(kbo->fd, &kbo->bo);
+ out_err0:
+ free(kbo);
+ return NULL;
+}
+
+
+static int
+driAllocSlab(struct _DriSlabSizeHeader *header)
+{
+ struct _DriSlab *slab;
+ struct _DriSlabBuffer *buf;
+ uint32_t numBuffers;
+ int ret;
+ int i;
+
+ slab = calloc(1, sizeof(*slab));
+ if (!slab)
+ return -ENOMEM;
+
+ slab->kbo = driAllocKernelBO(header);
+ if (!slab->kbo) {
+ ret = -ENOMEM;
+ goto out_err0;
+ }
+
+ numBuffers = slab->kbo->bo.size / header->bufSize;
+
+ slab->buffers = calloc(numBuffers, sizeof(*slab->buffers));
+ if (!slab->buffers) {
+ ret = -ENOMEM;
+ goto out_err1;
+ }
+
+ DRMINITLISTHEAD(&slab->head);
+ DRMINITLISTHEAD(&slab->freeBuffers);
+ slab->numBuffers = numBuffers;
+ slab->numFree = 0;
+ slab->header = header;
+
+ buf = slab->buffers;
+ for (i=0; i < numBuffers; ++i) {
+ buf->parent = slab;
+ buf->start = i* header->bufSize;
+ buf->mapCount = 0;
+ buf->isSlabBuffer = 1;
+ _glthread_INIT_COND(buf->event);
+ DRMLISTADDTAIL(&buf->head, &slab->freeBuffers);
+ slab->numFree++;
+ buf++;
+ }
+
+ DRMLISTADDTAIL(&slab->head, &header->slabs);
+
+ return 0;
+
+ out_err1:
+ driSetKernelBOFree(header->slabPool->fMan, slab->kbo);
+ free(slab->buffers);
+ out_err0:
+ free(slab);
+ return ret;
+}
+
+/*
+ * Delete a buffer from the slab header delayed list and put
+ * it on the slab free list.
+ */
+
+static void
+driSlabFreeBufferLocked(struct _DriSlabBuffer *buf)
+{
+ struct _DriSlab *slab = buf->parent;
+ struct _DriSlabSizeHeader *header = slab->header;
+ drmMMListHead *list = &buf->head;
+
+ DRMLISTDEL(list);
+ DRMLISTADDTAIL(list, &slab->freeBuffers);
+ slab->numFree++;
+
+ if (slab->head.next == &slab->head)
+ DRMLISTADDTAIL(&slab->head, &header->slabs);
+
+ if (slab->numFree == slab->numBuffers) {
+ list = &slab->head;
+ DRMLISTDEL(list);
+ DRMLISTADDTAIL(list, &header->freeSlabs);
+ }
+
+ if (header->slabs.next == &header->slabs ||
+ slab->numFree != slab->numBuffers) {
+
+ drmMMListHead *next;
+ struct _DriFreeSlabManager *fMan = header->slabPool->fMan;
+
+ for (list = header->freeSlabs.next, next = list->next;
+ list != &header->freeSlabs;
+ list = next, next = list->next) {
+
+ slab = DRMLISTENTRY(struct _DriSlab, list, head);
+
+ DRMLISTDELINIT(list);
+ driSetKernelBOFree(fMan, slab->kbo);
+ free(slab->buffers);
+ free(slab);
+ }
+ }
+}
+
+static void
+driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait)
+{
+ drmMMListHead *list, *prev, *first;
+ struct _DriSlabBuffer *buf;
+ struct _DriSlab *slab;
+ int firstWasSignaled = 1;
+ int signaled;
+ int i;
+ int ret;
+
+ /*
+ * Rerun the freeing test if the youngest tested buffer
+ * was signaled, since there might be more idle buffers
+ * in the delay list.
+ */
+
+ while (firstWasSignaled) {
+ firstWasSignaled = 0;
+ signaled = 0;
+ first = header->delayedBuffers.next;
+
+ /* Only examine the oldest 1/3 of delayed buffers:
+ */
+ if (header->numDelayed > 3) {
+ for (i = 0; i < header->numDelayed; i += 3) {
+ first = first->next;
+ }
+ }
+
+ for (list = first, prev = list->prev;
+ list != &header->delayedBuffers;
+ list = prev, prev = list->prev) {
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head);
+ slab = buf->parent;
+
+ if (!signaled) {
+ if (wait) {
+ ret = driFenceFinish(buf->fence, buf->fenceType, 0);
+ if (ret)
+ break;
+ signaled = 1;
+ wait = 0;
+ } else {
+ signaled = driFenceSignaled(buf->fence, buf->fenceType);
+ }
+ if (signaled) {
+ if (list == first)
+ firstWasSignaled = 1;
+ driFenceUnReference(&buf->fence);
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) {
+ driFenceUnReference(&buf->fence);
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ }
+ }
+}
+
+
+static struct _DriSlabBuffer *
+driSlabAllocBuffer(struct _DriSlabSizeHeader *header)
+{
+ static struct _DriSlabBuffer *buf;
+ struct _DriSlab *slab;
+ drmMMListHead *list;
+ int count = DRI_SLABPOOL_ALLOC_RETRIES;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ while(header->slabs.next == &header->slabs && count > 0) {
+ driSlabCheckFreeLocked(header, 0);
+ if (header->slabs.next != &header->slabs)
+ break;
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ if (count != DRI_SLABPOOL_ALLOC_RETRIES)
+ usleep(1);
+ _glthread_LOCK_MUTEX(header->mutex);
+ (void) driAllocSlab(header);
+ count--;
+ }
+
+ list = header->slabs.next;
+ if (list == &header->slabs) {
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ return NULL;
+ }
+ slab = DRMLISTENTRY(struct _DriSlab, list, head);
+ if (--slab->numFree == 0)
+ DRMLISTDELINIT(list);
+
+ list = slab->freeBuffers.next;
+ DRMLISTDELINIT(list);
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head);
+ return buf;
+}
+
+static void *
+pool_create(struct _DriBufferPool *driPool, unsigned long size,
+ uint64_t flags, unsigned hint, unsigned alignment)
+{
+ struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data;
+ struct _DriSlabSizeHeader *header;
+ struct _DriSlabBuffer *buf;
+ void *dummy;
+ int i;
+ int ret;
+
+ /*
+ * FIXME: Check for compatibility.
+ */
+
+ header = pool->headers;
+ for (i=0; i<pool->numBuckets; ++i) {
+ if (header->bufSize >= size)
+ break;
+ header++;
+ }
+
+ if (i < pool->numBuckets)
+ return driSlabAllocBuffer(header);
+
+
+ /*
+ * Fall back to allocate a buffer object directly from DRM.
+ * and wrap it in a driBO structure.
+ */
+
+
+ buf = calloc(1, sizeof(*buf));
+
+ if (!buf)
+ return NULL;
+
+ buf->bo = calloc(1, sizeof(*buf->bo));
+ if (!buf->bo)
+ goto out_err0;
+
+ if (alignment) {
+ if ((alignment < pool->pageSize) && (pool->pageSize % alignment))
+ goto out_err1;
+ if ((alignment > pool->pageSize) && (alignment % pool->pageSize))
+ goto out_err1;
+ }
+
+ ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL,
+ flags, hint, buf->bo);
+ if (ret)
+ goto out_err1;
+
+ ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+ 0, &dummy);
+ if (ret)
+ goto out_err2;
+
+ ret = drmBOUnmap(pool->fd, buf->bo);
+ if (ret)
+ goto out_err2;
+
+ return buf;
+ out_err2:
+ drmBOUnreference(pool->fd, buf->bo);
+ out_err1:
+ free(buf->bo);
+ out_err0:
+ free(buf);
+ return NULL;
+}
+
+static int
+pool_destroy(struct _DriBufferPool *driPool, void *private)
+{
+ struct _DriSlabBuffer *buf =
+ (struct _DriSlabBuffer *) private;
+ struct _DriSlab *slab;
+ struct _DriSlabSizeHeader *header;
+
+ if (!buf->isSlabBuffer) {
+ struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data;
+ int ret;
+
+ ret = drmBOUnreference(pool->fd, buf->bo);
+ free(buf->bo);
+ free(buf);
+ return ret;
+ }
+
+ slab = buf->parent;
+ header = slab->header;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ buf->unFenced = 0;
+ buf->mapCount = 0;
+
+ if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) {
+ DRMLISTADDTAIL(&buf->head, &header->delayedBuffers);
+ header->numDelayed++;
+ } else {
+ if (buf->fence)
+ driFenceUnReference(&buf->fence);
+ driSlabFreeBufferLocked(buf);
+ }
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ return 0;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *driPool, void *private,
+ _glthread_Mutex *mutex, int lazy)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ while(buf->unFenced)
+ _glthread_COND_WAIT(buf->event, *mutex);
+
+ if (!buf->fence)
+ return 0;
+
+ driFenceFinish(buf->fence, buf->fenceType, lazy);
+ driFenceUnReference(&buf->fence);
+
+ return 0;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ int busy;
+
+ if (buf->isSlabBuffer)
+ busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType));
+ else
+ busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType);
+
+
+ if (busy) {
+ if (hint & DRM_BO_HINT_DONT_BLOCK)
+ return -EBUSY;
+ else {
+ (void) pool_waitIdle(pool, private, mutex, 0);
+ }
+ }
+
+ ++buf->mapCount;
+ *virtual = (buf->isSlabBuffer) ?
+ (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) :
+ (void *) buf->bo->virtual;
+
+ return 0;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ --buf->mapCount;
+ if (buf->mapCount == 0 && buf->isSlabBuffer)
+ _glthread_COND_BROADCAST(buf->event);
+
+ return 0;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ struct _DriSlab *slab;
+ struct _DriSlabSizeHeader *header;
+
+ if (!buf->isSlabBuffer) {
+ assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE);
+ return buf->bo->offset;
+ }
+
+ slab = buf->parent;
+ header = slab->header;
+
+ (void) header;
+ assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE);
+ return slab->kbo->bo.offset + buf->start;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ return buf->start;
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ if (!buf->isSlabBuffer)
+ return buf->bo->flags;
+
+ return buf->parent->kbo->bo.flags;
+}
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ if (!buf->isSlabBuffer)
+ return buf->bo->size;
+
+ return buf->parent->header->bufSize;
+}
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ drmBO *bo;
+
+ if (buf->fence)
+ driFenceUnReference(&buf->fence);
+
+ buf->fence = driFenceReference(fence);
+ bo = (buf->isSlabBuffer) ?
+ &buf->parent->kbo->bo:
+ buf->bo;
+ buf->fenceType = bo->fenceFlags;
+
+ buf->unFenced = 0;
+ _glthread_COND_BROADCAST(buf->event);
+
+ return 0;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo;
+}
+
+static int
+pool_validate(struct _DriBufferPool *pool, void *private,
+ _glthread_Mutex *mutex)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ if (!buf->isSlabBuffer)
+ return 0;
+
+ while(buf->mapCount != 0)
+ _glthread_COND_WAIT(buf->event, *mutex);
+
+ buf->unFenced = 1;
+ return 0;
+}
+
+
+struct _DriFreeSlabManager *
+driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec)
+{
+ struct _DriFreeSlabManager *tmp;
+
+ tmp = calloc(1, sizeof(*tmp));
+ if (!tmp)
+ return NULL;
+
+ _glthread_INIT_MUTEX(tmp->mutex);
+ _glthread_LOCK_MUTEX(tmp->mutex);
+ tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000;
+ tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000;
+ tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000;
+
+ tmp->checkInterval.tv_usec = checkIntervalMsec*1000;
+ tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000;
+ tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000;
+
+ gettimeofday(&tmp->nextCheck, NULL);
+ driTimeAdd(&tmp->nextCheck, &tmp->checkInterval);
+ DRMINITLISTHEAD(&tmp->timeoutList);
+ DRMINITLISTHEAD(&tmp->unCached);
+ DRMINITLISTHEAD(&tmp->cached);
+ _glthread_UNLOCK_MUTEX(tmp->mutex);
+
+ return tmp;
+}
+
+void
+driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan)
+{
+ struct timeval time;
+
+ time = fMan->nextCheck;
+ driTimeAdd(&time, &fMan->checkInterval);
+
+ _glthread_LOCK_MUTEX(fMan->mutex);
+ driFreeTimeoutKBOsLocked(fMan, &time);
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+
+ assert(fMan->timeoutList.next == &fMan->timeoutList);
+ assert(fMan->unCached.next == &fMan->unCached);
+ assert(fMan->cached.next == &fMan->cached);
+
+ free(fMan);
+}
+
+static void
+driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size,
+ struct _DriSlabSizeHeader *header)
+{
+ _glthread_INIT_MUTEX(header->mutex);
+ _glthread_LOCK_MUTEX(header->mutex);
+
+ DRMINITLISTHEAD(&header->slabs);
+ DRMINITLISTHEAD(&header->freeSlabs);
+ DRMINITLISTHEAD(&header->delayedBuffers);
+
+ header->numDelayed = 0;
+ header->slabPool = pool;
+ header->bufSize = size;
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+}
+
+static void
+driFinishSizeHeader(struct _DriSlabSizeHeader *header)
+{
+ drmMMListHead *list, *next;
+ struct _DriSlabBuffer *buf;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ for (list = header->delayedBuffers.next, next = list->next;
+ list != &header->delayedBuffers;
+ list = next, next = list->next) {
+
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head);
+ if (buf->fence) {
+ (void) driFenceFinish(buf->fence, buf->fenceType, 0);
+ driFenceUnReference(&buf->fence);
+ }
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ _glthread_UNLOCK_MUTEX(header->mutex);
+}
+
+static void
+pool_takedown(struct _DriBufferPool *driPool)
+{
+ struct _DriSlabPool *pool = driPool->data;
+ int i;
+
+ for (i=0; i<pool->numBuckets; ++i) {
+ driFinishSizeHeader(&pool->headers[i]);
+ }
+
+ free(pool->headers);
+ free(pool->bucketSizes);
+ free(pool);
+ free(driPool);
+}
+
+struct _DriBufferPool *
+driSlabPoolInit(int fd, uint64_t flags,
+ uint64_t validMask,
+ uint32_t smallestSize,
+ uint32_t numSizes,
+ uint32_t desiredNumBuffers,
+ uint32_t maxSlabSize,
+ uint32_t pageAlignment,
+ struct _DriFreeSlabManager *fMan)
+{
+ struct _DriBufferPool *driPool;
+ struct _DriSlabPool *pool;
+ uint32_t i;
+
+ driPool = calloc(1, sizeof(*driPool));
+ if (!driPool)
+ return NULL;
+
+ pool = calloc(1, sizeof(*pool));
+ if (!pool)
+ goto out_err0;
+
+ pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes));
+ if (!pool->bucketSizes)
+ goto out_err1;
+
+ pool->headers = calloc(numSizes, sizeof(*pool->headers));
+ if (!pool->headers)
+ goto out_err2;
+
+ pool->fMan = fMan;
+ pool->proposedFlags = flags;
+ pool->validMask = validMask;
+ pool->numBuckets = numSizes;
+ pool->pageSize = getpagesize();
+ pool->fd = fd;
+ pool->pageAlignment = pageAlignment;
+ pool->maxSlabSize = maxSlabSize;
+ pool->desiredNumBuffers = desiredNumBuffers;
+
+ for (i=0; i<pool->numBuckets; ++i) {
+ pool->bucketSizes[i] = (smallestSize << i);
+ driInitSizeHeader(pool, pool->bucketSizes[i],
+ &pool->headers[i]);
+ }
+
+ driPool->data = (void *) pool;
+ driPool->map = &pool_map;
+ driPool->unmap = &pool_unmap;
+ driPool->destroy = &pool_destroy;
+ driPool->offset = &pool_offset;
+ driPool->poolOffset = &pool_poolOffset;
+ driPool->flags = &pool_flags;
+ driPool->size = &pool_size;
+ driPool->create = &pool_create;
+ driPool->fence = &pool_fence;
+ driPool->kernel = &pool_kernel;
+ driPool->validate = &pool_validate;
+ driPool->waitIdle = &pool_waitIdle;
+ driPool->takeDown = &pool_takedown;
+
+ return driPool;
+
+ out_err2:
+ free(pool->bucketSizes);
+ out_err1:
+ free(pool);
+ out_err0:
+ free(driPool);
+
+ return NULL;
+}
diff --git a/src/gallium/winsys/egl_drm/Makefile b/src/gallium/winsys/egl_drm/Makefile
new file mode 100644
index 0000000000..4139d9e71f
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/Makefile
@@ -0,0 +1,38 @@
+# src/mesa/drivers/egl_drm/Makefile
+
+TOP = ../../../..
+
+include $(TOP)/configs/current
+
+
+
+default: $(TOP)/$(LIB_DIR) subdirs
+
+
+$(TOP)/$(LIB_DIR):
+ -mkdir $(TOP)/$(LIB_DIR)
+
+
+subdirs:
+ @for dir in $(DRI_DIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE)) || exit 1 ; \
+ fi \
+ done
+
+
+install:
+ @for dir in $(DRI_DIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) install) || exit 1 ; \
+ fi \
+ done
+
+
+clean:
+ @for dir in $(DRI_DIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) clean) ; \
+ fi \
+ done
+ -rm -f common/*.o
diff --git a/src/gallium/winsys/egl_drm/Makefile.template b/src/gallium/winsys/egl_drm/Makefile.template
new file mode 100644
index 0000000000..3bc1fdd4d4
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/Makefile.template
@@ -0,0 +1,116 @@
+# -*-makefile-*-
+
+MESA_MODULES = \
+ $(TOP)/src/mesa/libmesa.a \
+ $(GALLIUM_AUXILIARIES)
+
+COMMON_GALLIUM_SOURCES = \
+ $(TOP)/src/mesa/drivers/dri/common/utils.c \
+ $(TOP)/src/mesa/drivers/dri/common/vblank.c \
+ $(TOP)/src/mesa/drivers/dri/common/dri_util.c \
+ $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c
+
+COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \
+ $(TOP)/src/mesa/drivers/common/driverfuncs.c \
+ $(TOP)/src/mesa/drivers/dri/common/texmem.c \
+ $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c
+
+COMMON_BM_SOURCES = \
+ $(TOP)/src/mesa/drivers/dri/common/dri_bufmgr.c \
+ $(TOP)/src/mesa/drivers/dri/common/dri_drmpool.c
+
+
+ifeq ($(WINDOW_SYSTEM),dri)
+WINOBJ=
+WINLIB=
+INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES)
+
+OBJECTS = \
+ $(C_SOURCES:.c=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+else
+# miniglx
+WINOBJ=
+WINLIB=-L$(MESA)/src/glx/mini
+MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
+INCLUDES = $(MINIGLX_INCLUDES) \
+ $(SHARED_INCLUDES) \
+ $(PCIACCESS_CFLAGS)
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(MINIGLX_SOURCES:.c=.o) \
+ $(ASM_SOURCES:.S=.o)
+endif
+
+
+### Include directories
+SHARED_INCLUDES = \
+ -I. \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -Iserver \
+ -I$(TOP)/include \
+ -I$(TOP)/include/GL/internal \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/mesa/glapi \
+ -I$(TOP)/src/mesa/math \
+ -I$(TOP)/src/mesa/transform \
+ -I$(TOP)/src/mesa/shader \
+ -I$(TOP)/src/mesa/swrast \
+ -I$(TOP)/src/mesa/swrast_setup \
+ -I$(TOP)/src/egl/main \
+ -I$(TOP)/src/egl/drivers/dri \
+ $(LIBDRM_CFLAGS)
+
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME)
+
+
+$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
+ $(TOP)/bin/mklib -noprefix -o $@ \
+ $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS)
+
+
+$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME)
+ $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)
+
+
+depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \
+ $(ASM_SOURCES) 2> /dev/null
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean:
+ -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS)
+ -rm -f depend depend.bak
+
+
+install: $(LIBNAME)
+ $(INSTALL) -d $(DRI_DRIVER_INSTALL_DIR)
+ $(INSTALL) -m 755 $(LIBNAME) $(DRI_DRIVER_INSTALL_DIR)
+
+
+include depend
diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile
new file mode 100644
index 0000000000..5778ba77c3
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/Makefile
@@ -0,0 +1,40 @@
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = EGL_i915.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/i915simple/libi915simple.a
+
+DRIVER_SOURCES = \
+ intel_winsys_pipe.c \
+ intel_winsys_softpipe.c \
+ intel_winsys_i915.c \
+ intel_batchbuffer.c \
+ intel_swapbuffers.c \
+ intel_context.c \
+ intel_lock.c \
+ intel_screen.c \
+ ws_dri_bufmgr.c \
+ ws_dri_drmpool.c \
+ ws_dri_fencemgr.c \
+ ws_dri_mallocpool.c \
+ ws_dri_slabpool.c \
+ intel_egl.c
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+DRIVER_DEFINES = -I$(TOP)/src/mesa/drivers/dri/intel $(shell pkg-config libdrm --atleast-version=2.3.1 \
+ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+
+include ../Makefile.template
+
+intel_tex_layout.o: $(TOP)/src/mesa/drivers/dri/intel/intel_tex_layout.c
+
+symlinks:
diff --git a/src/gallium/winsys/egl_drm/intel/SConscript b/src/gallium/winsys/egl_drm/intel/SConscript
new file mode 100644
index 0000000000..0ad19d42a8
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/SConscript
@@ -0,0 +1,39 @@
+Import('*')
+
+env = drienv.Clone()
+
+env.Append(CPPPATH = [
+ '../intel',
+ 'server'
+])
+
+#MINIGLX_SOURCES = server/intel_dri.c
+
+DRIVER_SOURCES = [
+ 'intel_winsys_pipe.c',
+ 'intel_winsys_softpipe.c',
+ 'intel_winsys_i915.c',
+ 'intel_batchbuffer.c',
+ 'intel_swapbuffers.c',
+ 'intel_context.c',
+ 'intel_lock.c',
+ 'intel_screen.c',
+ 'intel_batchpool.c',
+]
+
+sources = \
+ COMMON_GALLIUM_SOURCES + \
+ COMMON_BM_SOURCES + \
+ DRIVER_SOURCES
+
+drivers = [
+ softpipe,
+ i915simple
+]
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+env.SharedLibrary(
+ target ='i915tex_dri.so',
+ source = sources,
+ LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+) \ No newline at end of file
diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c
new file mode 100644
index 0000000000..7ffa05a6e6
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c
@@ -0,0 +1,465 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "intel_batchbuffer.h"
+#include "intel_context.h"
+#include "intel_egl.h"
+
+#include <errno.h>
+
+#if 0
+static void
+intel_dump_batchbuffer(GLuint offset, GLuint * ptr, GLuint count)
+{
+ int i;
+ fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count / 4);
+ for (i = 0; i < count / 4; i += 4)
+ fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n",
+ offset + i * 4, ptr[i], ptr[i + 1], ptr[i + 2], ptr[i + 3]);
+ fprintf(stderr, "END BATCH\n\n\n");
+}
+#endif
+
+static void
+intel_realloc_relocs(struct intel_batchbuffer *batch, int num_relocs)
+{
+ unsigned long size = num_relocs * I915_RELOC0_STRIDE + I915_RELOC_HEADER;
+
+ size *= sizeof(uint32_t);
+ batch->reloc = realloc(batch->reloc, size);
+ batch->reloc_size = num_relocs;
+}
+
+
+void
+intel_batchbuffer_reset(struct intel_batchbuffer *batch)
+{
+ /*
+ * Get a new, free batchbuffer.
+ */
+ drmBO *bo;
+ struct drm_bo_info_req *req;
+ int ret;
+
+ driBOUnrefUserList(batch->list);
+ driBOResetList(batch->list);
+
+ batch->size = 4096; // ZZZ JB batch->intel->intelScreen->maxBatchSize;
+ ret = driBOData(batch->buffer, batch->size, NULL, NULL, 0);
+ assert(!ret);
+
+ /*
+ * Add the batchbuffer to the validate list.
+ */
+
+ driBOAddListItem(batch->list, batch->buffer,
+ DRM_BO_FLAG_EXE | DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_EXE | DRM_BO_MASK_MEM,
+ &batch->dest_location, &batch->node);
+
+ req = &batch->node->bo_arg.d.req.bo_req;
+
+ /*
+ * Set up information needed for us to make relocations
+ * relative to the underlying drm buffer objects.
+ */
+
+ driReadLockKernelBO();
+ bo = driBOKernel(batch->buffer);
+ req->presumed_offset = (uint64_t) bo->offset;
+ req->hint = DRM_BO_HINT_PRESUMED_OFFSET;
+ batch->drmBOVirtual = (uint8_t *) bo->virtual;
+ driReadUnlockKernelBO();
+
+ /*
+ * Adjust the relocation buffer size.
+ */
+
+ if (batch->reloc_size > INTEL_MAX_RELOCS ||
+ batch->reloc == NULL)
+ intel_realloc_relocs(batch, INTEL_DEFAULT_RELOCS);
+
+ assert(batch->reloc != NULL);
+ batch->reloc[0] = 0; /* No relocs yet. */
+ batch->reloc[1] = 1; /* Reloc type 1 */
+ batch->reloc[2] = 0; /* Only a single relocation list. */
+ batch->reloc[3] = 0; /* Only a single relocation list. */
+
+ batch->map = driBOMap(batch->buffer, DRM_BO_FLAG_WRITE, 0);
+ batch->poolOffset = driBOPoolOffset(batch->buffer);
+ batch->ptr = batch->map;
+ batch->dirty_state = ~0;
+ batch->nr_relocs = 0;
+ batch->flags = 0;
+ batch->id = 0;//batch->intel->intelScreen->batch_id++;
+}
+
+/*======================================================================
+ * Public functions
+ */
+struct intel_batchbuffer *
+intel_batchbuffer_alloc(struct intel_screen *intel_screen)
+{
+ struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
+
+ batch->intel_screen = intel_screen;
+
+ driGenBuffers(intel_screen->batchPool, "batchbuffer", 1,
+ &batch->buffer, 4096,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE, 0);
+ batch->last_fence = NULL;
+ batch->list = driBOCreateList(20);
+ batch->reloc = NULL;
+ intel_batchbuffer_reset(batch);
+ return batch;
+}
+
+void
+intel_batchbuffer_free(struct intel_batchbuffer *batch)
+{
+ if (batch->last_fence) {
+ driFenceFinish(batch->last_fence,
+ DRM_FENCE_TYPE_EXE, GL_FALSE);
+ driFenceUnReference(&batch->last_fence);
+ }
+ if (batch->map) {
+ driBOUnmap(batch->buffer);
+ batch->map = NULL;
+ }
+ driBOUnReference(batch->buffer);
+ driBOFreeList(batch->list);
+ if (batch->reloc)
+ free(batch->reloc);
+ batch->buffer = NULL;
+ free(batch);
+}
+
+void
+intel_offset_relocation(struct intel_batchbuffer *batch,
+ unsigned pre_add,
+ struct _DriBufferObject *driBO,
+ uint64_t val_flags,
+ uint64_t val_mask)
+{
+ int itemLoc;
+ struct _drmBONode *node;
+ uint32_t *reloc;
+ struct drm_bo_info_req *req;
+
+ driBOAddListItem(batch->list, driBO, val_flags, val_mask,
+ &itemLoc, &node);
+ req = &node->bo_arg.d.req.bo_req;
+
+ if (!(req->hint & DRM_BO_HINT_PRESUMED_OFFSET)) {
+
+ /*
+ * Stop other threads from tampering with the underlying
+ * drmBO while we're reading its offset.
+ */
+
+ driReadLockKernelBO();
+ req->presumed_offset = (uint64_t) driBOKernel(driBO)->offset;
+ driReadUnlockKernelBO();
+ req->hint = DRM_BO_HINT_PRESUMED_OFFSET;
+ }
+
+ pre_add += driBOPoolOffset(driBO);
+
+ if (batch->nr_relocs == batch->reloc_size)
+ intel_realloc_relocs(batch, batch->reloc_size * 2);
+
+ reloc = batch->reloc +
+ (I915_RELOC_HEADER + batch->nr_relocs * I915_RELOC0_STRIDE);
+
+ reloc[0] = ((uint8_t *)batch->ptr - batch->drmBOVirtual);
+ intel_batchbuffer_emit_dword(batch, req->presumed_offset + pre_add);
+ reloc[1] = pre_add;
+ reloc[2] = itemLoc;
+ reloc[3] = batch->dest_location;
+ batch->nr_relocs++;
+}
+
+static void
+i915_drm_copy_reply(const struct drm_bo_info_rep * rep, drmBO * buf)
+{
+ buf->handle = rep->handle;
+ buf->flags = rep->flags;
+ buf->size = rep->size;
+ buf->offset = rep->offset;
+ buf->mapHandle = rep->arg_handle;
+ buf->proposedFlags = rep->proposed_flags;
+ buf->start = rep->buffer_start;
+ buf->fenceFlags = rep->fence_flags;
+ buf->replyFlags = rep->rep_flags;
+ buf->pageAlignment = rep->page_alignment;
+}
+
+static int
+i915_execbuf(struct intel_batchbuffer *batch,
+ GLuint used,
+ GLboolean ignore_cliprects,
+ drmBOList *list,
+ struct drm_i915_execbuffer *ea)
+{
+ struct intel_screen *intel_screen = batch->intel_screen;
+ drmBONode *node;
+ drmMMListHead *l;
+ struct drm_i915_op_arg *arg, *first;
+ struct drm_bo_op_req *req;
+ struct drm_bo_info_rep *rep;
+ uint64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret = 0;
+ uint32_t count = 0;
+
+ first = NULL;
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long)arg;
+
+ prevNext = &arg->next;
+ req->bo_req.handle = node->buf->handle;
+ req->op = drm_bo_validate;
+ req->bo_req.flags = node->arg0;
+ req->bo_req.mask = node->arg1;
+ req->bo_req.hint |= 0;
+ count++;
+ }
+
+ memset(ea, 0, sizeof(*ea));
+ ea->num_buffers = count;
+ ea->batch.start = batch->poolOffset;
+ ea->batch.used = used;
+#if 0 /* ZZZ JB: no cliprects used */
+ ea->batch.cliprects = intel->pClipRects;
+ ea->batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
+ ea->batch.DR1 = 0;
+ ea->batch.DR4 = 0;((((GLuint) intel->drawX) & 0xffff) |
+ (((GLuint) intel->drawY) << 16));
+#else
+ ea->batch.cliprects = NULL;
+ ea->batch.num_cliprects = 0;
+ ea->batch.DR1 = 0;
+ ea->batch.DR4 = 0;
+#endif
+ ea->fence_arg.flags = DRM_I915_FENCE_FLAG_FLUSHED;
+ ea->ops_list = (unsigned long) first;
+ first->reloc_ptr = (unsigned long) batch->reloc;
+ batch->reloc[0] = batch->nr_relocs;
+
+ //return -EFAULT;
+ do {
+ ret = drmCommandWriteRead(intel_screen->device->drmFD, DRM_I915_EXECBUFFER, ea,
+ sizeof(*ea));
+ } while (ret == -EAGAIN);
+
+ if (ret != 0) {
+ printf("%s somebody set us up the bomb\n", __FUNCTION__);
+ return ret;
+ }
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ arg = &node->bo_arg;
+ rep = &arg->d.rep.bo_info;
+
+ if (!arg->handled) {
+ return -EFAULT;
+ }
+ if (arg->d.rep.ret)
+ return arg->d.rep.ret;
+
+ buf = node->buf;
+ i915_drm_copy_reply(rep, buf);
+ }
+ return 0;
+}
+
+/* TODO: Push this whole function into bufmgr.
+ */
+static struct _DriFenceObject *
+do_flush_locked(struct intel_batchbuffer *batch,
+ GLuint used,
+ GLboolean ignore_cliprects, GLboolean allow_unlock)
+{
+ struct intel_screen *intel_screen = batch->intel_screen;
+ struct _DriFenceObject *fo;
+ drmFence fence;
+ drmBOList *boList;
+ struct drm_i915_execbuffer ea;
+ int ret = 0;
+
+ driBOValidateUserList(batch->list);
+ boList = driGetdrmBOList(batch->list);
+
+#if 0 /* ZZZ JB Allways run */
+ if (!(intel->numClipRects == 0 && !ignore_cliprects)) {
+#else
+ if (1) {
+#endif
+ ret = i915_execbuf(batch, used, ignore_cliprects, boList, &ea);
+ } else {
+ driPutdrmBOList(batch->list);
+ fo = NULL;
+ goto out;
+ }
+ driPutdrmBOList(batch->list);
+ if (ret)
+ abort();
+
+ if (ea.fence_arg.error != 0) {
+
+ /*
+ * The hardware has been idled by the kernel.
+ * Don't fence the driBOs.
+ */
+
+ if (batch->last_fence)
+ driFenceUnReference(&batch->last_fence);
+#if 0 /* ZZZ JB: no _mesa_* funcs in gallium */
+ _mesa_printf("fence error\n");
+#endif
+ batch->last_fence = NULL;
+ fo = NULL;
+ goto out;
+ }
+
+ fence.handle = ea.fence_arg.handle;
+ fence.fence_class = ea.fence_arg.fence_class;
+ fence.type = ea.fence_arg.type;
+ fence.flags = ea.fence_arg.flags;
+ fence.signaled = ea.fence_arg.signaled;
+
+ fo = driBOFenceUserList(intel_screen->mgr, batch->list,
+ "SuperFence", &fence);
+
+ if (driFenceType(fo) & DRM_I915_FENCE_TYPE_RW) {
+ if (batch->last_fence)
+ driFenceUnReference(&batch->last_fence);
+ /*
+ * FIXME: Context last fence??
+ */
+ batch->last_fence = fo;
+ driFenceReference(fo);
+ }
+ out:
+#if 0 /* ZZZ JB: fix this */
+ intel->vtbl.lost_hardware(intel);
+#else
+#endif
+ return fo;
+}
+
+
+struct _DriFenceObject *
+intel_batchbuffer_flush(struct intel_batchbuffer *batch)
+{
+ //struct intel_context *intel = batch->intel;
+ GLuint used = batch->ptr - batch->map;
+ //GLboolean was_locked = 1;
+ struct _DriFenceObject *fence;
+
+ if (used == 0) {
+ driFenceReference(batch->last_fence);
+ return batch->last_fence;
+ }
+
+ /* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a
+ * performance drain that we would like to avoid.
+ */
+#if 0 /* ZZZ JB: what should we do here? */
+ if (used & 4) {
+ ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
+ ((int *) batch->ptr)[1] = 0;
+ ((int *) batch->ptr)[2] = MI_BATCH_BUFFER_END;
+ used += 12;
+ }
+ else {
+ ((int *) batch->ptr)[0] = intel->vtbl.flush_cmd();
+ ((int *) batch->ptr)[1] = MI_BATCH_BUFFER_END;
+ used += 8;
+ }
+#else
+ if (used & 4) {
+ ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((int *) batch->ptr)[1] = 0;
+ ((int *) batch->ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ used += 12;
+ }
+ else {
+ ((int *) batch->ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((int *) batch->ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ used += 8;
+ }
+#endif
+ driBOUnmap(batch->buffer);
+ batch->ptr = NULL;
+ batch->map = NULL;
+
+ /* TODO: Just pass the relocation list and dma buffer up to the
+ * kernel.
+ */
+/* if (!was_locked)
+ LOCK_HARDWARE(intel);*/
+
+ fence = do_flush_locked(batch, used, !(batch->flags & INTEL_BATCH_CLIPRECTS),
+ GL_FALSE);
+
+/* if (!was_locked)
+ UNLOCK_HARDWARE(intel);*/
+
+ /* Reset the buffer:
+ */
+ intel_batchbuffer_reset(batch);
+ return fence;
+}
+
+void
+intel_batchbuffer_finish(struct intel_batchbuffer *batch)
+{
+ struct _DriFenceObject *fence = intel_batchbuffer_flush(batch);
+ driFenceFinish(fence, driFenceType(fence), GL_FALSE);
+ driFenceUnReference(&fence);
+}
+
+void
+intel_batchbuffer_data(struct intel_batchbuffer *batch,
+ const void *data, GLuint bytes, GLuint flags)
+{
+ assert((bytes & 3) == 0);
+ intel_batchbuffer_require_space(batch, bytes, flags);
+ memcpy(batch->ptr, data, bytes);
+ batch->ptr += bytes;
+}
diff --git a/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h
new file mode 100644
index 0000000000..6d35cf8b96
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h
@@ -0,0 +1,133 @@
+#ifndef INTEL_BATCHBUFFER_H
+#define INTEL_BATCHBUFFER_H
+
+#include "mtypes.h"
+#include "ws_dri_bufmgr.h"
+
+struct intel_screen;
+
+#define BATCH_SZ 16384
+#define BATCH_RESERVED 16
+
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS 0x2
+
+struct intel_batchbuffer
+{
+ struct bufmgr *bm;
+ struct intel_screen *intel_screen;
+
+ struct _DriBufferObject *buffer;
+ struct _DriFenceObject *last_fence;
+ GLuint flags;
+
+ struct _DriBufferList *list;
+ GLuint list_count;
+ GLubyte *map;
+ GLubyte *ptr;
+
+ uint32_t *reloc;
+ GLuint reloc_size;
+ GLuint nr_relocs;
+
+ GLuint size;
+
+ GLuint dirty_state;
+ GLuint id;
+
+ uint32_t poolOffset;
+ uint8_t *drmBOVirtual;
+ struct _drmBONode *node; /* Validation list node for this buffer */
+ int dest_location; /* Validation list sequence for this buffer */
+};
+
+struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_screen
+ *intel);
+
+void intel_batchbuffer_free(struct intel_batchbuffer *batch);
+
+
+void intel_batchbuffer_finish(struct intel_batchbuffer *batch);
+
+struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer
+ *batch);
+
+void intel_batchbuffer_reset(struct intel_batchbuffer *batch);
+
+
+/* Unlike bmBufferData, this currently requires the buffer be mapped.
+ * Consider it a convenience function wrapping multple
+ * intel_buffer_dword() calls.
+ */
+void intel_batchbuffer_data(struct intel_batchbuffer *batch,
+ const void *data, GLuint bytes, GLuint flags);
+
+void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
+ GLuint bytes);
+
+void
+intel_offset_relocation(struct intel_batchbuffer *batch,
+ unsigned pre_add,
+ struct _DriBufferObject *driBO,
+ uint64_t val_flags,
+ uint64_t val_mask);
+
+/* Inline functions - might actually be better off with these
+ * non-inlined. Certainly better off switching all command packets to
+ * be passed as structs rather than dwords, but that's a little bit of
+ * work...
+ */
+static INLINE GLuint
+intel_batchbuffer_space(struct intel_batchbuffer *batch)
+{
+ return (batch->size - BATCH_RESERVED) - (batch->ptr - batch->map);
+}
+
+
+static INLINE void
+intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch, GLuint dword)
+{
+ assert(batch->map);
+ assert(intel_batchbuffer_space(batch) >= 4);
+ *(GLuint *) (batch->ptr) = dword;
+ batch->ptr += 4;
+}
+
+static INLINE void
+intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
+ GLuint sz, GLuint flags)
+{
+ struct _DriFenceObject *fence;
+
+ assert(sz < batch->size - 8);
+ if (intel_batchbuffer_space(batch) < sz ||
+ (batch->flags != 0 && flags != 0 && batch->flags != flags)) {
+ fence = intel_batchbuffer_flush(batch);
+ driFenceUnReference(&fence);
+ }
+
+ batch->flags |= flags;
+}
+
+/* Here are the crusty old macros, to be removed:
+ */
+#define BATCH_LOCALS
+
+#define BEGIN_BATCH(n, flags) do { \
+ assert(!intel->prim.flush); \
+ intel_batchbuffer_require_space(intel->batch, (n)*4, flags); \
+} while (0)
+
+#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
+
+#define OUT_RELOC(buf,flags,mask,delta) do { \
+ assert((delta) >= 0); \
+ intel_offset_relocation(intel->batch, delta, buf, flags, mask); \
+} while (0)
+
+#define ADVANCE_BATCH() do { } while(0)
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c
new file mode 100644
index 0000000000..394a40d714
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.c
@@ -0,0 +1,366 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_swapbuffers.h"
+#include "intel_winsys.h"
+#include "intel_batchbuffer.h"
+
+#include "state_tracker/st_public.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_context.h"
+#include "intel_egl.h"
+#include "utils.h"
+
+#ifdef DEBUG
+int __intel_debug = 0;
+#endif
+
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_window_pos
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_cull_vertex
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_NV_vertex_program
+#include "extension_helper.h"
+
+
+/**
+ * Extension strings exported by the intel driver.
+ *
+ * \note
+ * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
+ * old i830-specific driver.
+ */
+const struct dri_extension card_extensions[] = {
+ {"GL_ARB_multisample", GL_ARB_multisample_functions},
+ {"GL_ARB_multitexture", NULL},
+ {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
+ {"GL_ARB_texture_border_clamp", NULL},
+ {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
+ {"GL_ARB_texture_cube_map", NULL},
+ {"GL_ARB_texture_env_add", NULL},
+ {"GL_ARB_texture_env_combine", NULL},
+ {"GL_ARB_texture_env_dot3", NULL},
+ {"GL_ARB_texture_mirrored_repeat", NULL},
+ {"GL_ARB_texture_rectangle", NULL},
+ {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
+ {"GL_ARB_pixel_buffer_object", NULL},
+ {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
+ {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
+ {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
+ {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
+ {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
+ {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
+ {"GL_EXT_blend_subtract", NULL},
+ {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
+ {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
+ {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
+ {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+ {"GL_EXT_packed_depth_stencil", NULL},
+ {"GL_EXT_pixel_buffer_object", NULL},
+ {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+ {"GL_EXT_stencil_wrap", NULL},
+ {"GL_EXT_texture_edge_clamp", NULL},
+ {"GL_EXT_texture_env_combine", NULL},
+ {"GL_EXT_texture_env_dot3", NULL},
+ {"GL_EXT_texture_filter_anisotropic", NULL},
+ {"GL_EXT_texture_lod_bias", NULL},
+ {"GL_3DFX_texture_compression_FXT1", NULL},
+ {"GL_APPLE_client_storage", NULL},
+ {"GL_MESA_pack_invert", NULL},
+ {"GL_MESA_ycbcr_texture", NULL},
+ {"GL_NV_blend_square", NULL},
+ {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
+ {"GL_NV_vertex_program1_1", NULL},
+ {"GL_SGIS_generate_mipmap", NULL },
+ {NULL, NULL}
+};
+
+int
+intel_create_context(struct egl_drm_context *eglCon, const __GLcontextModes *visual, void *sharedContextPrivate)
+{
+ struct intel_context *iCon = CALLOC_STRUCT(intel_context);
+ struct intel_screen *iScrn = (struct intel_screen *)eglCon->device->priv;
+ struct pipe_context *pipe;
+ struct st_context *st_share = NULL;
+
+ eglCon->priv = iCon;
+
+ iCon->intel_screen = iScrn;
+ iCon->egl_context = eglCon;
+ iCon->egl_device = eglCon->device;
+
+ iCon->batch = intel_batchbuffer_alloc(iScrn);
+ iCon->last_swap_fence = NULL;
+ iCon->first_swap_fence = NULL;
+
+ pipe = intel_create_i915simple(iCon, iScrn->winsys);
+// pipe = intel_create_softpipe(iCon, iScrn->winsys);
+
+ pipe->priv = iCon;
+
+ iCon->st = st_create_context(pipe, visual, st_share);
+ return TRUE;
+}
+
+void
+intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read)
+{
+ if (context) {
+ struct intel_context *intel = (struct intel_context *)context->priv;
+ struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
+ struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv;
+
+ assert(draw_fb->stfb);
+ assert(read_fb->stfb);
+
+ st_make_current(intel->st, draw_fb->stfb, read_fb->stfb);
+
+ intel->egl_drawable = draw;
+
+ st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
+
+ if (draw != read)
+ st_resize_framebuffer(read_fb->stfb, read->w, read->h);
+
+ //intelUpdateWindowSize(driDrawPriv);
+ } else {
+ st_make_current(NULL, NULL, NULL);
+ }
+}
+
+void
+intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
+{
+ struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv;
+ struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
+
+ driBOUnReference(draw_fb->front_buffer);
+ draw_fb->front_buffer = NULL;
+ draw_fb->front = NULL;
+
+ /* to unbind just call this function with front == NULL */
+ if (!front)
+ return;
+
+ draw_fb->front = front;
+
+ driGenBuffers(intelScreen->staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
+ driBOSetReferenced(draw_fb->front_buffer, front->handle);
+
+ st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
+}
+
+#if 0
+GLboolean
+intelCreateContext(const __GLcontextModes * visual,
+ __DRIcontextPrivate * driContextPriv,
+ void *sharedContextPrivate)
+{
+ struct intel_context *intel = CALLOC_STRUCT(intel_context);
+ __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ struct intel_screen *intelScreen = intel_screen(sPriv);
+ drmI830Sarea *saPriv = intelScreen->sarea;
+ int fthrottle_mode;
+ GLboolean havePools;
+ struct pipe_context *pipe;
+ struct st_context *st_share = NULL;
+
+ if (sharedContextPrivate) {
+ st_share = ((struct intel_context *) sharedContextPrivate)->st;
+ }
+
+ driContextPriv->driverPrivate = intel;
+ intel->intelScreen = intelScreen;
+ intel->driScreen = sPriv;
+ intel->sarea = saPriv;
+
+ driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
+ intel->driScreen->myNum, "i915");
+
+
+ /*
+ * memory pools
+ */
+ DRM_LIGHT_LOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
+ // ZZZ JB should be per screen and not be done per context
+ havePools = intelCreatePools(sPriv);
+ DRM_UNLOCK(sPriv->fd, &sPriv->pSAREA->lock, driContextPriv->hHWContext);
+ if (!havePools)
+ return GL_FALSE;
+
+
+ /* Dri stuff */
+ intel->hHWContext = driContextPriv->hHWContext;
+ intel->driFd = sPriv->fd;
+ intel->driHwLock = (drmLock *) & sPriv->pSAREA->lock;
+
+ fthrottle_mode = driQueryOptioni(&intel->optionCache, "fthrottle_mode");
+ intel->iw.irq_seq = -1;
+ intel->irqsEmitted = 0;
+
+ intel->batch = intel_batchbuffer_alloc(intel);
+ intel->last_swap_fence = NULL;
+ intel->first_swap_fence = NULL;
+
+#ifdef DEBUG
+ __intel_debug = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
+#endif
+
+ /*
+ * Pipe-related setup
+ */
+ if (getenv("INTEL_SP")) {
+ /* use softpipe driver instead of hw */
+ pipe = intel_create_softpipe( intel, intelScreen->winsys );
+ }
+ else {
+ switch (intel->intelScreen->deviceID) {
+ case PCI_CHIP_I945_G:
+ case PCI_CHIP_I945_GM:
+ case PCI_CHIP_I945_GME:
+ case PCI_CHIP_G33_G:
+ case PCI_CHIP_Q33_G:
+ case PCI_CHIP_Q35_G:
+ case PCI_CHIP_I915_G:
+ case PCI_CHIP_I915_GM:
+ pipe = intel_create_i915simple( intel, intelScreen->winsys );
+ break;
+ default:
+ fprintf(stderr, "Unknown PCIID %x in %s, using software driver\n",
+ intel->intelScreen->deviceID, __FUNCTION__);
+
+ pipe = intel_create_softpipe( intel, intelScreen->winsys );
+ break;
+ }
+ }
+
+ pipe->priv = intel;
+
+ intel->st = st_create_context(pipe, visual, st_share);
+
+ return GL_TRUE;
+}
+
+
+void
+intelDestroyContext(__DRIcontextPrivate * driContextPriv)
+{
+ struct intel_context *intel = intel_context(driContextPriv);
+
+ assert(intel); /* should never be null */
+ if (intel) {
+ st_finish(intel->st);
+
+ intel_batchbuffer_free(intel->batch);
+
+ if (intel->last_swap_fence) {
+ driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
+ driFenceUnReference(&intel->last_swap_fence);
+ intel->last_swap_fence = NULL;
+ }
+ if (intel->first_swap_fence) {
+ driFenceFinish(intel->first_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
+ driFenceUnReference(&intel->first_swap_fence);
+ intel->first_swap_fence = NULL;
+ }
+
+ if (intel->intelScreen->dummyContext == intel)
+ intel->intelScreen->dummyContext = NULL;
+
+ st_destroy_context(intel->st);
+ free(intel);
+ }
+}
+
+
+GLboolean
+intelUnbindContext(__DRIcontextPrivate * driContextPriv)
+{
+ struct intel_context *intel = intel_context(driContextPriv);
+ st_flush(intel->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ /* XXX make_current(NULL)? */
+ return GL_TRUE;
+}
+
+
+GLboolean
+intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv)
+{
+ if (driContextPriv) {
+ struct intel_context *intel = intel_context(driContextPriv);
+ struct intel_framebuffer *draw_fb = intel_framebuffer(driDrawPriv);
+ struct intel_framebuffer *read_fb = intel_framebuffer(driReadPriv);
+
+ assert(draw_fb->stfb);
+ assert(read_fb->stfb);
+
+ /* This is for situations in which we need a rendering context but
+ * there may not be any currently bound.
+ */
+ intel->intelScreen->dummyContext = intel;
+
+ st_make_current(intel->st, draw_fb->stfb, read_fb->stfb);
+
+ if ((intel->driDrawable != driDrawPriv) ||
+ (intel->lastStamp != driDrawPriv->lastStamp)) {
+ intel->driDrawable = driDrawPriv;
+ intelUpdateWindowSize(driDrawPriv);
+ intel->lastStamp = driDrawPriv->lastStamp;
+ }
+
+ /* The size of the draw buffer will have been updated above.
+ * If the readbuffer is a different window, check/update its size now.
+ */
+ if (driReadPriv != driDrawPriv) {
+ intelUpdateWindowSize(driReadPriv);
+ }
+
+ }
+ else {
+ st_make_current(NULL, NULL, NULL);
+ }
+
+ return GL_TRUE;
+}
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h
new file mode 100644
index 0000000000..aa9903f274
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.h
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_CONTEXT_H
+#define INTEL_CONTEXT_H
+
+#include <stdint.h>
+#include "drm.h"
+
+#include "pipe/p_debug.h"
+
+#include "intel_screen.h"
+#include "i915_drm.h"
+
+
+struct pipe_context;
+struct intel_context;
+struct _DriBufferObject;
+struct st_context;
+struct egl_drm_device;
+struct egl_drm_context;
+struct egl_drm_frontbuffer;
+
+
+#define INTEL_MAX_FIXUP 64
+
+/**
+ * Intel rendering context, contains a state tracker and intel-specific info.
+ */
+struct intel_context
+{
+ struct st_context *st;
+
+ struct _DriFenceObject *last_swap_fence;
+ struct _DriFenceObject *first_swap_fence;
+
+ struct intel_batchbuffer *batch;
+
+#if 0
+ boolean locked;
+ char *prevLockFile;
+ int prevLockLine;
+#endif
+
+ /* pick this up from the screen instead
+ int drmFd;
+ */
+
+ struct intel_screen *intel_screen;
+
+ uint lastStamp;
+ /* new egl stuff */
+ struct egl_drm_device *egl_device;
+ struct egl_drm_context *egl_context;
+ struct egl_drm_drawable *egl_drawable;
+};
+
+
+
+/**
+ * Intel framebuffer.
+ */
+struct intel_framebuffer
+{
+ struct st_framebuffer *stfb;
+
+ /* other fields TBD */
+ int other;
+ struct _DriBufferObject *front_buffer;
+ struct egl_drm_frontbuffer *front;
+};
+
+
+
+
+/* These are functions now:
+ */
+void LOCK_HARDWARE( struct intel_context *intel );
+void UNLOCK_HARDWARE( struct intel_context *intel );
+
+extern char *__progname;
+
+
+
+/* ================================================================
+ * Debugging:
+ */
+#ifdef DEBUG
+extern int __intel_debug;
+
+#define DEBUG_SWAP 0x1
+#define DEBUG_LOCK 0x2
+#define DEBUG_IOCTL 0x4
+#define DEBUG_BATCH 0x8
+
+#define DBG(flag, ...) do { \
+ if (__intel_debug & (DEBUG_##flag)) \
+ printf(__VA_ARGS__); \
+} while(0)
+
+#else
+#define DBG(flag, ...)
+#endif
+
+
+
+#define PCI_CHIP_845_G 0x2562
+#define PCI_CHIP_I830_M 0x3577
+#define PCI_CHIP_I855_GM 0x3582
+#define PCI_CHIP_I865_G 0x2572
+#define PCI_CHIP_I915_G 0x2582
+#define PCI_CHIP_I915_GM 0x2592
+#define PCI_CHIP_I945_G 0x2772
+#define PCI_CHIP_I945_GM 0x27A2
+#define PCI_CHIP_I945_GME 0x27AE
+#define PCI_CHIP_G33_G 0x29C2
+#define PCI_CHIP_Q35_G 0x29B2
+#define PCI_CHIP_Q33_G 0x29D2
+
+
+#if 0
+/** Cast wrapper */
+static INLINE struct intel_context *
+intel_context(__DRIcontextPrivate *driContextPriv)
+{
+ return (struct intel_context *) driContextPriv->driverPrivate;
+}
+
+
+/** Cast wrapper */
+static INLINE struct intel_framebuffer *
+intel_framebuffer(__DRIdrawablePrivate * driDrawPriv)
+{
+ return (struct intel_framebuffer *) driDrawPriv->driverPrivate;
+}
+#endif
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c
new file mode 100644
index 0000000000..41b7eac4ed
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c
@@ -0,0 +1,621 @@
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "eglconfig.h"
+#include "eglcontext.h"
+#include "egldisplay.h"
+#include "egldriver.h"
+#include "eglglobals.h"
+#include "eglmode.h"
+#include "eglscreen.h"
+#include "eglsurface.h"
+
+#include "intel_egl.h"
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+
+#include "intel_context.h"
+
+#include "ws_dri_bufmgr.h"
+
+#include "intel_winsys.h"
+#include "state_tracker/st_public.h"
+
+struct egl_drm_device* egl_drm_create_device(int drmFD);
+
+struct egl_drm_device*
+egl_drm_create_device(int drmFD)
+{
+ struct egl_drm_device *device = malloc(sizeof(*device));
+ memset(device, 0, sizeof(*device));
+ device->drmFD = drmFD;
+
+ if (!intel_init_driver(device)) {
+ printf("EGL: failed to initalize device\n");
+ free(device);
+ }
+
+ return device;
+}
+
+__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size );
+
+struct drm_driver
+{
+ _EGLDriver base; /* base class/object */
+
+ drmModeResPtr res;
+ struct egl_drm_device *device;
+};
+
+struct drm_surface
+{
+ _EGLSurface base; /* base class/object */
+
+ struct egl_drm_drawable *drawable;
+};
+
+struct drm_context
+{
+ _EGLContext base; /* base class/object */
+
+ struct egl_drm_context *context;
+};
+
+struct drm_screen
+{
+ _EGLScreen base;
+
+ /* backing buffer and crtc */
+ drmBO buffer;
+ drmModeFBPtr fb;
+ uint32_t fbID;
+ drmModeCrtcPtr crtc;
+
+ /* currently only support one output */
+ drmModeOutputPtr output;
+ uint32_t outputID;
+
+ struct drm_mode_modeinfo *mode;
+
+ /* geometry of the screen */
+ struct egl_drm_frontbuffer front;
+};
+
+static void
+drm_update_res(struct drm_driver *drm_drv)
+{
+ drmModeFreeResources(drm_drv->res);
+ drm_drv->res = drmModeGetResources(drm_drv->device->drmFD);
+}
+
+static void
+drm_add_modes_from_output(_EGLScreen *screen, drmModeOutputPtr output)
+{
+ struct drm_mode_modeinfo *m;
+ int i;
+
+ for (i = 0; i < output->count_modes; i++) {
+ m = &output->modes[i];
+ _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
+ }
+}
+
+static EGLBoolean
+drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_screen *screen = NULL;
+ drmModeOutputPtr output = NULL;
+ drmModeResPtr res = NULL;
+ unsigned count_outputs = 0;
+
+ EGLint i;
+ int fd;
+
+ fd = drmOpen("i915", NULL);
+ if (fd < 0) {
+ return EGL_FALSE;
+ }
+
+ drm_drv->device = egl_drm_create_device(fd);
+ if (!drm_drv->device) {
+ drmClose(fd);
+ return EGL_FALSE;
+ }
+
+ drm_update_res(drm_drv);
+ res = drm_drv->res;
+ if (res)
+ count_outputs = res->count_outputs;
+
+ for(i = 0; i < count_outputs; i++) {
+ output = drmModeGetOutput(fd, res->outputs[i]);
+
+ if (!output)
+ continue;
+
+ if (output->connection == DRM_MODE_DISCONNECTED) {
+ drmModeFreeOutput(output);
+ continue;
+ }
+
+ screen = malloc(sizeof(struct drm_screen));
+ memset(screen, 0, sizeof(*screen));
+ screen->outputID = res->outputs[i];
+ screen->output = output;
+ _eglInitScreen(&screen->base);
+ _eglAddScreen(disp, &screen->base);
+ drm_add_modes_from_output(&screen->base, output);
+ }
+
+ /* for now we only have one config */
+ _EGLConfig config;
+ _eglInitConfig(&config, i + 1);
+ _eglSetConfigAttrib(&config, EGL_RED_SIZE, 8);
+ _eglSetConfigAttrib(&config, EGL_GREEN_SIZE, 8);
+ _eglSetConfigAttrib(&config, EGL_BLUE_SIZE, 8);
+ _eglSetConfigAttrib(&config, EGL_ALPHA_SIZE, 8);
+ _eglSetConfigAttrib(&config, EGL_BUFFER_SIZE, 32);
+ _eglSetConfigAttrib(&config, EGL_DEPTH_SIZE, 24);
+ _eglSetConfigAttrib(&config, EGL_STENCIL_SIZE, 8);
+ _eglSetConfigAttrib(&config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
+ _eglAddConfig(disp, &config);
+
+ drv->Initialized = EGL_TRUE;
+
+ *major = 1;
+ *minor = 0;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
+drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+{
+ /* TODO: clean up */
+ free(drv);
+ return EGL_TRUE;
+}
+
+
+static struct drm_context *
+lookup_drm_context(EGLContext context)
+{
+ _EGLContext *c = _eglLookupContext(context);
+ return (struct drm_context *) c;
+}
+
+
+static struct drm_surface *
+lookup_drm_surface(EGLSurface surface)
+{
+ _EGLSurface *s = _eglLookupSurface(surface);
+ return (struct drm_surface *) s;
+}
+
+static struct drm_screen *
+lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
+{
+ _EGLScreen *s = _eglLookupScreen(dpy, screen);
+ return (struct drm_screen *) s;
+}
+
+static __GLcontextModes*
+visual_from_config(_EGLConfig *conf)
+{
+ __GLcontextModes *visual;
+ (void)conf;
+
+ visual = _gl_context_modes_create(1, sizeof(*visual));
+ visual->redBits = 8;
+ visual->greenBits = 8;
+ visual->blueBits = 8;
+ visual->alphaBits = 8;
+
+ visual->rgbBits = 32;
+ visual->doubleBufferMode = 1;
+
+ visual->depthBits = 24;
+ visual->stencilBits = 8;
+
+ return visual;
+}
+
+
+
+static EGLContext
+drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_context *c;
+ struct drm_egl_context *share = NULL;
+ _EGLConfig *conf;
+ int i;
+ int ret;
+ __GLcontextModes *visual;
+ struct egl_drm_context *context;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateContext");
+ return EGL_NO_CONTEXT;
+ }
+
+ for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
+ switch (attrib_list[i]) {
+ /* no attribs defined for now */
+ default:
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
+ return EGL_NO_CONTEXT;
+ }
+ }
+
+ c = (struct drm_context *) calloc(1, sizeof(struct drm_context));
+ if (!c)
+ return EGL_NO_CONTEXT;
+
+ _eglInitContext(drv, dpy, &c->base, config, attrib_list);
+
+ context = malloc(sizeof(*context));
+ memset(context, 0, sizeof(*context));
+
+ if (!context)
+ goto err_c;
+
+ context->device = drm_drv->device;
+ visual = visual_from_config(conf);
+
+ ret = intel_create_context(context, visual, share);
+ free(visual);
+
+ if (!ret)
+ goto err_gl;
+
+ c->context = context;
+
+ /* generate handle and insert into hash table */
+ _eglSaveContext(&c->base);
+ assert(_eglGetContextHandle(&c->base));
+
+ return _eglGetContextHandle(&c->base);
+err_gl:
+ free(context);
+err_c:
+ free(c);
+ return EGL_NO_CONTEXT;
+}
+
+static EGLBoolean
+drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+{
+ struct drm_context *fc = lookup_drm_context(context);
+ _eglRemoveContext(&fc->base);
+ if (fc->base.IsBound) {
+ fc->base.DeletePending = EGL_TRUE;
+ } else {
+ free(fc);
+ }
+ return EGL_TRUE;
+}
+
+
+static EGLSurface
+drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+{
+ return EGL_NO_SURFACE;
+}
+
+
+static EGLSurface
+drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+{
+ return EGL_NO_SURFACE;
+}
+
+static EGLSurface
+drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ int i;
+ int ret;
+ int width = -1;
+ int height = -1;
+ struct drm_surface *surf = NULL;
+ struct egl_drm_drawable *drawable = NULL;
+ __GLcontextModes *visual;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
+ return EGL_NO_CONTEXT;
+ }
+
+ for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
+ switch (attrib_list[i]) {
+ case EGL_WIDTH:
+ width = attrib_list[++i];
+ break;
+ case EGL_HEIGHT:
+ height = attrib_list[++i];
+ break;
+ default:
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+ }
+
+ if (width < 1 || height < 1) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
+ if (!surf)
+ goto err;
+
+ if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
+ goto err_surf;
+
+ drawable = malloc(sizeof(*drawable));
+ memset(drawable, 0, sizeof(*drawable));
+
+ drawable->w = width;
+ drawable->h = height;
+
+ visual = visual_from_config(conf);
+
+ drawable->device = drm_drv->device;
+ ret = intel_create_drawable(drawable, visual);
+ free(visual);
+
+ if (!ret)
+ goto err_draw;
+
+ surf->drawable = drawable;
+
+ _eglSaveSurface(&surf->base);
+ return surf->base.Handle;
+
+err_draw:
+ free(drawable);
+err_surf:
+ free(surf);
+err:
+ return EGL_NO_SURFACE;
+}
+
+static EGLSurface
+drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
+ const EGLint *attrib_list)
+{
+ EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
+
+ return surf;
+}
+
+static struct drm_mode_modeinfo *
+drm_find_mode(drmModeOutputPtr output, _EGLMode *mode)
+{
+ int i;
+ struct drm_mode_modeinfo *m;
+
+ for (i = 0; i < output->count_modes; i++) {
+ m = &output->modes[i];
+ if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
+ break;
+ m = NULL;
+ }
+
+ return m;
+}
+static void
+draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr)
+{
+ int i, j;
+
+ for (i = x; i < x + w; i++)
+ for(j = y; j < y + h; j++)
+ ptr[(i * pitch / 4) + j] = v;
+
+}
+
+static void
+prettyColors(int fd, unsigned int handle, size_t pitch)
+{
+ drmBO bo;
+ unsigned int *ptr;
+ int i;
+
+ drmBOReference(fd, handle, &bo);
+ drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr);
+
+ for (i = 0; i < (bo.size / 4); i++)
+ ptr[i] = 0xFFFFFFFF;
+
+ for (i = 0; i < 4; i++)
+ draw(i * 40, i * 40, 40, 40, pitch, 0, ptr);
+
+
+ draw(200, 100, 40, 40, pitch, 0xff00ff, ptr);
+ draw(100, 200, 40, 40, pitch, 0xff00ff, ptr);
+
+ drmBOUnmap(fd, &bo);
+}
+
+static EGLBoolean
+drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
+ EGLScreenMESA screen,
+ EGLSurface surface, EGLModeMESA m)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_surface *surf = lookup_drm_surface(surface);
+ struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
+ //struct intel_framebuffer *intel_fb = NULL;
+ //struct pipe_surface *front_surf = NULL;
+ _EGLMode *mode = _eglLookupMode(dpy, m);
+ size_t pitch = 2048 * 4;
+ size_t size = mode->Height * pitch;
+ int ret;
+
+ /* TODO if allready shown take down */
+
+ printf("setting mode to %i x %i\n", mode->Width, mode->Height);
+
+ ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT |
+ DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_NO_EVICT,
+ DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
+
+ if (ret) {
+ printf("failed to create framebuffer (ret %d)\n", ret);
+ return EGL_FALSE;
+ }
+
+ prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
+
+ ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height,
+ 32, 32, pitch,
+ scrn->buffer.handle,
+ &scrn->fbID);
+
+ if (ret)
+ goto err_bo;
+
+ scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID);
+ if (!scrn->fb)
+ goto err_bo;
+
+ scrn->mode = drm_find_mode(scrn->output, mode);
+ if (!scrn->mode) {
+ printf("oh noes, no matching mode found\n");
+ goto err_fb;
+ }
+
+ ret = drmModeSetCrtc(
+ drm_drv->device->drmFD,
+ drm_drv->res->crtcs[1],
+ scrn->fbID,
+ 0, 0,
+ &scrn->outputID, 1,
+ scrn->mode);
+
+
+ scrn->front.handle = scrn->buffer.handle;
+ scrn->front.pitch = pitch;
+ scrn->front.width = mode->Width;
+ scrn->front.height = mode->Height;
+
+ intel_bind_frontbuffer(surf->drawable, &scrn->front);
+
+ return EGL_TRUE;
+
+err_fb:
+ /* TODO remove fb */
+
+err_bo:
+ drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer);
+ return EGL_FALSE;
+}
+
+static EGLBoolean
+drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+{
+ struct drm_surface *fs = lookup_drm_surface(surface);
+ _eglRemoveSurface(&fs->base);
+ if (fs->base.IsBound) {
+ fs->base.DeletePending = EGL_TRUE;
+ } else {
+ free(fs);
+ }
+ return EGL_TRUE;
+}
+
+
+
+
+static EGLBoolean
+drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+{
+ struct drm_surface *readSurf = lookup_drm_surface(read);
+ struct drm_surface *drawSurf = lookup_drm_surface(draw);
+ struct drm_context *ctx = lookup_drm_context(context);
+ EGLBoolean b;
+
+ b = _eglMakeCurrent(drv, dpy, draw, read, context);
+ if (!b)
+ return EGL_FALSE;
+
+ /* XXX this is where we'd do the hardware context switch */
+ (void) drawSurf;
+ (void) readSurf;
+ (void) ctx;
+
+ intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+{
+ struct drm_surface *surf = lookup_drm_surface(draw);
+ if (!surf)
+ return EGL_FALSE;
+
+ /* error checking */
+ if (!_eglSwapBuffers(drv, dpy, draw))
+ return EGL_FALSE;
+
+ intel_swap_buffers(surf->drawable);
+ return EGL_TRUE;
+}
+
+
+/**
+ * The bootstrap function. Return a new drm_driver object and
+ * plug in API functions.
+ */
+_EGLDriver *
+_eglMain(_EGLDisplay *dpy, const char *args)
+{
+ struct drm_driver *drm;
+
+ drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
+ if (!drm) {
+ return NULL;
+ }
+
+ /* First fill in the dispatch table with defaults */
+ _eglInitDriverFallbacks(&drm->base);
+ /* then plug in our Drm-specific functions */
+ drm->base.API.Initialize = drm_initialize;
+ drm->base.API.Terminate = drm_terminate;
+ drm->base.API.CreateContext = drm_create_context;
+ drm->base.API.MakeCurrent = drm_make_current;
+ drm->base.API.CreateWindowSurface = drm_create_window_surface;
+ drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
+ drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
+ drm->base.API.DestroySurface = drm_destroy_surface;
+ drm->base.API.DestroyContext = drm_destroy_context;
+ drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
+ drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
+ drm->base.API.SwapBuffers = drm_swap_buffers;
+
+ /* enable supported extensions */
+ drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
+ drm->base.Extensions.MESA_copy_context = EGL_TRUE;
+
+ return &drm->base;
+}
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h
new file mode 100644
index 0000000000..18e84e8eea
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h
@@ -0,0 +1,42 @@
+
+#ifndef _INTEL_EGL_H_
+#define _INTEL_EGL_H_
+
+struct egl_drm_device
+{
+ void *priv;
+ int drmFD;
+};
+
+struct egl_drm_context
+{
+ void *priv;
+ struct egl_drm_device *device;
+};
+
+struct egl_drm_drawable
+{
+ void *priv;
+ struct egl_drm_device *device;
+ size_t h;
+ size_t w;
+};
+
+struct egl_drm_frontbuffer
+{
+ uint32_t handle;
+ uint32_t pitch;
+ uint32_t width;
+ uint32_t height;
+};
+
+#include "GL/internal/glcore.h"
+
+int intel_init_driver(struct egl_drm_device *device);
+int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
+int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
+void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read);
+void intel_swap_buffers(struct egl_drm_drawable *draw);
+void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front);
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_lock.c b/src/gallium/winsys/egl_drm/intel/intel_lock.c
new file mode 100644
index 0000000000..cec83c7585
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_lock.c
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "main/glheader.h"
+#include "glapi/glthread.h"
+#include <GL/internal/glcore.h>
+#include "state_tracker/st_public.h"
+#include "intel_context.h"
+
+#if 0
+
+_glthread_DECLARE_STATIC_MUTEX( lockMutex );
+
+
+static void
+intelContendedLock(struct intel_context *intel, uint flags)
+{
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ __DRIscreenPrivate *sPriv = intel->driScreen;
+ struct intel_screen *intelScreen = intel_screen(sPriv);
+ drmI830Sarea *sarea = intel->sarea;
+
+ drmGetLock(intel->driFd, intel->hHWContext, flags);
+
+ DBG(LOCK, "%s - got contended lock\n", __progname);
+
+ /* If the window moved, may need to set a new cliprect now.
+ *
+ * NOTE: This releases and regains the hw lock, so all state
+ * checking must be done *after* this call:
+ */
+ if (dPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
+
+ if (sarea->width != intelScreen->front.width ||
+ sarea->height != intelScreen->front.height) {
+
+ intelUpdateScreenRotation(sPriv, sarea);
+ }
+}
+
+
+/* Lock the hardware and validate our state.
+ */
+void LOCK_HARDWARE( struct intel_context *intel )
+{
+ char __ret = 0;
+
+ _glthread_LOCK_MUTEX(lockMutex);
+ assert(!intel->locked);
+
+ DRM_CAS(intel->driHwLock, intel->hHWContext,
+ (DRM_LOCK_HELD|intel->hHWContext), __ret);
+
+ if (__ret)
+ intelContendedLock( intel, 0 );
+
+ DBG(LOCK, "%s - locked\n", __progname);
+
+ intel->locked = 1;
+}
+
+
+/* Unlock the hardware using the global current context
+ */
+void UNLOCK_HARDWARE( struct intel_context *intel )
+{
+ assert(intel->locked);
+ intel->locked = 0;
+
+ DRM_UNLOCK(intel->driFd, intel->driHwLock, intel->hHWContext);
+
+ _glthread_UNLOCK_MUTEX(lockMutex);
+
+ DBG(LOCK, "%s - unlocked\n", __progname);
+}
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_reg.h b/src/gallium/winsys/egl_drm/intel/intel_reg.h
new file mode 100644
index 0000000000..f37c24fda9
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_reg.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef _INTEL_REG_H_
+#define _INTEL_REG_H_
+
+
+#define BR00_BITBLT_CLIENT 0x40000000
+#define BR00_OP_COLOR_BLT 0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR13_SOLID_PATTERN 0x80000000
+
+#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
+#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
+#define XY_COLOR_BLT_WRITE_RGB (1<<20)
+
+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+
+#define MI_WAIT_FOR_EVENT ((0x3<<23))
+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+
+#define MI_BATCH_BUFFER_END (0xA<<23)
+
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_screen.c
new file mode 100644
index 0000000000..38c4098087
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_screen.c
@@ -0,0 +1,680 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "utils.h"
+#include "vblank.h"
+#include "xmlpool.h"
+
+#include "intel_context.h"
+#include "intel_screen.h"
+#include "intel_batchbuffer.h"
+//#include "intel_batchpool.h"
+#include "intel_swapbuffers.h"
+#include "intel_winsys.h"
+
+#include "ws_dri_bufpool.h"
+
+#include "pipe/p_context.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_cb_fbo.h"
+#include "intel_egl.h"
+
+static boolean
+intel_create_pools(struct intel_screen *intel_screen)
+{
+ if (intel_screen->havePools)
+ return GL_TRUE;
+
+ intel_screen->mgr = driFenceMgrTTMInit(intel_screen->device->drmFD);
+ if (!intel_screen->mgr) {
+ fprintf(stderr, "Failed to create fence manager.\n");
+ return FALSE;
+ }
+
+ intel_screen->fMan = driInitFreeSlabManager(10, 10);
+ if (!intel_screen->fMan) {
+ fprintf(stderr, "Failed to create free slab manager.\n");
+ return FALSE;
+ }
+
+ intel_screen->staticPool = driDRMPoolInit(intel_screen->device->drmFD);
+ intel_screen->batchPool = driSlabPoolInit(intel_screen->device->drmFD,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ 4096, //intelScreen->maxBatchSize,
+ 1, 40, 16*16384, 0,
+ intel_screen->fMan);
+
+ intel_screen->havePools = GL_TRUE;
+
+ return GL_TRUE;
+}
+
+extern const struct dri_extension card_extensions[];
+
+int
+intel_init_driver(struct egl_drm_device *device)
+{
+ struct intel_screen *intel_screen;
+
+ /* Allocate the private area */
+ intel_screen = CALLOC_STRUCT(intel_screen);
+ if (!intel_screen)
+ return FALSE;
+
+ device->priv = (void *)intel_screen;
+ intel_screen->device = device;
+
+ if (!intel_create_pools(intel_screen))
+ return FALSE;
+
+ intel_screen->batch = intel_batchbuffer_alloc(intel_screen);
+
+ intel_screen->winsys = intel_create_pipe_winsys(device->drmFD, intel_screen->fMan);
+
+ /* hack */
+ driInitExtensions(NULL, card_extensions, GL_FALSE);
+
+ return TRUE;
+}
+
+int
+intel_create_drawable(struct egl_drm_drawable *drawable,
+ const __GLcontextModes * visual)
+{
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+ struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer);
+
+ if (!intelfb)
+ return GL_FALSE;
+
+ if (visual->redBits == 5)
+ colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
+ else
+ colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ if (visual->depthBits == 16)
+ depthFormat = PIPE_FORMAT_Z16_UNORM;
+ else if (visual->depthBits == 24)
+ depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ depthFormat = PIPE_FORMAT_NONE;
+
+ if (visual->stencilBits == 8)
+ stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ stencilFormat = PIPE_FORMAT_NONE;
+
+ intelfb->stfb = st_create_framebuffer(visual,
+ colorFormat,
+ depthFormat,
+ stencilFormat,
+ drawable->w,
+ drawable->h,
+ (void*) intelfb);
+
+ if (!intelfb->stfb) {
+ free(intelfb);
+ return GL_FALSE;
+ }
+
+ drawable->priv = (void *) intelfb;
+ return GL_TRUE;
+}
+
+#if 0
+PUBLIC const char __driConfigOptions[] =
+ DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
+ DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
+ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
+ DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
+ DRI_CONF_FORCE_S3TC_ENABLE(false)
+ DRI_CONF_ALLOW_LARGE_TEXTURES(1)
+ DRI_CONF_SECTION_END DRI_CONF_END;
+
+const uint __driNConfigOptions = 4;
+
+#ifdef USE_NEW_INTERFACE
+static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
+#endif /*USE_NEW_INTERFACE */
+
+extern const struct dri_extension card_extensions[];
+
+
+
+
+static void
+intelPrintDRIInfo(struct intel_screen * intelScreen,
+ __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv)
+{
+ fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n",
+ intelScreen->front.size, intelScreen->front.offset,
+ intelScreen->front.pitch);
+ fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem);
+}
+
+static void
+intelPrintSAREA(const drmI830Sarea * sarea)
+{
+ fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width,
+ sarea->height);
+ fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch);
+ fprintf(stderr,
+ "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->front_offset, sarea->front_size,
+ (unsigned) sarea->front_handle);
+ fprintf(stderr,
+ "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->back_offset, sarea->back_size,
+ (unsigned) sarea->back_handle);
+ fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->depth_offset, sarea->depth_size,
+ (unsigned) sarea->depth_handle);
+ fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n",
+ sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle);
+ fprintf(stderr, "SAREA: rotation: %d\n", sarea->rotation);
+ fprintf(stderr,
+ "SAREA: rotated offset: 0x%08x size: 0x%x\n",
+ sarea->rotated_offset, sarea->rotated_size);
+ fprintf(stderr, "SAREA: rotated pitch: %d\n", sarea->rotated_pitch);
+}
+
+/**
+ * Use the information in the sarea to update the screen parameters
+ * related to screen rotation. Needs to be called locked.
+ */
+void
+intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea)
+{
+ struct intel_screen *intelScreen = intel_screen(sPriv);
+
+ if (intelScreen->front.map) {
+ drmUnmap(intelScreen->front.map, intelScreen->front.size);
+ intelScreen->front.map = NULL;
+ }
+
+ if (intelScreen->front.buffer)
+ driDeleteBuffers(1, &intelScreen->front.buffer);
+
+ intelScreen->front.width = sarea->width;
+ intelScreen->front.height = sarea->height;
+ intelScreen->front.offset = sarea->front_offset;
+ intelScreen->front.pitch = sarea->pitch * intelScreen->front.cpp;
+ intelScreen->front.size = sarea->front_size;
+ intelScreen->front.handle = sarea->front_handle;
+
+ assert( sarea->front_size >=
+ intelScreen->front.pitch * intelScreen->front.height );
+
+#if 0 /* JB not important */
+ if (!sarea->front_handle)
+ return;
+
+ if (drmMap(sPriv->fd,
+ sarea->front_handle,
+ intelScreen->front.size,
+ (drmAddress *) & intelScreen->front.map) != 0) {
+ fprintf(stderr, "drmMap(frontbuffer) failed!\n");
+ return;
+ }
+#endif
+
+#if 0 /* JB */
+ if (intelScreen->staticPool) {
+ driGenBuffers(intelScreen->staticPool, "static region", 1,
+ &intelScreen->front.buffer, 64,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_NO_MOVE |
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0);
+
+ driBOSetStatic(intelScreen->front.buffer,
+ intelScreen->front.offset,
+ intelScreen->front.pitch * intelScreen->front.height,
+ intelScreen->front.map, 0);
+ }
+#else
+ if (intelScreen->staticPool) {
+ if (intelScreen->front.buffer)
+ driBOUnReference(intelScreen->front.buffer);
+ driGenBuffers(intelScreen->staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
+ driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle);
+ }
+#endif
+}
+
+
+boolean
+intelCreatePools(__DRIscreenPrivate * sPriv)
+{
+ //unsigned batchPoolSize = 1024*1024;
+ struct intel_screen *intelScreen = intel_screen(sPriv);
+
+ if (intelScreen->havePools)
+ return GL_TRUE;
+
+#if 0 /* ZZZ JB fix this */
+ intelScreen->staticPool = driDRMStaticPoolInit(sPriv->fd);
+ if (!intelScreen->staticPool)
+ return GL_FALSE;
+
+ batchPoolSize /= BATCH_SZ;
+ intelScreen->batchPool = driBatchPoolInit(sPriv->fd,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT |
+ DRM_BO_FLAG_MEM_LOCAL,
+ BATCH_SZ,
+ batchPoolSize, 5);
+ if (!intelScreen->batchPool) {
+ fprintf(stderr, "Failed to initialize batch pool - possible incorrect agpgart installed\n");
+ return GL_FALSE;
+ }
+#else
+ intelScreen->staticPool = driDRMPoolInit(sPriv->fd);
+ intelScreen->batchPool = driSlabPoolInit(sPriv->fd,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_EXE |
+ DRM_BO_FLAG_MEM_TT,
+ 4096, //intelScreen->maxBatchSize,
+ 1, 40, 16*16384, 0,
+ intelScreen->fMan);
+#endif
+ intelScreen->havePools = GL_TRUE;
+
+ //intelUpdateScreenRotation(sPriv, intelScreen->sarea);
+
+ return GL_TRUE;
+}
+
+
+static boolean
+intelInitDriver(__DRIscreenPrivate * sPriv)
+{
+ struct intel_screen *intelScreen;
+ I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv;
+
+ PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
+ (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->
+ getProcAddress("glxEnableExtension"));
+ void *const psc = sPriv->psc->screenConfigs;
+
+ if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
+ fprintf(stderr,
+ "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n");
+ return GL_FALSE;
+ }
+
+ /* Allocate the private area */
+ intelScreen = CALLOC_STRUCT(intel_screen);
+ if (!intelScreen)
+ return GL_FALSE;
+
+ /* parse information in __driConfigOptions */
+ driParseOptionInfo(&intelScreen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ sPriv->private = (void *) intelScreen;
+
+ intelScreen->sarea = (drmI830Sarea *) (((GLubyte *) sPriv->pSAREA) +
+ gDRIPriv->sarea_priv_offset);
+ intelScreen->deviceID = gDRIPriv->deviceID;
+ intelScreen->front.cpp = gDRIPriv->cpp;
+ intelScreen->drmMinor = sPriv->drmMinor;
+
+
+ assert(gDRIPriv->bitsPerPixel == 16 ||
+ gDRIPriv->bitsPerPixel == 32);
+
+
+ intelUpdateScreenRotation(sPriv, intelScreen->sarea);
+
+ if (0)
+ intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
+
+ if (glx_enable_extension != NULL) {
+ (*glx_enable_extension) (psc, "GLX_SGI_swap_control");
+ (*glx_enable_extension) (psc, "GLX_SGI_video_sync");
+ (*glx_enable_extension) (psc, "GLX_MESA_swap_control");
+ (*glx_enable_extension) (psc, "GLX_MESA_swap_frame_usage");
+ (*glx_enable_extension) (psc, "GLX_SGI_make_current_read");
+ }
+
+
+
+#if 1 // ZZZ JB
+ intelScreen->mgr = driFenceMgrTTMInit(sPriv->fd);
+ if (!intelScreen->mgr) {
+ fprintf(stderr, "Failed to create fence manager.\n");
+ return GL_FALSE;
+ }
+
+ intelScreen->fMan = driInitFreeSlabManager(10, 10);
+ if (!intelScreen->fMan) {
+ fprintf(stderr, "Failed to create free slab manager.\n");
+ return GL_FALSE;
+ }
+
+ if (!intelCreatePools(sPriv))
+ return GL_FALSE;
+#endif
+
+ intelScreen->winsys = intel_create_pipe_winsys(sPriv->fd, intelScreen->fMan);
+
+ return GL_TRUE;
+}
+
+
+static void
+intelDestroyScreen(__DRIscreenPrivate * sPriv)
+{
+ struct intel_screen *intelScreen = intel_screen(sPriv);
+
+ /* intelUnmapScreenRegions(intelScreen); */
+
+ if (intelScreen->havePools) {
+ driPoolTakeDown(intelScreen->staticPool);
+ driPoolTakeDown(intelScreen->batchPool);
+ }
+ FREE(intelScreen);
+ sPriv->private = NULL;
+}
+
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+static boolean
+intelCreateBuffer(__DRIscreenPrivate * driScrnPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ const __GLcontextModes * visual, boolean isPixmap)
+{
+ if (isPixmap) {
+ return GL_FALSE; /* not implemented */
+ }
+ else {
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+ struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer);
+
+ if (!intelfb)
+ return GL_FALSE;
+
+ if (visual->redBits == 5)
+ colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
+ else
+ colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ if (visual->depthBits == 16)
+ depthFormat = PIPE_FORMAT_Z16_UNORM;
+ else if (visual->depthBits == 24)
+ depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ depthFormat = PIPE_FORMAT_NONE;
+
+ if (visual->stencilBits == 8)
+ stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ stencilFormat = PIPE_FORMAT_NONE;
+
+ intelfb->stfb = st_create_framebuffer(visual,
+ colorFormat,
+ depthFormat,
+ stencilFormat,
+ driDrawPriv->w,
+ driDrawPriv->h,
+ (void*) intelfb);
+ if (!intelfb->stfb) {
+ free(intelfb);
+ return GL_FALSE;
+ }
+
+ driDrawPriv->driverPrivate = (void *) intelfb;
+ return GL_TRUE;
+ }
+}
+
+static void
+intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
+{
+ struct intel_framebuffer *intelfb = intel_framebuffer(driDrawPriv);
+ assert(intelfb->stfb);
+ st_unreference_framebuffer(&intelfb->stfb);
+ free(intelfb);
+}
+
+
+/**
+ * Get information about previous buffer swaps.
+ */
+static int
+intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
+{
+ if ((dPriv == NULL) || (dPriv->driverPrivate == NULL)
+ || (sInfo == NULL)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void
+intelSetTexOffset(__DRIcontext *pDRICtx, int texname,
+ unsigned long long offset, int depth, uint pitch)
+{
+ abort();
+#if 0
+ struct intel_context *intel = (struct intel_context*)
+ ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate;
+ struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
+ struct st_texture_object *stObj = st_texture_object(tObj);
+
+ if (!stObj)
+ return;
+
+ if (stObj->pt)
+ st->pipe->texture_release(intel->st->pipe, &stObj->pt);
+
+ stObj->imageOverride = GL_TRUE;
+ stObj->depthOverride = depth;
+ stObj->pitchOverride = pitch;
+
+ if (offset)
+ stObj->textureOffset = offset;
+#endif
+}
+
+
+static const struct __DriverAPIRec intelAPI = {
+ .InitDriver = intelInitDriver,
+ .DestroyScreen = intelDestroyScreen,
+ .CreateContext = intelCreateContext,
+ .DestroyContext = intelDestroyContext,
+ .CreateBuffer = intelCreateBuffer,
+ .DestroyBuffer = intelDestroyBuffer,
+ .SwapBuffers = intelSwapBuffers,
+ .MakeCurrent = intelMakeCurrent,
+ .UnbindContext = intelUnbindContext,
+ .GetSwapInfo = intelGetSwapInfo,
+ .GetMSC = driGetMSC32,
+ .WaitForMSC = driWaitForMSC32,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL,
+ .CopySubBuffer = intelCopySubBuffer,
+ .setTexOffset = intelSetTexOffset,
+};
+
+
+static __GLcontextModes *
+intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
+ unsigned stencil_bits, boolean have_back_buffer)
+{
+ __GLcontextModes *modes;
+ __GLcontextModes *m;
+ unsigned num_modes;
+ unsigned depth_buffer_factor;
+ unsigned back_buffer_factor;
+ GLenum fb_format;
+ GLenum fb_type;
+
+ /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
+ * support pageflipping at all.
+ */
+ static const GLenum back_buffer_modes[] = {
+ GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+ };
+
+ u_int8_t depth_bits_array[3];
+ u_int8_t stencil_bits_array[3];
+
+
+ depth_bits_array[0] = 0;
+ depth_bits_array[1] = depth_bits;
+ depth_bits_array[2] = depth_bits;
+
+ /* Just like with the accumulation buffer, always provide some modes
+ * with a stencil buffer. It will be a sw fallback, but some apps won't
+ * care about that.
+ */
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 0;
+ if (depth_bits == 24)
+ stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+ stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits;
+
+ depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
+ back_buffer_factor = (have_back_buffer) ? 3 : 1;
+
+ num_modes = depth_buffer_factor * back_buffer_factor * 4;
+
+ if (pixel_bits == 16) {
+ fb_format = GL_RGB;
+ fb_type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+ else {
+ fb_format = GL_BGRA;
+ fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ modes =
+ (*dri_interface->createContextModes) (num_modes,
+ sizeof(__GLcontextModes));
+ m = modes;
+ if (!driFillInModes(&m, fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor, back_buffer_modes,
+ back_buffer_factor, GLX_TRUE_COLOR)) {
+ fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+ __LINE__);
+ return NULL;
+ }
+ if (!driFillInModes(&m, fb_format, fb_type,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor, back_buffer_modes,
+ back_buffer_factor, GLX_DIRECT_COLOR)) {
+ fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+ __LINE__);
+ return NULL;
+ }
+
+ /* Mark the visual as slow if there are "fake" stencil bits.
+ */
+ for (m = modes; m != NULL; m = m->next) {
+ if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
+ m->visualRating = GLX_SLOW_CONFIG;
+ }
+ }
+
+ return modes;
+}
+
+
+/**
+ * This is the bootstrap function for the driver. libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
+ * failure.
+ */
+PUBLIC void *
+__driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn,
+ __DRIscreen * psc,
+ const __GLcontextModes * modes,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drmAddress pSAREA, int fd,
+ int internal_api_version,
+ const __DRIinterfaceMethods * interface,
+ __GLcontextModes ** driver_modes)
+{
+ __DRIscreenPrivate *psp;
+ static const __DRIversion ddx_expected = { 1, 7, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 1, 7, 0 };
+
+ dri_interface = interface;
+
+ if (!driCheckDriDdxDrmVersions2("i915",
+ dri_version, &dri_expected,
+ ddx_version, &ddx_expected,
+ drm_version, &drm_expected)) {
+ return NULL;
+ }
+
+ psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
+ ddx_version, dri_version, drm_version,
+ frame_buffer, pSAREA, fd,
+ internal_api_version, &intelAPI);
+
+ if (psp != NULL) {
+ I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv;
+ *driver_modes = intelFillInModes(dri_priv->cpp * 8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8, 1);
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create
+ * is called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ driInitExtensions(NULL, card_extensions, GL_FALSE);
+ }
+
+ return (void *) psp;
+}
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_screen.h
new file mode 100644
index 0000000000..e8c1cdfca4
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_screen.h
@@ -0,0 +1,133 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef _INTEL_SCREEN_H_
+#define _INTEL_SCREEN_H_
+
+#include "ws_dri_bufpool.h"
+
+#include "pipe/p_compiler.h"
+
+struct egl_drm_device *device;
+
+struct intel_screen
+{
+#if 0
+ struct {
+ drm_handle_t handle;
+
+ /* We create a static dri buffer for the frontbuffer.
+ */
+ struct _DriBufferObject *buffer;
+
+ char *map; /* memory map */
+ int offset; /* from start of video mem, in bytes */
+ int pitch; /* row stride, in bytes */
+ int width;
+ int height;
+ int size;
+ int cpp; /* for front and back buffers */
+ } front;
+#endif
+
+ int drmFB;
+
+#if 0
+ int deviceID;
+ int drmMinor;
+
+
+ drmI830Sarea *sarea;*/
+
+
+ /**
+ * Configuration cache with default values for all contexts
+ */
+ driOptionCache optionCache;
+#endif
+
+ struct _DriBufferPool *batchPool;
+ struct _DriBufferPool *staticPool; /** for the X screen/framebuffer */
+ boolean havePools;
+
+#if 0
+ /**
+ * Temporary(?) context to use for SwapBuffers or other situations in
+ * which we need a rendering context, but none is currently bound.
+ */
+ struct intel_context *dummyContext;
+#endif
+
+ /*
+ * New stuff form the i915tex integration
+ */
+ struct _DriFenceMgr *mgr;
+ struct _DriFreeSlabManager *fMan;
+ unsigned batch_id;
+
+ struct pipe_winsys *winsys;
+ struct egl_drm_device *device;
+
+ /* batch buffer used for swap buffers */
+ struct intel_batchbuffer *batch;
+};
+
+
+
+/** cast wrapper */
+#if 0
+static INLINE struct intel_screen *
+intel_screen(__DRIscreenPrivate *sPriv)
+{
+ return (struct intel_screen *) sPriv->private;
+}
+
+
+extern void
+intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea);
+
+
+extern void intelDestroyContext(__DRIcontextPrivate * driContextPriv);
+
+extern boolean intelUnbindContext(__DRIcontextPrivate * driContextPriv);
+
+extern boolean
+intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv);
+
+
+extern boolean
+intelCreatePools(__DRIscreenPrivate *sPriv);
+
+extern boolean
+intelCreateContext(const __GLcontextModes * visual,
+ __DRIcontextPrivate * driContextPriv,
+ void *sharedContextPrivate);
+
+#endif
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
new file mode 100644
index 0000000000..1ce4b2754a
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
@@ -0,0 +1,327 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_swapbuffers.h"
+#include "intel_batchbuffer.h"
+#include "intel_reg.h"
+#include "intel_winsys.h"
+
+#include "pipe/p_context.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_fbo.h"
+#include "intel_egl.h"
+
+
+static void
+intel_display_surface(struct egl_drm_drawable *draw,
+ struct pipe_surface *surf);
+
+void intel_swap_buffers(struct egl_drm_drawable *draw)
+{
+ struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
+ struct pipe_surface *back_surf;
+
+ assert(intel_fb);
+ assert(intel_fb->stfb);
+
+ back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT);
+ if (back_surf) {
+ st_notify_swapbuffers(intel_fb->stfb);
+ intel_display_surface(draw, back_surf);
+ st_notify_swapbuffers_complete(intel_fb->stfb);
+ }
+}
+
+static void
+intel_display_surface(struct egl_drm_drawable *draw,
+ struct pipe_surface *surf)
+{
+ struct intel_screen *intel = (struct intel_screen *)draw->device->priv;
+ struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
+ struct _DriFenceObject *fence;
+
+ //const int srcWidth = surf->width;
+ //const int srcHeight = surf->height;
+ const int srcPitch = surf->pitch;
+
+ const int dstWidth = intel_fb->front->width;
+ const int dstHeight = intel_fb->front->height;
+ const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp;
+
+ const int cpp = 4;//intel_fb->front->cpp;
+
+ int BR13, CMD;
+ //int i;
+
+
+ BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+ CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+
+ printf("srcPitch: %u, dstWidth: %u, dstHeight: %u, dstPitch: %u, cpp: %u\n", srcPitch, dstWidth, dstHeight, dstPitch, cpp);
+ BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+ OUT_BATCH(CMD);
+ OUT_BATCH(BR13);
+ OUT_BATCH((0 << 16) | 0);
+ OUT_BATCH((dstHeight << 16) | dstWidth);
+
+ OUT_RELOC(intel_fb->front_buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+
+ OUT_BATCH((0 << 16) | 0);
+ OUT_BATCH((srcPitch * cpp) & 0xffff);
+ OUT_RELOC(dri_bo(surf->buffer),
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
+
+ ADVANCE_BATCH();
+
+ fence = intel_batchbuffer_flush(intel->batch);
+ driFenceUnReference(&fence);
+ intel_batchbuffer_finish(intel->batch);
+}
+
+#if 0
+/**
+ * Display a colorbuffer surface in an X window.
+ * Used for SwapBuffers and flushing front buffer rendering.
+ *
+ * \param dPriv the window/drawable to display into
+ * \param surf the surface to display
+ * \param rect optional subrect of surface to display (may be NULL).
+ */
+void
+intelDisplaySurface(__DRIdrawablePrivate *dPriv,
+ struct pipe_surface *surf,
+ const drm_clip_rect_t *rect)
+{
+ struct intel_screen *intelScreen = intel_screen(dPriv->driScreenPriv);
+ //struct intel_context *intel = intelScreen->dummyContext;
+
+ DBG(SWAP, "%s\n", __FUNCTION__);
+
+#if 0
+ if (!intel) {
+ /* XXX this is where some kind of extra/meta context could be useful */
+ return;
+ }
+#endif
+
+ if (intel->last_swap_fence) {
+ driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, TRUE);
+ driFenceUnReference(&intel->last_swap_fence);
+ intel->last_swap_fence = NULL;
+ }
+ intel->last_swap_fence = intel->first_swap_fence;
+ intel->first_swap_fence = NULL;
+
+ /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
+ * should work regardless.
+ */
+ LOCK_HARDWARE(intel);
+ /* if this drawable isn't currently bound the LOCK_HARDWARE done on the
+ * current context (which is what intelScreenContext should return) might
+ * not get a contended lock and thus cliprects not updated (tests/manywin)
+ */
+ if (intel_context(dPriv->driContextPriv) != intel)
+ DRI_VALIDATE_DRAWABLE_INFO(intel->driScreen, dPriv);
+
+
+ if (dPriv && dPriv->numClipRects) {
+ const int srcWidth = surf->width;
+ const int srcHeight = surf->height;
+ const int nbox = dPriv->numClipRects;
+ const drm_clip_rect_t *pbox = dPriv->pClipRects;
+ const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
+ const int cpp = intelScreen->front.cpp;
+ const int srcpitch = surf->pitch;
+ int BR13, CMD;
+ int i;
+
+ ASSERT(surf->buffer);
+ ASSERT(surf->cpp == cpp);
+
+ DBG(SWAP, "screen pitch %d src surface pitch %d\n",
+ pitch, surf->pitch);
+
+ if (cpp == 2) {
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+ CMD = XY_SRC_COPY_BLT_CMD;
+ }
+ else {
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+ CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+ }
+
+ for (i = 0; i < nbox; i++, pbox++) {
+ drm_clip_rect_t box;
+ drm_clip_rect_t sbox;
+
+ if (pbox->x1 > pbox->x2 ||
+ pbox->y1 > pbox->y2 ||
+ pbox->x2 > intelScreen->front.width ||
+ pbox->y2 > intelScreen->front.height) {
+ /* invalid cliprect, skip it */
+ continue;
+ }
+
+ box = *pbox;
+
+ if (rect) {
+ /* intersect cliprect with user-provided src rect */
+ drm_clip_rect_t rrect;
+
+ rrect.x1 = dPriv->x + rect->x1;
+ rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y;
+ rrect.x2 = rect->x2 + rrect.x1;
+ rrect.y2 = rect->y2 + rrect.y1;
+ if (rrect.x1 > box.x1)
+ box.x1 = rrect.x1;
+ if (rrect.y1 > box.y1)
+ box.y1 = rrect.y1;
+ if (rrect.x2 < box.x2)
+ box.x2 = rrect.x2;
+ if (rrect.y2 < box.y2)
+ box.y2 = rrect.y2;
+
+ if (box.x1 > box.x2 || box.y1 > box.y2)
+ continue;
+ }
+
+ /* restrict blit to size of actually rendered area */
+ if (box.x2 - box.x1 > srcWidth)
+ box.x2 = srcWidth + box.x1;
+ if (box.y2 - box.y1 > srcHeight)
+ box.y2 = srcHeight + box.y1;
+
+ DBG(SWAP, "box x1 x2 y1 y2 %d %d %d %d\n",
+ box.x1, box.x2, box.y1, box.y2);
+
+ sbox.x1 = box.x1 - dPriv->x;
+ sbox.y1 = box.y1 - dPriv->y;
+
+ assert(box.x1 < box.x2);
+ assert(box.y1 < box.y2);
+
+ /* XXX this could be done with pipe->surface_copy() */
+ BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+ OUT_BATCH(CMD);
+ OUT_BATCH(BR13);
+ OUT_BATCH((box.y1 << 16) | box.x1);
+ OUT_BATCH((box.y2 << 16) | box.x2);
+
+ OUT_RELOC(intelScreen->front.buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+ OUT_BATCH((sbox.y1 << 16) | sbox.x1);
+ OUT_BATCH((srcpitch * cpp) & 0xffff);
+ OUT_RELOC(dri_bo(surf->buffer),
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
+
+ ADVANCE_BATCH();
+ }
+
+ if (intel->first_swap_fence)
+ driFenceUnReference(&intel->first_swap_fence);
+ intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
+ }
+
+ UNLOCK_HARDWARE(intel);
+
+ if (intel->lastStamp != dPriv->lastStamp) {
+ intelUpdateWindowSize(dPriv);
+ intel->lastStamp = dPriv->lastStamp;
+ }
+}
+
+
+
+/**
+ * This will be called whenever the currently bound window is moved/resized.
+ */
+void
+intelUpdateWindowSize(__DRIdrawablePrivate *dPriv)
+{
+ struct intel_framebuffer *intelfb = intel_framebuffer(dPriv);
+ assert(intelfb->stfb);
+ st_resize_framebuffer(intelfb->stfb, dPriv->w, dPriv->h);
+}
+
+
+
+void
+intelSwapBuffers(__DRIdrawablePrivate * dPriv)
+{
+ struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
+ struct pipe_surface *back_surf;
+
+ assert(intel_fb);
+ assert(intel_fb->stfb);
+
+ back_surf = st_get_framebuffer_surface(intel_fb->stfb,
+ ST_SURFACE_BACK_LEFT);
+ if (back_surf) {
+ st_notify_swapbuffers(intel_fb->stfb);
+ intelDisplaySurface(dPriv, back_surf, NULL);
+ st_notify_swapbuffers_complete(intel_fb->stfb);
+ }
+}
+
+
+/**
+ * Called via glXCopySubBufferMESA() to copy a subrect of the back
+ * buffer to the front buffer/screen.
+ */
+void
+intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
+{
+ struct intel_framebuffer *intel_fb = intel_framebuffer(dPriv);
+ struct pipe_surface *back_surf;
+
+ assert(intel_fb);
+ assert(intel_fb->stfb);
+
+ back_surf = st_get_framebuffer_surface(intel_fb->stfb,
+ ST_SURFACE_BACK_LEFT);
+ if (back_surf) {
+ drm_clip_rect_t rect;
+ rect.x1 = x;
+ rect.y1 = y;
+ rect.x2 = w;
+ rect.y2 = h;
+
+ st_notify_swapbuffers(intel_fb->stfb);
+ intelDisplaySurface(dPriv, back_surf, &rect);
+ }
+}
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h
new file mode 100644
index 0000000000..904f26732e
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_SWAPBUFFERS_H
+#define INTEL_SWAPBUFFERS_H
+
+
+struct pipe_surface;
+
+#if 0
+extern void intelDisplaySurface(__DRIdrawablePrivate * dPriv,
+ struct pipe_surface *surf,
+ const drm_clip_rect_t * rect);
+
+extern void intelSwapBuffers(__DRIdrawablePrivate * dPriv);
+
+extern void intelCopySubBuffer(__DRIdrawablePrivate * dPriv,
+ int x, int y, int w, int h);
+
+extern void intelUpdateWindowSize(__DRIdrawablePrivate *dPriv);
+#endif
+
+#endif /* INTEL_SWAPBUFFERS_H */
diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys.h b/src/gallium/winsys/egl_drm/intel/intel_winsys.h
new file mode 100644
index 0000000000..d0a319f9a4
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_winsys.h
@@ -0,0 +1,73 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_WINSYS_H
+#define INTEL_WINSYS_H
+
+#include "pipe/p_state.h"
+
+struct intel_context;
+struct pipe_context;
+struct pipe_winsys;
+struct pipe_buffer;
+struct _DriBufferObject;
+
+struct pipe_winsys *
+intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan );
+
+void
+intel_destroy_pipe_winsys( struct pipe_winsys *winsys );
+
+struct pipe_context *
+intel_create_softpipe( struct intel_context *intel,
+ struct pipe_winsys *winsys );
+
+struct pipe_context *
+intel_create_i915simple( struct intel_context *intel,
+ struct pipe_winsys *winsys );
+
+
+struct intel_buffer {
+ struct pipe_buffer base;
+ struct _DriBufferObject *driBO;
+};
+
+static INLINE struct intel_buffer *
+intel_buffer( struct pipe_buffer *buf )
+{
+ return (struct intel_buffer *)buf;
+}
+
+static INLINE struct _DriBufferObject *
+dri_bo( struct pipe_buffer *buf )
+{
+ return intel_buffer(buf)->driBO;
+}
+
+
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c
new file mode 100644
index 0000000000..8ec5c7e82a
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c
@@ -0,0 +1,184 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include <stdlib.h>
+#include <xf86drm.h>
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
+
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_winsys.h"
+
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+#include "i915simple/i915_winsys.h"
+#include "i915simple/i915_screen.h"
+
+
+struct intel_i915_winsys {
+ struct i915_winsys winsys; /**< batch buffer funcs */
+ struct pipe_winsys *pws;
+ struct intel_context *intel;
+};
+
+
+/* Turn a i915simple winsys into an intel/i915simple winsys:
+ */
+static inline struct intel_i915_winsys *
+intel_i915_winsys( struct i915_winsys *sws )
+{
+ return (struct intel_i915_winsys *)sws;
+}
+
+
+/* Simple batchbuffer interface:
+ */
+
+static unsigned *intel_i915_batch_start( struct i915_winsys *sws,
+ unsigned dwords,
+ unsigned relocs )
+{
+ struct intel_context *intel = intel_i915_winsys(sws)->intel;
+
+ /* XXX: check relocs.
+ */
+ if (intel_batchbuffer_space( intel->batch ) >= dwords * 4) {
+ /* XXX: Hmm, the driver can't really do much with this pointer:
+ */
+ return (unsigned *)intel->batch->ptr;
+ }
+ else
+ return NULL;
+}
+
+static void intel_i915_batch_dword( struct i915_winsys *sws,
+ unsigned dword )
+{
+ struct intel_context *intel = intel_i915_winsys(sws)->intel;
+ intel_batchbuffer_emit_dword( intel->batch, dword );
+}
+
+static void intel_i915_batch_reloc( struct i915_winsys *sws,
+ struct pipe_buffer *buf,
+ unsigned access_flags,
+ unsigned delta )
+{
+ struct intel_context *intel = intel_i915_winsys(sws)->intel;
+ unsigned flags = DRM_BO_FLAG_MEM_TT;
+ unsigned mask = DRM_BO_MASK_MEM;
+
+ if (access_flags & I915_BUFFER_ACCESS_WRITE) {
+ flags |= DRM_BO_FLAG_WRITE;
+ mask |= DRM_BO_FLAG_WRITE;
+ }
+
+ if (access_flags & I915_BUFFER_ACCESS_READ) {
+ flags |= DRM_BO_FLAG_READ;
+ mask |= DRM_BO_FLAG_READ;
+ }
+
+#if 0 /* JB old */
+ intel_batchbuffer_emit_reloc( intel->batch,
+ dri_bo( buf ),
+ flags, mask,
+ delta );
+#else /* new */
+ intel_offset_relocation( intel->batch,
+ delta,
+ dri_bo( buf ),
+ flags,
+ mask );
+#endif
+}
+
+
+
+static void intel_i915_batch_flush( struct i915_winsys *sws,
+ struct pipe_fence_handle **fence )
+{
+ struct intel_i915_winsys *iws = intel_i915_winsys(sws);
+ struct intel_context *intel = iws->intel;
+ union {
+ struct _DriFenceObject *dri;
+ struct pipe_fence_handle *pipe;
+ } fu;
+
+ if (fence)
+ assert(!*fence);
+
+ fu.dri = intel_batchbuffer_flush( intel->batch );
+
+ if (!fu.dri) {
+ assert(0);
+ *fence = NULL;
+ return;
+ }
+
+ if (fu.dri) {
+ if (fence)
+ *fence = fu.pipe;
+ else
+ driFenceUnReference(&fu.dri);
+ }
+
+}
+
+
+/**
+ * Create i915 hardware rendering context.
+ */
+struct pipe_context *
+intel_create_i915simple( struct intel_context *intel,
+ struct pipe_winsys *winsys )
+{
+ struct intel_i915_winsys *iws = CALLOC_STRUCT( intel_i915_winsys );
+ struct pipe_screen *screen;
+
+ /* Fill in this struct with callbacks that i915simple will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ iws->winsys.batch_start = intel_i915_batch_start;
+ iws->winsys.batch_dword = intel_i915_batch_dword;
+ iws->winsys.batch_reloc = intel_i915_batch_reloc;
+ iws->winsys.batch_flush = intel_i915_batch_flush;
+ iws->pws = winsys;
+ iws->intel = intel;
+
+ screen = i915_create_screen(winsys, PCI_CHIP_I945_GM);
+ assert(screen);
+
+ /* Create the i915simple context:
+ */
+ return i915_create_context( screen,
+ winsys,
+ &iws->winsys );
+}
diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c
new file mode 100644
index 0000000000..8bf8c21439
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c
@@ -0,0 +1,338 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include <stdlib.h>
+#include <xf86drm.h>
+//#include "dri_bufpool.h"
+//#include "dri_bufmgr.h"
+
+#include "intel_context.h"
+#include "intel_winsys.h"
+#include "intel_swapbuffers.h"
+#include "intel_batchbuffer.h"
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+
+
+
+struct intel_pipe_winsys {
+ struct pipe_winsys winsys;
+ struct _DriBufferPool *regionPool;
+ struct _DriFreeSlabManager *fMan;
+};
+
+
+
+/* Turn a pipe winsys into an intel/pipe winsys:
+ */
+static inline struct intel_pipe_winsys *
+intel_pipe_winsys( struct pipe_winsys *winsys )
+{
+ return (struct intel_pipe_winsys *)winsys;
+}
+
+
+/* Most callbacks map direcly onto dri_bufmgr operations:
+ */
+static void *intel_buffer_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf,
+ unsigned flags )
+{
+ unsigned drm_flags = 0;
+
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
+ drm_flags |= DRM_BO_FLAG_WRITE;
+
+ if (flags & PIPE_BUFFER_USAGE_CPU_READ)
+ drm_flags |= DRM_BO_FLAG_READ;
+
+ return driBOMap( dri_bo(buf), drm_flags, 0 );
+}
+
+static void intel_buffer_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ driBOUnmap( dri_bo(buf) );
+}
+
+
+static void
+intel_buffer_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ driBOUnReference( dri_bo(buf) );
+ FREE(buf);
+}
+
+
+/* Pipe has no concept of pools. We choose the tex/region pool
+ * for all buffers.
+ * Grabs the hardware lock!
+ */
+static struct pipe_buffer *
+intel_buffer_create(struct pipe_winsys *winsys,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size )
+{
+ struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
+ struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
+ unsigned flags = 0;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ if (usage & (PIPE_BUFFER_USAGE_VERTEX /*| IWS_BUFFER_USAGE_LOCAL*/)) {
+ flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
+ } else {
+ flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
+ }
+
+ if (usage & PIPE_BUFFER_USAGE_GPU_READ)
+ flags |= DRM_BO_FLAG_READ;
+
+ if (usage & PIPE_BUFFER_USAGE_GPU_WRITE)
+ flags |= DRM_BO_FLAG_WRITE;
+
+ /* drm complains if we don't set any read/write flags.
+ */
+ if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0)
+ flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
+
+#if 0
+ if (flags & IWS_BUFFER_USAGE_EXE)
+ flags |= DRM_BO_FLAG_EXE;
+
+ if (usage & IWS_BUFFER_USAGE_CACHED)
+ flags |= DRM_BO_FLAG_CACHED;
+#endif
+
+ driGenBuffers( iws->regionPool,
+ "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
+
+ driBOData( buffer->driBO, size, NULL, iws->regionPool, 0 );
+
+ return &buffer->base;
+}
+
+
+static struct pipe_buffer *
+intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
+{
+ struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
+ struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
+
+ driGenUserBuffer( iws->regionPool,
+ "pipe user buffer", &buffer->driBO, ptr, bytes );
+
+ buffer->base.refcount = 1;
+
+ return &buffer->base;
+}
+
+
+/* The state tracker (should!) keep track of whether the fake
+ * frontbuffer has been touched by any rendering since the last time
+ * we copied its contents to the real frontbuffer. Our task is easy:
+ */
+static void
+intel_flush_frontbuffer( struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+#if 0
+ struct intel_context *intel = (struct intel_context *) context_private;
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+
+ intelDisplaySurface(dPriv, surf, NULL);
+#endif
+}
+
+
+static struct pipe_surface *
+intel_i915_surface_alloc(struct pipe_winsys *winsys)
+{
+ struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
+ if (surf) {
+ surf->refcount = 1;
+ surf->winsys = winsys;
+ }
+ return surf;
+}
+
+
+/**
+ * Round n up to next multiple.
+ */
+static INLINE unsigned
+round_up(unsigned n, unsigned multiple)
+{
+ return (n + multiple - 1) & ~(multiple - 1);
+}
+
+/**
+ * Copied from xm_winsys.c
+ */
+static int
+intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned flags)
+{
+ const unsigned alignment = 64;
+ //int ret;
+
+ surf->width = width;
+ surf->height = height;
+ surf->format = format;
+ surf->cpp = pf_get_size(format);
+ surf->pitch = round_up(width, alignment / surf->cpp);
+
+ assert(!surf->buffer);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
+ if(!surf->buffer)
+ return -1;
+
+ return 0;
+}
+
+
+static void
+intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
+{
+ struct pipe_surface *surf = *s;
+ surf->refcount--;
+ if (surf->refcount == 0) {
+ if (surf->buffer)
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
+ free(surf);
+ }
+ *s = NULL;
+}
+
+
+
+static const char *
+intel_get_name( struct pipe_winsys *winsys )
+{
+ return "Intel/EGL/ttm";
+}
+
+static void
+intel_fence_reference( struct pipe_winsys *sws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence )
+{
+ if (*ptr)
+ driFenceUnReference((struct _DriFenceObject **)ptr);
+
+ if (fence)
+ *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence);
+}
+
+static int
+intel_fence_signalled( struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ return driFenceSignaled((struct _DriFenceObject *)fence, flag);
+}
+
+static int
+intel_fence_finish( struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag )
+{
+ /* JB: Lets allways lazy wait */
+ return driFenceFinish((struct _DriFenceObject *)fence, flag, 1);
+}
+
+struct pipe_winsys *
+intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
+{
+ struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys );
+
+ /* Fill in this struct with callbacks that pipe will need to
+ * communicate with the window system, buffer manager, etc.
+ *
+ * Pipe would be happy with a malloc based memory manager, but
+ * the SwapBuffers implementation in this winsys driver requires
+ * that rendering be done to an appropriate _DriBufferObject.
+ */
+ iws->winsys.buffer_create = intel_buffer_create;
+ iws->winsys.user_buffer_create = intel_user_buffer_create;
+ iws->winsys.buffer_map = intel_buffer_map;
+ iws->winsys.buffer_unmap = intel_buffer_unmap;
+ iws->winsys.buffer_destroy = intel_buffer_destroy;
+ iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
+ iws->winsys.get_name = intel_get_name;
+ iws->winsys.surface_alloc = intel_i915_surface_alloc;
+ iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;
+ iws->winsys.surface_release = intel_i915_surface_release;
+
+ iws->winsys.fence_reference = intel_fence_reference;
+ iws->winsys.fence_signalled = intel_fence_signalled;
+ iws->winsys.fence_finish = intel_fence_finish;
+
+ if (fd)
+ iws->regionPool = driSlabPoolInit(fd,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT,
+ DRM_BO_FLAG_READ |
+ DRM_BO_FLAG_WRITE |
+ DRM_BO_FLAG_MEM_TT,
+ 64, 6, 16, 4096, 0,
+ fMan);
+
+ return &iws->winsys;
+}
+
+
+void
+intel_destroy_pipe_winsys( struct pipe_winsys *winsys )
+{
+ struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
+ if (iws->regionPool) {
+ driPoolTakeDown(iws->regionPool);
+ }
+ free(iws);
+}
+
diff --git a/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c
new file mode 100644
index 0000000000..0bc2dc4002
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c
@@ -0,0 +1,82 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include "intel_context.h"
+#include "intel_winsys.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_util.h"
+#include "pipe/p_format.h"
+#include "softpipe/sp_winsys.h"
+
+
+struct intel_softpipe_winsys {
+ struct softpipe_winsys sws;
+ struct intel_context *intel;
+};
+
+/**
+ * Return list of surface formats supported by this driver.
+ */
+static boolean
+intel_is_format_supported(struct softpipe_winsys *sws,
+ enum pipe_format format)
+{
+ switch(format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+/**
+ * Create rendering context which uses software rendering.
+ */
+struct pipe_context *
+intel_create_softpipe( struct intel_context *intel,
+ struct pipe_winsys *winsys )
+{
+ struct intel_softpipe_winsys *isws = CALLOC_STRUCT( intel_softpipe_winsys );
+ struct pipe_screen *screen = softpipe_create_screen(winsys);
+
+ /* Fill in this struct with callbacks that softpipe will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ isws->sws.is_format_supported = intel_is_format_supported;
+ isws->intel = intel;
+
+ /* Create the softpipe context:
+ */
+ return softpipe_create( screen, winsys, &isws->sws );
+}
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c
new file mode 100644
index 0000000000..1bc1089352
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c
@@ -0,0 +1,953 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include "glthread.h"
+#include "errno.h"
+#include "ws_dri_bufmgr.h"
+#include "string.h"
+#include "imports.h"
+#include "ws_dri_bufpool.h"
+#include "ws_dri_fencemgr.h"
+
+/*
+ * This lock is here to protect drmBO structs changing underneath us during a
+ * validate list call, since validatelist cannot take individiual locks for
+ * each drmBO. Validatelist takes this lock in write mode. Any access to an
+ * individual drmBO should take this lock in read mode, since in that case, the
+ * driBufferObject mutex will protect the access. Locking order is
+ * driBufferObject mutex - > this rw lock.
+ */
+
+_glthread_DECLARE_STATIC_MUTEX(bmMutex);
+_glthread_DECLARE_STATIC_COND(bmCond);
+
+static int kernelReaders = 0;
+static int num_buffers = 0;
+static int num_user_buffers = 0;
+
+static drmBO *drmBOListBuf(void *iterator)
+{
+ drmBONode *node;
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ node = DRMLISTENTRY(drmBONode, l, head);
+ return node->buf;
+}
+
+static void *drmBOListIterator(drmBOList *list)
+{
+ void *ret = list->list.next;
+
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+static void *drmBOListNext(drmBOList *list, void *iterator)
+{
+ void *ret;
+
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ ret = l->next;
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
+ uint64_t arg0,
+ uint64_t arg1)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->free.next;
+ if (l == &list->free) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ return NULL;
+ }
+ list->numCurrent++;
+ }
+ else {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ }
+ node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
+ DRMLISTADD(&node->head, &list->list);
+ list->numOnList++;
+ return node;
+}
+
+static int drmAddValidateItem(drmBOList *list, drmBO *buf, uint64_t flags,
+ uint64_t mask, int *newItem)
+{
+ drmBONode *node, *cur;
+ drmMMListHead *l;
+
+ *newItem = 0;
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ }
+ if (!cur) {
+ cur = drmAddListItem(list, buf, flags, mask);
+ if (!cur) {
+ return -ENOMEM;
+ }
+ *newItem = 1;
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ }
+ else {
+ uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
+ uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
+
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ return -EINVAL;
+ }
+
+ cur->arg1 |= mask;
+ cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
+
+ if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
+ (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static void drmBOFreeList(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->list.next;
+ while(l != &list->list) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->list.next;
+ list->numCurrent--;
+ list->numOnList--;
+ }
+
+ l = list->free.next;
+ while(l != &list->free) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->free.next;
+ list->numCurrent--;
+ }
+}
+
+static int drmAdjustListNodes(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+ int ret = 0;
+
+ while(list->numCurrent < list->numTarget) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ ret = -ENOMEM;
+ break;
+ }
+ list->numCurrent++;
+ DRMLISTADD(&node->head, &list->free);
+ }
+
+ while(list->numCurrent > list->numTarget) {
+ l = list->free.next;
+ if (l == &list->free)
+ break;
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ list->numCurrent--;
+ }
+ return ret;
+}
+
+static int drmBOCreateList(int numTarget, drmBOList *list)
+{
+ DRMINITLISTHEAD(&list->list);
+ DRMINITLISTHEAD(&list->free);
+ list->numTarget = numTarget;
+ list->numCurrent = 0;
+ list->numOnList = 0;
+ return drmAdjustListNodes(list);
+}
+
+static int drmBOResetList(drmBOList *list)
+{
+ drmMMListHead *l;
+ int ret;
+
+ ret = drmAdjustListNodes(list);
+ if (ret)
+ return ret;
+
+ l = list->list.next;
+ while (l != &list->list) {
+ DRMLISTDEL(l);
+ DRMLISTADD(l, &list->free);
+ list->numOnList--;
+ l = list->list.next;
+ }
+ return drmAdjustListNodes(list);
+}
+
+void driWriteLockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ while(kernelReaders != 0)
+ _glthread_COND_WAIT(bmCond, bmMutex);
+}
+
+void driWriteUnlockKernelBO(void)
+{
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+void driReadLockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ kernelReaders++;
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+void driReadUnlockKernelBO(void)
+{
+ _glthread_LOCK_MUTEX(bmMutex);
+ if (--kernelReaders == 0)
+ _glthread_COND_BROADCAST(bmCond);
+ _glthread_UNLOCK_MUTEX(bmMutex);
+}
+
+
+
+
+/*
+ * TODO: Introduce fence pools in the same way as
+ * buffer object pools.
+ */
+
+typedef struct _DriBufferObject
+{
+ DriBufferPool *pool;
+ _glthread_Mutex mutex;
+ int refCount;
+ const char *name;
+ uint64_t flags;
+ unsigned hint;
+ unsigned alignment;
+ unsigned createdByReference;
+ void *private;
+ /* user-space buffer: */
+ unsigned userBuffer;
+ void *userData;
+ unsigned userSize;
+} DriBufferObject;
+
+typedef struct _DriBufferList {
+ drmBOList drmBuffers; /* List of kernel buffers needing validation */
+ drmBOList driBuffers; /* List of user-space buffers needing validation */
+} DriBufferList;
+
+
+void
+bmError(int val, const char *file, const char *function, int line)
+{
+ _mesa_printf("Fatal video memory manager error \"%s\".\n"
+ "Check kernel logs or set the LIBGL_DEBUG\n"
+ "environment variable to \"verbose\" for more info.\n"
+ "Detected in file %s, line %d, function %s.\n",
+ strerror(-val), file, line, function);
+#ifndef NDEBUG
+ abort();
+#else
+ abort();
+#endif
+}
+
+extern drmBO *
+driBOKernel(struct _DriBufferObject *buf)
+{
+ drmBO *ret;
+
+ driReadLockKernelBO();
+ _glthread_LOCK_MUTEX(buf->mutex);
+ assert(buf->private != NULL);
+ ret = buf->pool->kernel(buf->pool, buf->private);
+ if (!ret)
+ BM_CKFATAL(-EINVAL);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+void
+driBOWaitIdle(struct _DriBufferObject *buf, int lazy)
+{
+
+ /*
+ * This function may block. Is it sane to keep the mutex held during
+ * that time??
+ */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(buf->pool->waitIdle(buf->pool, buf->private, &buf->mutex, lazy));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void *
+driBOMap(struct _DriBufferObject *buf, unsigned flags, unsigned hint)
+{
+ void *virtual;
+ int retval;
+
+ if (buf->userBuffer) {
+ return buf->userData;
+ }
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ assert(buf->private != NULL);
+ retval = buf->pool->map(buf->pool, buf->private, flags, hint,
+ &buf->mutex, &virtual);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return retval == 0 ? virtual : NULL;
+}
+
+void
+driBOUnmap(struct _DriBufferObject *buf)
+{
+ if (buf->userBuffer)
+ return;
+
+ assert(buf->private != NULL);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+unsigned long
+driBOOffset(struct _DriBufferObject *buf)
+{
+ unsigned long ret;
+
+ assert(buf->private != NULL);
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->offset(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return ret;
+}
+
+unsigned long
+driBOPoolOffset(struct _DriBufferObject *buf)
+{
+ unsigned long ret;
+
+ assert(buf->private != NULL);
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->poolOffset(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return ret;
+}
+
+uint64_t
+driBOFlags(struct _DriBufferObject *buf)
+{
+ uint64_t ret;
+
+ assert(buf->private != NULL);
+
+ driReadLockKernelBO();
+ _glthread_LOCK_MUTEX(buf->mutex);
+ ret = buf->pool->flags(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+struct _DriBufferObject *
+driBOReference(struct _DriBufferObject *buf)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (++buf->refCount == 1) {
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(-EINVAL);
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ return buf;
+}
+
+void
+driBOUnReference(struct _DriBufferObject *buf)
+{
+ int tmp;
+
+ if (!buf)
+ return;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ tmp = --buf->refCount;
+ if (!tmp) {
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ if (buf->private) {
+ if (buf->createdByReference)
+ buf->pool->unreference(buf->pool, buf->private);
+ else
+ buf->pool->destroy(buf->pool, buf->private);
+ }
+ if (buf->userBuffer)
+ num_user_buffers--;
+ else
+ num_buffers--;
+ free(buf);
+ } else
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+}
+
+
+int
+driBOData(struct _DriBufferObject *buf,
+ unsigned size, const void *data,
+ DriBufferPool *newPool,
+ uint64_t flags)
+{
+ void *virtual = NULL;
+ int newBuffer;
+ int retval = 0;
+ struct _DriBufferPool *pool;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ pool = buf->pool;
+
+ if (pool == NULL && newPool != NULL) {
+ buf->pool = newPool;
+ pool = newPool;
+ }
+ if (newPool == NULL)
+ newPool = pool;
+
+ if (!pool->create) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "driBOData called on invalid buffer\n");
+ BM_CKFATAL(-EINVAL);
+ }
+
+ newBuffer = (!buf->private || pool != newPool ||
+ pool->size(pool, buf->private) < size);
+
+ if (!flags)
+ flags = buf->flags;
+
+ if (newBuffer) {
+
+ if (buf->createdByReference) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "driBOData requiring resizing called on "
+ "shared buffer.\n");
+ BM_CKFATAL(-EINVAL);
+ }
+
+ if (buf->private)
+ buf->pool->destroy(buf->pool, buf->private);
+
+ pool = newPool;
+ buf->pool = newPool;
+ buf->private = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
+ buf->alignment);
+ if (!buf->private)
+ retval = -ENOMEM;
+
+ if (retval == 0)
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE,
+ DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual);
+ } else if (pool->map(pool, buf->private, DRM_BO_FLAG_WRITE,
+ DRM_BO_HINT_DONT_BLOCK, &buf->mutex, &virtual)) {
+ /*
+ * Buffer is busy. need to create a new one.
+ */
+
+ void *newBuf;
+
+ newBuf = pool->create(pool, size, flags, DRM_BO_HINT_DONT_FENCE,
+ buf->alignment);
+ if (newBuf) {
+ buf->pool->destroy(buf->pool, buf->private);
+ buf->private = newBuf;
+ }
+
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
+ } else {
+ uint64_t flag_diff = flags ^ buf->flags;
+
+ /*
+ * We might need to change buffer flags.
+ */
+
+ if (flag_diff){
+ assert(pool->setStatus != NULL);
+ BM_CKFATAL(pool->unmap(pool, buf->private));
+ BM_CKFATAL(pool->setStatus(pool, buf->private, flag_diff,
+ buf->flags));
+ if (!data)
+ goto out;
+
+ retval = pool->map(pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex, &virtual);
+ }
+ }
+
+ if (retval == 0) {
+ if (data)
+ memcpy(virtual, data, size);
+
+ BM_CKFATAL(pool->unmap(pool, buf->private));
+ }
+
+ out:
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return retval;
+}
+
+void
+driBOSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size, const void *data)
+{
+ void *virtual;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (size && data) {
+ BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
+ DRM_BO_FLAG_WRITE, 0, &buf->mutex,
+ &virtual));
+ memcpy((unsigned char *) virtual + offset, data, size);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void
+driBOGetSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size, void *data)
+{
+ void *virtual;
+
+ assert(!buf->userBuffer); /* XXX just do a memcpy? */
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (size && data) {
+ BM_CKFATAL(buf->pool->map(buf->pool, buf->private,
+ DRM_BO_FLAG_READ, 0, &buf->mutex, &virtual));
+ memcpy(data, (unsigned char *) virtual + offset, size);
+ BM_CKFATAL(buf->pool->unmap(buf->pool, buf->private));
+ }
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+void
+driBOSetReferenced(struct _DriBufferObject *buf,
+ unsigned long handle)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->private != NULL) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "Invalid buffer for setReferenced\n");
+ BM_CKFATAL(-EINVAL);
+
+ }
+ if (buf->pool->reference == NULL) {
+ _mesa_error(NULL, GL_INVALID_OPERATION,
+ "Invalid buffer pool for setReferenced\n");
+ BM_CKFATAL(-EINVAL);
+ }
+ buf->private = buf->pool->reference(buf->pool, handle);
+ if (!buf->private) {
+ _mesa_error(NULL, GL_OUT_OF_MEMORY,
+ "Invalid buffer pool for setStatic\n");
+ BM_CKFATAL(-ENOMEM);
+ }
+ buf->createdByReference = GL_TRUE;
+ buf->flags = buf->pool->kernel(buf->pool, buf->private)->flags;
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+int
+driGenBuffers(struct _DriBufferPool *pool,
+ const char *name,
+ unsigned n,
+ struct _DriBufferObject *buffers[],
+ unsigned alignment, uint64_t flags, unsigned hint)
+{
+ struct _DriBufferObject *buf;
+ int i;
+
+ flags = (flags) ? flags : DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_MEM_VRAM |
+ DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
+
+ ++num_buffers;
+
+ assert(pool);
+
+ for (i = 0; i < n; ++i) {
+ buf = (struct _DriBufferObject *) calloc(1, sizeof(*buf));
+ if (!buf)
+ return -ENOMEM;
+
+ _glthread_INIT_MUTEX(buf->mutex);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ buf->refCount = 1;
+ buf->flags = flags;
+ buf->hint = hint;
+ buf->name = name;
+ buf->alignment = alignment;
+ buf->pool = pool;
+ buf->createdByReference = 0;
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ buffers[i] = buf;
+ }
+ return 0;
+}
+
+void
+driGenUserBuffer(struct _DriBufferPool *pool,
+ const char *name,
+ struct _DriBufferObject **buffers,
+ void *ptr, unsigned bytes)
+{
+ const unsigned alignment = 1, flags = 0, hint = 0;
+
+ --num_buffers; /* JB: is inced in GenBuffes */
+ driGenBuffers(pool, name, 1, buffers, alignment, flags, hint);
+ ++num_user_buffers;
+
+ (*buffers)->userBuffer = 1;
+ (*buffers)->userData = ptr;
+ (*buffers)->userSize = bytes;
+}
+
+void
+driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[])
+{
+ int i;
+
+ for (i = 0; i < n; ++i) {
+ driBOUnReference(buffers[i]);
+ }
+}
+
+
+void
+driInitBufMgr(int fd)
+{
+ ;
+}
+
+/*
+ * Note that lists are per-context and don't need mutex protection.
+ */
+
+struct _DriBufferList *
+driBOCreateList(int target)
+{
+ struct _DriBufferList *list = calloc(sizeof(*list), 1);
+
+ BM_CKFATAL(drmBOCreateList(target, &list->drmBuffers));
+ BM_CKFATAL(drmBOCreateList(target, &list->driBuffers));
+ return list;
+}
+
+int
+driBOResetList(struct _DriBufferList * list)
+{
+ int ret;
+ ret = drmBOResetList(&list->drmBuffers);
+ if (ret)
+ return ret;
+ ret = drmBOResetList(&list->driBuffers);
+ return ret;
+}
+
+void
+driBOFreeList(struct _DriBufferList * list)
+{
+ drmBOFreeList(&list->drmBuffers);
+ drmBOFreeList(&list->driBuffers);
+ free(list);
+}
+
+
+/*
+ * Copied from libdrm, because it is needed by driAddValidateItem.
+ */
+
+static drmBONode *
+driAddListItem(drmBOList * list, drmBO * item,
+ uint64_t arg0, uint64_t arg1)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->free.next;
+ if (l == &list->free) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ return NULL;
+ }
+ list->numCurrent++;
+ } else {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ }
+ memset(&node->bo_arg, 0, sizeof(node->bo_arg));
+ node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
+ DRMLISTADDTAIL(&node->head, &list->list);
+ list->numOnList++;
+ return node;
+}
+
+/*
+ * Slightly modified version compared to the libdrm version.
+ * This one returns the list index of the buffer put on the list.
+ */
+
+static int
+driAddValidateItem(drmBOList * list, drmBO * buf, uint64_t flags,
+ uint64_t mask, int *itemLoc,
+ struct _drmBONode **pnode)
+{
+ drmBONode *node, *cur;
+ drmMMListHead *l;
+ int count = 0;
+
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ count++;
+ }
+ if (!cur) {
+ cur = driAddListItem(list, buf, flags, mask);
+ if (!cur)
+ return -ENOMEM;
+
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ } else {
+ uint64_t memFlags = cur->arg0 & flags & DRM_BO_MASK_MEM;
+ uint64_t accFlags = (cur->arg0 | flags) & ~DRM_BO_MASK_MEM;
+
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ return -EINVAL;
+ }
+
+ cur->arg1 |= mask;
+ cur->arg0 = (cur->arg0 & ~mask) | ((memFlags | accFlags) & mask);
+
+ if (((cur->arg1 & DRM_BO_MASK_MEM) != 0) &&
+ (cur->arg0 & DRM_BO_MASK_MEM) == 0) {
+ return -EINVAL;
+ }
+ }
+ *itemLoc = count;
+ *pnode = cur;
+ return 0;
+}
+
+
+void
+driBOAddListItem(struct _DriBufferList * list, struct _DriBufferObject *buf,
+ uint64_t flags, uint64_t mask, int *itemLoc,
+ struct _drmBONode **node)
+{
+ int newItem;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ BM_CKFATAL(driAddValidateItem(&list->drmBuffers,
+ buf->pool->kernel(buf->pool, buf->private),
+ flags, mask, itemLoc, node));
+ BM_CKFATAL(drmAddValidateItem(&list->driBuffers, (drmBO *) buf,
+ flags, mask, &newItem));
+ if (newItem)
+ buf->refCount++;
+
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+}
+
+drmBOList *driGetdrmBOList(struct _DriBufferList *list)
+{
+ driWriteLockKernelBO();
+ return &list->drmBuffers;
+}
+
+void driPutdrmBOList(struct _DriBufferList *list)
+{
+ driWriteUnlockKernelBO();
+}
+
+
+void
+driBOFence(struct _DriBufferObject *buf, struct _DriFenceObject *fence)
+{
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->pool->fence)
+ BM_CKFATAL(buf->pool->fence(buf->pool, buf->private, fence));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+}
+
+void
+driBOUnrefUserList(struct _DriBufferList *list)
+{
+ struct _DriBufferObject *buf;
+ void *curBuf;
+
+ curBuf = drmBOListIterator(&list->driBuffers);
+ while (curBuf) {
+ buf = (struct _DriBufferObject *)drmBOListBuf(curBuf);
+ driBOUnReference(buf);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+}
+
+struct _DriFenceObject *
+driBOFenceUserList(struct _DriFenceMgr *mgr,
+ struct _DriBufferList *list, const char *name,
+ drmFence *kFence)
+{
+ struct _DriFenceObject *fence;
+ struct _DriBufferObject *buf;
+ void *curBuf;
+
+ fence = driFenceCreate(mgr, kFence->fence_class, kFence->type,
+ kFence, sizeof(*kFence));
+ curBuf = drmBOListIterator(&list->driBuffers);
+
+ /*
+ * User-space fencing callbacks.
+ */
+
+ while (curBuf) {
+ buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
+ driBOFence(buf, fence);
+ driBOUnReference(buf);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+
+ driBOResetList(list);
+ return fence;
+}
+
+void
+driBOValidateUserList(struct _DriBufferList * list)
+{
+ void *curBuf;
+ struct _DriBufferObject *buf;
+
+ curBuf = drmBOListIterator(&list->driBuffers);
+
+ /*
+ * User-space validation callbacks.
+ */
+
+ while (curBuf) {
+ buf = (struct _DriBufferObject *) drmBOListBuf(curBuf);
+ _glthread_LOCK_MUTEX(buf->mutex);
+ if (buf->pool->validate)
+ BM_CKFATAL(buf->pool->validate(buf->pool, buf->private, &buf->mutex));
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+ curBuf = drmBOListNext(&list->driBuffers, curBuf);
+ }
+}
+
+
+void
+driPoolTakeDown(struct _DriBufferPool *pool)
+{
+ pool->takeDown(pool);
+
+}
+
+unsigned long
+driBOSize(struct _DriBufferObject *buf)
+{
+ unsigned long size;
+
+ _glthread_LOCK_MUTEX(buf->mutex);
+ size = buf->pool->size(buf->pool, buf->private);
+ _glthread_UNLOCK_MUTEX(buf->mutex);
+
+ return size;
+
+}
+
+drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list)
+{
+ return &list->drmBuffers;
+}
+
+drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list)
+{
+ return &list->driBuffers;
+}
+
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h
new file mode 100644
index 0000000000..fdaf5ee93a
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h
@@ -0,0 +1,138 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Keith Whitwell <keithw-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _PSB_BUFMGR_H_
+#define _PSB_BUFMGR_H_
+#include <xf86mm.h>
+#include "i915_drm.h"
+#include "ws_dri_fencemgr.h"
+
+typedef struct _drmBONode
+{
+ drmMMListHead head;
+ drmBO *buf;
+ struct drm_i915_op_arg bo_arg;
+ uint64_t arg0;
+ uint64_t arg1;
+} drmBONode;
+
+typedef struct _drmBOList {
+ unsigned numTarget;
+ unsigned numCurrent;
+ unsigned numOnList;
+ drmMMListHead list;
+ drmMMListHead free;
+} drmBOList;
+
+
+struct _DriFenceObject;
+struct _DriBufferObject;
+struct _DriBufferPool;
+struct _DriBufferList;
+
+/*
+ * Return a pointer to the libdrm buffer object this DriBufferObject
+ * uses.
+ */
+
+extern drmBO *driBOKernel(struct _DriBufferObject *buf);
+extern void *driBOMap(struct _DriBufferObject *buf, unsigned flags,
+ unsigned hint);
+extern void driBOUnmap(struct _DriBufferObject *buf);
+extern unsigned long driBOOffset(struct _DriBufferObject *buf);
+extern unsigned long driBOPoolOffset(struct _DriBufferObject *buf);
+
+extern uint64_t driBOFlags(struct _DriBufferObject *buf);
+extern struct _DriBufferObject *driBOReference(struct _DriBufferObject *buf);
+extern void driBOUnReference(struct _DriBufferObject *buf);
+
+extern int driBOData(struct _DriBufferObject *r_buf,
+ unsigned size, const void *data,
+ struct _DriBufferPool *pool, uint64_t flags);
+
+extern void driBOSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size,
+ const void *data);
+extern void driBOGetSubData(struct _DriBufferObject *buf,
+ unsigned long offset, unsigned long size,
+ void *data);
+extern int driGenBuffers(struct _DriBufferPool *pool,
+ const char *name,
+ unsigned n,
+ struct _DriBufferObject *buffers[],
+ unsigned alignment, uint64_t flags, unsigned hint);
+extern void driGenUserBuffer(struct _DriBufferPool *pool,
+ const char *name,
+ struct _DriBufferObject *buffers[],
+ void *ptr, unsigned bytes);
+extern void driDeleteBuffers(unsigned n, struct _DriBufferObject *buffers[]);
+extern void driInitBufMgr(int fd);
+extern struct _DriBufferList *driBOCreateList(int target);
+extern int driBOResetList(struct _DriBufferList * list);
+extern void driBOAddListItem(struct _DriBufferList * list,
+ struct _DriBufferObject *buf,
+ uint64_t flags, uint64_t mask, int *itemLoc,
+ struct _drmBONode **node);
+
+extern void driBOValidateList(int fd, struct _DriBufferList * list);
+extern void driBOFreeList(struct _DriBufferList * list);
+extern struct _DriFenceObject *driBOFenceUserList(struct _DriFenceMgr *mgr,
+ struct _DriBufferList *list,
+ const char *name,
+ drmFence *kFence);
+extern void driBOUnrefUserList(struct _DriBufferList *list);
+extern void driBOValidateUserList(struct _DriBufferList * list);
+extern drmBOList *driGetdrmBOList(struct _DriBufferList *list);
+extern void driPutdrmBOList(struct _DriBufferList *list);
+
+extern void driBOFence(struct _DriBufferObject *buf,
+ struct _DriFenceObject *fence);
+
+extern void driPoolTakeDown(struct _DriBufferPool *pool);
+extern void driBOSetReferenced(struct _DriBufferObject *buf,
+ unsigned long handle);
+unsigned long driBOSize(struct _DriBufferObject *buf);
+extern void driBOWaitIdle(struct _DriBufferObject *buf, int lazy);
+extern void driPoolTakeDown(struct _DriBufferPool *pool);
+
+extern void driReadLockKernelBO(void);
+extern void driReadUnlockKernelBO(void);
+extern void driWriteLockKernelBO(void);
+extern void driWriteUnlockKernelBO(void);
+
+/*
+ * For debugging purposes.
+ */
+
+extern drmBOList *driBOGetDRMBuffers(struct _DriBufferList *list);
+extern drmBOList *driBOGetDRIBuffers(struct _DriBufferList *list);
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h
new file mode 100644
index 0000000000..3a302e13d3
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#ifndef _PSB_BUFPOOL_H_
+#define _PSB_BUFPOOL_H_
+
+#include <xf86drm.h>
+#include <glthread.h>
+struct _DriFenceObject;
+
+typedef struct _DriBufferPool
+{
+ int fd;
+ int (*map) (struct _DriBufferPool * pool, void *private,
+ unsigned flags, int hint, _glthread_Mutex *mutex,
+ void **virtual);
+ int (*unmap) (struct _DriBufferPool * pool, void *private);
+ int (*destroy) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*offset) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*poolOffset) (struct _DriBufferPool * pool, void *private);
+ uint64_t (*flags) (struct _DriBufferPool * pool, void *private);
+ unsigned long (*size) (struct _DriBufferPool * pool, void *private);
+ void *(*create) (struct _DriBufferPool * pool, unsigned long size,
+ uint64_t flags, unsigned hint, unsigned alignment);
+ void *(*reference) (struct _DriBufferPool * pool, unsigned handle);
+ int (*unreference) (struct _DriBufferPool * pool, void *private);
+ int (*fence) (struct _DriBufferPool * pool, void *private,
+ struct _DriFenceObject * fence);
+ drmBO *(*kernel) (struct _DriBufferPool * pool, void *private);
+ int (*validate) (struct _DriBufferPool * pool, void *private, _glthread_Mutex *mutex);
+ int (*waitIdle) (struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex,
+ int lazy);
+ int (*setStatus) (struct _DriBufferPool *pool, void *private,
+ uint64_t flag_diff, uint64_t old_flags);
+ void (*takeDown) (struct _DriBufferPool * pool);
+ void *data;
+} DriBufferPool;
+
+extern void bmError(int val, const char *file, const char *function,
+ int line);
+#define BM_CKFATAL(val) \
+ do{ \
+ int tstVal = (val); \
+ if (tstVal) \
+ bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \
+ } while(0);
+
+
+/*
+ * Builtin pools.
+ */
+
+/*
+ * Kernel buffer objects. Size in multiples of page size. Page size aligned.
+ */
+
+extern struct _DriBufferPool *driDRMPoolInit(int fd);
+extern struct _DriBufferPool *driMallocPoolInit(void);
+
+struct _DriFreeSlabManager;
+extern struct _DriBufferPool * driSlabPoolInit(int fd, uint64_t flags,
+ uint64_t validMask,
+ uint32_t smallestSize,
+ uint32_t numSizes,
+ uint32_t desiredNumBuffers,
+ uint32_t maxSlabSize,
+ uint32_t pageAlignment,
+ struct _DriFreeSlabManager *fMan);
+extern void driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan);
+extern struct _DriFreeSlabManager *
+driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec);
+
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c
new file mode 100644
index 0000000000..7c55dbc674
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c
@@ -0,0 +1,268 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
+#include "assert.h"
+
+/*
+ * Buffer pool implementation using DRM buffer objects as DRI buffer objects.
+ */
+
+static void *
+pool_create(struct _DriBufferPool *pool,
+ unsigned long size, uint64_t flags, unsigned hint,
+ unsigned alignment)
+{
+ drmBO *buf = (drmBO *) malloc(sizeof(*buf));
+ int ret;
+ unsigned pageSize = getpagesize();
+
+ if (!buf)
+ return NULL;
+
+ if ((alignment > pageSize) && (alignment % pageSize)) {
+ free(buf);
+ return NULL;
+ }
+
+ ret = drmBOCreate(pool->fd, size, alignment / pageSize,
+ NULL,
+ flags, hint, buf);
+ if (ret) {
+ free(buf);
+ return NULL;
+ }
+
+ return (void *) buf;
+}
+
+static void *
+pool_reference(struct _DriBufferPool *pool, unsigned handle)
+{
+ drmBO *buf = (drmBO *) malloc(sizeof(*buf));
+ int ret;
+
+ if (!buf)
+ return NULL;
+
+ ret = drmBOReference(pool->fd, handle, buf);
+
+ if (ret) {
+ free(buf);
+ return NULL;
+ }
+
+ return (void *) buf;
+}
+
+static int
+pool_destroy(struct _DriBufferPool *pool, void *private)
+{
+ int ret;
+ drmBO *buf = (drmBO *) private;
+ driReadLockKernelBO();
+ ret = drmBOUnreference(pool->fd, buf);
+ free(buf);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_unreference(struct _DriBufferPool *pool, void *private)
+{
+ int ret;
+ drmBO *buf = (drmBO *) private;
+ driReadLockKernelBO();
+ ret = drmBOUnreference(pool->fd, buf);
+ free(buf);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOMap(pool->fd, buf, flags, hint, virtual);
+ driReadUnlockKernelBO();
+ return ret;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOUnmap(pool->fd, buf);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ unsigned long offset;
+
+ driReadLockKernelBO();
+ assert(buf->flags & DRM_BO_FLAG_NO_MOVE);
+ offset = buf->offset;
+ driReadUnlockKernelBO();
+
+ return buf->offset;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ return 0;
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ uint64_t flags;
+
+ driReadLockKernelBO();
+ flags = buf->flags;
+ driReadUnlockKernelBO();
+
+ return flags;
+}
+
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ drmBO *buf = (drmBO *) private;
+ unsigned long size;
+
+ driReadLockKernelBO();
+ size = buf->size;
+ driReadUnlockKernelBO();
+
+ return buf->size;
+}
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ /*
+ * Noop. The kernel handles all fencing.
+ */
+
+ return 0;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ return (drmBO *) private;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *pool, void *private, _glthread_Mutex *mutex,
+ int lazy)
+{
+ drmBO *buf = (drmBO *) private;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOWaitIdle(pool->fd, buf, (lazy) ? DRM_BO_HINT_WAIT_LAZY:0);
+ driReadUnlockKernelBO();
+
+ return ret;
+}
+
+
+static void
+pool_takedown(struct _DriBufferPool *pool)
+{
+ free(pool);
+}
+
+/*static int
+pool_setStatus(struct _DriBufferPool *pool, void *private,
+ uint64_t flag_diff, uint64_t old_flags)
+{
+ drmBO *buf = (drmBO *) private;
+ uint64_t new_flags = old_flags ^ flag_diff;
+ int ret;
+
+ driReadLockKernelBO();
+ ret = drmBOSetStatus(pool->fd, buf, new_flags, flag_diff,
+ 0, 0, 0);
+ driReadUnlockKernelBO();
+ return ret;
+}*/
+
+struct _DriBufferPool *
+driDRMPoolInit(int fd)
+{
+ struct _DriBufferPool *pool;
+
+ pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
+
+ if (!pool)
+ return NULL;
+
+ pool->fd = fd;
+ pool->map = &pool_map;
+ pool->unmap = &pool_unmap;
+ pool->destroy = &pool_destroy;
+ pool->offset = &pool_offset;
+ pool->poolOffset = &pool_poolOffset;
+ pool->flags = &pool_flags;
+ pool->size = &pool_size;
+ pool->create = &pool_create;
+ pool->fence = &pool_fence;
+ pool->kernel = &pool_kernel;
+ pool->validate = NULL;
+ pool->waitIdle = &pool_waitIdle;
+ pool->takeDown = &pool_takedown;
+ pool->reference = &pool_reference;
+ pool->unreference = &pool_unreference;
+ pool->data = NULL;
+ return pool;
+}
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c
new file mode 100644
index 0000000000..1f893b47ce
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c
@@ -0,0 +1,377 @@
+#include "ws_dri_fencemgr.h"
+#include "glthread.h"
+#include <xf86mm.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Note: Locking order is
+ * _DriFenceObject::mutex
+ * _DriFenceMgr::mutex
+ */
+
+struct _DriFenceMgr {
+ /*
+ * Constant members. Need no mutex protection.
+ */
+ struct _DriFenceMgrCreateInfo info;
+ void *private;
+
+ /*
+ * These members are protected by this->mutex
+ */
+ _glthread_Mutex mutex;
+ int refCount;
+ drmMMListHead *heads;
+ int num_fences;
+};
+
+struct _DriFenceObject {
+
+ /*
+ * These members are constant and need no mutex protection.
+ */
+ struct _DriFenceMgr *mgr;
+ uint32_t fence_class;
+ uint32_t fence_type;
+
+ /*
+ * These members are protected by mgr->mutex.
+ */
+ drmMMListHead head;
+ int refCount;
+
+ /*
+ * These members are protected by this->mutex.
+ */
+ _glthread_Mutex mutex;
+ uint32_t signaled_type;
+ void *private;
+};
+
+uint32_t
+driFenceType(struct _DriFenceObject *fence)
+{
+ return fence->fence_type;
+}
+
+struct _DriFenceMgr *
+driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info)
+{
+ struct _DriFenceMgr *tmp;
+ uint32_t i;
+
+ tmp = calloc(1, sizeof(*tmp));
+ if (!tmp)
+ return NULL;
+
+ _glthread_INIT_MUTEX(tmp->mutex);
+ _glthread_LOCK_MUTEX(tmp->mutex);
+ tmp->refCount = 1;
+ tmp->info = *info;
+ tmp->num_fences = 0;
+ tmp->heads = calloc(tmp->info.num_classes, sizeof(*tmp->heads));
+ if (!tmp->heads)
+ goto out_err;
+
+ for (i=0; i<tmp->info.num_classes; ++i) {
+ DRMINITLISTHEAD(&tmp->heads[i]);
+ }
+ _glthread_UNLOCK_MUTEX(tmp->mutex);
+ return tmp;
+
+ out_err:
+ if (tmp)
+ free(tmp);
+ return NULL;
+}
+
+static void
+driFenceMgrUnrefUnlock(struct _DriFenceMgr **pMgr)
+{
+ struct _DriFenceMgr *mgr = *pMgr;
+
+ *pMgr = NULL;
+ if (--mgr->refCount == 0)
+ free(mgr);
+ else
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+}
+
+void
+driFenceMgrUnReference(struct _DriFenceMgr **pMgr)
+{
+ _glthread_LOCK_MUTEX((*pMgr)->mutex);
+ driFenceMgrUnrefUnlock(pMgr);
+}
+
+static void
+driFenceUnReferenceLocked(struct _DriFenceObject **pFence)
+{
+ struct _DriFenceObject *fence = *pFence;
+ struct _DriFenceMgr *mgr = fence->mgr;
+
+ *pFence = NULL;
+ if (--fence->refCount == 0) {
+ DRMLISTDELINIT(&fence->head);
+ if (fence->private)
+ mgr->info.unreference(mgr, &fence->private);
+ --mgr->num_fences;
+ fence->mgr = NULL;
+ --mgr->refCount;
+ free(fence);
+
+ }
+}
+
+
+static void
+driSignalPreviousFencesLocked(struct _DriFenceMgr *mgr,
+ drmMMListHead *list,
+ uint32_t fence_class,
+ uint32_t fence_type)
+{
+ struct _DriFenceObject *entry;
+ drmMMListHead *prev;
+
+ while(list != &mgr->heads[fence_class]) {
+ entry = DRMLISTENTRY(struct _DriFenceObject, list, head);
+
+ /*
+ * Up refcount so that entry doesn't disappear from under us
+ * when we unlock-relock mgr to get the correct locking order.
+ */
+
+ ++entry->refCount;
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ _glthread_LOCK_MUTEX(entry->mutex);
+ _glthread_LOCK_MUTEX(mgr->mutex);
+
+ prev = list->prev;
+
+
+
+ if (list->prev == list) {
+
+ /*
+ * Somebody else removed the entry from the list.
+ */
+
+ _glthread_UNLOCK_MUTEX(entry->mutex);
+ driFenceUnReferenceLocked(&entry);
+ return;
+ }
+
+ entry->signaled_type |= (fence_type & entry->fence_type);
+ if (entry->signaled_type == entry->fence_type) {
+ DRMLISTDELINIT(list);
+ mgr->info.unreference(mgr, &entry->private);
+ }
+ _glthread_UNLOCK_MUTEX(entry->mutex);
+ driFenceUnReferenceLocked(&entry);
+ list = prev;
+ }
+}
+
+
+int
+driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type,
+ int lazy_hint)
+{
+ struct _DriFenceMgr *mgr = fence->mgr;
+ int ret = 0;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+
+ if ((fence->signaled_type & fence_type) == fence_type)
+ goto out0;
+
+ ret = mgr->info.finish(mgr, fence->private, fence_type, lazy_hint);
+ if (ret)
+ goto out0;
+
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class,
+ fence_type);
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ return 0;
+
+ out0:
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return ret;
+}
+
+uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence)
+{
+ uint32_t ret;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+ ret = fence->signaled_type;
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ return ret;
+}
+
+int
+driFenceSignaledType(struct _DriFenceObject *fence, uint32_t flush_type,
+ uint32_t *signaled)
+{
+ int ret = 0;
+ struct _DriFenceMgr *mgr;
+
+ _glthread_LOCK_MUTEX(fence->mutex);
+ mgr = fence->mgr;
+ *signaled = fence->signaled_type;
+ if ((fence->signaled_type & flush_type) == flush_type)
+ goto out0;
+
+ ret = mgr->info.signaled(mgr, fence->private, flush_type, signaled);
+ if (ret) {
+ *signaled = fence->signaled_type;
+ goto out0;
+ }
+
+ if ((fence->signaled_type | *signaled) == fence->signaled_type)
+ goto out0;
+
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+
+ driSignalPreviousFencesLocked(mgr, &fence->head, fence->fence_class,
+ *signaled);
+
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ return 0;
+ out0:
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return ret;
+}
+
+struct _DriFenceObject *
+driFenceReference(struct _DriFenceObject *fence)
+{
+ _glthread_LOCK_MUTEX(fence->mgr->mutex);
+ ++fence->refCount;
+ _glthread_UNLOCK_MUTEX(fence->mgr->mutex);
+ return fence;
+}
+
+void
+driFenceUnReference(struct _DriFenceObject **pFence)
+{
+ struct _DriFenceMgr *mgr;
+
+ if (*pFence == NULL)
+ return;
+
+ mgr = (*pFence)->mgr;
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ ++mgr->refCount;
+ driFenceUnReferenceLocked(pFence);
+ driFenceMgrUnrefUnlock(&mgr);
+}
+
+struct _DriFenceObject
+*driFenceCreate(struct _DriFenceMgr *mgr, uint32_t fence_class,
+ uint32_t fence_type, void *private, size_t private_size)
+{
+ struct _DriFenceObject *fence;
+ size_t fence_size = sizeof(*fence);
+
+ if (private_size)
+ fence_size = ((fence_size + 15) & ~15);
+
+ fence = calloc(1, fence_size + private_size);
+
+ if (!fence) {
+ int ret = mgr->info.finish(mgr, private, fence_type, 0);
+
+ if (ret)
+ usleep(10000000);
+
+ return NULL;
+ }
+
+ _glthread_INIT_MUTEX(fence->mutex);
+ _glthread_LOCK_MUTEX(fence->mutex);
+ _glthread_LOCK_MUTEX(mgr->mutex);
+ fence->refCount = 1;
+ DRMLISTADDTAIL(&fence->head, &mgr->heads[fence_class]);
+ fence->mgr = mgr;
+ ++mgr->refCount;
+ ++mgr->num_fences;
+ _glthread_UNLOCK_MUTEX(mgr->mutex);
+ fence->fence_class = fence_class;
+ fence->fence_type = fence_type;
+ fence->signaled_type = 0;
+ fence->private = private;
+ if (private_size) {
+ fence->private = (void *)(((uint8_t *) fence) + fence_size);
+ memcpy(fence->private, private, private_size);
+ }
+
+ _glthread_UNLOCK_MUTEX(fence->mutex);
+ return fence;
+}
+
+
+static int
+tSignaled(struct _DriFenceMgr *mgr, void *private, uint32_t flush_type,
+ uint32_t *signaled_type)
+{
+ long fd = (long) mgr->private;
+ int dummy;
+ drmFence *fence = (drmFence *) private;
+ int ret;
+
+ *signaled_type = 0;
+ ret = drmFenceSignaled((int) fd, fence, flush_type, &dummy);
+ if (ret)
+ return ret;
+
+ *signaled_type = fence->signaled;
+
+ return 0;
+}
+
+static int
+tFinish(struct _DriFenceMgr *mgr, void *private, uint32_t fence_type,
+ int lazy_hint)
+{
+ long fd = (long) mgr->private;
+ unsigned flags = lazy_hint ? DRM_FENCE_FLAG_WAIT_LAZY : 0;
+
+ return drmFenceWait((int)fd, flags, (drmFence *) private, fence_type);
+}
+
+static int
+tUnref(struct _DriFenceMgr *mgr, void **private)
+{
+ long fd = (long) mgr->private;
+ drmFence *fence = (drmFence *) *private;
+ *private = NULL;
+
+ return drmFenceUnreference(fd, fence);
+}
+
+struct _DriFenceMgr *driFenceMgrTTMInit(int fd)
+{
+ struct _DriFenceMgrCreateInfo info;
+ struct _DriFenceMgr *mgr;
+
+ info.flags = DRI_FENCE_CLASS_ORDERED;
+ info.num_classes = 4;
+ info.signaled = tSignaled;
+ info.finish = tFinish;
+ info.unreference = tUnref;
+
+ mgr = driFenceMgrCreate(&info);
+ if (mgr == NULL)
+ return NULL;
+
+ mgr->private = (void *) (long) fd;
+ return mgr;
+}
+
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h
new file mode 100644
index 0000000000..4ea58dfe18
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h
@@ -0,0 +1,115 @@
+#ifndef DRI_FENCEMGR_H
+#define DRI_FENCEMGR_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+struct _DriFenceObject;
+struct _DriFenceMgr;
+
+/*
+ * Do a quick check to see if the fence manager has registered the fence
+ * object as signaled. Note that this function may return a false negative
+ * answer.
+ */
+extern uint32_t driFenceSignaledTypeCached(struct _DriFenceObject *fence);
+
+/*
+ * Check if the fence object is signaled. This function can be substantially
+ * more expensive to call than the above function, but will not return a false
+ * negative answer. The argument "flush_type" sets the types that the
+ * underlying mechanism must make sure will eventually signal.
+ */
+extern int driFenceSignaledType(struct _DriFenceObject *fence,
+ uint32_t flush_type, uint32_t *signaled);
+
+/*
+ * Convenience functions.
+ */
+
+static inline int driFenceSignaled(struct _DriFenceObject *fence,
+ uint32_t flush_type)
+{
+ uint32_t signaled_types;
+ int ret = driFenceSignaledType(fence, flush_type, &signaled_types);
+ if (ret)
+ return 0;
+ return ((signaled_types & flush_type) == flush_type);
+}
+
+static inline int driFenceSignaledCached(struct _DriFenceObject *fence,
+ uint32_t flush_type)
+{
+ uint32_t signaled_types =
+ driFenceSignaledTypeCached(fence);
+
+ return ((signaled_types & flush_type) == flush_type);
+}
+
+/*
+ * Reference a fence object.
+ */
+extern struct _DriFenceObject *driFenceReference(struct _DriFenceObject *fence);
+
+/*
+ * Unreference a fence object. The fence object pointer will be reset to NULL.
+ */
+
+extern void driFenceUnReference(struct _DriFenceObject **pFence);
+
+
+/*
+ * Wait for a fence to signal the indicated fence_type.
+ * If "lazy_hint" is true, it indicates that the wait may sleep to avoid
+ * busy-wait polling.
+ */
+extern int driFenceFinish(struct _DriFenceObject *fence, uint32_t fence_type,
+ int lazy_hint);
+
+/*
+ * Create a DriFenceObject for manager "mgr".
+ *
+ * "private" is a pointer that should be used for the callbacks in
+ * struct _DriFenceMgrCreateInfo.
+ *
+ * if private_size is nonzero, then the info stored at *private, with size
+ * private size will be copied and the fence manager will instead use a
+ * pointer to the copied data for the callbacks in
+ * struct _DriFenceMgrCreateInfo. In that case, the object pointed to by
+ * "private" may be destroyed after the call to driFenceCreate.
+ */
+extern struct _DriFenceObject *driFenceCreate(struct _DriFenceMgr *mgr,
+ uint32_t fence_class,
+ uint32_t fence_type,
+ void *private,
+ size_t private_size);
+
+extern uint32_t driFenceType(struct _DriFenceObject *fence);
+
+/*
+ * Fence creations are ordered. If a fence signals a fence_type,
+ * it is safe to assume that all fences of the same class that was
+ * created before that fence has signaled the same type.
+ */
+
+#define DRI_FENCE_CLASS_ORDERED (1 << 0)
+
+struct _DriFenceMgrCreateInfo {
+ uint32_t flags;
+ uint32_t num_classes;
+ int (*signaled) (struct _DriFenceMgr *mgr, void *private, uint32_t flush_type,
+ uint32_t *signaled_type);
+ int (*finish) (struct _DriFenceMgr *mgr, void *private, uint32_t fence_type, int lazy_hint);
+ int (*unreference) (struct _DriFenceMgr *mgr, void **private);
+};
+
+extern struct _DriFenceMgr *
+driFenceMgrCreate(const struct _DriFenceMgrCreateInfo *info);
+
+void
+driFenceMgrUnReference(struct _DriFenceMgr **pMgr);
+
+extern struct _DriFenceMgr *
+driFenceMgrTTMInit(int fd);
+
+#endif
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c
new file mode 100644
index 0000000000..bf97d7e440
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <xf86drm.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "imports.h"
+#include "glthread.h"
+#include "ws_dri_bufpool.h"
+#include "ws_dri_bufmgr.h"
+#include "intel_screen.h"
+
+static void *
+pool_create(struct _DriBufferPool *pool,
+ unsigned long size, uint64_t flags, unsigned hint,
+ unsigned alignment)
+{
+ unsigned long *private = malloc(size + 2*sizeof(unsigned long));
+ if ((flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_LOCAL)
+ abort();
+
+ *private = size;
+ return (void *)private;
+}
+
+
+static int
+pool_destroy(struct _DriBufferPool *pool, void *private)
+{
+ free(private);
+ return 0;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *pool, void *private,
+ _glthread_Mutex *mutex, int lazy)
+{
+ return 0;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ *virtual = (void *)((unsigned long *)private + 2);
+ return 0;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ return 0;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ /*
+ * BUG
+ */
+ abort();
+ return 0UL;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ /*
+ * BUG
+ */
+ abort();
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ return DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
+}
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ return *(unsigned long *) private;
+}
+
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ abort();
+ return 0UL;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ abort();
+ return NULL;
+}
+
+static void
+pool_takedown(struct _DriBufferPool *pool)
+{
+ free(pool);
+}
+
+
+struct _DriBufferPool *
+driMallocPoolInit(void)
+{
+ struct _DriBufferPool *pool;
+
+ pool = (struct _DriBufferPool *) malloc(sizeof(*pool));
+ if (!pool)
+ return NULL;
+
+ pool->data = NULL;
+ pool->fd = -1;
+ pool->map = &pool_map;
+ pool->unmap = &pool_unmap;
+ pool->destroy = &pool_destroy;
+ pool->offset = &pool_offset;
+ pool->poolOffset = &pool_poolOffset;
+ pool->flags = &pool_flags;
+ pool->size = &pool_size;
+ pool->create = &pool_create;
+ pool->fence = &pool_fence;
+ pool->kernel = &pool_kernel;
+ pool->validate = NULL;
+ pool->waitIdle = &pool_waitIdle;
+ pool->takeDown = &pool_takedown;
+ return pool;
+}
diff --git a/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c
new file mode 100644
index 0000000000..e69519a01f
--- /dev/null
+++ b/src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c
@@ -0,0 +1,970 @@
+/**************************************************************************
+ *
+ * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include "ws_dri_bufpool.h"
+#include "ws_dri_fencemgr.h"
+#include "ws_dri_bufmgr.h"
+#include "glthread.h"
+
+#define DRI_SLABPOOL_ALLOC_RETRIES 100
+
+struct _DriSlab;
+
+struct _DriSlabBuffer {
+ int isSlabBuffer;
+ drmBO *bo;
+ struct _DriFenceObject *fence;
+ struct _DriSlab *parent;
+ drmMMListHead head;
+ uint32_t mapCount;
+ uint32_t start;
+ uint32_t fenceType;
+ int unFenced;
+ _glthread_Cond event;
+};
+
+struct _DriKernelBO {
+ int fd;
+ drmBO bo;
+ drmMMListHead timeoutHead;
+ drmMMListHead head;
+ struct timeval timeFreed;
+ uint32_t pageAlignment;
+ void *virtual;
+};
+
+struct _DriSlab{
+ drmMMListHead head;
+ drmMMListHead freeBuffers;
+ uint32_t numBuffers;
+ uint32_t numFree;
+ struct _DriSlabBuffer *buffers;
+ struct _DriSlabSizeHeader *header;
+ struct _DriKernelBO *kbo;
+};
+
+
+struct _DriSlabSizeHeader {
+ drmMMListHead slabs;
+ drmMMListHead freeSlabs;
+ drmMMListHead delayedBuffers;
+ uint32_t numDelayed;
+ struct _DriSlabPool *slabPool;
+ uint32_t bufSize;
+ _glthread_Mutex mutex;
+};
+
+struct _DriFreeSlabManager {
+ struct timeval slabTimeout;
+ struct timeval checkInterval;
+ struct timeval nextCheck;
+ drmMMListHead timeoutList;
+ drmMMListHead unCached;
+ drmMMListHead cached;
+ _glthread_Mutex mutex;
+};
+
+
+struct _DriSlabPool {
+
+ /*
+ * The data of this structure remains constant after
+ * initialization and thus needs no mutex protection.
+ */
+
+ struct _DriFreeSlabManager *fMan;
+ uint64_t proposedFlags;
+ uint64_t validMask;
+ uint32_t *bucketSizes;
+ uint32_t numBuckets;
+ uint32_t pageSize;
+ int fd;
+ int pageAlignment;
+ int maxSlabSize;
+ int desiredNumBuffers;
+ struct _DriSlabSizeHeader *headers;
+};
+
+/*
+ * FIXME: Perhaps arrange timeout slabs in size buckets for fast
+ * retreival??
+ */
+
+
+static inline int
+driTimeAfterEq(struct timeval *arg1, struct timeval *arg2)
+{
+ return ((arg1->tv_sec > arg2->tv_sec) ||
+ ((arg1->tv_sec == arg2->tv_sec) &&
+ (arg1->tv_usec > arg2->tv_usec)));
+}
+
+static inline void
+driTimeAdd(struct timeval *arg, struct timeval *add)
+{
+ unsigned int sec;
+
+ arg->tv_sec += add->tv_sec;
+ arg->tv_usec += add->tv_usec;
+ sec = arg->tv_usec / 1000000;
+ arg->tv_sec += sec;
+ arg->tv_usec -= sec*1000000;
+}
+
+static void
+driFreeKernelBO(struct _DriKernelBO *kbo)
+{
+ if (!kbo)
+ return;
+
+ (void) drmBOUnreference(kbo->fd, &kbo->bo);
+ free(kbo);
+}
+
+
+static void
+driFreeTimeoutKBOsLocked(struct _DriFreeSlabManager *fMan,
+ struct timeval *time)
+{
+ drmMMListHead *list, *next;
+ struct _DriKernelBO *kbo;
+
+ if (!driTimeAfterEq(time, &fMan->nextCheck))
+ return;
+
+ for (list = fMan->timeoutList.next, next = list->next;
+ list != &fMan->timeoutList;
+ list = next, next = list->next) {
+
+ kbo = DRMLISTENTRY(struct _DriKernelBO, list, timeoutHead);
+
+ if (!driTimeAfterEq(time, &kbo->timeFreed))
+ break;
+
+ DRMLISTDELINIT(&kbo->timeoutHead);
+ DRMLISTDELINIT(&kbo->head);
+ driFreeKernelBO(kbo);
+ }
+
+ fMan->nextCheck = *time;
+ driTimeAdd(&fMan->nextCheck, &fMan->checkInterval);
+}
+
+
+/*
+ * Add a _DriKernelBO to the free slab manager.
+ * This means that it is available for reuse, but if it's not
+ * reused in a while, it will be freed.
+ */
+
+static void
+driSetKernelBOFree(struct _DriFreeSlabManager *fMan,
+ struct _DriKernelBO *kbo)
+{
+ struct timeval time;
+
+ _glthread_LOCK_MUTEX(fMan->mutex);
+ gettimeofday(&time, NULL);
+ driTimeAdd(&time, &fMan->slabTimeout);
+
+ kbo->timeFreed = time;
+
+ if (kbo->bo.flags & DRM_BO_FLAG_CACHED)
+ DRMLISTADD(&kbo->head, &fMan->cached);
+ else
+ DRMLISTADD(&kbo->head, &fMan->unCached);
+
+ DRMLISTADDTAIL(&kbo->timeoutHead, &fMan->timeoutList);
+ driFreeTimeoutKBOsLocked(fMan, &time);
+
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+}
+
+/*
+ * Get a _DriKernelBO for us to use as storage for a slab.
+ *
+ */
+
+static struct _DriKernelBO *
+driAllocKernelBO(struct _DriSlabSizeHeader *header)
+
+{
+ struct _DriSlabPool *slabPool = header->slabPool;
+ struct _DriFreeSlabManager *fMan = slabPool->fMan;
+ drmMMListHead *list, *next, *head;
+ uint32_t size = header->bufSize * slabPool->desiredNumBuffers;
+ struct _DriKernelBO *kbo;
+ struct _DriKernelBO *kboTmp;
+ int ret;
+
+ /*
+ * FIXME: We should perhaps allow some variation in slabsize in order
+ * to efficiently reuse slabs.
+ */
+
+ size = (size <= slabPool->maxSlabSize) ? size : slabPool->maxSlabSize;
+ size = (size + slabPool->pageSize - 1) & ~(slabPool->pageSize - 1);
+ _glthread_LOCK_MUTEX(fMan->mutex);
+
+ kbo = NULL;
+
+ retry:
+ head = (slabPool->proposedFlags & DRM_BO_FLAG_CACHED) ?
+ &fMan->cached : &fMan->unCached;
+
+ for (list = head->next, next = list->next;
+ list != head;
+ list = next, next = list->next) {
+
+ kboTmp = DRMLISTENTRY(struct _DriKernelBO, list, head);
+
+ if ((kboTmp->bo.size == size) &&
+ (slabPool->pageAlignment == 0 ||
+ (kboTmp->pageAlignment % slabPool->pageAlignment) == 0)) {
+
+ if (!kbo)
+ kbo = kboTmp;
+
+ if ((kbo->bo.proposedFlags ^ slabPool->proposedFlags) == 0)
+ break;
+
+ }
+ }
+
+ if (kbo) {
+ DRMLISTDELINIT(&kbo->head);
+ DRMLISTDELINIT(&kbo->timeoutHead);
+ }
+
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+
+ if (kbo) {
+ uint64_t new_mask = kbo->bo.proposedFlags ^ slabPool->proposedFlags;
+
+ ret = 0;
+ if (new_mask) {
+ ret = drmBOSetStatus(kbo->fd, &kbo->bo, slabPool->proposedFlags,
+ new_mask, DRM_BO_HINT_DONT_FENCE, 0, 0);
+ }
+ if (ret == 0)
+ return kbo;
+
+ driFreeKernelBO(kbo);
+ kbo = NULL;
+ goto retry;
+ }
+
+ kbo = calloc(1, sizeof(struct _DriKernelBO));
+ if (!kbo)
+ return NULL;
+
+ kbo->fd = slabPool->fd;
+ DRMINITLISTHEAD(&kbo->head);
+ DRMINITLISTHEAD(&kbo->timeoutHead);
+ ret = drmBOCreate(kbo->fd, size, slabPool->pageAlignment, NULL,
+ slabPool->proposedFlags,
+ DRM_BO_HINT_DONT_FENCE, &kbo->bo);
+ if (ret)
+ goto out_err0;
+
+ ret = drmBOMap(kbo->fd, &kbo->bo,
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+ 0, &kbo->virtual);
+
+ if (ret)
+ goto out_err1;
+
+ ret = drmBOUnmap(kbo->fd, &kbo->bo);
+ if (ret)
+ goto out_err1;
+
+ return kbo;
+
+ out_err1:
+ drmBOUnreference(kbo->fd, &kbo->bo);
+ out_err0:
+ free(kbo);
+ return NULL;
+}
+
+
+static int
+driAllocSlab(struct _DriSlabSizeHeader *header)
+{
+ struct _DriSlab *slab;
+ struct _DriSlabBuffer *buf;
+ uint32_t numBuffers;
+ int ret;
+ int i;
+
+ slab = calloc(1, sizeof(*slab));
+ if (!slab)
+ return -ENOMEM;
+
+ slab->kbo = driAllocKernelBO(header);
+ if (!slab->kbo) {
+ ret = -ENOMEM;
+ goto out_err0;
+ }
+
+ numBuffers = slab->kbo->bo.size / header->bufSize;
+
+ slab->buffers = calloc(numBuffers, sizeof(*slab->buffers));
+ if (!slab->buffers) {
+ ret = -ENOMEM;
+ goto out_err1;
+ }
+
+ DRMINITLISTHEAD(&slab->head);
+ DRMINITLISTHEAD(&slab->freeBuffers);
+ slab->numBuffers = numBuffers;
+ slab->numFree = 0;
+ slab->header = header;
+
+ buf = slab->buffers;
+ for (i=0; i < numBuffers; ++i) {
+ buf->parent = slab;
+ buf->start = i* header->bufSize;
+ buf->mapCount = 0;
+ buf->isSlabBuffer = 1;
+ _glthread_INIT_COND(buf->event);
+ DRMLISTADDTAIL(&buf->head, &slab->freeBuffers);
+ slab->numFree++;
+ buf++;
+ }
+
+ DRMLISTADDTAIL(&slab->head, &header->slabs);
+
+ return 0;
+
+ out_err1:
+ driSetKernelBOFree(header->slabPool->fMan, slab->kbo);
+ free(slab->buffers);
+ out_err0:
+ free(slab);
+ return ret;
+}
+
+/*
+ * Delete a buffer from the slab header delayed list and put
+ * it on the slab free list.
+ */
+
+static void
+driSlabFreeBufferLocked(struct _DriSlabBuffer *buf)
+{
+ struct _DriSlab *slab = buf->parent;
+ struct _DriSlabSizeHeader *header = slab->header;
+ drmMMListHead *list = &buf->head;
+
+ DRMLISTDEL(list);
+ DRMLISTADDTAIL(list, &slab->freeBuffers);
+ slab->numFree++;
+
+ if (slab->head.next == &slab->head)
+ DRMLISTADDTAIL(&slab->head, &header->slabs);
+
+ if (slab->numFree == slab->numBuffers) {
+ list = &slab->head;
+ DRMLISTDEL(list);
+ DRMLISTADDTAIL(list, &header->freeSlabs);
+ }
+
+ if (header->slabs.next == &header->slabs ||
+ slab->numFree != slab->numBuffers) {
+
+ drmMMListHead *next;
+ struct _DriFreeSlabManager *fMan = header->slabPool->fMan;
+
+ for (list = header->freeSlabs.next, next = list->next;
+ list != &header->freeSlabs;
+ list = next, next = list->next) {
+
+ slab = DRMLISTENTRY(struct _DriSlab, list, head);
+
+ DRMLISTDELINIT(list);
+ driSetKernelBOFree(fMan, slab->kbo);
+ free(slab->buffers);
+ free(slab);
+ }
+ }
+}
+
+static void
+driSlabCheckFreeLocked(struct _DriSlabSizeHeader *header, int wait)
+{
+ drmMMListHead *list, *prev, *first;
+ struct _DriSlabBuffer *buf;
+ struct _DriSlab *slab;
+ int firstWasSignaled = 1;
+ int signaled;
+ int i;
+ int ret;
+
+ /*
+ * Rerun the freeing test if the youngest tested buffer
+ * was signaled, since there might be more idle buffers
+ * in the delay list.
+ */
+
+ while (firstWasSignaled) {
+ firstWasSignaled = 0;
+ signaled = 0;
+ first = header->delayedBuffers.next;
+
+ /* Only examine the oldest 1/3 of delayed buffers:
+ */
+ if (header->numDelayed > 3) {
+ for (i = 0; i < header->numDelayed; i += 3) {
+ first = first->next;
+ }
+ }
+
+ for (list = first, prev = list->prev;
+ list != &header->delayedBuffers;
+ list = prev, prev = list->prev) {
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head);
+ slab = buf->parent;
+
+ if (!signaled) {
+ if (wait) {
+ ret = driFenceFinish(buf->fence, buf->fenceType, 0);
+ if (ret)
+ break;
+ signaled = 1;
+ wait = 0;
+ } else {
+ signaled = driFenceSignaled(buf->fence, buf->fenceType);
+ }
+ if (signaled) {
+ if (list == first)
+ firstWasSignaled = 1;
+ driFenceUnReference(&buf->fence);
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ } else if (driFenceSignaledCached(buf->fence, buf->fenceType)) {
+ driFenceUnReference(&buf->fence);
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ }
+ }
+}
+
+
+static struct _DriSlabBuffer *
+driSlabAllocBuffer(struct _DriSlabSizeHeader *header)
+{
+ static struct _DriSlabBuffer *buf;
+ struct _DriSlab *slab;
+ drmMMListHead *list;
+ int count = DRI_SLABPOOL_ALLOC_RETRIES;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ while(header->slabs.next == &header->slabs && count > 0) {
+ driSlabCheckFreeLocked(header, 0);
+ if (header->slabs.next != &header->slabs)
+ break;
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ if (count != DRI_SLABPOOL_ALLOC_RETRIES)
+ usleep(1);
+ _glthread_LOCK_MUTEX(header->mutex);
+ (void) driAllocSlab(header);
+ count--;
+ }
+
+ list = header->slabs.next;
+ if (list == &header->slabs) {
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ return NULL;
+ }
+ slab = DRMLISTENTRY(struct _DriSlab, list, head);
+ if (--slab->numFree == 0)
+ DRMLISTDELINIT(list);
+
+ list = slab->freeBuffers.next;
+ DRMLISTDELINIT(list);
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list, head);
+ return buf;
+}
+
+static void *
+pool_create(struct _DriBufferPool *driPool, unsigned long size,
+ uint64_t flags, unsigned hint, unsigned alignment)
+{
+ struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data;
+ struct _DriSlabSizeHeader *header;
+ struct _DriSlabBuffer *buf;
+ void *dummy;
+ int i;
+ int ret;
+
+ /*
+ * FIXME: Check for compatibility.
+ */
+ header = pool->headers;
+ for (i=0; i<pool->numBuckets; ++i) {
+ if (header->bufSize >= size)
+ break;
+ header++;
+ }
+
+ if (i < pool->numBuckets)
+ return driSlabAllocBuffer(header);
+
+
+ /*
+ * Fall back to allocate a buffer object directly from DRM.
+ * and wrap it in a driBO structure.
+ */
+
+
+ buf = calloc(1, sizeof(*buf));
+
+ if (!buf)
+ return NULL;
+
+ buf->bo = calloc(1, sizeof(*buf->bo));
+ if (!buf->bo)
+ goto out_err0;
+
+ if (alignment) {
+ if ((alignment < pool->pageSize) && (pool->pageSize % alignment))
+ goto out_err1;
+ if ((alignment > pool->pageSize) && (alignment % pool->pageSize))
+ goto out_err1;
+ }
+
+ ret = drmBOCreate(pool->fd, size, alignment / pool->pageSize, NULL,
+ flags, hint, buf->bo);
+ if (ret)
+ goto out_err1;
+
+ ret = drmBOMap(pool->fd, buf->bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE,
+ 0, &dummy);
+ if (ret)
+ goto out_err2;
+
+ ret = drmBOUnmap(pool->fd, buf->bo);
+ if (ret)
+ goto out_err2;
+
+ return buf;
+ out_err2:
+ drmBOUnreference(pool->fd, buf->bo);
+ out_err1:
+ free(buf->bo);
+ out_err0:
+ free(buf);
+ return NULL;
+}
+
+static int
+pool_destroy(struct _DriBufferPool *driPool, void *private)
+{
+ struct _DriSlabBuffer *buf =
+ (struct _DriSlabBuffer *) private;
+ struct _DriSlab *slab;
+ struct _DriSlabSizeHeader *header;
+
+ if (!buf->isSlabBuffer) {
+ struct _DriSlabPool *pool = (struct _DriSlabPool *) driPool->data;
+ int ret;
+
+ ret = drmBOUnreference(pool->fd, buf->bo);
+ free(buf->bo);
+ free(buf);
+ return ret;
+ }
+
+ slab = buf->parent;
+ header = slab->header;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ buf->unFenced = 0;
+ buf->mapCount = 0;
+
+ if (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType)) {
+ DRMLISTADDTAIL(&buf->head, &header->delayedBuffers);
+ header->numDelayed++;
+ } else {
+ if (buf->fence)
+ driFenceUnReference(&buf->fence);
+ driSlabFreeBufferLocked(buf);
+ }
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+ return 0;
+}
+
+static int
+pool_waitIdle(struct _DriBufferPool *driPool, void *private,
+ _glthread_Mutex *mutex, int lazy)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ while(buf->unFenced)
+ _glthread_COND_WAIT(buf->event, *mutex);
+
+ if (!buf->fence)
+ return 0;
+
+ driFenceFinish(buf->fence, buf->fenceType, lazy);
+ driFenceUnReference(&buf->fence);
+
+ return 0;
+}
+
+static int
+pool_map(struct _DriBufferPool *pool, void *private, unsigned flags,
+ int hint, _glthread_Mutex *mutex, void **virtual)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ int busy;
+
+ if (buf->isSlabBuffer)
+ busy = buf->unFenced || (buf->fence && !driFenceSignaledCached(buf->fence, buf->fenceType));
+ else
+ busy = buf->fence && !driFenceSignaled(buf->fence, buf->fenceType);
+
+
+ if (busy) {
+ if (hint & DRM_BO_HINT_DONT_BLOCK)
+ return -EBUSY;
+ else {
+ (void) pool_waitIdle(pool, private, mutex, 0);
+ }
+ }
+
+ ++buf->mapCount;
+ *virtual = (buf->isSlabBuffer) ?
+ (void *) ((uint8_t *) buf->parent->kbo->virtual + buf->start) :
+ (void *) buf->bo->virtual;
+
+ return 0;
+}
+
+static int
+pool_unmap(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ --buf->mapCount;
+ if (buf->mapCount == 0 && buf->isSlabBuffer)
+ _glthread_COND_BROADCAST(buf->event);
+
+ return 0;
+}
+
+static unsigned long
+pool_offset(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ struct _DriSlab *slab;
+ struct _DriSlabSizeHeader *header;
+
+ if (!buf->isSlabBuffer) {
+ assert(buf->bo->proposedFlags & DRM_BO_FLAG_NO_MOVE);
+ return buf->bo->offset;
+ }
+
+ slab = buf->parent;
+ header = slab->header;
+
+ (void) header;
+ assert(header->slabPool->proposedFlags & DRM_BO_FLAG_NO_MOVE);
+ return slab->kbo->bo.offset + buf->start;
+}
+
+static unsigned long
+pool_poolOffset(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ return buf->start;
+}
+
+static uint64_t
+pool_flags(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ if (!buf->isSlabBuffer)
+ return buf->bo->flags;
+
+ return buf->parent->kbo->bo.flags;
+}
+
+static unsigned long
+pool_size(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ if (!buf->isSlabBuffer)
+ return buf->bo->size;
+
+ return buf->parent->header->bufSize;
+}
+
+static int
+pool_fence(struct _DriBufferPool *pool, void *private,
+ struct _DriFenceObject *fence)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+ drmBO *bo;
+
+ if (buf->fence)
+ driFenceUnReference(&buf->fence);
+
+ buf->fence = driFenceReference(fence);
+ bo = (buf->isSlabBuffer) ?
+ &buf->parent->kbo->bo:
+ buf->bo;
+ buf->fenceType = bo->fenceFlags;
+
+ buf->unFenced = 0;
+ _glthread_COND_BROADCAST(buf->event);
+
+ return 0;
+}
+
+static drmBO *
+pool_kernel(struct _DriBufferPool *pool, void *private)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ if (!buf)
+ return NULL;
+
+ return (buf->isSlabBuffer) ? &buf->parent->kbo->bo : buf->bo;
+}
+
+static int
+pool_validate(struct _DriBufferPool *pool, void *private,
+ _glthread_Mutex *mutex)
+{
+ struct _DriSlabBuffer *buf = (struct _DriSlabBuffer *) private;
+
+ if (!buf->isSlabBuffer)
+ return 0;
+
+ while(buf->mapCount != 0)
+ _glthread_COND_WAIT(buf->event, *mutex);
+
+ buf->unFenced = 1;
+ return 0;
+}
+
+
+struct _DriFreeSlabManager *
+driInitFreeSlabManager(uint32_t checkIntervalMsec, uint32_t slabTimeoutMsec)
+{
+ struct _DriFreeSlabManager *tmp;
+
+ tmp = calloc(1, sizeof(*tmp));
+ if (!tmp)
+ return NULL;
+
+ _glthread_INIT_MUTEX(tmp->mutex);
+ _glthread_LOCK_MUTEX(tmp->mutex);
+ tmp->slabTimeout.tv_usec = slabTimeoutMsec*1000;
+ tmp->slabTimeout.tv_sec = tmp->slabTimeout.tv_usec / 1000000;
+ tmp->slabTimeout.tv_usec -= tmp->slabTimeout.tv_sec*1000000;
+
+ tmp->checkInterval.tv_usec = checkIntervalMsec*1000;
+ tmp->checkInterval.tv_sec = tmp->checkInterval.tv_usec / 1000000;
+ tmp->checkInterval.tv_usec -= tmp->checkInterval.tv_sec*1000000;
+
+ gettimeofday(&tmp->nextCheck, NULL);
+ driTimeAdd(&tmp->nextCheck, &tmp->checkInterval);
+ DRMINITLISTHEAD(&tmp->timeoutList);
+ DRMINITLISTHEAD(&tmp->unCached);
+ DRMINITLISTHEAD(&tmp->cached);
+ _glthread_UNLOCK_MUTEX(tmp->mutex);
+
+ return tmp;
+}
+
+void
+driFinishFreeSlabManager(struct _DriFreeSlabManager *fMan)
+{
+ struct timeval time;
+
+ time = fMan->nextCheck;
+ driTimeAdd(&time, &fMan->checkInterval);
+
+ _glthread_LOCK_MUTEX(fMan->mutex);
+ driFreeTimeoutKBOsLocked(fMan, &time);
+ _glthread_UNLOCK_MUTEX(fMan->mutex);
+
+ assert(fMan->timeoutList.next == &fMan->timeoutList);
+ assert(fMan->unCached.next == &fMan->unCached);
+ assert(fMan->cached.next == &fMan->cached);
+
+ free(fMan);
+}
+
+static void
+driInitSizeHeader(struct _DriSlabPool *pool, uint32_t size,
+ struct _DriSlabSizeHeader *header)
+{
+ _glthread_INIT_MUTEX(header->mutex);
+ _glthread_LOCK_MUTEX(header->mutex);
+
+ DRMINITLISTHEAD(&header->slabs);
+ DRMINITLISTHEAD(&header->freeSlabs);
+ DRMINITLISTHEAD(&header->delayedBuffers);
+
+ header->numDelayed = 0;
+ header->slabPool = pool;
+ header->bufSize = size;
+
+ _glthread_UNLOCK_MUTEX(header->mutex);
+}
+
+static void
+driFinishSizeHeader(struct _DriSlabSizeHeader *header)
+{
+ drmMMListHead *list, *next;
+ struct _DriSlabBuffer *buf;
+
+ _glthread_LOCK_MUTEX(header->mutex);
+ for (list = header->delayedBuffers.next, next = list->next;
+ list != &header->delayedBuffers;
+ list = next, next = list->next) {
+
+ buf = DRMLISTENTRY(struct _DriSlabBuffer, list , head);
+ if (buf->fence) {
+ (void) driFenceFinish(buf->fence, buf->fenceType, 0);
+ driFenceUnReference(&buf->fence);
+ }
+ header->numDelayed--;
+ driSlabFreeBufferLocked(buf);
+ }
+ _glthread_UNLOCK_MUTEX(header->mutex);
+}
+
+static void
+pool_takedown(struct _DriBufferPool *driPool)
+{
+ struct _DriSlabPool *pool = driPool->data;
+ int i;
+
+ for (i=0; i<pool->numBuckets; ++i) {
+ driFinishSizeHeader(&pool->headers[i]);
+ }
+
+ free(pool->headers);
+ free(pool->bucketSizes);
+ free(pool);
+ free(driPool);
+}
+
+struct _DriBufferPool *
+driSlabPoolInit(int fd, uint64_t flags,
+ uint64_t validMask,
+ uint32_t smallestSize,
+ uint32_t numSizes,
+ uint32_t desiredNumBuffers,
+ uint32_t maxSlabSize,
+ uint32_t pageAlignment,
+ struct _DriFreeSlabManager *fMan)
+{
+ struct _DriBufferPool *driPool;
+ struct _DriSlabPool *pool;
+ uint32_t i;
+
+ driPool = calloc(1, sizeof(*driPool));
+ if (!driPool)
+ return NULL;
+
+ pool = calloc(1, sizeof(*pool));
+ if (!pool)
+ goto out_err0;
+
+ pool->bucketSizes = calloc(numSizes, sizeof(*pool->bucketSizes));
+ if (!pool->bucketSizes)
+ goto out_err1;
+
+ pool->headers = calloc(numSizes, sizeof(*pool->headers));
+ if (!pool->headers)
+ goto out_err2;
+
+ pool->fMan = fMan;
+ pool->proposedFlags = flags;
+ pool->validMask = validMask;
+ pool->numBuckets = numSizes;
+ pool->pageSize = getpagesize();
+ pool->fd = fd;
+ pool->pageAlignment = pageAlignment;
+ pool->maxSlabSize = maxSlabSize;
+ pool->desiredNumBuffers = desiredNumBuffers;
+
+ for (i=0; i<pool->numBuckets; ++i) {
+ pool->bucketSizes[i] = (smallestSize << i);
+ driInitSizeHeader(pool, pool->bucketSizes[i],
+ &pool->headers[i]);
+ }
+
+ driPool->data = (void *) pool;
+ driPool->map = &pool_map;
+ driPool->unmap = &pool_unmap;
+ driPool->destroy = &pool_destroy;
+ driPool->offset = &pool_offset;
+ driPool->poolOffset = &pool_poolOffset;
+ driPool->flags = &pool_flags;
+ driPool->size = &pool_size;
+ driPool->create = &pool_create;
+ driPool->fence = &pool_fence;
+ driPool->kernel = &pool_kernel;
+ driPool->validate = &pool_validate;
+ driPool->waitIdle = &pool_waitIdle;
+ driPool->takeDown = &pool_takedown;
+
+ return driPool;
+
+ out_err2:
+ free(pool->bucketSizes);
+ out_err1:
+ free(pool);
+ out_err0:
+ free(driPool);
+
+ return NULL;
+}
diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile
new file mode 100644
index 0000000000..fe4b931e30
--- /dev/null
+++ b/src/gallium/winsys/egl_xlib/Makefile
@@ -0,0 +1,87 @@
+# src/gallium/winsys/egl_xlib/Makefile
+
+# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so"
+
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+
+LIBNAME = softpipe_egl.so
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary
+
+WINSYS_SOURCES = \
+ egl_xlib.c \
+ sw_winsys.c
+
+WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o)
+
+
+LIBS = \
+ $(GALLIUM_DRIVERS) \
+ $(TOP)/src/mesa/libglapi.a \
+ $(TOP)/src/mesa/libmesa.a \
+ $(GALLIUM_AUXILIARIES)
+
+
+LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1
+
+
+.SUFFIXES : .cpp
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@
+
+
+
+default: $(TOP)/$(LIB_DIR)/$(LIBNAME)
+
+
+# Make the softpipe_egl.so library
+$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS)
+ $(TOP)/bin/mklib -o $(LIBNAME) \
+ -linker "$(CC)" \
+ -noprefix \
+ -install $(TOP)/$(LIB_DIR) \
+ $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \
+ --start-group $(LIBS) --end-group
+
+# $(GL_LIB_DEPS)
+
+
+depend: $(ALL_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend # workaround oops on gutsy?!?
+ @ touch depend
+ @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
+ > /dev/null 2>/dev/null
+
+
+install: default
+ $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
+ @if [ -e $(TOP)/$(LIB_DIR) ]; then \
+ $(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \
+ fi
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+ -rm -f *.o *~ *.bak
+
+
+include depend
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
new file mode 100644
index 0000000000..99389970f5
--- /dev/null
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -0,0 +1,559 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * EGL / softpipe / xlib winsys module
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include <X11/Xutil.h>
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+#include "pipe/p_util.h"
+#include "pipe/p_winsys.h"
+#include "softpipe/sp_winsys.h"
+
+#include "eglconfig.h"
+#include "eglconfigutil.h"
+#include "eglcontext.h"
+#include "egldisplay.h"
+#include "egldriver.h"
+#include "eglglobals.h"
+#include "egllog.h"
+#include "eglsurface.h"
+
+#include "state_tracker/st_public.h"
+
+#include "sw_winsys.h"
+
+
+/** subclass of _EGLDriver */
+struct xlib_egl_driver
+{
+ _EGLDriver Base; /**< base class */
+
+ struct pipe_winsys *winsys;
+ struct pipe_screen *screen;
+};
+
+
+/** subclass of _EGLContext */
+struct xlib_egl_context
+{
+ _EGLContext Base; /**< base class */
+
+ struct pipe_context *pipe; /**< Gallium driver context */
+ struct st_context *Context; /**< Mesa/gallium state tracker context */
+};
+
+
+/** subclass of _EGLSurface */
+struct xlib_egl_surface
+{
+ _EGLSurface Base; /**< base class */
+
+ Display *Dpy; /**< The X Display of the window */
+ Window Win; /**< The user-created window ID */
+ GC Gc;
+ XVisualInfo VisInfo;
+
+ struct pipe_winsys *winsys;
+
+ struct st_framebuffer *Framebuffer;
+};
+
+
+/** cast wrapper */
+static INLINE struct xlib_egl_driver *
+xlib_egl_driver(_EGLDriver *drv)
+{
+ return (struct xlib_egl_driver *) drv;
+}
+
+
+static struct xlib_egl_surface *
+lookup_surface(EGLSurface surf)
+{
+ _EGLSurface *surface = _eglLookupSurface(surf);
+ return (struct xlib_egl_surface *) surface;
+}
+
+
+static struct xlib_egl_context *
+lookup_context(EGLContext surf)
+{
+ _EGLContext *context = _eglLookupContext(surf);
+ return (struct xlib_egl_context *) context;
+}
+
+
+/**
+ * XXX temporary
+ * Need to query X server's GLX visuals.
+ */
+static void
+init_configs(_EGLDriver *drv, EGLDisplay dpy)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ _EGLConfig config;
+ int id = i + 1;
+ _eglInitConfig(&config, id);
+ SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8);
+ SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8);
+ SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8);
+ SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8);
+ if (i > 0) {
+ SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24);
+ SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8);
+ }
+ _eglAddConfig(disp, &config);
+ }
+}
+
+
+
+/**
+ * Called via eglInitialize(), drv->API.Initialize().
+ */
+static EGLBoolean
+xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
+ EGLint *minor, EGLint *major)
+{
+ /* visual configs */
+
+ init_configs(drv, dpy);
+
+
+ drv->Initialized = EGL_TRUE;
+
+ /* we're supporting EGL 1.4 */
+ *minor = 1;
+ *major = 4;
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Called via eglTerminate(), drv->API.Terminate().
+ */
+static EGLBoolean
+xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+{
+
+ return EGL_TRUE;
+}
+
+
+static _EGLProc
+xlib_eglGetProcAddress(const char *procname)
+{
+ /* XXX for each supported API, evaluate GetProcAddress(name) */
+ /*
+ return _glapi_get_proc_address(procname);
+ */
+ return NULL;
+}
+
+
+static void
+get_drawable_visual_info(Display *dpy, Drawable d, XVisualInfo *visInfo)
+{
+ XWindowAttributes attr;
+ XVisualInfo visTemp, *vis;
+ int num_visuals;
+
+ XGetWindowAttributes(dpy, d, &attr);
+
+ visTemp.screen = DefaultScreen(dpy);
+ visTemp.visualid = attr.visual->visualid;
+ vis = XGetVisualInfo(dpy,
+ (VisualScreenMask | VisualIDMask),
+ &visTemp, &num_visuals);
+ if (vis)
+ *visInfo = *vis;
+
+ XFree(vis);
+}
+
+
+
+/** Get size of given window */
+static Status
+get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
+{
+ Window root;
+ Status stat;
+ int xpos, ypos;
+ unsigned int w, h, bw, depth;
+ stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
+ *width = w;
+ *height = h;
+ return stat;
+}
+
+
+static void
+check_and_update_buffer_size(struct xlib_egl_surface *surface)
+{
+ uint width, height;
+ get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ st_resize_framebuffer(surface->Framebuffer, width, height);
+ surface->Base.Width = width;
+ surface->Base.Height = height;
+}
+
+
+
+static void
+display_surface(struct pipe_winsys *pws,
+ struct pipe_surface *psurf,
+ struct xlib_egl_surface *xsurf)
+{
+ XImage *ximage;
+ void *data;
+
+ ximage = XCreateImage(xsurf->Dpy,
+ xsurf->VisInfo.visual,
+ xsurf->VisInfo.depth,
+ ZPixmap, 0, /* format, offset */
+ NULL, /* data */
+ 0, 0, /* size */
+ 32, /* bitmap_pad */
+ 0); /* bytes_per_line */
+
+
+ assert(ximage->format);
+ assert(ximage->bitmap_unit);
+
+ data = pws->buffer_map(pws, psurf->buffer, 0);
+
+ /* update XImage's fields */
+ ximage->data = data;
+ ximage->width = psurf->width;
+ ximage->height = psurf->height;
+ ximage->bytes_per_line = psurf->pitch * psurf->cpp;
+
+ XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
+ ximage, 0, 0, 0, 0, psurf->width, psurf->height);
+
+ XSync(xsurf->Dpy, 0);
+
+ ximage->data = NULL;
+ XDestroyImage(ximage);
+
+ pws->buffer_unmap(pws, psurf->buffer);
+}
+
+
+
+/** Display gallium surface in X window */
+static void
+flush_frontbuffer(struct pipe_winsys *pws,
+ struct pipe_surface *psurf,
+ void *context_private)
+{
+ struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private;
+ display_surface(pws, psurf, xsurf);
+}
+
+
+
+/**
+ * Called via eglCreateContext(), drv->API.CreateContext().
+ */
+static EGLContext
+xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ EGLContext share_list, const EGLint *attrib_list)
+{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+ struct xlib_egl_context *ctx;
+ struct st_context *share_ctx = NULL; /* XXX fix */
+ __GLcontextModes visual;
+
+ ctx = CALLOC_STRUCT(xlib_egl_context);
+ if (!ctx)
+ return EGL_NO_CONTEXT;
+
+ /* let EGL lib init the common stuff */
+ if (!_eglInitContext(drv, dpy, &ctx->Base, config, attrib_list)) {
+ free(ctx);
+ return EGL_NO_CONTEXT;
+ }
+
+ if (ctx->Base.ClientAPI != EGL_OPENGL_API) {
+ _eglError(EGL_BAD_MATCH, "eglCreateContext(only OpenGL API supported)");
+ free(ctx);
+ return EGL_NO_CONTEXT;
+ }
+
+ /* create a softpipe context */
+ ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL);
+
+ /* Now do xlib / state tracker inits here */
+ _eglConfigToContextModesRec(conf, &visual);
+ ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx);
+
+ _eglSaveContext(&ctx->Base);
+
+ return _eglGetContextHandle(&ctx->Base);
+}
+
+
+static EGLBoolean
+xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+{
+ struct xlib_egl_context *context = lookup_context(ctx);
+ if (context) {
+ if (context->Base.IsBound) {
+ context->Base.DeletePending = EGL_TRUE;
+ }
+ else {
+ st_destroy_context(context->Context);
+ free(context);
+ }
+ return EGL_TRUE;
+ }
+ else {
+ _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
+ return EGL_TRUE;
+ }
+}
+
+
+/**
+ * Called via eglMakeCurrent(), drv->API.MakeCurrent().
+ */
+static EGLBoolean
+xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy,
+ EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ struct xlib_egl_context *context = lookup_context(ctx);
+ struct xlib_egl_surface *draw_surf = lookup_surface(draw);
+ struct xlib_egl_surface *read_surf = lookup_surface(read);
+
+ if (!_eglMakeCurrent(drv, dpy, draw, read, context))
+ return EGL_FALSE;
+
+ st_make_current((context ? context->Context : NULL),
+ (draw_surf ? draw_surf->Framebuffer : NULL),
+ (read_surf ? read_surf->Framebuffer : NULL));
+
+ check_and_update_buffer_size(draw_surf);
+
+ return EGL_TRUE;
+}
+
+
+static enum pipe_format
+choose_color_format(const __GLcontextModes *visual)
+{
+ if (visual->redBits == 8 &&
+ visual->greenBits == 8 &&
+ visual->blueBits == 8 &&
+ visual->alphaBits == 8) {
+ /* XXX this really also depends on the ordering of R,G,B,A */
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ }
+ else {
+ assert(0);
+ return PIPE_FORMAT_NONE;
+ }
+}
+
+
+static enum pipe_format
+choose_depth_format(const __GLcontextModes *visual)
+{
+ if (visual->depthBits > 0)
+ return PIPE_FORMAT_S8Z24_UNORM;
+ else
+ return PIPE_FORMAT_NONE;
+}
+
+
+static enum pipe_format
+choose_stencil_format(const __GLcontextModes *visual)
+{
+ if (visual->stencilBits > 0)
+ return PIPE_FORMAT_S8Z24_UNORM;
+ else
+ return PIPE_FORMAT_NONE;
+}
+
+
+/**
+ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
+ */
+static EGLSurface
+xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window, const EGLint *attrib_list)
+{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+
+ struct xlib_egl_surface *surf;
+ __GLcontextModes visual;
+ uint width, height;
+
+ surf = CALLOC_STRUCT(xlib_egl_surface);
+ if (!surf)
+ return EGL_NO_SURFACE;
+
+ /* Let EGL lib init the common stuff */
+ if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT,
+ config, attrib_list)) {
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+
+ _eglSaveSurface(&surf->Base);
+
+ /*
+ * Now init the Xlib and gallium stuff
+ */
+ surf->Win = (Window) window; /* The X window ID */
+ surf->Dpy = disp->Xdpy; /* The X display */
+ surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL);
+
+ surf->winsys = xdrv->winsys;
+
+ _eglConfigToContextModesRec(conf, &visual);
+ get_drawable_size(surf->Dpy, surf->Win, &width, &height);
+ get_drawable_visual_info(surf->Dpy, surf->Win, &surf->VisInfo);
+
+ surf->Base.Width = width;
+ surf->Base.Height = height;
+
+ /* Create GL statetracker framebuffer */
+ surf->Framebuffer = st_create_framebuffer(&visual,
+ choose_color_format(&visual),
+ choose_depth_format(&visual),
+ choose_stencil_format(&visual),
+ width, height,
+ (void *) surf);
+
+ st_resize_framebuffer(surf->Framebuffer, width, height);
+
+ return _eglGetSurfaceHandle(&surf->Base);
+}
+
+
+static EGLBoolean
+xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+{
+ struct xlib_egl_surface *surf = lookup_surface(surface);
+ if (surf) {
+ _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
+ if (surf->Base.IsBound) {
+ surf->Base.DeletePending = EGL_TRUE;
+ }
+ else {
+ st_unreference_framebuffer(&surf->Framebuffer);
+ free(surf);
+ }
+ return EGL_TRUE;
+ }
+ else {
+ _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
+ return EGL_FALSE;
+ }
+}
+
+
+static EGLBoolean
+xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+{
+ /* error checking step: */
+ if (!_eglSwapBuffers(drv, dpy, draw))
+ return EGL_FALSE;
+
+ {
+ struct xlib_egl_surface *xsurf = lookup_surface(draw);
+ struct pipe_winsys *pws = xsurf->winsys;
+ struct pipe_surface *psurf =
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT);
+
+ st_notify_swapbuffers(xsurf->Framebuffer);
+
+ display_surface(pws, psurf, xsurf);
+
+ check_and_update_buffer_size(xsurf);
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * This is the main entrypoint into the driver.
+ * Called by libEGL to instantiate an _EGLDriver object.
+ */
+_EGLDriver *
+_eglMain(_EGLDisplay *dpy, const char *args)
+{
+ struct xlib_egl_driver *xdrv;
+
+ _eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args);
+
+ xdrv = CALLOC_STRUCT(xlib_egl_driver);
+ if (!xdrv)
+ return NULL;
+
+ _eglInitDriverFallbacks(&xdrv->Base);
+ xdrv->Base.API.Initialize = xlib_eglInitialize;
+ xdrv->Base.API.Terminate = xlib_eglTerminate;
+ xdrv->Base.API.GetProcAddress = xlib_eglGetProcAddress;
+ xdrv->Base.API.CreateContext = xlib_eglCreateContext;
+ xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
+ xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
+ xdrv->Base.API.DestroySurface = xlib_eglDestroySurface;
+ xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
+ xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
+
+ xdrv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+
+ xdrv->Base.Name = "Xlib/softpipe";
+
+ /* create one winsys and use it for all contexts/surfaces */
+ xdrv->winsys = create_sw_winsys();
+ xdrv->winsys->flush_frontbuffer = flush_frontbuffer;
+
+ xdrv->screen = softpipe_create_screen(xdrv->winsys);
+
+ return &xdrv->Base;
+}
+
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
new file mode 100644
index 0000000000..fd0cb9fb12
--- /dev/null
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -0,0 +1,281 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * Totally software-based winsys layer.
+ * Note that the one winsys function that we can't implement here
+ * is flush_frontbuffer().
+ * Whoever uses this code will have to provide that.
+ *
+ * Authors: Brian Paul
+ */
+
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_state.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+
+#include "sw_winsys.h"
+
+
+
+/** Subclass of pipe_winsys */
+struct sw_pipe_winsys
+{
+ struct pipe_winsys Base;
+ /* no extra fields for now */
+};
+
+
+/** subclass of pipe_buffer */
+struct sw_pipe_buffer
+{
+ struct pipe_buffer Base;
+ boolean UserBuffer; /** Is this a user-space buffer? */
+ void *Data;
+ void *Mapped;
+};
+
+
+/** cast wrapper */
+static INLINE struct sw_pipe_buffer *
+sw_pipe_buffer(struct pipe_buffer *b)
+{
+ return (struct sw_pipe_buffer *) b;
+}
+
+
+/**
+ * Round n up to next multiple.
+ */
+static INLINE unsigned
+round_up(unsigned n, unsigned multiple)
+{
+ return (n + multiple - 1) & ~(multiple - 1);
+}
+
+
+static const char *
+get_name(struct pipe_winsys *pws)
+{
+ return "software";
+}
+
+
+/** Create new pipe_buffer and allocate storage of given size */
+static struct pipe_buffer *
+buffer_create(struct pipe_winsys *pws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+ if (!buffer)
+ return NULL;
+
+ buffer->Base.refcount = 1;
+ buffer->Base.alignment = alignment;
+ buffer->Base.usage = usage;
+ buffer->Base.size = size;
+
+ /* align to 16-byte multiple for Cell */
+ buffer->Data = align_malloc(size, MAX2(alignment, 16));
+
+ return &buffer->Base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
+{
+ struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+ if (!buffer)
+ return NULL;
+
+ buffer->Base.refcount = 1;
+ buffer->Base.size = bytes;
+ buffer->UserBuffer = TRUE;
+ buffer->Data = ptr;
+
+ return &buffer->Base;
+}
+
+
+static void *
+buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+ buffer->Mapped = buffer->Data;
+ return buffer->Mapped;
+}
+
+
+static void
+buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+ buffer->Mapped = NULL;
+}
+
+
+static void
+buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+
+ if (buffer->Data && !buffer->UserBuffer) {
+ align_free(buffer->Data);
+ buffer->Data = NULL;
+ }
+
+ free(buffer);
+}
+
+
+/**
+ * Called via winsys->surface_alloc() to create new surfaces.
+ */
+static struct pipe_surface *
+surface_alloc(struct pipe_winsys *ws)
+{
+ struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
+ if (!surf)
+ return NULL;
+
+ surf->refcount = 1;
+ surf->winsys = ws;
+
+ return surf;
+}
+
+
+static int
+surface_alloc_storage(struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned flags,
+ unsigned tex_usage)
+{
+ const unsigned alignment = 64;
+
+ surf->width = width;
+ surf->height = height;
+ surf->format = format;
+ surf->cpp = pf_get_size(format);
+ surf->pitch = round_up(width, alignment / surf->cpp);
+ surf->usage = flags;
+
+ assert(!surf->buffer);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
+ if(!surf->buffer)
+ return -1;
+
+ return 0;
+}
+
+
+static void
+surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
+{
+ struct pipe_surface *surf = *s;
+ assert(!surf->texture);
+ surf->refcount--;
+ if (surf->refcount == 0) {
+ if (surf->buffer)
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
+ free(surf);
+ }
+ *s = NULL;
+}
+
+
+static void
+fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ /* no-op */
+}
+
+
+static int
+fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ /* no-op */
+ return 0;
+}
+
+
+static int
+fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ /* no-op */
+ return 0;
+}
+
+
+/**
+ * Create/return a new pipe_winsys object.
+ */
+struct pipe_winsys *
+create_sw_winsys(void)
+{
+ struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
+ if (!ws)
+ return NULL;
+
+ /* Fill in this struct with callbacks that pipe will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ ws->Base.buffer_create = buffer_create;
+ ws->Base.user_buffer_create = user_buffer_create;
+ ws->Base.buffer_map = buffer_map;
+ ws->Base.buffer_unmap = buffer_unmap;
+ ws->Base.buffer_destroy = buffer_destroy;
+
+ ws->Base.surface_alloc = surface_alloc;
+ ws->Base.surface_alloc_storage = surface_alloc_storage;
+ ws->Base.surface_release = surface_release;
+
+ ws->Base.fence_reference = fence_reference;
+ ws->Base.fence_signalled = fence_signalled;
+ ws->Base.fence_finish = fence_finish;
+
+ ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
+
+ ws->Base.get_name = get_name;
+
+ return &ws->Base;
+}
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.h b/src/gallium/winsys/egl_xlib/sw_winsys.h
new file mode 100644
index 0000000000..f96c5a14b0
--- /dev/null
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
+
+
+struct pipe_winsys;
+
+
+extern struct pipe_winsys *
+create_sw_winsys(void);
+
+
+#endif /* SW_WINSYS_H */
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript
new file mode 100644
index 0000000000..170fdf5127
--- /dev/null
+++ b/src/gallium/winsys/gdi/SConscript
@@ -0,0 +1,33 @@
+#######################################################################
+# SConscript for gdi winsys
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#src/mesa/glapi',
+ '#src/mesa',
+ '#src/mesa/main',
+ ])
+
+ sources = [
+ 'opengl32.def',
+ 'wgl.c',
+ 'wmesa.c',
+ ]
+
+ drivers = [
+ softpipe,
+ ]
+
+ env.Append(LIBS = ['gdi32', 'user32'])
+
+ # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+ env.SharedLibrary(
+ target ='opengl32',
+ source = sources,
+ LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'],
+ )
diff --git a/src/gallium/winsys/gdi/colors.h b/src/gallium/winsys/gdi/colors.h
new file mode 100644
index 0000000000..03e512c1fa
--- /dev/null
+++ b/src/gallium/winsys/gdi/colors.h
@@ -0,0 +1,29 @@
+/* Values for wmesa->pixelformat: */
+
+#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */
+#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */
+#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */
+#define PF_DITHER8 6 /* Dithered RGB using a lookup table */
+#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */
+#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */
+#define PF_BADFORMAT 11
+#define PF_INDEX8 12
+
+
+#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \
+ ((r & 0xe0)>>5))))
+
+/* Windows uses 5,5,5 for 16-bit */
+#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \
+ (((unsigned short)g & 0xf8) << 2) | \
+ (((unsigned short)r & 0xf8) << 7) )
+
+#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \
+ ((WORD)((BYTE)(g))<<8))| \
+ (((DWORD)(BYTE)(r))<<16)))
+
+#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \
+ ((WORD)((BYTE)(g))<<8))| \
+ (((DWORD)(BYTE)(r))<<16)))
+
+
diff --git a/src/gallium/winsys/gdi/opengl32.def b/src/gallium/winsys/gdi/opengl32.def
new file mode 100644
index 0000000000..54e72f57b1
--- /dev/null
+++ b/src/gallium/winsys/gdi/opengl32.def
@@ -0,0 +1,859 @@
+; DO NOT EDIT - This file generated automatically by mesadef.py script
+;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32'
+VERSION 6.5
+;
+; Module definition file for Mesa (OPENGL32.DLL)
+;
+; Note: The OpenGL functions use the STDCALL
+; function calling convention. Microsoft's
+; OPENGL32 uses this convention and so must the
+; Mesa OPENGL32 so that the Mesa DLL can be used
+; as a drop-in replacement.
+;
+; The linker exports STDCALL entry points with
+; 'decorated' names; e.g., _glBegin@0, where the
+; trailing number is the number of bytes of
+; parameter data pushed onto the stack. The
+; callee is responsible for popping this data
+; off the stack, usually via a RETF n instruction.
+;
+; However, the Microsoft OPENGL32.DLL does not export
+; the decorated names, even though the calling convention
+; is STDCALL. So, this module definition file is
+; needed to force the Mesa OPENGL32.DLL to export the
+; symbols in the same manner as the Microsoft DLL.
+; Were it not for this problem, this file would not
+; be needed (for the gl* functions) since the entry
+; points are compiled with dllexport declspec.
+;
+; However, this file is still needed to export "internal"
+; Mesa symbols for the benefit of the OSMESA32.DLL.
+;
+EXPORTS
+ glNewList
+ glEndList
+ glCallList
+ glCallLists
+ glDeleteLists
+ glGenLists
+ glListBase
+ glBegin
+ glBitmap
+ glColor3b
+ glColor3bv
+ glColor3d
+ glColor3dv
+ glColor3f
+ glColor3fv
+ glColor3i
+ glColor3iv
+ glColor3s
+ glColor3sv
+ glColor3ub
+ glColor3ubv
+ glColor3ui
+ glColor3uiv
+ glColor3us
+ glColor3usv
+ glColor4b
+ glColor4bv
+ glColor4d
+ glColor4dv
+ glColor4f
+ glColor4fv
+ glColor4i
+ glColor4iv
+ glColor4s
+ glColor4sv
+ glColor4ub
+ glColor4ubv
+ glColor4ui
+ glColor4uiv
+ glColor4us
+ glColor4usv
+ glEdgeFlag
+ glEdgeFlagv
+ glEnd
+ glIndexd
+ glIndexdv
+ glIndexf
+ glIndexfv
+ glIndexi
+ glIndexiv
+ glIndexs
+ glIndexsv
+ glNormal3b
+ glNormal3bv
+ glNormal3d
+ glNormal3dv
+ glNormal3f
+ glNormal3fv
+ glNormal3i
+ glNormal3iv
+ glNormal3s
+ glNormal3sv
+ glRasterPos2d
+ glRasterPos2dv
+ glRasterPos2f
+ glRasterPos2fv
+ glRasterPos2i
+ glRasterPos2iv
+ glRasterPos2s
+ glRasterPos2sv
+ glRasterPos3d
+ glRasterPos3dv
+ glRasterPos3f
+ glRasterPos3fv
+ glRasterPos3i
+ glRasterPos3iv
+ glRasterPos3s
+ glRasterPos3sv
+ glRasterPos4d
+ glRasterPos4dv
+ glRasterPos4f
+ glRasterPos4fv
+ glRasterPos4i
+ glRasterPos4iv
+ glRasterPos4s
+ glRasterPos4sv
+ glRectd
+ glRectdv
+ glRectf
+ glRectfv
+ glRecti
+ glRectiv
+ glRects
+ glRectsv
+ glTexCoord1d
+ glTexCoord1dv
+ glTexCoord1f
+ glTexCoord1fv
+ glTexCoord1i
+ glTexCoord1iv
+ glTexCoord1s
+ glTexCoord1sv
+ glTexCoord2d
+ glTexCoord2dv
+ glTexCoord2f
+ glTexCoord2fv
+ glTexCoord2i
+ glTexCoord2iv
+ glTexCoord2s
+ glTexCoord2sv
+ glTexCoord3d
+ glTexCoord3dv
+ glTexCoord3f
+ glTexCoord3fv
+ glTexCoord3i
+ glTexCoord3iv
+ glTexCoord3s
+ glTexCoord3sv
+ glTexCoord4d
+ glTexCoord4dv
+ glTexCoord4f
+ glTexCoord4fv
+ glTexCoord4i
+ glTexCoord4iv
+ glTexCoord4s
+ glTexCoord4sv
+ glVertex2d
+ glVertex2dv
+ glVertex2f
+ glVertex2fv
+ glVertex2i
+ glVertex2iv
+ glVertex2s
+ glVertex2sv
+ glVertex3d
+ glVertex3dv
+ glVertex3f
+ glVertex3fv
+ glVertex3i
+ glVertex3iv
+ glVertex3s
+ glVertex3sv
+ glVertex4d
+ glVertex4dv
+ glVertex4f
+ glVertex4fv
+ glVertex4i
+ glVertex4iv
+ glVertex4s
+ glVertex4sv
+ glClipPlane
+ glColorMaterial
+ glCullFace
+ glFogf
+ glFogfv
+ glFogi
+ glFogiv
+ glFrontFace
+ glHint
+ glLightf
+ glLightfv
+ glLighti
+ glLightiv
+ glLightModelf
+ glLightModelfv
+ glLightModeli
+ glLightModeliv
+ glLineStipple
+ glLineWidth
+ glMaterialf
+ glMaterialfv
+ glMateriali
+ glMaterialiv
+ glPointSize
+ glPolygonMode
+ glPolygonStipple
+ glScissor
+ glShadeModel
+ glTexParameterf
+ glTexParameterfv
+ glTexParameteri
+ glTexParameteriv
+ glTexImage1D
+ glTexImage2D
+ glTexEnvf
+ glTexEnvfv
+ glTexEnvi
+ glTexEnviv
+ glTexGend
+ glTexGendv
+ glTexGenf
+ glTexGenfv
+ glTexGeni
+ glTexGeniv
+ glFeedbackBuffer
+ glSelectBuffer
+ glRenderMode
+ glInitNames
+ glLoadName
+ glPassThrough
+ glPopName
+ glPushName
+ glDrawBuffer
+ glClear
+ glClearAccum
+ glClearIndex
+ glClearColor
+ glClearStencil
+ glClearDepth
+ glStencilMask
+ glColorMask
+ glDepthMask
+ glIndexMask
+ glAccum
+ glDisable
+ glEnable
+ glFinish
+ glFlush
+ glPopAttrib
+ glPushAttrib
+ glMap1d
+ glMap1f
+ glMap2d
+ glMap2f
+ glMapGrid1d
+ glMapGrid1f
+ glMapGrid2d
+ glMapGrid2f
+ glEvalCoord1d
+ glEvalCoord1dv
+ glEvalCoord1f
+ glEvalCoord1fv
+ glEvalCoord2d
+ glEvalCoord2dv
+ glEvalCoord2f
+ glEvalCoord2fv
+ glEvalMesh1
+ glEvalPoint1
+ glEvalMesh2
+ glEvalPoint2
+ glAlphaFunc
+ glBlendFunc
+ glLogicOp
+ glStencilFunc
+ glStencilOp
+ glDepthFunc
+ glPixelZoom
+ glPixelTransferf
+ glPixelTransferi
+ glPixelStoref
+ glPixelStorei
+ glPixelMapfv
+ glPixelMapuiv
+ glPixelMapusv
+ glReadBuffer
+ glCopyPixels
+ glReadPixels
+ glDrawPixels
+ glGetBooleanv
+ glGetClipPlane
+ glGetDoublev
+ glGetError
+ glGetFloatv
+ glGetIntegerv
+ glGetLightfv
+ glGetLightiv
+ glGetMapdv
+ glGetMapfv
+ glGetMapiv
+ glGetMaterialfv
+ glGetMaterialiv
+ glGetPixelMapfv
+ glGetPixelMapuiv
+ glGetPixelMapusv
+ glGetPolygonStipple
+ glGetString
+ glGetTexEnvfv
+ glGetTexEnviv
+ glGetTexGendv
+ glGetTexGenfv
+ glGetTexGeniv
+ glGetTexImage
+ glGetTexParameterfv
+ glGetTexParameteriv
+ glGetTexLevelParameterfv
+ glGetTexLevelParameteriv
+ glIsEnabled
+ glIsList
+ glDepthRange
+ glFrustum
+ glLoadIdentity
+ glLoadMatrixf
+ glLoadMatrixd
+ glMatrixMode
+ glMultMatrixf
+ glMultMatrixd
+ glOrtho
+ glPopMatrix
+ glPushMatrix
+ glRotated
+ glRotatef
+ glScaled
+ glScalef
+ glTranslated
+ glTranslatef
+ glViewport
+ glArrayElement
+ glColorPointer
+ glDisableClientState
+ glDrawArrays
+ glDrawElements
+ glEdgeFlagPointer
+ glEnableClientState
+ glGetPointerv
+ glIndexPointer
+ glInterleavedArrays
+ glNormalPointer
+ glTexCoordPointer
+ glVertexPointer
+ glPolygonOffset
+ glCopyTexImage1D
+ glCopyTexImage2D
+ glCopyTexSubImage1D
+ glCopyTexSubImage2D
+ glTexSubImage1D
+ glTexSubImage2D
+ glAreTexturesResident
+ glBindTexture
+ glDeleteTextures
+ glGenTextures
+ glIsTexture
+ glPrioritizeTextures
+ glIndexub
+ glIndexubv
+ glPopClientAttrib
+ glPushClientAttrib
+ glBlendColor
+ glBlendEquation
+ glDrawRangeElements
+ glColorTable
+ glColorTableParameterfv
+ glColorTableParameteriv
+ glCopyColorTable
+ glGetColorTable
+ glGetColorTableParameterfv
+ glGetColorTableParameteriv
+ glColorSubTable
+ glCopyColorSubTable
+ glConvolutionFilter1D
+ glConvolutionFilter2D
+ glConvolutionParameterf
+ glConvolutionParameterfv
+ glConvolutionParameteri
+ glConvolutionParameteriv
+ glCopyConvolutionFilter1D
+ glCopyConvolutionFilter2D
+ glGetConvolutionFilter
+ glGetConvolutionParameterfv
+ glGetConvolutionParameteriv
+ glGetSeparableFilter
+ glSeparableFilter2D
+ glGetHistogram
+ glGetHistogramParameterfv
+ glGetHistogramParameteriv
+ glGetMinmax
+ glGetMinmaxParameterfv
+ glGetMinmaxParameteriv
+ glHistogram
+ glMinmax
+ glResetHistogram
+ glResetMinmax
+ glTexImage3D
+ glTexSubImage3D
+ glCopyTexSubImage3D
+ glActiveTextureARB
+ glClientActiveTextureARB
+ glMultiTexCoord1dARB
+ glMultiTexCoord1dvARB
+ glMultiTexCoord1fARB
+ glMultiTexCoord1fvARB
+ glMultiTexCoord1iARB
+ glMultiTexCoord1ivARB
+ glMultiTexCoord1sARB
+ glMultiTexCoord1svARB
+ glMultiTexCoord2dARB
+ glMultiTexCoord2dvARB
+ glMultiTexCoord2fARB
+ glMultiTexCoord2fvARB
+ glMultiTexCoord2iARB
+ glMultiTexCoord2ivARB
+ glMultiTexCoord2sARB
+ glMultiTexCoord2svARB
+ glMultiTexCoord3dARB
+ glMultiTexCoord3dvARB
+ glMultiTexCoord3fARB
+ glMultiTexCoord3fvARB
+ glMultiTexCoord3iARB
+ glMultiTexCoord3ivARB
+ glMultiTexCoord3sARB
+ glMultiTexCoord3svARB
+ glMultiTexCoord4dARB
+ glMultiTexCoord4dvARB
+ glMultiTexCoord4fARB
+ glMultiTexCoord4fvARB
+ glMultiTexCoord4iARB
+ glMultiTexCoord4ivARB
+ glMultiTexCoord4sARB
+ glMultiTexCoord4svARB
+ glLoadTransposeMatrixfARB
+ glLoadTransposeMatrixdARB
+ glMultTransposeMatrixfARB
+ glMultTransposeMatrixdARB
+ glSampleCoverageARB
+ glCompressedTexImage3DARB
+ glCompressedTexImage2DARB
+ glCompressedTexImage1DARB
+ glCompressedTexSubImage3DARB
+ glCompressedTexSubImage2DARB
+ glCompressedTexSubImage1DARB
+ glGetCompressedTexImageARB
+ glActiveTexture
+ glClientActiveTexture
+ glMultiTexCoord1d
+ glMultiTexCoord1dv
+ glMultiTexCoord1f
+ glMultiTexCoord1fv
+ glMultiTexCoord1i
+ glMultiTexCoord1iv
+ glMultiTexCoord1s
+ glMultiTexCoord1sv
+ glMultiTexCoord2d
+ glMultiTexCoord2dv
+ glMultiTexCoord2f
+ glMultiTexCoord2fv
+ glMultiTexCoord2i
+ glMultiTexCoord2iv
+ glMultiTexCoord2s
+ glMultiTexCoord2sv
+ glMultiTexCoord3d
+ glMultiTexCoord3dv
+ glMultiTexCoord3f
+ glMultiTexCoord3fv
+ glMultiTexCoord3i
+ glMultiTexCoord3iv
+ glMultiTexCoord3s
+ glMultiTexCoord3sv
+ glMultiTexCoord4d
+ glMultiTexCoord4dv
+ glMultiTexCoord4f
+ glMultiTexCoord4fv
+ glMultiTexCoord4i
+ glMultiTexCoord4iv
+ glMultiTexCoord4s
+ glMultiTexCoord4sv
+ glLoadTransposeMatrixf
+ glLoadTransposeMatrixd
+ glMultTransposeMatrixf
+ glMultTransposeMatrixd
+ glSampleCoverage
+ glCompressedTexImage3D
+ glCompressedTexImage2D
+ glCompressedTexImage1D
+ glCompressedTexSubImage3D
+ glCompressedTexSubImage2D
+ glCompressedTexSubImage1D
+ glGetCompressedTexImage
+ glBlendColorEXT
+ glPolygonOffsetEXT
+ glTexImage3DEXT
+ glTexSubImage3DEXT
+ glTexSubImage1DEXT
+ glTexSubImage2DEXT
+ glCopyTexImage1DEXT
+ glCopyTexImage2DEXT
+ glCopyTexSubImage1DEXT
+ glCopyTexSubImage2DEXT
+ glCopyTexSubImage3DEXT
+ glAreTexturesResidentEXT
+ glBindTextureEXT
+ glDeleteTexturesEXT
+ glGenTexturesEXT
+ glIsTextureEXT
+ glPrioritizeTexturesEXT
+ glArrayElementEXT
+ glColorPointerEXT
+ glDrawArraysEXT
+ glEdgeFlagPointerEXT
+ glGetPointervEXT
+ glIndexPointerEXT
+ glNormalPointerEXT
+ glTexCoordPointerEXT
+ glVertexPointerEXT
+ glBlendEquationEXT
+ glPointParameterfEXT
+ glPointParameterfvEXT
+ glPointParameterfARB
+ glPointParameterfvARB
+ glColorTableEXT
+ glGetColorTableEXT
+ glGetColorTableParameterivEXT
+ glGetColorTableParameterfvEXT
+ glLockArraysEXT
+ glUnlockArraysEXT
+ glDrawRangeElementsEXT
+ glSecondaryColor3bEXT
+ glSecondaryColor3bvEXT
+ glSecondaryColor3dEXT
+ glSecondaryColor3dvEXT
+ glSecondaryColor3fEXT
+ glSecondaryColor3fvEXT
+ glSecondaryColor3iEXT
+ glSecondaryColor3ivEXT
+ glSecondaryColor3sEXT
+ glSecondaryColor3svEXT
+ glSecondaryColor3ubEXT
+ glSecondaryColor3ubvEXT
+ glSecondaryColor3uiEXT
+ glSecondaryColor3uivEXT
+ glSecondaryColor3usEXT
+ glSecondaryColor3usvEXT
+ glSecondaryColorPointerEXT
+ glMultiDrawArraysEXT
+ glMultiDrawElementsEXT
+ glFogCoordfEXT
+ glFogCoordfvEXT
+ glFogCoorddEXT
+ glFogCoorddvEXT
+ glFogCoordPointerEXT
+ glBlendFuncSeparateEXT
+ glFlushVertexArrayRangeNV
+ glVertexArrayRangeNV
+ glCombinerParameterfvNV
+ glCombinerParameterfNV
+ glCombinerParameterivNV
+ glCombinerParameteriNV
+ glCombinerInputNV
+ glCombinerOutputNV
+ glFinalCombinerInputNV
+ glGetCombinerInputParameterfvNV
+ glGetCombinerInputParameterivNV
+ glGetCombinerOutputParameterfvNV
+ glGetCombinerOutputParameterivNV
+ glGetFinalCombinerInputParameterfvNV
+ glGetFinalCombinerInputParameterivNV
+ glResizeBuffersMESA
+ glWindowPos2dMESA
+ glWindowPos2dvMESA
+ glWindowPos2fMESA
+ glWindowPos2fvMESA
+ glWindowPos2iMESA
+ glWindowPos2ivMESA
+ glWindowPos2sMESA
+ glWindowPos2svMESA
+ glWindowPos3dMESA
+ glWindowPos3dvMESA
+ glWindowPos3fMESA
+ glWindowPos3fvMESA
+ glWindowPos3iMESA
+ glWindowPos3ivMESA
+ glWindowPos3sMESA
+ glWindowPos3svMESA
+ glWindowPos4dMESA
+ glWindowPos4dvMESA
+ glWindowPos4fMESA
+ glWindowPos4fvMESA
+ glWindowPos4iMESA
+ glWindowPos4ivMESA
+ glWindowPos4sMESA
+ glWindowPos4svMESA
+ glWindowPos2dARB
+ glWindowPos2fARB
+ glWindowPos2iARB
+ glWindowPos2sARB
+ glWindowPos2dvARB
+ glWindowPos2fvARB
+ glWindowPos2ivARB
+ glWindowPos2svARB
+ glWindowPos3dARB
+ glWindowPos3fARB
+ glWindowPos3iARB
+ glWindowPos3sARB
+ glWindowPos3dvARB
+ glWindowPos3fvARB
+ glWindowPos3ivARB
+ glWindowPos3svARB
+ glAreProgramsResidentNV
+ glBindProgramNV
+ glDeleteProgramsNV
+ glExecuteProgramNV
+ glGenProgramsNV
+ glGetProgramParameterdvNV
+ glGetProgramParameterfvNV
+ glGetProgramivNV
+ glGetProgramStringNV
+ glGetTrackMatrixivNV
+ glGetVertexAttribdvNV
+ glGetVertexAttribfvNV
+ glGetVertexAttribivNV
+ glGetVertexAttribPointervNV
+ glIsProgramNV
+ glLoadProgramNV
+ glProgramParameter4dNV
+ glProgramParameter4dvNV
+ glProgramParameter4fNV
+ glProgramParameter4fvNV
+ glProgramParameters4dvNV
+ glProgramParameters4fvNV
+ glRequestResidentProgramsNV
+ glTrackMatrixNV
+ glVertexAttribPointerNV
+ glVertexAttrib1dNV
+ glVertexAttrib1dvNV
+ glVertexAttrib1fNV
+ glVertexAttrib1fvNV
+ glVertexAttrib1sNV
+ glVertexAttrib1svNV
+ glVertexAttrib2dNV
+ glVertexAttrib2dvNV
+ glVertexAttrib2fNV
+ glVertexAttrib2fvNV
+ glVertexAttrib2sNV
+ glVertexAttrib2svNV
+ glVertexAttrib3dNV
+ glVertexAttrib3dvNV
+ glVertexAttrib3fNV
+ glVertexAttrib3fvNV
+ glVertexAttrib3sNV
+ glVertexAttrib3svNV
+ glVertexAttrib4dNV
+ glVertexAttrib4dvNV
+ glVertexAttrib4fNV
+ glVertexAttrib4fvNV
+ glVertexAttrib4sNV
+ glVertexAttrib4svNV
+ glVertexAttrib4ubNV
+ glVertexAttrib4ubvNV
+ glVertexAttribs1dvNV
+ glVertexAttribs1fvNV
+ glVertexAttribs1svNV
+ glVertexAttribs2dvNV
+ glVertexAttribs2fvNV
+ glVertexAttribs2svNV
+ glVertexAttribs3dvNV
+ glVertexAttribs3fvNV
+ glVertexAttribs3svNV
+ glVertexAttribs4dvNV
+ glVertexAttribs4fvNV
+ glVertexAttribs4svNV
+ glVertexAttribs4ubvNV
+ glPointParameteriNV
+ glPointParameterivNV
+ glFogCoordf
+ glFogCoordfv
+ glFogCoordd
+ glFogCoorddv
+ glFogCoordPointer
+ glMultiDrawArrays
+ glMultiDrawElements
+ glPointParameterf
+ glPointParameterfv
+ glPointParameteri
+ glPointParameteriv
+ glSecondaryColor3b
+ glSecondaryColor3bv
+ glSecondaryColor3d
+ glSecondaryColor3dv
+ glSecondaryColor3f
+ glSecondaryColor3fv
+ glSecondaryColor3i
+ glSecondaryColor3iv
+ glSecondaryColor3s
+ glSecondaryColor3sv
+ glSecondaryColor3ub
+ glSecondaryColor3ubv
+ glSecondaryColor3ui
+ glSecondaryColor3uiv
+ glSecondaryColor3us
+ glSecondaryColor3usv
+ glSecondaryColorPointer
+ glWindowPos2d
+ glWindowPos2dv
+ glWindowPos2f
+ glWindowPos2fv
+ glWindowPos2i
+ glWindowPos2iv
+ glWindowPos2s
+ glWindowPos2sv
+ glWindowPos3d
+ glWindowPos3dv
+ glWindowPos3f
+ glWindowPos3fv
+ glWindowPos3i
+ glWindowPos3iv
+ glWindowPos3s
+ glWindowPos3sv
+ glVertexAttrib1sARB
+ glVertexAttrib1fARB
+ glVertexAttrib1dARB
+ glVertexAttrib2sARB
+ glVertexAttrib2fARB
+ glVertexAttrib2dARB
+ glVertexAttrib3sARB
+ glVertexAttrib3fARB
+ glVertexAttrib3dARB
+ glVertexAttrib4sARB
+ glVertexAttrib4fARB
+ glVertexAttrib4dARB
+ glVertexAttrib4NubARB
+ glVertexAttrib1svARB
+ glVertexAttrib1fvARB
+ glVertexAttrib1dvARB
+ glVertexAttrib2svARB
+ glVertexAttrib2fvARB
+ glVertexAttrib2dvARB
+ glVertexAttrib3svARB
+ glVertexAttrib3fvARB
+ glVertexAttrib3dvARB
+ glVertexAttrib4bvARB
+ glVertexAttrib4svARB
+ glVertexAttrib4ivARB
+ glVertexAttrib4ubvARB
+ glVertexAttrib4usvARB
+ glVertexAttrib4uivARB
+ glVertexAttrib4fvARB
+ glVertexAttrib4dvARB
+ glVertexAttrib4NbvARB
+ glVertexAttrib4NsvARB
+ glVertexAttrib4NivARB
+ glVertexAttrib4NubvARB
+ glVertexAttrib4NusvARB
+ glVertexAttrib4NuivARB
+ glVertexAttribPointerARB
+ glEnableVertexAttribArrayARB
+ glDisableVertexAttribArrayARB
+ glProgramStringARB
+ glBindProgramARB
+ glDeleteProgramsARB
+ glGenProgramsARB
+ glIsProgramARB
+ glProgramEnvParameter4dARB
+ glProgramEnvParameter4dvARB
+ glProgramEnvParameter4fARB
+ glProgramEnvParameter4fvARB
+ glProgramLocalParameter4dARB
+ glProgramLocalParameter4dvARB
+ glProgramLocalParameter4fARB
+ glProgramLocalParameter4fvARB
+ glGetProgramEnvParameterdvARB
+ glGetProgramEnvParameterfvARB
+ glGetProgramLocalParameterdvARB
+ glGetProgramLocalParameterfvARB
+ glGetProgramivARB
+ glGetProgramStringARB
+ glGetVertexAttribdvARB
+ glGetVertexAttribfvARB
+ glGetVertexAttribivARB
+ glGetVertexAttribPointervARB
+ glProgramNamedParameter4fNV
+ glProgramNamedParameter4dNV
+ glProgramNamedParameter4fvNV
+ glProgramNamedParameter4dvNV
+ glGetProgramNamedParameterfvNV
+ glGetProgramNamedParameterdvNV
+ glBindBufferARB
+ glBufferDataARB
+ glBufferSubDataARB
+ glDeleteBuffersARB
+ glGenBuffersARB
+ glGetBufferParameterivARB
+ glGetBufferPointervARB
+ glGetBufferSubDataARB
+ glIsBufferARB
+ glMapBufferARB
+ glUnmapBufferARB
+ glGenQueriesARB
+ glDeleteQueriesARB
+ glIsQueryARB
+ glBeginQueryARB
+ glEndQueryARB
+ glGetQueryivARB
+ glGetQueryObjectivARB
+ glGetQueryObjectuivARB
+ glBindBuffer
+ glBufferData
+ glBufferSubData
+ glDeleteBuffers
+ glGenBuffers
+ glGetBufferParameteriv
+ glGetBufferPointerv
+ glGetBufferSubData
+ glIsBuffer
+ glMapBuffer
+ glUnmapBuffer
+ glGenQueries
+ glDeleteQueries
+ glIsQuery
+ glBeginQuery
+ glEndQuery
+ glGetQueryiv
+ glGetQueryObjectiv
+ glGetQueryObjectuiv
+;
+; WGL API
+ wglChoosePixelFormat
+ wglCopyContext
+ wglCreateContext
+ wglCreateLayerContext
+ wglDeleteContext
+ wglDescribeLayerPlane
+ wglDescribePixelFormat
+ wglGetCurrentContext
+ wglGetCurrentDC
+ wglGetLayerPaletteEntries
+ wglGetPixelFormat
+ wglGetProcAddress
+ wglMakeCurrent
+ wglRealizeLayerPalette
+ wglSetLayerPaletteEntries
+ wglSetPixelFormat
+ wglShareLists
+ wglSwapBuffers
+ wglSwapLayerBuffers
+ wglUseFontBitmapsA
+ wglUseFontBitmapsW
+ wglUseFontOutlinesA
+ wglUseFontOutlinesW
+ wglGetExtensionsStringARB
diff --git a/src/gallium/winsys/gdi/wgl.c b/src/gallium/winsys/gdi/wgl.c
new file mode 100644
index 0000000000..50126014a8
--- /dev/null
+++ b/src/gallium/winsys/gdi/wgl.c
@@ -0,0 +1,703 @@
+/* $Id: wgl.c,v 1.12 2006/03/30 07:58:24 kschultz Exp $ */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * File name : wgl.c
+ * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru
+ * Some things originated from the 3Dfx WGL functions
+ */
+
+/*
+ * This file contains the implementation of the wgl* functions for
+ * Mesa on Windows. Since these functions are provided by Windows in
+ * GDI/OpenGL, we must supply our versions that work with Mesa here.
+ */
+
+
+/* We're essentially building part of GDI here, so define this so that
+ * we get the right export linkage. */
+#ifdef __MINGW32__
+
+#include <stdarg.h>
+#include <windef.h>
+#include <wincon.h>
+#include <winbase.h>
+
+# if defined(BUILD_GL32)
+# define WINGDIAPI __declspec(dllexport)
+# else
+# define __W32API_USE_DLLIMPORT__
+# endif
+
+#include <wingdi.h>
+#include "GL/mesa_wgl.h"
+#include <stdlib.h>
+
+#else
+
+#define _GDI32_
+#include <windows.h>
+
+#endif
+
+#include "glapi.h"
+#include "GL/wmesa.h" /* protos for wmesa* functions */
+
+/*
+ * Pixel Format Descriptors
+ */
+
+/* Extend the PFD to include DB flag */
+struct __pixelformat__
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ GLboolean doubleBuffered;
+};
+
+/* These are the PFD's supported by this driver. */
+struct __pixelformat__ pfd[] =
+{
+ /* Double Buffer, alpha */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 24,
+ 8, 0,
+ 8, 8,
+ 8, 16,
+ 8, 24,
+ 0, 0, 0, 0, 0,
+ 16, 8,
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ GL_TRUE
+ },
+ /* Single Buffer, alpha */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_GENERIC_FORMAT,
+ PFD_TYPE_RGBA,
+ 24,
+ 8, 0,
+ 8, 8,
+ 8, 16,
+ 8, 24,
+ 0, 0, 0, 0, 0,
+ 16, 8,
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ GL_FALSE
+ },
+ /* Double Buffer, no alpha */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
+ PFD_TYPE_RGBA,
+ 24,
+ 8, 0,
+ 8, 8,
+ 8, 16,
+ 0, 0,
+ 0, 0, 0, 0, 0,
+ 16, 8,
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ GL_TRUE
+ },
+ /* Single Buffer, no alpha */
+ {
+ {
+ sizeof(PIXELFORMATDESCRIPTOR), 1,
+ PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
+ PFD_GENERIC_FORMAT,
+ PFD_TYPE_RGBA,
+ 24,
+ 8, 0,
+ 8, 8,
+ 8, 16,
+ 0, 0,
+ 0, 0, 0, 0, 0,
+ 16, 8,
+ 0, 0, 0,
+ 0, 0, 0
+ },
+ GL_FALSE
+ },
+};
+
+int npfd = sizeof(pfd) / sizeof(pfd[0]);
+
+
+/*
+ * Contexts
+ */
+
+typedef struct {
+ WMesaContext ctx;
+} MesaWglCtx;
+
+#define MESAWGL_CTX_MAX_COUNT 20
+
+static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT];
+
+static unsigned ctx_count = 0;
+static int ctx_current = -1;
+static unsigned curPFD = 0;
+
+static HDC CurrentHDC = 0;
+
+
+WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc)
+{
+ int i = 0;
+ if (!ctx_count) {
+ for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) {
+ wgl_ctx[i].ctx = NULL;
+ }
+ }
+ for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
+ if ( wgl_ctx[i].ctx == NULL ) {
+ wgl_ctx[i].ctx =
+ WMesaCreateContext(hdc, NULL, (GLboolean)GL_TRUE,
+ (GLboolean) (pfd[curPFD-1].doubleBuffered ?
+ GL_TRUE : GL_FALSE),
+ (GLboolean)(pfd[curPFD-1].pfd.cAlphaBits ?
+ GL_TRUE : GL_FALSE) );
+ if (wgl_ctx[i].ctx == NULL)
+ break;
+ ctx_count++;
+ return ((HGLRC)wgl_ctx[i].ctx);
+ }
+ }
+ SetLastError(0);
+ return(NULL);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc)
+{
+ int i;
+ for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
+ if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ){
+ WMesaMakeCurrent((WMesaContext) hglrc, NULL);
+ WMesaDestroyContext(wgl_ctx[i].ctx);
+ wgl_ctx[i].ctx = NULL;
+ ctx_count--;
+ return(TRUE);
+ }
+ }
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID)
+{
+ if (ctx_current < 0)
+ return 0;
+ else
+ return (HGLRC) wgl_ctx[ctx_current].ctx;
+}
+
+WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID)
+{
+ return CurrentHDC;
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc)
+{
+ int i;
+
+ CurrentHDC = hdc;
+
+ if (!hdc || !hglrc) {
+ WMesaMakeCurrent(NULL, NULL);
+ ctx_current = -1;
+ return TRUE;
+ }
+
+ for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) {
+ if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ) {
+ WMesaMakeCurrent( (WMesaContext) hglrc, hdc );
+ ctx_current = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+WINGDIAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc,
+ CONST
+ PIXELFORMATDESCRIPTOR *ppfd)
+{
+ int i,best = -1,bestdelta = 0x7FFFFFFF,delta;
+ (void) hdc;
+
+ if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1)
+ {
+ SetLastError(0);
+ return(0);
+ }
+ for(i = 0; i < npfd;i++)
+ {
+ delta = 0;
+ if(
+ (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) &&
+ !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
+ continue;
+ if(
+ (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) &&
+ !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
+ continue;
+ if(
+ (ppfd->dwFlags & PFD_SUPPORT_GDI) &&
+ !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI))
+ continue;
+ if(
+ (ppfd->dwFlags & PFD_SUPPORT_OPENGL) &&
+ !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ continue;
+ if(
+ !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
+ (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
+ continue;
+ if(
+ !(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
+ ((ppfd->dwFlags & PFD_STEREO) !=
+ (pfd[i].pfd.dwFlags & PFD_STEREO)))
+ continue;
+ if(ppfd->iPixelType != pfd[i].pfd.iPixelType)
+ delta++;
+ if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits)
+ delta++;
+ if(delta < bestdelta)
+ {
+ best = i + 1;
+ bestdelta = delta;
+ if(bestdelta == 0)
+ break;
+ }
+ }
+ if(best == -1)
+ {
+ SetLastError(0);
+ return(0);
+ }
+ return(best);
+}
+
+WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc,
+ int iPixelFormat,
+ UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR ppfd)
+{
+ (void) hdc;
+
+ if(ppfd == NULL)
+ return(npfd);
+ if(iPixelFormat < 1 || iPixelFormat > npfd ||
+ nBytes != sizeof(PIXELFORMATDESCRIPTOR))
+ {
+ SetLastError(0);
+ return(0);
+ }
+ *ppfd = pfd[iPixelFormat - 1].pfd;
+ return(npfd);
+}
+
+WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc)
+{
+ PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc);
+ if (p)
+ return p;
+
+ SetLastError(0);
+ return(NULL);
+}
+
+WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc)
+{
+ (void) hdc;
+ if(curPFD == 0) {
+ SetLastError(0);
+ return(0);
+ }
+ return(curPFD);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
+ const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ (void) hdc;
+
+ if(iPixelFormat < 1 || iPixelFormat > npfd ||
+ ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
+ SetLastError(0);
+ return(FALSE);
+ }
+ curPFD = iPixelFormat;
+ return(TRUE);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc)
+{
+ WMesaSwapBuffers(hdc);
+ return TRUE;
+}
+
+static FIXED FixedFromDouble(double d)
+{
+ long l = (long) (d * 65536L);
+ return *(FIXED *) (void *) &l;
+}
+
+
+/*
+** This is cribbed from FX/fxwgl.c, and seems to implement support
+** for bitmap fonts where the wglUseFontBitmapsA() code implements
+** support for outline fonts. In combination they hopefully give
+** fairly generic support for fonts.
+*/
+static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar,
+ DWORD numChars, DWORD listBase)
+{
+#define VERIFY(a) a
+
+ TEXTMETRIC metric;
+ BITMAPINFO *dibInfo;
+ HDC bitDevice;
+ COLORREF tempColor;
+ int i;
+
+ VERIFY(GetTextMetrics(fontDevice, &metric));
+
+ dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
+ dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ dibInfo->bmiHeader.biPlanes = 1;
+ dibInfo->bmiHeader.biBitCount = 1;
+ dibInfo->bmiHeader.biCompression = BI_RGB;
+
+ bitDevice = CreateCompatibleDC(fontDevice);
+
+ /* Swap fore and back colors so the bitmap has the right polarity */
+ tempColor = GetBkColor(bitDevice);
+ SetBkColor(bitDevice, GetTextColor(bitDevice));
+ SetTextColor(bitDevice, tempColor);
+
+ /* Place chars based on base line */
+ VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0);
+
+ for(i = 0; i < (int)numChars; i++) {
+ SIZE size;
+ char curChar;
+ int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
+ HBITMAP bitObject;
+ HGDIOBJ origBmap;
+ unsigned char *bmap;
+
+ curChar = (char)(i + firstChar);
+
+ /* Find how high/wide this character is */
+ VERIFY(GetTextExtentPoint32(bitDevice, (LPCWSTR)&curChar, 1, &size));
+
+ /* Create the output bitmap */
+ charWidth = size.cx;
+ charHeight = size.cy;
+ /* Round up to the next multiple of 32 bits */
+ bmapWidth = ((charWidth + 31) / 32) * 32;
+ bmapHeight = charHeight;
+ bitObject = CreateCompatibleBitmap(bitDevice,
+ bmapWidth,
+ bmapHeight);
+ /* VERIFY(bitObject); */
+
+ /* Assign the output bitmap to the device */
+ origBmap = SelectObject(bitDevice, bitObject);
+ (void) VERIFY(origBmap);
+
+ VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
+
+ /* Use our source font on the device */
+ VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
+
+ /* Draw the character */
+ VERIFY(TextOut(bitDevice, 0, metric.tmAscent, (LPCWSTR)&curChar, 1));
+
+ /* Unselect our bmap object */
+ VERIFY(SelectObject(bitDevice, origBmap));
+
+ /* Convert the display dependant representation to a 1 bit deep DIB */
+ numBytes = (bmapWidth * bmapHeight) / 8;
+ bmap = (unsigned char *)malloc(numBytes);
+ dibInfo->bmiHeader.biWidth = bmapWidth;
+ dibInfo->bmiHeader.biHeight = bmapHeight;
+ res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
+ dibInfo,
+ DIB_RGB_COLORS);
+ /* VERIFY(res); */
+
+ /* Create the GL object */
+ glNewList(i + listBase, GL_COMPILE);
+ glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent,
+ (GLfloat)charWidth, 0.0,
+ bmap);
+ glEndList();
+ /* CheckGL(); */
+
+ /* Destroy the bmap object */
+ DeleteObject(bitObject);
+
+ /* Deallocate the bitmap data */
+ free(bmap);
+ }
+
+ /* Destroy the DC */
+ VERIFY(DeleteDC(bitDevice));
+
+ free(dibInfo);
+
+ return TRUE;
+#undef VERIFY
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first,
+ DWORD count, DWORD listBase)
+{
+ int i;
+ GLuint font_list;
+ DWORD size;
+ GLYPHMETRICS gm;
+ HANDLE hBits;
+ LPSTR lpBits;
+ MAT2 mat;
+ int success = TRUE;
+
+ if (count == 0)
+ return FALSE;
+
+ font_list = listBase;
+
+ mat.eM11 = FixedFromDouble(1);
+ mat.eM12 = FixedFromDouble(0);
+ mat.eM21 = FixedFromDouble(0);
+ mat.eM22 = FixedFromDouble(-1);
+
+ memset(&gm,0,sizeof(gm));
+
+ /*
+ ** If we can't get the glyph outline, it may be because this is a fixed
+ ** font. Try processing it that way.
+ */
+ if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat)
+ == GDI_ERROR ) {
+ return wglUseFontBitmaps_FX( hdc, first, count, listBase );
+ }
+
+ /*
+ ** Otherwise process all desired characters.
+ */
+ for (i = 0; i < (int)count; i++) {
+ DWORD err;
+
+ glNewList( font_list+i, GL_COMPILE );
+
+ /* allocate space for the bitmap/outline */
+ size = GetGlyphOutline(hdc, first + i, GGO_BITMAP,
+ &gm, 0, NULL, &mat);
+ if (size == GDI_ERROR) {
+ glEndList( );
+ err = GetLastError();
+ success = FALSE;
+ continue;
+ }
+
+ hBits = GlobalAlloc(GHND, size+1);
+ lpBits = GlobalLock(hBits);
+
+ err =
+ GetGlyphOutline(hdc, /* handle to device context */
+ first + i, /* character to query */
+ GGO_BITMAP, /* format of data to return */
+ &gm, /* ptr to structure for metrics*/
+ size, /* size of buffer for data */
+ lpBits, /* pointer to buffer for data */
+ &mat /* pointer to transformation */
+ /* matrix structure */
+ );
+
+ if (err == GDI_ERROR) {
+ GlobalUnlock(hBits);
+ GlobalFree(hBits);
+
+ glEndList( );
+ err = GetLastError();
+ success = FALSE;
+ continue;
+ }
+
+ glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY,
+ (GLfloat)-gm.gmptGlyphOrigin.x,
+ (GLfloat)gm.gmptGlyphOrigin.y,
+ (GLfloat)gm.gmCellIncX,
+ (GLfloat)gm.gmCellIncY,
+ (const GLubyte * )lpBits);
+
+ GlobalUnlock(hBits);
+ GlobalFree(hBits);
+
+ glEndList( );
+ }
+
+ return success;
+}
+
+
+
+/* NOT IMPLEMENTED YET */
+WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc,
+ HGLRC hglrcDst,
+ UINT mask)
+{
+ (void) hglrcSrc; (void) hglrcDst; (void) mask;
+ return(FALSE);
+}
+
+WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc,
+ int iLayerPlane)
+{
+ (void) hdc; (void) iLayerPlane;
+ SetLastError(0);
+ return(NULL);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1,
+ HGLRC hglrc2)
+{
+ (void) hglrc1; (void) hglrc2;
+ return(TRUE);
+}
+
+
+WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc,
+ DWORD first,
+ DWORD count,
+ DWORD listBase)
+{
+ (void) hdc; (void) first; (void) count; (void) listBase;
+ return FALSE;
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc,
+ DWORD first,
+ DWORD count,
+ DWORD listBase,
+ FLOAT deviation,
+ FLOAT extrusion,
+ int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ (void) hdc; (void) first; (void) count;
+ (void) listBase; (void) deviation; (void) extrusion; (void) format;
+ (void) lpgmf;
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc,
+ DWORD first,
+ DWORD count,
+ DWORD listBase,
+ FLOAT deviation,
+ FLOAT extrusion,
+ int format,
+ LPGLYPHMETRICSFLOAT lpgmf)
+{
+ (void) hdc; (void) first; (void) count;
+ (void) listBase; (void) deviation; (void) extrusion; (void) format;
+ (void) lpgmf;
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc,
+ int iPixelFormat,
+ int iLayerPlane,
+ UINT nBytes,
+ LPLAYERPLANEDESCRIPTOR plpd)
+{
+ (void) hdc; (void) iPixelFormat; (void) iLayerPlane;
+ (void) nBytes; (void) plpd;
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc,
+ int iLayerPlane,
+ int iStart,
+ int cEntries,
+ CONST COLORREF *pcr)
+{
+ (void) hdc; (void) iLayerPlane; (void) iStart;
+ (void) cEntries; (void) pcr;
+ SetLastError(0);
+ return(0);
+}
+
+WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc,
+ int iLayerPlane,
+ int iStart,
+ int cEntries,
+ COLORREF *pcr)
+{
+ (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr;
+ SetLastError(0);
+ return(0);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc,
+ int iLayerPlane,
+ BOOL bRealize)
+{
+ (void) hdc; (void) iLayerPlane; (void) bRealize;
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc,
+ UINT fuPlanes)
+{
+ (void) hdc; (void) fuPlanes;
+ SetLastError(0);
+ return(FALSE);
+}
+
+WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc)
+{
+ return "WGL_ARB_extensions_string";
+}
diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c
new file mode 100644
index 0000000000..74a8292352
--- /dev/null
+++ b/src/gallium/winsys/gdi/wmesa.c
@@ -0,0 +1,890 @@
+/*
+ * Windows (Win32/Win64) device driver for Mesa
+ *
+ */
+
+#include "mtypes.h"
+#include <GL/wmesa.h>
+#include "wmesadef.h"
+
+#undef Elements
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "softpipe/sp_winsys.h"
+#include "glapi/glapi.h"
+#include "colors.h"
+
+extern GLvisual *
+_mesa_create_visual( GLboolean rgbFlag,
+ GLboolean dbFlag,
+ GLboolean stereoFlag,
+ GLint redBits,
+ GLint greenBits,
+ GLint blueBits,
+ GLint alphaBits,
+ GLint indexBits,
+ GLint depthBits,
+ GLint stencilBits,
+ GLint accumRedBits,
+ GLint accumGreenBits,
+ GLint accumBlueBits,
+ GLint accumAlphaBits,
+ GLint numSamples );
+
+/* linked list of our Framebuffers (windows) */
+WMesaFramebuffer FirstFramebuffer = NULL;
+
+struct wmesa_pipe_winsys
+{
+ struct pipe_winsys base;
+};
+
+/**
+ * Choose the pixel format for the given visual.
+ * This will tell the gallium driver how to pack pixel data into
+ * drawing surfaces.
+ */
+static GLuint
+choose_pixel_format(GLvisual *v)
+{
+#if 1
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+#else
+ if ( GET_REDMASK(v) == 0x0000ff
+ && GET_GREENMASK(v) == 0x00ff00
+ && GET_BLUEMASK(v) == 0xff0000
+ && v->BitsPerPixel == 32) {
+ if (CHECK_BYTE_ORDER(v)) {
+ /* no byteswapping needed */
+ return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */;
+ }
+ else {
+ return PIPE_FORMAT_R8G8B8A8_UNORM;
+ }
+ }
+ else if ( GET_REDMASK(v) == 0xff0000
+ && GET_GREENMASK(v) == 0x00ff00
+ && GET_BLUEMASK(v) == 0x0000ff
+ && v->BitsPerPixel == 32) {
+ if (CHECK_BYTE_ORDER(v)) {
+ /* no byteswapping needed */
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ }
+ else {
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ }
+ }
+ else if ( GET_REDMASK(v) == 0xf800
+ && GET_GREENMASK(v) == 0x07e0
+ && GET_BLUEMASK(v) == 0x001f
+ && CHECK_BYTE_ORDER(v)
+ && v->BitsPerPixel == 16) {
+ /* 5-6-5 RGB */
+ return PIPE_FORMAT_R5G6B5_UNORM;
+ }
+
+printf("BITS %d\n",v->BitsPerPixel);
+ assert(0);
+ return 0;
+#endif
+}
+
+/*
+ * Determine the pixel format based on the pixel size.
+ */
+static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC)
+{
+ /* Only 16 and 32 bit targets are supported now */
+ assert(pwfb->cColorBits == 0 ||
+ pwfb->cColorBits == 16 ||
+ pwfb->cColorBits == 32);
+
+ switch(pwfb->cColorBits){
+ case 8:
+ pwfb->pixelformat = PF_INDEX8;
+ break;
+ case 16:
+ pwfb->pixelformat = PF_5R6G5B;
+ break;
+ case 32:
+ pwfb->pixelformat = PF_8R8G8B;
+ break;
+ default:
+ pwfb->pixelformat = PF_BADFORMAT;
+ }
+}
+
+
+/**
+ * Create DIB for back buffer.
+ * We write into this memory with the span routines and then blit it
+ * to the window on a buffer swap.
+ */
+BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize)
+{
+ HDC hdc = pwfb->hDC;
+ BITMAPINFO bmi;
+ LPBITMAPINFO pbmi = &bmi;
+ HDC hic;
+
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = lxSize;
+ pbmi->bmiHeader.biHeight= -lySize;
+ pbmi->bmiHeader.biPlanes = 1;
+ pbmi->bmiHeader.biBitCount = pwfb->cColorBits;
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ hic = CreateIC("display", NULL, NULL, NULL);
+ pwfb->dib_hDC = CreateCompatibleDC(hic);
+
+ pwfb->hbmDIB = CreateDIBSection(hic,
+ pbmi,
+ DIB_RGB_COLORS,
+ (void **)&(pwfb->pbPixels),
+ 0,
+ 0);
+ pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB);
+
+ DeleteDC(hic);
+
+ wmSetPixelFormat(pwfb, pwfb->hDC);
+ return TRUE;
+}
+
+/**
+ * Create a new WMesaFramebuffer object which will correspond to the
+ * given HDC (Window handle).
+ */
+WMesaFramebuffer
+wmesa_new_framebuffer(HDC hdc, GLvisual *visual, GLuint width, GLuint height)
+{
+ WMesaFramebuffer pwfb
+ = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));
+ if (pwfb) {
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+
+ /* determine PIPE_FORMATs for buffers */
+ colorFormat = choose_pixel_format(visual);
+
+ if (visual->depthBits == 0)
+ depthFormat = PIPE_FORMAT_NONE;
+ else if (visual->depthBits <= 16)
+ depthFormat = PIPE_FORMAT_Z16_UNORM;
+ else if (visual->depthBits <= 24)
+ depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ depthFormat = PIPE_FORMAT_Z32_UNORM;
+
+ if (visual->stencilBits == 8) {
+ if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
+ stencilFormat = depthFormat;
+ else
+ stencilFormat = PIPE_FORMAT_S8_UNORM;
+ }
+ else {
+ stencilFormat = PIPE_FORMAT_NONE;
+ }
+
+ pwfb->stfb = st_create_framebuffer(visual,
+ colorFormat, depthFormat, stencilFormat,
+ width, height,
+ (void *) pwfb);
+
+ pwfb->cColorBits = GetDeviceCaps(hdc, BITSPIXEL);
+
+#if 0
+ wmCreateBackingStore(pwfb, width, height);
+#endif
+
+ pwfb->hDC = hdc;
+ /* insert at head of list */
+ pwfb->next = FirstFramebuffer;
+ FirstFramebuffer = pwfb;
+ }
+ return pwfb;
+}
+
+/**
+ * Given an hdc, free the corresponding WMesaFramebuffer
+ */
+void
+wmesa_free_framebuffer(HDC hdc)
+{
+ WMesaFramebuffer pwfb, prev;
+ for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
+ if (pwfb->hDC == hdc)
+ break;
+ prev = pwfb;
+ }
+ if (pwfb) {
+ if (pwfb == FirstFramebuffer)
+ FirstFramebuffer = pwfb->next;
+ else
+ prev->next = pwfb->next;
+ free(pwfb);
+ }
+}
+
+/**
+ * Given an hdc, return the corresponding WMesaFramebuffer
+ */
+WMesaFramebuffer
+wmesa_lookup_framebuffer(HDC hdc)
+{
+ WMesaFramebuffer pwfb;
+ for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {
+ if (pwfb->hDC == hdc)
+ return pwfb;
+ }
+ return NULL;
+}
+
+
+/**
+ * Given a GLframebuffer, return the corresponding WMesaFramebuffer.
+ */
+static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb)
+{
+ return (WMesaFramebuffer) fb;
+}
+
+
+/**
+ * Given a GLcontext, return the corresponding WMesaContext.
+ */
+static WMesaContext wmesa_context(const GLcontext *ctx)
+{
+ return (WMesaContext) ctx;
+}
+
+static wmDeleteBackingStore(WMesaFramebuffer pwfb)
+{
+ if (pwfb->hbmDIB) {
+ SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap);
+ DeleteDC(pwfb->dib_hDC);
+ DeleteObject(pwfb->hbmDIB);
+ }
+}
+
+
+/**
+ * Find the width and height of the window named by hdc.
+ */
+static void
+get_window_size(HDC hdc, GLuint *width, GLuint *height)
+{
+ if (WindowFromDC(hdc)) {
+ RECT rect;
+ GetClientRect(WindowFromDC(hdc), &rect);
+ *width = rect.right - rect.left;
+ *height = rect.bottom - rect.top;
+ }
+ else { /* Memory context */
+ /* From contributed code - use the size of the desktop
+ * for the size of a memory context (?) */
+ *width = GetDeviceCaps(hdc, HORZRES);
+ *height = GetDeviceCaps(hdc, VERTRES);
+ }
+}
+
+/**
+ * Low-level OS/window system memory buffer
+ */
+struct wm_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+ void *mapped;
+};
+
+struct wmesa_surface
+{
+ struct pipe_surface surface;
+
+ int no_swap;
+};
+
+
+/** Cast wrapper */
+static INLINE struct wmesa_surface *
+wmesa_surface(struct pipe_surface *ps)
+{
+// assert(0);
+ return (struct wmesa_surface *) ps;
+}
+
+/**
+ * Turn the softpipe opaque buffer pointer into a dri_bufmgr opaque
+ * buffer pointer...
+ */
+static INLINE struct wm_buffer *
+wm_buffer( struct pipe_buffer *buf )
+{
+ return (struct wm_buffer *)buf;
+}
+
+
+
+/* Most callbacks map direcly onto dri_bufmgr operations:
+ */
+static void *
+wm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct wm_buffer *wm_buf = wm_buffer(buf);
+ wm_buf->mapped = wm_buf->data;
+ return wm_buf->mapped;
+}
+
+static void
+wm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+ struct wm_buffer *wm_buf = wm_buffer(buf);
+ wm_buf->mapped = NULL;
+}
+
+static void
+wm_buffer_destroy(struct pipe_winsys *pws,
+ struct pipe_buffer *buf)
+{
+ struct wm_buffer *oldBuf = wm_buffer(buf);
+
+ if (oldBuf->data) {
+ {
+ if (!oldBuf->userBuffer) {
+ align_free(oldBuf->data);
+ }
+ }
+
+ oldBuf->data = NULL;
+ }
+
+ free(oldBuf);
+}
+
+
+static void
+wm_flush_frontbuffer(struct pipe_winsys *pws,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+ WMesaContext pwc = context_private;
+ WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC);
+ struct wm_buffer *wm_buf;
+ BITMAPINFO bmi, *pbmi;
+
+#if 0
+ if (pwfb)
+ BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height,
+ pwfb->dib_hDC, 0, 0, SRCCOPY);
+#else
+ wm_buf = wm_buffer(surf->buffer);
+
+ pbmi = &bmi;
+ memset(pbmi, 0, sizeof(BITMAPINFO));
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width;
+ pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height);
+ pbmi->bmiHeader.biPlanes = 1;
+ pbmi->bmiHeader.biBitCount = pwfb->cColorBits;
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY);
+#endif
+}
+
+
+
+static const char *
+wm_get_name(struct pipe_winsys *pws)
+{
+ return "gdi";
+}
+
+static struct pipe_buffer *
+wm_buffer_create(struct pipe_winsys *pws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer);
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ if (buffer->data == NULL) {
+ /* align to 16-byte multiple for Cell */
+ buffer->data = align_malloc(size, max(alignment, 16));
+ }
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+wm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
+{
+ struct wm_buffer *buffer = CALLOC_STRUCT(wm_buffer);
+ buffer->base.refcount = 1;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+
+/**
+ * Round n up to next multiple.
+ */
+static INLINE unsigned
+round_up(unsigned n, unsigned multiple)
+{
+ return (n + multiple - 1) & ~(multiple - 1);
+}
+
+static int
+wm_surface_alloc_storage(struct pipe_winsys *winsys,
+ struct pipe_surface *surf,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned flags)
+{
+ const unsigned alignment = 64;
+
+ surf->width = width;
+ surf->height = height;
+ surf->format = format;
+ surf->cpp = pf_get_size(format);
+ surf->pitch = round_up(width, alignment / surf->cpp);
+
+ assert(!surf->buffer);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->pitch * surf->cpp * height);
+ if(!surf->buffer)
+ return -1;
+
+ return 0;
+}
+
+
+/**
+ * Called via winsys->surface_alloc() to create new surfaces.
+ */
+static struct pipe_surface *
+wm_surface_alloc(struct pipe_winsys *ws)
+{
+ struct wmesa_surface *wms = CALLOC_STRUCT(wmesa_surface);
+ static boolean no_swap = 0;
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ no_swap = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ assert(ws);
+
+ wms->surface.refcount = 1;
+ wms->surface.winsys = ws;
+
+ wms->no_swap = no_swap;
+
+ return &wms->surface;
+}
+
+static void
+wm_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
+{
+ struct pipe_surface *surf = *s;
+ surf->refcount--;
+ if (surf->refcount == 0) {
+ if (surf->buffer)
+ pipe_buffer_reference(winsys, &surf->buffer, NULL);
+ free(surf);
+ }
+ *s = NULL;
+}
+
+
+/*
+ * Fence functions - basically nothing to do, as we don't create any actual
+ * fence objects.
+ */
+
+static void
+wm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+}
+
+
+static int
+wm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static int
+wm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+
+struct pipe_winsys *
+wmesa_get_pipe_winsys(GLvisual *visual)
+{
+ static struct wmesa_pipe_winsys *ws = NULL;
+
+ if (!ws) {
+ ws = CALLOC_STRUCT(wmesa_pipe_winsys);
+
+ /* Fill in this struct with callbacks that pipe will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ ws->base.buffer_create = wm_buffer_create;
+ ws->base.user_buffer_create = wm_user_buffer_create;
+ ws->base.buffer_map = wm_buffer_map;
+ ws->base.buffer_unmap = wm_buffer_unmap;
+ ws->base.buffer_destroy = wm_buffer_destroy;
+
+ ws->base.surface_alloc = wm_surface_alloc;
+ ws->base.surface_alloc_storage = wm_surface_alloc_storage;
+ ws->base.surface_release = wm_surface_release;
+
+ ws->base.fence_reference = wm_fence_reference;
+ ws->base.fence_signalled = wm_fence_signalled;
+ ws->base.fence_finish = wm_fence_finish;
+
+ ws->base.flush_frontbuffer = wm_flush_frontbuffer;
+ ws->base.get_name = wm_get_name;
+ }
+
+ return &ws->base;
+}
+
+
+
+/**********************************************************************/
+/***** WMESA Functions *****/
+/**********************************************************************/
+
+WMesaContext WMesaCreateContext(HDC hDC,
+ HPALETTE* Pal,
+ GLboolean rgb_flag,
+ GLboolean db_flag,
+ GLboolean alpha_flag)
+{
+ WMesaContext c;
+ struct pipe_winsys *pws;
+ struct pipe_context *pipe;
+ struct pipe_screen *screen;
+ GLint red_bits, green_bits, blue_bits, alpha_bits;
+ GLvisual *visual;
+
+ (void) Pal;
+
+ /* Indexed mode not supported */
+ if (!rgb_flag)
+ return NULL;
+
+ /* Allocate wmesa context */
+ c = CALLOC_STRUCT(wmesa_context);
+ if (!c)
+ return NULL;
+
+ c->hDC = hDC;
+
+ /* Get data for visual */
+ /* Dealing with this is actually a bit of overkill because Mesa will end
+ * up treating all color component size requests less than 8 by using
+ * a single byte per channel. In addition, the interface to the span
+ * routines passes colors as an entire byte per channel anyway, so there
+ * is nothing to be saved by telling the visual to be 16 bits if the device
+ * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per
+ * channel anyway.
+ * But we go through the motions here anyway.
+ */
+ c->cColorBits = GetDeviceCaps(c->hDC, BITSPIXEL);
+
+ switch (c->cColorBits) {
+ case 16:
+ red_bits = green_bits = blue_bits = 5;
+ alpha_bits = 0;
+ break;
+ default:
+ red_bits = green_bits = blue_bits = 8;
+ alpha_bits = 8;
+ break;
+ }
+ /* Create visual based on flags */
+ visual = _mesa_create_visual(rgb_flag,
+ db_flag, /* db_flag */
+ GL_FALSE, /* stereo */
+ red_bits, green_bits, blue_bits, /* color RGB */
+ alpha_flag ? alpha_bits : 0, /* color A */
+ 0, /* index bits */
+ DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */
+ 8, /* stencil_bits */
+ 16,16,16, /* accum RGB */
+ alpha_flag ? 16 : 0, /* accum A */
+ 1); /* num samples */
+
+ if (!visual) {
+ _mesa_free(c);
+ return NULL;
+ }
+
+ pws = wmesa_get_pipe_winsys(visual);
+
+ screen = softpipe_create_screen(pws);
+
+ if (!screen) {
+ _mesa_free(c);
+ return NULL;
+ }
+
+ pipe = softpipe_create(screen, pws, NULL);
+
+ if (!pipe) {
+ /* FIXME - free screen */
+ _mesa_free(c);
+ return NULL;
+ }
+
+ pipe->priv = c;
+
+ c->st = st_create_context(pipe, visual, NULL);
+
+ c->st->ctx->DriverCtx = c;
+
+ return c;
+}
+
+
+void WMesaDestroyContext( WMesaContext pwc )
+{
+ GLcontext *ctx = pwc->st->ctx;
+ WMesaFramebuffer pwfb;
+ GET_CURRENT_CONTEXT(cur_ctx);
+
+ if (cur_ctx == ctx) {
+ /* unbind current if deleting current context */
+ WMesaMakeCurrent(NULL, NULL);
+ }
+
+ /* clean up frame buffer resources */
+ pwfb = wmesa_lookup_framebuffer(pwc->hDC);
+ if (pwfb) {
+#if 0
+ wmDeleteBackingStore(pwfb);
+#endif
+ wmesa_free_framebuffer(pwc->hDC);
+ }
+
+ /* Release for device, not memory contexts */
+ if (WindowFromDC(pwc->hDC) != NULL)
+ {
+ ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC);
+ }
+
+ st_destroy_context(pwc->st);
+ _mesa_free(pwc);
+}
+
+
+void WMesaMakeCurrent(WMesaContext c, HDC hdc)
+{
+ GLuint width = 0, height = 0;
+ WMesaFramebuffer pwfb;
+
+ {
+ /* return if already current */
+ GET_CURRENT_CONTEXT(ctx);
+ WMesaContext pwc = wmesa_context(ctx);
+ if (pwc && c == pwc && pwc->hDC == hdc)
+ return;
+ }
+
+ pwfb = wmesa_lookup_framebuffer(hdc);
+
+ if (hdc) {
+ get_window_size(hdc, &width, &height);
+ }
+
+ /* Lazy creation of framebuffers */
+ if (c && !pwfb && (hdc != 0)) {
+ GLvisual *visual = &c->st->ctx->Visual;
+
+ pwfb = wmesa_new_framebuffer(hdc, visual, width, height);
+ }
+
+ if (c && pwfb) {
+ st_make_current(c->st, pwfb->stfb, pwfb->stfb);
+
+ st_resize_framebuffer(pwfb->stfb, width, height);
+ }
+ else {
+ /* Detach */
+ st_make_current( NULL, NULL, NULL );
+ }
+}
+
+
+void WMesaSwapBuffers( HDC hdc )
+{
+ struct pipe_surface *surf;
+ struct wm_buffer *wm_buf;
+ WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc);
+ BITMAPINFO bmi, *pbmi;
+
+ if (!pwfb) {
+ _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc");
+ return;
+ }
+
+
+ /* If we're swapping the buffer associated with the current context
+ * we have to flush any pending rendering commands first.
+ */
+ st_notify_swapbuffers(pwfb->stfb);
+
+#if 0
+ BitBlt(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height,
+ pwfb->dib_hDC, 0, 0, SRCCOPY);
+#else
+ surf = st_get_framebuffer_surface(pwfb->stfb, ST_SURFACE_BACK_LEFT);
+ wm_buf = wm_buffer(surf->buffer);
+
+ pbmi = &bmi;
+ memset(pbmi, 0, sizeof(BITMAPINFO));
+ pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmi->bmiHeader.biWidth = pwfb->stfb->Base.Width;
+ pbmi->bmiHeader.biHeight= -((long)pwfb->stfb->Base.Height);
+ pbmi->bmiHeader.biPlanes = 1;
+ pbmi->bmiHeader.biBitCount = pwfb->cColorBits;
+ pbmi->bmiHeader.biCompression = BI_RGB;
+ pbmi->bmiHeader.biSizeImage = 0;
+ pbmi->bmiHeader.biXPelsPerMeter = 0;
+ pbmi->bmiHeader.biYPelsPerMeter = 0;
+ pbmi->bmiHeader.biClrUsed = 0;
+ pbmi->bmiHeader.biClrImportant = 0;
+
+ StretchDIBits(pwfb->hDC, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, 0, 0, pwfb->stfb->Base.Width, pwfb->stfb->Base.Height, wm_buf->data, pbmi, 0, SRCCOPY);
+
+ {
+ GLuint width = 0, height = 0;
+
+ get_window_size(pwfb->hDC, &width, &height);
+
+ st_resize_framebuffer(pwfb->stfb, width, height);
+ }
+#endif
+}
+
+/* This is hopefully a temporary hack to define some needed dispatch
+ * table entries. Hopefully, I'll find a better solution. The
+ * dispatch table generation scripts ought to be making these dummy
+ * stubs as well. */
+#if !defined(__MINGW32__) || !defined(GL_NO_STDCALL)
+void gl_dispatch_stub_543(void){}
+void gl_dispatch_stub_544(void){}
+void gl_dispatch_stub_545(void){}
+void gl_dispatch_stub_546(void){}
+void gl_dispatch_stub_547(void){}
+void gl_dispatch_stub_548(void){}
+void gl_dispatch_stub_549(void){}
+void gl_dispatch_stub_550(void){}
+void gl_dispatch_stub_551(void){}
+void gl_dispatch_stub_552(void){}
+void gl_dispatch_stub_553(void){}
+void gl_dispatch_stub_554(void){}
+void gl_dispatch_stub_555(void){}
+void gl_dispatch_stub_556(void){}
+void gl_dispatch_stub_557(void){}
+void gl_dispatch_stub_558(void){}
+void gl_dispatch_stub_559(void){}
+void gl_dispatch_stub_560(void){}
+void gl_dispatch_stub_561(void){}
+void gl_dispatch_stub_565(void){}
+void gl_dispatch_stub_566(void){}
+void gl_dispatch_stub_577(void){}
+void gl_dispatch_stub_578(void){}
+void gl_dispatch_stub_603(void){}
+void gl_dispatch_stub_645(void){}
+void gl_dispatch_stub_646(void){}
+void gl_dispatch_stub_647(void){}
+void gl_dispatch_stub_648(void){}
+void gl_dispatch_stub_649(void){}
+void gl_dispatch_stub_650(void){}
+void gl_dispatch_stub_651(void){}
+void gl_dispatch_stub_652(void){}
+void gl_dispatch_stub_653(void){}
+void gl_dispatch_stub_733(void){}
+void gl_dispatch_stub_734(void){}
+void gl_dispatch_stub_735(void){}
+void gl_dispatch_stub_736(void){}
+void gl_dispatch_stub_737(void){}
+void gl_dispatch_stub_738(void){}
+void gl_dispatch_stub_744(void){}
+void gl_dispatch_stub_745(void){}
+void gl_dispatch_stub_746(void){}
+void gl_dispatch_stub_760(void){}
+void gl_dispatch_stub_761(void){}
+void gl_dispatch_stub_763(void){}
+void gl_dispatch_stub_765(void){}
+void gl_dispatch_stub_766(void){}
+void gl_dispatch_stub_767(void){}
+void gl_dispatch_stub_768(void){}
+
+void gl_dispatch_stub_562(void){}
+void gl_dispatch_stub_563(void){}
+void gl_dispatch_stub_564(void){}
+void gl_dispatch_stub_567(void){}
+void gl_dispatch_stub_568(void){}
+void gl_dispatch_stub_569(void){}
+void gl_dispatch_stub_580(void){}
+void gl_dispatch_stub_581(void){}
+void gl_dispatch_stub_606(void){}
+void gl_dispatch_stub_654(void){}
+void gl_dispatch_stub_655(void){}
+void gl_dispatch_stub_656(void){}
+void gl_dispatch_stub_739(void){}
+void gl_dispatch_stub_740(void){}
+void gl_dispatch_stub_741(void){}
+void gl_dispatch_stub_748(void){}
+void gl_dispatch_stub_749(void){}
+void gl_dispatch_stub_769(void){}
+void gl_dispatch_stub_770(void){}
+void gl_dispatch_stub_771(void){}
+void gl_dispatch_stub_772(void){}
+void gl_dispatch_stub_773(void){}
+
+#endif
diff --git a/src/gallium/winsys/gdi/wmesadef.h b/src/gallium/winsys/gdi/wmesadef.h
new file mode 100644
index 0000000000..fb8ce30a08
--- /dev/null
+++ b/src/gallium/winsys/gdi/wmesadef.h
@@ -0,0 +1,40 @@
+#ifndef WMESADEF_H
+#define WMESADEF_H
+#ifdef __MINGW32__
+#include <windows.h>
+#endif
+#if 0
+#include "context.h"
+#endif
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_public.h"
+
+
+/**
+ * The Windows Mesa rendering context, derived from GLcontext.
+ */
+struct wmesa_context {
+ struct st_context *st;
+ HDC hDC;
+ BYTE cColorBits;
+};
+
+/**
+ * Windows framebuffer, derived from gl_framebuffer
+ */
+struct wmesa_framebuffer
+{
+ struct st_framebuffer *stfb;
+ HDC hDC;
+ int pixelformat;
+ BYTE cColorBits;
+ HDC dib_hDC;
+ HBITMAP hbmDIB;
+ HBITMAP hOldBitmap;
+ PBYTE pbPixels;
+ struct wmesa_framebuffer *next;
+};
+
+typedef struct wmesa_framebuffer *WMesaFramebuffer;
+
+#endif /* WMESADEF_H */
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index 218b89285f..5e98a36abc 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -3,30 +3,32 @@
Import('*')
-env = env.Clone()
+if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']:
-env.Append(CPPPATH = [
- '#/src/mesa',
- '#/src/mesa/main',
-])
+ env = env.Clone()
-sources = [
- 'glxapi.c',
- 'fakeglx.c',
- 'xfonts.c',
- 'xm_api.c',
- 'xm_winsys.c',
- 'xm_winsys_aub.c',
- 'brw_aub.c',
-]
-
-drivers = [
- softpipe,
-]
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/mesa/main',
+ ])
-# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
-env.SharedLibrary(
- target ='GL',
- source = sources,
- LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'],
-)
+ sources = [
+ 'glxapi.c',
+ 'fakeglx.c',
+ 'xfonts.c',
+ 'xm_api.c',
+ 'xm_winsys.c',
+ 'xm_winsys_aub.c',
+ 'brw_aub.c',
+ ]
+
+ drivers = [
+ softpipe,
+ ]
+
+ # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+ env.SharedLibrary(
+ target ='GL',
+ source = sources,
+ LIBS = glapi + mesa + drivers + auxiliaries + env['LIBS'],
+ )
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 6b99dacf2a..04b771a7e1 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -4,307 +4,309 @@
Import('*')
-env = env.Clone()
+if env['platform'] != 'winddk':
-# Includes
-env.Append(CPPPATH = [
- '#/src/mesa',
- '#/src/mesa/main',
-])
-
-if gcc:
- env.Append(CFLAGS = [
- '-std=c99',
- ])
-
-# x86 assembly
-if x86 and gcc:
- env.Append(CPPDEFINES = [
- 'USE_X86_ASM',
- 'USE_MMX_ASM',
- 'USE_3DNOW_ASM',
- 'USE_SSE_ASM',
+ env = env.Clone()
+
+ # Includes
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/mesa/main',
])
-
-
-#######################################################################
-# Core sources
-
-MAIN_SOURCES = [
- 'main/api_arrayelt.c',
- 'main/api_loopback.c',
- 'main/api_noop.c',
- 'main/api_validate.c',
- 'main/accum.c',
- 'main/attrib.c',
- 'main/arrayobj.c',
- 'main/blend.c',
- 'main/bufferobj.c',
- 'main/buffers.c',
- 'main/clip.c',
- 'main/colortab.c',
- 'main/context.c',
- 'main/convolve.c',
- 'main/debug.c',
- 'main/depth.c',
- 'main/depthstencil.c',
- 'main/dlist.c',
- 'main/drawpix.c',
- 'main/enable.c',
- 'main/enums.c',
- 'main/eval.c',
- 'main/execmem.c',
- 'main/extensions.c',
- 'main/fbobject.c',
- 'main/feedback.c',
- 'main/ffvertex_prog.c',
- 'main/fog.c',
- 'main/framebuffer.c',
- 'main/get.c',
- 'main/getstring.c',
- 'main/hash.c',
- 'main/hint.c',
- 'main/histogram.c',
- 'main/image.c',
- 'main/imports.c',
- 'main/light.c',
- 'main/lines.c',
- 'main/matrix.c',
- 'main/mipmap.c',
- 'main/mm.c',
- 'main/pixel.c',
- 'main/points.c',
- 'main/polygon.c',
- 'main/queryobj.c',
- 'main/rastpos.c',
- 'main/rbadaptors.c',
- 'main/renderbuffer.c',
- 'main/shaders.c',
- 'main/state.c',
- 'main/stencil.c',
- 'main/texcompress.c',
- 'main/texcompress_s3tc.c',
- 'main/texcompress_fxt1.c',
- 'main/texenvprogram.c',
- 'main/texformat.c',
- 'main/teximage.c',
- 'main/texobj.c',
- 'main/texrender.c',
- 'main/texstate.c',
- 'main/texstore.c',
- 'main/varray.c',
- 'main/vtxfmt.c',
-]
-
-GLAPI_SOURCES = [
- 'main/dispatch.c',
- 'glapi/glapi.c',
- 'glapi/glthread.c',
-]
-
-MATH_SOURCES = [
- 'math/m_debug_clip.c',
- 'math/m_debug_norm.c',
- 'math/m_debug_xform.c',
- 'math/m_eval.c',
- 'math/m_matrix.c',
- 'math/m_translate.c',
- 'math/m_vector.c',
- 'math/m_xform.c',
-]
-
-VBO_SOURCES = [
- 'vbo/vbo_context.c',
- 'vbo/vbo_exec.c',
- 'vbo/vbo_exec_api.c',
- 'vbo/vbo_exec_array.c',
- 'vbo/vbo_exec_draw.c',
- 'vbo/vbo_exec_eval.c',
- 'vbo/vbo_rebase.c',
- 'vbo/vbo_split.c',
- 'vbo/vbo_split_copy.c',
- 'vbo/vbo_split_inplace.c',
- 'vbo/vbo_save.c',
- 'vbo/vbo_save_api.c',
- 'vbo/vbo_save_draw.c',
- 'vbo/vbo_save_loopback.c',
-]
-
-VF_SOURCES = [
- 'vf/vf.c',
- 'vf/vf_generic.c',
- 'vf/vf_sse.c',
-]
-
-STATETRACKER_SOURCES = [
- 'state_tracker/st_atom.c',
- 'state_tracker/st_atom_blend.c',
- 'state_tracker/st_atom_clip.c',
- 'state_tracker/st_atom_constbuf.c',
- 'state_tracker/st_atom_depth.c',
- 'state_tracker/st_atom_framebuffer.c',
- 'state_tracker/st_atom_pixeltransfer.c',
- 'state_tracker/st_atom_sampler.c',
- 'state_tracker/st_atom_scissor.c',
- 'state_tracker/st_atom_shader.c',
- 'state_tracker/st_atom_rasterizer.c',
- 'state_tracker/st_atom_stipple.c',
- 'state_tracker/st_atom_texture.c',
- 'state_tracker/st_atom_viewport.c',
- 'state_tracker/st_cb_accum.c',
- 'state_tracker/st_cb_bitmap.c',
- 'state_tracker/st_cb_blit.c',
- 'state_tracker/st_cb_bufferobjects.c',
- 'state_tracker/st_cb_clear.c',
- 'state_tracker/st_cb_flush.c',
- 'state_tracker/st_cb_drawpixels.c',
- 'state_tracker/st_cb_fbo.c',
- 'state_tracker/st_cb_feedback.c',
- 'state_tracker/st_cb_program.c',
- 'state_tracker/st_cb_queryobj.c',
- 'state_tracker/st_cb_rasterpos.c',
- 'state_tracker/st_cb_readpixels.c',
- 'state_tracker/st_cb_strings.c',
- 'state_tracker/st_cb_texture.c',
- 'state_tracker/st_context.c',
- 'state_tracker/st_debug.c',
- 'state_tracker/st_draw.c',
- 'state_tracker/st_extensions.c',
- 'state_tracker/st_format.c',
- 'state_tracker/st_framebuffer.c',
- 'state_tracker/st_gen_mipmap.c',
- 'state_tracker/st_mesa_to_tgsi.c',
- 'state_tracker/st_program.c',
- 'state_tracker/st_texture.c',
-]
-
-SHADER_SOURCES = [
- 'shader/arbprogparse.c',
- 'shader/arbprogram.c',
- 'shader/atifragshader.c',
- 'shader/grammar/grammar_mesa.c',
- 'shader/nvfragparse.c',
- 'shader/nvprogram.c',
- 'shader/nvvertparse.c',
- 'shader/program.c',
- 'shader/prog_cache.c',
- 'shader/prog_debug.c',
- 'shader/prog_execute.c',
- 'shader/prog_instruction.c',
- 'shader/prog_parameter.c',
- 'shader/prog_print.c',
- 'shader/prog_statevars.c',
- 'shader/prog_uniform.c',
- 'shader/programopt.c',
- 'shader/shader_api.c',
-]
-
-SLANG_SOURCES = [
- 'shader/slang/slang_builtin.c',
- 'shader/slang/slang_codegen.c',
- 'shader/slang/slang_compile.c',
- 'shader/slang/slang_compile_function.c',
- 'shader/slang/slang_compile_operation.c',
- 'shader/slang/slang_compile_struct.c',
- 'shader/slang/slang_compile_variable.c',
- 'shader/slang/slang_emit.c',
- 'shader/slang/slang_ir.c',
- 'shader/slang/slang_label.c',
- 'shader/slang/slang_library_noise.c',
- 'shader/slang/slang_link.c',
- 'shader/slang/slang_log.c',
- 'shader/slang/slang_mem.c',
- 'shader/slang/slang_preprocess.c',
- 'shader/slang/slang_print.c',
- 'shader/slang/slang_simplify.c',
- 'shader/slang/slang_storage.c',
- 'shader/slang/slang_typeinfo.c',
- 'shader/slang/slang_vartable.c',
- 'shader/slang/slang_utility.c',
-]
-
-
-#######################################################################
-# Assembly sources
-
-ASM_C_SOURCES = [
- 'x86/common_x86.c',
- 'x86/x86.c',
- 'x86/3dnow.c',
- 'x86/sse.c',
- 'sparc/sparc.c',
- 'ppc/common_ppc.c',
- 'x86-64/x86-64.c',
-]
-
-X86_SOURCES = [
- 'x86/common_x86_asm.S',
- 'x86/x86_xform2.S',
- 'x86/x86_xform3.S',
- 'x86/x86_xform4.S',
- 'x86/x86_cliptest.S',
- 'x86/mmx_blend.S',
- 'x86/3dnow_xform1.S',
- 'x86/3dnow_xform2.S',
- 'x86/3dnow_xform3.S',
- 'x86/3dnow_xform4.S',
- 'x86/3dnow_normal.S',
- 'x86/sse_xform1.S',
- 'x86/sse_xform2.S',
- 'x86/sse_xform3.S',
- 'x86/sse_xform4.S',
- 'x86/sse_normal.S',
- 'x86/read_rgba_span_x86.S',
-]
-
-X86_API = [
- 'x86/glapi_x86.S',
-]
-
-X86_64_SOURCES = [
- 'x86-64/xform4.S',
-]
-
-X86_64_API = [
- 'x86-64/glapi_x86-64.S',
-]
-
-SPARC_SOURCES = [
- 'sparc/clip.S',
- 'sparc/norm.S',
- 'sparc/xform.S',
-]
-
-SPARC_API = [
- 'sparc/glapi_sparc.S',
-]
-
-if x86 and gcc:
- ASM_SOURCES = ASM_C_SOURCES + X86_SOURCES
- API_SOURCES = X86_API
-else:
- ASM_SOURCES = []
- API_SOURCES = []
-
-SOLO_SOURCES = \
- MAIN_SOURCES + \
- MATH_SOURCES + \
- VBO_SOURCES + \
- VF_SOURCES + \
- STATETRACKER_SOURCES + \
- SHADER_SOURCES + \
- ASM_SOURCES + \
- SLANG_SOURCES
-
-mesa = env.ConvenienceLibrary(
- target = 'mesa',
- source = SOLO_SOURCES,
-)
-Export('mesa')
-
-if not dri:
- glapi = env.ConvenienceLibrary(
- target = 'glapi',
- source = GLAPI_SOURCES + API_SOURCES,
+
+ if gcc:
+ env.Append(CFLAGS = [
+ '-std=c99',
+ ])
+
+ # x86 assembly
+ if x86 and gcc:
+ env.Append(CPPDEFINES = [
+ 'USE_X86_ASM',
+ 'USE_MMX_ASM',
+ 'USE_3DNOW_ASM',
+ 'USE_SSE_ASM',
+ ])
+
+
+ #######################################################################
+ # Core sources
+
+ MAIN_SOURCES = [
+ 'main/api_arrayelt.c',
+ 'main/api_loopback.c',
+ 'main/api_noop.c',
+ 'main/api_validate.c',
+ 'main/accum.c',
+ 'main/attrib.c',
+ 'main/arrayobj.c',
+ 'main/blend.c',
+ 'main/bufferobj.c',
+ 'main/buffers.c',
+ 'main/clip.c',
+ 'main/colortab.c',
+ 'main/context.c',
+ 'main/convolve.c',
+ 'main/debug.c',
+ 'main/depth.c',
+ 'main/depthstencil.c',
+ 'main/dlist.c',
+ 'main/drawpix.c',
+ 'main/enable.c',
+ 'main/enums.c',
+ 'main/eval.c',
+ 'main/execmem.c',
+ 'main/extensions.c',
+ 'main/fbobject.c',
+ 'main/feedback.c',
+ 'main/ffvertex_prog.c',
+ 'main/fog.c',
+ 'main/framebuffer.c',
+ 'main/get.c',
+ 'main/getstring.c',
+ 'main/hash.c',
+ 'main/hint.c',
+ 'main/histogram.c',
+ 'main/image.c',
+ 'main/imports.c',
+ 'main/light.c',
+ 'main/lines.c',
+ 'main/matrix.c',
+ 'main/mipmap.c',
+ 'main/mm.c',
+ 'main/pixel.c',
+ 'main/points.c',
+ 'main/polygon.c',
+ 'main/queryobj.c',
+ 'main/rastpos.c',
+ 'main/rbadaptors.c',
+ 'main/renderbuffer.c',
+ 'main/shaders.c',
+ 'main/state.c',
+ 'main/stencil.c',
+ 'main/texcompress.c',
+ 'main/texcompress_s3tc.c',
+ 'main/texcompress_fxt1.c',
+ 'main/texenvprogram.c',
+ 'main/texformat.c',
+ 'main/teximage.c',
+ 'main/texobj.c',
+ 'main/texrender.c',
+ 'main/texstate.c',
+ 'main/texstore.c',
+ 'main/varray.c',
+ 'main/vtxfmt.c',
+ ]
+
+ GLAPI_SOURCES = [
+ 'main/dispatch.c',
+ 'glapi/glapi.c',
+ 'glapi/glthread.c',
+ ]
+
+ MATH_SOURCES = [
+ 'math/m_debug_clip.c',
+ 'math/m_debug_norm.c',
+ 'math/m_debug_xform.c',
+ 'math/m_eval.c',
+ 'math/m_matrix.c',
+ 'math/m_translate.c',
+ 'math/m_vector.c',
+ 'math/m_xform.c',
+ ]
+
+ VBO_SOURCES = [
+ 'vbo/vbo_context.c',
+ 'vbo/vbo_exec.c',
+ 'vbo/vbo_exec_api.c',
+ 'vbo/vbo_exec_array.c',
+ 'vbo/vbo_exec_draw.c',
+ 'vbo/vbo_exec_eval.c',
+ 'vbo/vbo_rebase.c',
+ 'vbo/vbo_split.c',
+ 'vbo/vbo_split_copy.c',
+ 'vbo/vbo_split_inplace.c',
+ 'vbo/vbo_save.c',
+ 'vbo/vbo_save_api.c',
+ 'vbo/vbo_save_draw.c',
+ 'vbo/vbo_save_loopback.c',
+ ]
+
+ VF_SOURCES = [
+ 'vf/vf.c',
+ 'vf/vf_generic.c',
+ 'vf/vf_sse.c',
+ ]
+
+ STATETRACKER_SOURCES = [
+ 'state_tracker/st_atom.c',
+ 'state_tracker/st_atom_blend.c',
+ 'state_tracker/st_atom_clip.c',
+ 'state_tracker/st_atom_constbuf.c',
+ 'state_tracker/st_atom_depth.c',
+ 'state_tracker/st_atom_framebuffer.c',
+ 'state_tracker/st_atom_pixeltransfer.c',
+ 'state_tracker/st_atom_sampler.c',
+ 'state_tracker/st_atom_scissor.c',
+ 'state_tracker/st_atom_shader.c',
+ 'state_tracker/st_atom_rasterizer.c',
+ 'state_tracker/st_atom_stipple.c',
+ 'state_tracker/st_atom_texture.c',
+ 'state_tracker/st_atom_viewport.c',
+ 'state_tracker/st_cb_accum.c',
+ 'state_tracker/st_cb_bitmap.c',
+ 'state_tracker/st_cb_blit.c',
+ 'state_tracker/st_cb_bufferobjects.c',
+ 'state_tracker/st_cb_clear.c',
+ 'state_tracker/st_cb_flush.c',
+ 'state_tracker/st_cb_drawpixels.c',
+ 'state_tracker/st_cb_fbo.c',
+ 'state_tracker/st_cb_feedback.c',
+ 'state_tracker/st_cb_program.c',
+ 'state_tracker/st_cb_queryobj.c',
+ 'state_tracker/st_cb_rasterpos.c',
+ 'state_tracker/st_cb_readpixels.c',
+ 'state_tracker/st_cb_strings.c',
+ 'state_tracker/st_cb_texture.c',
+ 'state_tracker/st_context.c',
+ 'state_tracker/st_debug.c',
+ 'state_tracker/st_draw.c',
+ 'state_tracker/st_extensions.c',
+ 'state_tracker/st_format.c',
+ 'state_tracker/st_framebuffer.c',
+ 'state_tracker/st_gen_mipmap.c',
+ 'state_tracker/st_mesa_to_tgsi.c',
+ 'state_tracker/st_program.c',
+ 'state_tracker/st_texture.c',
+ ]
+
+ SHADER_SOURCES = [
+ 'shader/arbprogparse.c',
+ 'shader/arbprogram.c',
+ 'shader/atifragshader.c',
+ 'shader/grammar/grammar_mesa.c',
+ 'shader/nvfragparse.c',
+ 'shader/nvprogram.c',
+ 'shader/nvvertparse.c',
+ 'shader/program.c',
+ 'shader/prog_cache.c',
+ 'shader/prog_debug.c',
+ 'shader/prog_execute.c',
+ 'shader/prog_instruction.c',
+ 'shader/prog_parameter.c',
+ 'shader/prog_print.c',
+ 'shader/prog_statevars.c',
+ 'shader/prog_uniform.c',
+ 'shader/programopt.c',
+ 'shader/shader_api.c',
+ ]
+
+ SLANG_SOURCES = [
+ 'shader/slang/slang_builtin.c',
+ 'shader/slang/slang_codegen.c',
+ 'shader/slang/slang_compile.c',
+ 'shader/slang/slang_compile_function.c',
+ 'shader/slang/slang_compile_operation.c',
+ 'shader/slang/slang_compile_struct.c',
+ 'shader/slang/slang_compile_variable.c',
+ 'shader/slang/slang_emit.c',
+ 'shader/slang/slang_ir.c',
+ 'shader/slang/slang_label.c',
+ 'shader/slang/slang_library_noise.c',
+ 'shader/slang/slang_link.c',
+ 'shader/slang/slang_log.c',
+ 'shader/slang/slang_mem.c',
+ 'shader/slang/slang_preprocess.c',
+ 'shader/slang/slang_print.c',
+ 'shader/slang/slang_simplify.c',
+ 'shader/slang/slang_storage.c',
+ 'shader/slang/slang_typeinfo.c',
+ 'shader/slang/slang_vartable.c',
+ 'shader/slang/slang_utility.c',
+ ]
+
+
+ #######################################################################
+ # Assembly sources
+
+ ASM_C_SOURCES = [
+ 'x86/common_x86.c',
+ 'x86/x86.c',
+ 'x86/3dnow.c',
+ 'x86/sse.c',
+ 'sparc/sparc.c',
+ 'ppc/common_ppc.c',
+ 'x86-64/x86-64.c',
+ ]
+
+ X86_SOURCES = [
+ 'x86/common_x86_asm.S',
+ 'x86/x86_xform2.S',
+ 'x86/x86_xform3.S',
+ 'x86/x86_xform4.S',
+ 'x86/x86_cliptest.S',
+ 'x86/mmx_blend.S',
+ 'x86/3dnow_xform1.S',
+ 'x86/3dnow_xform2.S',
+ 'x86/3dnow_xform3.S',
+ 'x86/3dnow_xform4.S',
+ 'x86/3dnow_normal.S',
+ 'x86/sse_xform1.S',
+ 'x86/sse_xform2.S',
+ 'x86/sse_xform3.S',
+ 'x86/sse_xform4.S',
+ 'x86/sse_normal.S',
+ 'x86/read_rgba_span_x86.S',
+ ]
+
+ X86_API = [
+ 'x86/glapi_x86.S',
+ ]
+
+ X86_64_SOURCES = [
+ 'x86-64/xform4.S',
+ ]
+
+ X86_64_API = [
+ 'x86-64/glapi_x86-64.S',
+ ]
+
+ SPARC_SOURCES = [
+ 'sparc/clip.S',
+ 'sparc/norm.S',
+ 'sparc/xform.S',
+ ]
+
+ SPARC_API = [
+ 'sparc/glapi_sparc.S',
+ ]
+
+ if x86 and gcc:
+ ASM_SOURCES = ASM_C_SOURCES + X86_SOURCES
+ API_SOURCES = X86_API
+ else:
+ ASM_SOURCES = []
+ API_SOURCES = []
+
+ SOLO_SOURCES = \
+ MAIN_SOURCES + \
+ MATH_SOURCES + \
+ VBO_SOURCES + \
+ VF_SOURCES + \
+ STATETRACKER_SOURCES + \
+ SHADER_SOURCES + \
+ ASM_SOURCES + \
+ SLANG_SOURCES
+
+ mesa = env.ConvenienceLibrary(
+ target = 'mesa',
+ source = SOLO_SOURCES,
)
- Export('glapi')
+ Export('mesa')
+
+ if not dri:
+ glapi = env.ConvenienceLibrary(
+ target = 'glapi',
+ source = GLAPI_SOURCES + API_SOURCES,
+ )
+ Export('glapi')
diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h
index afb04f7bf2..b8e9d5f59b 100644
--- a/src/mesa/glapi/glthread.h
+++ b/src/mesa/glapi/glthread.h
@@ -116,9 +116,49 @@ typedef pthread_mutex_t _glthread_Mutex;
#define _glthread_UNLOCK_MUTEX(name) \
(void) pthread_mutex_unlock(&(name))
-#endif /* PTHREADS */
+typedef pthread_cond_t _glthread_Cond;
+#define _glthread_DECLARE_STATIC_COND(name) \
+ static _glthread_Cond name = PTHREAD_COND_INITIALIZER
+#define _glthread_INIT_COND(cond) \
+ pthread_cond_init(&(cond), NULL)
+
+#define _glthread_DESTROY_COND(name) \
+ pthread_cond_destroy(&(name))
+
+#define _glthread_COND_WAIT(cond, mutex) \
+ pthread_cond_wait(&(cond), &(mutex))
+
+#define _glthread_COND_SIGNAL(cond) \
+ pthread_cond_signal(&(cond))
+
+#define _glthread_COND_BROADCAST(cond) \
+ pthread_cond_broadcast(&(cond))
+
+
+#else /* PTHREADS */
+
+typedef unsigned int _glthread_Cond;
+#define _glthread_DECLARE_STATIC_COND(name) \
+// #warning Condition variables not implemented.
+
+#define _glthread_INIT_COND(cond) \
+ abort();
+
+#define _glthread_DESTROY_COND(name) \
+ abort();
+
+#define _glthread_COND_WAIT(cond, mutex) \
+ abort();
+
+#define _glthread_COND_SIGNAL(cond) \
+ abort();
+
+#define _glthread_COND_BROADCAST(cond) \
+ abort();
+
+#endif
/*
@@ -259,11 +299,11 @@ typedef benaphore _glthread_Mutex;
* THREADS not defined
*/
-typedef unsigned _glthread_TSD;
+typedef GLuint _glthread_TSD;
-typedef unsigned _glthread_Thread;
+typedef GLuint _glthread_Thread;
-typedef unsigned _glthread_Mutex;
+typedef GLuint _glthread_Mutex;
#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0
diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c
index 72091b0789..d124c724c9 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -166,7 +166,7 @@ static void GLAPIENTRY VertexAttrib1NbvNV(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib1bvNV(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
@@ -176,7 +176,7 @@ static void GLAPIENTRY VertexAttrib2NbvNV(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib2bvNV(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
@@ -188,7 +188,7 @@ static void GLAPIENTRY VertexAttrib3NbvNV(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib3bvNV(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
@@ -201,7 +201,7 @@ static void GLAPIENTRY VertexAttrib4NbvNV(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib4bvNV(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_BYTE attributes */
@@ -213,7 +213,7 @@ static void GLAPIENTRY VertexAttrib1NubvNV(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib1ubvNV(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
@@ -224,7 +224,7 @@ static void GLAPIENTRY VertexAttrib2NubvNV(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib2ubvNV(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
@@ -235,7 +235,7 @@ static void GLAPIENTRY VertexAttrib3NubvNV(GLuint index, const GLubyte *v)
}
static void GLAPIENTRY VertexAttrib3ubvNV(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
@@ -248,7 +248,7 @@ static void GLAPIENTRY VertexAttrib4NubvNV(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib4ubvNV(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_SHORT attributes */
@@ -260,7 +260,7 @@ static void GLAPIENTRY VertexAttrib1NsvNV(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib1svNV(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
@@ -271,7 +271,7 @@ static void GLAPIENTRY VertexAttrib2NsvNV(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib2svNV(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
@@ -283,7 +283,7 @@ static void GLAPIENTRY VertexAttrib3NsvNV(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib3svNV(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
@@ -296,7 +296,7 @@ static void GLAPIENTRY VertexAttrib4NsvNV(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib4svNV(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_SHORT attributes */
@@ -308,7 +308,7 @@ static void GLAPIENTRY VertexAttrib1NusvNV(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib1usvNV(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
@@ -319,7 +319,7 @@ static void GLAPIENTRY VertexAttrib2NusvNV(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib2usvNV(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
@@ -331,7 +331,7 @@ static void GLAPIENTRY VertexAttrib3NusvNV(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib3usvNV(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
@@ -344,7 +344,7 @@ static void GLAPIENTRY VertexAttrib4NusvNV(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib4usvNV(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_INT attributes */
@@ -356,7 +356,7 @@ static void GLAPIENTRY VertexAttrib1NivNV(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib1ivNV(GLuint index, const GLint *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
@@ -367,7 +367,7 @@ static void GLAPIENTRY VertexAttrib2NivNV(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib2ivNV(GLuint index, const GLint *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
@@ -379,7 +379,7 @@ static void GLAPIENTRY VertexAttrib3NivNV(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib3ivNV(GLuint index, const GLint *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
@@ -392,7 +392,7 @@ static void GLAPIENTRY VertexAttrib4NivNV(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib4ivNV(GLuint index, const GLint *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_INT attributes */
@@ -404,7 +404,7 @@ static void GLAPIENTRY VertexAttrib1NuivNV(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib1uivNV(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fNV(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
@@ -415,7 +415,7 @@ static void GLAPIENTRY VertexAttrib2NuivNV(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib2uivNV(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
@@ -427,7 +427,7 @@ static void GLAPIENTRY VertexAttrib3NuivNV(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib3uivNV(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
@@ -440,7 +440,7 @@ static void GLAPIENTRY VertexAttrib4NuivNV(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib4uivNV(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fNV(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_FLOAT attributes */
@@ -602,7 +602,7 @@ static void GLAPIENTRY VertexAttrib1NbvARB(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib1bvARB(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NbvARB(GLuint index, const GLbyte *v)
@@ -612,7 +612,7 @@ static void GLAPIENTRY VertexAttrib2NbvARB(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib2bvARB(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NbvARB(GLuint index, const GLbyte *v)
@@ -624,7 +624,7 @@ static void GLAPIENTRY VertexAttrib3NbvARB(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib3bvARB(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
@@ -637,7 +637,7 @@ static void GLAPIENTRY VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
static void GLAPIENTRY VertexAttrib4bvARB(GLuint index, const GLbyte *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_BYTE attributes */
@@ -649,7 +649,7 @@ static void GLAPIENTRY VertexAttrib1NubvARB(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib1ubvARB(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NubvARB(GLuint index, const GLubyte *v)
@@ -660,7 +660,7 @@ static void GLAPIENTRY VertexAttrib2NubvARB(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib2ubvARB(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NubvARB(GLuint index, const GLubyte *v)
@@ -671,7 +671,7 @@ static void GLAPIENTRY VertexAttrib3NubvARB(GLuint index, const GLubyte *v)
}
static void GLAPIENTRY VertexAttrib3ubvARB(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
@@ -684,7 +684,7 @@ static void GLAPIENTRY VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
static void GLAPIENTRY VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_SHORT attributes */
@@ -696,7 +696,7 @@ static void GLAPIENTRY VertexAttrib1NsvARB(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib1svARB(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NsvARB(GLuint index, const GLshort *v)
@@ -707,7 +707,7 @@ static void GLAPIENTRY VertexAttrib2NsvARB(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib2svARB(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NsvARB(GLuint index, const GLshort *v)
@@ -719,7 +719,7 @@ static void GLAPIENTRY VertexAttrib3NsvARB(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib3svARB(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NsvARB(GLuint index, const GLshort *v)
@@ -732,7 +732,7 @@ static void GLAPIENTRY VertexAttrib4NsvARB(GLuint index, const GLshort *v)
static void GLAPIENTRY VertexAttrib4svARB(GLuint index, const GLshort *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_SHORT attributes */
@@ -744,7 +744,7 @@ static void GLAPIENTRY VertexAttrib1NusvARB(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib1usvARB(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NusvARB(GLuint index, const GLushort *v)
@@ -755,7 +755,7 @@ static void GLAPIENTRY VertexAttrib2NusvARB(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib2usvARB(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NusvARB(GLuint index, const GLushort *v)
@@ -767,7 +767,7 @@ static void GLAPIENTRY VertexAttrib3NusvARB(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib3usvARB(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NusvARB(GLuint index, const GLushort *v)
@@ -780,7 +780,7 @@ static void GLAPIENTRY VertexAttrib4NusvARB(GLuint index, const GLushort *v)
static void GLAPIENTRY VertexAttrib4usvARB(GLuint index, const GLushort *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_INT attributes */
@@ -792,7 +792,7 @@ static void GLAPIENTRY VertexAttrib1NivARB(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib1ivARB(GLuint index, const GLint *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NivARB(GLuint index, const GLint *v)
@@ -803,7 +803,7 @@ static void GLAPIENTRY VertexAttrib2NivARB(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib2ivARB(GLuint index, const GLint *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NivARB(GLuint index, const GLint *v)
@@ -815,7 +815,7 @@ static void GLAPIENTRY VertexAttrib3NivARB(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib3ivARB(GLuint index, const GLint *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NivARB(GLuint index, const GLint *v)
@@ -828,7 +828,7 @@ static void GLAPIENTRY VertexAttrib4NivARB(GLuint index, const GLint *v)
static void GLAPIENTRY VertexAttrib4ivARB(GLuint index, const GLint *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_UNSIGNED_INT attributes */
@@ -840,7 +840,7 @@ static void GLAPIENTRY VertexAttrib1NuivARB(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib1uivARB(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, v[0]));
+ CALL_VertexAttrib1fARB(GET_DISPATCH(), (index, (GLfloat)v[0]));
}
static void GLAPIENTRY VertexAttrib2NuivARB(GLuint index, const GLuint *v)
@@ -851,7 +851,7 @@ static void GLAPIENTRY VertexAttrib2NuivARB(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib2uivARB(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, v[0], v[1]));
+ CALL_VertexAttrib2fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1]));
}
static void GLAPIENTRY VertexAttrib3NuivARB(GLuint index, const GLuint *v)
@@ -863,7 +863,7 @@ static void GLAPIENTRY VertexAttrib3NuivARB(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib3uivARB(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, v[0], v[1], v[2]));
+ CALL_VertexAttrib3fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2]));
}
static void GLAPIENTRY VertexAttrib4NuivARB(GLuint index, const GLuint *v)
@@ -876,7 +876,7 @@ static void GLAPIENTRY VertexAttrib4NuivARB(GLuint index, const GLuint *v)
static void GLAPIENTRY VertexAttrib4uivARB(GLuint index, const GLuint *v)
{
- CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, v[0], v[1], v[2], v[3]));
+ CALL_VertexAttrib4fARB(GET_DISPATCH(), (index, (GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]));
}
/* GL_FLOAT attributes */
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 64ab324af2..9144b4bc66 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -87,7 +87,7 @@ _mesa_validate_DrawElements(GLcontext *ctx,
indexBytes = count * sizeof(GLushort);
}
- if (indexBytes > ctx->Array.ElementArrayBufferObj->Size) {
+ if (indexBytes > (GLuint) ctx->Array.ElementArrayBufferObj->Size) {
_mesa_warning(ctx, "glDrawElements index out of buffer bounds");
return GL_FALSE;
}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 2158eb6873..0053180000 100755
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1532,7 +1532,7 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
* if the DRIdrawable changes, and everything relies on them.
* This is a bit messy (same as needed in _mesa_BindFramebufferEXT)
*/
- int i;
+ unsigned int i;
GLenum buffers[MAX_DRAW_BUFFERS];
_mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 13ebd4dd0d..f933580b2d 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -5069,7 +5069,7 @@ save_Indexfv(const GLfloat * v)
static void GLAPIENTRY
save_EdgeFlag(GLboolean x)
{
- save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? 1.0 : 0.0);
+ save_Attr1fNV(VERT_ATTRIB_EDGEFLAG, x ? (GLfloat)1.0 : (GLfloat)0.0);
}
static void GLAPIENTRY
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index fa422bb3c7..016ddd0a81 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -377,7 +377,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
if (ctx->RenderMode == GL_RENDER) {
/* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
- const GLfloat epsilon = 0.0001;
+ const GLfloat epsilon = (const GLfloat)0.0001;
GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index c9b30d3252..894d99afd2 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -67,7 +67,7 @@ compute_depth_max(struct gl_framebuffer *fb)
fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
/* Minimum resolvable depth value, for polygon offset */
- fb->_MRD = 1.0 / fb->_DepthMaxF;
+ fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF;
}
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index eb81ee4a52..ee48b78318 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -2124,7 +2124,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
params[0] = (GLfloat)(ctx->DrawBuffer->Visual.depthBits);
break;
case GL_DEPTH_CLEAR_VALUE:
- params[0] = ctx->Depth.Clear;
+ params[0] = (GLfloat)ctx->Depth.Clear;
break;
case GL_DEPTH_FUNC:
params[0] = ENUM_TO_FLOAT(ctx->Depth.Func);
@@ -2914,7 +2914,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE);
ASSERT(n <= 100);
for (i = 0; i < n; i++)
- params[i] = ENUM_TO_INT(formats[i]);
+ params[i] = (GLfloat)(ENUM_TO_INT(formats[i]));
}
break;
case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT:
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 76e105e65e..285c8346a5 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -1169,7 +1169,7 @@ _mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
GLuint mask = ctx->PixelMaps.StoS.Size - 1;
GLuint i;
for (i = 0; i < n; i++) {
- stencil[i] = ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
+ stencil[i] = (GLstencil)ctx->PixelMaps.StoS.Map[ stencil[i] & mask ];
}
}
}
@@ -3680,7 +3680,7 @@ _mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n,
const GLuint mask = ctx->PixelMaps.StoS.Size - 1;
GLuint i;
for (i = 0; i < n; i++) {
- indexes[i] = ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
+ indexes[i] = (GLuint)ctx->PixelMaps.StoS.Map[ indexes[i] & mask ];
}
}
@@ -4035,7 +4035,7 @@ _mesa_unpack_depth_span( const GLcontext *ctx, GLuint n,
if (needClamp) {
GLuint i;
for (i = 0; i < n; i++) {
- depthValues[i] = CLAMP(depthValues[i], 0.0, 1.0);
+ depthValues[i] = (GLfloat)CLAMP(depthValues[i], 0.0, 1.0);
}
}
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 0af647e13c..f37d1f216f 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -1119,7 +1119,7 @@ compute_light_positions( GLcontext *ctx )
}
else {
/* positional light w/ homogeneous coordinate, divide by W */
- GLfloat wInv = 1.0 / light->_Position[3];
+ GLfloat wInv = (GLfloat)1.0 / light->_Position[3];
light->_Position[0] *= wInv;
light->_Position[1] *= wInv;
light->_Position[2] *= wInv;
@@ -1357,7 +1357,7 @@ _mesa_init_lighting( GLcontext *ctx )
/* Miscellaneous */
ctx->Light._NeedEyeCoords = GL_FALSE;
ctx->_NeedEyeCoords = GL_FALSE;
- ctx->_ForceEyeCoords = GL_TRUE;
+ ctx->_ForceEyeCoords = GL_FALSE;
ctx->_ModelViewInvScale = 1.0;
}
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index d3d1958951..061378f3b7 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -292,7 +292,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
GLfloat *dst = (GLfloat *) dstRow;
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
i++, j += colStride, k += colStride) {
- dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
+ dst[i] = (GLfloat)(rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4);
}
}
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index 0e9915dd38..7eeae05dbd 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -304,7 +304,7 @@ store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize,
/* special case */
ctx->PixelMaps.StoS.Size = mapsize;
for (i = 0; i < mapsize; i++) {
- ctx->PixelMaps.StoS.Map[i] = IROUND(values[i]);
+ ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]);
}
break;
case GL_PIXEL_MAP_I_TO_I:
@@ -1142,7 +1142,7 @@ _mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
GLuint n, GLubyte rgba[][4])
{
const GLubyte *lut = table->TableUB;
- const GLfloat scale = (GLfloat) (table->Size - 1) / 255.0;
+ const GLfloat scale = (GLfloat) (table->Size - 1) / (GLfloat)255.0;
GLuint i;
if (!table->TableUB || table->Size == 0)
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index e30f5480da..a1e32e70ba 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -382,7 +382,7 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
*params = 0x7fffffff;
}
else {
- *params = q->Result;
+ *params = (GLint)q->Result;
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
@@ -422,7 +422,7 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
*params = 0xffffffff;
}
else {
- *params = q->Result;
+ *params = (GLuint)q->Result;
}
break;
case GL_QUERY_RESULT_AVAILABLE_ARB:
diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c
index ee163e0c71..f0500083ec 100644
--- a/src/mesa/main/rastpos.c
+++ b/src/mesa/main/rastpos.c
@@ -63,7 +63,7 @@ rasterpos(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
void GLAPIENTRY
_mesa_RasterPos2d(GLdouble x, GLdouble y)
{
- rasterpos(x, y, 0.0F, 1.0F);
+ rasterpos((GLfloat)x, (GLfloat)y, (GLfloat)0.0, (GLfloat)1.0);
}
void GLAPIENTRY
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 644b1f39c7..6877ef96f2 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -904,14 +904,14 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
*/
if (alpha_shift || rgb_shift) {
if (rgb_shift == alpha_shift) {
- shift = register_scalar_const(p, 1<<rgb_shift);
+ shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift));
}
else {
shift = register_const4f(p,
- 1<<rgb_shift,
- 1<<rgb_shift,
- 1<<rgb_shift,
- 1<<alpha_shift);
+ (GLfloat)(1<<rgb_shift),
+ (GLfloat)(1<<rgb_shift),
+ (GLfloat)(1<<rgb_shift),
+ (GLfloat)(1<<alpha_shift));
}
return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW,
saturate, out, shift, undef );
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index 8ce2ca3964..abb143c4b9 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -92,7 +92,7 @@ get_register_pointer(const struct prog_src_register *source,
source->File == PROGRAM_CONSTANT ||
source->File == PROGRAM_STATE_VAR);
params = machine->CurProgram->Parameters;
- if (reg < 0 || reg >= params->NumParameters)
+ if (reg < 0 || reg >= (GLint)params->NumParameters)
return ZeroVec;
else
return params->ParameterValues[reg];
@@ -227,7 +227,7 @@ fetch_vector4_deriv(GLcontext * ctx,
const struct gl_program_machine *machine,
char xOrY, GLfloat result[4])
{
- if (source->File == PROGRAM_INPUT && source->Index < machine->NumDeriv) {
+ if (source->File == PROGRAM_INPUT && source->Index < (GLint)machine->NumDeriv) {
const GLint col = machine->CurElement;
const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3];
const GLfloat invQ = 1.0f / w;
@@ -506,7 +506,7 @@ _mesa_execute_program(GLcontext * ctx,
{
const GLuint numInst = program->NumInstructions;
const GLuint maxExec = 10000;
- GLint pc, numExec = 0;
+ GLuint pc, numExec = 0;
machine->CurProgram = program;
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
index 44fbfdcd04..8f48155825 100644
--- a/src/mesa/shader/prog_statevars.c
+++ b/src/mesa/shader/prog_statevars.c
@@ -250,7 +250,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
value[1] = ctx->Fog.Start;
value[2] = ctx->Fog.End;
value[3] = (ctx->Fog.End == ctx->Fog.Start)
- ? 1.0 : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ ? 1.0 : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start));
return;
case STATE_CLIPPLANE:
{
@@ -411,7 +411,7 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
if (texObj) {
struct gl_texture_image *texImage = texObj->Image[0][0];
ASSIGN_4V(value, 1.0 / texImage->Width,
- 1.0 / texImage->Height,
+ (GLfloat)(1.0 / texImage->Height),
0.0, 1.0);
}
}
@@ -426,10 +426,10 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
* exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
*/
value[0] = (ctx->Fog.End == ctx->Fog.Start)
- ? 1.0 : -1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ ? 1.0 : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
value[1] = ctx->Fog.End * -value[0];
- value[2] = ctx->Fog.Density * ONE_DIV_LN2;
- value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2;
+ value[2] = (GLfloat)(ctx->Fog.Density * ONE_DIV_LN2);
+ value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
return;
case STATE_LIGHT_SPOT_DIR_NORMALIZED: {
diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c
index 20e004b350..d96a916533 100644
--- a/src/mesa/shader/prog_uniform.c
+++ b/src/mesa/shader/prog_uniform.c
@@ -135,7 +135,7 @@ _mesa_longest_uniform_name(const struct gl_uniform_list *list)
GLuint i;
for (i = 0; i < list->NumUniforms; i++) {
GLuint len = _mesa_strlen(list->Uniforms[i].Name);
- if (len > max)
+ if (len > (GLuint)max)
max = len;
}
return max;
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 24ab7568d6..856179e1d5 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -719,7 +719,7 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
if (shProg) {
- GLint i;
+ GLuint i;
for (i = 0; i < maxCount && i < shProg->NumShaders; i++) {
obj[i] = shProg->Shaders[i]->Name;
}
@@ -893,7 +893,7 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
= _mesa_lookup_shader_program(ctx, program);
if (shProg) {
if (location < shProg->Uniforms->NumUniforms) {
- GLint progPos, i;
+ GLuint progPos, i;
const struct gl_program *prog = NULL;
progPos = shProg->Uniforms->Uniforms[location].VertPos;
@@ -1111,7 +1111,7 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program, GLint location,
}
else {
/* ordinary uniform variable */
- GLint k, i;
+ GLuint k, i;
if (count * elems > program->Parameters->Parameters[location].Size) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)");
diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index e500ac8684..e4de875e8c 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -77,7 +77,7 @@ is_identity(const GLfloat m[16])
GLuint i;
for (i = 0; i < 16; i++) {
const int row = i % 4, col = i / 4;
- const float val = (row == col);
+ const float val = (GLfloat)(row == col);
if (m[i] != val)
return GL_FALSE;
}
diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c
index f5db492403..3fd59e1945 100644
--- a/src/mesa/state_tracker/st_atom_scissor.c
+++ b/src/mesa/state_tracker/st_atom_scissor.c
@@ -52,14 +52,14 @@ update_scissor( struct st_context *st )
scissor.maxy = fb->Height;
if (st->ctx->Scissor.Enabled) {
- if (st->ctx->Scissor.X > scissor.minx)
+ if ((GLuint)st->ctx->Scissor.X > scissor.minx)
scissor.minx = st->ctx->Scissor.X;
- if (st->ctx->Scissor.Y > scissor.miny)
+ if ((GLuint)st->ctx->Scissor.Y > scissor.miny)
scissor.miny = st->ctx->Scissor.Y;
- if (st->ctx->Scissor.X + st->ctx->Scissor.Width < scissor.maxx)
+ if ((GLuint)st->ctx->Scissor.X + st->ctx->Scissor.Width < scissor.maxx)
scissor.maxx = st->ctx->Scissor.X + st->ctx->Scissor.Width;
- if (st->ctx->Scissor.Y + st->ctx->Scissor.Height < scissor.maxy)
+ if ((GLuint)st->ctx->Scissor.Y + st->ctx->Scissor.Height < scissor.maxy)
scissor.maxy = st->ctx->Scissor.Y + st->ctx->Scissor.Height;
/* check for null space */
diff --git a/src/mesa/state_tracker/st_atom_viewport.c b/src/mesa/state_tracker/st_atom_viewport.c
index 4b51521470..b105909e96 100644
--- a/src/mesa/state_tracker/st_atom_viewport.c
+++ b/src/mesa/state_tracker/st_atom_viewport.c
@@ -49,7 +49,7 @@ update_viewport( struct st_context *st )
*/
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
yScale = -1;
- yBias = ctx->DrawBuffer->Height ;
+ yBias = (GLfloat)ctx->DrawBuffer->Height;
}
else {
yScale = 1.0;
@@ -59,12 +59,12 @@ update_viewport( struct st_context *st )
/* _NEW_VIEWPORT
*/
{
- GLfloat x = ctx->Viewport.X;
- GLfloat y = ctx->Viewport.Y;
+ GLfloat x = (GLfloat)ctx->Viewport.X;
+ GLfloat y = (GLfloat)ctx->Viewport.Y;
GLfloat z = ctx->Viewport.Near;
- GLfloat half_width = ctx->Viewport.Width / 2.0;
- GLfloat half_height = ctx->Viewport.Height / 2.0;
- GLfloat half_depth = (ctx->Viewport.Far - ctx->Viewport.Near) / 2.0;
+ GLfloat half_width = (GLfloat)ctx->Viewport.Width / 2.0;
+ GLfloat half_height = (GLfloat)ctx->Viewport.Height / 2.0;
+ GLfloat half_depth = (GLfloat)(ctx->Viewport.Far - ctx->Viewport.Near) / 2.0;
st->state.viewport.scale[0] = half_width;
st->state.viewport.scale[1] = half_height * yScale;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 593938f8cf..9763eebe54 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -360,18 +360,18 @@ setup_bitmap_vertex_data(struct st_context *st,
{
struct pipe_context *pipe = st->pipe;
const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- const GLfloat fb_width = fb->Width;
- const GLfloat fb_height = fb->Height;
- const GLfloat x0 = x;
- const GLfloat x1 = x + width;
- const GLfloat y0 = y;
- const GLfloat y1 = y + height;
- const GLfloat sLeft = 0.0F, sRight = 1.0F;
- const GLfloat tTop = 0.0, tBot = 1.0 - tTop;
- const GLfloat clip_x0 = x0 / fb_width * 2.0 - 1.0;
- const GLfloat clip_y0 = y0 / fb_height * 2.0 - 1.0;
- const GLfloat clip_x1 = x1 / fb_width * 2.0 - 1.0;
- const GLfloat clip_y1 = y1 / fb_height * 2.0 - 1.0;
+ const GLfloat fb_width = (GLfloat)fb->Width;
+ const GLfloat fb_height = (GLfloat)fb->Height;
+ const GLfloat x0 = (GLfloat)x;
+ const GLfloat x1 = (GLfloat)(x + width);
+ const GLfloat y0 = (GLfloat)y;
+ const GLfloat y1 = (GLfloat)(y + height);
+ const GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
+ const GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
+ const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0);
+ const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
+ const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
+ const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
GLuint i;
void *buf;
@@ -444,8 +444,8 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
* it up into chunks.
*/
maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
- assert(width <= maxSize);
- assert(height <= maxSize);
+ assert(width <= (GLsizei)maxSize);
+ assert(height <= (GLsizei)maxSize);
cso_save_rasterizer(cso);
cso_save_samplers(cso);
@@ -488,15 +488,15 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
{
const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
- const float width = fb->Width;
- const float height = fb->Height;
+ const GLfloat width = (GLfloat)fb->Width;
+ const GLfloat height = (GLfloat)fb->Height;
struct pipe_viewport_state vp;
vp.scale[0] = 0.5 * width;
- vp.scale[1] = height * (invert ? -0.5 : 0.5);
+ vp.scale[1] = (GLfloat)(height * (invert ? -0.5 : 0.5));
vp.scale[2] = 1.0;
vp.scale[3] = 1.0;
- vp.translate[0] = 0.5 * width;
- vp.translate[1] = 0.5 * height;
+ vp.translate[0] = (GLfloat)(0.5 * width);
+ vp.translate[1] = (GLfloat)(0.5 * height);
vp.translate[2] = 0.0;
vp.translate[3] = 0.0;
cso_set_viewport(cso, &vp);
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index d2be450bdb..12979de523 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -550,18 +550,16 @@ make_input_decl(
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;
decl.Declaration.UsageMask = usage_mask;
decl.Declaration.Semantic = semantic_info;
- decl.u.DeclarationRange.First = index;
- decl.u.DeclarationRange.Last = index;
+ decl.DeclarationRange.First = index;
+ decl.DeclarationRange.Last = index;
if (semantic_info) {
decl.Semantic.SemanticName = semantic_name;
decl.Semantic.SemanticIndex = semantic_index;
}
if (interpolate_info) {
- decl.Declaration.Interpolate = 1;
- decl.Interpolation.Interpolate = interpolate;
+ decl.Declaration.Interpolate = interpolate;
}
return decl;
@@ -583,11 +581,10 @@ make_output_decl(
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;
decl.Declaration.UsageMask = usage_mask;
decl.Declaration.Semantic = 1;
- decl.u.DeclarationRange.First = index;
- decl.u.DeclarationRange.Last = index;
+ decl.DeclarationRange.First = index;
+ decl.DeclarationRange.Last = index;
decl.Semantic.SemanticName = semantic_name;
decl.Semantic.SemanticIndex = semantic_index;
@@ -603,9 +600,8 @@ make_temp_decl(
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;
- decl.u.DeclarationRange.First = start_index;
- decl.u.DeclarationRange.Last = end_index;
+ decl.DeclarationRange.First = start_index;
+ decl.DeclarationRange.Last = end_index;
return decl;
}
@@ -616,9 +612,8 @@ make_sampler_decl(GLuint index)
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;
- decl.u.DeclarationRange.First = index;
- decl.u.DeclarationRange.Last = index;
+ decl.DeclarationRange.First = index;
+ decl.DeclarationRange.Last = index;
return decl;
}
@@ -629,9 +624,8 @@ make_constant_decl(GLuint first, GLuint last)
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_CONSTANT;
- decl.Declaration.Declare = TGSI_DECLARE_RANGE;
- decl.u.DeclarationRange.First = first;
- decl.u.DeclarationRange.Last = last;
+ decl.DeclarationRange.First = first;
+ decl.DeclarationRange.Last = last;
return decl;
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index a52521db64..dbee2188ee 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -41,7 +41,7 @@ static void get_minmax_index( GLuint count, GLuint type,
GLuint *min_index,
GLuint *max_index)
{
- GLint i;
+ GLuint i;
switch(type) {
case GL_UNSIGNED_INT: {
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index aded738143..f62be5c14c 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -864,6 +864,9 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
_ae_map_vbos( ctx );
+ if (ctx->Array.ElementArrayBufferObj->Name)
+ indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
+
vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
switch (type) {
diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c
index 958afccd0c..fbc856e93b 100644
--- a/src/mesa/vbo/vbo_split_inplace.c
+++ b/src/mesa/vbo/vbo_split_inplace.c
@@ -58,7 +58,7 @@ struct split_context {
static void flush_vertex( struct split_context *split )
{
- GLint min_index, max_index;
+ GLuint min_index, max_index;
if (!split->dstprim_nr)
return;