Merge branch 'gallium-tex-surfaces' into gallium-0.1
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 3 Jun 2008 14:32:45 +0000 (15:32 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 3 Jun 2008 14:32:45 +0000 (15:32 +0100)
202 files changed:
Makefile
SConstruct
common.py
configs/linux-dri
configs/linux-egl [new file with mode: 0644]
include/EGL/eglplatform.h [new file with mode: 0644]
include/GLES/egl.h
include/GLES/eglext.h [new file with mode: 0644]
include/GLES/egltypes.h [deleted file]
progs/egl/Makefile
progs/egl/demo1.c
progs/egl/demo2.c
progs/egl/demo3.c
progs/egl/eglgears.c
progs/egl/eglinfo.c
progs/egl/xeglgears.c [new file with mode: 0644]
scons/evc.py [new file with mode: 0644]
scons/mslib_sa.py [new file with mode: 0644]
scons/mslink_sa.py [new file with mode: 0644]
scons/msvc_sa.py [moved from winddk.py with 70% similarity]
scons/winddk.py [new file with mode: 0644]
src/egl/drivers/demo/demo.c
src/egl/drivers/dri/Makefile
src/egl/drivers/dri/egldri.c
src/egl/drivers/dri/egldri.h
src/egl/main/Makefile
src/egl/main/eglapi.c
src/egl/main/eglapi.h
src/egl/main/eglconfig.c
src/egl/main/eglconfig.h
src/egl/main/eglconfigutil.c [new file with mode: 0644]
src/egl/main/eglconfigutil.h [new file with mode: 0644]
src/egl/main/eglcontext.c
src/egl/main/eglcontext.h
src/egl/main/egldefines.h [moved from src/gallium/winsys/dri/intel/intel_batchpool.h with 75% similarity]
src/egl/main/egldisplay.c
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/egl/main/eglglobals.c
src/egl/main/eglglobals.h
src/egl/main/eglmisc.c [new file with mode: 0644]
src/egl/main/eglmisc.h [new file with mode: 0644]
src/egl/main/eglmode.h
src/egl/main/eglstring.c [new file with mode: 0644]
src/egl/main/eglstring.h [new file with mode: 0644]
src/egl/main/eglsurface.c
src/egl/main/eglsurface.h
src/egl/main/egltypedefs.h
src/egl/main/eglx.c [new file with mode: 0644]
src/egl/main/eglx.h [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe.c
src/gallium/auxiliary/draw/draw_pipe_aaline.c
src/gallium/auxiliary/draw/draw_pipe_aapoint.c
src/gallium/auxiliary/draw/draw_pipe_pstipple.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/draw/draw_pt_decompose.h
src/gallium/auxiliary/draw/draw_pt_elts.c
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_vcache.c
src/gallium/auxiliary/draw/draw_vs.c
src/gallium/auxiliary/draw/draw_vs_aos.c
src/gallium/auxiliary/draw/draw_vs_aos_io.c
src/gallium/auxiliary/draw/draw_vs_sse.c
src/gallium/auxiliary/gallivm/tgsitollvm.cpp
src/gallium/auxiliary/rtasm/rtasm_cpu.c
src/gallium/auxiliary/rtasm/rtasm_x86sse.c
src/gallium/auxiliary/rtasm/rtasm_x86sse.h
src/gallium/auxiliary/tgsi/exec/tgsi_exec.c
src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c
src/gallium/auxiliary/tgsi/util/tgsi_build.c
src/gallium/auxiliary/tgsi/util/tgsi_build.h
src/gallium/auxiliary/tgsi/util/tgsi_dump.c
src/gallium/auxiliary/tgsi/util/tgsi_parse.c
src/gallium/auxiliary/tgsi/util/tgsi_parse.h
src/gallium/auxiliary/tgsi/util/tgsi_scan.c
src/gallium/auxiliary/tgsi/util/tgsi_util.c
src/gallium/auxiliary/translate/translate.c
src/gallium/auxiliary/translate/translate_generic.c
src/gallium/auxiliary/translate/translate_sse.c
src/gallium/auxiliary/util/p_debug.c
src/gallium/auxiliary/util/u_simple_shaders.c
src/gallium/auxiliary/util/u_time.c
src/gallium/auxiliary/util/u_time.h
src/gallium/drivers/cell/spu/spu_exec.c
src/gallium/drivers/i915simple/i915_batch.h
src/gallium/drivers/i915simple/i915_blit.c
src/gallium/drivers/i915simple/i915_context.c
src/gallium/drivers/i915simple/i915_context.h
src/gallium/drivers/i915simple/i915_debug.c
src/gallium/drivers/i915simple/i915_flush.c
src/gallium/drivers/i915simple/i915_fpc_translate.c
src/gallium/drivers/i915simple/i915_prim_vbuf.c
src/gallium/drivers/i915simple/i915_state.c
src/gallium/drivers/i915simple/i915_state_emit.c
src/gallium/drivers/i915simple/i915_state_immediate.c
src/gallium/drivers/i915simple/i915_texture.c
src/gallium/drivers/i915simple/i915_winsys.h
src/gallium/drivers/i965simple/brw_sf.c
src/gallium/drivers/i965simple/brw_shader_info.c
src/gallium/drivers/i965simple/brw_vs_emit.c
src/gallium/drivers/i965simple/brw_wm_decl.c
src/gallium/drivers/softpipe/sp_fs_sse.c
src/gallium/drivers/softpipe/sp_quad_depth_test.c
src/gallium/drivers/softpipe/sp_tile_cache.c
src/gallium/include/pipe/p_compiler.h
src/gallium/include/pipe/p_config.h
src/gallium/include/pipe/p_debug.h
src/gallium/include/pipe/p_shader_tokens.h
src/gallium/include/pipe/p_util.h
src/gallium/winsys/SConscript
src/gallium/winsys/dri/SConscript
src/gallium/winsys/dri/intel/Makefile
src/gallium/winsys/dri/intel/SConscript
src/gallium/winsys/dri/intel/intel_batchbuffer.c
src/gallium/winsys/dri/intel/intel_batchbuffer.h
src/gallium/winsys/dri/intel/intel_batchpool.c [deleted file]
src/gallium/winsys/dri/intel/intel_context.c
src/gallium/winsys/dri/intel/intel_context.h
src/gallium/winsys/dri/intel/intel_screen.c
src/gallium/winsys/dri/intel/intel_screen.h
src/gallium/winsys/dri/intel/intel_swapbuffers.c
src/gallium/winsys/dri/intel/intel_winsys.h
src/gallium/winsys/dri/intel/intel_winsys_i915.c
src/gallium/winsys/dri/intel/intel_winsys_pipe.c
src/gallium/winsys/dri/intel/server/i830_common.h
src/gallium/winsys/dri/intel/ws_dri_bufmgr.c [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_bufmgr.h [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_bufpool.h [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_drmpool.c [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_fencemgr.c [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_fencemgr.h [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_mallocpool.c [new file with mode: 0644]
src/gallium/winsys/dri/intel/ws_dri_slabpool.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/Makefile [new file with mode: 0644]
src/gallium/winsys/egl_drm/Makefile.template [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/Makefile [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/SConscript [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_batchbuffer.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_batchbuffer.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_context.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_context.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_egl.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_egl.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_lock.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_reg.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_screen.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_screen.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_swapbuffers.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_winsys.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_winsys_i915.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_winsys_pipe.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/intel_winsys_softpipe.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_bufmgr.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_bufpool.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_drmpool.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_fencemgr.h [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_mallocpool.c [new file with mode: 0644]
src/gallium/winsys/egl_drm/intel/ws_dri_slabpool.c [new file with mode: 0644]
src/gallium/winsys/egl_xlib/Makefile [new file with mode: 0644]
src/gallium/winsys/egl_xlib/egl_xlib.c [new file with mode: 0644]
src/gallium/winsys/egl_xlib/sw_winsys.c [new file with mode: 0644]
src/gallium/winsys/egl_xlib/sw_winsys.h [new file with mode: 0644]
src/gallium/winsys/gdi/SConscript [new file with mode: 0644]
src/gallium/winsys/gdi/colors.h [new file with mode: 0644]
src/gallium/winsys/gdi/opengl32.def [new file with mode: 0644]
src/gallium/winsys/gdi/wgl.c [new file with mode: 0644]
src/gallium/winsys/gdi/wmesa.c [new file with mode: 0644]
src/gallium/winsys/gdi/wmesadef.h [new file with mode: 0644]
src/gallium/winsys/xlib/SConscript
src/mesa/SConscript
src/mesa/glapi/glthread.h
src/mesa/main/api_arrayelt.c
src/mesa/main/api_validate.c
src/mesa/main/context.c
src/mesa/main/dlist.c
src/mesa/main/drawpix.c
src/mesa/main/framebuffer.c
src/mesa/main/get.c
src/mesa/main/image.c
src/mesa/main/light.c
src/mesa/main/mipmap.c
src/mesa/main/pixel.c
src/mesa/main/queryobj.c
src/mesa/main/rastpos.c
src/mesa/main/texenvprogram.c
src/mesa/shader/prog_execute.c
src/mesa/shader/prog_statevars.c
src/mesa/shader/prog_uniform.c
src/mesa/shader/shader_api.c
src/mesa/state_tracker/st_atom_pixeltransfer.c
src/mesa/state_tracker/st_atom_scissor.c
src/mesa/state_tracker/st_atom_viewport.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_mesa_to_tgsi.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_split_inplace.c

index 1ec8ce7..9b3be43 100644 (file)
--- 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 \
index e7c10fc..549ff64 100644 (file)
@@ -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)
 
 
index d3c0261..b6251d3 100644 (file)
--- 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)
index 67e60cb..cd82c57 100644 (file)
@@ -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 (file)
index 0000000..e906806
--- /dev/null
@@ -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 (file)
index 0000000..3d71910
--- /dev/null
@@ -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 */
index a211bbc..e33a315 100644 (file)
+/* -*- 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 (file)
index 0000000..a4698cc
--- /dev/null
@@ -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 (file)
index ca1f5a9..0000000
+++ /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_
index 33447a9..ae2267f 100644 (file)
@@ -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
index 9ef17e3..5267318 100644 (file)
@@ -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)) {
index 17bbca6..c95aaaf 100644 (file)
@@ -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, 
index 9edf7c9..6ea7578 100644 (file)
@@ -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)) {
index 9feee20..a004cb7 100644 (file)
  * 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)) {
index f9c2475..442de5d 100644 (file)
@@ -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 (file)
index 0000000..519d4bb
--- /dev/null
@@ -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 (file)
index 0000000..22a9260
--- /dev/null
@@ -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 (file)
index 0000000..da51c57
--- /dev/null
@@ -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 (file)
index 0000000..53331de
--- /dev/null
@@ -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:
similarity index 70%
rename from winddk.py
rename to scons/msvc_sa.py
index 58de183..136d305 100644 (file)
--- a/winddk.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 (file)
index 0000000..be81d12
--- /dev/null
@@ -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:
index 4554575..6b8b71d 100644 (file)
@@ -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;
 
index fa3720a..bdc683a 100644 (file)
@@ -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
index cab0be2..1a922a7 100644 (file)
@@ -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"
 #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;
index 34b12d6..54a9a4e 100644 (file)
@@ -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;
 
index e6844d4..96742bb 100644 (file)
@@ -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
index bfa580e..49d1f3d 100644 (file)
 
 
 /**
- * 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)
 {
index 555aa5d..f6163a0 100644 (file)
@@ -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;
index c180e30..c6369e7 100644 (file)
 #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;
-}
index 1fb976e..b10a619 100644 (file)
@@ -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 (file)
index 0000000..b658561
--- /dev/null
@@ -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 (file)
index 0000000..5db906d
--- /dev/null
@@ -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 */
index 374c006..bf1addf 100644 (file)
@@ -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));
       }
    }
 
index 82bfde1..34fee9c 100644 (file)
@@ -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);
  
similarity index 75%
rename from src/gallium/winsys/dri/intel/intel_batchpool.h
rename to src/egl/main/egldefines.h
index f6a9572..8fc2301 100644 (file)
@@ -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
  * 
  **************************************************************************/
 
-#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 */
index 074a85b..8fd29b8 100644 (file)
@@ -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 */
 }
index 1a03fdd..e2ebab0 100644 (file)
@@ -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);
 
index bda06dd..80fa49b 100644 (file)
+/**
+ * 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;
-}
index 88526e9..af028ea 100644 (file)
@@ -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 */
index 608311d..9a077ed 100644 (file)
@@ -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);
 }
 
index c16baa2..14d8ea4 100644 (file)
@@ -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 (file)
index 0000000..b5bdc3e
--- /dev/null
@@ -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 (file)
index 0000000..4e2a40e
--- /dev/null
@@ -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 */
index e70da85..52d4875 100644 (file)
@@ -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 (file)
index 0000000..ba74061
--- /dev/null
@@ -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 (file)
index 0000000..1046863
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef EGLSTRING_INCLUDED
+#define EGLSTRING_INCLUDED
+
+
+extern char *
+_eglstrdup(const char *s);
+
+
+#endif /* EGLSTRING_INCLUDED */
index 874f318..796d62f 100644 (file)
@@ -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;
       }
