summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/Makefile6
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c12
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c13
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c5
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c36
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h1
-rw-r--r--src/gallium/state_trackers/egl/Makefile70
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c1351
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h94
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c131
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.h73
-rw-r--r--src/gallium/state_trackers/egl/common/native.h272
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h20
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c105
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c443
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.c274
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.h195
-rw-r--r--src/gallium/state_trackers/egl/egl_visual.c85
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c856
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h139
-rw-r--r--src/gallium/state_trackers/egl/x11/glxinit.c682
-rw-r--r--src/gallium/state_trackers/egl/x11/glxinit.h11
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c693
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c150
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h37
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c684
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.h40
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c453
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.h105
-rw-r--r--src/gallium/state_trackers/es/Makefile84
-rw-r--r--src/gallium/state_trackers/es/st_es1.c3
-rw-r--r--src/gallium/state_trackers/es/st_es2.c3
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_getproc.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c10
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_winsys.h7
-rw-r--r--src/gallium/state_trackers/python/SConscript1
-rw-r--r--src/gallium/state_trackers/python/gallium.i3
-rw-r--r--src/gallium/state_trackers/python/p_context.i5
-rwxr-xr-xsrc/gallium/state_trackers/python/retrace/interpreter.py10
-rw-r--r--src/gallium/state_trackers/python/samples/gs.py10
-rw-r--r--src/gallium/state_trackers/python/samples/tri.py10
-rw-r--r--src/gallium/state_trackers/python/st_device.c23
-rw-r--r--src/gallium/state_trackers/python/st_device.h1
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c17
-rw-r--r--src/gallium/state_trackers/python/st_llvmpipe_winsys.c11
-rw-r--r--src/gallium/state_trackers/python/st_sample.c2
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c218
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h3
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore1
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh13
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh9
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh2
-rw-r--r--src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py49
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore1
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh16
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh12
-rw-r--r--src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py50
-rwxr-xr-xsrc/gallium/state_trackers/python/tests/texture_render.py10
-rwxr-xr-xsrc/gallium/state_trackers/python/tests/texture_sample.py20
-rw-r--r--src/gallium/state_trackers/vega/Makefile80
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c36
-rw-r--r--src/gallium/state_trackers/vega/api_images.c2
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c20
-rw-r--r--src/gallium/state_trackers/vega/api_path.c2
-rw-r--r--src/gallium/state_trackers/vega/asm_fill.h551
-rw-r--r--src/gallium/state_trackers/vega/image.c2
-rw-r--r--src/gallium/state_trackers/vega/mask.c49
-rw-r--r--src/gallium/state_trackers/vega/paint.c5
-rw-r--r--src/gallium/state_trackers/vega/polygon.c13
-rw-r--r--src/gallium/state_trackers/vega/renderer.c22
-rw-r--r--src/gallium/state_trackers/vega/shader.c22
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c151
-rw-r--r--src/gallium/state_trackers/vega/st_inlines.h2
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c94
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h8
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c28
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h6
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c28
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h2
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c26
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.h2
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_winsys.h3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c52
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c100
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c41
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_winsys.h1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c24
97 files changed, 7249 insertions, 2043 deletions
diff --git a/src/gallium/state_trackers/Makefile b/src/gallium/state_trackers/Makefile
index 265ca468c2..0900efc664 100644
--- a/src/gallium/state_trackers/Makefile
+++ b/src/gallium/state_trackers/Makefile
@@ -21,5 +21,9 @@ clean:
rm -f `find . -name depend`
-# Dummy install target
install:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index f2e5f3fb23..5033c3c85b 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -69,14 +69,12 @@ dri_create_context(const __GLcontextModes * visual,
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- ctx->pipe = screen->api->create_context(screen->api, screen->pipe_screen);
+ ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
+ ctx );
if (ctx->pipe == NULL)
goto fail;
- /* used in dri_flush_frontbuffer */
- ctx->pipe->priv = ctx;
-
ctx->st = st_create_context(ctx->pipe, visual, st_share);
if (ctx->st == NULL)
goto fail;
@@ -101,6 +99,12 @@ dri_destroy_context(__DRIcontext * cPriv)
{
struct dri_context *ctx = dri_context(cPriv);
+ /* note: we are freeing values and nothing more because
+ * driParseConfigFiles allocated values only - the rest
+ * is owned by screen optionCache.
+ */
+ FREE(ctx->optionCache.values);
+
/* No particular reason to wait for command completion before
* destroying a context, but it is probably worthwhile flushing it
* to avoid having to add code elsewhere to cope with flushing a
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index f131e77ac5..f7ed6605bf 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -35,7 +35,6 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
#include "main/mtypes.h"
#include "main/renderbuffer.h"
#include "state_tracker/drm_api.h"
@@ -47,6 +46,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_inlines.h"
static struct pipe_surface *
dri_surface_from_handle(struct drm_api *api,
@@ -123,11 +123,12 @@ dri_get_buffers(__DRIdrawable * dPriv)
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *surface = NULL;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct dri_screen *st_screen = dri_screen(drawable->sPriv);
+ struct pipe_screen *screen = st_screen->pipe_screen;
__DRIbuffer *buffers = NULL;
__DRIscreen *dri_screen = drawable->sPriv;
__DRIdrawable *dri_drawable = drawable->dPriv;
- struct drm_api *api = ((struct dri_screen*)(dri_screen->private))->api;
+ struct drm_api *api = st_screen->api;
boolean have_depth = FALSE;
int i, count;
@@ -180,6 +181,9 @@ dri_get_buffers(__DRIdrawable * dPriv)
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
+ if (!st_screen->auto_fake_front)
+ continue;
+ /* fallthrough */
case __DRI_BUFFER_FAKE_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = drawable->color_format;
@@ -372,7 +376,8 @@ dri_create_buffer(__DRIscreen * sPriv,
/* TODO incase of double buffer visual, delay fake creation */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-
+ if (!screen->auto_fake_front)
+ drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
if (visual->doubleBufferMode)
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
if (visual->depthBits && visual->stencilBits)
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 8b014a2a8b..1259813a41 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -50,6 +50,7 @@
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_cull_vertex
+#define need_GL_EXT_draw_buffers2
#define need_GL_EXT_fog_coord
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_multi_draw_arrays
@@ -98,6 +99,7 @@ static const struct dri_extension card_extensions[] = {
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
{"GL_EXT_blend_subtract", NULL},
{"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
+ {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions},
{"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
{"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
{"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
@@ -130,6 +132,9 @@ dri_init_extensions(struct dri_context *ctx)
/* The card_extensions list should be pruned according to the
* capabilities of the pipe_screen. This is actually something
* that can/should be done inside st_create_context().
+ * XXX Not pruning is very bogus. Always all these extensions above
+ * will be advertized, regardless what st_init_extensions
+ * (which depends on the pipe cap bits) does.
*/
driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE);
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 793db087ee..2052867309 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -37,14 +37,12 @@
#include "dri_context.h"
#include "dri_drawable.h"
-#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
#include "pipe/p_format.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_cb_fbo.h"
+
+#include "util/u_debug.h"
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
@@ -83,7 +81,7 @@ dri_fill_in_modes(struct dri_screen *screen,
unsigned num_modes;
uint8_t depth_bits_array[5];
uint8_t stencil_bits_array[5];
- uint8_t msaa_samples_array[1];
+ uint8_t msaa_samples_array[2];
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
unsigned msaa_samples_factor;
@@ -147,8 +145,9 @@ dri_fill_in_modes(struct dri_screen *screen,
}
msaa_samples_array[0] = 0;
+ msaa_samples_array[1] = 4;
back_buffer_factor = 3;
- msaa_samples_factor = 1;
+ msaa_samples_factor = 2;
num_modes =
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
@@ -158,7 +157,7 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array, msaa_samples_factor);
} else {
__DRIconfig **configs_a8r8g8b8 = NULL;
__DRIconfig **configs_x8r8g8b8 = NULL;
@@ -170,7 +169,8 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array,
+ msaa_samples_factor);
if (pf_x8r8g8b8)
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
depth_bits_array,
@@ -178,7 +178,8 @@ dri_fill_in_modes(struct dri_screen *screen,
depth_buffer_factor,
back_buffer_modes,
back_buffer_factor,
- msaa_samples_array, 1);
+ msaa_samples_array,
+ msaa_samples_factor);
if (configs_a8r8g8b8 && configs_x8r8g8b8)
configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
@@ -195,7 +196,7 @@ dri_fill_in_modes(struct dri_screen *screen,
return NULL;
}
- return (const const __DRIconfig **)configs;
+ return (const __DRIconfig **)configs;
}
/**
@@ -289,6 +290,8 @@ dri_init_screen2(__DRIscreen * sPriv)
{
struct dri_screen *screen;
struct drm_create_screen_arg arg;
+ const __DRIdri2LoaderExtension *dri2_ext =
+ sPriv->dri2.loader;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -314,6 +317,9 @@ dri_init_screen2(__DRIscreen * sPriv)
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
+ screen->auto_fake_front = dri2_ext->base.version >= 3 &&
+ dri2_ext->getBuffersWithFormat != NULL;
+
return dri_fill_in_modes(screen, 32);
fail:
return NULL;
@@ -323,8 +329,18 @@ static void
dri_destroy_screen(__DRIscreen * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
+ int i;
screen->pipe_screen->destroy(screen->pipe_screen);
+
+ for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
+ FREE(screen->optionCache.info[i].name);
+ FREE(screen->optionCache.info[i].ranges);
+ }
+
+ FREE(screen->optionCache.info);
+ FREE(screen->optionCache.values);
+
FREE(screen);
sPriv->private = NULL;
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 03387a0e81..75a0ee4250 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -59,6 +59,7 @@ struct dri_screen
struct pipe_screen *pipe_screen;
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
+ boolean auto_fake_front;
};
/** cast wrapper */
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index e825aa718b..794785006f 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -1,19 +1,73 @@
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = egldrm
-
-LIBRARY_INCLUDES = \
+common_INCLUDES = \
+ -I. \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/mesa/drivers/dri/common \
- -I$(TOP)/src/mesa \
- -I$(TOP)/include \
-I$(TOP)/src/egl/main \
+ -I$(TOP)/include
+
+common_SOURCES = $(wildcard common/*.c)
+common_OBJECTS = $(common_SOURCES:.c=.o)
+
+
+x11_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/glx \
+ -I$(TOP)/src/mesa \
$(shell pkg-config --cflags-only-I libdrm)
+x11_SOURCES = $(wildcard x11/*.c) \
+ $(TOP)/src/glx/dri2.c
+x11_OBJECTS = $(x11_SOURCES:.c=.o)
+
+
+kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm)
+kms_SOURCES = $(wildcard kms/*.c)
+kms_OBJECTS = $(kms_SOURCES:.c=.o)
+
+
+ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES)
+ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES)
+ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS)
+
+##### TARGETS #####
+
+EGL_DISPLAYS_MODS = $(foreach dpy, $(EGL_DISPLAYS), libegl$(dpy).a)
+
+default: depend $(EGL_DISPLAYS_MODS)
+
+
+libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile
+ $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS)
+
+libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile
+ $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS)
+
+depend:
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
+
+clean:
+ rm -f $(ALL_OBJECTS)
+ rm -f $(EGL_DISPLAYS_MODS)
+ rm -f depend depend.bak
+
+# Dummy target
+install:
+ @echo -n ""
+
+##### RULES #####
+
+$(common_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-C_SOURCES = $(wildcard ./*.c)
+$(x11_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+$(kms_OBJECTS): %.o: %.c
+ $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
-include ../../Makefile.template
+sinclude depend
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
new file mode 100644
index 0000000000..80dd126995
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -0,0 +1,1351 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "egldriver.h"
+#include "eglcurrent.h"
+#include "eglconfigutil.h"
+#include "egllog.h"
+
+#include "native.h"
+#include "egl_g3d.h"
+#include "egl_st.h"
+
+/**
+ * Validate the draw/read surfaces of the context.
+ */
+static void
+egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
+ ST_SURFACE_FRONT_LEFT,
+ ST_SURFACE_BACK_LEFT,
+ ST_SURFACE_FRONT_RIGHT,
+ ST_SURFACE_BACK_RIGHT,
+ };
+ EGLint num_surfaces, s;
+
+ /* validate draw and/or read buffers */
+ num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
+ for (s = 0; s < num_surfaces; s++) {
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ struct egl_g3d_surface *gsurf;
+ struct egl_g3d_buffer *gbuf;
+ EGLint att;
+
+ if (s == 0) {
+ gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+ gbuf = &gctx->draw;
+ }
+ else {
+ gsurf = egl_g3d_surface(gctx->base.ReadSurface);
+ gbuf = &gctx->read;
+ }
+
+ if (!gctx->force_validate) {
+ unsigned int seq_num;
+
+ gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
+ &seq_num, NULL, NULL, NULL);
+ /* skip validation */
+ if (gsurf->sequence_number == seq_num)
+ continue;
+ }
+
+ pipe_surface_reference(&gsurf->render_surface, NULL);
+ memset(textures, 0, sizeof(textures));
+
+ gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
+ &gsurf->sequence_number, textures,
+ &gsurf->base.Width, &gsurf->base.Height);
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *pt = textures[att];
+ struct pipe_surface *ps;
+
+ if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
+ ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+ gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
+ st_att_map[att], ps);
+
+ if (gsurf->render_att == att)
+ pipe_surface_reference(&gsurf->render_surface, ps);
+
+ pipe_surface_reference(&ps, NULL);
+ pipe_texture_reference(&pt, NULL);
+ }
+ }
+
+ gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
+ gsurf->base.Width, gsurf->base.Height);
+ }
+
+ gctx->force_validate = EGL_FALSE;
+
+}
+
+/**
+ * Create a st_framebuffer.
+ */
+static struct st_framebuffer *
+create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
+
+ return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
+ gconf->native->color_format, gconf->native->depth_format,
+ gconf->native->stencil_format,
+ gsurf->base.Width, gsurf->base.Height, &gsurf->base);
+}
+
+/**
+ * Update the attachments of draw/read surfaces.
+ */
+static void
+egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ EGLint s;
+
+ /* route draw and read buffers' attachments */
+ for (s = 0; s < 2; s++) {
+ struct egl_g3d_surface *gsurf;
+ struct egl_g3d_buffer *gbuf;
+
+ if (s == 0) {
+ gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+ gbuf = &gctx->draw;
+ }
+ else {
+ gsurf = egl_g3d_surface(gctx->base.ReadSurface);
+ gbuf = &gctx->read;
+ }
+
+ gbuf->attachment_mask = (1 << gsurf->render_att);
+
+ /* FIXME OpenGL defaults to draw the front or back buffer when the
+ * context is single-buffered or double-buffered respectively. In EGL,
+ * however, the buffer to be drawn is determined by the surface, instead
+ * of the context. As a result, rendering to a pixmap surface with a
+ * double-buffered context does not work as expected.
+ *
+ * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
+ * NATIVE_ATTACHMENT_FRONT_LEFT);
+ */
+
+ /*
+ * FIXME If the back buffer is asked for here, and the front buffer is
+ * later needed by the client API (e.g. glDrawBuffer is called to draw
+ * the front buffer), it will create a new pipe texture and draw there.
+ * One fix is to ask for both buffers here, but it would be a waste if
+ * the front buffer is never used. A better fix is to add a callback to
+ * the pipe screen with context private (just like flush_frontbuffer).
+ */
+ }
+}
+
+/**
+ * Reallocate the context's framebuffers after draw/read surfaces change.
+ */
+static EGLBoolean
+egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
+ struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
+
+ /* unreference the old framebuffers */
+ if (gctx->draw.st_fb) {
+ EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
+ void *priv;
+
+ priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
+ if (!gdraw || priv != (void *) &gdraw->base) {
+ gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
+ gctx->draw.st_fb = NULL;
+ gctx->draw.attachment_mask = 0x0;
+ }
+
+ if (is_equal) {
+ gctx->read.st_fb = NULL;
+ gctx->draw.attachment_mask = 0x0;
+ }
+ else {
+ priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
+ if (!gread || priv != (void *) &gread->base) {
+ gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
+ gctx->read.st_fb = NULL;
+ gctx->draw.attachment_mask = 0x0;
+ }
+ }
+ }
+
+ if (!gdraw)
+ return EGL_TRUE;
+
+ /* create the draw fb */
+ if (!gctx->draw.st_fb) {
+ gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
+ if (!gctx->draw.st_fb)
+ return EGL_FALSE;
+ }
+
+ /* create the read fb */
+ if (!gctx->read.st_fb) {
+ if (gread != gdraw) {
+ gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
+ if (!gctx->read.st_fb) {
+ gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
+ gctx->draw.st_fb = NULL;
+ return EGL_FALSE;
+ }
+ }
+ else {
+ /* there is no st_reference_framebuffer... */
+ gctx->read.st_fb = gctx->draw.st_fb;
+ }
+ }
+
+ egl_g3d_route_context(dpy, &gctx->base);
+ gctx->force_validate = EGL_TRUE;
+
+ return EGL_TRUE;
+}
+
+/**
+ * Return the state tracker for the given context.
+ */
+static const struct egl_g3d_st *
+egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ const struct egl_g3d_st *stapi;
+ EGLint idx = -1;
+
+ switch (ctx->ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ switch (ctx->ClientVersion) {
+ case 1:
+ idx = EGL_G3D_ST_OPENGL_ES;
+ break;
+ case 2:
+ idx = EGL_G3D_ST_OPENGL_ES2;
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "unknown client version %d",
+ ctx->ClientVersion);
+ break;
+ }
+ break;
+ case EGL_OPENVG_API:
+ idx = EGL_G3D_ST_OPENVG;
+ break;
+ case EGL_OPENGL_API:
+ idx = EGL_G3D_ST_OPENGL;
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
+ break;
+ }
+
+ stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
+ return stapi;
+}
+
+/**
+ * Initialize the state trackers.
+ */
+static void
+egl_g3d_init_st(_EGLDriver *drv)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ EGLint i;
+
+ /* already initialized */
+ if (gdrv->api_mask)
+ return;
+
+ for (i = 0; i < NUM_EGL_G3D_STS; i++) {
+ gdrv->stapis[i] = egl_g3d_get_st(i);
+ if (gdrv->stapis[i])
+ gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+ }
+
+ if (gdrv->api_mask)
+ _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
+ else
+ _eglLog(_EGL_WARNING, "No supported client API");
+}
+
+/**
+ * Get the probe object of the display.
+ *
+ * Note that this function may be called before the display is initialized.
+ */
+static struct native_probe *
+egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct native_probe *nprobe;
+
+ nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
+ if (!nprobe || nprobe->display != dpy->NativeDisplay) {
+ if (nprobe)
+ nprobe->destroy(nprobe);
+ nprobe = native_create_probe(dpy->NativeDisplay);
+ _eglSetProbeCache(gdrv->probe_key, (void *) nprobe);
+ }
+
+ return nprobe;
+}
+
+/**
+ * Destroy the probe object of the display. The display may be NULL.
+ *
+ * Note that this function may be called before the display is initialized.
+ */
+static void
+egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct native_probe *nprobe;
+
+ nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
+ if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) {
+ nprobe->destroy(nprobe);
+ _eglSetProbeCache(gdrv->probe_key, NULL);
+ }
+}
+
+/**
+ * Return an API mask that consists of the state trackers that supports the
+ * given mode.
+ *
+ * FIXME add st_is_mode_supported()?
+ */
+static EGLint
+get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
+{
+ EGLint check;
+
+ /* OpenGL ES 1.x and 2.x are checked together */
+ check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
+ if (api_mask & check) {
+ /* this is required by EGL, not by OpenGL ES */
+ if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
+ api_mask &= ~check;
+ }
+
+ check = EGL_OPENVG_BIT;
+ if (api_mask & check) {
+ /* vega st needs the depth/stencil rb */
+ if (!mode->depthBits && !mode->stencilBits)
+ api_mask &= ~check;
+ }
+
+ return api_mask;
+}
+
+#ifdef EGL_MESA_screen_surface
+
+static void
+egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ const struct native_connector **native_connectors;
+ EGLint num_connectors, i;
+
+ native_connectors =
+ gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
+ if (!num_connectors) {
+ if (native_connectors)
+ free(native_connectors);
+ return;
+ }
+
+ for (i = 0; i < num_connectors; i++) {
+ const struct native_connector *nconn = native_connectors[i];
+ struct egl_g3d_screen *gscr;
+ const struct native_mode **native_modes;
+ EGLint num_modes, j;
+
+ /* TODO support for hotplug */
+ native_modes =
+ gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
+ if (!num_modes) {
+ if (native_modes)
+ free(native_modes);
+ continue;
+ }
+
+ gscr = CALLOC_STRUCT(egl_g3d_screen);
+ if (!gscr) {
+ free(native_modes);
+ continue;
+ }
+
+ _eglInitScreen(&gscr->base);
+
+ for (j = 0; j < num_modes; j++) {
+ const struct native_mode *nmode = native_modes[j];
+ _EGLMode *mode;
+
+ mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
+ nmode->refresh_rate, nmode->desc);
+ if (!mode)
+ break;
+ /* gscr->native_modes and gscr->base.Modes should be consistent */
+ assert(mode == &gscr->base.Modes[j]);
+ }
+
+ gscr->native = nconn;
+ gscr->native_modes = native_modes;
+
+ _eglAddScreen(dpy, &gscr->base);
+ }
+
+ free(native_connectors);
+}
+
+#endif /* EGL_MESA_screen_surface */
+
+/**
+ * Add configs to display and return the next config ID.
+ */
+static EGLint
+egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ const struct native_config **native_configs;
+ int num_configs, i;
+
+ native_configs = gdpy->native->get_configs(gdpy->native,
+ &num_configs);
+ if (!num_configs) {
+ if (native_configs)
+ free(native_configs);
+ return id;
+ }
+
+ for (i = 0; i < num_configs; i++) {
+ EGLint api_mask;
+ struct egl_g3d_config *gconf;
+ EGLBoolean valid;
+
+ gconf = CALLOC_STRUCT(egl_g3d_config);
+ if (!gconf)
+ continue;
+
+ _eglInitConfig(&gconf->base, dpy, id);
+
+ api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
+ if (!api_mask) {
+ _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+ native_configs[i]->mode.visualID);
+ }
+
+ valid = _eglConfigFromContextModesRec(&gconf->base,
+ &native_configs[i]->mode, api_mask, api_mask);
+ if (valid) {
+#ifdef EGL_MESA_screen_surface
+ /* check if scanout surface bit is set */
+ if (native_configs[i]->scanout_bit) {
+ EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
+ val |= EGL_SCREEN_BIT_MESA;
+ SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ }
+#endif
+ valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
+ }
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
+ native_configs[i]->mode.visualID);
+ free(gconf);
+ continue;
+ }
+
+ gconf->native = native_configs[i];
+ _eglAddConfig(dpy, &gconf->base);
+ id++;
+ }
+
+ free(native_configs);
+ return id;
+}
+
+/**
+ * Flush the front buffer of the context's draw surface.
+ */
+static void
+egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(context_private);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+
+ if (gsurf)
+ gsurf->native->flush_frontbuffer(gsurf->native);
+}
+
+/**
+ * Re-validate the context.
+ */
+static void
+egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(context_private);
+
+ /**
+ * It is likely that the surface has changed when this function is called.
+ * Set force_validate to skip an unnecessary check.
+ */
+ gctx->force_validate = EGL_TRUE;
+ egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
+}
+
+static EGLBoolean
+egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ EGLint i;
+
+ _eglReleaseDisplayResources(drv, dpy);
+ _eglCleanupDisplay(dpy);
+
+ if (dpy->Screens) {
+ for (i = 0; i < dpy->NumScreens; i++) {
+ struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
+ free(gscr->native_modes);
+ free(gscr);
+ }
+ free(dpy->Screens);
+ }
+
+ if (gdpy->native)
+ gdpy->native->destroy(gdpy->native);
+
+ free(gdpy);
+ dpy->DriverData = NULL;
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLint *major, EGLint *minor)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_display *gdpy;
+
+ /* the probe object is unlikely to be needed again */
+ egl_g3d_destroy_probe(drv, dpy);
+
+ gdpy = CALLOC_STRUCT(egl_g3d_display);
+ if (!gdpy) {
+ _eglError(EGL_BAD_ALLOC, "eglInitialize");
+ goto fail;
+ }
+ dpy->DriverData = gdpy;
+
+ gdpy->native = native_create_display(dpy->NativeDisplay);
+ if (!gdpy->native) {
+ _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
+ goto fail;
+ }
+
+ gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
+ gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
+
+ egl_g3d_init_st(&gdrv->base);
+ dpy->ClientAPIsMask = gdrv->api_mask;
+
+ if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
+ _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
+ goto fail;
+ }
+
+#ifdef EGL_MESA_screen_surface
+ /* enable MESA_screen_surface */
+ if (gdpy->native->modeset) {
+ dpy->Extensions.MESA_screen_surface = EGL_TRUE;
+ egl_g3d_add_screens(drv, dpy);
+ }
+#endif
+
+ *major = 1;
+ *minor = 4;
+
+ return EGL_TRUE;
+
+fail:
+ if (gdpy)
+ egl_g3d_terminate(drv, dpy);
+ return EGL_FALSE;
+}
+
+static _EGLContext *
+egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share, const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_context *gshare = egl_g3d_context(share);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_context *gctx;
+ const __GLcontextModes *mode;
+
+ gctx = CALLOC_STRUCT(egl_g3d_context);
+ if (!gctx) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+ return NULL;
+ }
+
+ if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
+ free(gctx);
+ return NULL;
+ }
+
+ gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
+ if (!gctx->stapi) {
+ free(gctx);
+ return NULL;
+ }
+
+ mode = &gconf->native->mode;
+
+ gctx->pipe = gdpy->native->screen->context_create(
+ gdpy->native->screen,
+ (void *) &gctx->base);
+
+ if (!gctx->pipe) {
+ free(gctx);
+ return NULL;
+ }
+
+ gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
+ (gshare) ? gshare->st_ctx : NULL);
+ if (!gctx->st_ctx) {
+ gctx->pipe->destroy(gctx->pipe);
+ free(gctx);
+ return NULL;
+ }
+
+ return &gctx->base;
+}
+
+/**
+ * Destroy a context.
+ */
+static void
+destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* FIXME a context might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
+
+ egl_g3d_realloc_context(dpy, &gctx->base);
+ /* it will destroy the associated pipe context */
+ gctx->stapi->st_destroy_context(gctx->st_ctx);
+
+ free(gctx);
+}
+
+static EGLBoolean
+egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ if (!_eglIsContextBound(ctx))
+ destroy_context(dpy, ctx);
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+init_surface_geometry(_EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ return gsurf->native->validate(gsurf->native, 0x0,
+ &gsurf->sequence_number, NULL,
+ &gsurf->base.Width, &gsurf->base.Height);
+}
+
+static _EGLSurface *
+egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativeWindowType win,
+ const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) {
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->native =
+ gdpy->native->create_window_surface(gdpy->native, win, gconf->native);
+ if (!gsurf->native) {
+ free(gsurf);
+ return NULL;
+ }
+
+ if (!init_surface_geometry(&gsurf->base)) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER ||
+ !gconf->native->mode.doubleBufferMode) ?
+ NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+ return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativePixmapType pix,
+ const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) {
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->native =
+ gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native);
+ if (!gsurf->native) {
+ free(gsurf);
+ return NULL;
+ }
+
+ if (!init_surface_geometry(&gsurf->base)) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
+
+ return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->native =
+ gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native,
+ gsurf->base.Width, gsurf->base.Height);
+ if (!gsurf->native) {
+ free(gsurf);
+ return NULL;
+ }
+
+ if (!init_surface_geometry(&gsurf->base)) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
+ NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+ return &gsurf->base;
+}
+
+/**
+ * Destroy a surface.
+ */
+static void
+destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ /* FIXME a surface might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
+
+ pipe_surface_reference(&gsurf->render_surface, NULL);
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+}
+
+static EGLBoolean
+egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ if (!_eglIsSurfaceBound(surf))
+ destroy_surface(dpy, surf);
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
+ struct egl_g3d_context *old_gctx;
+ EGLBoolean ok = EGL_TRUE;
+
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &draw, &read))
+ return EGL_FALSE;
+ old_gctx = egl_g3d_context(ctx);
+
+ if (old_gctx) {
+ /* flush old context */
+ old_gctx->stapi->st_flush(old_gctx->st_ctx,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+
+ /*
+ * The old context is no longer current, and egl_g3d_realloc_context()
+ * should be called to destroy the framebuffers. However, it is possible
+ * that it will be made current again with the same draw/read surfaces.
+ * It might be better to keep it around.
+ */
+ }
+
+ if (gctx) {
+ ok = egl_g3d_realloc_context(dpy, &gctx->base);
+ if (ok) {
+ ok = gctx->stapi->st_make_current(gctx->st_ctx,
+ gctx->draw.st_fb, gctx->read.st_fb);
+ if (ok) {
+ egl_g3d_validate_context(dpy, &gctx->base);
+ if (gdraw->base.Type == EGL_WINDOW_BIT) {
+ gctx->base.WindowRenderBuffer =
+ (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
+ EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
+ }
+ }
+ }
+ }
+ else if (old_gctx) {
+ ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
+ old_gctx->base.WindowRenderBuffer = EGL_NONE;
+ }
+
+ if (ctx && !_eglIsContextLinked(ctx))
+ destroy_context(dpy, ctx);
+ if (draw && !_eglIsSurfaceLinked(draw))
+ destroy_surface(dpy, draw);
+ if (read && read != draw && !_eglIsSurfaceLinked(read))
+ destroy_surface(dpy, read);
+
+ return ok;
+}
+
+static EGLBoolean
+egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = NULL;
+
+ /* no-op for pixmap or pbuffer surface */
+ if (gsurf->base.Type == EGL_PIXMAP_BIT ||
+ gsurf->base.Type == EGL_PBUFFER_BIT)
+ return EGL_TRUE;
+
+ /* or when the surface is single-buffered */
+ if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
+ return EGL_TRUE;
+
+ if (ctx && ctx->DrawSurface == surf)
+ gctx = egl_g3d_context(ctx);
+
+ /* flush if the surface is current */
+ if (gctx)
+ gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
+
+ /*
+ * We drew on the back buffer, unless there was no back buffer.
+ * In that case, we drew on the front buffer. Either case, we call
+ * swap_buffers.
+ */
+ if (!gsurf->native->swap_buffers(gsurf->native))
+ return EGL_FALSE;
+
+ if (gctx) {
+ struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
+
+ /* force validation if the swap method is not copy */
+ if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) {
+ gctx->force_validate = EGL_TRUE;
+ egl_g3d_validate_context(dpy, &gctx->base);
+ }
+ }
+
+ return EGL_TRUE;
+}
+
+/**
+ * Find a config that supports the pixmap.
+ */
+static _EGLConfig *
+find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf;
+ EGLint i;
+
+ for (i = 0; i < dpy->NumConfigs; i++) {
+ gconf = egl_g3d_config(dpy->Configs[i]);
+ if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
+ break;
+ }
+
+ return (i < dpy->NumConfigs) ? &gconf->base : NULL;
+}
+
+/**
+ * Get the pipe surface of the given attachment of the native surface.
+ */
+static struct pipe_surface *
+get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
+ enum native_attachment natt)
+{
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_surface *psurf;
+
+ textures[natt] = NULL;
+ nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
+ if (!textures[natt])
+ return NULL;
+
+ psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
+ 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
+ pipe_texture_reference(&textures[natt], NULL);
+
+ return psurf;
+}
+
+static EGLBoolean
+egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+ EGLNativePixmapType target)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_config *gconf;
+ struct native_surface *nsurf;
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_surface *psurf;
+
+ if (!gsurf->render_surface)
+ return EGL_TRUE;
+
+ gconf = egl_g3d_config(find_pixmap_config(dpy, target));
+ if (!gconf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ target, gconf->native);
+ if (!nsurf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ /* flush if the surface is current */
+ if (ctx && ctx->DrawSurface == &gsurf->base) {
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ gctx->stapi->st_flush(gctx->st_ctx,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+ if (psurf) {
+ struct pipe_context pipe;
+
+ /**
+ * XXX This is hacky. If we might allow the EGLDisplay to create a pipe
+ * context of its own and use the blitter context for this.
+ */
+ memset(&pipe, 0, sizeof(pipe));
+ pipe.screen = screen;
+
+ util_surface_copy(&pipe, FALSE, psurf, 0, 0,
+ gsurf->render_surface, 0, 0, psurf->width, psurf->height);
+
+ pipe_surface_reference(&psurf, NULL);
+ nsurf->flush_frontbuffer(nsurf);
+ }
+
+ nsurf->destroy(nsurf);
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ gctx->stapi->st_finish(gctx->st_ctx);
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+
+ if (engine != EGL_CORE_NATIVE_ENGINE)
+ return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
+
+ if (ctx && ctx->DrawSurface) {
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
+ gsurf->native->wait(gsurf->native);
+ }
+
+ return EGL_TRUE;
+}
+
+static _EGLProc
+egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ _EGLProc proc;
+ EGLint i;
+
+ /* in case this is called before a display is initialized */
+ egl_g3d_init_st(&gdrv->base);
+
+ for (i = 0; i < NUM_EGL_G3D_STS; i++) {
+ const struct egl_g3d_st *stapi = gdrv->stapis[i];
+ if (stapi) {
+ proc = (_EGLProc) stapi->st_get_proc_address(procname);
+ if (proc)
+ return proc;
+ }
+ }
+
+ return (_EGLProc) NULL;
+}
+
+static EGLBoolean
+egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint buffer)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx;
+ enum pipe_format target_format;
+ int target;
+
+ if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
+ return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ if (gsurf->base.BoundToTexture)
+ return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+ switch (gsurf->base.TextureFormat) {
+ case EGL_TEXTURE_RGB:
+ target_format = PIPE_FORMAT_R8G8B8_UNORM;
+ break;
+ case EGL_TEXTURE_RGBA:
+ target_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ switch (gsurf->base.TextureTarget) {
+ case EGL_TEXTURE_2D:
+ target = ST_TEXTURE_2D;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ if (!es1)
+ return EGL_TRUE;
+ if (!gsurf->render_surface)
+ return EGL_FALSE;
+
+ /* flush properly if the surface is bound */
+ if (gsurf->base.CurrentContext) {
+ gctx = egl_g3d_context(gsurf->base.CurrentContext);
+ gctx->stapi->st_flush(gctx->st_ctx,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ gctx = egl_g3d_context(es1);
+ gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
+ target, gsurf->base.MipmapLevel, target_format);
+
+ gsurf->base.BoundToTexture = EGL_TRUE;
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint buffer)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
+ !gsurf->base.BoundToTexture)
+ return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+ if (gsurf->render_surface) {
+ _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* what if the context the surface binds to is no longer current? */
+ if (gctx)
+ gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
+ ST_TEXTURE_2D, gsurf->base.MipmapLevel);
+ }
+
+ gsurf->base.BoundToTexture = EGL_FALSE;
+
+ return EGL_TRUE;
+}
+
+#ifdef EGL_MESA_screen_surface
+
+static _EGLSurface *
+egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy,
+ EGL_SCREEN_BIT_MESA, conf, attribs)) {
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->native =
+ gdpy->native->modeset->create_scanout_surface(gdpy->native,
+ gconf->native, gsurf->base.Width, gsurf->base.Height);
+ if (!gsurf->native) {
+ free(gsurf);
+ return NULL;
+ }
+
+ gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
+ NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+
+ return &gsurf->base;
+}
+
+static EGLBoolean
+egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scr, _EGLSurface *surf,
+ _EGLMode *mode)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct native_surface *nsurf;
+ const struct native_mode *nmode;
+ EGLBoolean changed;
+
+ if (gsurf) {
+ EGLint idx;
+
+ if (!mode)
+ return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+ if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
+ return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
+ if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
+ return _eglError(EGL_BAD_MATCH,
+ "eglShowSurfaceMESA(surface smaller than mode size)");
+
+ /* find the index of the mode */
+ for (idx = 0; idx < gscr->base.NumModes; idx++)
+ if (mode == &gscr->base.Modes[idx])
+ break;
+ if (idx >= gscr->base.NumModes) {
+ return _eglError(EGL_BAD_MODE_MESA,
+ "eglShowSurfaceMESA(unknown mode)");
+ }
+
+ nsurf = gsurf->native;
+ nmode = gscr->native_modes[idx];
+ }
+ else {
+ if (mode)
+ return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+
+ /* disable the screen */
+ nsurf = NULL;
+ nmode = NULL;
+ }
+
+ /* TODO surface panning by CRTC choosing */
+ changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
+ gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
+ if (changed) {
+ gscr->base.CurrentSurface = &gsurf->base;
+ gscr->base.CurrentMode = mode;
+ }
+
+ return changed;
+}
+
+#endif /* EGL_MESA_screen_surface */
+
+static EGLint
+egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct native_probe *nprobe;
+ enum native_probe_result res;
+ EGLint score;
+
+ nprobe = egl_g3d_get_probe(drv, dpy);
+ res = native_get_probe_result(nprobe);
+
+ switch (res) {
+ case NATIVE_PROBE_UNKNOWN:
+ default:
+ score = 0;
+ break;
+ case NATIVE_PROBE_FALLBACK:
+ score = 40;
+ break;
+ case NATIVE_PROBE_SUPPORTED:
+ score = 50;
+ break;
+ case NATIVE_PROBE_EXACT:
+ score = 100;
+ break;
+ }
+
+ return score;
+}
+
+static void
+egl_g3d_unload(_EGLDriver *drv)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+
+ egl_g3d_destroy_probe(drv, NULL);
+ free(gdrv);
+}
+
+_EGLDriver *
+_eglMain(const char *args)
+{
+ static char driver_name[64];
+ struct egl_g3d_driver *gdrv;
+
+ snprintf(driver_name, sizeof(driver_name),
+ "Gallium/%s", native_get_name());
+
+ gdrv = CALLOC_STRUCT(egl_g3d_driver);
+ if (!gdrv)
+ return NULL;
+
+ _eglInitDriverFallbacks(&gdrv->base);
+
+ gdrv->base.API.Initialize = egl_g3d_initialize;
+ gdrv->base.API.Terminate = egl_g3d_terminate;
+ gdrv->base.API.CreateContext = egl_g3d_create_context;
+ gdrv->base.API.DestroyContext = egl_g3d_destroy_context;
+ gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface;
+ gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
+ gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
+ gdrv->base.API.DestroySurface = egl_g3d_destroy_surface;
+ gdrv->base.API.MakeCurrent = egl_g3d_make_current;
+ gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers;
+ gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers;
+ gdrv->base.API.WaitClient = egl_g3d_wait_client;
+ gdrv->base.API.WaitNative = egl_g3d_wait_native;
+ gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
+
+ gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image;
+ gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image;
+
+#ifdef EGL_MESA_screen_surface
+ gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
+ gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
+#endif
+
+ gdrv->base.Name = driver_name;
+ gdrv->base.Probe = egl_g3d_probe;
+ gdrv->base.Unload = egl_g3d_unload;
+
+ /* the key is " EGL G3D" */
+ gdrv->probe_key = 0x0E61063D;
+
+ return &gdrv->base;
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
new file mode 100644
index 0000000000..5d2d9c481a
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -0,0 +1,94 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _EGL_G3D_H_
+#define _EGL_G3D_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_format.h"
+#include "egldriver.h"
+#include "egldisplay.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+#include "eglconfig.h"
+#include "eglscreen.h"
+#include "eglmode.h"
+
+#include "native.h"
+#include "egl_st.h"
+
+struct egl_g3d_driver {
+ _EGLDriver base;
+ const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
+ EGLint api_mask;
+
+ EGLint probe_key;
+};
+
+struct egl_g3d_display {
+ struct native_display *native;
+};
+
+struct egl_g3d_buffer {
+ struct st_framebuffer *st_fb;
+ uint attachment_mask;
+};
+
+struct egl_g3d_context {
+ _EGLContext base;
+
+ const struct egl_g3d_st *stapi;
+ struct pipe_context *pipe;
+
+ struct st_context *st_ctx;
+ EGLBoolean force_validate;
+ struct egl_g3d_buffer draw, read;
+};
+
+struct egl_g3d_surface {
+ _EGLSurface base;
+ struct native_surface *native;
+ enum native_attachment render_att;
+ struct pipe_surface *render_surface;
+ unsigned int sequence_number;
+};
+
+struct egl_g3d_config {
+ _EGLConfig base;
+ const struct native_config *native;
+};
+
+struct egl_g3d_screen {
+ _EGLScreen base;
+ const struct native_connector *native;
+ const struct native_mode **native_modes;
+};
+
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
+_EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
+
+#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c
new file mode 100644
index 0000000000..a88ff911cd
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_st.c
@@ -0,0 +1,131 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <dlfcn.h>
+#include "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "egllog.h"
+#include "EGL/egl.h" /* for EGL_api_BIT */
+
+#include "egl_st.h"
+
+#ifndef HAVE_DLADDR
+#define HAVE_DLADDR 1
+#endif
+
+#if HAVE_DLADDR
+
+static const char *
+egl_g3d_st_names[] = {
+#define ST_PUBLIC(name, ...) #name,
+#include "st_public_tmp.h"
+ NULL
+};
+
+static boolean
+egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
+{
+ st_proc *procs = (st_proc *) stapi;
+ void *handle;
+ Dl_info info;
+ const char **name;
+
+ if (!dladdr(sym, &info))
+ return FALSE;
+ handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
+ if (!handle)
+ return FALSE;
+
+ for (name = egl_g3d_st_names; *name; name++) {
+ st_proc proc = (st_proc) dlsym(handle, *name);
+ if (!proc) {
+ _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
+ memset(stapi, 0, sizeof(*stapi));
+ dlclose(handle);
+ return FALSE;
+ }
+ *procs++ = proc;
+ }
+
+ dlclose(handle);
+ return TRUE;
+}
+
+#else /* HAVE_DLADDR */
+
+static boolean
+egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
+{
+#define ST_PUBLIC(name, ...) stapi->name = name;
+#include "st_public_tmp.h"
+ return TRUE;
+}
+
+#endif /* HAVE_DLADDR */
+
+static boolean
+egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
+{
+ void *handle, *sym;
+ boolean res = FALSE;
+
+ /* already initialized */
+ if (stapi->st_notify_swapbuffers != NULL)
+ return TRUE;
+
+ handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
+ if (!handle)
+ return FALSE;
+
+ sym = dlsym(handle, api);
+ if (sym && egl_g3d_fill_st(stapi, sym))
+ res = TRUE;
+
+ dlclose(handle);
+ return res;
+}
+
+static struct {
+ const char *symbol;
+ EGLint api_bit;
+} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
+ { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
+ { "st_api_OpenVG", EGL_OPENVG_BIT },
+ { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
+ { "st_api_OpenGL", EGL_OPENGL_BIT },
+};
+
+const struct egl_g3d_st *
+egl_g3d_get_st(enum egl_g3d_st_api api)
+{
+ static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
+
+ if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
+ all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
+ return &all_trackers[api];
+ }
+ else {
+ return NULL;
+ }
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h
new file mode 100644
index 0000000000..8fb464bd3d
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_st.h
@@ -0,0 +1,73 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _EGL_ST_H_
+#define _EGL_ST_H_
+
+#include "GL/gl.h" /* for GL types */
+#include "GL/internal/glcore.h" /* for __GLcontextModes */
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+
+/* avoid calling st functions directly */
+#if 1
+
+#define ST_SURFACE_FRONT_LEFT 0
+#define ST_SURFACE_BACK_LEFT 1
+#define ST_SURFACE_FRONT_RIGHT 2
+#define ST_SURFACE_BACK_RIGHT 3
+
+#define ST_TEXTURE_2D 0x2
+
+struct st_context;
+struct st_framebuffer;
+typedef void (*st_proc)();
+
+#else
+#include "state_tracker/st_public.h"
+#endif
+
+/* remember to update egl_g3d_get_st() when update the enums */
+enum egl_g3d_st_api {
+ EGL_G3D_ST_OPENGL_ES = 0,
+ EGL_G3D_ST_OPENVG,
+ EGL_G3D_ST_OPENGL_ES2,
+ EGL_G3D_ST_OPENGL,
+
+ NUM_EGL_G3D_STS
+};
+
+struct egl_g3d_st {
+#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
+#include "st_public_tmp.h"
+ /* fields must be added here */
+ EGLint api_bit;
+};
+
+const struct egl_g3d_st *
+egl_g3d_get_st(enum egl_g3d_st_api api);
+
+#endif /* _EGL_ST_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
new file mode 100644
index 0000000000..4f9758545a
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -0,0 +1,272 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _NATIVE_H_
+#define _NATIVE_H_
+
+#include "EGL/egl.h" /* for EGL native types */
+#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
+#include "GL/internal/glcore.h" /* for __GLcontextModes */
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+/**
+ * Only color buffers are listed. The others are allocated privately through,
+ * for example, st_renderbuffer_alloc_storage().
+ */
+enum native_attachment {
+ NATIVE_ATTACHMENT_FRONT_LEFT,
+ NATIVE_ATTACHMENT_BACK_LEFT,
+ NATIVE_ATTACHMENT_FRONT_RIGHT,
+ NATIVE_ATTACHMENT_BACK_RIGHT,
+
+ NUM_NATIVE_ATTACHMENTS
+};
+
+/**
+ * Enumerations for probe results.
+ */
+enum native_probe_result {
+ NATIVE_PROBE_UNKNOWN,
+ NATIVE_PROBE_FALLBACK,
+ NATIVE_PROBE_SUPPORTED,
+ NATIVE_PROBE_EXACT,
+};
+
+/**
+ * A probe object for display probe.
+ */
+struct native_probe {
+ int magic;
+ EGLNativeDisplayType display;
+ void *data;
+
+ void (*destroy)(struct native_probe *nprobe);
+};
+
+struct native_surface {
+ void (*destroy)(struct native_surface *nsurf);
+
+ /**
+ * Swap the front and back buffers so that the back buffer is visible. It
+ * is no-op if the surface is single-buffered. The contents of the back
+ * buffer after swapping may or may not be preserved.
+ */
+ boolean (*swap_buffers)(struct native_surface *nsurf);
+
+ /**
+ * Make the front buffer visible. In some native displays, changes to the
+ * front buffer might not be visible immediately and require manual flush.
+ */
+ boolean (*flush_frontbuffer)(struct native_surface *nsurf);
+
+ /**
+ * Validate the buffers of the surface. textures, if not NULL, points to an
+ * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned
+ * by the caller. A sequence number is also returned. The caller can use
+ * it to check if anything has changed since the last call. Any of the
+ * pointers may be NULL and it indicates the caller has no interest in those
+ * values.
+ *
+ * If this function is called multiple times with different attachment
+ * masks, those not listed in the latest call might be destroyed. This
+ * behavior might change in the future.
+ */
+ boolean (*validate)(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height);
+
+ /**
+ * Wait until all native commands affecting the surface has been executed.
+ */
+ void (*wait)(struct native_surface *nsurf);
+};
+
+struct native_config {
+ /* __GLcontextModes should go away some day */
+ __GLcontextModes mode;
+ enum pipe_format color_format;
+ enum pipe_format depth_format;
+ enum pipe_format stencil_format;
+
+ /* treat it as an additional flag to mode.drawableType */
+ boolean scanout_bit;
+};
+
+struct native_connector {
+ int dummy;
+};
+
+struct native_mode {
+ const char *desc;
+ int width, height;
+ int refresh_rate;
+};
+
+struct native_display_modeset;
+
+/**
+ * A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis
+ * hardware. A native display consists of a pipe winsys, a pipe screen, and
+ * the native display server.
+ */
+struct native_display {
+ /**
+ * The pipe screen of the native display.
+ *
+ * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be
+ * overridden.
+ */
+ struct pipe_screen *screen;
+
+ void (*destroy)(struct native_display *ndpy);
+
+ /**
+ * Get the supported configs. The configs are owned by the display, but
+ * the returned array should be free()ed.
+ *
+ * The configs will be converted to EGL config by
+ * _eglConfigFromContextModesRec and validated by _eglValidateConfig.
+ * Those failing to pass the test will be skipped.
+ */
+ const struct native_config **(*get_configs)(struct native_display *ndpy,
+ int *num_configs);
+
+ /**
+ * Test if a pixmap is supported by the given config. Required unless no
+ * config has GLX_PIXMAP_BIT set.
+ *
+ * This function is usually called to find a config that supports a given
+ * pixmap. Thus, it is usually called with the same pixmap in a row.
+ */
+ boolean (*is_pixmap_supported)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf);
+
+
+ /**
+ * Create a window surface. Required unless no config has GLX_WINDOW_BIT
+ * set.
+ */
+ struct native_surface *(*create_window_surface)(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf);
+
+ /**
+ * Create a pixmap surface. Required unless no config has GLX_PIXMAP_BIT
+ * set.
+ */
+ struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf);
+
+ /**
+ * Create a pbuffer surface. Required unless no config has GLX_PBUFFER_BIT
+ * set.
+ */
+ struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height);
+
+ const struct native_display_modeset *modeset;
+};
+
+/**
+ * Mode setting interface of the native display. It exposes the mode setting
+ * capabilities of the underlying graphics hardware.
+ */
+struct native_display_modeset {
+ /**
+ * Get the available physical connectors and the number of CRTCs.
+ */
+ const struct native_connector **(*get_connectors)(struct native_display *ndpy,
+ int *num_connectors,
+ int *num_crtcs);
+
+ /**
+ * Get the current supported modes of a connector. The returned modes may
+ * change every time this function is called and those from previous calls
+ * might become invalid.
+ */
+ const struct native_mode **(*get_modes)(struct native_display *ndpy,
+ const struct native_connector *nconn,
+ int *num_modes);
+
+ /**
+ * Create a scan-out surface. Required unless no config has
+ * GLX_SCREEN_BIT_MESA set.
+ */
+ struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height);
+
+ /**
+ * Program the CRTC to output the surface to the given connectors with the
+ * given mode. When surface is not given, the CRTC is disabled.
+ *
+ * This interface does not export a way to query capabilities of the CRTCs.
+ * The native display usually needs to dynamically map the index to a CRTC
+ * that supports the given connectors.
+ */
+ boolean (*program)(struct native_display *ndpy, int crtc_idx,
+ struct native_surface *nsurf, uint x, uint y,
+ const struct native_connector **nconns, int num_nconns,
+ const struct native_mode *nmode);
+};
+
+/**
+ * Test whether an attachment is set in the mask.
+ */
+static INLINE boolean
+native_attachment_mask_test(uint mask, enum native_attachment att)
+{
+ return !!(mask & (1 << att));
+}
+
+/**
+ * Return a probe object for the given display.
+ *
+ * Note that the returned object may be cached and used by different native
+ * display modules. It allows fast probing when multiple modules probe the
+ * same display.
+ */
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy);
+
+/**
+ * Probe the probe object.
+ */
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe);
+
+const char *
+native_get_name(void);
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy);
+
+#endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
new file mode 100644
index 0000000000..507a0ec402
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h
@@ -0,0 +1,20 @@
+ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
+ST_PUBLIC(st_destroy_context, void, struct st_context *st)
+ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask)
+ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
+ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height)
+ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
+ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height)
+ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
+ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
+ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
+ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
+ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read)
+ST_PUBLIC(st_get_current, struct st_context *, void)
+ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
+ST_PUBLIC(st_finish, void, struct st_context *st)
+ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb)
+ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format)
+ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level)
+ST_PUBLIC(st_get_proc_address, st_proc, const char *procname)
+#undef ST_PUBLIC
diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c
deleted file mode 100644
index fee186c601..0000000000
--- a/src/gallium/state_trackers/egl/egl_context.c
+++ /dev/null
@@ -1,105 +0,0 @@
-
-#include "utils.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-
-#include "state_tracker/st_public.h"
-#include "state_tracker/drm_api.h"
-
-#include "GL/internal/glcore.h"
-
-_EGLContext *
-drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_context *ctx;
- struct drm_context *share = NULL;
- struct st_context *st_share = NULL;
- int i;
- __GLcontextModes *visual;
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- /* no attribs defined for now */
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
- }
-
- ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
- if (!ctx)
- goto err_c;
-
- _eglInitContext(drv, &ctx->base, conf, attrib_list);
-
- ctx->pipe = dev->api->create_context(dev->api, dev->screen);
- if (!ctx->pipe)
- goto err_pipe;
-
- if (share)
- st_share = share->st;
-
- visual = drm_visual_from_config(conf);
- ctx->st = st_create_context(ctx->pipe, visual, st_share);
- drm_visual_modes_destroy(visual);
-
- if (!ctx->st)
- goto err_gl;
-
- return &ctx->base;
-
-err_gl:
- ctx->pipe->destroy(ctx->pipe);
-err_pipe:
- free(ctx);
-err_c:
- return NULL;
-}
-
-EGLBoolean
-drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
-{
- struct drm_context *c = lookup_drm_context(context);
- if (!_eglIsContextBound(&c->base)) {
- st_destroy_context(c->st);
- free(c);
- }
- return EGL_TRUE;
-}
-
-EGLBoolean
-drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context)
-{
- struct drm_surface *readSurf = lookup_drm_surface(read);
- struct drm_surface *drawSurf = lookup_drm_surface(draw);
- struct drm_context *ctx = lookup_drm_context(context);
- EGLBoolean b;
-
- b = _eglMakeCurrent(drv, dpy, draw, read, context);
- if (!b)
- return EGL_FALSE;
-
- if (ctx) {
- if (!drawSurf || !readSurf)
- return EGL_FALSE;
-
- st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
-
- /* st_resize_framebuffer needs a bound context to work */
- st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
- st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
- } else {
- st_make_current(NULL, NULL, NULL);
- }
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
deleted file mode 100644
index d55aa51b82..0000000000
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ /dev/null
@@ -1,443 +0,0 @@
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-#include "pipe/p_inlines.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_context.h"
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_format.h"
-#include "util/u_rect.h"
-
-/*
- * Util functions
- */
-
-static drmModeModeInfoPtr
-drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
-{
- int i;
- drmModeModeInfoPtr m = NULL;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
- break;
- m = &connector->modes[0]; /* if we can't find one, return first */
- }
-
- return m;
-}
-
-static struct st_framebuffer *
-drm_create_framebuffer(struct pipe_screen *screen,
- const __GLcontextModes *visual,
- unsigned width,
- unsigned height,
- void *priv)
-{
- enum pipe_format color_format, depth_stencil_format;
- boolean d_depth_bits_last;
- boolean ds_depth_bits_last;
-
- d_depth_bits_last =
- screen->is_format_supported(screen, PIPE_FORMAT_X8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- ds_depth_bits_last =
- screen->is_format_supported(screen, PIPE_FORMAT_S8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-
- if (visual->redBits == 8) {
- if (visual->alphaBits == 8)
- color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
- else
- color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
- } else {
- color_format = PIPE_FORMAT_R5G6B5_UNORM;
- }
-
- switch(visual->depthBits) {
- default:
- case 0:
- depth_stencil_format = PIPE_FORMAT_NONE;
- break;
- case 16:
- depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
- break;
- case 24:
- if (visual->stencilBits == 0) {
- depth_stencil_format = (d_depth_bits_last) ?
- PIPE_FORMAT_X8Z24_UNORM:
- PIPE_FORMAT_Z24X8_UNORM;
- } else {
- depth_stencil_format = (ds_depth_bits_last) ?
- PIPE_FORMAT_S8Z24_UNORM:
- PIPE_FORMAT_Z24S8_UNORM;
- }
- break;
- case 32:
- depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- break;
- }
-
- return st_create_framebuffer(visual,
- color_format,
- depth_stencil_format,
- depth_stencil_format,
- width,
- height,
- priv);
-}
-
-static void
-drm_create_texture(_EGLDisplay *dpy,
- struct drm_screen *scrn,
- unsigned w, unsigned h)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct pipe_screen *screen = dev->screen;
- struct pipe_surface *surface;
- struct pipe_texture *texture;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
- unsigned pitch = 0;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth0 = 1;
- templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
- templat.width0 = w;
- templat.height0 = h;
-
- texture = screen->texture_create(dev->screen,
- &templat);
-
- if (!texture)
- goto err_tex;
-
- surface = screen->get_tex_surface(screen,
- texture,
- 0,
- 0,
- 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- if (!surface)
- goto err_surf;
-
- scrn->tex = texture;
- scrn->surface = surface;
- scrn->front.width = w;
- scrn->front.height = h;
- scrn->front.pitch = pitch;
- dev->api->local_handle_from_texture(dev->api, screen, texture,
- &scrn->front.pitch, &scrn->front.handle);
- if (0)
- goto err_handle;
-
- return;
-
-err_handle:
- pipe_surface_reference(&surface, NULL);
-err_surf:
- pipe_texture_reference(&texture, NULL);
-err_tex:
- pipe_buffer_reference(&buf, NULL);
- return;
-}
-
-/*
- * Exported functions
- */
-
-void
-drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
-
- screen->surf = NULL;
-
- drmModeSetCrtc(
- dev->drmFD,
- screen->crtcID,
- 0, /* FD */
- 0, 0,
- NULL, 0, /* List of output ids */
- NULL);
-
- drmModeRmFB(dev->drmFD, screen->fbID);
- drmModeFreeFB(screen->fb);
- screen->fb = NULL;
-
- pipe_surface_reference(&screen->surface, NULL);
- pipe_texture_reference(&screen->tex, NULL);
-
- screen->shown = 0;
-}
-
-/**
- * Called by libEGL's eglCreateWindowSurface().
- */
-_EGLSurface *
-drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Called by libEGL's eglCreatePixmapSurface().
- */
-_EGLSurface *
-drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-/**
- * Called by libEGL's eglCreatePbufferSurface().
- */
-_EGLSurface *
-drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- int i;
- int width = -1;
- int height = -1;
- struct drm_surface *surf = NULL;
- __GLcontextModes *visual;
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- width = attrib_list[++i];
- break;
- case EGL_HEIGHT:
- height = attrib_list[++i];
- break;
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
- }
-
- if (width < 1 || height < 1) {
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return NULL;
- }
-
- surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
- if (!surf)
- goto err;
-
- if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list))
- goto err_surf;
-
- surf->w = width;
- surf->h = height;
-
- visual = drm_visual_from_config(conf);
- surf->stfb = drm_create_framebuffer(dev->screen, visual,
- width, height,
- (void*)surf);
- drm_visual_modes_destroy(visual);
-
- return &surf->base;
-
-err_surf:
- free(surf);
-err:
- return NULL;
-}
-
-/**
- * Called by libEGL's eglCreateScreenSurfaceMESA().
- */
-_EGLSurface *
-drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg,
- const EGLint *attrib_list)
-{
- EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
-
- return surf;
-}
-
-/**
- * Called by libEGL's eglShowScreenSurfaceMESA().
- */
-EGLBoolean
-drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLScreen *screen,
- _EGLSurface *surface, _EGLMode *mode)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_surface *surf = lookup_drm_surface(surface);
- struct drm_screen *scrn = lookup_drm_screen(screen);
- int ret;
- unsigned int i, k;
-
- if (scrn->shown)
- drm_takedown_shown_screen(dpy, scrn);
-
-
- drm_create_texture(dpy, scrn, mode->Width, mode->Height);
- if (!scrn->tex)
- goto err_tex;
-
- ret = drmModeAddFB(dev->drmFD,
- scrn->front.width, scrn->front.height,
- 32, 32, scrn->front.pitch,
- scrn->front.handle,
- &scrn->fbID);
-
- if (ret)
- goto err_bo;
-
- scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID);
- if (!scrn->fb)
- goto err_bo;
-
- /* find a fitting crtc */
- {
- drmModeConnector *con = scrn->connector;
-
- scrn->mode = drm_find_mode(con, mode);
- if (!scrn->mode)
- goto err_fb;
-
- for (k = 0; k < con->count_encoders; k++) {
- drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]);
- for (i = 0; i < dev->res->count_crtcs; i++) {
- if (enc->possible_crtcs & (1<<i)) {
- /* save the ID */
- scrn->crtcID = dev->res->crtcs[i];
-
- /* skip the rest */
- i = dev->res->count_crtcs;
- k = dev->res->count_encoders;
- }
- }
- drmModeFreeEncoder(enc);
- }
- }
-
- ret = drmModeSetCrtc(dev->drmFD,
- scrn->crtcID,
- scrn->fbID,
- 0, 0,
- &scrn->connectorID, 1,
- scrn->mode);
-
- if (ret)
- goto err_crtc;
-
-
- if (scrn->dpms)
- drmModeConnectorSetProperty(dev->drmFD,
- scrn->connectorID,
- scrn->dpms->prop_id,
- DRM_MODE_DPMS_ON);
-
- surf->screen = scrn;
-
- scrn->surf = surf;
- scrn->shown = 1;
-
- return EGL_TRUE;
-
-err_crtc:
- scrn->crtcID = 0;
-
-err_fb:
- drmModeRmFB(dev->drmFD, scrn->fbID);
- drmModeFreeFB(scrn->fb);
- scrn->fb = NULL;
-
-err_bo:
- pipe_surface_reference(&scrn->surface, NULL);
- pipe_texture_reference(&scrn->tex, NULL);
-
-err_tex:
- return EGL_FALSE;
-}
-
-/**
- * Called by libEGL's eglDestroySurface().
- */
-EGLBoolean
-drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
-{
- struct drm_surface *surf = lookup_drm_surface(surface);
- if (!_eglIsSurfaceBound(&surf->base)) {
- if (surf->screen)
- drm_takedown_shown_screen(dpy, surf->screen);
- st_unreference_framebuffer(surf->stfb);
- free(surf);
- }
- return EGL_TRUE;
-}
-
-/**
- * Called by libEGL's eglSwapBuffers().
- */
-EGLBoolean
-drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_surface *surf = lookup_drm_surface(draw);
- struct pipe_surface *back_surf;
-
- if (!surf)
- return EGL_FALSE;
-
- st_get_framebuffer_surface(surf->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
-
- if (back_surf) {
- struct drm_context *ctx = lookup_drm_context(draw->Binding);
-
- st_notify_swapbuffers(surf->stfb);
-
- if (ctx && surf->screen) {
- if (ctx->pipe->surface_copy) {
- ctx->pipe->surface_copy(ctx->pipe,
- surf->screen->surface,
- 0, 0,
- back_surf,
- 0, 0,
- surf->w, surf->h);
- } else {
- util_surface_copy(ctx->pipe, FALSE,
- surf->screen->surface,
- 0, 0,
- back_surf,
- 0, 0,
- surf->w, surf->h);
- }
- ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
-
-#ifdef DRM_MODE_FEATURE_DIRTYFB
- /* TODO query connector property to see if this is needed */
- drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0);
-#else
- (void)dev;
-#endif
-
- /* TODO more stuff here */
- }
- }
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
deleted file mode 100644
index 9345b0f490..0000000000
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ /dev/null
@@ -1,274 +0,0 @@
-
-#include "utils.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "egl_tracker.h"
-
-#include <fcntl.h>
-
-#include "egllog.h"
-#include "state_tracker/drm_api.h"
-
-#include "pipe/p_screen.h"
-#include "pipe/internal/p_winsys_screen.h"
-
-/** HACK */
-void* driDriverAPI;
-
-
-/*
- * Exported functions
- */
-
-/** Called by libEGL just prior to unloading/closing the driver.
- */
-static void
-drm_unload(_EGLDriver *drv)
-{
- free(drv);
-}
-
-/**
- * The bootstrap function. Return a new drm_driver object and
- * plug in API functions.
- * libEGL finds this function with dlopen()/dlsym() and calls it from
- * "load driver" function.
- */
-_EGLDriver *
-_eglMain(const char *args)
-{
- _EGLDriver *drv;
-
- drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver));
- if (!drv) {
- return NULL;
- }
-
- /* First fill in the dispatch table with defaults */
- _eglInitDriverFallbacks(drv);
- /* then plug in our Drm-specific functions */
- drv->API.Initialize = drm_initialize;
- drv->API.Terminate = drm_terminate;
- drv->API.CreateContext = drm_create_context;
- drv->API.MakeCurrent = drm_make_current;
- drv->API.CreateWindowSurface = drm_create_window_surface;
- drv->API.CreatePixmapSurface = drm_create_pixmap_surface;
- drv->API.CreatePbufferSurface = drm_create_pbuffer_surface;
- drv->API.DestroySurface = drm_destroy_surface;
- drv->API.DestroyContext = drm_destroy_context;
- drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
- drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
- drv->API.SwapBuffers = drm_swap_buffers;
-
- drv->Name = "DRM/Gallium/Win";
- drv->Unload = drm_unload;
-
- return drv;
-}
-
-static void
-drm_get_device_id(struct drm_device *device)
-{
- char path[512];
- FILE *file;
- char *ret;
-
- /* TODO get the real minor */
- int minor = 0;
-
- device->deviceID = 0;
-
- snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
- file = fopen(path, "r");
- if (!file) {
- _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
- return;
- }
-
- ret = fgets(path, sizeof( path ), file);
- fclose(file);
- if (!ret)
- return;
-
- sscanf(path, "%x", &device->deviceID);
-}
-
-static void
-drm_update_res(struct drm_device *dev)
-{
- drmModeFreeResources(dev->res);
- dev->res = drmModeGetResources(dev->drmFD);
-}
-
-static void
-drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
-{
- drmModeModeInfoPtr m = NULL;
- int i;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
- }
-}
-
-static void
-drm_find_dpms(struct drm_device *dev, struct drm_screen *screen)
-{
- drmModeConnectorPtr c = screen->connector;
- drmModePropertyPtr p;
- int i;
-
- for (i = 0; i < c->count_props; i++) {
- p = drmModeGetProperty(dev->drmFD, c->props[i]);
- if (!strcmp(p->name, "DPMS"))
- break;
-
- drmModeFreeProperty(p);
- p = NULL;
- }
-
- screen->dpms = p;
-}
-
-static int drm_open_minor(int minor)
-{
- char buf[64];
-
- sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
- return open(buf, O_RDWR, 0);
-}
-
-EGLBoolean
-drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
-{
- struct drm_device *dev;
- struct drm_screen *screen = NULL;
- drmModeConnectorPtr connector = NULL;
- drmModeResPtr res = NULL;
- unsigned count_connectors = 0;
- int num_screens = 0;
- EGLint i;
- int fd;
- _EGLConfig *config;
-
- dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
- if (!dev)
- return EGL_FALSE;
- dev->api = drm_api_create();
-
- /* try the first node */
- fd = drm_open_minor(0);
- if (fd < 0)
- goto err_fd;
-
- dev->drmFD = fd;
- drm_get_device_id(dev);
-
- dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL);
- if (!dev->screen)
- goto err_screen;
- dev->winsys = dev->screen->winsys;
-
- driInitExtensions(NULL, NULL, GL_FALSE);
-
- drm_update_res(dev);
- res = dev->res;
- if (res)
- count_connectors = res->count_connectors;
- else
- _eglLog(_EGL_WARNING, "Could not retrive kms information\n");
-
- for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
- connector = drmModeGetConnector(fd, res->connectors[i]);
-
- if (!connector)
- continue;
-
- if (connector->connection != DRM_MODE_CONNECTED) {
- drmModeFreeConnector(connector);
- continue;
- }
-
- screen = malloc(sizeof(struct drm_screen));
- memset(screen, 0, sizeof(*screen));
- screen->connector = connector;
- screen->connectorID = connector->connector_id;
- _eglInitScreen(&screen->base);
- _eglAddScreen(disp, &screen->base);
- drm_add_modes_from_connector(&screen->base, connector);
- drm_find_dpms(dev, screen);
- dev->screens[num_screens++] = screen;
- }
- dev->count_screens = num_screens;
-
- disp->DriverData = dev;
-
- /* for now we only have one config */
- config = calloc(1, sizeof(*config));
- memset(config, 1, sizeof(*config));
- _eglInitConfig(config, 1);
- _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
- _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
- _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
- _eglAddConfig(disp, config);
-
- disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
- /* enable supported extensions */
- disp->Extensions.MESA_screen_surface = EGL_TRUE;
- disp->Extensions.MESA_copy_context = EGL_TRUE;
-
- *major = 1;
- *minor = 4;
-
- return EGL_TRUE;
-
-err_screen:
- drmClose(fd);
-err_fd:
- free(dev);
- return EGL_FALSE;
-}
-
-EGLBoolean
-drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- struct drm_device *dev = lookup_drm_device(dpy);
- struct drm_screen *screen;
- int i = 0;
-
- _eglReleaseDisplayResources(drv, dpy);
- _eglCleanupDisplay(dpy);
-
- drmFreeVersion(dev->version);
-
- for (i = 0; i < dev->count_screens; i++) {
- screen = dev->screens[i];
-
- if (screen->shown)
- drm_takedown_shown_screen(dpy, screen);
-
- drmModeFreeProperty(screen->dpms);
- drmModeFreeConnector(screen->connector);
- _eglDestroyScreen(&screen->base);
- dev->screens[i] = NULL;
- }
-
- dev->screen->destroy(dev->screen);
- dev->winsys = NULL;
-
- drmClose(dev->drmFD);
-
- dev->api->destroy(dev->api);
- free(dev);
- dpy->DriverData = NULL;
-
- return EGL_TRUE;
-}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h
deleted file mode 100644
index 73eb1a1226..0000000000
--- a/src/gallium/state_trackers/egl/egl_tracker.h
+++ /dev/null
@@ -1,195 +0,0 @@
-
-#ifndef _EGL_TRACKER_H_
-#define _EGL_TRACKER_H_
-
-#include <stdint.h>
-
-#include "eglconfig.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglglobals.h"
-#include "eglmode.h"
-#include "eglscreen.h"
-#include "eglsurface.h"
-
-#include "xf86drm.h"
-#include "xf86drmMode.h"
-
-#include "pipe/p_compiler.h"
-
-#include "state_tracker/st_public.h"
-
-#define MAX_SCREENS 16
-
-struct pipe_winsys;
-struct pipe_screen;
-struct pipe_context;
-struct state_tracker;
-
-struct drm_screen;
-struct drm_context;
-
-struct drm_device
-{
- /*
- * pipe
- */
-
- struct drm_api *api;
- struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- /*
- * drm
- */
-
- int drmFD;
- drmVersionPtr version;
- int deviceID;
-
- drmModeResPtr res;
-
- struct drm_screen *screens[MAX_SCREENS];
- size_t count_screens;
-};
-
-struct drm_surface
-{
- _EGLSurface base; /* base class/object */
-
- /*
- * pipe
- */
-
-
- struct st_framebuffer *stfb;
-
- /*
- * drm
- */
-
- struct drm_screen *screen;
-
- int w;
- int h;
-};
-
-struct drm_context
-{
- _EGLContext base; /* base class/object */
-
- /* pipe */
-
- struct pipe_context *pipe;
- struct st_context *st;
-};
-
-struct drm_screen
-{
- _EGLScreen base;
-
- /*
- * pipe
- */
-
- struct pipe_texture *tex;
- struct pipe_surface *surface;
-
- /*
- * drm
- */
-
- struct {
- unsigned height;
- unsigned width;
- unsigned pitch;
- unsigned handle;
- } front;
-
- /* currently only support one connector */
- drmModeConnectorPtr connector;
- uint32_t connectorID;
-
- /* dpms property */
- drmModePropertyPtr dpms;
-
- /* Has this screen been shown */
- int shown;
-
- /* Surface that is currently attached to this screen */
- struct drm_surface *surf;
-
- /* framebuffer */
- drmModeFBPtr fb;
- uint32_t fbID;
-
- /* crtc and mode used */
- /*drmModeCrtcPtr crtc;*/
- uint32_t crtcID;
-
- drmModeModeInfoPtr mode;
-};
-
-
-static INLINE struct drm_device *
-lookup_drm_device(_EGLDisplay *d)
-{
- return (struct drm_device *) d->DriverData;
-}
-
-
-static INLINE struct drm_context *
-lookup_drm_context(_EGLContext *c)
-{
- return (struct drm_context *) c;
-}
-
-
-static INLINE struct drm_surface *
-lookup_drm_surface(_EGLSurface *s)
-{
- return (struct drm_surface *) s;
-}
-
-static INLINE struct drm_screen *
-lookup_drm_screen(_EGLScreen *s)
-{
- return (struct drm_screen *) s;
-}
-
-/**
- * egl_visual.h
- */
-/*@{*/
-void drm_visual_modes_destroy(__GLcontextModes *modes);
-__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size);
-__GLcontextModes* drm_visual_from_config(_EGLConfig *conf);
-/*@}*/
-
-/**
- * egl_surface.h
- */
-/*@{*/
-void drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen);
-/*@}*/
-
-/**
- * All function exported to the egl side.
- */
-/*@{*/
-EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
-EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy);
-_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
-EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context);
-_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
-_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
-_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
-EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
-EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
-EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context);
-EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
-/*@}*/
-
-#endif
diff --git a/src/gallium/state_trackers/egl/egl_visual.c b/src/gallium/state_trackers/egl/egl_visual.c
deleted file mode 100644
index e59f893851..0000000000
--- a/src/gallium/state_trackers/egl/egl_visual.c
+++ /dev/null
@@ -1,85 +0,0 @@
-
-#include "egl_tracker.h"
-
-#include "egllog.h"
-
-void
-drm_visual_modes_destroy(__GLcontextModes *modes)
-{
- _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
-
- while (modes) {
- __GLcontextModes * const next = modes->next;
- free(modes);
- modes = next;
- }
-}
-
-__GLcontextModes *
-drm_visual_modes_create(unsigned count, size_t minimum_size)
-{
- /* This code copied from libGLX, and modified */
- const size_t size = (minimum_size > sizeof(__GLcontextModes))
- ? minimum_size : sizeof(__GLcontextModes);
- __GLcontextModes * head = NULL;
- __GLcontextModes ** next;
- unsigned i;
-
- _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
-
- next = & head;
- for (i = 0 ; i < count ; i++) {
- *next = (__GLcontextModes *) calloc(1, size);
- if (*next == NULL) {
- drm_visual_modes_destroy(head);
- head = NULL;
- break;
- }
-
- (*next)->doubleBufferMode = 1;
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = 0;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = & ((*next)->next);
- }
-
- return head;
-}
-
-__GLcontextModes *
-drm_visual_from_config(_EGLConfig *conf)
-{
- __GLcontextModes *visual;
- (void)conf;
-
- visual = drm_visual_modes_create(1, sizeof(*visual));
- visual->redBits = 8;
- visual->greenBits = 8;
- visual->blueBits = 8;
- visual->alphaBits = 8;
-
- visual->rgbBits = 32;
- visual->doubleBufferMode = 1;
-
- visual->depthBits = 24;
- visual->haveDepthBuffer = visual->depthBits > 0;
- visual->stencilBits = 8;
- visual->haveStencilBuffer = visual->stencilBits > 0;
-
- return visual;
-}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
new file mode 100644
index 0000000000..91cefc538d
--- /dev/null
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -0,0 +1,856 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "egllog.h"
+
+#include "native_kms.h"
+
+static boolean
+kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
+{
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ struct kms_display *kdpy = ksurf->kdpy;
+ struct pipe_screen *screen = kdpy->base.screen;
+ struct pipe_texture templ, *ptex;
+ int att;
+
+ if (attachment_mask) {
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = ksurf->width;
+ templ.height0 = ksurf->height;
+ templ.depth0 = 1;
+ templ.format = ksurf->color_format;
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ }
+
+ /* create textures */
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
+
+ ptex = ksurf->textures[att];
+ if (!ptex) {
+ ptex = screen->texture_create(screen, &templ);
+ ksurf->textures[att] = ptex;
+ }
+
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], ptex);
+ }
+ }
+
+ if (seq_num)
+ *seq_num = ksurf->sequence_number;
+ if (width)
+ *width = ksurf->width;
+ if (height)
+ *height = ksurf->height;
+
+ return TRUE;
+}
+
+/**
+ * Add textures as DRM framebuffers.
+ */
+static boolean
+kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
+{
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ struct kms_display *kdpy = ksurf->kdpy;
+ int num_framebuffers = (need_back) ? 2 : 1;
+ int i, err;
+
+ for (i = 0; i < num_framebuffers; i++) {
+ struct kms_framebuffer *fb;
+ enum native_attachment natt;
+ unsigned int handle, stride;
+ uint block_bits;
+
+ if (i == 0) {
+ fb = &ksurf->front_fb;
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ }
+ else {
+ fb = &ksurf->back_fb;
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ }
+
+ if (!fb->texture) {
+ /* make sure the texture has been allocated */
+ kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL);
+ if (!ksurf->textures[natt])
+ return FALSE;
+
+ pipe_texture_reference(&fb->texture, ksurf->textures[natt]);
+ }
+
+ /* already initialized */
+ if (fb->buffer_id)
+ continue;
+
+ /* TODO detect the real value */
+ fb->is_passive = TRUE;
+
+ if (!kdpy->api->local_handle_from_texture(kdpy->api,
+ kdpy->base.screen, fb->texture, &stride, &handle))
+ return FALSE;
+
+ block_bits = util_format_get_blocksizebits(ksurf->color_format);
+ err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
+ block_bits, block_bits, stride, handle, &fb->buffer_id);
+ if (err) {
+ fb->buffer_id = 0;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static boolean
+kms_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ struct kms_display *kdpy = ksurf->kdpy;
+
+ /* pbuffer is private */
+ if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ if (ksurf->front_fb.is_passive)
+ drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0);
+#endif
+
+ return TRUE;
+}
+
+static boolean
+kms_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ struct kms_crtc *kcrtc = &ksurf->current_crtc;
+ struct kms_display *kdpy = ksurf->kdpy;
+ struct kms_framebuffer tmp_fb;
+ struct pipe_texture *tmp_texture;
+ int err;
+
+ /* pbuffer is private */
+ if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ if (!ksurf->back_fb.buffer_id) {
+ if (!kms_surface_init_framebuffers(&ksurf->base, TRUE))
+ return FALSE;
+ }
+
+ if (ksurf->is_shown && kcrtc->crtc) {
+ err = drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
+ ksurf->back_fb.buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
+ kcrtc->connectors, kcrtc->num_connectors, &kcrtc->crtc->mode);
+ if (err)
+ return FALSE;
+ }
+
+ /* swap the buffers */
+ tmp_fb = ksurf->front_fb;
+ ksurf->front_fb = ksurf->back_fb;
+ ksurf->back_fb = tmp_fb;
+
+ tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT];
+ ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] =
+ ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT];
+ ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture;
+
+ /* the front/back textures are swapped */
+ ksurf->sequence_number++;
+
+ return TRUE;
+}
+
+static void
+kms_surface_wait(struct native_surface *nsurf)
+{
+ /* no-op */
+}
+
+static void
+kms_surface_destroy(struct native_surface *nsurf)
+{
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ int i;
+
+ if (ksurf->current_crtc.crtc)
+ drmModeFreeCrtc(ksurf->current_crtc.crtc);
+
+ if (ksurf->front_fb.buffer_id)
+ drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id);
+ pipe_texture_reference(&ksurf->front_fb.texture, NULL);
+
+ if (ksurf->back_fb.buffer_id)
+ drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
+ pipe_texture_reference(&ksurf->back_fb.texture, NULL);
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ struct pipe_texture *ptex = ksurf->textures[i];
+ pipe_texture_reference(&ptex, NULL);
+ }
+
+ free(ksurf);
+}
+
+static struct kms_surface *
+kms_display_create_surface(struct native_display *ndpy,
+ enum kms_surface_type type,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct kms_config *kconf = kms_config(nconf);
+ struct kms_surface *ksurf;
+
+ ksurf = CALLOC_STRUCT(kms_surface);
+ if (!ksurf)
+ return NULL;
+
+ ksurf->kdpy = kdpy;
+ ksurf->type = type;
+ ksurf->color_format = kconf->base.color_format;
+ ksurf->width = width;
+ ksurf->height = height;
+
+ ksurf->base.destroy = kms_surface_destroy;
+ ksurf->base.swap_buffers = kms_surface_swap_buffers;
+ ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer;
+ ksurf->base.validate = kms_surface_validate;
+ ksurf->base.wait = kms_surface_wait;
+
+ return ksurf;
+}
+
+/**
+ * Choose a CRTC that supports all given connectors.
+ */
+static uint32_t
+kms_display_choose_crtc(struct native_display *ndpy,
+ uint32_t *connectors, int num_connectors)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ int idx;
+
+ for (idx = 0; idx < kdpy->resources->count_crtcs; idx++) {
+ boolean found_crtc = TRUE;
+ int i, j;
+
+ for (i = 0; i < num_connectors; i++) {
+ drmModeConnectorPtr connector;
+ int encoder_idx = -1;
+
+ connector = drmModeGetConnector(kdpy->fd, connectors[i]);
+ if (!connector) {
+ found_crtc = FALSE;
+ break;
+ }
+
+ /* find an encoder the CRTC supports */
+ for (j = 0; j < connector->count_encoders; j++) {
+ drmModeEncoderPtr encoder =
+ drmModeGetEncoder(kdpy->fd, connector->encoders[j]);
+ if (encoder->possible_crtcs & (1 << idx)) {
+ encoder_idx = j;
+ break;
+ }
+ drmModeFreeEncoder(encoder);
+ }
+
+ drmModeFreeConnector(connector);
+ if (encoder_idx < 0) {
+ found_crtc = FALSE;
+ break;
+ }
+ }
+
+ if (found_crtc)
+ break;
+ }
+
+ if (idx >= kdpy->resources->count_crtcs) {
+ _eglLog(_EGL_WARNING,
+ "failed to find a CRTC that supports the given %d connectors",
+ num_connectors);
+ return 0;
+ }
+
+ return kdpy->resources->crtcs[idx];
+}
+
+/**
+ * Remember the original CRTC status and set the CRTC
+ */
+static boolean
+kms_display_set_crtc(struct native_display *ndpy, int crtc_idx,
+ uint32_t buffer_id, uint32_t x, uint32_t y,
+ uint32_t *connectors, int num_connectors,
+ drmModeModeInfoPtr mode)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct kms_crtc *kcrtc = &kdpy->saved_crtcs[crtc_idx];
+ uint32_t crtc_id;
+ int err;
+
+ if (kcrtc->crtc) {
+ crtc_id = kcrtc->crtc->crtc_id;
+ }
+ else {
+ int count = 0, i;
+
+ /*
+ * Choose the CRTC once. It could be more dynamic, but let's keep it
+ * simple for now.
+ */
+ crtc_id = kms_display_choose_crtc(&kdpy->base,
+ connectors, num_connectors);
+
+ /* save the original CRTC status */
+ kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
+ if (!kcrtc->crtc)
+ return FALSE;
+
+ for (i = 0; i < kdpy->num_connectors; i++) {
+ struct kms_connector *kconn = &kdpy->connectors[i];
+ drmModeConnectorPtr connector = kconn->connector;
+ drmModeEncoderPtr encoder;
+
+ encoder = drmModeGetEncoder(kdpy->fd, connector->encoder_id);
+ if (encoder) {
+ if (encoder->crtc_id == crtc_id) {
+ kcrtc->connectors[count++] = connector->connector_id;
+ if (count >= Elements(kcrtc->connectors))
+ break;
+ }
+ drmModeFreeEncoder(encoder);
+ }
+ }
+
+ kcrtc->num_connectors = count;
+ }
+
+ err = drmModeSetCrtc(kdpy->fd, crtc_id, buffer_id, x, y,
+ connectors, num_connectors, mode);
+ if (err) {
+ drmModeFreeCrtc(kcrtc->crtc);
+ kcrtc->crtc = NULL;
+ kcrtc->num_connectors = 0;
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static boolean
+kms_display_program(struct native_display *ndpy, int crtc_idx,
+ struct native_surface *nsurf, uint x, uint y,
+ const struct native_connector **nconns, int num_nconns,
+ const struct native_mode *nmode)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct kms_surface *ksurf = kms_surface(nsurf);
+ const struct kms_mode *kmode = kms_mode(nmode);
+ uint32_t connector_ids[32];
+ uint32_t buffer_id;
+ drmModeModeInfo mode_tmp, *mode;
+ int i;
+
+ if (num_nconns > Elements(connector_ids)) {
+ _eglLog(_EGL_WARNING, "too many connectors (%d)", num_nconns);
+ num_nconns = Elements(connector_ids);
+ }
+
+ if (ksurf) {
+ if (!kms_surface_init_framebuffers(&ksurf->base, FALSE))
+ return FALSE;
+
+ buffer_id = ksurf->front_fb.buffer_id;
+ /* the mode argument of drmModeSetCrtc is not constified */
+ mode_tmp = kmode->mode;
+ mode = &mode_tmp;
+ }
+ else {
+ /* disable the CRTC */
+ buffer_id = 0;
+ mode = NULL;
+ num_nconns = 0;
+ }
+
+ for (i = 0; i < num_nconns; i++) {
+ struct kms_connector *kconn = kms_connector(nconns[i]);
+ connector_ids[i] = kconn->connector->connector_id;
+ }
+
+ if (!kms_display_set_crtc(&kdpy->base, crtc_idx, buffer_id, x, y,
+ connector_ids, num_nconns, mode)) {
+ _eglLog(_EGL_WARNING, "failed to set CRTC %d", crtc_idx);
+
+ return FALSE;
+ }
+
+ if (kdpy->shown_surfaces[crtc_idx])
+ kdpy->shown_surfaces[crtc_idx]->is_shown = FALSE;
+ kdpy->shown_surfaces[crtc_idx] = ksurf;
+
+ /* remember the settings for buffer swapping */
+ if (ksurf) {
+ uint32_t crtc_id = kdpy->saved_crtcs[crtc_idx].crtc->crtc_id;
+ struct kms_crtc *kcrtc = &ksurf->current_crtc;
+
+ if (kcrtc->crtc)
+ drmModeFreeCrtc(kcrtc->crtc);
+ kcrtc->crtc = drmModeGetCrtc(kdpy->fd, crtc_id);
+
+ assert(num_nconns < Elements(kcrtc->connectors));
+ memcpy(kcrtc->connectors, connector_ids,
+ sizeof(*connector_ids) * num_nconns);
+ kcrtc->num_connectors = num_nconns;
+
+ ksurf->is_shown = TRUE;
+ }
+
+ return TRUE;
+}
+
+static const struct native_mode **
+kms_display_get_modes(struct native_display *ndpy,
+ const struct native_connector *nconn,
+ int *num_modes)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct kms_connector *kconn = kms_connector(nconn);
+ const struct native_mode **nmodes_return;
+ int count, i;
+
+ /* delete old data */
+ if (kconn->connector) {
+ drmModeFreeConnector(kconn->connector);
+ free(kconn->kms_modes);
+
+ kconn->connector = NULL;
+ kconn->kms_modes = NULL;
+ kconn->num_modes = 0;
+ }
+
+ /* detect again */
+ kconn->connector = drmModeGetConnector(kdpy->fd, kconn->connector_id);
+ if (!kconn->connector)
+ return NULL;
+
+ count = kconn->connector->count_modes;
+ kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes));
+ if (!kconn->kms_modes) {
+ drmModeFreeConnector(kconn->connector);
+ kconn->connector = NULL;
+
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct kms_mode *kmode = &kconn->kms_modes[i];
+ drmModeModeInfoPtr mode = &kconn->connector->modes[i];
+
+ kmode->mode = *mode;
+
+ kmode->base.desc = kmode->mode.name;
+ kmode->base.width = kmode->mode.hdisplay;
+ kmode->base.height = kmode->mode.vdisplay;
+ kmode->base.refresh_rate = kmode->mode.vrefresh / 1000;
+ }
+
+ nmodes_return = malloc(count * sizeof(*nmodes_return));
+ if (nmodes_return) {
+ for (i = 0; i < count; i++)
+ nmodes_return[i] = &kconn->kms_modes[i].base;
+ if (num_modes)
+ *num_modes = count;
+ }
+
+ return nmodes_return;
+}
+
+static const struct native_connector **
+kms_display_get_connectors(struct native_display *ndpy, int *num_connectors,
+ int *num_crtc)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ const struct native_connector **connectors;
+ int i;
+
+ if (!kdpy->connectors) {
+ kdpy->connectors =
+ calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors));
+ if (!kdpy->connectors)
+ return NULL;
+
+ for (i = 0; i < kdpy->resources->count_connectors; i++) {
+ struct kms_connector *kconn = &kdpy->connectors[i];
+
+ kconn->connector_id = kdpy->resources->connectors[i];
+ /* kconn->connector is allocated when the modes are asked */
+ }
+
+ kdpy->num_connectors = kdpy->resources->count_connectors;
+ }
+
+ connectors = malloc(kdpy->num_connectors * sizeof(*connectors));
+ if (connectors) {
+ for (i = 0; i < kdpy->num_connectors; i++)
+ connectors[i] = &kdpy->connectors[i].base;
+ if (num_connectors)
+ *num_connectors = kdpy->num_connectors;
+ }
+
+ if (num_crtc)
+ *num_crtc = kdpy->resources->count_crtcs;
+
+ return connectors;
+}
+
+static struct native_surface *
+kms_display_create_scanout_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ struct kms_surface *ksurf;
+
+ ksurf = kms_display_create_surface(ndpy,
+ KMS_SURFACE_TYPE_SCANOUT, nconf, width, height);
+ return &ksurf->base;
+}
+
+static struct native_surface *
+kms_display_create_pbuffer_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ struct kms_surface *ksurf;
+
+ ksurf = kms_display_create_surface(ndpy,
+ KMS_SURFACE_TYPE_PBUFFER, nconf, width, height);
+ return &ksurf->base;
+}
+
+
+static boolean
+kms_display_is_format_supported(struct native_display *ndpy,
+ enum pipe_format fmt, boolean is_color)
+{
+ return ndpy->screen->is_format_supported(ndpy->screen,
+ fmt, PIPE_TEXTURE_2D,
+ (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+}
+
+static const struct native_config **
+kms_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ const struct native_config **configs;
+
+ /* first time */
+ if (!kdpy->config) {
+ struct native_config *nconf;
+ enum pipe_format format;
+
+ kdpy->config = calloc(1, sizeof(*kdpy->config));
+ if (!kdpy->config)
+ return NULL;
+
+ nconf = &kdpy->config->base;
+
+ /* always double-buffered */
+ nconf->mode.doubleBufferMode = TRUE;
+
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) {
+ format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ if (!kms_display_is_format_supported(&kdpy->base, format, TRUE))
+ format = PIPE_FORMAT_NONE;
+ }
+ if (format == PIPE_FORMAT_NONE)
+ return NULL;
+
+ nconf->color_format = format;
+ nconf->mode.redBits = 8;
+ nconf->mode.greenBits = 8;
+ nconf->mode.blueBits = 8;
+ nconf->mode.alphaBits = 8;
+ nconf->mode.rgbBits = 32;
+
+ format = PIPE_FORMAT_S8Z24_UNORM;
+ if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) {
+ format = PIPE_FORMAT_Z24S8_UNORM;
+ if (!kms_display_is_format_supported(&kdpy->base, format, FALSE))
+ format = PIPE_FORMAT_NONE;
+ }
+ if (format != PIPE_FORMAT_NONE) {
+ nconf->depth_format = format;
+ nconf->stencil_format = format;
+
+ nconf->mode.depthBits = 24;
+ nconf->mode.stencilBits = 8;
+ nconf->mode.haveDepthBuffer = TRUE;
+ nconf->mode.haveStencilBuffer = TRUE;
+ }
+
+ nconf->scanout_bit = TRUE;
+ nconf->mode.drawableType = GLX_PBUFFER_BIT;
+ nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML;
+
+ nconf->mode.visualID = 0;
+ nconf->mode.visualType = EGL_NONE;
+
+ nconf->mode.renderType = GLX_RGBA_BIT;
+ nconf->mode.rgbMode = TRUE;
+ nconf->mode.xRenderable = FALSE;
+ }
+
+ configs = malloc(sizeof(*configs));
+ if (configs) {
+ configs[0] = &kdpy->config->base;
+ if (num_configs)
+ *num_configs = 1;
+ }
+
+ return configs;
+}
+
+static void
+kms_display_destroy(struct native_display *ndpy)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ int i;
+
+ if (kdpy->config)
+ free(kdpy->config);
+
+ if (kdpy->connectors) {
+ for (i = 0; i < kdpy->num_connectors; i++) {
+ struct kms_connector *kconn = &kdpy->connectors[i];
+ if (kconn->connector) {
+ drmModeFreeConnector(kconn->connector);
+ free(kconn->kms_modes);
+ }
+ }
+ free(kdpy->connectors);
+ }
+
+ if (kdpy->shown_surfaces)
+ free(kdpy->shown_surfaces);
+
+ if (kdpy->saved_crtcs) {
+ for (i = 0; i < kdpy->resources->count_crtcs; i++) {
+ struct kms_crtc *kcrtc = &kdpy->saved_crtcs[i];
+
+ if (kcrtc->crtc) {
+ /* restore crtc */
+ drmModeSetCrtc(kdpy->fd, kcrtc->crtc->crtc_id,
+ kcrtc->crtc->buffer_id, kcrtc->crtc->x, kcrtc->crtc->y,
+ kcrtc->connectors, kcrtc->num_connectors,
+ &kcrtc->crtc->mode);
+
+ drmModeFreeCrtc(kcrtc->crtc);
+ }
+ }
+ free(kdpy->saved_crtcs);
+ }
+
+ if (kdpy->resources)
+ drmModeFreeResources(kdpy->resources);
+
+ if (kdpy->base.screen)
+ kdpy->base.screen->destroy(kdpy->base.screen);
+
+ if (kdpy->fd >= 0)
+ drmClose(kdpy->fd);
+
+ if (kdpy->api)
+ kdpy->api->destroy(kdpy->api);
+ free(kdpy);
+}
+
+/**
+ * Initialize KMS and pipe screen.
+ */
+static boolean
+kms_display_init_screen(struct native_display *ndpy)
+{
+ struct kms_display *kdpy = kms_display(ndpy);
+ struct drm_create_screen_arg arg;
+ int fd;
+
+ fd = drmOpen(kdpy->api->name, NULL);
+ if (fd < 0) {
+ _eglLog(_EGL_WARNING, "failed to open DRM device");
+ return FALSE;
+ }
+
+#if 0
+ if (drmSetMaster(fd)) {
+ _eglLog(_EGL_WARNING, "failed to become DRM master");
+ return FALSE;
+ }
+#endif
+
+ memset(&arg, 0, sizeof(arg));
+ arg.mode = DRM_CREATE_NORMAL;
+ kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg);
+ if (!kdpy->base.screen) {
+ _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ drmClose(fd);
+ return FALSE;
+ }
+
+ kdpy->fd = fd;
+
+ return TRUE;
+}
+
+static struct native_display_modeset kms_display_modeset = {
+ .get_connectors = kms_display_get_connectors,
+ .get_modes = kms_display_get_modes,
+ .create_scanout_surface = kms_display_create_scanout_surface,
+ .program = kms_display_program
+};
+
+static struct native_display *
+kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
+{
+ struct kms_display *kdpy;
+
+ kdpy = CALLOC_STRUCT(kms_display);
+ if (!kdpy)
+ return NULL;
+
+ kdpy->api = api;
+ if (!kdpy->api) {
+ _eglLog(_EGL_WARNING, "failed to create DRM API");
+ free(kdpy);
+ return NULL;
+ }
+
+ kdpy->fd = -1;
+ if (!kms_display_init_screen(&kdpy->base)) {
+ kms_display_destroy(&kdpy->base);
+ return NULL;
+ }
+
+ /* resources are fixed, unlike crtc, connector, or encoder */
+ kdpy->resources = drmModeGetResources(kdpy->fd);
+ if (!kdpy->resources) {
+ kms_display_destroy(&kdpy->base);
+ return NULL;
+ }
+
+ kdpy->saved_crtcs =
+ calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs));
+ if (!kdpy->saved_crtcs) {
+ kms_display_destroy(&kdpy->base);
+ return NULL;
+ }
+
+ kdpy->shown_surfaces =
+ calloc(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces));
+ if (!kdpy->shown_surfaces) {
+ kms_display_destroy(&kdpy->base);
+ return NULL;
+ }
+
+ kdpy->base.destroy = kms_display_destroy;
+ kdpy->base.get_configs = kms_display_get_configs;
+ kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface;
+
+ kdpy->base.modeset = &kms_display_modeset;
+
+ return &kdpy->base;
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ return NULL;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ return NATIVE_PROBE_UNKNOWN;
+}
+
+/* the api is destroyed with the native display */
+static struct drm_api *drm_api;
+
+const char *
+native_get_name(void)
+{
+ static char kms_name[32];
+
+ if (!drm_api)
+ drm_api = drm_api_create();
+
+ if (drm_api)
+ snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
+ else
+ snprintf(kms_name, sizeof(kms_name), "KMS");
+
+ return kms_name;
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy)
+{
+ struct native_display *ndpy = NULL;
+
+ if (!drm_api)
+ drm_api = drm_api_create();
+
+ if (drm_api)
+ ndpy = kms_create_display(dpy, drm_api);
+
+ return ndpy;
+}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
new file mode 100644
index 0000000000..095186e3cf
--- /dev/null
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -0,0 +1,139 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _NATIVE_KMS_H_
+#define _NATIVE_KMS_H_
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_format.h"
+#include "pipe/p_state.h"
+#include "state_tracker/drm_api.h"
+
+#include "common/native.h"
+
+enum kms_surface_type {
+ KMS_SURFACE_TYPE_PBUFFER,
+ KMS_SURFACE_TYPE_SCANOUT
+};
+
+struct kms_config;
+struct kms_connector;
+struct kms_mode;
+
+struct kms_crtc {
+ drmModeCrtcPtr crtc;
+ uint32_t connectors[32];
+ int num_connectors;
+};
+
+struct kms_display {
+ struct native_display base;
+
+ int fd;
+ struct drm_api *api;
+ drmModeResPtr resources;
+ struct kms_config *config;
+
+ struct kms_connector *connectors;
+ int num_connectors;
+
+ struct kms_surface **shown_surfaces;
+ /* save the original settings of the CRTCs */
+ struct kms_crtc *saved_crtcs;
+};
+
+struct kms_framebuffer {
+ struct pipe_texture *texture;
+ boolean is_passive;
+
+ uint32_t buffer_id;
+};
+
+struct kms_surface {
+ struct native_surface base;
+ enum kms_surface_type type;
+ enum pipe_format color_format;
+ struct kms_display *kdpy;
+ int width, height;
+
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
+ struct kms_framebuffer front_fb, back_fb;
+
+ boolean is_shown;
+ struct kms_crtc current_crtc;
+};
+
+struct kms_config {
+ struct native_config base;
+};
+
+struct kms_connector {
+ struct native_connector base;
+
+ uint32_t connector_id;
+ drmModeConnectorPtr connector;
+ struct kms_mode *kms_modes;
+ int num_modes;
+};
+
+struct kms_mode {
+ struct native_mode base;
+ drmModeModeInfo mode;
+};
+
+static INLINE struct kms_display *
+kms_display(const struct native_display *ndpy)
+{
+ return (struct kms_display *) ndpy;
+}
+
+static INLINE struct kms_surface *
+kms_surface(const struct native_surface *nsurf)
+{
+ return (struct kms_surface *) nsurf;
+}
+
+static INLINE struct kms_config *
+kms_config(const struct native_config *nconf)
+{
+ return (struct kms_config *) nconf;
+}
+
+static INLINE struct kms_connector *
+kms_connector(const struct native_connector *nconn)
+{
+ return (struct kms_connector *) nconn;
+}
+
+static INLINE struct kms_mode *
+kms_mode(const struct native_mode *nmode)
+{
+ return (struct kms_mode *) nmode;
+}
+
+#endif /* _NATIVE_KMS_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c
new file mode 100644
index 0000000000..1ed2afd345
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/glxinit.c
@@ -0,0 +1,682 @@
+/**
+ * GLX initialization. Code based on glxext.c, glx_query.c, and
+ * glcontextmodes.c under src/glx/. The major difference is that DRI
+ * related code is stripped out.
+ *
+ * If the maintenance of this file takes too much time, we should consider
+ * refactoring glxext.c.
+ */
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <sys/time.h>
+
+#include "glxinit.h"
+
+typedef struct GLXGenericGetString
+{
+ CARD8 reqType;
+ CARD8 glxCode;
+ CARD16 length B16;
+ CARD32 for_whom B32;
+ CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+/* Extension required boiler plate */
+
+static char *__glXExtensionName = GLX_EXTENSION_NAME;
+static XExtensionInfo *__glXExtensionInfo = NULL;
+
+static int
+__glXCloseDisplay(Display * dpy, XExtCodes * codes)
+{
+ return XextRemoveDisplay(__glXExtensionInfo, dpy);
+}
+
+static /* const */ XExtensionHooks __glXExtensionHooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ __glXCloseDisplay, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
+ __glXExtensionName, &__glXExtensionHooks,
+ __GLX_NUMBER_EVENTS, NULL)
+
+static GLint
+_gl_convert_from_x_visual_type(int visualType)
+{
+#define NUM_VISUAL_TYPES 6
+ static const int glx_visual_types[NUM_VISUAL_TYPES] = {
+ GLX_STATIC_GRAY, GLX_GRAY_SCALE,
+ GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+ GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+ };
+
+ return ((unsigned) visualType < NUM_VISUAL_TYPES)
+ ? glx_visual_types[visualType] : GLX_NONE;
+}
+
+static __GLcontextModes *
+_gl_context_modes_create(unsigned count, size_t minimum_size)
+{
+ const size_t size = (minimum_size > sizeof(__GLcontextModes))
+ ? minimum_size : sizeof(__GLcontextModes);
+ __GLcontextModes *base = NULL;
+ __GLcontextModes **next;
+ unsigned i;
+
+ next = &base;
+ for (i = 0; i < count; i++) {
+ *next = (__GLcontextModes *) Xmalloc(size);
+ if (*next == NULL) {
+ _gl_context_modes_destroy(base);
+ base = NULL;
+ break;
+ }
+
+ memset(*next, 0, size);
+ (*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 = GLX_DONT_CARE;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = &((*next)->next);
+ }
+
+ return base;
+}
+
+_X_HIDDEN void
+_gl_context_modes_destroy(__GLcontextModes * modes)
+{
+ while (modes != NULL) {
+ __GLcontextModes *const next = modes->next;
+
+ Xfree(modes);
+ modes = next;
+ }
+}
+
+_X_HIDDEN char *
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
+{
+ xGLXGenericGetStringReq *req;
+ xGLXSingleReply reply;
+ int length;
+ int numbytes;
+ char *buf;
+ CARD32 for_whom = screen;
+ CARD32 glxCode = X_GLXQueryServerString;
+
+
+ LockDisplay(dpy);
+
+
+ /* All of the GLX protocol requests for getting a string from the server
+ * look the same. The exact meaning of the for_whom field is usually
+ * either the screen number (for glXQueryServerString) or the context tag
+ * (for GLXSingle).
+ */
+
+ GetReq(GLXGenericGetString, req);
+ req->reqType = opcode;
+ req->glxCode = glxCode;
+ req->for_whom = for_whom;
+ req->name = name;
+
+ _XReply(dpy, (xReply *) & reply, 0, False);
+
+ length = reply.length * 4;
+ numbytes = reply.size;
+
+ buf = (char *) Xmalloc(numbytes);
+ if (buf != NULL) {
+ _XRead(dpy, buf, numbytes);
+ length -= numbytes;
+ }
+
+ _XEatData(dpy, length);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buf;
+}
+
+/************************************************************************/
+/*
+** Free the per screen configs data as well as the array of
+** __glXScreenConfigs.
+*/
+static void
+FreeScreenConfigs(__GLXdisplayPrivate * priv)
+{
+ __GLXscreenConfigs *psc;
+ GLint i, screens;
+
+ /* Free screen configuration information */
+ psc = priv->screenConfigs;
+ screens = ScreenCount(priv->dpy);
+ for (i = 0; i < screens; i++, psc++) {
+ if (psc->configs) {
+ _gl_context_modes_destroy(psc->configs);
+ psc->configs = NULL; /* NOTE: just for paranoia */
+ }
+ if (psc->visuals) {
+ _gl_context_modes_destroy(psc->visuals);
+ psc->visuals = NULL; /* NOTE: just for paranoia */
+ }
+ Xfree((char *) psc->serverGLXexts);
+ }
+ XFree((char *) priv->screenConfigs);
+ priv->screenConfigs = NULL;
+}
+
+/*
+** Release the private memory referred to in a display private
+** structure. The caller will free the extension structure.
+*/
+static int
+__glXFreeDisplayPrivate(XExtData * extension)
+{
+ __GLXdisplayPrivate *priv;
+
+ priv = (__GLXdisplayPrivate *) extension->private_data;
+ FreeScreenConfigs(priv);
+ if (priv->serverGLXvendor) {
+ Xfree((char *) priv->serverGLXvendor);
+ priv->serverGLXvendor = 0x0; /* to protect against double free's */
+ }
+ if (priv->serverGLXversion) {
+ Xfree((char *) priv->serverGLXversion);
+ priv->serverGLXversion = 0x0; /* to protect against double free's */
+ }
+
+ Xfree((char *) priv);
+ return 0;
+}
+
+/************************************************************************/
+
+/*
+** Query the version of the GLX extension. This procedure works even if
+** the client extension is not completely set up.
+*/
+static Bool
+QueryVersion(Display * dpy, int opcode, int *major, int *minor)
+{
+ xGLXQueryVersionReq *req;
+ xGLXQueryVersionReply reply;
+
+ /* Send the glXQueryVersion request */
+ LockDisplay(dpy);
+ GetReq(GLXQueryVersion, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXQueryVersion;
+ req->majorVersion = GLX_MAJOR_VERSION;
+ req->minorVersion = GLX_MINOR_VERSION;
+ _XReply(dpy, (xReply *) & reply, 0, False);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (reply.majorVersion != GLX_MAJOR_VERSION) {
+ /*
+ ** The server does not support the same major release as this
+ ** client.
+ */
+ return GL_FALSE;
+ }
+ *major = reply.majorVersion;
+ *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
+ return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
+ const INT32 * bp, Bool tagged_only,
+ Bool fbconfig_style_tags)
+{
+ int i;
+
+ if (!tagged_only) {
+ /* Copy in the first set of properties */
+ config->visualID = *bp++;
+
+ config->visualType = _gl_convert_from_x_visual_type(*bp++);
+
+ config->rgbMode = *bp++;
+
+ config->redBits = *bp++;
+ config->greenBits = *bp++;
+ config->blueBits = *bp++;
+ config->alphaBits = *bp++;
+ config->accumRedBits = *bp++;
+ config->accumGreenBits = *bp++;
+ config->accumBlueBits = *bp++;
+ config->accumAlphaBits = *bp++;
+
+ config->doubleBufferMode = *bp++;
+ config->stereoMode = *bp++;
+
+ config->rgbBits = *bp++;
+ config->depthBits = *bp++;
+ config->stencilBits = *bp++;
+ config->numAuxBuffers = *bp++;
+ config->level = *bp++;
+
+ count -= __GLX_MIN_CONFIG_PROPS;
+ }
+
+ /*
+ ** Additional properties may be in a list at the end
+ ** of the reply. They are in pairs of property type
+ ** and property value.
+ */
+
+#define FETCH_OR_SET(tag) \
+ config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
+
+ for (i = 0; i < count; i += 2) {
+ switch (*bp++) {
+ case GLX_RGBA:
+ FETCH_OR_SET(rgbMode);
+ break;
+ case GLX_BUFFER_SIZE:
+ config->rgbBits = *bp++;
+ break;
+ case GLX_LEVEL:
+ config->level = *bp++;
+ break;
+ case GLX_DOUBLEBUFFER:
+ FETCH_OR_SET(doubleBufferMode);
+ break;
+ case GLX_STEREO:
+ FETCH_OR_SET(stereoMode);
+ break;
+ case GLX_AUX_BUFFERS:
+ config->numAuxBuffers = *bp++;
+ break;
+ case GLX_RED_SIZE:
+ config->redBits = *bp++;
+ break;
+ case GLX_GREEN_SIZE:
+ config->greenBits = *bp++;
+ break;
+ case GLX_BLUE_SIZE:
+ config->blueBits = *bp++;
+ break;
+ case GLX_ALPHA_SIZE:
+ config->alphaBits = *bp++;
+ break;
+ case GLX_DEPTH_SIZE:
+ config->depthBits = *bp++;
+ break;
+ case GLX_STENCIL_SIZE:
+ config->stencilBits = *bp++;
+ break;
+ case GLX_ACCUM_RED_SIZE:
+ config->accumRedBits = *bp++;
+ break;
+ case GLX_ACCUM_GREEN_SIZE:
+ config->accumGreenBits = *bp++;
+ break;
+ case GLX_ACCUM_BLUE_SIZE:
+ config->accumBlueBits = *bp++;
+ break;
+ case GLX_ACCUM_ALPHA_SIZE:
+ config->accumAlphaBits = *bp++;
+ break;
+ case GLX_VISUAL_CAVEAT_EXT:
+ config->visualRating = *bp++;
+ break;
+ case GLX_X_VISUAL_TYPE:
+ config->visualType = *bp++;
+ break;
+ case GLX_TRANSPARENT_TYPE:
+ config->transparentPixel = *bp++;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE:
+ config->transparentIndex = *bp++;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE:
+ config->transparentRed = *bp++;
+ break;
+ case GLX_TRANSPARENT_GREEN_VALUE:
+ config->transparentGreen = *bp++;
+ break;
+ case GLX_TRANSPARENT_BLUE_VALUE:
+ config->transparentBlue = *bp++;
+ break;
+ case GLX_TRANSPARENT_ALPHA_VALUE:
+ config->transparentAlpha = *bp++;
+ break;
+ case GLX_VISUAL_ID:
+ config->visualID = *bp++;
+ break;
+ case GLX_DRAWABLE_TYPE:
+ config->drawableType = *bp++;
+ break;
+ case GLX_RENDER_TYPE:
+ config->renderType = *bp++;
+ break;
+ case GLX_X_RENDERABLE:
+ config->xRenderable = *bp++;
+ break;
+ case GLX_FBCONFIG_ID:
+ config->fbconfigID = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_WIDTH:
+ config->maxPbufferWidth = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_HEIGHT:
+ config->maxPbufferHeight = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_PIXELS:
+ config->maxPbufferPixels = *bp++;
+ break;
+ case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+ config->optimalPbufferWidth = *bp++;
+ break;
+ case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+ config->optimalPbufferHeight = *bp++;
+ break;
+ case GLX_VISUAL_SELECT_GROUP_SGIX:
+ config->visualSelectGroup = *bp++;
+ break;
+ case GLX_SWAP_METHOD_OML:
+ config->swapMethod = *bp++;
+ break;
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ config->sampleBuffers = *bp++;
+ break;
+ case GLX_SAMPLES_SGIS:
+ config->samples = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ config->bindToTextureRgb = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ config->bindToTextureRgba = *bp++;
+ break;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ config->bindToMipmapTexture = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ config->bindToTextureTargets = *bp++;
+ break;
+ case GLX_Y_INVERTED_EXT:
+ config->yInverted = *bp++;
+ break;
+ case None:
+ i = count;
+ break;
+ default:
+ break;
+ }
+ }
+
+ config->renderType =
+ (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+
+ config->haveAccumBuffer = ((config->accumRedBits +
+ config->accumGreenBits +
+ config->accumBlueBits +
+ config->accumAlphaBits) > 0);
+ config->haveDepthBuffer = (config->depthBits > 0);
+ config->haveStencilBuffer = (config->stencilBits > 0);
+}
+
+static __GLcontextModes *
+createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
+ int screen, GLboolean tagged_only)
+{
+ INT32 buf[__GLX_TOTAL_CONFIG], *props;
+ unsigned prop_size;
+ __GLcontextModes *modes, *m;
+ int i;
+
+ if (nprops == 0)
+ return NULL;
+
+ /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
+
+ /* Check number of properties */
+ if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+ return NULL;
+
+ /* Allocate memory for our config structure */
+ modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+ if (!modes)
+ return NULL;
+
+ prop_size = nprops * __GLX_SIZE_INT32;
+ if (prop_size <= sizeof(buf))
+ props = buf;
+ else
+ props = Xmalloc(prop_size);
+
+ /* Read each config structure and convert it into our format */
+ m = modes;
+ for (i = 0; i < nvisuals; i++) {
+ _XRead(dpy, (char *) props, prop_size);
+ /* Older X servers don't send this so we default it here. */
+ m->drawableType = GLX_WINDOW_BIT;
+ __glXInitializeVisualConfigFromTags(m, nprops, props,
+ tagged_only, GL_TRUE);
+ m->screen = screen;
+ m = m->next;
+ }
+
+ if (props != buf)
+ Xfree(props);
+
+ return modes;
+}
+
+static GLboolean
+getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+ xGLXGetVisualConfigsReq *req;
+ __GLXscreenConfigs *psc;
+ xGLXGetVisualConfigsReply reply;
+
+ LockDisplay(dpy);
+
+ psc = priv->screenConfigs + screen;
+ psc->visuals = NULL;
+ GetReq(GLXGetVisualConfigs, req);
+ req->reqType = priv->majorOpcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = screen;
+
+ if (!_XReply(dpy, (xReply *) & reply, 0, False))
+ goto out;
+
+ psc->visuals = createConfigsFromProperties(dpy,
+ reply.numVisuals,
+ reply.numProps,
+ screen, GL_FALSE);
+
+ out:
+ UnlockDisplay(dpy);
+ return psc->visuals != NULL;
+}
+
+static GLboolean
+getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+ xGLXGetFBConfigsReq *fb_req;
+ xGLXGetFBConfigsSGIXReq *sgi_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXGetFBConfigsReply reply;
+ __GLXscreenConfigs *psc;
+
+ psc = priv->screenConfigs + screen;
+ psc->serverGLXexts =
+ __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+
+ LockDisplay(dpy);
+
+ psc->configs = NULL;
+ if (atof(priv->serverGLXversion) >= 1.3) {
+ GetReq(GLXGetFBConfigs, fb_req);
+ fb_req->reqType = priv->majorOpcode;
+ fb_req->glxCode = X_GLXGetFBConfigs;
+ fb_req->screen = screen;
+ }
+ else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXGetFBConfigsSGIXReq +
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+ sgi_req->reqType = priv->majorOpcode;
+ sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+ sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+ sgi_req->screen = screen;
+ }
+ else
+ goto out;
+
+ if (!_XReply(dpy, (xReply *) & reply, 0, False))
+ goto out;
+
+ psc->configs = createConfigsFromProperties(dpy,
+ reply.numFBConfigs,
+ reply.numAttribs * 2,
+ screen, GL_TRUE);
+
+ out:
+ UnlockDisplay(dpy);
+ return psc->configs != NULL;
+}
+
+static GLboolean
+AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+{
+ __GLXscreenConfigs *psc;
+ GLint i, screens;
+
+ /*
+ ** First allocate memory for the array of per screen configs.
+ */
+ screens = ScreenCount(dpy);
+ psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
+ if (!psc) {
+ return GL_FALSE;
+ }
+ memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
+ priv->screenConfigs = psc;
+
+ priv->serverGLXversion =
+ __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
+ if (priv->serverGLXversion == NULL) {
+ FreeScreenConfigs(priv);
+ return GL_FALSE;
+ }
+
+ for (i = 0; i < screens; i++, psc++) {
+ getFBConfigs(dpy, priv, i);
+ getVisualConfigs(dpy, priv, i);
+ psc->scr = i;
+ psc->dpy = dpy;
+ }
+
+ SyncHandle();
+
+ return GL_TRUE;
+}
+
+_X_HIDDEN __GLXdisplayPrivate *
+__glXInitialize(Display * dpy)
+{
+ XExtDisplayInfo *info = __glXFindDisplay(dpy);
+ XExtData **privList, *private, *found;
+ __GLXdisplayPrivate *dpyPriv;
+ XEDataObject dataObj;
+ int major, minor;
+
+ if (!XextHasExtension(info))
+ return NULL;
+
+ /* See if a display private already exists. If so, return it */
+ dataObj.display = dpy;
+ privList = XEHeadOfExtensionList(dataObj);
+ found = XFindOnExtensionList(privList, info->codes->extension);
+ if (found)
+ return (__GLXdisplayPrivate *) found->private_data;
+
+ /* See if the versions are compatible */
+ if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
+ return NULL;
+
+ /*
+ ** Allocate memory for all the pieces needed for this buffer.
+ */
+ private = (XExtData *) Xmalloc(sizeof(XExtData));
+ if (!private)
+ return NULL;
+ dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
+ if (!dpyPriv) {
+ Xfree(private);
+ return NULL;
+ }
+
+ /*
+ ** Init the display private and then read in the screen config
+ ** structures from the server.
+ */
+ dpyPriv->majorOpcode = info->codes->major_opcode;
+ dpyPriv->majorVersion = major;
+ dpyPriv->minorVersion = minor;
+ dpyPriv->dpy = dpy;
+
+ dpyPriv->serverGLXvendor = NULL;
+ dpyPriv->serverGLXversion = NULL;
+
+ if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+ Xfree(dpyPriv);
+ Xfree(private);
+ return NULL;
+ }
+
+ /*
+ ** Fill in the private structure. This is the actual structure that
+ ** hangs off of the Display structure. Our private structure is
+ ** referred to by this structure. Got that?
+ */
+ private->number = info->codes->extension;
+ private->next = 0;
+ private->free_private = __glXFreeDisplayPrivate;
+ private->private_data = (char *) dpyPriv;
+ XAddToExtensionList(privList, private);
+
+ return dpyPriv;
+}
diff --git a/src/gallium/state_trackers/egl/x11/glxinit.h b/src/gallium/state_trackers/egl/x11/glxinit.h
new file mode 100644
index 0000000000..1cc7c460fe
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/glxinit.h
@@ -0,0 +1,11 @@
+#ifndef GLXINIT_INCLUDED
+#define GLXINIT_INCLUDED
+
+#include <X11/Xlib.h>
+#include "glxclient.h"
+
+/* this is used by DRI loaders */
+extern void
+_gl_context_modes_destroy(__GLcontextModes * modes);
+
+#endif /* GLXINIT_INCLUDED */
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
new file mode 100644
index 0000000000..5f2fd41260
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -0,0 +1,693 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/drm_api.h"
+#include "egllog.h"
+
+#include "native_x11.h"
+#include "x11_screen.h"
+
+enum dri2_surface_type {
+ DRI2_SURFACE_TYPE_WINDOW,
+ DRI2_SURFACE_TYPE_PIXMAP,
+ DRI2_SURFACE_TYPE_PBUFFER
+};
+
+struct dri2_display {
+ struct native_display base;
+ Display *dpy;
+ boolean own_dpy;
+
+ struct drm_api *api;
+ struct x11_screen *xscr;
+ int xscr_number;
+
+ struct dri2_config *configs;
+ int num_configs;
+};
+
+struct dri2_surface {
+ struct native_surface base;
+ Drawable drawable;
+ enum dri2_surface_type type;
+ enum pipe_format color_format;
+ struct dri2_display *dri2dpy;
+
+ struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
+ boolean have_back, have_fake;
+ int width, height;
+ unsigned int sequence_number;
+};
+
+struct dri2_config {
+ struct native_config base;
+};
+
+static INLINE struct dri2_display *
+dri2_display(const struct native_display *ndpy)
+{
+ return (struct dri2_display *) ndpy;
+}
+
+static INLINE struct dri2_surface *
+dri2_surface(const struct native_surface *nsurf)
+{
+ return (struct dri2_surface *) nsurf;
+}
+
+static INLINE struct dri2_config *
+dri2_config(const struct native_config *nconf)
+{
+ return (struct dri2_config *) nconf;
+}
+
+static boolean
+dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ /* pbuffer is private */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ /* copy to real front buffer */
+ if (dri2surf->have_fake)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+
+ return TRUE;
+}
+
+static boolean
+dri2_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ /* pbuffer is private */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ /* copy to front buffer */
+ if (dri2surf->have_back)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferBackLeft, DRI2BufferFrontLeft);
+
+ /* and update fake front buffer */
+ if (dri2surf->have_fake)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+
+ return TRUE;
+}
+
+static boolean
+dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+ unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_texture templ;
+ struct x11_drawable_buffer *xbufs;
+ int num_ins, num_outs, att, i;
+
+ if (attachment_mask) {
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+ templ.depth0 = 1;
+ templ.format = dri2surf->color_format;
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ if (textures)
+ memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS);
+ }
+
+ /* create textures for pbuffer */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
+ struct pipe_screen *screen = dri2dpy->base.screen;
+
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *ptex = dri2surf->pbuffer_textures[att];
+
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
+
+ if (!ptex) {
+ ptex = screen->texture_create(screen, &templ);
+ dri2surf->pbuffer_textures[att] = ptex;
+ }
+
+ if (textures)
+ pipe_texture_reference(&textures[att], ptex);
+ }
+
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
+ if (width)
+ *width = dri2surf->width;
+ if (height)
+ *height = dri2surf->height;
+
+ return TRUE;
+ }
+
+ /* prepare the attachments */
+ num_ins = 0;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(attachment_mask, att)) {
+ unsigned int dri2att;
+
+ switch (att) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ dri2att = DRI2BufferFrontLeft;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ dri2att = DRI2BufferBackLeft;
+ break;
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ dri2att = DRI2BufferFrontRight;
+ break;
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ dri2att = DRI2BufferBackRight;
+ break;
+ default:
+ assert(0);
+ dri2att = 0;
+ break;
+ }
+
+ dri2atts[num_ins] = dri2att;
+ num_ins++;
+ }
+ }
+
+ dri2surf->have_back = FALSE;
+ dri2surf->have_fake = FALSE;
+
+ /* remember old geometry */
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+
+ xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
+ &dri2surf->width, &dri2surf->height,
+ dri2atts, FALSE, num_ins, &num_outs);
+ if (!xbufs)
+ return FALSE;
+
+ if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) {
+ /* are there cases where the buffers change and the geometry doesn't? */
+ dri2surf->sequence_number++;
+
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+ }
+
+ for (i = 0; i < num_outs; i++) {
+ struct x11_drawable_buffer *xbuf = &xbufs[i];
+ const char *desc;
+ enum native_attachment natt;
+
+ switch (xbuf->attachment) {
+ case DRI2BufferFrontLeft:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ desc = "DRI2 Front Buffer";
+ break;
+ case DRI2BufferFakeFrontLeft:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ desc = "DRI2 Fake Front Buffer";
+ dri2surf->have_fake = TRUE;
+ break;
+ case DRI2BufferBackLeft:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ desc = "DRI2 Back Buffer";
+ dri2surf->have_back = TRUE;
+ break;
+ default:
+ desc = NULL;
+ break;
+ }
+
+ if (!desc || !native_attachment_mask_test(attachment_mask, natt) ||
+ (textures && textures[natt])) {
+ if (!desc)
+ _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
+ else if (!native_attachment_mask_test(attachment_mask, natt))
+ _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
+ else
+ _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
+ continue;
+ }
+
+ if (textures) {
+ struct pipe_texture *ptex =
+ dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
+ dri2dpy->base.screen, &templ,
+ desc, xbuf->pitch, xbuf->name);
+ if (ptex) {
+ /* the caller owns the textures */
+ textures[natt] = ptex;
+ }
+ }
+ }
+
+ free(xbufs);
+
+ if (seq_num)
+ *seq_num = dri2surf->sequence_number;
+ if (width)
+ *width = dri2surf->width;
+ if (height)
+ *height = dri2surf->height;
+
+ return TRUE;
+}
+
+static void
+dri2_surface_wait(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ if (dri2surf->have_fake) {
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ }
+}
+
+static void
+dri2_surface_destroy(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ struct pipe_texture *ptex = dri2surf->pbuffer_textures[i];
+ pipe_texture_reference(&ptex, NULL);
+ }
+
+ if (dri2surf->drawable)
+ x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
+ dri2surf->drawable, FALSE);
+ free(dri2surf);
+}
+
+static struct dri2_surface *
+dri2_display_create_surface(struct native_display *ndpy,
+ enum dri2_surface_type type,
+ Drawable drawable,
+ const struct native_config *nconf)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ struct dri2_config *dri2conf = dri2_config(nconf);
+ struct dri2_surface *dri2surf;
+
+ dri2surf = CALLOC_STRUCT(dri2_surface);
+ if (!dri2surf)
+ return NULL;
+
+ if (drawable)
+ x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
+
+ dri2surf->dri2dpy = dri2dpy;
+ dri2surf->type = type;
+ dri2surf->drawable = drawable;
+ dri2surf->color_format = dri2conf->base.color_format;
+
+ dri2surf->base.destroy = dri2_surface_destroy;
+ dri2surf->base.swap_buffers = dri2_surface_swap_buffers;
+ dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer;
+ dri2surf->base.validate = dri2_surface_validate;
+ dri2surf->base.wait = dri2_surface_wait;
+
+ return dri2surf;
+}
+
+static struct native_surface *
+dri2_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
+{
+ struct dri2_surface *dri2surf;
+
+ dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_WINDOW,
+ (Drawable) win, nconf);
+ return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static struct native_surface *
+dri2_display_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct dri2_surface *dri2surf;
+
+ dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PIXMAP,
+ (Drawable) pix, nconf);
+ return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static struct native_surface *
+dri2_display_create_pbuffer_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ struct dri2_surface *dri2surf;
+
+ dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER,
+ (Drawable) None, nconf);
+ if (dri2surf) {
+ dri2surf->width = width;
+ dri2surf->height = height;
+ }
+ return (dri2surf) ? &dri2surf->base : NULL;
+}
+
+static int
+choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
+{
+ int count = 0;
+
+ switch (mode->rgbBits) {
+ case 32:
+ formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
+ formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 24:
+ formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
+ formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
+ formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
+ formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ case 16:
+ formats[count++] = PIPE_FORMAT_R5G6B5_UNORM;
+ break;
+ default:
+ break;
+ }
+
+ return count;
+}
+
+static int
+choose_depth_stencil_format(const __GLcontextModes *mode,
+ enum pipe_format formats[32])
+{
+ int count = 0;
+
+ switch (mode->depthBits) {
+ case 32:
+ formats[count++] = PIPE_FORMAT_Z32_UNORM;
+ break;
+ case 24:
+ if (mode->stencilBits) {
+ formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
+ formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
+ }
+ else {
+ formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
+ formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
+ }
+ break;
+ case 16:
+ formats[count++] = PIPE_FORMAT_Z16_UNORM;
+ break;
+ default:
+ break;
+ }
+
+ return count;
+}
+
+static boolean
+is_format_supported(struct pipe_screen *screen,
+ enum pipe_format fmt, boolean is_color)
+{
+ return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
+ (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+}
+
+static boolean
+dri2_display_convert_config(struct native_display *ndpy,
+ const __GLcontextModes *mode,
+ struct native_config *nconf)
+{
+ enum pipe_format formats[32];
+ int num_formats, i;
+
+ if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode)
+ return FALSE;
+
+ /* skip single-buffered configs */
+ if (!mode->doubleBufferMode)
+ return FALSE;
+
+ nconf->mode = *mode;
+ nconf->mode.renderType = GLX_RGBA_BIT;
+ nconf->mode.rgbMode = TRUE;
+ /* pbuffer is allocated locally and is always supported */
+ nconf->mode.drawableType |= GLX_PBUFFER_BIT;
+ /* the swap method is always copy */
+ nconf->mode.swapMethod = GLX_SWAP_COPY_OML;
+
+ /* fix up */
+ nconf->mode.rgbBits =
+ nconf->mode.redBits + nconf->mode.greenBits +
+ nconf->mode.blueBits + nconf->mode.alphaBits;
+ if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) {
+ nconf->mode.visualID = 0;
+ nconf->mode.visualType = GLX_NONE;
+ }
+ if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) {
+ nconf->mode.bindToTextureRgb = FALSE;
+ nconf->mode.bindToTextureRgba = FALSE;
+ }
+
+ nconf->color_format = PIPE_FORMAT_NONE;
+ nconf->depth_format = PIPE_FORMAT_NONE;
+ nconf->stencil_format = PIPE_FORMAT_NONE;
+
+ /* choose color format */
+ num_formats = choose_color_format(mode, formats);
+ for (i = 0; i < num_formats; i++) {
+ if (is_format_supported(ndpy->screen, formats[i], TRUE)) {
+ nconf->color_format = formats[i];
+ break;
+ }
+ }
+ if (nconf->color_format == PIPE_FORMAT_NONE)
+ return FALSE;
+
+ /* choose depth/stencil format */
+ num_formats = choose_depth_stencil_format(mode, formats);
+ for (i = 0; i < num_formats; i++) {
+ if (is_format_supported(ndpy->screen, formats[i], FALSE)) {
+ nconf->depth_format = formats[i];
+ nconf->stencil_format = formats[i];
+ break;
+ }
+ }
+ if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) ||
+ (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE))
+ return FALSE;
+
+ return TRUE;
+}
+
+static const struct native_config **
+dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ const struct native_config **configs;
+ int i;
+
+ /* first time */
+ if (!dri2dpy->configs) {
+ const __GLcontextModes *modes;
+ int num_modes, count;
+
+ modes = x11_screen_get_glx_configs(dri2dpy->xscr);
+ if (!modes)
+ return NULL;
+ num_modes = x11_context_modes_count(modes);
+
+ dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs));
+ if (!dri2dpy->configs)
+ return NULL;
+
+ count = 0;
+ for (i = 0; i < num_modes; i++) {
+ struct native_config *nconf = &dri2dpy->configs[count].base;
+ if (dri2_display_convert_config(&dri2dpy->base, modes, nconf))
+ count++;
+ modes = modes->next;
+ }
+
+ dri2dpy->num_configs = count;
+ }
+
+ configs = malloc(dri2dpy->num_configs * sizeof(*configs));
+ if (configs) {
+ for (i = 0; i < dri2dpy->num_configs; i++)
+ configs[i] = (const struct native_config *) &dri2dpy->configs[i];
+ if (num_configs)
+ *num_configs = dri2dpy->num_configs;
+ }
+
+ return configs;
+}
+
+static boolean
+dri2_display_is_pixmap_supported(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ uint depth, nconf_depth;
+
+ depth = x11_drawable_get_depth(dri2dpy->xscr, (Drawable) pix);
+ nconf_depth = util_format_get_blocksizebits(nconf->color_format);
+
+ /* simple depth match for now */
+ return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
+}
+
+static void
+dri2_display_destroy(struct native_display *ndpy)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+
+ if (dri2dpy->configs)
+ free(dri2dpy->configs);
+
+ if (dri2dpy->base.screen)
+ dri2dpy->base.screen->destroy(dri2dpy->base.screen);
+
+ if (dri2dpy->xscr)
+ x11_screen_destroy(dri2dpy->xscr);
+ if (dri2dpy->own_dpy)
+ XCloseDisplay(dri2dpy->dpy);
+ if (dri2dpy->api && dri2dpy->api->destroy)
+ dri2dpy->api->destroy(dri2dpy->api);
+ free(dri2dpy);
+}
+
+/**
+ * Initialize DRI2 and pipe screen.
+ */
+static boolean
+dri2_display_init_screen(struct native_display *ndpy)
+{
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ const char *driver = dri2dpy->api->name;
+ struct drm_create_screen_arg arg;
+ int fd;
+
+ if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
+ !x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_GLX)) {
+ _eglLog(_EGL_WARNING, "GLX/DRI2 is not supported");
+ return FALSE;
+ }
+
+ fd = x11_screen_enable_dri2(dri2dpy->xscr, driver);
+ if (fd < 0)
+ return FALSE;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.mode = DRM_CREATE_NORMAL;
+ dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg);
+ if (!dri2dpy->base.screen) {
+ _eglLog(_EGL_WARNING, "failed to create DRM screen");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+struct native_display *
+x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
+{
+ struct dri2_display *dri2dpy;
+
+ dri2dpy = CALLOC_STRUCT(dri2_display);
+ if (!dri2dpy)
+ return NULL;
+
+ dri2dpy->api = api;
+ if (!dri2dpy->api) {
+ _eglLog(_EGL_WARNING, "failed to create DRM API");
+ free(dri2dpy);
+ return NULL;
+ }
+
+ dri2dpy->dpy = dpy;
+ if (!dri2dpy->dpy) {
+ dri2dpy->dpy = XOpenDisplay(NULL);
+ if (!dri2dpy->dpy) {
+ dri2_display_destroy(&dri2dpy->base);
+ return NULL;
+ }
+ dri2dpy->own_dpy = TRUE;
+ }
+
+ dri2dpy->xscr_number = DefaultScreen(dri2dpy->dpy);
+ dri2dpy->xscr = x11_screen_create(dri2dpy->dpy, dri2dpy->xscr_number);
+ if (!dri2dpy->xscr) {
+ dri2_display_destroy(&dri2dpy->base);
+ return NULL;
+ }
+
+ if (!dri2_display_init_screen(&dri2dpy->base)) {
+ dri2_display_destroy(&dri2dpy->base);
+ return NULL;
+ }
+
+ dri2dpy->base.destroy = dri2_display_destroy;
+ dri2dpy->base.get_configs = dri2_display_get_configs;
+ dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
+ dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
+ dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
+ dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface;
+
+ return &dri2dpy->base;
+}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
new file mode 100644
index 0000000000..8eb542bd82
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -0,0 +1,150 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "state_tracker/drm_api.h"
+#include "egllog.h"
+
+#include "native_x11.h"
+#include "x11_screen.h"
+
+#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
+
+static struct drm_api *api;
+
+static void
+x11_probe_destroy(struct native_probe *nprobe)
+{
+ if (nprobe->data)
+ free(nprobe->data);
+ free(nprobe);
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ struct native_probe *nprobe;
+ struct x11_screen *xscr;
+ int scr;
+ const char *driver_name = NULL;
+ Display *xdpy;
+
+ nprobe = CALLOC_STRUCT(native_probe);
+ if (!nprobe)
+ return NULL;
+
+ xdpy = dpy;
+ if (!xdpy) {
+ xdpy = XOpenDisplay(NULL);
+ if (!xdpy) {
+ free(nprobe);
+ return NULL;
+ }
+ }
+
+ scr = DefaultScreen(xdpy);
+ xscr = x11_screen_create(xdpy, scr);
+ if (xscr) {
+ if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
+ driver_name = x11_screen_probe_dri2(xscr);
+ if (driver_name)
+ nprobe->data = strdup(driver_name);
+ }
+
+ x11_screen_destroy(xscr);
+ }
+
+ if (xdpy != dpy)
+ XCloseDisplay(xdpy);
+
+ nprobe->magic = X11_PROBE_MAGIC;
+ nprobe->display = dpy;
+
+ nprobe->destroy = x11_probe_destroy;
+
+ return nprobe;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
+ return NATIVE_PROBE_UNKNOWN;
+
+ if (!api)
+ api = drm_api_create();
+
+ /* this is a software driver */
+ if (!api)
+ return NATIVE_PROBE_SUPPORTED;
+
+ /* the display does not support DRI2 or the driver mismatches */
+ if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
+ return NATIVE_PROBE_FALLBACK;
+
+ return NATIVE_PROBE_EXACT;
+}
+
+const char *
+native_get_name(void)
+{
+ static char x11_name[32];
+
+ if (!api)
+ api = drm_api_create();
+
+ if (api)
+ snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
+ else
+ snprintf(x11_name, sizeof(x11_name), "X11");
+
+ return x11_name;
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy)
+{
+ struct native_display *ndpy = NULL;
+ boolean force_sw;
+
+ if (!api)
+ api = drm_api_create();
+
+ force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
+ if (api && !force_sw) {
+ ndpy = x11_create_dri2_display(dpy, api);
+ }
+
+ if (!ndpy) {
+ EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
+
+ _eglLog(level, "use software fallback");
+ ndpy = x11_create_ximage_display(dpy, TRUE);
+ }
+
+ return ndpy;
+}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
new file mode 100644
index 0000000000..622ddac5df
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _NATIVE_X11_H_
+#define _NATIVE_X11_H_
+
+#include "state_tracker/drm_api.h"
+#include "common/native.h"
+
+struct native_display *
+x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm);
+
+struct native_display *
+x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api);
+
+#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
new file mode 100644
index 0000000000..92a62f230e
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -0,0 +1,684 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "pipe/p_compiler.h"
+#include "util/u_simple_screen.h"
+#include "util/u_inlines.h"
+#include "softpipe/sp_winsys.h"
+#include "egllog.h"
+
+#include "sw_winsys.h"
+#include "native_x11.h"
+#include "x11_screen.h"
+
+enum ximage_surface_type {
+ XIMAGE_SURFACE_TYPE_WINDOW,
+ XIMAGE_SURFACE_TYPE_PIXMAP,
+ XIMAGE_SURFACE_TYPE_PBUFFER
+};
+
+struct ximage_display {
+ struct native_display base;
+ Display *dpy;
+ boolean own_dpy;
+
+ struct x11_screen *xscr;
+ int xscr_number;
+
+ boolean use_xshm;
+
+ struct pipe_winsys *winsys;
+ struct ximage_config *configs;
+ int num_configs;
+};
+
+struct ximage_buffer {
+ XImage *ximage;
+
+ struct pipe_texture *texture;
+ XShmSegmentInfo *shm_info;
+ boolean xshm_attached;
+};
+
+struct ximage_surface {
+ struct native_surface base;
+ Drawable drawable;
+ enum ximage_surface_type type;
+ enum pipe_format color_format;
+ XVisualInfo visual;
+ struct ximage_display *xdpy;
+
+ int width, height;
+ GC gc;
+
+ struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
+ unsigned int sequence_number;
+};
+
+struct ximage_config {
+ struct native_config base;
+ const XVisualInfo *visual;
+};
+
+static INLINE struct ximage_display *
+ximage_display(const struct native_display *ndpy)
+{
+ return (struct ximage_display *) ndpy;
+}
+
+static INLINE struct ximage_surface *
+ximage_surface(const struct native_surface *nsurf)
+{
+ return (struct ximage_surface *) nsurf;
+}
+
+static INLINE struct ximage_config *
+ximage_config(const struct native_config *nconf)
+{
+ return (struct ximage_config *) nconf;
+}
+
+static void
+ximage_surface_free_buffer(struct native_surface *nsurf,
+ enum native_attachment which)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_buffer *xbuf = &xsurf->buffers[which];
+
+ pipe_texture_reference(&xbuf->texture, NULL);
+
+ if (xbuf->shm_info) {
+ if (xbuf->xshm_attached)
+ XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
+ if (xbuf->shm_info->shmaddr != (void *) -1)
+ shmdt(xbuf->shm_info->shmaddr);
+ if (xbuf->shm_info->shmid != -1)
+ shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
+
+ xbuf->shm_info->shmaddr = (void *) -1;
+ xbuf->shm_info->shmid = -1;
+ }
+}
+
+static boolean
+ximage_surface_alloc_buffer(struct native_surface *nsurf,
+ enum native_attachment which)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_buffer *xbuf = &xsurf->buffers[which];
+ struct pipe_screen *screen = xsurf->xdpy->base.screen;
+ struct pipe_texture templ;
+
+ /* free old data */
+ if (xbuf->texture)
+ ximage_surface_free_buffer(&xsurf->base, which);
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = xsurf->color_format;
+ templ.width0 = xsurf->width;
+ templ.height0 = xsurf->height;
+ templ.depth0 = 1;
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ if (xbuf->shm_info) {
+ struct pipe_buffer *pbuf;
+ unsigned stride, size;
+ void *addr = NULL;
+
+ stride = util_format_get_stride(xsurf->color_format, xsurf->width);
+ /* alignment should depend on visual? */
+ stride = align(stride, 4);
+ size = stride * xsurf->height;
+
+ /* create and attach shm object */
+ xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
+ if (xbuf->shm_info->shmid != -1) {
+ xbuf->shm_info->shmaddr =
+ shmat(xbuf->shm_info->shmid, NULL, 0);
+ if (xbuf->shm_info->shmaddr != (void *) -1) {
+ if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
+ addr = xbuf->shm_info->shmaddr;
+ xbuf->xshm_attached = TRUE;
+ }
+ }
+ }
+
+ if (addr) {
+ pbuf = screen->user_buffer_create(screen, addr, size);
+ if (pbuf) {
+ xbuf->texture =
+ screen->texture_blanket(screen, &templ, &stride, pbuf);
+ pipe_buffer_reference(&pbuf, NULL);
+ }
+ }
+ }
+ else {
+ xbuf->texture = screen->texture_create(screen, &templ);
+ }
+
+ /* clean up the buffer if allocation failed */
+ if (!xbuf->texture)
+ ximage_surface_free_buffer(&xsurf->base, which);
+
+ return (xbuf->texture != NULL);
+}
+
+static boolean
+ximage_surface_draw_buffer(struct native_surface *nsurf,
+ enum native_attachment which)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_buffer *xbuf = &xsurf->buffers[which];
+ struct pipe_screen *screen = xsurf->xdpy->base.screen;
+ struct pipe_transfer *transfer;
+
+ if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+
+ transfer = screen->get_tex_transfer(screen, xbuf->texture,
+ 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
+ if (!transfer)
+ return FALSE;
+
+ xbuf->ximage->bytes_per_line = transfer->stride;
+ xbuf->ximage->data = screen->transfer_map(screen, transfer);
+ if (!xbuf->ximage->data) {
+ screen->tex_transfer_destroy(transfer);
+ return FALSE;
+ }
+
+
+ if (xbuf->shm_info)
+ XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
+ xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
+ else
+ XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
+ xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
+
+ xbuf->ximage->data = NULL;
+ screen->transfer_unmap(screen, transfer);
+
+ /*
+ * softpipe allows the pipe transfer to be re-used, but we don't want to
+ * rely on that behavior.
+ */
+ screen->tex_transfer_destroy(transfer);
+
+ XSync(xsurf->xdpy->dpy, FALSE);
+
+ return TRUE;
+}
+
+static boolean
+ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+ return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+}
+
+static boolean
+ximage_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_buffer *xfront, *xback, xtmp;
+
+ xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
+ xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
+
+ /* draw the back buffer directly if there is no front buffer */
+ if (!xfront->texture)
+ return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
+
+ /* swap the buffers */
+ xtmp = *xfront;
+ *xfront = *xback;
+ *xback = xtmp;
+
+ /* the front/back textures are swapped */
+ xsurf->sequence_number++;
+
+ return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+}
+
+static void
+ximage_surface_update_geometry(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ Status ok;
+ Window root;
+ int x, y;
+ unsigned int w, h, border, depth;
+
+ /* pbuffer has fixed geometry */
+ if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
+ return;
+
+ ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
+ &root, &x, &y, &w, &h, &border, &depth);
+ if (ok) {
+ xsurf->width = w;
+ xsurf->height = h;
+ }
+}
+
+static boolean
+ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ boolean new_buffers = FALSE;
+ int att;
+
+ ximage_surface_update_geometry(&xsurf->base);
+
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[att];
+
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
+
+ /* reallocate the texture */
+ if (!xbuf->texture ||
+ xsurf->width != xbuf->texture->width0 ||
+ xsurf->height != xbuf->texture->height0) {
+ new_buffers = TRUE;
+ if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
+ /* update ximage */
+ if (xbuf->ximage) {
+ xbuf->ximage->width = xsurf->width;
+ xbuf->ximage->height = xsurf->height;
+ }
+ }
+ }
+
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], xbuf->texture);
+ }
+ }
+
+ /* increase the sequence number so that caller knows */
+ if (new_buffers)
+ xsurf->sequence_number++;
+
+ if (seq_num)
+ *seq_num = xsurf->sequence_number;
+ if (width)
+ *width = xsurf->width;
+ if (height)
+ *height = xsurf->height;
+
+ return TRUE;
+}
+
+static void
+ximage_surface_wait(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ XSync(xsurf->xdpy->dpy, FALSE);
+ /* TODO XGetImage and update the front texture */
+}
+
+static void
+ximage_surface_destroy(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[i];
+ ximage_surface_free_buffer(&xsurf->base, i);
+ /* xbuf->shm_info is owned by xbuf->ximage? */
+ if (xbuf->ximage) {
+ XDestroyImage(xbuf->ximage);
+ xbuf->ximage = NULL;
+ }
+ }
+
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
+ XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
+ free(xsurf);
+}
+
+static struct ximage_surface *
+ximage_display_create_surface(struct native_display *ndpy,
+ enum ximage_surface_type type,
+ Drawable drawable,
+ const struct native_config *nconf)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ struct ximage_config *xconf = ximage_config(nconf);
+ struct ximage_surface *xsurf;
+ int i;
+
+ xsurf = CALLOC_STRUCT(ximage_surface);
+ if (!xsurf)
+ return NULL;
+
+ xsurf->xdpy = xdpy;
+ xsurf->type = type;
+ xsurf->color_format = xconf->base.color_format;
+ xsurf->drawable = drawable;
+
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+ xsurf->drawable = drawable;
+ xsurf->visual = *xconf->visual;
+
+ xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
+ if (!xsurf->gc) {
+ free(xsurf);
+ return NULL;
+ }
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[i];
+
+ if (xdpy->use_xshm) {
+ xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
+ if (xbuf->shm_info) {
+ /* initialize shm info */
+ xbuf->shm_info->shmid = -1;
+ xbuf->shm_info->shmaddr = (void *) -1;
+ xbuf->shm_info->readOnly = TRUE;
+
+ xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
+ xsurf->visual.visual,
+ xsurf->visual.depth,
+ ZPixmap, NULL,
+ xbuf->shm_info,
+ 0, 0);
+ }
+ }
+ else {
+ xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
+ xsurf->visual.visual,
+ xsurf->visual.depth,
+ ZPixmap, 0, /* format, offset */
+ NULL, /* data */
+ 0, 0, /* size */
+ 8, /* bitmap_pad */
+ 0); /* bytes_per_line */
+ }
+
+ if (!xbuf->ximage) {
+ XFreeGC(xdpy->dpy, xsurf->gc);
+ free(xsurf);
+ return NULL;
+ }
+ }
+ }
+
+ xsurf->base.destroy = ximage_surface_destroy;
+ xsurf->base.swap_buffers = ximage_surface_swap_buffers;
+ xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer;
+ xsurf->base.validate = ximage_surface_validate;
+ xsurf->base.wait = ximage_surface_wait;
+
+ return xsurf;
+}
+
+static struct native_surface *
+ximage_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
+{
+ struct ximage_surface *xsurf;
+
+ xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_WINDOW,
+ (Drawable) win, nconf);
+ return (xsurf) ? &xsurf->base : NULL;
+}
+
+static struct native_surface *
+ximage_display_create_pixmap_surface(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct ximage_surface *xsurf;
+
+ xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PIXMAP,
+ (Drawable) pix, nconf);
+ return (xsurf) ? &xsurf->base : NULL;
+}
+
+static struct native_surface *
+ximage_display_create_pbuffer_surface(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height)
+{
+ struct ximage_surface *xsurf;
+
+ xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER,
+ (Drawable) None, nconf);
+ if (xsurf) {
+ xsurf->width = width;
+ xsurf->height = height;
+ }
+ return (xsurf) ? &xsurf->base : NULL;
+}
+
+static enum pipe_format
+choose_format(const XVisualInfo *vinfo)
+{
+ enum pipe_format fmt;
+ /* TODO elaborate the formats */
+ switch (vinfo->depth) {
+ case 32:
+ fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case 24:
+ fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+ break;
+ case 16:
+ fmt = PIPE_FORMAT_R5G6B5_UNORM;
+ break;
+ default:
+ fmt = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return fmt;
+}
+
+static const struct native_config **
+ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ const struct native_config **configs;
+ int i;
+
+ /* first time */
+ if (!xdpy->configs) {
+ const XVisualInfo *visuals;
+ int num_visuals, count, j;
+
+ visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
+ if (!visuals)
+ return NULL;
+
+ /*
+ * Create two configs for each visual.
+ * One with depth/stencil buffer; one without
+ */
+ xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs));
+ if (!xdpy->configs)
+ return NULL;
+
+ count = 0;
+ for (i = 0; i < num_visuals; i++) {
+ for (j = 0; j < 2; j++) {
+ struct ximage_config *xconf = &xdpy->configs[count];
+ __GLcontextModes *mode = &xconf->base.mode;
+
+ xconf->visual = &visuals[i];
+ xconf->base.color_format = choose_format(xconf->visual);
+ if (xconf->base.color_format == PIPE_FORMAT_NONE)
+ continue;
+
+ x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode);
+ /* support double buffer mode */
+ mode->doubleBufferMode = TRUE;
+
+ xconf->base.depth_format = PIPE_FORMAT_NONE;
+ xconf->base.stencil_format = PIPE_FORMAT_NONE;
+ /* create the second config with depth/stencil buffer */
+ if (j == 1) {
+ xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM;
+ xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM;
+ mode->depthBits = 24;
+ mode->stencilBits = 8;
+ mode->haveDepthBuffer = TRUE;
+ mode->haveStencilBuffer = TRUE;
+ }
+
+ mode->maxPbufferWidth = 4096;
+ mode->maxPbufferHeight = 4096;
+ mode->maxPbufferPixels = 4096 * 4096;
+ mode->drawableType =
+ GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
+ mode->swapMethod = GLX_SWAP_EXCHANGE_OML;
+
+ if (mode->alphaBits)
+ mode->bindToTextureRgba = TRUE;
+ else
+ mode->bindToTextureRgb = TRUE;
+
+ count++;
+ }
+ }
+
+ xdpy->num_configs = count;
+ }
+
+ configs = malloc(xdpy->num_configs * sizeof(*configs));
+ if (configs) {
+ for (i = 0; i < xdpy->num_configs; i++)
+ configs[i] = (const struct native_config *) &xdpy->configs[i];
+ if (num_configs)
+ *num_configs = xdpy->num_configs;
+ }
+ return configs;
+}
+
+static boolean
+ximage_display_is_pixmap_supported(struct native_display *ndpy,
+ EGLNativePixmapType pix,
+ const struct native_config *nconf)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+ enum pipe_format fmt;
+ uint depth;
+
+ depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
+ switch (depth) {
+ case 32:
+ fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case 24:
+ fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+ break;
+ case 16:
+ fmt = PIPE_FORMAT_R5G6B5_UNORM;
+ break;
+ default:
+ fmt = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return (fmt == nconf->color_format);
+}
+
+static void
+ximage_display_destroy(struct native_display *ndpy)
+{
+ struct ximage_display *xdpy = ximage_display(ndpy);
+
+ if (xdpy->configs)
+ free(xdpy->configs);
+
+ xdpy->base.screen->destroy(xdpy->base.screen);
+ free(xdpy->winsys);
+
+ x11_screen_destroy(xdpy->xscr);
+ if (xdpy->own_dpy)
+ XCloseDisplay(xdpy->dpy);
+ free(xdpy);
+}
+
+struct native_display *
+x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
+{
+ struct ximage_display *xdpy;
+
+ xdpy = CALLOC_STRUCT(ximage_display);
+ if (!xdpy)
+ return NULL;
+
+ xdpy->dpy = dpy;
+ if (!xdpy->dpy) {
+ xdpy->dpy = XOpenDisplay(NULL);
+ if (!xdpy->dpy) {
+ free(xdpy);
+ return NULL;
+ }
+ xdpy->own_dpy = TRUE;
+ }
+
+ xdpy->xscr_number = DefaultScreen(xdpy->dpy);
+ xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
+ if (!xdpy->xscr) {
+ free(xdpy);
+ return NULL;
+ }
+
+ xdpy->use_xshm =
+ (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
+
+ xdpy->winsys = create_sw_winsys();
+ xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+
+ xdpy->base.destroy = ximage_display_destroy;
+
+ xdpy->base.get_configs = ximage_display_get_configs;
+ xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
+ xdpy->base.create_window_surface = ximage_display_create_window_surface;
+ xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
+ xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface;
+
+ return &xdpy->base;
+}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
new file mode 100644
index 0000000000..33328aadf2
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/sw_winsys.c
@@ -0,0 +1,231 @@
+/**************************************************************************
+ *
+ * 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 "util/u_simple_screen.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "sw_winsys.h"
+
+
+
+/** Subclass of pipe_winsys */
+struct sw_pipe_winsys
+{
+ struct pipe_winsys Base;
+ /* no extra fields for now */
+};
+
+
+/** subclass of pipe_buffer */
+struct sw_pipe_buffer
+{
+ struct pipe_buffer Base;
+ boolean UserBuffer; /** Is this a user-space buffer? */
+ void *Data;
+ void *Mapped;
+};
+
+
+/** cast wrapper */
+static INLINE struct sw_pipe_buffer *
+sw_pipe_buffer(struct pipe_buffer *b)
+{
+ return (struct sw_pipe_buffer *) b;
+}
+
+
+static const char *
+get_name(struct pipe_winsys *pws)
+{
+ return "software";
+}
+
+
+/** Create new pipe_buffer and allocate storage of given size */
+static struct pipe_buffer *
+buffer_create(struct pipe_winsys *pws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+ if (!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->Base.reference, 1);
+ buffer->Base.alignment = alignment;
+ buffer->Base.usage = usage;
+ buffer->Base.size = size;
+
+ /* align to 16-byte multiple for Cell */
+ buffer->Data = align_malloc(size, MAX2(alignment, 16));
+
+ return &buffer->Base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
+{
+ struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
+ if (!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->Base.reference, 1);
+ buffer->Base.size = bytes;
+ buffer->UserBuffer = TRUE;
+ buffer->Data = ptr;
+
+ return &buffer->Base;
+}
+
+
+static void *
+buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+ buffer->Mapped = buffer->Data;
+ return buffer->Mapped;
+}
+
+
+static void
+buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+ buffer->Mapped = NULL;
+}
+
+
+static void
+buffer_destroy(struct pipe_buffer *buf)
+{
+ struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
+
+ if (buffer->Data && !buffer->UserBuffer) {
+ align_free(buffer->Data);
+ buffer->Data = NULL;
+ }
+
+ free(buffer);
+}
+
+
+static struct pipe_buffer *
+surface_buffer_create(struct pipe_winsys *winsys,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ const unsigned alignment = 64;
+ unsigned nblocksy;
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ *stride = align(util_format_get_stride(format, width), alignment);
+
+ return winsys->buffer_create(winsys, alignment,
+ usage,
+ *stride * nblocksy);
+}
+
+
+static void
+fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ /* no-op */
+}
+
+
+static int
+fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ /* no-op */
+ return 0;
+}
+
+
+static int
+fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ /* no-op */
+ return 0;
+}
+
+
+/**
+ * Create/return a new pipe_winsys object.
+ */
+struct pipe_winsys *
+create_sw_winsys(void)
+{
+ struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
+ if (!ws)
+ return NULL;
+
+ /* Fill in this struct with callbacks that pipe will need to
+ * communicate with the window system, buffer manager, etc.
+ */
+ ws->Base.buffer_create = buffer_create;
+ ws->Base.user_buffer_create = user_buffer_create;
+ ws->Base.buffer_map = buffer_map;
+ ws->Base.buffer_unmap = buffer_unmap;
+ ws->Base.buffer_destroy = buffer_destroy;
+
+ ws->Base.surface_buffer_create = surface_buffer_create;
+
+ ws->Base.fence_reference = fence_reference;
+ ws->Base.fence_signalled = fence_signalled;
+ ws->Base.fence_finish = fence_finish;
+
+ ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
+
+ ws->Base.get_name = get_name;
+
+ return &ws->Base;
+}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h
new file mode 100644
index 0000000000..f96c5a14b0
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/sw_winsys.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef SW_WINSYS_H
+#define SW_WINSYS_H
+
+
+struct pipe_winsys;
+
+
+extern struct pipe_winsys *
+create_sw_winsys(void);
+
+
+#endif /* SW_WINSYS_H */
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
new file mode 100644
index 0000000000..d72bfc99d3
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -0,0 +1,453 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/XShm.h>
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "xf86drm.h"
+#include "egllog.h"
+
+#include "x11_screen.h"
+#include "dri2.h"
+#include "glxinit.h"
+
+struct x11_screen {
+ Display *dpy;
+ int number;
+
+ /*
+ * This is used to fetch GLX visuals/fbconfigs. It steals code from GLX.
+ * It might be better to rewrite the part in Xlib or XCB.
+ */
+ __GLXdisplayPrivate *glx_dpy;
+
+ int dri_major, dri_minor;
+ char *dri_driver;
+ char *dri_device;
+ int dri_fd;
+
+ XVisualInfo *visuals;
+ int num_visuals;
+
+ /* cached values for x11_drawable_get_depth */
+ Drawable last_drawable;
+ unsigned int last_depth;
+};
+
+
+/**
+ * Create a X11 screen.
+ */
+struct x11_screen *
+x11_screen_create(Display *dpy, int screen)
+{
+ struct x11_screen *xscr;
+
+ if (screen >= ScreenCount(dpy))
+ return NULL;
+
+ xscr = CALLOC_STRUCT(x11_screen);
+ if (xscr) {
+ xscr->dpy = dpy;
+ xscr->number = screen;
+
+ xscr->dri_major = -1;
+ xscr->dri_fd = -1;
+ }
+ return xscr;
+}
+
+/**
+ * Destroy a X11 screen.
+ */
+void
+x11_screen_destroy(struct x11_screen *xscr)
+{
+ if (xscr->dri_fd >= 0)
+ close(xscr->dri_fd);
+ if (xscr->dri_driver)
+ Xfree(xscr->dri_driver);
+ if (xscr->dri_device)
+ Xfree(xscr->dri_device);
+
+ /* xscr->glx_dpy will be destroyed with the X display */
+
+ if (xscr->visuals)
+ XFree(xscr->visuals);
+ free(xscr);
+}
+
+static boolean
+x11_screen_init_dri2(struct x11_screen *xscr)
+{
+ if (xscr->dri_major < 0) {
+ int eventBase, errorBase;
+
+ if (!DRI2QueryExtension(xscr->dpy, &eventBase, &errorBase) ||
+ !DRI2QueryVersion(xscr->dpy, &xscr->dri_major, &xscr->dri_minor))
+ xscr->dri_major = -1;
+ }
+ return (xscr->dri_major >= 0);
+}
+
+static boolean
+x11_screen_init_glx(struct x11_screen *xscr)
+{
+ if (!xscr->glx_dpy)
+ xscr->glx_dpy = __glXInitialize(xscr->dpy);
+ return (xscr->glx_dpy != NULL);
+}
+
+/**
+ * Return true if the screen supports the extension.
+ */
+boolean
+x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext)
+{
+ boolean supported = FALSE;
+
+ switch (ext) {
+ case X11_SCREEN_EXTENSION_XSHM:
+ supported = XShmQueryExtension(xscr->dpy);
+ break;
+ case X11_SCREEN_EXTENSION_GLX:
+ supported = x11_screen_init_glx(xscr);
+ break;
+ case X11_SCREEN_EXTENSION_DRI2:
+ supported = x11_screen_init_dri2(xscr);
+ break;
+ default:
+ break;
+ }
+
+ return supported;
+}
+
+/**
+ * Return the X visuals.
+ */
+const XVisualInfo *
+x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
+{
+ if (!xscr->visuals) {
+ XVisualInfo vinfo_template;
+ vinfo_template.screen = xscr->number;
+ xscr->visuals = XGetVisualInfo(xscr->dpy, VisualScreenMask,
+ &vinfo_template, &xscr->num_visuals);
+ }
+
+ if (num_visuals)
+ *num_visuals = xscr->num_visuals;
+ return xscr->visuals;
+}
+
+void
+x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
+ __GLcontextModes *mode)
+{
+ int r, g, b, a;
+ int visual_type;
+
+ r = util_bitcount(visual->red_mask);
+ g = util_bitcount(visual->green_mask);
+ b = util_bitcount(visual->blue_mask);
+ a = visual->depth - (r + g + b);
+#if defined(__cplusplus) || defined(c_plusplus)
+ visual_type = visual->c_class;
+#else
+ visual_type = visual->class;
+#endif
+
+ /* convert to GLX visual type */
+ switch (visual_type) {
+ case TrueColor:
+ visual_type = GLX_TRUE_COLOR;
+ break;
+ case DirectColor:
+ visual_type = GLX_DIRECT_COLOR;
+ break;
+ case PseudoColor:
+ visual_type = GLX_PSEUDO_COLOR;
+ break;
+ case StaticColor:
+ visual_type = GLX_STATIC_COLOR;
+ break;
+ case GrayScale:
+ visual_type = GLX_GRAY_SCALE;
+ break;
+ case StaticGray:
+ visual_type = GLX_STATIC_GRAY;
+ break;
+ default:
+ visual_type = GLX_NONE;
+ break;
+ }
+
+ mode->rgbBits = r + g + b + a;
+ mode->redBits = r;
+ mode->greenBits = g;
+ mode->blueBits = b;
+ mode->alphaBits = a;
+ mode->visualID = visual->visualid;
+ mode->visualType = visual_type;
+
+ /* sane defaults */
+ mode->renderType = GLX_RGBA_BIT;
+ mode->rgbMode = TRUE;
+ mode->visualRating = GLX_SLOW_CONFIG;
+ mode->xRenderable = TRUE;
+}
+
+/**
+ * Return the GLX fbconfigs.
+ */
+const __GLcontextModes *
+x11_screen_get_glx_configs(struct x11_screen *xscr)
+{
+ return (x11_screen_init_glx(xscr))
+ ? xscr->glx_dpy->screenConfigs[xscr->number].configs
+ : NULL;
+}
+
+/**
+ * Return the GLX visuals.
+ */
+const __GLcontextModes *
+x11_screen_get_glx_visuals(struct x11_screen *xscr)
+{
+ return (x11_screen_init_glx(xscr))
+ ? xscr->glx_dpy->screenConfigs[xscr->number].visuals
+ : NULL;
+}
+
+static boolean
+x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
+{
+ return (strcmp(xscr->dri_driver, driver) == 0);
+}
+
+/**
+ * Probe the screen for the DRI2 driver name.
+ */
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr)
+{
+ /* get the driver name and the device name */
+ if (!xscr->dri_driver) {
+ if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
+ &xscr->dri_driver, &xscr->dri_device))
+ xscr->dri_driver = xscr->dri_device = NULL;
+ }
+
+ return xscr->dri_driver;
+}
+
+/**
+ * Enable DRI2 and returns the file descriptor of the DRM device. The file
+ * descriptor will be closed automatically when the screen is destoryed.
+ */
+int
+x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
+{
+ if (xscr->dri_fd < 0) {
+ int fd;
+ drm_magic_t magic;
+
+ /* get the driver name and the device name first */
+ if (!x11_screen_probe_dri2(xscr))
+ return -1;
+
+ if (!x11_screen_is_driver_equal(xscr, driver)) {
+ _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
+ xscr->dri_driver, driver);
+ return -1;
+ }
+
+ fd = open(xscr->dri_device, O_RDWR);
+ if (fd < 0) {
+ _eglLog(_EGL_WARNING, "failed to open %s", xscr->dri_device);
+ return -1;
+ }
+
+ memset(&magic, 0, sizeof(magic));
+ if (drmGetMagic(fd, &magic)) {
+ _eglLog(_EGL_WARNING, "failed to get magic");
+ close(fd);
+ return -1;
+ }
+
+ if (!DRI2Authenticate(xscr->dpy,
+ RootWindow(xscr->dpy, xscr->number), magic)) {
+ _eglLog(_EGL_WARNING, "failed to authenticate magic");
+ close(fd);
+ return -1;
+ }
+
+ xscr->dri_fd = fd;
+ }
+
+ return xscr->dri_fd;
+}
+
+/**
+ * Create/Destroy the DRI drawable.
+ */
+void
+x11_drawable_enable_dri2(struct x11_screen *xscr,
+ Drawable drawable, boolean on)
+{
+ if (on)
+ DRI2CreateDrawable(xscr->dpy, drawable);
+ else
+ DRI2DestroyDrawable(xscr->dpy, drawable);
+}
+
+/**
+ * Copy between buffers of the DRI2 drawable.
+ */
+void
+x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
+ int x, int y, int width, int height,
+ int src_buf, int dst_buf)
+{
+ XRectangle rect;
+ XserverRegion region;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = width;
+ rect.height = height;
+
+ region = XFixesCreateRegion(xscr->dpy, &rect, 1);
+ DRI2CopyRegion(xscr->dpy, drawable, region, dst_buf, src_buf);
+ XFixesDestroyRegion(xscr->dpy, region);
+}
+
+/**
+ * Get the buffers of the DRI2 drawable. The returned array should be freed.
+ */
+struct x11_drawable_buffer *
+x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
+ int *width, int *height, unsigned int *attachments,
+ boolean with_format, int num_ins, int *num_outs)
+{
+ DRI2Buffer *dri2bufs;
+
+ if (with_format)
+ dri2bufs = DRI2GetBuffersWithFormat(xscr->dpy, drawable, width, height,
+ attachments, num_ins, num_outs);
+ else
+ dri2bufs = DRI2GetBuffers(xscr->dpy, drawable, width, height,
+ attachments, num_ins, num_outs);
+
+ return (struct x11_drawable_buffer *) dri2bufs;
+}
+
+/**
+ * Return the depth of a drawable.
+ *
+ * Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
+ */
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
+{
+ unsigned int depth;
+
+ if (drawable != xscr->last_drawable) {
+ Window root;
+ int x, y;
+ unsigned int w, h, border;
+ Status ok;
+
+ ok = XGetGeometry(xscr->dpy, drawable, &root,
+ &x, &y, &w, &h, &border, &depth);
+ if (!ok)
+ depth = 0;
+
+ xscr->last_drawable = drawable;
+ xscr->last_depth = depth;
+ }
+ else {
+ depth = xscr->last_depth;
+ }
+
+ return depth;
+}
+
+/**
+ * Create a mode list of the given size.
+ */
+__GLcontextModes *
+x11_context_modes_create(unsigned count)
+{
+ const size_t size = sizeof(__GLcontextModes);
+ __GLcontextModes *base = NULL;
+ __GLcontextModes **next;
+ unsigned i;
+
+ next = &base;
+ for (i = 0; i < count; i++) {
+ *next = (__GLcontextModes *) calloc(1, size);
+ if (*next == NULL) {
+ x11_context_modes_destroy(base);
+ base = NULL;
+ break;
+ }
+ next = &((*next)->next);
+ }
+
+ return base;
+}
+
+/**
+ * Destroy a mode list.
+ */
+void
+x11_context_modes_destroy(__GLcontextModes *modes)
+{
+ while (modes != NULL) {
+ __GLcontextModes *next = modes->next;
+ free(modes);
+ modes = next;
+ }
+}
+
+/**
+ * Return the number of the modes in the mode list.
+ */
+unsigned
+x11_context_modes_count(const __GLcontextModes *modes)
+{
+ const __GLcontextModes *mode;
+ int count = 0;
+ for (mode = modes; mode; mode = mode->next)
+ count++;
+ return count;
+}
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h
new file mode 100644
index 0000000000..5432858ac3
--- /dev/null
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -0,0 +1,105 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ *
+ * 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.
+ */
+
+#ifndef _X11_SCREEN_H_
+#define _X11_SCREEN_H_
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/dri2tokens.h>
+#include "pipe/p_compiler.h"
+#include "common/native.h"
+
+enum x11_screen_extension {
+ X11_SCREEN_EXTENSION_XSHM,
+ X11_SCREEN_EXTENSION_GLX,
+ X11_SCREEN_EXTENSION_DRI2,
+};
+
+/* the same as DRI2Buffer */
+struct x11_drawable_buffer {
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+};
+
+struct x11_screen;
+
+struct x11_screen *
+x11_screen_create(Display *dpy, int screen);
+
+void
+x11_screen_destroy(struct x11_screen *xscr);
+
+boolean
+x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
+
+const XVisualInfo *
+x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
+
+void
+x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
+ __GLcontextModes *mode);
+
+const __GLcontextModes *
+x11_screen_get_glx_configs(struct x11_screen *xscr);
+
+const __GLcontextModes *
+x11_screen_get_glx_visuals(struct x11_screen *xscr);
+
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr);
+
+int
+x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
+
+__GLcontextModes *
+x11_context_modes_create(unsigned count);
+
+void
+x11_context_modes_destroy(__GLcontextModes *modes);
+
+unsigned
+x11_context_modes_count(const __GLcontextModes *modes);
+
+void
+x11_drawable_enable_dri2(struct x11_screen *xscr,
+ Drawable drawable, boolean on);
+
+void
+x11_drawable_copy_buffers(struct x11_screen *xscr, Drawable drawable,
+ int x, int y, int width, int height,
+ int src_buf, int dst_buf);
+
+struct x11_drawable_buffer *
+x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
+ int *width, int *height, unsigned int *attachments,
+ boolean with_format, int num_ins, int *num_outs);
+
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
+
+#endif /* _X11_SCREEN_H_ */
diff --git a/src/gallium/state_trackers/es/Makefile b/src/gallium/state_trackers/es/Makefile
new file mode 100644
index 0000000000..b036551271
--- /dev/null
+++ b/src/gallium/state_trackers/es/Makefile
@@ -0,0 +1,84 @@
+# src/gallium/state_trackers/es/Makefile
+
+# Build the ES 1/2 state tracker libraries
+# This consists of core Mesa ES, plus GL/gallium state tracker.
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+GLES_1_VERSION_MAJOR = 1
+GLES_1_VERSION_MINOR = 1
+GLES_1_VERSION_PATCH = 0
+
+GLES_2_VERSION_MAJOR = 2
+GLES_2_VERSION_MINOR = 0
+GLES_2_VERSION_PATCH = 0
+
+
+# Maybe move these into configs/default:
+GLES_1_LIB = GLESv1_CM
+GLES_1_LIB_NAME = lib$(GLES_1_LIB).so
+GLES_2_LIB = GLESv2
+GLES_2_LIB_NAME = lib$(GLES_2_LIB).so
+
+
+ES1_OBJECTS = st_es1.o
+ES2_OBJECTS = st_es2.o
+
+
+ES1_LIBS = \
+ $(TOP)/src/mesa/es/libes1gallium.a \
+ $(TOP)/src/mesa/es/libes1api.a
+
+ES2_LIBS = \
+ $(TOP)/src/mesa/es/libes2gallium.a \
+ $(TOP)/src/mesa/es/libes2api.a
+
+SYS_LIBS = -lm -pthread
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/src/gallium/include
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+
+
+# Default: make both GL ES 1.1 and GL ES 2.0 libraries
+default: $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)
+
+# Make the shared libs
+$(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME): $(ES1_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES)
+ $(MKLIB) -o $(GLES_1_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(GLES_1_VERSION_MAJOR) \
+ -minor $(GLES_1_VERSION_MINOR) \
+ -patch $(GLES_1_VERSION_PATCH) \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ $(ES1_OBJECTS) \
+ -Wl,--whole-archive $(ES1_LIBS) -Wl,--no-whole-archive \
+ $(GALLIUM_AUXILIARIES) $(SYS_LIBS)
+
+$(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME): $(ES2_OBJECTS) $(ES1_LIBS) $(GALLIUM_AUXILIARIES)
+ $(MKLIB) -o $(GLES_2_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(GLES_2_VERSION_MAJOR) \
+ -minor $(GLES_2_VERSION_MINOR) \
+ -patch $(GLES_2_VERSION_PATCH) \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ $(ES2_OBJECTS) \
+ -Wl,--whole-archive $(ES2_LIBS) -Wl,--no-whole-archive \
+ $(GALLIUM_AUXILIARIES) $(SYS_LIBS)
+
+install: default
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES
+ $(INSTALL) -m 644 $(TOP)/include/GLES/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/GLES2
+ $(INSTALL) -m 644 $(TOP)/include/GLES2/*.h $(DESTDIR)$(INSTALL_DIR)/include/GLES2
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv1* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGLESv2* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+
+clean:
+ -rm -f *.o *~
+ -rm -f $(TOP)/$(LIB_DIR)/$(GLES_1_LIB_NAME)* $(TOP)/$(LIB_DIR)/$(GLES_2_LIB_NAME)*
+
+depend:
diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c
new file mode 100644
index 0000000000..25bc53b21e
--- /dev/null
+++ b/src/gallium/state_trackers/es/st_es1.c
@@ -0,0 +1,3 @@
+#include "pipe/p_compiler.h"
+
+PUBLIC const int st_api_OpenGL_ES1 = 1;
diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c
new file mode 100644
index 0000000000..171ea62b97
--- /dev/null
+++ b/src/gallium/state_trackers/es/st_es2.c
@@ -0,0 +1,3 @@
+#include "pipe/p_compiler.h"
+
+PUBLIC const int st_api_OpenGL_ES2 = 1;
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
index 84d47b12ed..bd4a85caa0 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -193,7 +193,7 @@ _glxapi_get_proc_address(const char *funcName)
}
-__GLXextFuncPtr
+PUBLIC __GLXextFuncPtr
glXGetProcAddressARB(const GLubyte *procName)
{
__GLXextFuncPtr f;
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 1783bc504d..fb314f3b52 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -760,7 +760,6 @@ PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
static GLboolean firstTime = GL_TRUE;
- struct pipe_context *_pipe = NULL;
struct pipe_context *pipe = NULL;
XMesaContext c;
GLcontext *mesaCtx;
@@ -788,11 +787,12 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
if (screen == NULL)
goto fail;
- _pipe = driver.create_pipe_context(_screen, (void *) c);
- if (_pipe == NULL)
+ /* Trace screen knows how to properly wrap context creation in the
+ * wrapped screen, so nothing special to do here:
+ */
+ pipe = screen->context_create(screen, (void *) c);
+ if (pipe == NULL)
goto fail;
- pipe = trace_context_create(screen, _pipe);
- pipe->priv = c;
c->st = st_create_context(pipe,
&v->mesa_visual,
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index d24971ca1c..63a329cbe0 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -60,7 +60,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "main/mtypes.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#include "pipe/p_thread.h"
+#include "os/os_thread.h"
# include <X11/Xlib.h>
diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_winsys.h
index 0e57605c34..4bd5b5c8d3 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_winsys.h
@@ -39,13 +39,6 @@ struct xm_driver {
struct pipe_screen *(*create_pipe_screen)( void );
- /* The context_private argument needs to go away. Is currently used
- * in a round-about way to associate a display-target surface with its
- * Xlib window.
- */
- struct pipe_context *(*create_pipe_context)( struct pipe_screen *,
- void *context_private );
-
void (*display_surface)( struct xmesa_buffer *,
struct pipe_surface * );
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 8498a90812..527e065cd9 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -21,6 +21,7 @@ if 'python' in env['statetrackers']:
'gdi32',
'user32',
'kernel32',
+ 'ws2_32',
])
else:
env.Append(LIBS = [
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index 96b13c2258..99e177b0be 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -40,9 +40,9 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "cso_cache/cso_context.h"
+#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_tile.h"
#include "util/u_math.h"
@@ -76,7 +76,6 @@
%rename(BlendColor) pipe_blend_color;
%rename(Blend) pipe_blend_state;
%rename(Clip) pipe_clip_state;
-%rename(ConstantBuffer) pipe_constant_buffer;
%rename(Depth) pipe_depth_state;
%rename(Stencil) pipe_stencil_state;
%rename(Alpha) pipe_alpha_state;
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 84ce1a41e6..ce893dad45 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -142,10 +142,7 @@ struct st_context {
void set_constant_buffer(unsigned shader, unsigned index,
struct pipe_buffer *buffer )
{
- struct pipe_constant_buffer state;
- memset(&state, 0, sizeof(state));
- state.buffer = buffer;
- $self->pipe->set_constant_buffer($self->pipe, shader, index, &state);
+ $self->pipe->set_constant_buffer($self->pipe, shader, index, buffer);
}
void set_framebuffer(const struct pipe_framebuffer_state *state )
diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py
index bb61979d07..190db43b08 100755
--- a/src/gallium/state_trackers/python/retrace/interpreter.py
+++ b/src/gallium/state_trackers/python/retrace/interpreter.py
@@ -94,7 +94,7 @@ struct_factories = {
"pipe_blend_color": gallium.BlendColor,
"pipe_blend_state": gallium.Blend,
#"pipe_clip_state": gallium.Clip,
- #"pipe_constant_buffer": gallium.ConstantBuffer,
+ #"pipe_buffer": gallium.Buffer,
"pipe_depth_state": gallium.Depth,
"pipe_stencil_state": gallium.Stencil,
"pipe_alpha_state": gallium.Alpha,
@@ -462,10 +462,10 @@ class Context(Object):
sys.stdout.flush()
def set_constant_buffer(self, shader, index, buffer):
- if buffer is not None and buffer.buffer is not None:
- self.real.set_constant_buffer(shader, index, buffer.buffer)
+ if buffer is not None:
+ self.real.set_constant_buffer(shader, index, buffer)
- self.dump_constant_buffer(buffer.buffer)
+ self.dump_constant_buffer(buffer)
def set_framebuffer_state(self, state):
_state = gallium.Framebuffer()
@@ -534,6 +534,8 @@ class Context(Object):
gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f',
gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f',
gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B',
+ gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B',
+ gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h',
}[velem.src_format]
data = vbuf.buffer.read()
diff --git a/src/gallium/state_trackers/python/samples/gs.py b/src/gallium/state_trackers/python/samples/gs.py
index a07cf557f2..cd68abac9a 100644
--- a/src/gallium/state_trackers/python/samples/gs.py
+++ b/src/gallium/state_trackers/python/samples/gs.py
@@ -72,11 +72,11 @@ def test(dev):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py
index e5e168bdc8..f0b5e3dc98 100644
--- a/src/gallium/state_trackers/python/samples/tri.py
+++ b/src/gallium/state_trackers/python/samples/tri.py
@@ -72,11 +72,11 @@ def test(dev):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index d144af2447..1146a8b0c3 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -29,7 +29,7 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_shader_tokens.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "cso_cache/cso_context.h"
#include "util/u_math.h"
#include "util/u_memory.h"
@@ -80,8 +80,7 @@ st_device_create_from_st_winsys(const struct st_winsys *st_ws)
{
struct st_device *st_dev;
- if(!st_ws->screen_create ||
- !st_ws->context_create)
+ if(!st_ws->screen_create)
return NULL;
st_dev = CALLOC_STRUCT(st_device);
@@ -158,13 +157,7 @@ st_context_create(struct st_device *st_dev)
st_device_reference(&st_ctx->st_dev, st_dev);
- st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen);
- if(!st_ctx->real_pipe) {
- st_context_destroy(st_ctx);
- return NULL;
- }
-
- st_ctx->pipe = trace_context_create(st_dev->screen, st_ctx->real_pipe);
+ st_ctx->pipe = st_dev->screen->create_context(st_dev->screen, NULL);
if(!st_ctx->pipe) {
st_context_destroy(st_ctx);
return NULL;
@@ -180,11 +173,11 @@ st_context_create(struct st_device *st_dev)
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(st_ctx->cso, &blend);
}
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index f786e13411..de9e0215d8 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -50,7 +50,6 @@ struct st_surface
struct st_context {
struct st_device *st_dev;
- struct pipe_context *real_pipe;
struct pipe_context *pipe;
struct cso_context *cso;
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index 43aaaabf2a..a3110a19d5 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -217,21 +217,6 @@ st_hardpipe_screen_create(void)
}
-static struct pipe_context *
-st_hardpipe_context_create(struct pipe_screen *screen)
-{
- if(st_hardpipe_load()) {
- if(screen == pfnGetGalliumScreenMESA())
- return pfnCreateGalliumContextMESA();
- else
- return NULL;
- }
- else
- return st_softpipe_winsys.context_create(screen);
-}
-
-
const struct st_winsys st_hardpipe_winsys = {
- &st_hardpipe_screen_create,
- &st_hardpipe_context_create
+ &st_hardpipe_screen_create
};
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
index 0096b18c99..5d83b5a9e1 100644
--- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
@@ -36,7 +36,7 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "llvmpipe/lp_winsys.h"
@@ -135,14 +135,7 @@ no_winsys:
}
-static struct pipe_context *
-st_llvmpipe_context_create(struct pipe_screen *screen)
-{
- return llvmpipe_create(screen);
-}
-
const struct st_winsys st_softpipe_winsys = {
- &st_llvmpipe_screen_create,
- &st_llvmpipe_context_create,
+ &st_llvmpipe_screen_create
};
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index 9637741421..32a6551a87 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -29,7 +29,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_tile.h"
#include "util/u_math.h"
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index a3294e877a..81676bc3a4 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -35,225 +35,9 @@
* @author Jose Fonseca
*/
-
-#include "pipe/internal/p_winsys_screen.h"/* port to just p_screen */
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
#include "softpipe/sp_winsys.h"
#include "st_winsys.h"
-
-struct st_softpipe_buffer
-{
- struct pipe_buffer base;
- boolean userBuffer; /** Is this a user-space buffer? */
- void *data;
- void *mapped;
-};
-
-
-/** Cast wrapper */
-static INLINE struct st_softpipe_buffer *
-st_softpipe_buffer( struct pipe_buffer *buf )
-{
- return (struct st_softpipe_buffer *)buf;
-}
-
-
-static void *
-st_softpipe_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = st_softpipe_buf->data;
- return st_softpipe_buf->mapped;
-}
-
-
-static void
-st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
- st_softpipe_buf->mapped = NULL;
-}
-
-
-static void
-st_softpipe_buffer_destroy(struct pipe_buffer *buf)
-{
- struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
-
- if (oldBuf->data) {
- if (!oldBuf->userBuffer)
- align_free(oldBuf->data);
-
- oldBuf->data = NULL;
- }
-
- FREE(oldBuf);
-}
-
-
-static void
-st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
- struct pipe_surface *surf,
- void *context_private)
-{
-}
-
-
-
-static const char *
-st_softpipe_get_name(struct pipe_winsys *winsys)
-{
- return "softpipe";
-}
-
-
-static struct pipe_buffer *
-st_softpipe_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
-
- buffer->data = align_malloc(size, alignment);
-
- return &buffer->base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
- void *ptr,
- unsigned bytes)
-{
- struct st_softpipe_buffer *buffer;
-
- buffer = CALLOC_STRUCT(st_softpipe_buffer);
- if(!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.size = bytes;
- buffer->userBuffer = TRUE;
- buffer->data = ptr;
-
- return &buffer->base;
-}
-
-
-static struct pipe_buffer *
-st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-st_softpipe_fence_reference(struct pipe_winsys *winsys,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
-}
-
-
-static int
-st_softpipe_fence_signalled(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static int
-st_softpipe_fence_finish(struct pipe_winsys *winsys,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- return 0;
-}
-
-
-static void
-st_softpipe_destroy(struct pipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-st_softpipe_screen_create(void)
-{
- static struct pipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(pipe_winsys);
- if(!winsys)
- return NULL;
-
- winsys->destroy = st_softpipe_destroy;
-
- winsys->buffer_create = st_softpipe_buffer_create;
- winsys->user_buffer_create = st_softpipe_user_buffer_create;
- winsys->buffer_map = st_softpipe_buffer_map;
- winsys->buffer_unmap = st_softpipe_buffer_unmap;
- winsys->buffer_destroy = st_softpipe_buffer_destroy;
-
- winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
-
- winsys->fence_reference = st_softpipe_fence_reference;
- winsys->fence_signalled = st_softpipe_fence_signalled;
- winsys->fence_finish = st_softpipe_fence_finish;
-
- winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
- winsys->get_name = st_softpipe_get_name;
-
- screen = softpipe_create_screen(winsys);
- if(!screen)
- st_softpipe_destroy(winsys);
-
- return screen;
-}
-
-
-static struct pipe_context *
-st_softpipe_context_create(struct pipe_screen *screen)
-{
- return softpipe_create(screen);
-}
-
-
const struct st_winsys st_softpipe_winsys = {
- &st_softpipe_screen_create,
- &st_softpipe_context_create,
+ &softpipe_create_screen_malloc
};
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index b8cb612d86..0c7b6a200e 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -38,9 +38,6 @@ struct st_winsys
{
struct pipe_screen *
(*screen_create)(void);
-
- struct pipe_context *
- (*context_create)(struct pipe_screen *screen);
};
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore b/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore
new file mode 100644
index 0000000000..e33609d251
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore
@@ -0,0 +1 @@
+*.png
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh
new file mode 100644
index 0000000000..85fb9ea4e7
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh
@@ -0,0 +1,13 @@
+FRAG
+
+DCL IN[0], COLOR, LINEAR
+DCL OUT[0], COLOR
+DCL CONST[1]
+DCL CONST[3]
+DCL TEMP[0..1]
+
+ADD TEMP[0], IN[0], CONST[1]
+RCP TEMP[1], CONST[3].xxxx
+MUL OUT[0], TEMP[0], TEMP[1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh
new file mode 100644
index 0000000000..f70a5146f4
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh
@@ -0,0 +1,9 @@
+FRAG
+
+DCL IN[0], COLOR, LINEAR
+DCL OUT[0], COLOR
+DCL CONST[1][1..2]
+
+MAD OUT[0], IN[0], CONST[1][2], CONST[1][1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
index f2a1521cbf..d58b7886a1 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh
@@ -1,4 +1,4 @@
-FRAG1.1
+FRAG
DCL IN[0], COLOR, LINEAR
DCL OUT[0], COLOR
diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
index 8d3bf9d4d7..41dd69d254 100644
--- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py
@@ -26,6 +26,7 @@
#
##########################################################################
+import struct
from gallium import *
@@ -50,11 +51,11 @@ def test(dev, name):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
@@ -146,6 +147,42 @@ def test(dev, name):
fs = Shader(file('frag-' + name + '.sh', 'rt').read())
ctx.set_fragment_shader(fs)
+ constbuf0 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
+ cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
+ cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
+ cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
+
+ constbuf0.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
+ 0,
+ constbuf0)
+
+ constbuf1 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
+ cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
+ cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
+ cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
+
+ constbuf1.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
+ 1,
+ constbuf1)
+
xy = [
-0.8, -0.8,
0.8, -0.8,
@@ -184,6 +221,8 @@ def main():
tests = [
'abs',
'add',
+ 'cb-1d',
+ 'cb-2d',
'dp3',
'dp4',
'dst',
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore b/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore
new file mode 100644
index 0000000000..e33609d251
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore
@@ -0,0 +1 @@
+*.png
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh
new file mode 100644
index 0000000000..b41fe5dd38
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh
@@ -0,0 +1,16 @@
+VERT
+
+DCL IN[0], POSITION
+DCL IN[1], COLOR
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL CONST[1]
+DCL CONST[3]
+DCL TEMP[0..1]
+
+MOV OUT[0], IN[0]
+ADD TEMP[0], IN[1], CONST[1]
+RCP TEMP[1], CONST[3].xxxx
+MUL OUT[1], TEMP[0], TEMP[1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh
new file mode 100644
index 0000000000..45f5e6b729
--- /dev/null
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh
@@ -0,0 +1,12 @@
+VERT
+
+DCL IN[0], POSITION
+DCL IN[1], COLOR
+DCL OUT[0], POSITION
+DCL OUT[1], COLOR
+DCL CONST[1][1..2]
+
+MOV OUT[0], IN[0]
+MAD OUT[1], IN[1], CONST[1][2], CONST[1][1]
+
+END
diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
index 01bf5a3210..2c44f872e1 100644
--- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
+++ b/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py
@@ -27,6 +27,8 @@
##########################################################################
+import struct
+
from gallium import *
def make_image(surface):
@@ -50,11 +52,11 @@ def test(dev, name):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
@@ -143,6 +145,42 @@ def test(dev, name):
''')
ctx.set_fragment_shader(fs)
+ constbuf0 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
+ cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
+ cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
+ cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
+
+ constbuf0.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
+ 0,
+ constbuf0)
+
+ constbuf1 = dev.buffer_create(64,
+ (PIPE_BUFFER_USAGE_CONSTANT |
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE),
+ 4 * 4 * 4)
+
+ cbdata = ''
+ cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
+ cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
+ cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
+ cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
+
+ constbuf1.write(cbdata, 0)
+
+ ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
+ 1,
+ constbuf1)
+
xy = [
0.0, 0.8,
-0.2, 0.4,
@@ -213,6 +251,8 @@ def main():
'add',
'arl',
'arr',
+ 'cb-1d',
+ 'cb-2d',
'dp3',
'dp4',
'dst',
diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/src/gallium/state_trackers/python/tests/texture_render.py
index 79287f2cac..0fac1ea5ef 100755
--- a/src/gallium/state_trackers/python/tests/texture_render.py
+++ b/src/gallium/state_trackers/python/tests/texture_render.py
@@ -115,11 +115,11 @@ class TextureTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# no-op depth/stencil/alpha
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py
index 520961c805..db32b537a1 100755
--- a/src/gallium/state_trackers/python/tests/texture_sample.py
+++ b/src/gallium/state_trackers/python/tests/texture_sample.py
@@ -140,11 +140,11 @@ class TextureColorSampleTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# no-op depth/stencil/alpha
@@ -327,11 +327,11 @@ class TextureDepthSampleTest(TestCase):
# disabled blending/masking
blend = Blend()
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.colormask = PIPE_MASK_RGBA
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
+ blend.rt[0].colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index fc97bf51f8..037d8dc911 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -1,8 +1,14 @@
-# src/mesa/Makefile
+# src/gallium/state_trackers/vega/Makefile
TOP = ../../../..
include $(TOP)/configs/current
-GALLIUM = $(TOP)
+
+VG_LIB = OpenVG
+VG_LIB_NAME = lib$(VG_LIB).so
+
+VG_MAJOR = 1
+VG_MINOR = 0
+VG_TINY = 0
### Lists of source files, included by Makefiles
@@ -34,88 +40,54 @@ VG_SOURCES = \
shader.c \
shaders_cache.c
+VG_OBJECTS = $(VG_SOURCES:.c=.o)
-### All the core C sources
-
-ALL_SOURCES = \
- $(VG_SOURCES)
-
-
-### Object files
-VG_OBJECTS = \
- $(VG_SOURCES:.c=.o)
+VG_LIBS = $(GALLIUM_AUXILIARIES) -lm
### Include directories
INCLUDE_DIRS = \
-I$(TOP)/include \
- -I$(GALLIUM)/include \
- -I$(GALLIUM)/src/gallium/include \
- -I$(GALLIUM)/src/gallium/auxiliary
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary
-VG_LIB = OpenVG
-VG_LIB_NAME = lib$(VG_LIB).so
-
-VG_MAJOR = 1
-VG_MINOR = 0
-VG_TINY = 0
-
-GALLIUM_LIBS = \
- $(GALLIUM)/src/gallium/auxiliary/libgallium.a
-
-.SUFFIXES : .cpp
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
-.cpp.o:
- $(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $< -o $@
-
-.S.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
-
-
-default: depend subdirs $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
+default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
# Make the OpenVG library
-$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(GALLIUM_LIBS)
- $(TOP)/bin/mklib -o $(VG_LIB) \
+$(TOP)/$(LIB_DIR)/$(VG_LIB_NAME): $(VG_OBJECTS) $(VG_LIBS)
+ $(MKLIB) -o $(VG_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-major $(VG_MAJOR) \
-minor $(VG_MINOR) \
-patch $(VG_TINY) \
-install $(TOP)/$(LIB_DIR) \
- $(VG_OBJECTS) $(GALLIUM_LIBS) \
- -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive $(SYS_LIBS)
+ $(VG_OBJECTS) $(VG_LIBS)
######################################################################
# Generic stuff
-depend: $(ALL_SOURCES)
+depend: $(VG_SOURCES)
@ echo "running $(MKDEP)"
@ rm -f depend # workaround oops on gutsy?!?
@ touch depend
- @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
+ @ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(VG_SOURCES) \
> /dev/null 2>/dev/null
-
-subdirs:
-
install: default
- $(INSTALL) -d $(INSTALL_DIR)/include/VG
- $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
- $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(INSTALL_DIR)/include/VG
- @if [ -e $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(INSTALL_DIR)/$(LIB_DIR); \
- fi
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/include/VG
+ $(INSTALL) -m 644 $(TOP)/include/VG/*.h $(DESTDIR)$(INSTALL_DIR)/include/VG
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libOpenVG* $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
# Emacs tags
tags:
etags `find . -name \*.[ch]` $(TOP)/include/VG/*.h
clean:
- -rm -f *.o
- -rm -f */*.o
- -rm -f */*/*.o
- -rm -f depend depend.bak
+ rm -f $(VG_OBJECTS)
+ rm -f depend depend.bak
-include depend
+sinclude depend
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 2f984fb7b9..20c72c1ff5 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -34,7 +34,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
@@ -127,19 +127,19 @@ static void setup_blend()
struct vg_context *ctx = vg_current_context();
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
if (ctx->state.vg.filter_channel_mask & VG_RED)
- blend.colormask |= PIPE_MASK_R;
+ blend.rt[0].colormask |= PIPE_MASK_R;
if (ctx->state.vg.filter_channel_mask & VG_GREEN)
- blend.colormask |= PIPE_MASK_G;
+ blend.rt[0].colormask |= PIPE_MASK_G;
if (ctx->state.vg.filter_channel_mask & VG_BLUE)
- blend.colormask |= PIPE_MASK_B;
+ blend.rt[0].colormask |= PIPE_MASK_B;
if (ctx->state.vg.filter_channel_mask & VG_ALPHA)
- blend.colormask |= PIPE_MASK_A;
- blend.blend_enable = 1;
+ blend.rt[0].colormask |= PIPE_MASK_A;
+ blend.rt[0].blend_enable = 0;
cso_set_blend(ctx->cso_context, &blend);
}
@@ -147,22 +147,22 @@ static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
VGint param_bytes)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_constant_buffer *cbuf = &ctx->filter.buffer;
+ struct pipe_buffer **cbuf = &ctx->filter.buffer;
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization. */
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ pipe_buffer_reference(cbuf, NULL);
- cbuf->buffer = pipe_buffer_create(pipe->screen, 16,
- PIPE_BUFFER_USAGE_CONSTANT,
- param_bytes);
+ *cbuf = pipe_buffer_create(pipe->screen, 16,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
- if (cbuf->buffer) {
- st_no_flush_pipe_buffer_write(ctx, cbuf->buffer,
+ if (*cbuf) {
+ st_no_flush_pipe_buffer_write(ctx, *cbuf,
0, param_bytes, buffer);
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+ ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
}
static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c
index c437553bc2..015241498e 100644
--- a/src/gallium/state_trackers/vega/api_images.c
+++ b/src/gallium/state_trackers/vega/api_images.c
@@ -35,7 +35,7 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_blit.h"
#include "util/u_tile.h"
#include "util/u_memory.h"
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 4f9f3dae17..9c123a4cf9 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -31,8 +31,7 @@
#include "vg_context.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h" /* for winsys->update_buffer */
+#include "util/u_inlines.h"
#include "util/u_pack_color.h"
#include "util/u_draw_quad.h"
@@ -116,8 +115,8 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/
- if (st->pipe->winsys && st->pipe->winsys->update_buffer)
- st->pipe->winsys->update_buffer( st->pipe->winsys,
+ if (st->pipe->screen && st->pipe->screen->update_buffer)
+ st->pipe->screen->update_buffer( st->pipe->screen,
st->pipe->priv );
cso_save_blend(st->cso_context);
@@ -129,14 +128,11 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask |= PIPE_MASK_R;
- blend.colormask |= PIPE_MASK_G;
- blend.colormask |= PIPE_MASK_B;
- blend.colormask |= PIPE_MASK_A;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(st->cso_context, &blend);
}
diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c
index 15ac1900f4..58ebb3b60e 100644
--- a/src/gallium/state_trackers/vega/api_path.c
+++ b/src/gallium/state_trackers/vega/api_path.c
@@ -32,7 +32,7 @@
#include "paint.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
VGPath vgCreatePath(VGint pathFormat,
diff --git a/src/gallium/state_trackers/vega/asm_fill.h b/src/gallium/state_trackers/vega/asm_fill.h
index 2f394ad6c5..27773467fa 100644
--- a/src/gallium/state_trackers/vega/asm_fill.h
+++ b/src/gallium/state_trackers/vega/asm_fill.h
@@ -27,166 +27,375 @@
#ifndef ASM_FILL_H
#define ASM_FILL_H
-static const char solid_fill_asm[] =
- "MOV %s, CONST[0]\n";
-
-
-static const char linear_grad_asm[] =
- "MOV TEMP[0].xy, IN[0]\n"
- "MOV TEMP[0].z, CONST[1].yyyy\n"
- "DP3 TEMP[1], CONST[2], TEMP[0]\n"
- "DP3 TEMP[2], CONST[3], TEMP[0]\n"
- "DP3 TEMP[3], CONST[4], TEMP[0]\n"
- "RCP TEMP[3], TEMP[3]\n"
- "MUL TEMP[1], TEMP[1], TEMP[3]\n"
- "MUL TEMP[2], TEMP[2], TEMP[3]\n"
- "MOV TEMP[4].x, TEMP[1]\n"
- "MOV TEMP[4].y, TEMP[2]\n"
- "MUL TEMP[0], CONST[0].yyyy, TEMP[4].yyyy\n"
- "MAD TEMP[1], CONST[0].xxxx, TEMP[4].xxxx, TEMP[0]\n"
- "MUL TEMP[2], TEMP[1], CONST[0].zzzz\n"
- "TEX %s, TEMP[2], SAMP[0], 1D\n";
-
-static const char radial_grad_asm[] =
- "MOV TEMP[0].xy, IN[0]\n"
- "MOV TEMP[0].z, CONST[1].yyyy\n"
- "DP3 TEMP[1], CONST[2], TEMP[0]\n"
- "DP3 TEMP[2], CONST[3], TEMP[0]\n"
- "DP3 TEMP[3], CONST[4], TEMP[0]\n"
- "RCP TEMP[3], TEMP[3]\n"
- "MUL TEMP[1], TEMP[1], TEMP[3]\n"
- "MUL TEMP[2], TEMP[2], TEMP[3]\n"
- "MOV TEMP[5].x, TEMP[1]\n"
- "MOV TEMP[5].y, TEMP[2]\n"
- "MUL TEMP[0], CONST[0].yyyy, TEMP[5].yyyy\n"
- "MAD TEMP[1], CONST[0].xxxx, TEMP[5].xxxx, TEMP[0]\n"
- "ADD TEMP[1], TEMP[1], TEMP[1]\n"
- "MUL TEMP[3], TEMP[5].yyyy, TEMP[5].yyyy\n"
- "MAD TEMP[4], TEMP[5].xxxx, TEMP[5].xxxx, TEMP[3]\n"
- "MOV TEMP[4], -TEMP[4]\n"
- "MUL TEMP[2], CONST[0].zzzz, TEMP[4]\n"
- "MUL TEMP[0], CONST[1].wwww, TEMP[2]\n"
- "MUL TEMP[3], TEMP[1], TEMP[1]\n"
- "SUB TEMP[2], TEMP[3], TEMP[0]\n"
- "RSQ TEMP[2], |TEMP[2]|\n"
- "RCP TEMP[2], TEMP[2]\n"
- "SUB TEMP[1], TEMP[2], TEMP[1]\n"
- "ADD TEMP[0], CONST[0].zzzz, CONST[0].zzzz\n"
- "RCP TEMP[0], TEMP[0]\n"
- "MUL TEMP[2], TEMP[1], TEMP[0]\n"
- "TEX %s, TEMP[2], SAMP[0], 1D\n";
-
-static const char pattern_asm[] =
- "MOV TEMP[0].xy, IN[0]\n"
- "MOV TEMP[0].z, CONST[1].yyyy\n"
- "DP3 TEMP[1], CONST[2], TEMP[0]\n"
- "DP3 TEMP[2], CONST[3], TEMP[0]\n"
- "DP3 TEMP[3], CONST[4], TEMP[0]\n"
- "RCP TEMP[3], TEMP[3]\n"
- "MUL TEMP[1], TEMP[1], TEMP[3]\n"
- "MUL TEMP[2], TEMP[2], TEMP[3]\n"
- "MOV TEMP[4].x, TEMP[1]\n"
- "MOV TEMP[4].y, TEMP[2]\n"
- "RCP TEMP[0], CONST[1].zwzw\n"
- "MOV TEMP[1], TEMP[4]\n"
- "MUL TEMP[1].x, TEMP[1], TEMP[0]\n"
- "MUL TEMP[1].y, TEMP[1], TEMP[0]\n"
- "TEX %s, TEMP[1], SAMP[0], 2D\n";
-
-
-static const char mask_asm[] =
- "TEX TEMP[1], IN[0], SAMP[1], 2D\n"
- "MUL TEMP[0].w, TEMP[0].wwww, TEMP[1].wwww\n"
- "MOV %s, TEMP[0]\n";
-
-
-static const char image_normal_asm[] =
- "TEX %s, IN[1], SAMP[3], 2D\n";
-
-static const char image_multiply_asm[] =
- "TEX TEMP[1], IN[1], SAMP[3], 2D\n"
- "MUL %s, TEMP[0], TEMP[1]\n";
-
-static const char image_stencil_asm[] =
- "TEX TEMP[1], IN[1], SAMP[3], 2D\n"
- "MUL %s, TEMP[0], TEMP[1]\n";
-
-
-#define EXTENDED_BLEND_OVER \
- "SUB TEMP[3], CONST[1].yyyy, TEMP[1].wwww\n" \
- "SUB TEMP[4], CONST[1].yyyy, TEMP[0].wwww\n" \
- "MUL TEMP[3], TEMP[0], TEMP[3]\n" \
- "MUL TEMP[4], TEMP[1], TEMP[4]\n" \
- "ADD TEMP[3], TEMP[3], TEMP[4]\n"
-
-static const char blend_multiply_asm[] =
- "TEX TEMP[1], IN[0], SAMP[2], 2D\n"
- EXTENDED_BLEND_OVER
- "MUL TEMP[4], TEMP[0], TEMP[1]\n"
- "ADD TEMP[1], TEMP[4], TEMP[3]\n"/*result.rgb*/
- "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n"
- "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n"
- "SUB TEMP[1].w, TEMP[3], TEMP[2]\n"
- "MOV %s, TEMP[1]\n";
-#if 1
-static const char blend_screen_asm[] =
- "TEX TEMP[1], IN[0], SAMP[2], 2D\n"
- "ADD TEMP[3], TEMP[0], TEMP[1]\n"
- "MUL TEMP[2], TEMP[0], TEMP[1]\n"
- "SUB %s, TEMP[3], TEMP[2]\n";
-#else
-static const char blend_screen_asm[] =
- "TEX TEMP[1], IN[0], SAMP[2], 2D\n"
- "MOV %s, TEMP[1]\n";
-#endif
-
-static const char blend_darken_asm[] =
- "TEX TEMP[1], IN[0], SAMP[2], 2D\n"
- EXTENDED_BLEND_OVER
- "MUL TEMP[4], TEMP[0], TEMP[1].wwww\n"
- "MUL TEMP[5], TEMP[1], TEMP[0].wwww\n"
- "MIN TEMP[4], TEMP[4], TEMP[5]\n"
- "ADD TEMP[1], TEMP[3], TEMP[4]\n"
- "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n"
- "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n"
- "SUB TEMP[1].w, TEMP[3], TEMP[2]\n"
- "MOV %s, TEMP[1]\n";
-
-static const char blend_lighten_asm[] =
- "TEX TEMP[1], IN[0], SAMP[2], 2D\n"
- EXTENDED_BLEND_OVER
- "MUL TEMP[4], TEMP[0], TEMP[1].wwww\n"
- "MUL TEMP[5], TEMP[1], TEMP[0].wwww\n"
- "MAX TEMP[4], TEMP[4], TEMP[5]\n"
- "ADD TEMP[1], TEMP[3], TEMP[4]\n"
- "MUL TEMP[2], TEMP[0].wwww, TEMP[1].wwww\n"
- "ADD TEMP[3], TEMP[0].wwww, TEMP[1].wwww\n"
- "SUB TEMP[1].w, TEMP[3], TEMP[2]\n"
- "MOV %s, TEMP[1]\n";
-
-
-static const char premultiply_asm[] =
- "MUL TEMP[0].xyz, TEMP[0], TEMP[0].wwww\n";
-
-static const char unpremultiply_asm[] =
- "TEX TEMP[0], IN[0], SAMP[1], 2D\n";
-
-
-static const char color_bw_asm[] =
- "ADD TEMP[1], CONST[1].yyyy, CONST[1].yyyy\n"
- "RCP TEMP[2], TEMP[1]\n"
- "ADD TEMP[1], CONST[1].yyyy, TEMP[2]\n"
- "ADD TEMP[2].x, TEMP[0].xxxx, TEMP[0].yyyy\n"
- "ADD TEMP[2].x, TEMP[0].zzzz, TEMP[0].xxxx\n"
- "SGE TEMP[0].xyz, TEMP[2].xxxx, TEMP[1]\n"
- "SGE TEMP[0].w, TEMP[0].wwww, TEMP[2].yyyy\n"
- "MOV %s, TEMP[0]\n";
+#include "tgsi/tgsi_ureg.h"
+
+typedef void (* ureg_func)( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant);
+
+static INLINE void
+solid_fill( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_MOV(ureg, *out, constant[0]);
+}
+
+static INLINE void
+linear_grad( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
+ in[0]);
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+ ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
+ ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
+ ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
+ ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[0],
+ ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp[1],
+ ureg_scalar(constant[0], TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp[4]), TGSI_SWIZZLE_X),
+ ureg_src(temp[0]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[1]),
+ ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
+}
+
+static INLINE void
+radial_grad( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+
+ ureg_MOV(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_XY), in[0]);
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+ ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
+ ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
+ ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_X), ureg_src(temp[1]));
+ ureg_MOV(ureg, ureg_writemask(temp[5], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[0], ureg_scalar(constant[0], TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp[1],
+ ureg_scalar(constant[0], TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X), ureg_src(temp[0]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[1]));
+ ureg_MUL(ureg, temp[3],
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp[4],
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp[5]), TGSI_SWIZZLE_X),
+ ureg_src(temp[3]));
+ ureg_MOV(ureg, temp[4], ureg_negate(ureg_src(temp[4])));
+ ureg_MUL(ureg, temp[2],
+ ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
+ ureg_src(temp[4]));
+ ureg_MUL(ureg, temp[0],
+ ureg_scalar(constant[1], TGSI_SWIZZLE_W),
+ ureg_src(temp[2]));
+ ureg_MUL(ureg, temp[3], ureg_src(temp[1]), ureg_src(temp[1]));
+
+ ureg_SUB(ureg, temp[2], ureg_src(temp[3]), ureg_src(temp[0]));
+ ureg_RSQ(ureg, temp[2], ureg_abs(ureg_src(temp[2])));
+ ureg_RCP(ureg, temp[2], ureg_src(temp[2]));
+ ureg_SUB(ureg, temp[1], ureg_src(temp[2]), ureg_src(temp[1]));
+ ureg_ADD(ureg, temp[0],
+ ureg_scalar(constant[0], TGSI_SWIZZLE_Z),
+ ureg_scalar(constant[0], TGSI_SWIZZLE_Z));
+ ureg_RCP(ureg, temp[0], ureg_src(temp[0]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[1]), ureg_src(temp[0]));
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_1D, ureg_src(temp[2]), sampler[0]);
+
+}
+
+
+static INLINE void
+pattern( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_XY),
+ in[0]);
+ ureg_MOV(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_Z),
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+ ureg_DP3(ureg, temp[1], constant[2], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[2], constant[3], ureg_src(temp[0]));
+ ureg_DP3(ureg, temp[3], constant[4], ureg_src(temp[0]));
+ ureg_RCP(ureg, temp[3], ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[1], ureg_src(temp[1]), ureg_src(temp[3]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[2]), ureg_src(temp[3]));
+ ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_X), ureg_src(temp[1]));
+ ureg_MOV(ureg, ureg_writemask(temp[4], TGSI_WRITEMASK_Y), ureg_src(temp[2]));
+ ureg_RCP(ureg, temp[0],
+ ureg_swizzle(constant[1],
+ TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_W,
+ TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_W));
+ ureg_MOV(ureg, temp[1], ureg_src(temp[4]));
+ ureg_MUL(ureg,
+ ureg_writemask(temp[1], TGSI_WRITEMASK_X),
+ ureg_src(temp[1]),
+ ureg_src(temp[0]));
+ ureg_MUL(ureg,
+ ureg_writemask(temp[1], TGSI_WRITEMASK_Y),
+ ureg_src(temp[1]),
+ ureg_src(temp[0]));
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, ureg_src(temp[1]), sampler[0]);
+}
+
+static INLINE void
+mask( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[1]);
+ ureg_MUL(ureg, ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
+
+static INLINE void
+image_normal( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, *out, TGSI_TEXTURE_2D, in[1], sampler[3]);
+}
+
+
+static INLINE void
+image_multiply( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
+ ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
+}
+
+
+static INLINE void
+image_stencil( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[1], sampler[3]);
+ ureg_MUL(ureg, *out, ureg_src(temp[0]), ureg_src(temp[1]));
+}
+
+#define EXTENDED_BLENDER_OVER_FUNC \
+ ureg_SUB(ureg, temp[3], \
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W)); \
+ ureg_SUB(ureg, temp[3], \
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y), \
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W)); \
+ ureg_MUL(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[3])); \
+ ureg_MUL(ureg, temp[4], ureg_src(temp[1]), ureg_src(temp[4])); \
+ ureg_ADD(ureg, temp[3], ureg_src(temp[3]), ureg_src(temp[4]));
+
+
+static INLINE void
+blend_multiply( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
+ EXTENDED_BLENDER_OVER_FUNC
+ ureg_MUL(ureg, temp[4], ureg_src(temp[0]), ureg_src(temp[1]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[4]), ureg_src(temp[3]));
+
+ ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+ ureg_src(temp[3]), ureg_src(temp[2]));
+
+ ureg_MOV(ureg, *out, ureg_src(temp[1]));
+}
+
+static INLINE void
+blend_screen( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
+ ureg_ADD(ureg, temp[3], ureg_src(temp[0]), ureg_src(temp[1]));
+ ureg_MUL(ureg, temp[2], ureg_src(temp[0]), ureg_src(temp[1]));
+ ureg_SUB(ureg, *out, ureg_src(temp[3]), ureg_src(temp[2]));
+}
+
+static INLINE void
+blend_darken( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
+ EXTENDED_BLENDER_OVER_FUNC
+ ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MIN(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
+
+ ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+ ureg_src(temp[3]), ureg_src(temp[2]));
+
+ ureg_MOV(ureg, *out, ureg_src(temp[1]));
+}
+
+static INLINE void
+blend_lighten( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[1], TGSI_TEXTURE_2D, in[0], sampler[2]);
+ EXTENDED_BLENDER_OVER_FUNC
+ ureg_MUL(ureg, temp[4], ureg_src(temp[0]),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, temp[5], ureg_src(temp[1]),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+ ureg_MAX(ureg, temp[4], ureg_src(temp[4]), ureg_src(temp[5]));
+ ureg_ADD(ureg, temp[1], ureg_src(temp[3]), ureg_src(temp[4]));
+
+ ureg_MUL(ureg, temp[2], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_ADD(ureg, temp[3], ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[1]), TGSI_SWIZZLE_W));
+ ureg_SUB(ureg, ureg_writemask(temp[1], TGSI_WRITEMASK_W),
+ ureg_src(temp[3]), ureg_src(temp[2]));
+
+ ureg_MOV(ureg, *out, ureg_src(temp[1]));
+}
+
+static INLINE void
+premultiply( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_MUL(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
+ ureg_src(temp[0]),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W));
+}
+
+static INLINE void
+unpremultiply( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_TEX(ureg, temp[0], TGSI_TEXTURE_2D, in[0], sampler[1]);
+}
+
+
+static INLINE void
+color_bw( struct ureg_program *ureg,
+ struct ureg_dst *out,
+ struct ureg_src *in,
+ struct ureg_src *sampler,
+ struct ureg_dst *temp,
+ struct ureg_src *constant)
+{
+ ureg_ADD(ureg, temp[1],
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y));
+ ureg_RCP(ureg, temp[2], ureg_src(temp[1]));
+ ureg_ADD(ureg, temp[1],
+ ureg_scalar(constant[1], TGSI_SWIZZLE_Y),
+ ureg_src(temp[2]));
+ ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Y));
+ ureg_ADD(ureg, ureg_writemask(temp[2], TGSI_WRITEMASK_X),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_Z),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_X));
+ ureg_SGE(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_XYZ),
+ ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_X),
+ ureg_src(temp[1]));
+ ureg_SGE(ureg,
+ ureg_writemask(temp[0], TGSI_WRITEMASK_W),
+ ureg_scalar(ureg_src(temp[0]), TGSI_SWIZZLE_W),
+ ureg_scalar(ureg_src(temp[2]), TGSI_SWIZZLE_Y));
+ ureg_MOV(ureg, *out, ureg_src(temp[0]));
+}
struct shader_asm_info {
VGint id;
- VGint num_tokens;
- const char * txt;
+ ureg_func func;
VGboolean needs_position;
@@ -203,44 +412,44 @@ struct shader_asm_info {
static const struct shader_asm_info shaders_asm[] = {
/* fills */
- {VEGA_SOLID_FILL_SHADER, 40, solid_fill_asm,
+ {VEGA_SOLID_FILL_SHADER, solid_fill,
VG_FALSE, 0, 1, 0, 0, 0, 0},
- {VEGA_LINEAR_GRADIENT_SHADER, 200, linear_grad_asm,
+ {VEGA_LINEAR_GRADIENT_SHADER, linear_grad,
VG_TRUE, 0, 5, 0, 1, 0, 5},
- {VEGA_RADIAL_GRADIENT_SHADER, 200, radial_grad_asm,
+ {VEGA_RADIAL_GRADIENT_SHADER, radial_grad,
VG_TRUE, 0, 5, 0, 1, 0, 6},
- {VEGA_PATTERN_SHADER, 100, pattern_asm,
+ {VEGA_PATTERN_SHADER, pattern,
VG_TRUE, 1, 4, 0, 1, 0, 5},
/* image draw modes */
- {VEGA_IMAGE_NORMAL_SHADER, 200, image_normal_asm,
+ {VEGA_IMAGE_NORMAL_SHADER, image_normal,
VG_TRUE, 0, 0, 3, 1, 0, 0},
- {VEGA_IMAGE_MULTIPLY_SHADER, 200, image_multiply_asm,
+ {VEGA_IMAGE_MULTIPLY_SHADER, image_multiply,
VG_TRUE, 0, 0, 3, 1, 0, 2},
- {VEGA_IMAGE_STENCIL_SHADER, 200, image_stencil_asm,
+ {VEGA_IMAGE_STENCIL_SHADER, image_stencil,
VG_TRUE, 0, 0, 3, 1, 0, 2},
- {VEGA_MASK_SHADER, 100, mask_asm,
+ {VEGA_MASK_SHADER, mask,
VG_TRUE, 0, 0, 1, 1, 0, 2},
/* extra blend modes */
- {VEGA_BLEND_MULTIPLY_SHADER, 200, blend_multiply_asm,
+ {VEGA_BLEND_MULTIPLY_SHADER, blend_multiply,
VG_TRUE, 1, 1, 2, 1, 0, 5},
- {VEGA_BLEND_SCREEN_SHADER, 200, blend_screen_asm,
+ {VEGA_BLEND_SCREEN_SHADER, blend_screen,
VG_TRUE, 0, 0, 2, 1, 0, 4},
- {VEGA_BLEND_DARKEN_SHADER, 200, blend_darken_asm,
+ {VEGA_BLEND_DARKEN_SHADER, blend_darken,
VG_TRUE, 1, 1, 2, 1, 0, 6},
- {VEGA_BLEND_LIGHTEN_SHADER, 200, blend_lighten_asm,
+ {VEGA_BLEND_LIGHTEN_SHADER, blend_lighten,
VG_TRUE, 1, 1, 2, 1, 0, 6},
/* premultiply */
- {VEGA_PREMULTIPLY_SHADER, 100, premultiply_asm,
+ {VEGA_PREMULTIPLY_SHADER, premultiply,
VG_FALSE, 0, 0, 0, 0, 0, 1},
- {VEGA_UNPREMULTIPLY_SHADER, 100, unpremultiply_asm,
+ {VEGA_UNPREMULTIPLY_SHADER, unpremultiply,
VG_FALSE, 0, 0, 0, 0, 0, 1},
/* color transform to black and white */
- {VEGA_BW_SHADER, 150, color_bw_asm,
+ {VEGA_BW_SHADER, color_bw,
VG_FALSE, 1, 1, 0, 0, 0, 3},
};
#endif
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 1112ad9839..2e10965be4 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -37,7 +37,7 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_blit.h"
#include "util/u_format.h"
#include "util/u_tile.h"
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 42300bb6d5..467b95b751 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -35,7 +35,7 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
@@ -217,7 +217,7 @@ static void setup_mask_framebuffer(struct pipe_surface *surf,
static void setup_mask_operation(VGMaskOperation operation)
{
struct vg_context *ctx = vg_current_context();
- struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf;
+ struct pipe_buffer **cbuf = &ctx->mask.cbuf;
const VGint param_bytes = 4 * sizeof(VGfloat);
const VGfloat ones[4] = {1.f, 1.f, 1.f, 1.f};
void *shader = 0;
@@ -225,17 +225,17 @@ static void setup_mask_operation(VGMaskOperation operation)
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization.
*/
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ pipe_buffer_reference(cbuf, NULL);
- cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 1,
- PIPE_BUFFER_USAGE_CONSTANT,
- param_bytes);
- if (cbuf->buffer) {
- st_no_flush_pipe_buffer_write(ctx, cbuf->buffer,
+ *cbuf = pipe_buffer_create(ctx->pipe->screen, 1,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
+ if (*cbuf) {
+ st_no_flush_pipe_buffer_write(ctx, *cbuf,
0, param_bytes, ones);
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+ ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
switch (operation) {
case VG_UNION_MASK: {
if (!ctx->mask.union_fs) {
@@ -320,22 +320,22 @@ static void setup_mask_samplers(struct pipe_texture *umask)
static void setup_mask_fill(const VGfloat color[4])
{
struct vg_context *ctx = vg_current_context();
- struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf;
+ struct pipe_buffer **cbuf = &ctx->mask.cbuf;
const VGint param_bytes = 4 * sizeof(VGfloat);
/* We always need to get a new buffer, to keep the drivers simple and
* avoid gratuitous rendering synchronization.
*/
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ pipe_buffer_reference(cbuf, NULL);
- cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 1,
- PIPE_BUFFER_USAGE_CONSTANT,
- param_bytes);
- if (cbuf->buffer) {
- st_no_flush_pipe_buffer_write(ctx, cbuf->buffer, 0, param_bytes, color);
+ *cbuf = pipe_buffer_create(ctx->pipe->screen, 1,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
+ if (*cbuf) {
+ st_no_flush_pipe_buffer_write(ctx, *cbuf, 0, param_bytes, color);
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+ ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
cso_set_fragment_shader_handle(ctx->cso_context,
shaders_cache_fill(ctx->sc,
VEGA_SOLID_FILL_SHADER));
@@ -354,15 +354,12 @@ static void setup_mask_blend()
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_R;
- blend.colormask |= PIPE_MASK_G;
- blend.colormask |= PIPE_MASK_B;
- blend.colormask |= PIPE_MASK_A;
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
cso_set_blend(ctx->cso_context, &blend);
}
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index cc73771d35..3405d635f0 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -32,7 +32,7 @@
#include "st_inlines.h"
#include "pipe/p_compiler.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_format.h"
#include "util/u_memory.h"
@@ -77,7 +77,8 @@ struct vg_paint {
struct pipe_sampler_state sampler;
} pattern;
- struct pipe_constant_buffer cbuf;
+ /* XXX next 3 all unneded? */
+ struct pipe_buffer *cbuf;
struct pipe_shader_state fs_state;
void *fs;
};
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index b6d282d803..f56ea0c8b4 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -37,7 +37,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/u_draw_quad.h"
@@ -248,12 +248,12 @@ VGboolean polygon_is_closed(struct polygon *p)
static void set_blend_for_fill(struct pipe_blend_state *blend)
{
memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->colormask = 0; /*disable colorwrites*/
+ blend->rt[0].colormask = 0; /*disable colorwrites*/
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
}
static void draw_polygon(struct vg_context *ctx,
@@ -293,6 +293,7 @@ static void draw_polygon(struct vg_context *ctx,
/* tell pipe about the vertex attributes */
velement.src_offset = 0;
+ velement.instance_divisor = 0;
velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
velement.nr_components = COMPONENTS;
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 64e3a7c545..05620efa9c 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -30,7 +30,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
@@ -317,11 +317,11 @@ void renderer_copy_texture(struct renderer *ctx,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(ctx->cso, &blend);
}
@@ -486,11 +486,11 @@ void renderer_copy_surface(struct renderer *ctx,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(ctx->cso, &blend);
}
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index d9074a377b..0e71a507bf 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -35,7 +35,7 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_memory.h"
#define MAX_CONSTANTS 20
@@ -51,7 +51,7 @@ struct shader {
VGImageMode image_mode;
float constants[MAX_CONSTANTS];
- struct pipe_constant_buffer cbuf;
+ struct pipe_buffer *cbuf;
struct pipe_shader_state fs_state;
void *fs;
};
@@ -96,25 +96,25 @@ static void setup_constant_buffer(struct shader *shader)
{
struct vg_context *ctx = shader->context;
struct pipe_context *pipe = shader->context->pipe;
- struct pipe_constant_buffer *cbuf = &shader->cbuf;
+ struct pipe_buffer **cbuf = &shader->cbuf;
VGint param_bytes = paint_constant_buffer_size(shader->paint);
float temp_buf[MAX_CONSTANTS];
assert(param_bytes <= sizeof(temp_buf));
paint_fill_constant_buffer(shader->paint, temp_buf);
- if (cbuf->buffer == NULL ||
+ if (*cbuf == NULL ||
memcmp(temp_buf, shader->constants, param_bytes) != 0)
{
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ pipe_buffer_reference(cbuf, NULL);
memcpy(shader->constants, temp_buf, param_bytes);
- cbuf->buffer = pipe_user_buffer_create(pipe->screen,
- &shader->constants,
- sizeof(shader->constants));
+ *cbuf = pipe_user_buffer_create(pipe->screen,
+ &shader->constants,
+ sizeof(shader->constants));
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+ ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_FRAGMENT, 0, *cbuf);
}
static VGint blend_bind_samplers(struct vg_context *ctx,
@@ -135,8 +135,8 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
textures[2] = stfb->blend_texture;
if (!samplers[0] || !textures[0]) {
- samplers[1] = samplers[2];
- textures[1] = textures[2];
+ samplers[0] = samplers[2];
+ textures[0] = textures[2];
}
if (!samplers[1] || !textures[1]) {
samplers[1] = samplers[0];
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index f620075d0b..f43fe6ee4c 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -30,7 +30,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
@@ -123,17 +123,23 @@ static INLINE VGint range_max(VGint max, VGint current)
return MAX2(max, current);
}
-static void
-create_preamble(char *txt,
- const struct shader_asm_info *shaders[SHADER_STAGES],
- int num_shaders)
+static void *
+combine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
+ struct pipe_context *pipe,
+ struct pipe_shader_state *shader)
{
VGboolean declare_input = VG_FALSE;
VGint start_const = -1, end_const = 0;
VGint start_temp = -1, end_temp = 0;
VGint start_sampler = -1, end_sampler = 0;
- VGint i;
+ VGint i, current_shader = 0;
VGint num_consts, num_temps, num_samplers;
+ struct ureg_program *ureg;
+ struct ureg_src in[2];
+ struct ureg_src *sampler = NULL;
+ struct ureg_src *constant = NULL;
+ struct ureg_dst out, *temp = NULL;
+ void *p = NULL;
for (i = 0; i < num_shaders; ++i) {
if (shaders[i]->num_consts)
@@ -158,99 +164,94 @@ create_preamble(char *txt,
if (start_temp < 0)
start_temp = 0;
if (start_sampler < 0)
- start_sampler = 0;
+ start_sampler = 0;
num_consts = end_const - start_const;
num_temps = end_temp - start_temp;
num_samplers = end_sampler - start_sampler;
- /* end exclusive */
- --end_const;
- --end_temp;
- --end_sampler;
- sprintf(txt, "FRAG\n");
+ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!ureg)
+ return NULL;
if (declare_input) {
- sprintf(txt + strlen(txt), "DCL IN[0], POSITION, LINEAR\n");
- sprintf(txt + strlen(txt), "DCL IN[1], GENERIC[0], PERSPECTIVE\n");
+ in[0] = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_POSITION,
+ 0,
+ TGSI_INTERPOLATE_LINEAR);
+ in[1] = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_GENERIC,
+ 0,
+ TGSI_INTERPOLATE_PERSPECTIVE);
}
/* we always have a color output */
- sprintf(txt + strlen(txt), "DCL OUT[0], COLOR, CONSTANT\n");
-
- if (num_consts > 1)
- sprintf(txt + strlen(txt), "DCL CONST[%d..%d], CONSTANT\n", start_const, end_const);
- else if (num_consts == 1)
- sprintf(txt + strlen(txt), "DCL CONST[%d], CONSTANT\n", start_const);
-
- if (num_temps > 1)
- sprintf(txt + strlen(txt), "DCL TEMP[%d..%d], CONSTANT\n", start_temp, end_temp);
- else if (num_temps > 1)
- sprintf(txt + strlen(txt), "DCL TEMP[%d], CONSTANT\n", start_temp);
-
- if (num_samplers > 1)
- sprintf(txt + strlen(txt), "DCL SAMP[%d..%d], CONSTANT\n", start_sampler, end_sampler);
- else if (num_samplers == 1)
- sprintf(txt + strlen(txt), "DCL SAMP[%d], CONSTANT\n", start_sampler);
-}
+ out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
-static void *
-combine_shaders(const struct shader_asm_info *shaders[SHADER_STAGES], int num_shaders,
- struct pipe_context *pipe,
- struct pipe_shader_state *shader)
-{
- char *combined_txt;
- int combined_len = MAX_PREAMBLE;
- int combined_tokens = 0;
- int i = 0;
- int current_shader = 0;
- int current_len;
+ if (num_consts >= 1) {
+ constant = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_const);
+ for (i = start_const; i < end_const; i++) {
+ constant[i] = ureg_DECL_constant(ureg, i);
+ }
- for (i = 0; i < num_shaders; ++i) {
- combined_len += strlen(shaders[i]->txt);
- combined_tokens += shaders[i]->num_tokens;
}
- /* add for the %s->TEMP[0] substitutions */
- combined_len += num_shaders * 7 /*TEMP[0]*/ + 4 /*"END\n"*/;
- combined_txt = (char*)malloc(combined_len);
- combined_txt[0] = '\0';
+ if (num_temps >= 1) {
+ temp = (struct ureg_dst *) malloc(sizeof(struct ureg_dst) * end_temp);
+ for (i = start_temp; i < end_temp; i++) {
+ temp[i] = ureg_DECL_temporary(ureg);
+ }
+ }
- create_preamble(combined_txt, shaders, num_shaders);
+ if (num_samplers >= 1) {
+ sampler = (struct ureg_src *) malloc(sizeof(struct ureg_src) * end_sampler);
+ for (i = start_sampler; i < end_sampler; i++) {
+ sampler[i] = ureg_DECL_sampler(ureg, i);
+ }
+ }
while (current_shader < num_shaders) {
- const char temp[] = "TEMP[0]";
- const char out[] = "OUT[0]";
- const char *subst = temp;
-
- current_len = strlen(combined_txt);
-
- /* if the last shader then output */
- if (current_shader + 1 == num_shaders)
- subst = out;
-
- snprintf(combined_txt + current_len,
- combined_len - current_len,
- shaders[current_shader]->txt,
- subst);
- ++current_shader;
+ if ((current_shader + 1) == num_shaders) {
+ shaders[current_shader]->func(ureg,
+ &out,
+ in,
+ sampler,
+ temp,
+ constant);
+ } else {
+ shaders[current_shader]->func(ureg,
+ &temp[0],
+ in,
+ sampler,
+ temp,
+ constant);
+ }
+ current_shader++;
}
+ ureg_END(ureg);
- current_len = strlen(combined_txt);
- snprintf(combined_txt + current_len,
- combined_len - current_len,
- "END\n");
+ shader->tokens = ureg_finalize(ureg);
+ if(!shader->tokens)
+ return NULL;
- debug_printf("Combined shader is : \n%s\n",
- combined_txt);
+ p = pipe->create_fs_state(pipe, shader);
+ ureg_destroy(ureg);
- shader->tokens = tokens_from_assembly(
- combined_txt, combined_tokens);
+ if (num_temps >= 1) {
+ for (i = start_temp; i < end_temp; i++) {
+ ureg_release_temporary(ureg, temp[i]);
+ }
+ }
- free(combined_txt);
+ if (temp)
+ free(temp);
+ if (constant)
+ free(constant);
+ if (sampler)
+ free(sampler);
- return pipe->create_fs_state(pipe, shader);
+ return p;
}
static void *
diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h
index 610755e063..419151c3ae 100644
--- a/src/gallium/state_trackers/vega/st_inlines.h
+++ b/src/gallium/state_trackers/vega/st_inlines.h
@@ -38,7 +38,7 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_defines.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_state.h"
static INLINE struct pipe_transfer *
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 00d23f5c22..426bf9bc62 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -34,7 +34,7 @@
#include "st_inlines.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "cso_cache/cso_context.h"
@@ -122,8 +122,8 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
void vg_destroy_context(struct vg_context *ctx)
{
- struct pipe_constant_buffer *cbuf = &ctx->mask.cbuf;
- struct pipe_constant_buffer *vsbuf = &ctx->vs_const_buffer;
+ struct pipe_buffer **cbuf = &ctx->mask.cbuf;
+ struct pipe_buffer **vsbuf = &ctx->vs_const_buffer;
util_destroy_blit(ctx->blit);
renderer_destroy(ctx->renderer);
@@ -131,11 +131,11 @@ void vg_destroy_context(struct vg_context *ctx)
shader_destroy(ctx->shader);
paint_destroy(ctx->default_paint);
- if (cbuf && cbuf->buffer)
- pipe_buffer_reference(&cbuf->buffer, NULL);
+ if (*cbuf)
+ pipe_buffer_reference(cbuf, NULL);
- if (vsbuf && vsbuf->buffer)
- pipe_buffer_reference(&vsbuf->buffer, NULL);
+ if (*vsbuf)
+ pipe_buffer_reference(vsbuf, NULL);
if (ctx->clear.fs) {
cso_delete_fragment_shader(ctx->cso_context, ctx->clear.fs);
@@ -252,7 +252,7 @@ static void update_clip_state(struct vg_context *ctx)
ctx->pipe->clear(ctx->pipe, PIPE_CLEAR_DEPTHSTENCIL, NULL, 1.0, 0);
/* disable color writes */
- blend->colormask = 0; /*disable colorwrites*/
+ blend->rt[0].colormask = 0; /*disable colorwrites*/
cso_set_blend(ctx->cso_context, blend);
/* enable scissoring */
@@ -286,7 +286,6 @@ static void update_clip_state(struct vg_context *ctx)
renderer_draw_quad(ctx->renderer, minx, miny, maxx, maxy, 0.0f);
}
- blend->colormask = 1; /*enable colorwrites*/
cso_restore_blend(ctx->cso_context);
cso_restore_fragment_shader(ctx->cso_context);
@@ -301,57 +300,56 @@ void vg_validate_state(struct vg_context *ctx)
if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));
- blend->blend_enable = 1;
- blend->colormask |= PIPE_MASK_R;
- blend->colormask |= PIPE_MASK_G;
- blend->colormask |= PIPE_MASK_B;
- blend->colormask |= PIPE_MASK_A;
+ blend->rt[0].blend_enable = 1;
+ blend->rt[0].colormask = PIPE_MASK_RGBA;
switch (ctx->state.vg.blend_mode) {
case VG_BLEND_SRC:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].blend_enable = 0;
break;
case VG_BLEND_SRC_OVER:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
break;
case VG_BLEND_DST_OVER:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
break;
case VG_BLEND_SRC_IN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
break;
case VG_BLEND_DST_IN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
break;
case VG_BLEND_MULTIPLY:
case VG_BLEND_SCREEN:
case VG_BLEND_DARKEN:
case VG_BLEND_LIGHTEN:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend->rt[0].blend_enable = 0;
break;
case VG_BLEND_ADDITIVE:
- blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
- blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
break;
default:
assert(!"not implemented blend mode");
@@ -371,20 +369,20 @@ void vg_validate_state(struct vg_context *ctx)
2.f/fb->width, 2.f/fb->height, 1, 1,
-1, -1, 0, 0
};
- struct pipe_constant_buffer *cbuf = &ctx->vs_const_buffer;
+ struct pipe_buffer **cbuf = &ctx->vs_const_buffer;
vg_set_viewport(ctx, VEGA_Y0_BOTTOM);
- pipe_buffer_reference(&cbuf->buffer, NULL);
- cbuf->buffer = pipe_buffer_create(ctx->pipe->screen, 16,
+ pipe_buffer_reference(cbuf, NULL);
+ *cbuf = pipe_buffer_create(ctx->pipe->screen, 16,
PIPE_BUFFER_USAGE_CONSTANT,
param_bytes);
- if (cbuf->buffer) {
- st_no_flush_pipe_buffer_write(ctx, cbuf->buffer,
+ if (*cbuf) {
+ st_no_flush_pipe_buffer_write(ctx, *cbuf,
0, param_bytes, vs_consts);
}
- ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, cbuf);
+ ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf);
}
if ((ctx->state.dirty & VS_DIRTY)) {
cso_set_vertex_shader_handle(ctx->cso_context,
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index ccc8889c8c..bc88c8d139 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -50,7 +50,7 @@ struct st_renderbuffer {
};
struct st_framebuffer {
- VGint init_width, init_height;
+ VGint width, height;
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
@@ -113,7 +113,7 @@ struct vg_context
} clear;
struct {
- struct pipe_constant_buffer cbuf;
+ struct pipe_buffer *cbuf;
struct pipe_sampler_state sampler;
struct vg_shader *union_fs;
@@ -135,7 +135,7 @@ struct vg_context
struct pipe_sampler_state blend_sampler;
struct {
- struct pipe_constant_buffer buffer;
+ struct pipe_buffer *buffer;
void *color_matrix_fs;
} filter;
struct vg_paint *default_paint;
@@ -145,7 +145,7 @@ struct vg_context
struct vg_shader *plain_vs;
struct vg_shader *clear_vs;
struct vg_shader *texture_vs;
- struct pipe_constant_buffer vs_const_buffer;
+ struct pipe_buffer *vs_const_buffer;
};
struct vg_object {
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index e503913275..a94dfb160c 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -29,13 +29,16 @@
#include "mask.h"
#include "pipe/p_context.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_rect.h"
+/* advertise OpenVG support */
+PUBLIC const int st_api_OpenVG = 1;
+
static struct pipe_texture *
create_texture(struct pipe_context *pipe, enum pipe_format format,
VGint width, VGint height)
@@ -190,8 +193,8 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
*/
stfb->alpha_mask = 0;
- stfb->init_width = width;
- stfb->init_height = height;
+ stfb->width = width;
+ stfb->height = height;
stfb->privateData = privateData;
}
@@ -279,11 +282,14 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
/* If this is a noop, exit early and don't do the clear, etc below.
*/
- if (strb->width == width &&
- strb->height == height &&
+ if (stfb->width == width &&
+ stfb->height == height &&
state->zsbuf)
return;
+ stfb->width = width;
+ stfb->height = height;
+
if (strb->width != width || strb->height != height)
st_renderbuffer_alloc_storage(ctx, strb,
width, height);
@@ -368,14 +374,15 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb)
/* FIXME */
}
-void st_make_current(struct vg_context *st,
- struct st_framebuffer *draw,
- struct st_framebuffer *read)
+boolean st_make_current(struct vg_context *st,
+ struct st_framebuffer *draw,
+ struct st_framebuffer *read)
{
vg_set_current_context(st);
if (st) {
st->draw_buffer = draw;
}
+ return VG_TRUE;
}
struct vg_context *st_get_current(void)
@@ -425,3 +432,8 @@ int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
{
return 0;
}
+
+st_proc st_get_proc_address(const char *procname)
+{
+ return NULL;
+}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index 0f0c27f455..c1196954a7 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -99,9 +99,9 @@ PUBLIC
void st_unreference_framebuffer(struct st_framebuffer *stfb);
PUBLIC
-void st_make_current(struct vg_context *st,
- struct st_framebuffer *draw,
- struct st_framebuffer *read);
+boolean st_make_current(struct vg_context *st,
+ struct st_framebuffer *draw,
+ struct st_framebuffer *read);
PUBLIC
struct vg_context *st_get_current(void);
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index f2f0264844..0785d2c6b8 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -34,11 +34,6 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
#include "stw_icd.h"
#include "stw_device.h"
#include "stw_winsys.h"
@@ -152,7 +147,6 @@ DrvCreateLayerContext(
const struct stw_pixelformat_info *pfi;
GLvisual visual;
struct stw_context *ctx = NULL;
- struct pipe_screen *screen = NULL;
struct pipe_context *pipe = NULL;
if(!stw_dev)
@@ -175,28 +169,12 @@ DrvCreateLayerContext(
ctx->hdc = hdc;
ctx->iPixelFormat = iPixelFormat;
- screen = stw_dev->screen;
-
-#ifdef DEBUG
- /* Unwrap screen */
- if(stw_dev->trace_running)
- screen = trace_screen(screen)->screen;
-#endif
-
- pipe = stw_dev->stw_winsys->create_context( screen );
+ /* priv == hdc, pass to stw_flush_frontbuffer as context_private
+ */
+ pipe = stw_dev->screen->context_create( stw_dev->screen, hdc );
if (pipe == NULL)
goto no_pipe;
-#ifdef DEBUG
- /* Wrap context */
- if(stw_dev->trace_running)
- pipe = trace_context_create(stw_dev->screen, pipe);
-#endif
-
- /* pass to stw_flush_frontbuffer as context_private */
- assert(!pipe->priv);
- pipe->priv = hdc;
-
ctx->st = st_create_context( pipe, &visual, NULL );
if (ctx->st == NULL)
goto no_st_ctx;
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index 0bf3b0da82..a83841f6b7 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -30,7 +30,7 @@
#include "pipe/p_compiler.h"
-#include "pipe/p_thread.h"
+#include "os/os_thread.h"
#include "util/u_handle_table.h"
#include "stw_icd.h"
#include "stw_pixelformat.h"
diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index fb30ec5dba..8dd63f124a 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -48,32 +48,8 @@ wglGetGalliumScreenMESA(void)
struct pipe_context * APIENTRY
wglCreateGalliumContextMESA(void)
{
- struct pipe_screen *screen = NULL;
- struct pipe_context *pipe = NULL;
-
if(!stw_dev)
return NULL;
- screen = stw_dev->screen;
-
-#ifdef DEBUG
- /* Unwrap screen */
- if(stw_dev->trace_running)
- screen = trace_screen(screen)->screen;
-#endif
-
- pipe = stw_dev->stw_winsys->create_context( screen );
- if (pipe == NULL)
- goto no_pipe;
-
-#ifdef DEBUG
- /* Wrap context */
- if(stw_dev->trace_running)
- pipe = trace_context_create(stw_dev->screen, pipe);
-#endif
-
- return pipe;
-
-no_pipe:
- return NULL;
+ return stw_dev->screen->context_create( stw_dev->screen, NULL );
}
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index b80d168a7c..08cc4973bc 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -32,7 +32,7 @@
#include "main/mtypes.h"
-#include "pipe/p_thread.h"
+#include "os/os_thread.h"
struct pipe_surface;
struct stw_pixelformat_info;
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index 54cc361412..7d4c2430b0 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -95,8 +95,6 @@ stw_pf_depth_stencil[] = {
{ PIPE_FORMAT_Z24X8_UNORM, {24, 0} },
{ PIPE_FORMAT_X8Z24_UNORM, {24, 0} },
{ PIPE_FORMAT_Z16_UNORM, {16, 0} },
- /* pure stencil */
- { PIPE_FORMAT_S8_UNORM, { 0, 8} },
/* combined depth-stencil */
{ PIPE_FORMAT_S8Z24_UNORM, {24, 8} },
{ PIPE_FORMAT_Z24S8_UNORM, {24, 8} }
@@ -220,7 +218,8 @@ stw_pixelformat_init( void )
const struct stw_pf_color_info *color = &stw_pf_color[j];
if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ PIPE_TEXTURE_USAGE_RENDER_TARGET |
+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET, 0))
continue;
for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) {
diff --git a/src/gallium/state_trackers/wgl/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h
index 1de6e906d0..270fad56a1 100644
--- a/src/gallium/state_trackers/wgl/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/stw_winsys.h
@@ -43,9 +43,6 @@ struct stw_winsys
struct pipe_screen *
(*create_screen)( void );
- struct pipe_context *
- (*create_context)( struct pipe_screen *screen );
-
/**
* Present the color buffer to the window associated with the device context.
*/
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 1c248a629e..c50873c150 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -4,10 +4,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
-#include "util/u_draw_quad.h"
-#include "util/u_math.h"
-#include "pipe/p_inlines.h"
/*XXX also in Xrender.h but the including it here breaks compilition */
#define XFixedToDouble(f) (((double) (f)) / 65536.)
@@ -220,13 +217,13 @@ bind_blend_state(struct exa_context *exa, int op,
blend_for_op(&blend_opt, op, pSrcPicture, pMaskPicture, pDstPicture);
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 1;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
- blend.rgb_src_factor = blend_opt.rgb_src;
- blend.alpha_src_factor = blend_opt.rgb_src;
- blend.rgb_dst_factor = blend_opt.rgb_dst;
- blend.alpha_dst_factor = blend_opt.rgb_dst;
+ blend.rt[0].rgb_src_factor = blend_opt.rgb_src;
+ blend.rt[0].alpha_src_factor = blend_opt.rgb_src;
+ blend.rt[0].rgb_dst_factor = blend_opt.rgb_dst;
+ blend.rt[0].alpha_dst_factor = blend_opt.rgb_dst;
cso_set_blend(exa->renderer->cso, &blend);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 650d2c0d1d..221ce772af 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -49,8 +49,7 @@
#include <X11/extensions/dpms.h>
#endif
-#include "pipe/p_inlines.h"
-#include "util/u_format.h"
+#include "util/u_inlines.h"
#include "util/u_rect.h"
#ifdef HAVE_LIBKMS
@@ -243,7 +242,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
unsigned attr[8];
attr[0] = KMS_BO_TYPE;
+#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
+ attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
+#else
attr[1] = KMS_BO_TYPE_CURSOR;
+#endif
attr[2] = KMS_WIDTH;
attr[3] = 64;
attr[4] = KMS_HEIGHT;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index fd82f4fa1d..7457fe1c6d 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -38,15 +38,17 @@
#include "dri2.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include "util/u_format.h"
-#include "util/u_rect.h"
/* Make all the #if cases in the code esier to read */
-/* XXX can it be set to 1? */
#ifndef DRI2INFOREC_VERSION
-#define DRI2INFOREC_VERSION 0
+#define DRI2INFOREC_VERSION 1
+#endif
+
+#if DRI2INFOREC_VERSION == 2
+static Bool set_format_in_do_create_buffer;
#endif
typedef struct {
@@ -147,7 +149,9 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
#if DRI2INFOREC_VERSION == 2
- ((DRI2Buffer2Ptr)buffer)->format = 0;
+ /* ABI forwards/backwards compatibility */
+ if (set_format_in_do_create_buffer)
+ ((DRI2Buffer2Ptr)buffer)->format = 0;
#elif DRI2INFOREC_VERSION >= 3
buffer->format = 0;
#endif
@@ -211,7 +215,9 @@ dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
xfree(buffer);
}
-#else /* DRI2INFOREC_VERSION < 2 */
+#endif /* DRI2INFOREC_VERSION >= 2 */
+
+#if DRI2INFOREC_VERSION <= 2
static DRI2BufferPtr
dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count)
@@ -261,7 +267,7 @@ dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
-#endif /* DRI2INFOREC_VERSION >= 2 */
+#endif /* DRI2INFOREC_VERSION <= 2 */
static void
dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
@@ -369,12 +375,19 @@ xorg_dri2_init(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
-
#if DRI2INFOREC_VERSION >= 2
- dri2info.version = DRI2INFOREC_VERSION;
-#else
- dri2info.version = 1;
+ int major, minor;
+
+ if (xf86LoaderCheckSymbol("DRI2Version")) {
+ DRI2Version(&major, &minor);
+ } else {
+ /* Assume version 1.0 */
+ major = 1;
+ minor = 0;
+ }
#endif
+
+ dri2info.version = DRI2INFOREC_VERSION;
dri2info.fd = ms->fd;
dri2info.driverName = pScrn->driverName;
@@ -383,7 +396,22 @@ xorg_dri2_init(ScreenPtr pScreen)
#if DRI2INFOREC_VERSION >= 2
dri2info.CreateBuffer = dri2_create_buffer;
dri2info.DestroyBuffer = dri2_destroy_buffer;
-#else
+#endif
+
+ /* For X servers in the 1.6.x series there where two DRI2 version.
+ * This allows us to build one binary that works on both servers.
+ */
+#if DRI2INFOREC_VERSION == 2
+ if (minor == 0) {
+ set_format_in_do_create_buffer = FALSE;
+ dri2info.CreateBuffers = dri2_create_buffers;
+ dri2info.DestroyBuffers = dri2_destroy_buffers;
+ } else
+ set_format_in_do_create_buffer = FALSE;
+#endif
+
+ /* For version 1 set these unconditionaly. */
+#if DRI2INFOREC_VERSION == 1
dri2info.CreateBuffers = dri2_create_buffers;
dri2info.DestroyBuffers = dri2_destroy_buffers;
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index b02fe68f31..f53a879a14 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -45,7 +45,6 @@
#include "miscstruct.h"
#include "dixstruct.h"
#include "xf86xv.h"
-#include <X11/extensions/Xv.h>
#ifndef XSERVER_LIBPCIACCESS
#error "libpciaccess needed"
#endif
@@ -79,11 +78,13 @@ typedef enum
{
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
+ OPTION_DEBUG_FALLBACK,
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -111,6 +112,28 @@ xorg_tracker_set_functions(ScrnInfoPtr scrn)
scrn->ValidMode = drv_valid_mode;
}
+Bool
+xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device)
+{
+ char *BusID = xalloc(64);
+ sprintf(BusID, "pci:%04x:%02x:%02x.%d",
+ device->domain, device->bus,
+ device->dev, device->func);
+
+ if (drmCheckModesettingSupported(BusID)) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
+ "Drm modesetting not supported %s\n", BusID);
+ xfree(BusID);
+ return FALSE;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
+ "Drm modesetting supported on %s\n", BusID);
+
+ xfree(BusID);
+ return TRUE;
+}
+
/*
* Internal function definitions
@@ -206,16 +229,41 @@ drv_init_drm(ScrnInfoPtr pScrn)
ms->PciInfo->dev, ms->PciInfo->func
);
- ms->fd = drmOpen(NULL, BusID);
- if (ms->fd < 0)
- return FALSE;
+ ms->api = drm_api_create();
+ ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID);
+ xfree(BusID);
+
+ if (ms->fd >= 0)
+ return TRUE;
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+
+ ms->api = NULL;
+
+ return FALSE;
}
return TRUE;
}
static Bool
+drv_close_drm(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+ ms->api = NULL;
+
+ drmClose(ms->fd);
+ ms->fd = -1;
+
+ return TRUE;
+}
+
+static Bool
drv_init_resource_management(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
@@ -229,7 +277,6 @@ drv_init_resource_management(ScrnInfoPtr pScrn)
if (ms->screen || ms->kms)
return TRUE;
- ms->api = drm_api_create();
if (ms->api) {
ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
@@ -269,10 +316,6 @@ drv_close_resource_management(ScrnInfoPtr pScrn)
}
ms->screen = NULL;
- if (ms->api && ms->api->destroy)
- ms->api->destroy(ms->api);
- ms->api = NULL;
-
#ifdef HAVE_LIBKMS
if (ms->kms)
kms_destroy(&ms->kms);
@@ -629,10 +672,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
+ ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
+ ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
+
if (ms->screen) {
- ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
- OPTION_2D_ACCEL, TRUE));
- ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+ ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
xorg_xv_init(pScreen);
#ifdef DRI2
@@ -640,6 +684,17 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#endif
}
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
+ ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
+ ms->debug_fallback ? "enabled" : "disabled");
+#ifdef DRI2
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is %s\n",
+ ms->screen ? "enabled" : "disabled");
+#else
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
+#endif
+
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
@@ -823,8 +878,7 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
drv_close_resource_management(pScrn);
- drmClose(ms->fd);
- ms->fd = -1;
+ drv_close_drm(pScrn);
pScrn->vtSema = FALSE;
pScreen->CloseScreen = ms->CloseScreen;
@@ -954,7 +1008,11 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
int ret;
attr[0] = KMS_BO_TYPE;
+#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8
+ attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8;
+#else
attr[1] = KMS_BO_TYPE_SCANOUT;
+#endif
attr[2] = KMS_WIDTH;
attr[3] = pScrn->virtualX;
attr[4] = KMS_HEIGHT;
@@ -1012,12 +1070,22 @@ drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
goto err_destroy;
pScreen->ModifyPixmapHeader(rootPixmap,
- pScreen->width,
- pScreen->height,
+ pScrn->virtualX,
+ pScrn->virtualY,
pScreen->rootDepth,
pScrn->bitsPerPixel,
stride,
ptr);
+
+ /* This a hack to work around EnableDisableFBAccess setting the pointer
+ * the real fix would be to replace pScrn->EnableDisableFBAccess hook
+ * and set the rootPixmap->devPrivate.ptr to something valid before that.
+ *
+ * But in its infinit visdome something uses either this some times before
+ * that, so our hook doesn't get called before the crash happens.
+ */
+ pScrn->pixmapPrivate.ptr = ptr;
+
return TRUE;
err_destroy:
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index d9432babf1..ae66c4baa9 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -41,9 +41,7 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-#include "util/u_format.h"
#include "util/u_rect.h"
#include "util/u_math.h"
#include "util/u_debug.h"
@@ -1063,7 +1061,10 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
}
exa->scrn = ms->screen;
- exa->pipe = ms->api->create_context(ms->api, exa->scrn);
+ exa->pipe = exa->scrn->context_create(exa->scrn, NULL);
+ if (exa->pipe == NULL)
+ goto out_err;
+
/* Share context with DRI */
ms->ctx = exa->pipe;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index bed17caab7..3e5e6bd6a6 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -6,11 +6,9 @@
#include "pipe/p_format.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_memory.h"
-#include "util/u_simple_shaders.h"
#include "tgsi/tgsi_ureg.h"
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 251f331ea7..13c3fb97e3 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -49,8 +49,6 @@
#include <X11/extensions/dpms.h>
#endif
-#include "X11/Xatom.h"
-
#include "xorg_tracker.h"
static char *output_enum_list[] = {
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index d80f341e6c..83b0d31e38 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -5,12 +5,11 @@
#include "cso_cache/cso_context.h"
#include "util/u_draw_quad.h"
-#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
#include <math.h>
@@ -379,14 +378,14 @@ struct xorg_renderer * renderer_create(struct pipe_context *pipe)
void renderer_destroy(struct xorg_renderer *r)
{
- struct pipe_constant_buffer *vsbuf = &r->vs_const_buffer;
- struct pipe_constant_buffer *fsbuf = &r->fs_const_buffer;
+ struct pipe_buffer **vsbuf = &r->vs_const_buffer;
+ struct pipe_buffer **fsbuf = &r->fs_const_buffer;
- if (vsbuf && vsbuf->buffer)
- pipe_buffer_reference(&vsbuf->buffer, NULL);
+ if (*vsbuf)
+ pipe_buffer_reference(vsbuf, NULL);
- if (fsbuf && fsbuf->buffer)
- pipe_buffer_reference(&fsbuf->buffer, NULL);
+ if (*fsbuf)
+ pipe_buffer_reference(fsbuf, NULL);
if (r->shaders) {
xorg_shaders_destroy(r->shaders);
@@ -409,20 +408,20 @@ void renderer_set_constants(struct xorg_renderer *r,
const float *params,
int param_bytes)
{
- struct pipe_constant_buffer *cbuf =
+ struct pipe_buffer **cbuf =
(shader_type == PIPE_SHADER_VERTEX) ? &r->vs_const_buffer :
&r->fs_const_buffer;
- pipe_buffer_reference(&cbuf->buffer, NULL);
- cbuf->buffer = pipe_buffer_create(r->pipe->screen, 16,
- PIPE_BUFFER_USAGE_CONSTANT,
- param_bytes);
+ pipe_buffer_reference(cbuf, NULL);
+ *cbuf = pipe_buffer_create(r->pipe->screen, 16,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
- if (cbuf->buffer) {
- pipe_buffer_write(r->pipe->screen, cbuf->buffer,
+ if (*cbuf) {
+ pipe_buffer_write(r->pipe->screen, *cbuf,
0, param_bytes, params);
}
- r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf);
+ r->pipe->set_constant_buffer(r->pipe, shader_type, 0, *cbuf);
}
@@ -445,11 +444,11 @@ void renderer_copy_prepare(struct xorg_renderer *r,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.colormask = PIPE_MASK_RGBA;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
cso_set_blend(r->cso, &blend);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 5272cde2b3..af6aa0567d 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -23,8 +23,8 @@ struct xorg_renderer {
int fb_width;
int fb_height;
- struct pipe_constant_buffer vs_const_buffer;
- struct pipe_constant_buffer fs_const_buffer;
+ struct pipe_buffer *vs_const_buffer;
+ struct pipe_buffer *fs_const_buffer;
float buffer[BUF_SIZE];
int buffer_size;
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 4d5d4780dc..58bb60a721 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -47,6 +47,8 @@
#endif
#include "pipe/p_screen.h"
+#include "util/u_inlines.h"
+#include "util/u_debug.h"
#include "state_tracker/drm_api.h"
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@@ -112,6 +114,7 @@ typedef struct _modesettingRec
/* exa */
struct exa_context *exa;
Bool noEvict;
+ Bool accelerate_2d;
Bool debug_fallback;
/* winsys hocks */
diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h
index 47ee4b9ffd..865733bca2 100644
--- a/src/gallium/state_trackers/xorg/xorg_winsys.h
+++ b/src/gallium/state_trackers/xorg/xorg_winsys.h
@@ -45,5 +45,6 @@
void xorg_tracker_set_functions(ScrnInfoPtr scrn);
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
+Bool xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device);
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 6b5a41a372..3dcef22c13 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -11,9 +11,6 @@
#include "cso_cache/cso_context.h"
#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
-
-#include "util/u_format.h"
/*XXX get these from pipe's texture limits */
#define IMAGE_MAX_WIDTH 2048
@@ -403,14 +400,14 @@ bind_blend_state(struct xorg_xv_port_priv *port)
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(struct pipe_blend_state));
- blend.blend_enable = 1;
- blend.colormask |= PIPE_MASK_RGBA;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
/* porter&duff src */
- blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
- blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
- blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
cso_set_blend(port->r->cso, &blend);
}
@@ -486,8 +483,11 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
int dxo, dyo;
Bool hdtv;
int x, y, w, h;
- struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap);
- struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+ struct exa_pixmap_priv *dst;
+ struct pipe_surface *dst_surf = NULL;
+
+ exaMoveInPixmap(pPixmap);
+ dst = exaGetPixmapDriverPrivate(pPixmap);
if (dst && !dst->tex) {
xorg_exa_set_shared_usage(pPixmap);
@@ -497,6 +497,7 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
if (!dst || !dst->tex)
XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
+ dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
hdtv = ((src_w >= RES_720P_X) && (src_h >= RES_720P_Y));
REGION_TRANSLATE(pScrn->pScreen, dstRegion, -pPixmap->screen_x,
@@ -516,7 +517,6 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
bind_samplers(pPriv);
setup_fs_video_constants(pPriv->r, hdtv);
- exaMoveInPixmap(pPixmap);
DamageDamageRegion(&pPixmap->drawable, dstRegion);
while (nbox--) {