summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/drm/intel/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/drm/intel/egl')
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile28
-rw-r--r--src/gallium/winsys/drm/intel/egl/SConscript39
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h24
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_context.c242
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_context.h118
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_device.c137
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_device.h50
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_egl.c796
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_egl.h53
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_reg.h53
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c111
11 files changed, 1651 insertions, 0 deletions
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
new file mode 100644
index 0000000000..f0b5a44389
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -0,0 +1,28 @@
+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 \
+ ../common/libinteldrm.a
+
+DRIVER_SOURCES = \
+ intel_swapbuffers.c \
+ intel_context.c \
+ intel_device.c \
+ intel_egl.c
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+ASM_SOURCES =
+
+DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \
+ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+
+include ../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/drm/intel/egl/SConscript b/src/gallium/winsys/drm/intel/egl/SConscript
new file mode 100644
index 0000000000..0ad19d42a8
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/SConscript
@@ -0,0 +1,39 @@
+Import('*')
+
+env = drienv.Clone()
+
+env.Append(CPPPATH = [
+ '../intel',
+ 'server'
+])
+
+#MINIGLX_SOURCES = server/intel_dri.c
+
+DRIVER_SOURCES = [
+ 'intel_winsys_pipe.c',
+ 'intel_winsys_softpipe.c',
+ 'intel_winsys_i915.c',
+ 'intel_batchbuffer.c',
+ 'intel_swapbuffers.c',
+ 'intel_context.c',
+ 'intel_lock.c',
+ 'intel_screen.c',
+ 'intel_batchpool.c',
+]
+
+sources = \
+ COMMON_GALLIUM_SOURCES + \
+ COMMON_BM_SOURCES + \
+ DRIVER_SOURCES
+
+drivers = [
+ softpipe,
+ i915simple
+]
+
+# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
+env.SharedLibrary(
+ target ='i915tex_dri.so',
+ source = sources,
+ LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+) \ No newline at end of file
diff --git a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h
new file mode 100644
index 0000000000..3e95326168
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h
@@ -0,0 +1,24 @@
+#ifndef INTEL_BATCHBUFFER_H
+#define INTEL_BATCHBUFFER_H
+
+#include "intel_be_batchbuffer.h"
+
+/*
+ * Need to redefine the BATCH defines
+ */
+
+#undef BEGIN_BATCH
+#define BEGIN_BATCH(dwords, relocs) \
+ (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs))
+
+#undef OUT_BATCH
+#define OUT_BATCH(d) \
+ i915_batchbuffer_dword(&intel->base.batch->base, d)
+
+#undef OUT_RELOC
+#define OUT_RELOC(buf,flags,mask,delta) do { \
+ assert((delta) >= 0); \
+ intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \
+} while (0)
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.c b/src/gallium/winsys/drm/intel/egl/intel_context.c
new file mode 100644
index 0000000000..927addb834
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_context.c
@@ -0,0 +1,242 @@
+/**************************************************************************
+ *
+ * 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 "i915simple/i915_screen.h"
+
+#include "intel_device.h"
+#include "intel_context.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}
+};
+
+
+/*
+ * Hardware lock functions.
+ * Doesn't do anything in EGL
+ */
+
+static void
+intel_lock_hardware(struct intel_be_context *context)
+{
+ (void)context;
+}
+
+static void
+intel_unlock_hardware(struct intel_be_context *context)
+{
+ (void)context;
+}
+
+static boolean
+intel_locked_hardware(struct intel_be_context *context)
+{
+ (void)context;
+ return FALSE;
+}
+
+
+/*
+ * Misc functions.
+ */
+
+int
+intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate)
+{
+ struct intel_context *intel = CALLOC_STRUCT(intel_context);
+ struct intel_device *device = (struct intel_device *)egl_context->device->priv;
+ struct pipe_context *pipe;
+ struct st_context *st_share = NULL;
+
+ egl_context->priv = intel;
+
+ intel->intel_device = device;
+ intel->egl_context = egl_context;
+ intel->egl_device = egl_context->device;
+
+ intel->base.hardware_lock = intel_lock_hardware;
+ intel->base.hardware_unlock = intel_unlock_hardware;
+ intel->base.hardware_locked = intel_locked_hardware;
+
+ intel_be_init_context(&intel->base, &device->base);
+
+#if 0
+ pipe = intel_create_softpipe(intel, screen->winsys);
+#else
+ pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base);
+#endif
+
+ pipe->priv = intel;
+
+ intel->st = st_create_context(pipe, visual, st_share);
+
+ device->dummy = intel;
+
+ return TRUE;
+}
+
+int
+intel_destroy_context(struct egl_drm_context *egl_context)
+{
+ struct intel_context *intel = egl_context->priv;
+
+ if (intel->intel_device->dummy == intel)
+ intel->intel_device->dummy = NULL;
+
+ st_destroy_context(intel->st);
+ intel_be_destroy_context(&intel->base);
+ free(intel);
+ 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);
+
+ } else {
+ st_make_current(NULL, NULL, NULL);
+ }
+}
+
+void
+intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
+{
+ struct intel_device *device = (struct intel_device *)draw->device->priv;
+ struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
+
+ if (draw_fb->front_buffer)
+ 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(device->base.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);
+}
diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.h b/src/gallium/winsys/drm/intel/egl/intel_context.h
new file mode 100644
index 0000000000..477fdec7f7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_context.h
@@ -0,0 +1,118 @@
+/**************************************************************************
+ *
+ * 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 "pipe/p_debug.h"
+#include "intel_be_context.h"
+
+
+struct st_context;
+struct egl_drm_device;
+struct egl_drm_context;
+struct egl_drm_frontbuffer;
+
+
+/**
+ * Intel rendering context, contains a state tracker and intel-specific info.
+ */
+struct intel_context
+{
+ struct intel_be_context base;
+
+ struct st_context *st;
+
+ struct intel_device *intel_device;
+
+ /* 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;
+
+ struct intel_device *device;
+ 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
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c
new file mode 100644
index 0000000000..b9649cbec7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_device.c
@@ -0,0 +1,137 @@
+/**************************************************************************
+ *
+ * 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 "state_tracker/st_public.h"
+#include "i915simple/i915_screen.h"
+
+#include "intel_context.h"
+#include "intel_device.h"
+#include "intel_batchbuffer.h"
+#include "intel_egl.h"
+
+
+extern const struct dri_extension card_extensions[];
+
+
+int
+intel_create_device(struct egl_drm_device *device)
+{
+ struct intel_device *intel_device;
+
+ /* Allocate the private area */
+ intel_device = CALLOC_STRUCT(intel_device);
+ if (!intel_device)
+ return FALSE;
+
+ device->priv = (void *)intel_device;
+ intel_device->device = device;
+
+ intel_device->deviceID = device->deviceID;
+
+ intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID);
+
+ intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID);
+
+ /* hack */
+ driInitExtensions(NULL, card_extensions, GL_FALSE);
+
+ return TRUE;
+}
+
+int
+intel_destroy_device(struct egl_drm_device *device)
+{
+ struct intel_device *intel_device = (struct intel_device *)device->priv;
+
+ intel_be_destroy_device(&intel_device->base);
+
+ free(intel_device);
+ device->priv = NULL;
+
+ 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;
+
+ intelfb->device = drawable->device->priv;
+
+ 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;
+}
+
+int
+intel_destroy_drawable(struct egl_drm_drawable *drawable)
+{
+ struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv;
+ drawable->priv = NULL;
+
+ assert(intelfb->stfb);
+ st_unreference_framebuffer(&intelfb->stfb);
+ free(intelfb);
+ return TRUE;
+}
diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.h b/src/gallium/winsys/drm/intel/egl/intel_device.h
new file mode 100644
index 0000000000..323a7c2aef
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_device.h
@@ -0,0 +1,50 @@
+/**************************************************************************
+ *
+ * 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 "intel_be_device.h"
+
+#include "pipe/p_compiler.h"
+
+struct pipe_screen;
+struct egl_drm_device;
+struct intel_context;
+
+struct intel_device
+{
+ struct intel_be_device base;
+ struct pipe_screen *pipe;
+
+ int deviceID;
+ struct egl_drm_device *device;
+
+ struct intel_context *dummy;
+};
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c
new file mode 100644
index 0000000000..3204ed3131
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_egl.c
@@ -0,0 +1,796 @@
+
+#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 "egllog.h"
+
+#include "intel_egl.h"
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+
+#include "intel_context.h"
+
+#include "state_tracker/st_public.h"
+
+#define MAX_SCREENS 16
+
+static void
+drm_get_device_id(struct egl_drm_device *device)
+{
+ char path[512];
+ FILE *file;
+
+ /* TODO get the real minor */
+ int minor = 0;
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
+ file = fopen(path, "r");
+ if (!file) {
+ _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
+ return;
+ }
+
+ fgets(path, sizeof( path ), file);
+ sscanf(path, "%x", &device->deviceID);
+ fclose(file);
+}
+
+static 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;
+
+ device->version = drmGetVersion(device->drmFD);
+
+ drm_get_device_id(device);
+
+ if (!intel_create_device(device)) {
+ free(device);
+ return NULL;
+ }
+
+ return device;
+}
+
+static void
+_egl_context_modes_destroy(__GLcontextModes *modes)
+{
+ _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
+
+ while (modes) {
+ __GLcontextModes * const next = modes->next;
+ free(modes);
+ modes = next;
+ }
+}
+/**
+ * Create a linked list of 'count' GLcontextModes.
+ * These are used during the client/server visual negotiation phase,
+ * then discarded.
+ */
+static __GLcontextModes *
+_egl_context_modes_create(unsigned count, size_t minimum_size)
+{
+ /* This code copied from libGLX, and modified */
+ const size_t size = (minimum_size > sizeof(__GLcontextModes))
+ ? minimum_size : sizeof(__GLcontextModes);
+ __GLcontextModes * head = NULL;
+ __GLcontextModes ** next;
+ unsigned i;
+
+ _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
+
+ next = & head;
+ for (i = 0 ; i < count ; i++) {
+ *next = (__GLcontextModes *) calloc(1, size);
+ if (*next == NULL) {
+ _egl_context_modes_destroy(head);
+ head = NULL;
+ break;
+ }
+
+ (*next)->doubleBufferMode = 1;
+ (*next)->visualID = GLX_DONT_CARE;
+ (*next)->visualType = GLX_DONT_CARE;
+ (*next)->visualRating = GLX_NONE;
+ (*next)->transparentPixel = GLX_NONE;
+ (*next)->transparentRed = GLX_DONT_CARE;
+ (*next)->transparentGreen = GLX_DONT_CARE;
+ (*next)->transparentBlue = GLX_DONT_CARE;
+ (*next)->transparentAlpha = GLX_DONT_CARE;
+ (*next)->transparentIndex = GLX_DONT_CARE;
+ (*next)->xRenderable = GLX_DONT_CARE;
+ (*next)->fbconfigID = GLX_DONT_CARE;
+ (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ (*next)->bindToTextureRgb = GLX_DONT_CARE;
+ (*next)->bindToTextureRgba = GLX_DONT_CARE;
+ (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+ (*next)->bindToTextureTargets = 0;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = & ((*next)->next);
+ }
+
+ return head;
+}
+
+struct drm_screen;
+
+struct drm_driver
+{
+ _EGLDriver base; /* base class/object */
+
+ drmModeResPtr res;
+
+ struct drm_screen *screens[MAX_SCREENS];
+ size_t count_screens;
+
+ 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;
+
+ /* currently only support one connector */
+ drmModeConnectorPtr connector;
+
+ /* Has this screen been shown */
+ int shown;
+
+ /* Surface that is currently attached to this screen */
+ struct drm_surface *surf;
+
+ /* backing buffer */
+ drmBO buffer;
+
+ /* framebuffer */
+ drmModeFBPtr fb;
+ uint32_t fbID;
+
+ /* crtc and mode used */
+ drmModeCrtcPtr crtc;
+ uint32_t crtcID;
+
+ 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_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
+{
+ struct drm_mode_modeinfo *m;
+ int i;
+
+ for (i = 0; i < connector->count_modes; i++) {
+ m = &connector->modes[i];
+ _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
+ }
+}
+
+
+static 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;
+ drmModeConnectorPtr connector = NULL;
+ drmModeResPtr res = NULL;
+ unsigned count_connectors = 0;
+ int num_screens = 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_connectors = res->count_connectors;
+
+ for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
+ connector = drmModeGetConnector(fd, res->connectors[i]);
+
+ if (!connector)
+ continue;
+
+ if (connector->connection != DRM_MODE_CONNECTED) {
+ drmModeFreeConnector(connector);
+ continue;
+ }
+
+ screen = malloc(sizeof(struct drm_screen));
+ memset(screen, 0, sizeof(*screen));
+ screen->connector = connector;
+ _eglInitScreen(&screen->base);
+ _eglAddScreen(disp, &screen->base);
+ drm_add_modes_from_connector(&screen->base, connector);
+ drm_drv->screens[num_screens++] = screen;
+ }
+ drm_drv->count_screens = num_screens;
+
+ /* for now we only have one config */
+ _EGLConfig *config = calloc(1, sizeof(*config));
+ memset(config, 1, sizeof(*config));
+ _eglInitConfig(config, 1);
+ _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
+ _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
+ _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
+ _eglAddConfig(disp, config);
+
+ drv->Initialized = EGL_TRUE;
+
+ *major = 1;
+ *minor = 4;
+
+ return EGL_TRUE;
+}
+
+static void
+drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ unsigned int i;
+
+ intel_bind_frontbuffer(screen->surf->drawable, NULL);
+ screen->surf = NULL;
+
+ for (i = 0; i < drm_drv->res->count_crtcs; i++) {
+ drmModeSetCrtc(
+ drm_drv->device->drmFD,
+ drm_drv->res->crtcs[i],
+ 0, // FD
+ 0, 0,
+ NULL, 0, // List of output ids
+ NULL);
+ }
+
+ drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
+ drmModeFreeFB(screen->fb);
+ screen->fb = NULL;
+
+ drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
+
+ screen->shown = 0;
+}
+
+static EGLBoolean
+drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_screen *screen;
+ int i = 0;
+
+ intel_destroy_device(drm_drv->device);
+ drmFreeVersion(drm_drv->device->version);
+
+ for (i = 0; i < drm_drv->count_screens; i++) {
+ screen = drm_drv->screens[i];
+
+ if (screen->shown)
+ drm_takedown_shown_screen(drv, screen);
+
+ drmModeFreeConnector(screen->connector);
+ _eglDestroyScreen(&screen->base);
+ drm_drv->screens[i] = NULL;
+ }
+
+ drmClose(drm_drv->device->drmFD);
+
+ free(drm_drv->device);
+
+ _eglCleanupDisplay(_eglLookupDisplay(dpy));
+ free(drm_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 = _egl_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->haveDepthBuffer = visual->depthBits > 0;
+ visual->stencilBits = 8;
+ visual->haveStencilBuffer = visual->stencilBits > 0;
+
+ 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 {
+ intel_destroy_context(fc->context);
+ free(fc->context);
+ 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(drmModeConnectorPtr connector, _EGLMode *mode)
+{
+ int i;
+ struct drm_mode_modeinfo *m;
+
+ for (i = 0; i < connector->count_modes; i++) {
+ m = &connector->modes[i];
+ if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
+ break;
+ m = &connector->modes[0]; /* if we can't find one, return first */
+ }
+
+ return m;
+}
+static 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;
+ void *p;
+ int i;
+
+ drmBOReference(fd, handle, &bo);
+ drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p);
+ ptr = (unsigned int*)p;
+
+ 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);
+ _EGLMode *mode = _eglLookupMode(dpy, m);
+ size_t pitch = mode->Width * 4;
+ size_t size = mode->Height * pitch;
+ int ret;
+ unsigned int i,j,k;
+
+ if (scrn->shown)
+ drm_takedown_shown_screen(drv, scrn);
+
+ 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)
+ 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;
+
+ for (j = 0; j < drm_drv->res->count_connectors; j++) {
+ drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]);
+ scrn->mode = drm_find_mode(con, mode);
+ if (!scrn->mode)
+ goto err_fb;
+
+ for (k = 0; k < con->count_encoders; k++) {
+ drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]);
+ for (i = 0; i < drm_drv->res->count_crtcs; i++) {
+ if (enc->possible_crtcs & (1<<i)) {
+ ret = drmModeSetCrtc(
+ drm_drv->device->drmFD,
+ drm_drv->res->crtcs[i],
+ scrn->fbID,
+ 0, 0,
+ &drm_drv->res->connectors[j], 1,
+ scrn->mode);
+ /* skip the other crtcs now */
+ i = drm_drv->res->count_crtcs;
+ }
+ }
+ }
+ }
+
+ scrn->front.handle = scrn->buffer.handle;
+ scrn->front.pitch = pitch;
+ scrn->front.width = mode->Width;
+ scrn->front.height = mode->Height;
+
+ scrn->surf = surf;
+ intel_bind_frontbuffer(surf->drawable, &scrn->front);
+
+ scrn->shown = 1;
+
+ 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 {
+ intel_bind_frontbuffer(fs->drawable, NULL);
+ intel_destroy_drawable(fs->drawable);
+ free(fs->drawable);
+ 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;
+
+ if (ctx) {
+ if (!drawSurf || !readSurf)
+ return EGL_FALSE;
+
+ intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
+ } else {
+ intel_make_current(NULL, NULL, NULL);
+ }
+
+ 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;
+
+ drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ drm->base.Name = "DRM/Gallium";
+
+ /* 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/drm/intel/egl/intel_egl.h b/src/gallium/winsys/drm/intel/egl/intel_egl.h
new file mode 100644
index 0000000000..1ee27e0847
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_egl.h
@@ -0,0 +1,53 @@
+
+#ifndef _INTEL_EGL_H_
+#define _INTEL_EGL_H_
+
+#include <xf86drm.h>
+
+struct egl_drm_device
+{
+ void *priv;
+ int drmFD;
+
+ drmVersionPtr version;
+ int deviceID;
+};
+
+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_create_device(struct egl_drm_device *device);
+int intel_destroy_device(struct egl_drm_device *device);
+
+int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
+int intel_destroy_context(struct egl_drm_context *context);
+
+int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
+int intel_destroy_drawable(struct egl_drm_drawable *drawable);
+
+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/drm/intel/egl/intel_reg.h b/src/gallium/winsys/drm/intel/egl/intel_reg.h
new file mode 100644
index 0000000000..4f33bee438
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_reg.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef _INTEL_REG_H_
+#define _INTEL_REG_H_
+
+
+#define BR00_BITBLT_CLIENT 0x40000000
+#define BR00_OP_COLOR_BLT 0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR13_SOLID_PATTERN 0x80000000
+
+#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
+#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
+#define XY_COLOR_BLT_WRITE_RGB (1<<20)
+
+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+
+#define MI_WAIT_FOR_EVENT ((0x3<<23))
+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+
+#define MI_BATCH_BUFFER_END (0xA<<23)
+
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c
new file mode 100644
index 0000000000..2edcbc79ff
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c
@@ -0,0 +1,111 @@
+/**************************************************************************
+ *
+ * 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_device.h"
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_reg.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);
+ if (intel_fb->front)
+ 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_context *intel = NULL;
+ struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
+ struct _DriFenceObject *fence;
+
+ //const int srcWidth = surf->width;
+ //const int srcHeight = surf->height;
+
+ intel = intel_fb->device->dummy;
+ if (!intel) {
+ printf("No dummy context\n");
+ return;
+ }
+
+ 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;
+ const int srcPitch = surf->stride / 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);
+
+ BEGIN_BATCH(8, 2);
+ 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);
+
+ fence = intel_be_batchbuffer_flush(intel->base.batch);
+ driFenceUnReference(&fence);
+ intel_be_batchbuffer_finish(intel->base.batch);
+}