index 79abeca..df1e701 100644 (file)
@@ -51,6 +51,10 @@ extern void
 _eglRemoveSurface(_EGLSurface *surf);
 
 
+extern EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surface);
+
+
 extern _EGLSurface *
 _eglLookupSurface(EGLSurface surf);
  
index fa8cb49..efbb17a 100644 (file)
@@ -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 (file)
index 0000000..085da33
--- /dev/null
@@ -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 (file)
index 0000000..4323d55
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef EGLX_INCLUDED
+#define EGLX_INCLUDED
+
+
+#include "egldisplay.h"
+
+
+extern const char *
+_xeglChooseDriver(_EGLDisplay *dpy);
+
+
+#endif /* EGLX_INCLUDED */
index 1d26706..3355c87 100644 (file)
@@ -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
 
index fd48b22..634bf06 100644 (file)
@@ -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;
index 97d74ad..96dcdb4 100644 (file)
@@ -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;
index 4c92416..4087cf7 100644 (file)
@@ -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}
index 4f8ccee..423f642 100644 (file)
@@ -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;
 
 
index 7230771..f0d7b51 100644 (file)
 #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;
    }
index dccfde9..3fb0695 100644 (file)
@@ -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;
 
index 2094c08..b7780fb 100644 (file)
@@ -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;
    }
 }     
