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.h1
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c5
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.h1
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c4
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c2
-rw-r--r--src/gallium/state_trackers/egl/Makefile2
-rw-r--r--src/gallium/state_trackers/egl/SConscript1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c12
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h20
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c33
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c245
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.h8
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.c284
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_sync.h53
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c79
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c8
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_usefont.c3
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c78
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h4
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c24
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c2
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c2
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c4
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.h2
24 files changed, 803 insertions, 74 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 692c49d7cd..35b870a8a3 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -34,7 +34,6 @@
#include "pipe/p_compiler.h"
#include "dri_wrapper.h"
-#include "main/mtypes.h"
struct pipe_context;
struct pipe_fence;
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index 6ad2c7da4d..0ab4dd1893 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -383,6 +383,11 @@ dri_init_screen_helper(struct dri_screen *screen,
if (!screen->st_api)
return NULL;
+ if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))
+ screen->target = PIPE_TEXTURE_2D;
+ else
+ screen->target = PIPE_TEXTURE_RECT;
+
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h
index 53ccce145b..849f399b2f 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.h
+++ b/src/gallium/state_trackers/dri/common/dri_screen.h
@@ -68,6 +68,7 @@ struct dri_screen
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
boolean auto_fake_front;
+ enum pipe_texture_target target;
};
/** cast wrapper */
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 47005c17e2..93f910a26d 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -195,7 +195,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
pipe_resource_reference(&drawable->textures[i], NULL);
memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = screen->target;
templ.last_level = 0;
templ.width0 = dri_drawable->w;
templ.height0 = dri_drawable->h;
@@ -342,7 +342,7 @@ dri2_create_image_from_name(__DRIcontext *context,
memset(&templ, 0, sizeof(templ));
templ.bind = tex_usage;
templ.format = pf;
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = screen->target;
templ.last_level = 0;
templ.width0 = width;
templ.height0 = height;
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index 249ccd7fcf..04bba631ae 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -216,7 +216,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
}
memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = screen->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 9e9e479e7e..4199d7c6ba 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -24,7 +24,7 @@ x11_SOURCES = $(wildcard x11/*.c) \
x11_OBJECTS = $(x11_SOURCES:.c=.o)
-kms_INCLUDES = $(shell pkg-config --cflags-only-I libdrm)
+kms_INCLUDES = -I$(TOP)/src/gallium/winsys $(shell pkg-config --cflags-only-I libdrm)
kms_SOURCES = $(wildcard kms/*.c)
kms_OBJECTS = $(kms_SOURCES:.c=.o)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
index e71aec35b7..efcce25e31 100644
--- a/src/gallium/state_trackers/egl/SConscript
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -21,6 +21,7 @@ if 'egl' in env['statetrackers']:
'common/egl_g3d_api.c',
'common/egl_g3d_image.c',
'common/egl_g3d_st.c',
+ 'common/egl_g3d_sync.c',
'common/native_helper.c',
]
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 56d575ffe0..4e653bdf3b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -530,6 +530,18 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+ dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
+ dpy->Extensions.KHR_fence_sync = EGL_TRUE;
+
+ dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
+ dpy->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
+ dpy->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
+
+ if (dpy->Platform == _EGL_PLATFORM_DRM) {
+ dpy->Extensions.MESA_drm_display = EGL_TRUE;
+ dpy->Extensions.MESA_drm_image = EGL_TRUE;
+ }
+
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
goto fail;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index f33dc91cf9..be450bbede 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -30,12 +30,14 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_format.h"
+#include "os/os_thread.h"
#include "egldriver.h"
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
#include "eglimage.h"
+#include "eglsync.h"
#include "eglscreen.h"
#include "eglmode.h"
@@ -99,6 +101,24 @@ struct egl_g3d_image {
_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
+#ifdef EGL_KHR_reusable_sync
+
+struct egl_g3d_sync {
+ _EGLSync base;
+
+ int refs;
+
+ /* the mutex protects only the condvar, not the struct */
+ pipe_mutex mutex;
+ pipe_condvar condvar;
+
+ /* for fence sync */
+ struct pipe_fence_handle *fence;
+};
+_EGL_DRIVER_TYPECAST(egl_g3d_sync, _EGLSync, obj)
+
+#endif /* EGL_KHR_reusable_sync */
+
#ifdef EGL_MESA_screen_surface
struct egl_g3d_screen {
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 edac72a822..3ec53653f4 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -34,6 +34,7 @@
#include "egl_g3d.h"
#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
+#include "egl_g3d_sync.h"
#include "egl_g3d_st.h"
#include "egl_g3d_loader.h"
#include "native.h"
@@ -103,7 +104,7 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
}
gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
- &gconf->stvis, (gshare) ? gshare->stctxi : NULL);
+ (gconf) ? &gconf->stvis : NULL, (gshare) ? gshare->stctxi : NULL);
if (!gctx->stctxi) {
FREE(gctx);
return NULL;
@@ -437,16 +438,19 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
(gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
if (ok) {
- gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gdraw->stfbi);
- if (gread != gdraw) {
+ if (gdraw) {
gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
- gread->stfbi);
- }
+ gdraw->stfbi);
- if (gdraw->base.Type == EGL_WINDOW_BIT) {
- gctx->base.WindowRenderBuffer =
- (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
- EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
+ if (gdraw->base.Type == EGL_WINDOW_BIT) {
+ gctx->base.WindowRenderBuffer =
+ (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ?
+ EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
+ }
+ }
+ if (gread && gread != gdraw) {
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
+ gread->stfbi);
}
}
}
@@ -805,6 +809,17 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
drv->API.CreateImageKHR = egl_g3d_create_image;
drv->API.DestroyImageKHR = egl_g3d_destroy_image;
+#ifdef EGL_MESA_drm_image
+ drv->API.CreateDRMImageMESA = egl_g3d_create_drm_image;
+ drv->API.ExportDRMImageMESA = egl_g3d_export_drm_image;
+#endif
+
+#ifdef EGL_KHR_reusable_sync
+ drv->API.CreateSyncKHR = egl_g3d_create_sync;
+ drv->API.DestroySyncKHR = egl_g3d_destroy_sync;
+ drv->API.ClientWaitSyncKHR = egl_g3d_client_wait_sync;
+ drv->API.SignalSyncKHR = egl_g3d_signal_sync;
+#endif
#ifdef EGL_MESA_screen_surface
drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index 1e13cfcf7e..558638e72f 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -31,12 +31,16 @@
#include "util/u_rect.h"
#include "util/u_inlines.h"
#include "eglcurrent.h"
+#include "egllog.h"
#include "native.h"
#include "egl_g3d.h"
#include "egl_g3d_api.h"
#include "egl_g3d_image.h"
+/* move this to native display? */
+#include "state_tracker/drm_driver.h"
+
/**
* Reference and return the front left buffer of the native pixmap.
*/
@@ -67,6 +71,165 @@ egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
return textures[natt];
}
+#ifdef EGL_MESA_drm_image
+
+static struct pipe_resource *
+egl_g3d_create_drm_buffer(_EGLDisplay *dpy, const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_resource templ;
+ EGLint width = 0, height = 0, format = 0, use = 0;
+ EGLint valid_use;
+ EGLint i, err = EGL_SUCCESS;
+
+ for (i = 0; attribs[i] != EGL_NONE; i++) {
+ EGLint attr = attribs[i++];
+ EGLint val = attribs[i];
+
+ switch (attr) {
+ case EGL_WIDTH:
+ width = val;
+ break;
+ case EGL_HEIGHT:
+ height = val;
+ break;
+ case EGL_DRM_BUFFER_FORMAT_MESA:
+ format = val;
+ break;
+ case EGL_DRM_BUFFER_USE_MESA:
+ use = val;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglLog(_EGL_DEBUG, "bad image attribute 0x%04x", attr);
+ return NULL;
+ }
+ }
+
+ if (width <= 0 || height <= 0) {
+ _eglLog(_EGL_DEBUG, "bad width or height (%dx%d)", width, height);
+ return NULL;
+ }
+
+ switch (format) {
+ case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
+ format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ default:
+ _eglLog(_EGL_DEBUG, "bad image format value 0x%04x", format);
+ return NULL;
+ break;
+ }
+
+ valid_use = EGL_DRM_BUFFER_USE_SCANOUT_MESA |
+ EGL_DRM_BUFFER_USE_SHARE_MESA;
+ if (use & ~valid_use) {
+ _eglLog(_EGL_DEBUG, "bad image use bit 0x%04x", use);
+ return NULL;
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = format;
+ templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+
+ /*
+ * XXX fix apps (e.g. wayland) and pipe drivers (e.g. i915) and remove the
+ * size check
+ */
+ if ((use & EGL_DRM_BUFFER_USE_SCANOUT_MESA) &&
+ width >= 640 && height >= 480)
+ templ.bind |= PIPE_BIND_SCANOUT;
+ if (use & EGL_DRM_BUFFER_USE_SHARE_MESA)
+ templ.bind |= PIPE_BIND_SHARED;
+
+ return screen->resource_create(screen, &templ);
+}
+
+static struct pipe_resource *
+egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name,
+ const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_resource templ;
+ struct winsys_handle wsh;
+ EGLint width = 0, height = 0, format = 0, stride = 0;
+ EGLint i, err = EGL_SUCCESS;
+
+ /* winsys_handle is in theory platform-specific */
+ if (dpy->Platform != _EGL_PLATFORM_DRM)
+ return NULL;
+
+ for (i = 0; attribs[i] != EGL_NONE; i++) {
+ EGLint attr = attribs[i++];
+ EGLint val = attribs[i];
+
+ switch (attr) {
+ case EGL_WIDTH:
+ width = val;
+ break;
+ case EGL_HEIGHT:
+ height = val;
+ break;
+ case EGL_DRM_BUFFER_FORMAT_MESA:
+ format = val;
+ break;
+ case EGL_DRM_BUFFER_STRIDE_MESA:
+ stride = val;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglLog(_EGL_DEBUG, "bad image attribute 0x%04x", attr);
+ return NULL;
+ }
+ }
+
+ if (width <= 0 || height <= 0 || stride <= 0) {
+ _eglLog(_EGL_DEBUG, "bad width, height, or stride (%dx%dx%d)",
+ width, height, stride);
+ return NULL;
+ }
+
+ switch (format) {
+ case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
+ format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ default:
+ _eglLog(_EGL_DEBUG, "bad image format value 0x%04x", format);
+ return NULL;
+ break;
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = format;
+ templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+
+ memset(&wsh, 0, sizeof(wsh));
+ wsh.handle = (unsigned) name;
+ wsh.stride = stride;
+
+ return screen->resource_from_handle(screen, &templ, &wsh);
+}
+
+#endif /* EGL_MESA_drm_image */
+
_EGLImage *
egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLenum target, EGLClientBuffer buffer,
@@ -92,6 +255,11 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
ptex = egl_g3d_reference_native_pixmap(dpy,
(EGLNativePixmapType) buffer);
break;
+#ifdef EGL_MESA_drm_image
+ case EGL_DRM_BUFFER_MESA:
+ ptex = egl_g3d_reference_drm_buffer(dpy, (EGLint) buffer, attribs);
+ break;
+#endif
default:
ptex = NULL;
break;
@@ -134,3 +302,80 @@ egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
return EGL_TRUE;
}
+
+_EGLImage *
+egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ const EGLint *attribs)
+{
+ struct egl_g3d_image *gimg;
+ struct pipe_resource *ptex;
+
+ gimg = CALLOC_STRUCT(egl_g3d_image);
+ if (!gimg) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateDRMImageKHR");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&gimg->base, dpy, attribs)) {
+ FREE(gimg);
+ return NULL;
+ }
+
+#ifdef EGL_MESA_drm_image
+ ptex = egl_g3d_create_drm_buffer(dpy, attribs);
+#else
+ ptex = NULL;
+#endif
+ if (!ptex) {
+ FREE(gimg);
+ return NULL;
+ }
+
+ /* transfer the ownership to the image */
+ gimg->texture = ptex;
+ gimg->face = 0;
+ gimg->level = 0;
+ gimg->zslice = 0;
+
+ return &gimg->base;
+}
+
+EGLBoolean
+egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
+ EGLint *name, EGLint *handle, EGLint *stride)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_image *gimg = egl_g3d_image(img);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct winsys_handle wsh;
+
+ /* winsys_handle is in theory platform-specific */
+ if (dpy->Platform != _EGL_PLATFORM_DRM)
+ return EGL_FALSE;
+
+ /* get shared handle */
+ if (name) {
+ memset(&handle, 0, sizeof(handle));
+ wsh.type = DRM_API_HANDLE_TYPE_SHARED;
+ if (!screen->resource_get_handle(screen, gimg->texture, &wsh)) {
+ return EGL_FALSE;
+ }
+
+ *name = wsh.handle;
+ }
+
+ /* get KMS handle */
+ if (handle || stride) {
+ memset(&wsh, 0, sizeof(wsh));
+ wsh.type = DRM_API_HANDLE_TYPE_KMS;
+ if (!screen->resource_get_handle(screen, gimg->texture, &wsh))
+ return EGL_FALSE;
+
+ if (handle)
+ *handle = wsh.handle;
+ if (stride)
+ *stride = wsh.stride;
+ }
+
+ return EGL_TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.h b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
index adda933371..f051da8283 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
@@ -39,4 +39,12 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
EGLBoolean
egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
+_EGLImage *
+egl_g3d_create_drm_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ const EGLint *attribs);
+
+EGLBoolean
+egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img,
+ EGLint *name, EGLint *handle, EGLint *stride);
+
#endif /* _EGL_G3D_IMAGE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
new file mode 100644
index 0000000000..ec74e9eb94
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c
@@ -0,0 +1,284 @@
+/*
+ * 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_memory.h"
+#include "util/u_atomic.h"
+#include "os/os_thread.h"
+#include "eglsync.h"
+#include "eglcurrent.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_sync.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+/**
+ * Wait for the conditional variable.
+ */
+static EGLint
+egl_g3d_wait_sync_condvar(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+ _EGLDisplay *dpy = gsync->base.Resource.Display;
+
+ pipe_mutex_lock(gsync->mutex);
+
+ /* unlock display lock just before waiting */
+ _eglUnlockMutex(&dpy->Mutex);
+
+ /* No timed wait. Always treat timeout as EGL_FOREVER_KHR */
+ pipe_condvar_wait(gsync->condvar, gsync->mutex);
+
+ _eglLockMutex(&dpy->Mutex);
+
+ pipe_mutex_unlock(gsync->mutex);
+
+ return EGL_CONDITION_SATISFIED_KHR;
+}
+
+/**
+ * Signal the conditional variable.
+ */
+static void
+egl_g3d_signal_sync_condvar(struct egl_g3d_sync *gsync)
+{
+ pipe_mutex_lock(gsync->mutex);
+ pipe_condvar_broadcast(gsync->condvar);
+ pipe_mutex_unlock(gsync->mutex);
+}
+
+/**
+ * Insert a fence command to the command stream of the current context.
+ */
+static EGLint
+egl_g3d_insert_fence_sync(struct egl_g3d_sync *gsync)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* already checked in egl_g3d_create_sync */
+ assert(gctx);
+
+ /* insert the fence command */
+ gctx->stctxi->flush(gctx->stctxi, 0x0, &gsync->fence);
+ if (!gsync->fence)
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+ return EGL_SUCCESS;
+}
+
+/**
+ * Wait for the fence sync to be signaled.
+ */
+static EGLint
+egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout)
+{
+ EGLint ret;
+
+ if (gsync->fence) {
+ _EGLDisplay *dpy = gsync->base.Resource.Display;
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_fence_handle *fence = gsync->fence;
+
+ gsync->fence = NULL;
+
+ _eglUnlockMutex(&dpy->Mutex);
+ /* no timed finish? */
+ screen->fence_finish(screen, fence, 0x0);
+ ret = EGL_CONDITION_SATISFIED_KHR;
+ _eglLockMutex(&dpy->Mutex);
+
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+
+ screen->fence_reference(screen, &fence, NULL);
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+ else {
+ ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+ }
+
+ return ret;
+}
+
+static INLINE void
+egl_g3d_ref_sync(struct egl_g3d_sync *gsync)
+{
+ p_atomic_inc(&gsync->refs);
+}
+
+static INLINE void
+egl_g3d_unref_sync(struct egl_g3d_sync *gsync)
+{
+ if (p_atomic_dec_zero(&gsync->refs)) {
+ pipe_condvar_destroy(gsync->condvar);
+ pipe_mutex_destroy(gsync->mutex);
+
+ if (gsync->fence) {
+ struct egl_g3d_display *gdpy =
+ egl_g3d_display(gsync->base.Resource.Display);
+ struct pipe_screen *screen = gdpy->native->screen;
+
+ screen->fence_reference(screen, &gsync->fence, NULL);
+ }
+
+ FREE(gsync);
+ }
+}
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum type, const EGLint *attrib_list)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_sync *gsync;
+ EGLint err;
+
+ if (!ctx || ctx->Resource.Display != dpy) {
+ _eglError(EGL_BAD_MATCH, "eglCreateSyncKHR");
+ return NULL;
+ }
+
+ gsync = CALLOC_STRUCT(egl_g3d_sync);
+ if (!gsync) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateSyncKHR");
+ return NULL;
+ }
+
+ if (!_eglInitSync(&gsync->base, dpy, type, attrib_list)) {
+ FREE(gsync);
+ return NULL;
+ }
+
+ switch (type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ err = EGL_SUCCESS;
+ break;
+ case EGL_SYNC_FENCE_KHR:
+ err = egl_g3d_insert_fence_sync(gsync);
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglError(err, "eglCreateSyncKHR");
+ FREE(gsync);
+ return NULL;
+ }
+
+ pipe_mutex_init(gsync->mutex);
+ pipe_condvar_init(gsync->condvar);
+ p_atomic_set(&gsync->refs, 1);
+
+ return &gsync->base;
+}
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+ switch (gsync->base.Type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ /* signal the waiters */
+ if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+ gsync->base.SyncStatus = EGL_SIGNALED_KHR;
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+ break;
+ default:
+ break;
+ }
+
+ egl_g3d_unref_sync(gsync);
+
+ return EGL_TRUE;
+}
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLint flags, EGLTimeKHR timeout)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+ EGLint ret = EGL_CONDITION_SATISFIED_KHR;
+
+ if (gsync->base.SyncStatus != EGL_SIGNALED_KHR) {
+ /* flush if there is a current context */
+ if (flags & EGL_SYNC_FLUSH_COMMANDS_BIT_KHR) {
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ if (gctx)
+ gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL);
+ }
+
+ if (timeout) {
+ /* reference the sync object in case it is destroyed while waiting */
+ egl_g3d_ref_sync(gsync);
+
+ switch (gsync->base.Type) {
+ case EGL_SYNC_REUSABLE_KHR:
+ ret = egl_g3d_wait_sync_condvar(gsync, timeout);
+ break;
+ case EGL_SYNC_FENCE_KHR:
+ ret = egl_g3d_wait_fence_sync(gsync, timeout);
+ default:
+ break;
+ }
+
+ egl_g3d_unref_sync(gsync);
+ }
+ else {
+ ret = EGL_TIMEOUT_EXPIRED_KHR;
+ }
+ }
+
+ return ret;
+}
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLenum mode)
+{
+ struct egl_g3d_sync *gsync = egl_g3d_sync(sync);
+
+ /* only for reusable sync */
+ if (sync->Type != EGL_SYNC_REUSABLE_KHR)
+ return _eglError(EGL_BAD_MATCH, "eglSignalSyncKHR");
+
+ if (gsync->base.SyncStatus != mode) {
+ gsync->base.SyncStatus = mode;
+ if (mode == EGL_SIGNALED_KHR)
+ egl_g3d_signal_sync_condvar(gsync);
+ }
+
+ return EGL_TRUE;
+}
+
+#endif /* EGL_KHR_reusable_sync */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.h b/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
new file mode 100644
index 0000000000..3179ca04e1
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.h
@@ -0,0 +1,53 @@
+/*
+ * 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>
+ */
+
+#ifndef _EGL_G3D_SYNC_H_
+#define _EGL_G3D_SYNC_H_
+
+#include "egl_g3d.h"
+
+#ifdef EGL_KHR_reusable_sync
+
+_EGLSync *
+egl_g3d_create_sync(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum type, const EGLint *attrib_list);
+
+EGLBoolean
+egl_g3d_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync);
+
+EGLint
+egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLint flags, EGLTimeKHR timeout);
+
+EGLBoolean
+egl_g3d_signal_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync,
+ EGLenum mode);
+
+#endif /* EGL_KHR_reusable_sync */
+
+#endif /* _EGL_G3D_SYNC_H_ */
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index d4e8fbc913..208f73306c 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -38,6 +38,10 @@
#include "native_kms.h"
+/* see get_drm_screen_name */
+#include <radeon_drm.h>
+#include "radeon/drm/radeon_drm.h"
+
static boolean
kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_resource **textures,
@@ -584,7 +588,9 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
nconf->color_format = format;
- nconf->scanout_bit = TRUE;
+ /* support KMS */
+ if (kdpy->resources)
+ nconf->scanout_bit = TRUE;
}
configs = MALLOC(sizeof(*configs));
@@ -664,6 +670,27 @@ kms_display_destroy(struct native_display *ndpy)
FREE(kdpy);
}
+static const char *
+get_drm_screen_name(int fd, drmVersionPtr version)
+{
+ const char *name = version->name;
+
+ if (name && !strcmp(name, "radeon")) {
+ int chip_id;
+ struct drm_radeon_info info;
+
+ memset(&info, 0, sizeof(info));
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = pointer_to_intptr(&chip_id);
+ if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0)
+ return NULL;
+
+ name = is_r3xx(chip_id) ? "r300" : "r600";
+ }
+
+ return name;
+}
+
/**
* Initialize KMS and pipe screen.
*/
@@ -672,6 +699,7 @@ kms_display_init_screen(struct native_display *ndpy)
{
struct kms_display *kdpy = kms_display(ndpy);
drmVersionPtr version;
+ const char *name;
version = drmGetVersion(kdpy->fd);
if (!version) {
@@ -679,8 +707,11 @@ kms_display_init_screen(struct native_display *ndpy)
return FALSE;
}
- kdpy->base.screen = kdpy->event_handler->new_drm_screen(&kdpy->base,
- version->name, kdpy->fd);;
+ name = get_drm_screen_name(kdpy->fd, version);
+ if (name) {
+ kdpy->base.screen =
+ kdpy->event_handler->new_drm_screen(&kdpy->base, name, kdpy->fd);
+ }
drmFreeVersion(version);
if (!kdpy->base.screen) {
@@ -717,32 +748,32 @@ kms_create_display(int fd, struct native_event_handler *event_handler,
return NULL;
}
+ kdpy->base.destroy = kms_display_destroy;
+ kdpy->base.get_param = kms_display_get_param;
+ kdpy->base.get_configs = kms_display_get_configs;
+
/* resources are fixed, unlike crtc, connector, or encoder */
kdpy->resources = drmModeGetResources(kdpy->fd);
- if (!kdpy->resources) {
- kms_display_destroy(&kdpy->base);
- return NULL;
- }
+ if (kdpy->resources) {
+ kdpy->saved_crtcs =
+ CALLOC(kdpy->resources->count_crtcs, sizeof(*kdpy->saved_crtcs));
+ if (!kdpy->saved_crtcs) {
+ 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->shown_surfaces =
- CALLOC(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces));
- if (!kdpy->shown_surfaces) {
- kms_display_destroy(&kdpy->base);
- return NULL;
+ kdpy->base.modeset = &kms_display_modeset;
+ }
+ else {
+ _eglLog(_EGL_DEBUG, "Failed to get KMS resources. Disable modeset.");
}
-
- kdpy->base.destroy = kms_display_destroy;
- kdpy->base.get_param = kms_display_get_param;
- kdpy->base.get_configs = kms_display_get_configs;
-
- kdpy->base.modeset = &kms_display_modeset;
return &kdpy->base;
}
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index eb8d6a1933..dcd50e19d7 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -34,10 +34,6 @@
#include "GL/glx.h"
#include "xm_api.h"
-#include "main/context.h"
-#include "main/macros.h"
-#include "main/imports.h"
-#include "main/version.h"
/* This indicates the client-side GLX API and GLX encoder version. */
@@ -603,8 +599,8 @@ destroy_visuals_on_display(Display *dpy)
static int
close_display_callback(Display *dpy, XExtCodes *codes)
{
- destroy_visuals_on_display(dpy);
xmesa_destroy_buffers_on_display(dpy);
+ destroy_visuals_on_display(dpy);
return 0;
}
@@ -1299,7 +1295,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
XMesaContext xm_dst = dst->xmesaContext;
(void) dpy;
if (MakeCurrent_PrevContext == src) {
- _mesa_Flush();
+ glFlush();
}
XMesaCopyContext(xm_src, xm_dst, mask);
}
diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index 8903b0e6cb..0aa37e150b 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -30,8 +30,7 @@
*/
-#include "main/context.h"
-#include "main/imports.h"
+#include "main/core.h"
#include <GL/glx.h>
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index c0c418306f..eb4ce74266 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -56,7 +56,6 @@
#include "xm_api.h"
#include "xm_st.h"
-#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
@@ -72,10 +71,35 @@
static struct xm_driver driver;
static struct st_api *stapi;
+/* Default strict invalidate to false. This means we will not call
+ * XGetGeometry after every swapbuffers, which allows swapbuffers to
+ * remain asynchronous. For apps running at 100fps with synchronous
+ * swapping, a 10% boost is typical. For gears, I see closer to 20%
+ * speedup.
+ *
+ * Note that the work of copying data on swapbuffers doesn't disappear
+ * - this change just allows the X server to execute the PutImage
+ * asynchronously without us effectively blocked until its completion.
+ *
+ * This speeds up even llvmpipe's threaded rasterization as the
+ * swapbuffers operation was a large part of the serial component of
+ * an llvmpipe frame.
+ *
+ * The downside of this is correctness - applications which don't call
+ * glViewport on window resizes will get incorrect rendering. A
+ * better solution would be to have per-frame but asynchronous
+ * invalidation. Xcb almost looks as if it could provide this, but
+ * the API doesn't seem to quite be there.
+ */
+boolean xmesa_strict_invalidate = FALSE;
+
void xmesa_set_driver( const struct xm_driver *templ )
{
driver = *templ;
stapi = driver.create_st_api();
+
+ xmesa_strict_invalidate =
+ debug_get_bool_option("XMESA_STRICT_INVALIDATE", FALSE);
}
@@ -91,7 +115,12 @@ static int
xmesa_get_param(struct st_manager *smapi,
enum st_manager_param param)
{
- return 0;
+ switch(param) {
+ case ST_MANAGER_BROKEN_INVALIDATE:
+ return !xmesa_strict_invalidate;
+ default:
+ return 0;
+ }
}
static XMesaDisplay
@@ -263,7 +292,6 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
Status stat;
pipe_mutex_lock(xmdpy->mutex);
- XSync(b->xm_visual->display, 0); /* added for Chromium */
stat = get_drawable_size(dpy, b->ws.drawable, width, height);
pipe_mutex_unlock(xmdpy->mutex);
@@ -726,15 +754,39 @@ XMesaVisual XMesaCreateVisual( Display *display,
alpha_bits = v->mesa_visual.alphaBits;
}
- _mesa_initialize_visual( &v->mesa_visual,
- db_flag, stereo_flag,
- red_bits, green_bits,
- blue_bits, alpha_bits,
- depth_size,
- stencil_size,
- accum_red_size, accum_green_size,
- accum_blue_size, accum_alpha_size,
- 0 );
+ /* initialize visual */
+ {
+ __GLcontextModes *vis = &v->mesa_visual;
+
+ vis->rgbMode = GL_TRUE;
+ vis->doubleBufferMode = db_flag;
+ vis->stereoMode = stereo_flag;
+
+ vis->redBits = red_bits;
+ vis->greenBits = green_bits;
+ vis->blueBits = blue_bits;
+ vis->alphaBits = alpha_bits;
+ vis->rgbBits = red_bits + green_bits + blue_bits;
+
+ vis->indexBits = 0;
+ vis->depthBits = depth_size;
+ vis->stencilBits = stencil_size;
+
+ vis->accumRedBits = accum_red_size;
+ vis->accumGreenBits = accum_green_size;
+ vis->accumBlueBits = accum_blue_size;
+ vis->accumAlphaBits = accum_alpha_size;
+
+ vis->haveAccumBuffer = accum_red_size > 0;
+ vis->haveDepthBuffer = depth_size > 0;
+ vis->haveStencilBuffer = stencil_size > 0;
+
+ vis->numAuxBuffers = 0;
+ vis->level = 0;
+ vis->pixmapMode = 0;
+ vis->sampleBuffers = 0;
+ vis->samples = 0;
+ }
v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
if (db_flag)
@@ -1154,7 +1206,7 @@ void XMesaFlush( XMesaContext c )
xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
}
- XSync( c->xm_visual->display, False );
+ XFlush( c->xm_visual->display );
}
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 4f2c8a6e6a..f209b14ea1 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -57,7 +57,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#define XMESA_H
-#include "main/mtypes.h"
+#include "main/core.h" /* for GLvisual and MESA_VERSION_STRING */
#include "state_tracker/st_api.h"
#include "os/os_thread.h"
@@ -378,6 +378,6 @@ xmesa_buffer_height(XMesaBuffer b)
return b->height;
}
-
+extern boolean xmesa_strict_invalidate;
#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
index c62eb8bfbd..0f74b3f7aa 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_st.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -26,18 +26,18 @@
* Chia-I Wu <olv@lunarg.com>
*/
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-
#include "xm_api.h"
#include "xm_st.h"
+#include "util/u_inlines.h"
+
struct xmesa_st_framebuffer {
XMesaDisplay display;
XMesaBuffer buffer;
struct pipe_screen *screen;
struct st_visual stvis;
+ enum pipe_texture_target target;
unsigned texture_width, texture_height, texture_mask;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
@@ -139,7 +139,7 @@ xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
}
memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = xstfb->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
@@ -210,6 +210,12 @@ xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
/* record newly allocated textures */
new_mask = statt_mask & ~xstfb->texture_mask;
+ /* If xmesa_strict_invalidate is not set, we will not yet have
+ * called XGetGeometry(). Do so here:
+ */
+ if (!xmesa_strict_invalidate)
+ xmesa_check_buffer_size(xstfb->buffer);
+
resized = (xstfb->buffer->width != xstfb->texture_width ||
xstfb->buffer->height != xstfb->texture_height);
@@ -251,7 +257,8 @@ xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
boolean ret;
ret = xmesa_st_framebuffer_display(stfbi, statt);
- if (ret)
+
+ if (ret && xmesa_strict_invalidate)
xmesa_check_buffer_size(xstfb->buffer);
return ret;
@@ -279,6 +286,10 @@ xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
xstfb->buffer = b;
xstfb->screen = xmdpy->screen;
xstfb->stvis = b->xm_visual->stvis;
+ if(xstfb->screen->get_param(xstfb->screen, PIPE_CAP_NPOT_TEXTURES))
+ xstfb->target = PIPE_TEXTURE_2D;
+ else
+ xstfb->target = PIPE_TEXTURE_RECT;
stfbi->visual = &xstfb->stvis;
stfbi->flush_front = xmesa_st_framebuffer_flush_front;
@@ -322,7 +333,8 @@ xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
*back = tmp;
}
- xmesa_check_buffer_size(xstfb->buffer);
+ if (xmesa_strict_invalidate)
+ xmesa_check_buffer_size(xstfb->buffer);
}
}
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 0fb7cd8306..a0e14b9601 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -33,7 +33,7 @@
/* for _mesa_share_state */
#include "state_tracker/st_context.h"
-#include "main/context.h"
+#include "main/core.h"
#include "stw_icd.h"
#include "stw_device.h"
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index a107c71bda..37809d084c 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -27,7 +27,7 @@
#include <windows.h>
-#include "glapi/glthread.h"
+#include "glapi/glapi.h"
#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index e606477e97..18ac482369 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -25,15 +25,13 @@
*
**************************************************************************/
-#include "main/mtypes.h"
-#include "main/context.h"
-
#include "pipe/p_format.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "util/u_format.h"
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "stw_icd.h"
#include "stw_device.h"
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h
index d405172773..282c9f643c 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -34,8 +34,6 @@
#define PFD_SUPPORT_COMPOSITION 0x00008000
#endif
-#include "main/mtypes.h"
-
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "state_tracker/st_api.h"