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/dri/common/dri_context.h2
-rw-r--r--src/gallium/state_trackers/dri/drm/SConscript1
-rw-r--r--src/gallium/state_trackers/egl/SConscript32
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c2
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c102
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c83
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c235
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.h70
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c427
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c111
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h6
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c244
-rw-r--r--src/gallium/state_trackers/python/p_context.i42
-rw-r--r--src/gallium/state_trackers/vega/SConscript51
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c11
-rw-r--r--src/gallium/state_trackers/vega/arc.c3
-rw-r--r--src/gallium/state_trackers/vega/renderer.c3
-rw-r--r--src/gallium/state_trackers/vega/stroker.c5
-rw-r--r--src/gallium/state_trackers/vega/util_array.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c9
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c63
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h12
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c14
28 files changed, 1204 insertions, 352 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 54e56c6499..b29e853383 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -65,6 +65,8 @@ struct dri_context
static INLINE struct dri_context *
dri_context(__DRIcontext * driContextPriv)
{
+ if (!driContextPriv)
+ return NULL;
return (struct dri_context *)driContextPriv->driverPrivate;
}
diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript
index 965dc95760..0c279d2236 100644
--- a/src/gallium/state_trackers/dri/drm/SConscript
+++ b/src/gallium/state_trackers/dri/drm/SConscript
@@ -22,7 +22,6 @@ if env['dri']:
'dri_drawable.c',
'dri_screen.c',
'dri1_helper.c',
- 'dri1.c',
'dri2.c',
]
)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
new file mode 100644
index 0000000000..c4d01d6b28
--- /dev/null
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -0,0 +1,32 @@
+#######################################################################
+# SConscript for egl state_tracker
+
+Import('*')
+
+if 'egl' in env['statetrackers']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/egl/main',
+ '#/src/gallium/winsys/sw',
+ '.',
+ ])
+
+ common_sources = [
+ 'common/egl_g3d.c',
+ 'common/egl_g3d_api.c',
+ 'common/egl_g3d_image.c',
+ 'common/egl_g3d_st.c',
+ 'common/native_helper.c',
+ ]
+
+ gdi_sources = common_sources + [
+ 'gdi/native_gdi.c',
+ ]
+
+ st_egl_gdi = env.ConvenienceLibrary(
+ target = 'st_egl_gdi',
+ source = gdi_sources,
+ )
+ Export('st_egl_gdi')
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index d63b81a1c5..361cc7960b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -426,7 +426,7 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
}
static struct native_event_handler egl_g3d_native_event_handler = {
- .invalid_surface = egl_g3d_invalid_surface
+ egl_g3d_invalid_surface
};
static EGLBoolean
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 5a3c80b968..d516d8fe03 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -75,6 +75,9 @@ struct egl_g3d_surface {
struct native_surface *native;
struct pipe_resource *render_texture;
+ EGLenum client_buffer_type;
+ EGLClientBuffer client_buffer;
+
unsigned int sequence_number;
};
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 4615a5829a..255a1fb730 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -267,16 +267,16 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
-static _EGLSurface *
-egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, const EGLint *attribs)
+static struct egl_g3d_surface *
+create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf,
+ const EGLint *attribs, const char *func)
{
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");
+ _eglError(EGL_BAD_ALLOC, func);
return NULL;
}
@@ -293,6 +293,96 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return NULL;
}
+ return gsurf;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const EGLint *attribs)
+{
+ struct egl_g3d_surface *gsurf;
+ struct pipe_resource *ptex = NULL;
+
+ gsurf = create_pbuffer_surface(dpy, conf, attribs,
+ "eglCreatePbufferSurface");
+ if (!gsurf)
+ return NULL;
+
+ gsurf->client_buffer_type = EGL_NONE;
+
+ if (!gsurf->stfbi->validate(gsurf->stfbi,
+ &gsurf->stvis.render_buffer, 1, &ptex)) {
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+ FREE(gsurf);
+ return NULL;
+ }
+
+ return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ _EGLConfig *conf,
+ const EGLint *attribs)
+{
+ struct egl_g3d_surface *gsurf;
+ struct pipe_resource *ptex = NULL;
+ EGLint pbuffer_attribs[32];
+ EGLint count, i;
+
+ switch (buftype) {
+ case EGL_OPENVG_IMAGE:
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
+ return NULL;
+ break;
+ }
+
+ /* parse the attributes first */
+ count = 0;
+ for (i = 0; attribs && attribs[i] != EGL_NONE; i++) {
+ EGLint attr = attribs[i++];
+ EGLint val = attribs[i];
+ EGLint err = EGL_SUCCESS;
+
+ switch (attr) {
+ case EGL_TEXTURE_FORMAT:
+ case EGL_TEXTURE_TARGET:
+ case EGL_MIPMAP_TEXTURE:
+ pbuffer_attribs[count++] = attr;
+ pbuffer_attribs[count++] = val;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ /* bail out */
+ if (err != EGL_SUCCESS) {
+ _eglError(err, "eglCreatePbufferFromClientBuffer");
+ return NULL;
+ }
+ }
+
+ pbuffer_attribs[count++] = EGL_NONE;
+
+ gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs,
+ "eglCreatePbufferFromClientBuffer");
+ if (!gsurf)
+ return NULL;
+
+ gsurf->client_buffer_type = buftype;
+ gsurf->client_buffer = buffer;
+
+ if (!gsurf->stfbi->validate(gsurf->stfbi,
+ &gsurf->stvis.render_buffer, 1, &ptex)) {
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+ FREE(gsurf);
+ return NULL;
+ }
+
return &gsurf->base;
}
@@ -428,7 +518,6 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_config *gconf;
struct native_surface *nsurf;
- struct pipe_screen *screen = gdpy->native->screen;
struct pipe_resource *ptex;
if (!gsurf->render_texture)
@@ -460,7 +549,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (ptex) {
- struct pipe_surface *psrc;
+ struct pipe_resource *psrc = gsurf->render_texture;
struct pipe_subresource subsrc, subdst;
subsrc.face = 0;
subsrc.level = 0;
@@ -704,6 +793,7 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
drv->API.CreateWindowSurface = egl_g3d_create_window_surface;
drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
+ drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer;
drv->API.DestroySurface = egl_g3d_destroy_surface;
drv->API.MakeCurrent = egl_g3d_make_current;
drv->API.SwapBuffers = egl_g3d_swap_buffers;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index cdf13140cb..e2217b3b2b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -29,6 +29,8 @@
#include "util/u_memory.h"
#include "util/u_string.h"
#include "util/u_inlines.h"
+#include "util/u_pointer.h"
+#include "util/u_format.h"
#include "util/u_dl.h"
#include "egldriver.h"
#include "eglimage.h"
@@ -62,6 +64,11 @@ egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data)
char path[1024];
int ret;
+ if (!len) {
+ stmod->lib = util_dl_open(stmod->filename);
+ return !(stmod->lib);
+ }
+
ret = util_snprintf(path, sizeof(path),
"%.*s/%s", len, dir, stmod->filename);
if (ret > 0 && ret < sizeof(path))
@@ -103,6 +110,12 @@ egl_g3d_load_st_module(struct egl_g3d_st_module *stmod,
}
}
+#ifdef PIPE_OS_WINDOWS
+#define ST_MODULE_SUFFIX ".dll"
+#else
+#define ST_MODULE_SUFFIX ".so"
+#endif
+
void
egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
{
@@ -121,24 +134,24 @@ egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
case ST_API_OPENGL:
skip_checks[api] = "glColor4d";
symbols[api] = ST_CREATE_OPENGL_SYMBOL;
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENGL_ES1:
skip_checks[api] = "glColor4x";
symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL;
- filenames[api][count++] = "api_GLESv1_CM.so";
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GLESv1_CM" ST_MODULE_SUFFIX;
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENGL_ES2:
skip_checks[api] = "glShaderBinary";
symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL;
- filenames[api][count++] = "api_GLESv2.so";
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GLESv2" ST_MODULE_SUFFIX;
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENVG:
skip_checks[api] = "vgClear";
symbols[api] = ST_CREATE_OPENVG_SYMBOL;
- filenames[api][count++]= "api_OpenVG.so";
+ filenames[api][count++]= "api_OpenVG" ST_MODULE_SUFFIX;
break;
default:
assert(!"Unknown API Type\n");
@@ -206,6 +219,7 @@ egl_g3d_destroy_st_apis(void)
static boolean
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
+ struct st_context_iface *stctx,
void *egl_image,
struct st_egl_image *out)
{
@@ -275,7 +289,34 @@ egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi,
return TRUE;
}
-static boolean
+static void
+pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
+{
+ /* TODO */
+}
+
+static void
+pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
+{
+ struct egl_g3d_display *gdpy =
+ egl_g3d_display(gsurf->base.Resource.Display);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_resource templ, *ptex;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = gsurf->base.Width;
+ templ.height0 = gsurf->base.Height;
+ templ.depth0 = 1;
+ templ.format = gsurf->stvis.color_format;
+ templ.bind = PIPE_BIND_RENDER_TARGET;
+
+ ptex = screen->resource_create(screen, &templ);
+ gsurf->render_texture = ptex;
+}
+
+static boolean
egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
@@ -283,7 +324,6 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct pipe_resource templ;
unsigned i;
for (i = 0; i < count; i++) {
@@ -293,20 +333,19 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
continue;
if (!gsurf->render_texture) {
- struct egl_g3d_display *gdpy =
- egl_g3d_display(gsurf->base.Resource.Display);
- struct pipe_screen *screen = gdpy->native->screen;
-
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = gsurf->base.Width;
- templ.height0 = gsurf->base.Height;
- templ.depth0 = 1;
- templ.format = gsurf->stvis.color_format;
- templ.bind = PIPE_BIND_RENDER_TARGET;
-
- gsurf->render_texture = screen->resource_create(screen, &templ);
+ switch (gsurf->client_buffer_type) {
+ case EGL_NONE:
+ pbuffer_allocate_render_texture(gsurf);
+ break;
+ case EGL_OPENVG_IMAGE:
+ pbuffer_reference_openvg_image(gsurf);
+ break;
+ default:
+ break;
+ }
+
+ if (!gsurf->render_texture)
+ return FALSE;
}
pipe_resource_reference(&out[i], gsurf->render_texture);
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
new file mode 100644
index 0000000000..7832b2b693
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -0,0 +1,235 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+#include "native_helper.h"
+
+struct resource_surface {
+ struct pipe_screen *screen;
+ enum pipe_format format;
+ uint bind;
+
+ struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_surface *present_surfaces[NUM_NATIVE_ATTACHMENTS];
+ uint resource_mask;
+ uint width, height;
+};
+
+struct resource_surface *
+resource_surface_create(struct pipe_screen *screen,
+ enum pipe_format format, uint bind)
+{
+ struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface);
+
+ if (rsurf) {
+ rsurf->screen = screen;
+ rsurf->format = format;
+ rsurf->bind = bind;
+ }
+
+ return rsurf;
+}
+
+static void
+resource_surface_free_resources(struct resource_surface *rsurf)
+{
+ if (rsurf->resource_mask) {
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (rsurf->present_surfaces[i])
+ pipe_surface_reference(&rsurf->present_surfaces[i], NULL);
+ if (rsurf->resources[i])
+ pipe_resource_reference(&rsurf->resources[i], NULL);
+ }
+ rsurf->resource_mask = 0x0;
+ }
+}
+
+void
+resource_surface_destroy(struct resource_surface *rsurf)
+{
+ resource_surface_free_resources(rsurf);
+ FREE(rsurf);
+}
+
+boolean
+resource_surface_set_size(struct resource_surface *rsurf,
+ uint width, uint height)
+{
+ boolean changed = FALSE;
+
+ if (rsurf->width != width || rsurf->height != height) {
+ resource_surface_free_resources(rsurf);
+ rsurf->width = width;
+ rsurf->height = height;
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
+void
+resource_surface_get_size(struct resource_surface *rsurf,
+ uint *width, uint *height)
+{
+ if (width)
+ *width = rsurf->width;
+ if (height)
+ *height = rsurf->height;
+}
+
+boolean
+resource_surface_add_resources(struct resource_surface *rsurf,
+ uint resource_mask)
+{
+ struct pipe_resource templ;
+ int i;
+
+ resource_mask &= ~rsurf->resource_mask;
+ if (!resource_mask)
+ return TRUE;
+
+ if (!rsurf->width || !rsurf->height)
+ return FALSE;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = rsurf->format;
+ templ.bind = rsurf->bind;
+ templ.width0 = rsurf->width;
+ templ.height0 = rsurf->height;
+ templ.depth0 = 1;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (resource_mask & (1 <<i)) {
+ assert(!rsurf->resources[i]);
+
+ rsurf->resources[i] =
+ rsurf->screen->resource_create(rsurf->screen, &templ);
+ if (rsurf->resources[i])
+ rsurf->resource_mask |= 1 << i;
+ }
+ }
+
+ return ((rsurf->resource_mask & resource_mask) == resource_mask);
+}
+
+
+void
+resource_surface_get_resources(struct resource_surface *rsurf,
+ struct pipe_resource **resources,
+ uint resource_mask)
+{
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (resource_mask & (1 << i)) {
+ resources[i] = NULL;
+ pipe_resource_reference(&resources[i], rsurf->resources[i]);
+ }
+ }
+}
+
+struct pipe_resource *
+resource_surface_get_single_resource(struct resource_surface *rsurf,
+ enum native_attachment which)
+{
+ struct pipe_resource *pres = NULL;
+ pipe_resource_reference(&pres, rsurf->resources[which]);
+ return pres;
+}
+
+static INLINE void
+pointer_swap(const void **p1, const void **p2)
+{
+ const void *tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+void
+resource_surface_swap_buffers(struct resource_surface *rsurf,
+ enum native_attachment buf1,
+ enum native_attachment buf2,
+ boolean only_if_exist)
+{
+ const uint buf1_bit = 1 << buf1;
+ const uint buf2_bit = 1 << buf2;
+ uint mask;
+
+ if (only_if_exist && !(rsurf->resources[buf1] && rsurf->resources[buf2]))
+ return;
+
+ pointer_swap((const void **) &rsurf->resources[buf1],
+ (const void **) &rsurf->resources[buf2]);
+ pointer_swap((const void **) &rsurf->present_surfaces[buf1],
+ (const void **) &rsurf->present_surfaces[buf2]);
+
+ /* swap mask bits */
+ mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit);
+ if (rsurf->resource_mask & buf1_bit)
+ mask |= buf2_bit;
+ if (rsurf->resource_mask & buf2_bit)
+ mask |= buf1_bit;
+
+ rsurf->resource_mask = mask;
+}
+
+boolean
+resource_surface_present(struct resource_surface *rsurf,
+ enum native_attachment which,
+ void *winsys_drawable_handle)
+{
+ struct pipe_resource *pres = rsurf->resources[which];
+ struct pipe_surface *psurf = rsurf->present_surfaces[which];
+
+ if (!pres)
+ return TRUE;
+
+ if (!psurf) {
+ psurf = rsurf->screen->get_tex_surface(rsurf->screen,
+ pres, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
+ if (!psurf)
+ return FALSE;
+
+ rsurf->present_surfaces[which] = psurf;
+ }
+
+ assert(psurf->texture == pres);
+
+ rsurf->screen->flush_frontbuffer(rsurf->screen,
+ psurf, winsys_drawable_handle);
+
+ return TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h
new file mode 100644
index 0000000000..62956d5220
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_helper.h
@@ -0,0 +1,70 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "native.h"
+
+struct resource_surface;
+
+struct resource_surface *
+resource_surface_create(struct pipe_screen *screen,
+ enum pipe_format format, uint bind);
+
+void
+resource_surface_destroy(struct resource_surface *rsurf);
+
+boolean
+resource_surface_set_size(struct resource_surface *rsurf,
+ uint width, uint height);
+
+void
+resource_surface_get_size(struct resource_surface *rsurf,
+ uint *width, uint *height);
+
+boolean
+resource_surface_add_resources(struct resource_surface *rsurf,
+ uint resource_mask);
+
+void
+resource_surface_get_resources(struct resource_surface *rsurf,
+ struct pipe_resource **resources,
+ uint resource_mask);
+
+struct pipe_resource *
+resource_surface_get_single_resource(struct resource_surface *rsurf,
+ enum native_attachment which);
+
+void
+resource_surface_swap_buffers(struct resource_surface *rsurf,
+ enum native_attachment buf1,
+ enum native_attachment buf2,
+ boolean only_if_exist);
+
+boolean
+resource_surface_present(struct resource_surface *rsurf,
+ enum native_attachment which,
+ void *winsys_drawable_handle);
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
new file mode 100644
index 0000000000..29e89bcae8
--- /dev/null
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -0,0 +1,427 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <windows.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "target-helpers/wrap_screen.h"
+#include "llvmpipe/lp_public.h"
+#include "softpipe/sp_public.h"
+#include "gdi/gdi_sw_winsys.h"
+
+#include "common/native_helper.h"
+#include "common/native.h"
+
+struct gdi_display {
+ struct native_display base;
+
+ HDC hDC;
+ struct native_event_handler *event_handler;
+
+ struct native_config *configs;
+ int num_configs;
+};
+
+struct gdi_surface {
+ struct native_surface base;
+
+ HWND hWnd;
+ enum pipe_format color_format;
+
+ struct gdi_display *gdpy;
+
+ unsigned int server_stamp;
+ unsigned int client_stamp;
+
+ struct resource_surface *rsurf;
+};
+
+static INLINE struct gdi_display *
+gdi_display(const struct native_display *ndpy)
+{
+ return (struct gdi_display *) ndpy;
+}
+
+static INLINE struct gdi_surface *
+gdi_surface(const struct native_surface *nsurf)
+{
+ return (struct gdi_surface *) nsurf;
+}
+
+/**
+ * Update the geometry of the surface. This is a slow functions.
+ */
+static void
+gdi_surface_update_geometry(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ RECT rect;
+ uint w, h;
+
+ GetClientRect(gsurf->hWnd, &rect);
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ if (resource_surface_set_size(gsurf->rsurf, w, h))
+ gsurf->server_stamp++;
+}
+
+/**
+ * Update the buffers of the surface.
+ */
+static boolean
+gdi_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+
+ if (gsurf->client_stamp != gsurf->server_stamp) {
+ gdi_surface_update_geometry(&gsurf->base);
+ gsurf->client_stamp = gsurf->server_stamp;
+ }
+
+ return resource_surface_add_resources(gsurf->rsurf, buffer_mask);
+}
+
+/**
+ * Emulate an invalidate event.
+ */
+static void
+gdi_surface_invalidate(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ struct gdi_display *gdpy = gsurf->gdpy;
+
+ gsurf->server_stamp++;
+ gdpy->event_handler->invalid_surface(&gdpy->base,
+ &gsurf->base, gsurf->server_stamp);
+}
+
+static boolean
+gdi_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ HDC hDC;
+ boolean ret;
+
+ hDC = GetDC(gsurf->hWnd);
+ ret = resource_surface_present(gsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, (void *) hDC);
+ ReleaseDC(gsurf->hWnd, hDC);
+
+ /* force buffers to be updated in next validation call */
+ gdi_surface_invalidate(&gsurf->base);
+
+ return ret;
+}
+
+static boolean
+gdi_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ HDC hDC;
+ boolean ret;
+
+ hDC = GetDC(gsurf->hWnd);
+ ret = resource_surface_present(gsurf->rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT, (void *) hDC);
+ ReleaseDC(gsurf->hWnd, hDC);
+
+ resource_surface_swap_buffers(gsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
+ /* the front/back buffers have been swapped */
+ gdi_surface_invalidate(&gsurf->base);
+
+ return ret;
+}
+
+static boolean
+gdi_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_resource **textures,
+ int *width, int *height)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ uint w, h;
+
+ if (!gdi_surface_update_buffers(&gsurf->base, attachment_mask))
+ return FALSE;
+
+ if (seq_num)
+ *seq_num = gsurf->client_stamp;
+
+ if (textures)
+ resource_surface_get_resources(gsurf->rsurf, textures, attachment_mask);
+
+ resource_surface_get_size(gsurf->rsurf, &w, &h);
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+
+ return TRUE;
+}
+
+static void
+gdi_surface_wait(struct native_surface *nsurf)
+{
+ /* no-op */
+}
+
+static void
+gdi_surface_destroy(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+
+ resource_surface_destroy(gsurf->rsurf);
+ FREE(gsurf);
+}
+
+static struct native_surface *
+gdi_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+ struct gdi_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(gdi_surface);
+ if (!gsurf)
+ return NULL;
+
+ gsurf->gdpy = gdpy;
+ gsurf->color_format = nconf->color_format;
+ gsurf->hWnd = (HWND) win;
+
+ gsurf->rsurf = resource_surface_create(gdpy->base.screen,
+ gsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!gsurf->rsurf) {
+ FREE(gsurf);
+ return NULL;
+ }
+
+ /* initialize the geometry */
+ gdi_surface_update_geometry(&gsurf->base);
+
+ gsurf->base.destroy = gdi_surface_destroy;
+ gsurf->base.swap_buffers = gdi_surface_swap_buffers;
+ gsurf->base.flush_frontbuffer = gdi_surface_flush_frontbuffer;
+ gsurf->base.validate = gdi_surface_validate;
+ gsurf->base.wait = gdi_surface_wait;
+
+ return &gsurf->base;
+}
+
+static int
+fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8])
+{
+ struct pipe_screen *screen = ndpy->screen;
+ int i, count = 0;
+
+ enum pipe_format candidates[] = {
+ /* 32-bit */
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ /* 24-bit */
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_X8R8G8B8_UNORM,
+ /* 16-bit */
+ PIPE_FORMAT_B5G6R5_UNORM
+ };
+
+ assert(Elements(candidates) <= 8);
+
+ for (i = 0; i < Elements(candidates); i++) {
+ if (screen->is_format_supported(screen, candidates[i],
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))
+ formats[count++] = candidates[i];
+ }
+
+ return count;
+}
+
+static const struct native_config **
+gdi_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+ const struct native_config **configs;
+ int i;
+
+ /* first time */
+ if (!gdpy->configs) {
+ enum pipe_format formats[8];
+ int i, count;
+
+ count = fill_color_formats(&gdpy->base, formats);
+
+ gdpy->configs = CALLOC(count, sizeof(*gdpy->configs));
+ if (!gdpy->configs)
+ return NULL;
+
+ for (i = 0; i < count; i++) {
+ struct native_config *nconf = &gdpy->configs[i];
+
+ nconf->buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+ nconf->color_format = formats[i];
+
+ nconf->window_bit = TRUE;
+ nconf->slow_config = TRUE;
+ }
+
+ gdpy->num_configs = count;
+ }
+
+ configs = MALLOC(gdpy->num_configs * sizeof(*configs));
+ if (configs) {
+ for (i = 0; i < gdpy->num_configs; i++)
+ configs[i] = (const struct native_config *) &gdpy->configs[i];
+ if (num_configs)
+ *num_configs = gdpy->num_configs;
+ }
+ return configs;
+}
+
+static int
+gdi_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ /* private buffers are allocated */
+ val = FALSE;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static void
+gdi_display_destroy(struct native_display *ndpy)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+
+ if (gdpy->configs)
+ FREE(gdpy->configs);
+
+ gdpy->base.screen->destroy(gdpy->base.screen);
+
+ FREE(gdpy);
+}
+
+static struct native_display *
+gdi_create_display(HDC hDC, struct pipe_screen *screen,
+ struct native_event_handler *event_handler)
+{
+ struct gdi_display *gdpy;
+
+ gdpy = CALLOC_STRUCT(gdi_display);
+ if (!gdpy)
+ return NULL;
+
+ gdpy->hDC = hDC;
+ gdpy->event_handler = event_handler;
+
+ gdpy->base.screen = screen;
+
+ gdpy->base.destroy = gdi_display_destroy;
+ gdpy->base.get_param = gdi_display_get_param;
+
+ gdpy->base.get_configs = gdi_display_get_configs;
+ gdpy->base.create_window_surface = gdi_display_create_window_surface;
+
+ return &gdpy->base;
+}
+
+static struct pipe_screen *
+gdi_create_screen(void)
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ winsys = gdi_create_sw_winsys();
+ if (!winsys)
+ return NULL;
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen(winsys);
+#endif
+ if (!screen)
+ screen = softpipe_create_screen(winsys);
+
+ if (!screen) {
+ if (winsys->destroy)
+ winsys->destroy(winsys);
+ return NULL;
+ }
+
+ return gallium_wrap_screen(screen);
+}
+
+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;
+}
+
+const char *
+native_get_name(void)
+{
+ return "GDI";
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
+{
+ struct pipe_screen *screen;
+
+ screen = gdi_create_screen();
+ if (!screen)
+ return NULL;
+
+ return gdi_create_display((HDC) dpy, screen, event_handler);
+}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index d81178e559..bfb4a9d258 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -28,6 +28,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_pointer.h"
#include "util/u_string.h"
#include "egllog.h"
@@ -39,39 +40,11 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
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_resource 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.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SCANOUT;
- }
-
- /* 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->resource_create(screen, &templ);
- ksurf->textures[att] = ptex;
- }
- if (textures) {
- textures[att] = NULL;
- pipe_resource_reference(&textures[att], ptex);
- }
- }
+ if (!resource_surface_add_resources(ksurf->rsurf, attachment_mask))
+ return FALSE;
+ if (textures)
+ resource_surface_get_resources(ksurf->rsurf, textures, attachment_mask);
if (seq_num)
*seq_num = ksurf->sequence_number;
@@ -111,11 +84,11 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
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])
+ resource_surface_add_resources(ksurf->rsurf, 1 << natt);
+ fb->texture =
+ resource_surface_get_single_resource(ksurf->rsurf, natt);
+ if (!fb->texture)
return FALSE;
-
- pipe_resource_reference(&fb->texture, ksurf->textures[natt]);
}
/* already initialized */
@@ -166,7 +139,6 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
struct kms_crtc *kcrtc = &ksurf->current_crtc;
struct kms_display *kdpy = ksurf->kdpy;
struct kms_framebuffer tmp_fb;
- struct pipe_resource *tmp_texture;
int err;
if (!ksurf->back_fb.buffer_id) {
@@ -187,11 +159,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
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;
-
+ resource_surface_swap_buffers(ksurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
/* the front/back textures are swapped */
ksurf->sequence_number++;
kdpy->event_handler->invalid_surface(&kdpy->base,
@@ -210,7 +179,6 @@ 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);
@@ -223,11 +191,7 @@ kms_surface_destroy(struct native_surface *nsurf)
drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
pipe_resource_reference(&ksurf->back_fb.texture, NULL);
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct pipe_resource *ptex = ksurf->textures[i];
- pipe_resource_reference(&ptex, NULL);
- }
-
+ resource_surface_destroy(ksurf->rsurf);
FREE(ksurf);
}
@@ -249,6 +213,19 @@ kms_display_create_surface(struct native_display *ndpy,
ksurf->width = width;
ksurf->height = height;
+ ksurf->rsurf = resource_surface_create(kdpy->base.screen,
+ ksurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!ksurf->rsurf) {
+ FREE(ksurf);
+ return NULL;
+ }
+
+ resource_surface_set_size(ksurf->rsurf, ksurf->width, ksurf->height);
+
ksurf->base.destroy = kms_surface_destroy;
ksurf->base.swap_buffers = kms_surface_swap_buffers;
ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer;
@@ -694,7 +671,27 @@ kms_display_init_screen(struct native_display *ndpy)
struct kms_display *kdpy = kms_display(ndpy);
int fd;
- fd = drmOpen(kdpy->api->driver_name, NULL);
+ fd = kdpy->fd;
+ if (fd >= 0) {
+ drmVersionPtr version = drmGetVersion(fd);
+ if (!version || strcmp(version->name, kdpy->api->driver_name)) {
+ if (version) {
+ _eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
+ drmFreeVersion(version);
+ }
+ else {
+ _eglLog(_EGL_WARNING, "invalid fd %d", fd);
+ }
+
+ return FALSE;
+ }
+
+ drmFreeVersion(version);
+ }
+ else {
+ fd = drmOpen(kdpy->api->driver_name, NULL);
+ }
+
if (fd < 0) {
_eglLog(_EGL_WARNING, "failed to open DRM device");
return FALSE;
@@ -707,7 +704,7 @@ kms_display_init_screen(struct native_display *ndpy)
}
#endif
- kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, NULL);
+ kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd);
if (!kdpy->base.screen) {
_eglLog(_EGL_WARNING, "failed to create DRM screen");
drmClose(fd);
@@ -727,8 +724,7 @@ static struct native_display_modeset kms_display_modeset = {
};
static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
+kms_create_display(int fd, struct native_event_handler *event_handler,
struct drm_api *api)
{
struct kms_display *kdpy;
@@ -746,7 +742,7 @@ kms_create_display(EGLNativeDisplayType dpy,
return NULL;
}
- kdpy->fd = -1;
+ kdpy->fd = fd;
if (!kms_display_init_screen(&kdpy->base)) {
kms_display_destroy(&kdpy->base);
return NULL;
@@ -818,12 +814,17 @@ native_create_display(EGLNativeDisplayType dpy,
struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
+ int fd;
if (!drm_api)
drm_api = drm_api_create();
- if (drm_api)
- ndpy = kms_create_display(dpy, event_handler, drm_api);
+ if (drm_api) {
+ /* well, this makes fd 0 being ignored */
+ fd = (dpy != EGL_DEFAULT_DISPLAY) ?
+ (int) pointer_to_intptr((void *) dpy) : -1;
+ ndpy = kms_create_display(fd, event_handler, 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
index 3b08e930c5..d69c8d38c8 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -35,6 +35,7 @@
#include "state_tracker/drm_api.h"
#include "common/native.h"
+#include "common/native_helper.h"
struct kms_config;
struct kms_connector;
@@ -73,11 +74,12 @@ struct kms_framebuffer {
struct kms_surface {
struct native_surface base;
- enum pipe_format color_format;
struct kms_display *kdpy;
+
+ struct resource_surface *rsurf;
+ enum pipe_format color_format;
int width, height;
- struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
unsigned int sequence_number;
struct kms_framebuffer front_fb, back_fb;
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 47f5423b67..3388fc61e1 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -37,6 +37,7 @@
#include "llvmpipe/lp_public.h"
#include "egllog.h"
+#include "common/native_helper.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -59,11 +60,6 @@ struct ximage_display {
int num_configs;
};
-struct ximage_buffer {
- struct pipe_resource *texture;
- struct xlib_drawable xdraw;
-};
-
struct ximage_surface {
struct native_surface base;
Drawable drawable;
@@ -74,11 +70,9 @@ struct ximage_surface {
unsigned int server_stamp;
unsigned int client_stamp;
- int width, height;
- struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
- uint valid_mask;
- struct pipe_surface *draw_surface;
+ struct resource_surface *rsurf;
+ struct xlib_drawable xdraw;
};
struct ximage_config {
@@ -104,68 +98,10 @@ 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_resource_reference(&xbuf->texture, NULL);
-}
-
-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_resource 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.bind = PIPE_BIND_RENDER_TARGET;
-
- switch (which) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- case NATIVE_ATTACHMENT_FRONT_RIGHT:
- templ.bind |= PIPE_BIND_SCANOUT;
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- case NATIVE_ATTACHMENT_BACK_RIGHT:
- templ.bind |= PIPE_BIND_DISPLAY_TARGET;
- break;
- default:
- break;
- }
- xbuf->texture = screen->resource_create(screen, &templ);
- if (xbuf->texture) {
- xbuf->xdraw.visual = xsurf->visual.visual;
- xbuf->xdraw.depth = xsurf->visual.depth;
- xbuf->xdraw.drawable = xsurf->drawable;
- }
-
- /* clean up the buffer if allocation failed */
- if (!xbuf->texture)
- ximage_surface_free_buffer(&xsurf->base, which);
-
- return (xbuf->texture != NULL);
-}
-
/**
- * Update the geometry of the surface. Return TRUE if the geometry has changed
- * since last call.
+ * Update the geometry of the surface. This is a slow functions.
*/
-static boolean
+static void
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
@@ -173,102 +109,41 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
Window root;
int x, y;
unsigned int w, h, border, depth;
- boolean updated = FALSE;
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
- if (ok && (xsurf->width != w || xsurf->height != h)) {
- xsurf->width = w;
- xsurf->height = h;
-
+ if (ok && resource_surface_set_size(xsurf->rsurf, w, h))
xsurf->server_stamp++;
- updated = TRUE;
- }
-
- return updated;
-}
-
-static void
-ximage_surface_notify_invalid(struct native_surface *nsurf)
-{
- struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_display *xdpy = xsurf->xdpy;
-
- xdpy->event_handler->invalid_surface(&xdpy->base,
- &xsurf->base, xsurf->server_stamp);
}
/**
- * Update the buffers of the surface. It is a slow function due to the
- * round-trip to the server.
+ * Update the buffers of the surface.
*/
static boolean
ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean updated;
- uint new_valid;
- int att;
-
- updated = ximage_surface_update_geometry(&xsurf->base);
- if (updated) {
- /* all buffers become invalid */
- xsurf->valid_mask = 0x0;
- }
- else {
- buffer_mask &= ~xsurf->valid_mask;
- /* all requested buffers are valid */
- if (!buffer_mask) {
- xsurf->client_stamp = xsurf->server_stamp;
- return TRUE;
- }
- }
- new_valid = 0x0;
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(buffer_mask, att)) {
- /* reallocate the texture */
- if (!ximage_surface_alloc_buffer(&xsurf->base, att))
- break;
-
- new_valid |= (1 << att);
- if (buffer_mask == new_valid)
- break;
- }
+ if (xsurf->client_stamp != xsurf->server_stamp) {
+ ximage_surface_update_geometry(&xsurf->base);
+ xsurf->client_stamp = xsurf->server_stamp;
}
- xsurf->valid_mask |= new_valid;
- xsurf->client_stamp = xsurf->server_stamp;
-
- return (new_valid == buffer_mask);
+ return resource_surface_add_resources(xsurf->rsurf, buffer_mask);
}
-static boolean
-ximage_surface_draw_buffer(struct native_surface *nsurf,
- enum native_attachment which)
+/**
+ * Emulate an invalidate event.
+ */
+static void
+ximage_surface_invalidate(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xbuf = &xsurf->buffers[which];
- struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_surface *psurf;
-
- assert(xsurf->drawable && xbuf->texture);
-
- psurf = xsurf->draw_surface;
- if (!psurf || psurf->texture != xbuf->texture) {
- pipe_surface_reference(&xsurf->draw_surface, NULL);
-
- psurf = screen->get_tex_surface(screen,
- xbuf->texture, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
- if (!psurf)
- return FALSE;
-
- xsurf->draw_surface = psurf;
- }
-
- screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
+ struct ximage_display *xdpy = xsurf->xdpy;
- return TRUE;
+ xsurf->server_stamp++;
+ xdpy->event_handler->invalid_surface(&xdpy->base,
+ &xsurf->base, xsurf->server_stamp);
}
static boolean
@@ -277,11 +152,10 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
- ret = ximage_surface_draw_buffer(&xsurf->base,
- NATIVE_ATTACHMENT_FRONT_LEFT);
+ ret = resource_surface_present(xsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, (void *) &xsurf->xdraw);
/* force buffers to be updated in next validation call */
- xsurf->server_stamp++;
- ximage_surface_notify_invalid(&xsurf->base);
+ ximage_surface_invalidate(&xsurf->base);
return ret;
}
@@ -290,25 +164,15 @@ static boolean
ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xfront, *xback, xtmp;
boolean ret;
- /* display the back buffer first */
- ret = ximage_surface_draw_buffer(&xsurf->base,
- NATIVE_ATTACHMENT_BACK_LEFT);
- /* force buffers to be updated in next validation call */
- xsurf->server_stamp++;
- ximage_surface_notify_invalid(&xsurf->base);
+ ret = resource_surface_present(xsurf->rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT, (void *) &xsurf->xdraw);
- xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
- xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
-
- /* skip swapping unless there is a front buffer */
- if (xfront->texture) {
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
- }
+ resource_surface_swap_buffers(xsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
+ /* the front/back buffers have been swapped */
+ ximage_surface_invalidate(&xsurf->base);
return ret;
}
@@ -319,32 +183,22 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
+ uint w, h;
- if (xsurf->client_stamp != xsurf->server_stamp ||
- (xsurf->valid_mask & attachment_mask) != attachment_mask) {
- if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
- return FALSE;
- }
+ if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
+ return FALSE;
if (seq_num)
*seq_num = xsurf->client_stamp;
- if (textures) {
- int att;
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(attachment_mask, att)) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
- textures[att] = NULL;
- pipe_resource_reference(&textures[att], xbuf->texture);
- }
- }
- }
+ if (textures)
+ resource_surface_get_resources(xsurf->rsurf, textures, attachment_mask);
+ resource_surface_get_size(xsurf->rsurf, &w, &h);
if (width)
- *width = xsurf->width;
+ *width = w;
if (height)
- *height = xsurf->height;
+ *height = h;
return TRUE;
}
@@ -361,13 +215,8 @@ static void
ximage_surface_destroy(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- int i;
-
- pipe_surface_reference(&xsurf->draw_surface, NULL);
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
- ximage_surface_free_buffer(&xsurf->base, i);
+ resource_surface_destroy(xsurf->rsurf);
FREE(xsurf);
}
@@ -390,10 +239,25 @@ ximage_display_create_surface(struct native_display *ndpy,
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
+ xsurf->rsurf = resource_surface_create(xdpy->base.screen,
+ xsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!xsurf->rsurf) {
+ FREE(xsurf);
+ return NULL;
+ }
+
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
/* initialize the geometry */
- ximage_surface_update_buffers(&xsurf->base, 0x0);
+ ximage_surface_update_geometry(&xsurf->base);
+
+ xsurf->xdraw.visual = xsurf->visual.visual;
+ xsurf->xdraw.depth = xsurf->visual.depth;
+ xsurf->xdraw.drawable = xsurf->drawable;
xsurf->base.destroy = ximage_surface_destroy;
xsurf->base.swap_buffers = ximage_surface_swap_buffers;
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 0294e769a6..cf0144b5dc 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -414,39 +414,21 @@ error1:
* Surface functions
*/
- void surface_copy(struct st_surface *dst,
- unsigned destx, unsigned desty,
- struct st_surface *src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
+ void resource_copy_region(struct pipe_resource *dst,
+ struct pipe_subresource subdst,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src,
+ struct pipe_subresource subsrc,
+ unsigned srcx, unsigned srcy, unsigned srcz,
+ unsigned width, unsigned height)
{
-/* XXX
- struct pipe_surface *_dst = NULL;
- struct pipe_surface *_src = NULL;
-
- _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION);
- if(!_dst)
- SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
-
- _src = st_pipe_surface(src, PIPE_BIND_BLIT_SOURCE);
- if(!_src)
- SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading");
-
- $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height);
-
- fail:
- pipe_surface_reference(&_src, NULL);
- pipe_surface_reference(&_dst, NULL);
-*/
- struct pipe_subresource subdst, subsrc;
- subsrc.face = src->face;
- subsrc.level = src->level;
- subdst.face = dst->face;
- subdst.level = dst->level;
- $self->pipe->resource_copy_region($self->pipe, dst->texture, subdst, destx, desty, dst->zslice,
- src->texture, subsrc, srcx, srcy, src->zslice, width, height);
+ $self->pipe->resource_copy_region($self->pipe,
+ dst, subdst, dstx, dsty, dstz,
+ src, subsrc, srcx, srcy, srcz,
+ width, height);
}
+
void clear_render_target(struct st_surface *dst,
float *rgba,
unsigned x, unsigned y,
diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript
new file mode 100644
index 0000000000..548053eb64
--- /dev/null
+++ b/src/gallium/state_trackers/vega/SConscript
@@ -0,0 +1,51 @@
+#######################################################################
+# SConscript for vega state_tracker
+
+Import('*')
+
+if 'egl' in env['statetrackers']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mapi',
+ ])
+
+ vega_sources = [
+ 'api.c',
+ 'api_context.c',
+ 'api_filters.c',
+ 'api_images.c',
+ 'api_masks.c',
+ 'api_misc.c',
+ 'api_paint.c',
+ 'api_params.c',
+ 'api_path.c',
+ 'api_text.c',
+ 'api_transform.c',
+ 'vgu.c',
+ 'vg_context.c',
+ 'vg_manager.c',
+ 'vg_state.c',
+ 'vg_translate.c',
+ 'polygon.c',
+ 'bezier.c',
+ 'path.c',
+ 'paint.c',
+ 'arc.c',
+ 'image.c',
+ 'renderer.c',
+ 'stroker.c',
+ 'mask.c',
+ 'shader.c',
+ 'shaders_cache.c',
+ ]
+
+ # vgapi_header must be generated first
+ env.Depends(vega_sources, vgapi_header)
+
+ st_vega = env.ConvenienceLibrary(
+ target = 'st_vega',
+ source = vega_sources,
+ )
+ Export('st_vega')
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 144fb8f323..8ace985336 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -42,6 +42,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
+#include "util/u_string.h"
#include "asm_filters.h"
@@ -271,7 +272,7 @@ static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_d
VGint num_consts = (VGint)(long)(user_data);
struct vg_shader *shader;
- snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
+ util_snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
@@ -299,16 +300,16 @@ static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user
switch(channel) {
case VG_RED:
- snprintf(buffer, 1023, lookup_single_asm, "xxxx");
+ util_snprintf(buffer, 1023, lookup_single_asm, "xxxx");
break;
case VG_GREEN:
- snprintf(buffer, 1023, lookup_single_asm, "yyyy");
+ util_snprintf(buffer, 1023, lookup_single_asm, "yyyy");
break;
case VG_BLUE:
- snprintf(buffer, 1023, lookup_single_asm, "zzzz");
+ util_snprintf(buffer, 1023, lookup_single_asm, "zzzz");
break;
case VG_ALPHA:
- snprintf(buffer, 1023, lookup_single_asm, "wwww");
+ util_snprintf(buffer, 1023, lookup_single_asm, "wwww");
break;
default:
debug_assert(!"Unknown color channel");
diff --git a/src/gallium/state_trackers/vega/arc.c b/src/gallium/state_trackers/vega/arc.c
index 2d12340870..65a985fbbb 100644
--- a/src/gallium/state_trackers/vega/arc.c
+++ b/src/gallium/state_trackers/vega/arc.c
@@ -33,8 +33,7 @@
#include "path.h"
#include "util/u_debug.h"
-
-#include <math.h>
+#include "util/u_math.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index fe0f166e88..c40ea8675e 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -59,7 +59,8 @@ static void setup_shaders(struct renderer *ctx)
{
struct pipe_context *pipe = ctx->pipe;
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+ ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
}
static struct pipe_resource *
diff --git a/src/gallium/state_trackers/vega/stroker.c b/src/gallium/state_trackers/vega/stroker.c
index 68a52029db..d89b6cf25c 100644
--- a/src/gallium/state_trackers/vega/stroker.c
+++ b/src/gallium/state_trackers/vega/stroker.c
@@ -35,7 +35,7 @@
#include "path_utils.h"
#include "polygon.h"
-#include "math.h"
+#include "util/u_math.h"
#ifndef M_2PI
#define M_2PI 6.28318530717958647692528676655900576
@@ -870,7 +870,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it,
VGboolean cap_first,
VGfloat *start_tangent)
{
- const int MAX_OFFSET = 16;
+#define MAX_OFFSET 16
struct bezier offset_curves[MAX_OFFSET];
VGPathCommand first_element;
VGfloat start[2], prev[2];
@@ -1017,6 +1017,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it,
#endif
return VG_FALSE;
}
+#undef MAX_OFFSET
}
static void stroker_process_subpath(struct stroker *stroker)
diff --git a/src/gallium/state_trackers/vega/util_array.h b/src/gallium/state_trackers/vega/util_array.h
index 4343dfe36e..b2d22f476e 100644
--- a/src/gallium/state_trackers/vega/util_array.h
+++ b/src/gallium/state_trackers/vega/util_array.h
@@ -65,7 +65,7 @@ static INLINE void array_destroy(struct array *array)
{
if (array)
free(array->data);
- free(array);
+ FREE(array);
}
static INLINE void array_resize(struct array *array, int num)
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index f9022a9f93..f1a07bd863 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -146,6 +146,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
/* XXX: hockup */
}
+#if 0 /* Implement and enable to enable rotation and reflection. */
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
@@ -168,6 +169,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
/* ScrnInfoPtr pScrn = crtc->scrn; */
}
+#endif
+
/*
* Cursor functions
*/
@@ -362,9 +365,9 @@ static const xf86CrtcFuncsRec crtc_funcs = {
.hide_cursor = crtc_hide_cursor,
.load_cursor_argb = crtc_load_cursor_argb,
- .shadow_create = crtc_shadow_create,
- .shadow_allocate = crtc_shadow_allocate,
- .shadow_destroy = crtc_shadow_destroy,
+ .shadow_create = NULL,
+ .shadow_allocate = NULL,
+ .shadow_destroy = NULL,
.gamma_set = crtc_gamma_set,
.destroy = crtc_destroy,
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index e719644d34..4e01bd1030 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -299,6 +299,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
GCPtr gc;
RegionPtr copy_clip;
Bool save_accel;
+ CustomizerPtr cust = ms->cust;
/*
* In driCreateBuffers we dewrap windows into the
@@ -352,7 +353,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
- if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
+ if (ms->swapThrottling &&
+ dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
if (extents->x1 == 0 && extents->y1 == 0 &&
@@ -374,6 +376,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
DamageRegionAppend(src_draw, pRegion);
DamageRegionProcessPending(src_draw);
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
+
(*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
ms->exa->accel = save_accel;
@@ -381,8 +386,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
FreeScratchGC(gc);
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
- pDestBuffer->attachment == DRI2BufferFrontLeft ?
+ (pDestBuffer->attachment == DRI2BufferFrontLeft
+ && ms->swapThrottling) ?
&dst_priv->fence : NULL);
+
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
+
}
Bool
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 84c0545b1b..6b6e2009fe 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -79,12 +79,16 @@ typedef enum
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
OPTION_DEBUG_FALLBACK,
+ OPTION_THROTTLE_SWAP,
+ OPTION_THROTTLE_DIRTY
} 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},
+ {OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -534,23 +538,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
if (ms->ctx) {
int j;
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+ ms->dirtyThrottling ?
+ &ms->fence[XORG_NR_FENCES-1] :
+ NULL);
- if (ms->fence[0])
- ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+ if (ms->dirtyThrottling) {
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen,
+ ms->fence[0], 0);
- /* The amount of rendering generated by a block handler can be
- * quite small. Let us get a fair way ahead of hardware before
- * throttling.
- */
- for (j = 0; j < XORG_NR_FENCES - 1; j++)
- ms->screen->fence_reference(ms->screen,
- &ms->fence[j],
- ms->fence[j+1]);
-
- ms->screen->fence_reference(ms->screen,
- &ms->fence[XORG_NR_FENCES-1],
- NULL);
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
}
@@ -634,6 +644,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
unsigned max_width, max_height;
VisualPtr visual;
CustomizerPtr cust = ms->cust;
+ MessageType from_st;
+ MessageType from_dt;
if (!drv_init_drm(pScrn)) {
FatalError("Could not init DRM");
@@ -720,6 +732,19 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
+ if (cust && cust->winsys_screen_init)
+ cust->winsys_screen_init(cust, ms->fd);
+
+ ms->swapThrottling = cust ? cust->swap_throttling : TRUE;
+ from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
+ &ms->swapThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
+ ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE;
+ from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
+ &ms->dirtyThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
if (ms->screen) {
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
@@ -744,6 +769,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
#endif
+ xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
+ ms->swapThrottling ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
+ ms->dirtyThrottling ? "enabled" : "disabled");
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
miInitializeBackingStore(pScreen);
@@ -776,9 +806,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- if (cust && cust->winsys_screen_init)
- cust->winsys_screen_init(cust, ms->fd);
-
return drv_enter_vt(scrnIndex, 1);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index ee40bc8ccb..bd84668300 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -46,7 +46,6 @@
#include "util/u_math.h"
#include "util/u_debug.h"
#include "util/u_format.h"
-#include "util/u_surface.h"
#define DEBUG_PRINT 0
#define ROUND_UP_TEXTURES 1
@@ -987,6 +986,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
ExaDriverPtr pExa;
+ CustomizerPtr cust = ms->cust;
exa = xcalloc(1, sizeof(struct exa_context));
if (!exa)
@@ -1048,6 +1048,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
/* Share context with DRI */
ms->ctx = exa->pipe;
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
exa->renderer = renderer_create(exa->pipe);
exa->accel = accel;
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index e5def3e2ed..92f1cc5065 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -8,7 +8,6 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
-#include "util/u_surface.h"
#include "util/u_inlines.h"
@@ -602,7 +601,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_resource **textures)
{
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 0454a6513d..fb09fabe15 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -54,7 +54,7 @@ void renderer_set_constants(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_resource **textures);
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 65fbc3234b..25da9b1a3b 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -67,12 +67,22 @@ typedef struct
#define XORG_NR_FENCES 3
+enum xorg_throttling_reason {
+ THROTTLE_RENDER,
+ THROTTLE_SWAP
+};
+
typedef struct _CustomizerRec
{
+ Bool dirty_throttling;
+ Bool swap_throttling;
Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
+ void (*winsys_context_throttle)(struct _CustomizerRec *cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason);
} CustomizerRec, *CustomizerPtr;
typedef struct _modesettingRec
@@ -91,6 +101,8 @@ typedef struct _modesettingRec
Bool noAccel;
Bool SWCursor;
CursorPtr cursor;
+ Bool swapThrottling;
+ Bool dirtyThrottling;
CloseScreenProcPtr CloseScreen;
/* Broken-out options. */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index a221594454..f98bd93901 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -413,7 +413,7 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
static void
draw_yuv(struct xorg_xv_port_priv *port,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h)
{
struct pipe_resource **textures = port->yuv[port->current_set];
@@ -562,10 +562,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
int box_y2 = pbox->y2;
float diff_x = (float)src_w / (float)dst_w;
float diff_y = (float)src_h / (float)dst_h;
- int offset_x = box_x1 - dstX + pPixmap->screen_x;
- int offset_y = box_y1 - dstY + pPixmap->screen_y;
- int offset_w;
- int offset_h;
+ float offset_x = box_x1 - dstX + pPixmap->screen_x;
+ float offset_y = box_y1 - dstY + pPixmap->screen_y;
+ float offset_w;
+ float offset_h;
x = box_x1;
y = box_y1;
@@ -576,8 +576,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
offset_h = dst_h - h;
draw_yuv(pPriv,
- src_x + offset_x*diff_x, src_y + offset_y*diff_y,
- src_w - offset_w*diff_x, src_h - offset_h*diff_y,
+ (float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y,
+ (float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y,
x, y, w, h);
pbox++;