index 260f28f..f19e885 100644 (file)
@@ -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;
 }
 
 
index 9ffc99a..ad86ab4 100644 (file)
@@ -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;
    }
index ce35112..979f986 100644 (file)
@@ -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);
 
index 3cf4a4d..45f36cf 100644 (file)
@@ -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);
index 45e2092..b720185 100644 (file)
@@ -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);
 }
index 24f619a..0aa0c9a 100644 (file)
   *   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 );
    
index 9695358..98014bd 100644 (file)
@@ -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);
    }
 }
index f01e12f..5499018 100644 (file)
@@ -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;
index 672d2ff..f4ca282 100644 (file)
@@ -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);
index 63e812f..af94577 100644 (file)
@@ -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 );
index 826b432..6689c3f 100644 (file)
@@ -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 );
index 189dc60..cdbdf5c 100755 (executable)
@@ -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 );
 
index 9c883ab..18e44b3 100644 (file)
@@ -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 =
index 80bffc4..423cf14 100644 (file)
@@ -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 );
 
index b018ea9..d1a3dfd 100644 (file)
@@ -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();
index 5c0b0bf..d16f0cd 100644 (file)
@@ -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 );
index 4102101..0543507 100644 (file)
@@ -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
index 65650ed..bda7bc2 100644 (file)
@@ -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 */
index 4cdd891..56a50d3 100644 (file)
@@ -8,7 +8,7 @@
 union pointer_hack
 {
    void *pointer;
-   unsigned long long uint64;
+   uint64_t uint64;
 };
 
 void *
index b04bc6e..b93fbf9 100644 (file)
@@ -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;
index a25d94f..3fec89b 100644 (file)
@@ -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;
    }
 }
 
index be48a14..18a212a 100644 (file)
@@ -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;
 }
index ce7fb58..d1dfc37 100644 (file)
@@ -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;
index 5f8d121..505d93d 100644 (file)
@@ -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,
index 9b97050..49dce75 100644 (file)
  */
 
 
-#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;
index 48ec7a4..f9963ce 100644 (file)
@@ -61,7 +61,7 @@ struct util_time
 #if defined(PIPE_OS_LINUX)
    struct timeval tv;
 #else
-   long long counter;
+   int64_t counter;
 #endif
 };
    
index 48edc62..3a80df4 100644 (file)
@@ -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 );
index 4ea06ce..45bf4f4 100644 (file)
 #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
index 24449e3..22f91fa 100644 (file)
@@ -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();
 }
 
 
index c609d16..243b4a6 100644 (file)
@@ -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;
 }
index 53fc5ed..2ee0381 100644 (file)
@@ -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;
index 9b91111..5e26d1b 100644 (file)
@@ -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;
 
index 7d23e6b..472e0ab 100644 (file)
@@ -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;
 }
 
 
index 3ccf74c..23cd909 100644 (file)
@@ -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] */
index 7fb2adb..adfb16f 100644 (file)
@@ -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;
 }
index e09c225..39d5d5e 100644 (file)
@@ -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;
index 6f947d4..de0c1a7 100644 (file)
@@ -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);
index dfbbcab..704ea4d 100644 (file)
@@ -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! 
     */
index 3e23e54..16354dc 100644 (file)
@@ -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;
 }
index 5e16543..9afaa16 100644 (file)
@@ -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 );
 };
index c3b815a..96f8fb8 100644 (file)
@@ -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 = 
index f4694a4..fb3da92 100644 (file)
@@ -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);
index 9020fcc..81423e2 100644 (file)
@@ -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:
        */
index 74ccfd4..bf1b4d9 100644 (file)
@@ -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;
index 55741cc..69f7f96 100644 (file)
@@ -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],
index a1859f9..33888ab 100644 (file)
@@ -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;
index 28c29da..0e4c8c4 100644 (file)
@@ -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);
index 01d1807..b14260d 100644 (file)
 #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 */
index 5c030bd..af3746c 100644 (file)
  * 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>
  */
 #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
  * 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__)
 
 
 /*
- * 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 */
 
index 0af635b..05eca75 100644 (file)
@@ -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
index f05e1a3..84e5096 100644 (file)
@@ -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
index 3d8ad48..5547e57 100644 (file)
@@ -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
index e8a581a..bf1718e 100644 (file)
@@ -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',
+       ])
index 8c56ce9..aef5210 100644 (file)
@@ -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',
+               ])
index 40654bb..c0ce2f9 100644 (file)
@@ -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 = 
index 0ad19d4..6a4f50a 100644 (file)
@@ -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'],
+       )
index 5830b88..aa33c12 100644 (file)
  * 
  **************************************************************************/
 
-#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;
 }
index caf6870..abb7a62 100644 (file)
@@ -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 (file)
index ce154c7..0000000
+++ /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;
-}
index 8eba33c..6a0c381 100644 (file)
@@ -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;
       }
 
index 4543098..597dc13 100644 (file)
@@ -28,7 +28,7 @@
 #ifndef INTEL_CONTEXT_H
 #define INTEL_CONTEXT_H
 
-
+#include <stdint.h>
 #include "drm.h"
 
 #include "pipe/p_debug.h"
index 9e31c01..0be8897 100644 (file)
 #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;
 }
index 3396f9e..1db0502 100644 (file)
@@ -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;
 };
 
index 56b86d6..923b542 100644 (file)
@@ -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);
index ffc4078..3d32db1 100644 (file)
@@ -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
index 4d183db..0132913 100644 (file)
@@ -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;
index d15143a..51a79ca 100644 (file)
@@ -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"
 #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);
 }
-
index 50bb751..f84f453 100644 (file)
@@ -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 (file)
index 0000000..1bc1089
--- /dev/null
@@ -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 (file)
index 0000000..fdaf5ee
--- /dev/null
@@ -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 (file)
index 0000000..3a302e1
--- /dev/null
@@ -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 (file)
index 0000000..7c55dbc
--- /dev/null
@@ -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 (file)
index 0000000..1f893b4
--- /dev/null
@@ -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 (file)
index 0000000..4ea58df
--- /dev/null
@@ -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 (file)
index 0000000..bf97d7e
--- /dev/null
@@ -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 (file)
index 0000000..62d82bb
--- /dev/null
@@ -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 (file)
index 0000000..4139d9e
--- /dev/null
@@ -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 (file)
index 0000000..3bc1fdd
--- /dev/null
@@ -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 (file)
index 0000000..5778ba7
--- /dev/null
@@ -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 (file)
index 0000000..0ad19d4
--- /dev/null
@@ -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 (file)
index 0000000..7ffa05a
--- /dev/null
@@ -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 (file)
index 0000000..6d35cf8
--- /dev/null
@@ -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 (file)
index 0000000..394a40d
--- /dev/null
@@ -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 (file)
index 0000000..aa9903f
--- /dev/null
@@ -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 (file)
index 0000000..41b7eac
--- /dev/null
@@ -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 (file)
index 0000000..18e84e8
--- /dev/null
@@ -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 (file)
index 0000000..cec83c7
--- /dev/null
@@ -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 (file)
index 0000000..f37c24f
--- /dev/null
@@ -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 (file)
index 0000000..38c4098
--- /dev/null
@@ -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 (file)
index 0000000..e8c1cdf
--- /dev/null
@@ -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 (file)
index 0000000..1ce4b27
--- /dev/null
@@ -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 (file)
index 0000000..904f267
--- /dev/null
@@ -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 (file)
index 0000000..d0a319f
--- /dev/null
@@ -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 (file)
index 0000000..8ec5c7e
--- /dev/null
@@ -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 (file)
index 0000000..8bf8c21
--- /dev/null
@@ -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 (file)
index 0000000..0bc2dc4
--- /dev/null
@@ -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 (file)
index 0000000..1bc1089
--- /dev/null
@@ -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 (file)
index 0000000..fdaf5ee
--- /dev/null
@@ -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 (file)
index 0000000..3a302e1
--- /dev/null
@@ -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 (file)
index 0000000..7c55dbc
--- /dev/null
@@ -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 (file)
index 0000000..1f893b4
--- /dev/null
@@ -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 (file)
index 0000000..4ea58df
--- /dev/null
@@ -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 (file)
index 0000000..bf97d7e
--- /dev/null
@@ -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 (file)
index 0000000..e69519a
--- /dev/null
@@ -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 (file)
index 0000000..fe4b931
--- /dev/null
@@ -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 (file)
index 0000000..9938997
--- /dev/null
@@ -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 (file)
index 0000000..fd0cb9f
--- /dev/null
@@ -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 (file)
index 0000000..f96c5a1
--- /dev/null
@@ -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 (file)
index 0000000..170fdf5
--- /dev/null
@@ -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 (file)
index 0000000..03e512c
--- /dev/null
@@ -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 (file)
index 0000000..54e72f5
--- /dev/null
@@ -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 (file)
index 0000000..5012601
--- /dev/null
@@ -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 (file)
index 0000000..74a8292
--- /dev/null
@@ -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 (file)
index 0000000..fb8ce30
--- /dev/null
@@ -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 */
index 218b892..5e98a36 100644 (file)
@@ -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'],
+       )
index 6b99dac..04b771a 100644 (file)
 
 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')
index afb04f7..b8e9d5f 100644 (file)
@@ -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
 
index 72091b0..d124c72 100644 (file)
@@ -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 */
index 64ab324..9144b4b 100644 (file)
@@ -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;
       }
index 2158eb6..0053180 100755 (executable)
@@ -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);
index 13ebd4d..f933580 100644 (file)
@@ -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
index fa422bb..016ddd0 100644 (file)
@@ -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);
 
index c9b30d3..894d99a 100644 (file)
@@ -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;
 }
 
 
index eb81ee4..ee48b78 100644 (file)
@@ -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:
index 76e105e..285c834 100644 (file)
@@ -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);
       }
    }
 
index 0af647e..f37d1f2 100644 (file)
@@ -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;
 }
 
index d3d1958..061378f 100644 (file)
@@ -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);
       }
    }
 
index 0e9915d..7eeae05 100644 (file)
@@ -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)
index e30f548..a1e32e7 100644 (file)
@@ -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:
index ee163e0..f050008 100644 (file)
@@ -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
index 644b1f3..6877ef9 100644 (file)
@@ -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 );
index 8ce2ca3..abb143c 100644 (file)
@@ -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;
 
index 44fbfdc..8f48155 100644 (file)
@@ -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: {
index 20e004b..d96a916 100644 (file)
@@ -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;
index 24ab756..856179e 100644 (file)
@@ -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)");
index e500ac8..e4de875 100644 (file)
@@ -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;
    }
index f5db492..3fd59e1 100644 (file)
@@ -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 */
index 4b51521..b105909 100644 (file)
@@ -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;
index 593938f..9763eeb 100644 (file)
@@ -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);
index d2be450..12979de 100644 (file)
@@ -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;
 }
 
index a52521d..dbee218 100644 (file)
@@ -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: {
index aded738..f62be5c 100644 (file)
@@ -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) {
index 958afcc..fbc856e 100644 (file)
@@ -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;