aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/egl')
-rw-r--r--src/gallium/state_trackers/egl/Makefile1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c1282
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h48
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c731
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.h37
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c136
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.h42
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c312
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.h80
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c131
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.h73
-rw-r--r--src/gallium/state_trackers/egl/common/native.h181
-rw-r--r--src/gallium/state_trackers/egl/common/native_modeset.h88
-rw-r--r--src/gallium/state_trackers/egl/common/native_probe.h68
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h20
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c198
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h23
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c283
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c41
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h18
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c444
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.h40
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c79
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.h17
25 files changed, 2325 insertions, 2279 deletions
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 794785006f5..1768241352f 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -16,6 +16,7 @@ x11_INCLUDES = \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/glx \
-I$(TOP)/src/mesa \
+ $(X11_CFLAGS) \
$(shell pkg-config --cflags-only-I libdrm)
x11_SOURCES = $(wildcard x11/*.c) \
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 04268c71c5a..3ab72dce2f3 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -14,276 +14,28 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include "pipe/p_screen.h"
-#include "util/u_memory.h"
-#include "util/u_rect.h"
-#include "util/u_inlines.h"
#include "egldriver.h"
#include "eglcurrent.h"
-#include "eglconfigutil.h"
#include "egllog.h"
-#include "native.h"
-#include "egl_g3d.h"
-#include "egl_st.h"
-
-/**
- * Validate the draw/read surfaces of the context.
- */
-static void
-egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct pipe_screen *screen = gdpy->native->screen;
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = {
- ST_SURFACE_FRONT_LEFT,
- ST_SURFACE_BACK_LEFT,
- ST_SURFACE_FRONT_RIGHT,
- ST_SURFACE_BACK_RIGHT,
- };
- EGLint num_surfaces, s;
-
- /* validate draw and/or read buffers */
- num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2;
- for (s = 0; s < num_surfaces; s++) {
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
- EGLint att;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- if (!gctx->force_validate) {
- unsigned int seq_num;
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &seq_num, NULL, NULL, NULL);
- /* skip validation */
- if (gsurf->sequence_number == seq_num)
- continue;
- }
-
- pipe_surface_reference(&gsurf->render_surface, NULL);
- memset(textures, 0, sizeof(textures));
-
- gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
- &gsurf->sequence_number, textures,
- &gsurf->base.Width, &gsurf->base.Height);
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- struct pipe_texture *pt = textures[att];
- struct pipe_surface *ps;
-
- if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) {
- ps = screen->get_tex_surface(screen, pt, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
- gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb,
- st_att_map[att], ps);
-
- if (gsurf->render_att == att)
- pipe_surface_reference(&gsurf->render_surface, ps);
-
- pipe_surface_reference(&ps, NULL);
- pipe_texture_reference(&pt, NULL);
- }
- }
-
- gctx->stapi->st_resize_framebuffer(gbuf->st_fb,
- gsurf->base.Width, gsurf->base.Height);
- }
-
- gctx->force_validate = EGL_FALSE;
-
-}
-
-/**
- * Create a st_framebuffer.
- */
-static struct st_framebuffer *
-create_framebuffer(_EGLContext *ctx, _EGLSurface *surf)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
-
- return gctx->stapi->st_create_framebuffer(&gconf->native->mode,
- gconf->native->color_format, gconf->native->depth_format,
- gconf->native->stencil_format,
- gsurf->base.Width, gsurf->base.Height, &gsurf->base);
-}
-
-/**
- * Update the attachments of draw/read surfaces.
- */
-static void
-egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- EGLint s;
-
- /* route draw and read buffers' attachments */
- for (s = 0; s < 2; s++) {
- struct egl_g3d_surface *gsurf;
- struct egl_g3d_buffer *gbuf;
-
- if (s == 0) {
- gsurf = egl_g3d_surface(gctx->base.DrawSurface);
- gbuf = &gctx->draw;
- }
- else {
- gsurf = egl_g3d_surface(gctx->base.ReadSurface);
- gbuf = &gctx->read;
- }
-
- gbuf->attachment_mask = (1 << gsurf->render_att);
-
- /* FIXME OpenGL defaults to draw the front or back buffer when the
- * context is single-buffered or double-buffered respectively. In EGL,
- * however, the buffer to be drawn is determined by the surface, instead
- * of the context. As a result, rendering to a pixmap surface with a
- * double-buffered context does not work as expected.
- *
- * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt ==
- * NATIVE_ATTACHMENT_FRONT_LEFT);
- */
-
- /*
- * FIXME If the back buffer is asked for here, and the front buffer is
- * later needed by the client API (e.g. glDrawBuffer is called to draw
- * the front buffer), it will create a new pipe texture and draw there.
- * One fix is to ask for both buffers here, but it would be a waste if
- * the front buffer is never used. A better fix is to add a callback to
- * the pipe screen with context private (just like flush_frontbuffer).
- */
- }
-}
-
-/**
- * Reallocate the context's framebuffers after draw/read surfaces change.
- */
-static EGLBoolean
-egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface);
- struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface);
-
- /* unreference the old framebuffers */
- if (gctx->draw.st_fb) {
- EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb);
- void *priv;
-
- priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb);
- if (!gdraw || priv != (void *) &gdraw->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
-
- if (is_equal) {
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- else {
- priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb);
- if (!gread || priv != (void *) &gread->base) {
- gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb);
- gctx->read.st_fb = NULL;
- gctx->draw.attachment_mask = 0x0;
- }
- }
- }
-
- if (!gdraw)
- return EGL_TRUE;
-
- /* create the draw fb */
- if (!gctx->draw.st_fb) {
- gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base);
- if (!gctx->draw.st_fb)
- return EGL_FALSE;
- }
-
- /* create the read fb */
- if (!gctx->read.st_fb) {
- if (gread != gdraw) {
- gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base);
- if (!gctx->read.st_fb) {
- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
- gctx->draw.st_fb = NULL;
- return EGL_FALSE;
- }
- }
- else {
- /* there is no st_reference_framebuffer... */
- gctx->read.st_fb = gctx->draw.st_fb;
- }
- }
-
- egl_g3d_route_context(dpy, &gctx->base);
- gctx->force_validate = EGL_TRUE;
-
- return EGL_TRUE;
-}
-
-/**
- * Return the state tracker for the given context.
- */
-static const struct egl_g3d_st *
-egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
-{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- const struct egl_g3d_st *stapi;
- EGLint idx = -1;
-
- switch (ctx->ClientAPI) {
- case EGL_OPENGL_ES_API:
- switch (ctx->ClientVersion) {
- case 1:
- idx = EGL_G3D_ST_OPENGL_ES;
- break;
- case 2:
- idx = EGL_G3D_ST_OPENGL_ES2;
- break;
- default:
- _eglLog(_EGL_WARNING, "unknown client version %d",
- ctx->ClientVersion);
- break;
- }
- break;
- case EGL_OPENVG_API:
- idx = EGL_G3D_ST_OPENVG;
- break;
- case EGL_OPENGL_API:
- idx = EGL_G3D_ST_OPENGL;
- break;
- default:
- _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
- break;
- }
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "util/u_string.h"
- stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
- return stapi;
-}
+#include "egl_g3d.h"
+#include "egl_g3d_api.h"
+#include "egl_g3d_st.h"
+#include "native.h"
/**
* Initialize the state trackers.
@@ -298,10 +50,10 @@ egl_g3d_init_st(_EGLDriver *drv)
if (gdrv->api_mask)
return;
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- gdrv->stapis[i] = egl_g3d_get_st(i);
+ for (i = 0; i < ST_API_COUNT; i++) {
+ gdrv->stapis[i] = egl_g3d_create_st_api(i);
if (gdrv->stapis[i])
- gdrv->api_mask |= gdrv->stapis[i]->api_bit;
+ gdrv->api_mask |= egl_g3d_st_api_bit(i);
}
if (gdrv->api_mask)
@@ -350,35 +102,6 @@ egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
}
}
-/**
- * Return an API mask that consists of the state trackers that supports the
- * given mode.
- *
- * FIXME add st_is_mode_supported()?
- */
-static EGLint
-get_mode_api_mask(const __GLcontextModes *mode, EGLint api_mask)
-{
- EGLint check;
-
- /* OpenGL ES 1.x and 2.x are checked together */
- check = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
- if (api_mask & check) {
- /* this is required by EGL, not by OpenGL ES */
- if (mode->drawableType & GLX_WINDOW_BIT && !mode->doubleBufferMode)
- api_mask &= ~check;
- }
-
- check = EGL_OPENVG_BIT;
- if (api_mask & check) {
- /* vega st needs the depth/stencil rb */
- if (!mode->depthBits && !mode->stencilBits)
- api_mask &= ~check;
- }
-
- return api_mask;
-}
-
#ifdef EGL_MESA_screen_surface
static void
@@ -392,7 +115,7 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
if (!num_connectors) {
if (native_connectors)
- free(native_connectors);
+ FREE(native_connectors);
return;
}
@@ -407,13 +130,13 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
if (!num_modes) {
if (native_modes)
- free(native_modes);
+ FREE(native_modes);
continue;
}
gscr = CALLOC_STRUCT(egl_g3d_screen);
if (!gscr) {
- free(native_modes);
+ FREE(native_modes);
continue;
}
@@ -437,100 +160,275 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
_eglAddScreen(dpy, &gscr->base);
}
- free(native_connectors);
+ FREE(native_connectors);
}
#endif /* EGL_MESA_screen_surface */
/**
- * Add configs to display and return the next config ID.
+ * Initialize and validate the EGL config attributes.
*/
-static EGLint
-egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
+static EGLBoolean
+init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
+ EGLint api_mask, enum pipe_format depth_stencil_format)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- const struct native_config **native_configs;
- int num_configs, i;
+ uint rgba[4], depth_stencil[2], buffer_size;
+ EGLint surface_type;
+ EGLint i;
- native_configs = gdpy->native->get_configs(gdpy->native,
- &num_configs);
- if (!num_configs) {
- if (native_configs)
- free(native_configs);
- return id;
+ /* get the color and depth/stencil component sizes */
+ assert(nconf->color_format != PIPE_FORMAT_NONE);
+ buffer_size = 0;
+ for (i = 0; i < 4; i++) {
+ rgba[i] = util_format_get_component_bits(nconf->color_format,
+ UTIL_FORMAT_COLORSPACE_RGB, i);
+ buffer_size += rgba[i];
+ }
+ for (i = 0; i < 2; i++) {
+ if (depth_stencil_format != PIPE_FORMAT_NONE) {
+ depth_stencil[i] =
+ util_format_get_component_bits(depth_stencil_format,
+ UTIL_FORMAT_COLORSPACE_ZS, i);
+ }
+ else {
+ depth_stencil[i] = 0;
+ }
}
- for (i = 0; i < num_configs; i++) {
- EGLint api_mask;
- struct egl_g3d_config *gconf;
- EGLBoolean valid;
+ surface_type = 0x0;
+ if (nconf->window_bit)
+ surface_type |= EGL_WINDOW_BIT;
+ if (nconf->pixmap_bit)
+ surface_type |= EGL_PIXMAP_BIT;
+#ifdef EGL_MESA_screen_surface
+ if (nconf->scanout_bit)
+ surface_type |= EGL_SCREEN_BIT_MESA;
+#endif
- gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
+ surface_type |= EGL_PBUFFER_BIT;
- _eglInitConfig(&gconf->base, dpy, id);
+ SET_CONFIG_ATTRIB(conf, EGL_CONFORMANT, api_mask);
+ SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, api_mask);
- api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
- if (!api_mask) {
- _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
- native_configs[i]->mode.visualID);
- }
+ SET_CONFIG_ATTRIB(conf, EGL_RED_SIZE, rgba[0]);
+ SET_CONFIG_ATTRIB(conf, EGL_GREEN_SIZE, rgba[1]);
+ SET_CONFIG_ATTRIB(conf, EGL_BLUE_SIZE, rgba[2]);
+ SET_CONFIG_ATTRIB(conf, EGL_ALPHA_SIZE, rgba[3]);
+ SET_CONFIG_ATTRIB(conf, EGL_BUFFER_SIZE, buffer_size);
- valid = _eglConfigFromContextModesRec(&gconf->base,
- &native_configs[i]->mode, api_mask, api_mask);
- if (valid) {
-#ifdef EGL_MESA_screen_surface
- /* check if scanout surface bit is set */
- if (native_configs[i]->scanout_bit) {
- EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
- val |= EGL_SCREEN_BIT_MESA;
- SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
- }
-#endif
- valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
- }
- if (!valid) {
- _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
- native_configs[i]->mode.visualID);
- free(gconf);
- continue;
+ SET_CONFIG_ATTRIB(conf, EGL_DEPTH_SIZE, depth_stencil[0]);
+ SET_CONFIG_ATTRIB(conf, EGL_STENCIL_SIZE, depth_stencil[1]);
+
+ SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, surface_type);
+
+ SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_TRUE);
+ if (surface_type & EGL_WINDOW_BIT) {
+ SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_ID, nconf->native_visual_id);
+ SET_CONFIG_ATTRIB(conf, EGL_NATIVE_VISUAL_TYPE,
+ nconf->native_visual_type);
+ }
+
+ if (surface_type & EGL_PBUFFER_BIT) {
+ SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
+ if (rgba[3])
+ SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+
+ SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_WIDTH, 4096);
+ SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_HEIGHT, 4096);
+ SET_CONFIG_ATTRIB(conf, EGL_MAX_PBUFFER_PIXELS, 4096 * 4096);
+ }
+
+ SET_CONFIG_ATTRIB(conf, EGL_LEVEL, nconf->level);
+ SET_CONFIG_ATTRIB(conf, EGL_SAMPLES, nconf->samples);
+ SET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS, 1);
+
+ if (nconf->slow_config)
+ SET_CONFIG_ATTRIB(conf, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG);
+
+ if (nconf->transparent_rgb) {
+ rgba[0] = nconf->transparent_rgb_values[0];
+ rgba[1] = nconf->transparent_rgb_values[1];
+ rgba[2] = nconf->transparent_rgb_values[2];
+
+ SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RGB);
+ SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_RED_VALUE, rgba[0]);
+ SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_GREEN_VALUE, rgba[1]);
+ SET_CONFIG_ATTRIB(conf, EGL_TRANSPARENT_BLUE_VALUE, rgba[2]);
+ }
+
+ return _eglValidateConfig(conf, EGL_FALSE);
+}
+
+/**
+ * Initialize an EGL config from the native config.
+ */
+static EGLBoolean
+egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const struct native_config *nconf,
+ enum pipe_format depth_stencil_format)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ EGLint buffer_mask, api_mask;
+ EGLBoolean valid;
+ EGLint i;
+
+ buffer_mask = 0x0;
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
+ buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_LEFT))
+ buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_RIGHT))
+ buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_BACK_RIGHT))
+ buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+
+ gconf->stvis.buffer_mask = buffer_mask;
+ gconf->stvis.color_format = nconf->color_format;
+ gconf->stvis.depth_stencil_format = depth_stencil_format;
+ gconf->stvis.accum_format = PIPE_FORMAT_NONE;
+ gconf->stvis.samples = nconf->samples;
+
+ gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
+ ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
+
+ api_mask = 0;
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
+ if (stapi) {
+ if (stapi->is_visual_supported(stapi, &gconf->stvis))
+ api_mask |= egl_g3d_st_api_bit(i);
}
+ }
+ /* this is required by EGL, not by OpenGL ES */
+ if (nconf->window_bit &&
+ gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
+ api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
- gconf->native = native_configs[i];
- _eglAddConfig(dpy, &gconf->base);
- id++;
+ if (!api_mask) {
+ _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+ nconf->native_visual_id);
}
- free(native_configs);
- return id;
+ valid = init_config_attributes(&gconf->base,
+ nconf, api_mask, depth_stencil_format);
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
+ return EGL_FALSE;
+ }
+
+ gconf->native = nconf;
+
+ return EGL_TRUE;
}
/**
- * Flush the front buffer of the context's draw surface.
+ * Get all interested depth/stencil formats of a display.
*/
-static void
-egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
+static EGLint
+egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
+ enum pipe_format formats[8])
{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct pipe_screen *screen = gdpy->native->screen;
+ const EGLint candidates[] = {
+ 1, PIPE_FORMAT_Z16_UNORM,
+ 1, PIPE_FORMAT_Z32_UNORM,
+ 2, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+ 2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
+ 0
+ };
+ const EGLint *fmt = candidates;
+ EGLint count;
+
+ count = 0;
+ formats[count++] = PIPE_FORMAT_NONE;
+
+ while (*fmt) {
+ EGLint i, n = *fmt++;
+
+ /* pick the first supported format */
+ for (i = 0; i < n; i++) {
+ if (screen->is_format_supported(screen, fmt[i],
+ PIPE_TEXTURE_2D, PIPE_BIND_DEPTH_STENCIL, 0)) {
+ formats[count++] = fmt[i];
+ break;
+ }
+ }
+
+ fmt += n;
+ }
- if (gsurf)
- gsurf->native->flush_frontbuffer(gsurf->native);
+ return count;
}
/**
- * Re-validate the context.
+ * Add configs to display and return the next config ID.
*/
+static EGLint
+egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ const struct native_config **native_configs;
+ enum pipe_format depth_stencil_formats[8];
+ int num_formats, num_configs, i, j;
+
+ native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
+ if (!num_configs) {
+ if (native_configs)
+ FREE(native_configs);
+ return id;
+ }
+
+ num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
+ depth_stencil_formats);
+
+ for (i = 0; i < num_configs; i++) {
+ for (j = 0; j < num_formats; j++) {
+ struct egl_g3d_config *gconf;
+
+ gconf = CALLOC_STRUCT(egl_g3d_config);
+ if (gconf) {
+ _eglInitConfig(&gconf->base, dpy, id);
+ if (!egl_g3d_init_config(drv, dpy, &gconf->base,
+ native_configs[i], depth_stencil_formats[j])) {
+ FREE(gconf);
+ break;
+ }
+
+ _eglAddConfig(dpy, &gconf->base);
+ id++;
+ }
+ }
+ }
+
+ FREE(native_configs);
+ return id;
+}
+
static void
-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
+egl_g3d_invalid_surface(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num)
{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
+ /* XXX not thread safe? */
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+ struct egl_g3d_context *gctx;
+
+ /*
+ * Some functions such as egl_g3d_copy_buffers create a temporary native
+ * surface. There is no gsurf associated with it.
+ */
+ gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
+ if (gctx)
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
}
+static struct native_event_handler egl_g3d_native_event_handler = {
+ .invalid_surface = egl_g3d_invalid_surface
+};
+
static EGLBoolean
egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
@@ -540,19 +438,25 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
_eglCleanupDisplay(dpy);
+ if (gdpy->pipe)
+ gdpy->pipe->destroy(gdpy->pipe);
+
if (dpy->Screens) {
for (i = 0; i < dpy->NumScreens; i++) {
struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
- free(gscr->native_modes);
- free(gscr);
+ FREE(gscr->native_modes);
+ FREE(gscr);
}
- free(dpy->Screens);
+ FREE(dpy->Screens);
}
+ if (gdpy->smapi)
+ egl_g3d_destroy_st_manager(gdpy->smapi);
+
if (gdpy->native)
gdpy->native->destroy(gdpy->native);
- free(gdpy);
+ FREE(gdpy);
dpy->DriverData = NULL;
return EGL_TRUE;
@@ -575,18 +479,25 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
dpy->DriverData = gdpy;
- gdpy->native = native_create_display(dpy->NativeDisplay);
+ gdpy->native = native_create_display(dpy->NativeDisplay,
+ &egl_g3d_native_event_handler);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
- gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
+ gdpy->native->user_data = (void *) dpy;
egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;
+ gdpy->smapi = egl_g3d_create_st_manager(dpy);
+ if (!gdpy->smapi) {
+ _eglError(EGL_NOT_INITIALIZED,
+ "eglInitialize(failed to create st manager)");
+ goto fail;
+ }
+
#ifdef EGL_MESA_screen_surface
/* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
@@ -595,6 +506,10 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
#endif
+ dpy->Extensions.KHR_image_base = EGL_TRUE;
+ if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
+ dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+
if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
goto fail;
@@ -611,448 +526,6 @@ fail:
return EGL_FALSE;
}
-static _EGLContext *
-egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- _EGLContext *share, const EGLint *attribs)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_context *gshare = egl_g3d_context(share);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- struct egl_g3d_context *gctx;
- const __GLcontextModes *mode;
-
- gctx = CALLOC_STRUCT(egl_g3d_context);
- if (!gctx) {
- _eglError(EGL_BAD_ALLOC, "eglCreateContext");
- return NULL;
- }
-
- if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
- free(gctx);
- return NULL;
- }
-
- gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
- if (!gctx->stapi) {
- free(gctx);
- return NULL;
- }
-
- mode = &gconf->native->mode;
-
- gctx->pipe = gdpy->native->screen->context_create(
- gdpy->native->screen,
- (void *) &gctx->base);
-
- if (!gctx->pipe) {
- free(gctx);
- return NULL;
- }
-
- gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode,
- (gshare) ? gshare->st_ctx : NULL);
- if (!gctx->st_ctx) {
- gctx->pipe->destroy(gctx->pipe);
- free(gctx);
- return NULL;
- }
-
- return &gctx->base;
-}
-
-/**
- * Destroy a context.
- */
-static void
-destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
-
- /* FIXME a context might live longer than its display */
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
-
- egl_g3d_realloc_context(dpy, &gctx->base);
- /* it will destroy the associated pipe context */
- gctx->stapi->st_destroy_context(gctx->st_ctx);
-
- free(gctx);
-}
-
-static EGLBoolean
-egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- if (!_eglIsContextBound(ctx))
- destroy_context(dpy, ctx);
- return EGL_TRUE;
-}
-
-struct egl_g3d_create_surface_arg {
- EGLint type;
- union {
- EGLNativeWindowType win;
- EGLNativePixmapType pix;
- } u;
-};
-
-static _EGLSurface *
-egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- struct egl_g3d_create_surface_arg *arg,
- const EGLint *attribs)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- struct egl_g3d_surface *gsurf;
- struct native_surface *nsurf;
- const char *err;
-
- switch (arg->type) {
- case EGL_WINDOW_BIT:
- err = "eglCreateWindowSurface";
- break;
- case EGL_PIXMAP_BIT:
- err = "eglCreatePixmapSurface";
- break;
- case EGL_PBUFFER_BIT:
- err = "eglCreatePBufferSurface";
- break;
-#ifdef EGL_MESA_screen_surface
- case EGL_SCREEN_BIT_MESA:
- err = "eglCreateScreenSurface";
- break;
-#endif
- default:
- err = "eglCreateUnknownSurface";
- break;
- }
-
- gsurf = CALLOC_STRUCT(egl_g3d_surface);
- if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, err);
- return NULL;
- }
-
- if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
- free(gsurf);
- return NULL;
- }
-
- /* create the native surface */
- switch (arg->type) {
- case EGL_WINDOW_BIT:
- nsurf = gdpy->native->create_window_surface(gdpy->native,
- arg->u.win, gconf->native);
- break;
- case EGL_PIXMAP_BIT:
- nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
- arg->u.pix, gconf->native);
- break;
- case EGL_PBUFFER_BIT:
- nsurf = gdpy->native->create_pbuffer_surface(gdpy->native,
- gconf->native, gsurf->base.Width, gsurf->base.Height);
- break;
-#ifdef EGL_MESA_screen_surface
- case EGL_SCREEN_BIT_MESA:
- /* prefer back buffer (move to _eglInitSurface?) */
- gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
- nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
- gconf->native, gsurf->base.Width, gsurf->base.Height);
- break;
-#endif
- default:
- nsurf = NULL;
- break;
- }
-
- if (!nsurf) {
- free(gsurf);
- return NULL;
- }
- /* initialize the geometry */
- if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
- &gsurf->base.Width, &gsurf->base.Height)) {
- nsurf->destroy(nsurf);
- free(gsurf);
- return NULL;
- }
-
- gsurf->native = nsurf;
-
- gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
- if (!gconf->native->mode.doubleBufferMode)
- gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
-
- return &gsurf->base;
-}
-
-static _EGLSurface *
-egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, EGLNativeWindowType win,
- const EGLint *attribs)
-{
- struct egl_g3d_create_surface_arg arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = EGL_WINDOW_BIT;
- arg.u.win = win;
-
- return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
-}
-
-static _EGLSurface *
-egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, EGLNativePixmapType pix,
- const EGLint *attribs)
-{
- struct egl_g3d_create_surface_arg arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = EGL_PIXMAP_BIT;
- arg.u.pix = pix;
-
- 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)
-{
- struct egl_g3d_create_surface_arg arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = EGL_PBUFFER_BIT;
-
- return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
-}
-
-/**
- * Destroy a surface.
- */
-static void
-destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
-{
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
-
- /* FIXME a surface might live longer than its display */
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
-
- pipe_surface_reference(&gsurf->render_surface, NULL);
- gsurf->native->destroy(gsurf->native);
- free(gsurf);
-}
-
-static EGLBoolean
-egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
-{
- if (!_eglIsSurfaceBound(surf))
- destroy_surface(dpy, surf);
- return EGL_TRUE;
-}
-
-static EGLBoolean
-egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
- struct egl_g3d_context *old_gctx;
- EGLBoolean ok = EGL_TRUE;
-
- /* bind the new context and return the "orphaned" one */
- if (!_eglBindContext(&ctx, &draw, &read))
- return EGL_FALSE;
- old_gctx = egl_g3d_context(ctx);
-
- if (old_gctx) {
- /* flush old context */
- old_gctx->stapi->st_flush(old_gctx->st_ctx,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
-
- /*
- * The old context is no longer current, and egl_g3d_realloc_context()
- * should be called to destroy the framebuffers. However, it is possible
- * that it will be made current again with the same draw/read surfaces.
- * It might be better to keep it around.
- */
- }
-
- if (gctx) {
- ok = egl_g3d_realloc_context(dpy, &gctx->base);
- if (ok) {
- ok = gctx->stapi->st_make_current(gctx->st_ctx,
- gctx->draw.st_fb, gctx->read.st_fb);
- if (ok) {
- egl_g3d_validate_context(dpy, &gctx->base);
- if (gdraw->base.Type == EGL_WINDOW_BIT) {
- gctx->base.WindowRenderBuffer =
- (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ?
- EGL_SINGLE_BUFFER : EGL_BACK_BUFFER;
- }
- }
- }
- }
- else if (old_gctx) {
- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
- old_gctx->base.WindowRenderBuffer = EGL_NONE;
- }
-
- if (ctx && !_eglIsContextLinked(ctx))
- destroy_context(dpy, ctx);
- if (draw && !_eglIsSurfaceLinked(draw))
- destroy_surface(dpy, draw);
- if (read && read != draw && !_eglIsSurfaceLinked(read))
- destroy_surface(dpy, read);
-
- return ok;
-}
-
-static EGLBoolean
-egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
-{
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- _EGLContext *ctx = _eglGetCurrentContext();
- struct egl_g3d_context *gctx = NULL;
-
- /* no-op for pixmap or pbuffer surface */
- if (gsurf->base.Type == EGL_PIXMAP_BIT ||
- gsurf->base.Type == EGL_PBUFFER_BIT)
- return EGL_TRUE;
-
- /* or when the surface is single-buffered */
- if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
- return EGL_TRUE;
-
- if (ctx && ctx->DrawSurface == surf)
- gctx = egl_g3d_context(ctx);
-
- /* flush if the surface is current */
- if (gctx)
- gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
-
- return gsurf->native->swap_buffers(gsurf->native);
-}
-
-/**
- * Find a config that supports the pixmap.
- */
-static _EGLConfig *
-find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf;
- EGLint i;
-
- for (i = 0; i < dpy->NumConfigs; i++) {
- gconf = egl_g3d_config(dpy->Configs[i]);
- if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
- break;
- }
-
- return (i < dpy->NumConfigs) ? &gconf->base : NULL;
-}
-
-/**
- * Get the pipe surface of the given attachment of the native surface.
- */
-static struct pipe_surface *
-get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
- enum native_attachment natt)
-{
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
- struct pipe_surface *psurf;
-
- textures[natt] = NULL;
- nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
- if (!textures[natt])
- return NULL;
-
- psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
- pipe_texture_reference(&textures[natt], NULL);
-
- return psurf;
-}
-
-static EGLBoolean
-egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLNativePixmapType target)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- _EGLContext *ctx = _eglGetCurrentContext();
- struct egl_g3d_config *gconf;
- struct native_surface *nsurf;
- struct pipe_screen *screen = gdpy->native->screen;
- struct pipe_surface *psurf;
-
- if (!gsurf->render_surface)
- return EGL_TRUE;
-
- gconf = egl_g3d_config(find_pixmap_config(dpy, target));
- if (!gconf)
- return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
-
- nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
- target, gconf->native);
- if (!nsurf)
- return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
-
- /* flush if the surface is current */
- if (ctx && ctx->DrawSurface == &gsurf->base) {
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_flush(gctx->st_ctx,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
- }
-
- psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
- if (psurf) {
- struct pipe_context pipe;
-
- /**
- * XXX This is hacky. If we might allow the EGLDisplay to create a pipe
- * context of its own and use the blitter context for this.
- */
- memset(&pipe, 0, sizeof(pipe));
- pipe.screen = screen;
-
- util_surface_copy(&pipe, FALSE, psurf, 0, 0,
- gsurf->render_surface, 0, 0, psurf->width, psurf->height);
-
- pipe_surface_reference(&psurf, NULL);
- nsurf->flush_frontbuffer(nsurf);
- }
-
- nsurf->destroy(nsurf);
-
- return EGL_TRUE;
-}
-
-static EGLBoolean
-egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
- gctx->stapi->st_finish(gctx->st_ctx);
- return EGL_TRUE;
-}
-
-static EGLBoolean
-egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
-{
- _EGLContext *ctx = _eglGetCurrentContext();
-
- if (engine != EGL_CORE_NATIVE_ENGINE)
- return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
-
- if (ctx && ctx->DrawSurface) {
- struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
- gsurf->native->wait(gsurf->native);
- }
-
- return EGL_TRUE;
-}
-
static _EGLProc
egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
{
@@ -1063,10 +536,10 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
/* in case this is called before a display is initialized */
egl_g3d_init_st(&gdrv->base);
- for (i = 0; i < NUM_EGL_G3D_STS; i++) {
- const struct egl_g3d_st *stapi = gdrv->stapis[i];
+ for (i = 0; i < ST_API_COUNT; i++) {
+ struct st_api *stapi = gdrv->stapis[i];
if (stapi) {
- proc = (_EGLProc) stapi->st_get_proc_address(procname);
+ proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
if (proc)
return proc;
}
@@ -1075,161 +548,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
return (_EGLProc) NULL;
}
-static EGLBoolean
-egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLSurface *surf, EGLint buffer)
-{
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
- struct egl_g3d_context *gctx;
- enum pipe_format target_format;
- int target;
-
- if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
- return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
- if (buffer != EGL_BACK_BUFFER)
- return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
- if (gsurf->base.BoundToTexture)
- return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
-
- switch (gsurf->base.TextureFormat) {
- case EGL_TEXTURE_RGB:
- target_format = PIPE_FORMAT_R8G8B8_UNORM;
- break;
- case EGL_TEXTURE_RGBA:
- target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- break;
- default:
- return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- }
-
- switch (gsurf->base.TextureTarget) {
- case EGL_TEXTURE_2D:
- target = ST_TEXTURE_2D;
- break;
- default:
- return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
- }
-
- if (!es1)
- return EGL_TRUE;
- if (!gsurf->render_surface)
- return EGL_FALSE;
-
- /* flush properly if the surface is bound */
- if (gsurf->base.CurrentContext) {
- gctx = egl_g3d_context(gsurf->base.CurrentContext);
- gctx->stapi->st_flush(gctx->st_ctx,
- PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
- }
-
- gctx = egl_g3d_context(es1);
- gctx->stapi->st_bind_texture_surface(gsurf->render_surface,
- target, gsurf->base.MipmapLevel, target_format);
-
- gsurf->base.BoundToTexture = EGL_TRUE;
-
- return EGL_TRUE;
-}
-
-static EGLBoolean
-egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLSurface *surf, EGLint buffer)
-{
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
-
- if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
- !gsurf->base.BoundToTexture)
- return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
- if (buffer != EGL_BACK_BUFFER)
- return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
-
- if (gsurf->render_surface) {
- _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
- struct egl_g3d_context *gctx = egl_g3d_context(ctx);
-
- /* what if the context the surface binds to is no longer current? */
- if (gctx)
- gctx->stapi->st_unbind_texture_surface(gsurf->render_surface,
- ST_TEXTURE_2D, gsurf->base.MipmapLevel);
- }
-
- gsurf->base.BoundToTexture = EGL_FALSE;
-
- return EGL_TRUE;
-}
-
-#ifdef EGL_MESA_screen_surface
-
-static _EGLSurface *
-egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, const EGLint *attribs)
-{
- struct egl_g3d_create_surface_arg arg;
-
- memset(&arg, 0, sizeof(arg));
- arg.type = EGL_SCREEN_BIT_MESA;
-
- return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
-}
-
-static EGLBoolean
-egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLScreen *scr, _EGLSurface *surf,
- _EGLMode *mode)
-{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct native_surface *nsurf;
- const struct native_mode *nmode;
- EGLBoolean changed;
-
- if (gsurf) {
- EGLint idx;
-
- if (!mode)
- return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
- if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
- return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
- if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
- return _eglError(EGL_BAD_MATCH,
- "eglShowSurfaceMESA(surface smaller than mode size)");
-
- /* find the index of the mode */
- for (idx = 0; idx < gscr->base.NumModes; idx++)
- if (mode == &gscr->base.Modes[idx])
- break;
- if (idx >= gscr->base.NumModes) {
- return _eglError(EGL_BAD_MODE_MESA,
- "eglShowSurfaceMESA(unknown mode)");
- }
-
- nsurf = gsurf->native;
- nmode = gscr->native_modes[idx];
- }
- else {
- if (mode)
- return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
-
- /* disable the screen */
- nsurf = NULL;
- nmode = NULL;
- }
-
- /* TODO surface panning by CRTC choosing */
- changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
- gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
- if (changed) {
- gscr->base.CurrentSurface = &gsurf->base;
- gscr->base.CurrentMode = mode;
- }
-
- return changed;
-}
-
-#endif /* EGL_MESA_screen_surface */
-
static EGLint
egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
{
@@ -1263,9 +581,15 @@ static void
egl_g3d_unload(_EGLDriver *drv)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ EGLint i;
+
+ for (i = 0; i < ST_API_COUNT; i++) {
+ if (gdrv->stapis[i])
+ gdrv->stapis[i]->destroy(gdrv->stapis[i]);
+ }
egl_g3d_destroy_probe(drv, NULL);
- free(gdrv);
+ FREE(gdrv);
}
_EGLDriver *
@@ -1274,38 +598,18 @@ _eglMain(const char *args)
static char driver_name[64];
struct egl_g3d_driver *gdrv;
- snprintf(driver_name, sizeof(driver_name),
+ util_snprintf(driver_name, sizeof(driver_name),
"Gallium/%s", native_get_name());
gdrv = CALLOC_STRUCT(egl_g3d_driver);
if (!gdrv)
return NULL;
- _eglInitDriverFallbacks(&gdrv->base);
-
+ egl_g3d_init_driver_api(&gdrv->base);
gdrv->base.API.Initialize = egl_g3d_initialize;
gdrv->base.API.Terminate = egl_g3d_terminate;
- gdrv->base.API.CreateContext = egl_g3d_create_context;
- gdrv->base.API.DestroyContext = egl_g3d_destroy_context;
- gdrv->base.API.CreateWindowSurface = egl_g3d_create_window_surface;
- gdrv->base.API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
- gdrv->base.API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
- gdrv->base.API.DestroySurface = egl_g3d_destroy_surface;
- gdrv->base.API.MakeCurrent = egl_g3d_make_current;
- gdrv->base.API.SwapBuffers = egl_g3d_swap_buffers;
- gdrv->base.API.CopyBuffers = egl_g3d_copy_buffers;
- gdrv->base.API.WaitClient = egl_g3d_wait_client;
- gdrv->base.API.WaitNative = egl_g3d_wait_native;
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
- gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image;
- gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image;
-
-#ifdef EGL_MESA_screen_surface
- gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
- gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
-#endif
-
gdrv->base.Name = driver_name;
gdrv->base.Probe = egl_g3d_probe;
gdrv->base.Unload = egl_g3d_unload;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 5d2d9c481ab..5a3c80b9689 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -14,12 +14,13 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#ifndef _EGL_G3D_H_
@@ -34,15 +35,16 @@
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
+#include "eglimage.h"
#include "eglscreen.h"
#include "eglmode.h"
#include "native.h"
-#include "egl_st.h"
+#include "egl_g3d_st.h"
struct egl_g3d_driver {
_EGLDriver base;
- const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS];
+ struct st_api *stapis[ST_API_COUNT];
EGLint api_mask;
EGLint probe_key;
@@ -50,35 +52,44 @@ struct egl_g3d_driver {
struct egl_g3d_display {
struct native_display *native;
-};
-struct egl_g3d_buffer {
- struct st_framebuffer *st_fb;
- uint attachment_mask;
+ struct st_manager *smapi;
+ struct pipe_context *pipe;
};
struct egl_g3d_context {
_EGLContext base;
- const struct egl_g3d_st *stapi;
- struct pipe_context *pipe;
+ struct st_api *stapi;
- struct st_context *st_ctx;
- EGLBoolean force_validate;
- struct egl_g3d_buffer draw, read;
+ struct st_context_iface *stctxi;
};
struct egl_g3d_surface {
_EGLSurface base;
+
+ struct st_visual stvis;
+ struct st_framebuffer_iface *stfbi;
+
+ /* the native surface; NULL for pbuffers */
struct native_surface *native;
- enum native_attachment render_att;
- struct pipe_surface *render_surface;
+ struct pipe_resource *render_texture;
+
unsigned int sequence_number;
};
struct egl_g3d_config {
_EGLConfig base;
const struct native_config *native;
+ struct st_visual stvis;
+};
+
+struct egl_g3d_image {
+ _EGLImage base;
+ struct pipe_resource *texture;
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
};
struct egl_g3d_screen {
@@ -90,5 +101,6 @@ struct egl_g3d_screen {
/* standard typecasts */
_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
_EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
+_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
new file mode 100644
index 00000000000..478516453ce
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -0,0 +1,731 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ *
+ * 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.
+ */
+
+#include "egldriver.h"
+#include "eglcurrent.h"
+#include "egllog.h"
+
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_api.h"
+#include "egl_g3d_image.h"
+#include "egl_g3d_st.h"
+#include "native.h"
+
+/**
+ * Return the state tracker for the given context.
+ */
+static struct st_api *
+egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct st_api *stapi;
+ EGLint idx = -1;
+
+ switch (ctx->ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ switch (ctx->ClientVersion) {
+ case 1:
+ idx = ST_API_OPENGL_ES1;
+ break;
+ case 2:
+ idx = ST_API_OPENGL_ES2;
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "unknown client version %d",
+ ctx->ClientVersion);
+ break;
+ }
+ break;
+ case EGL_OPENVG_API:
+ idx = ST_API_OPENVG;
+ break;
+ case EGL_OPENGL_API:
+ idx = ST_API_OPENGL;
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
+ break;
+ }
+
+ stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
+ return stapi;
+}
+
+static _EGLContext *
+egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share, const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_context *gshare = egl_g3d_context(share);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_context *gctx;
+
+ gctx = CALLOC_STRUCT(egl_g3d_context);
+ if (!gctx) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+ return NULL;
+ }
+
+ if (!_eglInitContext(&gctx->base, dpy, conf, attribs)) {
+ FREE(gctx);
+ return NULL;
+ }
+
+ gctx->stapi = egl_g3d_choose_st(drv, &gctx->base);
+ if (!gctx->stapi) {
+ FREE(gctx);
+ return NULL;
+ }
+
+ gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
+ &gconf->stvis, (gshare) ? gshare->stctxi : NULL);
+ if (!gctx->stctxi) {
+ FREE(gctx);
+ return NULL;
+ }
+
+ gctx->stctxi->st_manager_private = (void *) &gctx->base;
+
+ return &gctx->base;
+}
+
+/**
+ * Destroy a context.
+ */
+static void
+destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* FIXME a context might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
+
+ gctx->stctxi->destroy(gctx->stctxi);
+
+ FREE(gctx);
+}
+
+static EGLBoolean
+egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ if (!_eglIsContextBound(ctx))
+ destroy_context(dpy, ctx);
+ return EGL_TRUE;
+}
+
+struct egl_g3d_create_surface_arg {
+ EGLint type;
+ union {
+ EGLNativeWindowType win;
+ EGLNativePixmapType pix;
+ } u;
+};
+
+static _EGLSurface *
+egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ struct egl_g3d_create_surface_arg *arg,
+ const EGLint *attribs)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+ struct native_surface *nsurf;
+ const char *err;
+
+ switch (arg->type) {
+ case EGL_WINDOW_BIT:
+ err = "eglCreateWindowSurface";
+ break;
+ case EGL_PIXMAP_BIT:
+ err = "eglCreatePixmapSurface";
+ break;
+#ifdef EGL_MESA_screen_surface
+ case EGL_SCREEN_BIT_MESA:
+ err = "eglCreateScreenSurface";
+ break;
+#endif
+ default:
+ err = "eglCreateUnknownSurface";
+ break;
+ }
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, err);
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
+ FREE(gsurf);
+ return NULL;
+ }
+
+ /* create the native surface */
+ switch (arg->type) {
+ case EGL_WINDOW_BIT:
+ nsurf = gdpy->native->create_window_surface(gdpy->native,
+ arg->u.win, gconf->native);
+ break;
+ case EGL_PIXMAP_BIT:
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ arg->u.pix, gconf->native);
+ break;
+#ifdef EGL_MESA_screen_surface
+ case EGL_SCREEN_BIT_MESA:
+ /* prefer back buffer (move to _eglInitSurface?) */
+ gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
+ nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
+ gconf->native, gsurf->base.Width, gsurf->base.Height);
+ break;
+#endif
+ default:
+ nsurf = NULL;
+ break;
+ }
+
+ if (!nsurf) {
+ FREE(gsurf);
+ return NULL;
+ }
+ /* initialize the geometry */
+ if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
+ &gsurf->base.Width, &gsurf->base.Height)) {
+ nsurf->destroy(nsurf);
+ FREE(gsurf);
+ return NULL;
+ }
+
+ gsurf->stvis = gconf->stvis;
+ if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER)
+ gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT;
+
+ gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
+ if (!gsurf->stfbi) {
+ nsurf->destroy(nsurf);
+ FREE(gsurf);
+ return NULL;
+ }
+
+ nsurf->user_data = &gsurf->base;
+ gsurf->native = nsurf;
+
+ return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativeWindowType win,
+ const EGLint *attribs)
+{
+ struct egl_g3d_create_surface_arg arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_WINDOW_BIT;
+ arg.u.win = win;
+
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
+}
+
+static _EGLSurface *
+egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativePixmapType pix,
+ const EGLint *attribs)
+{
+ struct egl_g3d_create_surface_arg arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_PIXMAP_BIT;
+ arg.u.pix = pix;
+
+ 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)
+{
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ struct egl_g3d_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(egl_g3d_surface);
+ if (!gsurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
+ FREE(gsurf);
+ return NULL;
+ }
+
+ gsurf->stvis = gconf->stvis;
+
+ gsurf->stfbi = egl_g3d_create_st_framebuffer(&gsurf->base);
+ if (!gsurf->stfbi) {
+ FREE(gsurf);
+ return NULL;
+ }
+
+ return &gsurf->base;
+}
+
+/**
+ * Destroy a surface.
+ */
+static void
+destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ /* FIXME a surface might live longer than its display */
+ if (!dpy->Initialized)
+ _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
+
+ pipe_resource_reference(&gsurf->render_texture, NULL);
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+ if (gsurf->native)
+ gsurf->native->destroy(gsurf->native);
+ FREE(gsurf);
+}
+
+static EGLBoolean
+egl_g3d_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ if (!_eglIsSurfaceBound(surf))
+ destroy_surface(dpy, surf);
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
+{
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct egl_g3d_surface *gdraw = egl_g3d_surface(draw);
+ struct egl_g3d_surface *gread = egl_g3d_surface(read);
+ struct egl_g3d_context *old_gctx;
+ EGLBoolean ok = EGL_TRUE;
+
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &draw, &read))
+ return EGL_FALSE;
+ old_gctx = egl_g3d_context(ctx);
+
+ if (old_gctx) {
+ /* flush old context */
+ old_gctx->stctxi->flush(old_gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ if (gctx) {
+ 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) {
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi,
+ gread->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;
+ }
+ }
+ }
+ else if (old_gctx) {
+ ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
+ old_gctx->base.WindowRenderBuffer = EGL_NONE;
+ }
+
+ if (ctx && !_eglIsContextLinked(ctx))
+ destroy_context(dpy, ctx);
+ if (draw && !_eglIsSurfaceLinked(draw))
+ destroy_surface(dpy, draw);
+ if (read && read != draw && !_eglIsSurfaceLinked(read))
+ destroy_surface(dpy, read);
+
+ return ok;
+}
+
+static EGLBoolean
+egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_context *gctx = NULL;
+
+ /* no-op for pixmap or pbuffer surface */
+ if (gsurf->base.Type == EGL_PIXMAP_BIT ||
+ gsurf->base.Type == EGL_PBUFFER_BIT)
+ return EGL_TRUE;
+
+ /* or when the surface is single-buffered */
+ if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT)
+ return EGL_TRUE;
+
+ if (ctx && ctx->DrawSurface == surf)
+ gctx = egl_g3d_context(ctx);
+
+ /* flush if the surface is current */
+ if (gctx) {
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ return gsurf->native->swap_buffers(gsurf->native);
+}
+
+/**
+ * Get the pipe surface of the given attachment of the native surface.
+ */
+static struct pipe_surface *
+get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
+ enum native_attachment natt,
+ unsigned bind)
+{
+ struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_surface *psurf;
+
+ textures[natt] = NULL;
+ nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL);
+ if (!textures[natt])
+ return NULL;
+
+ psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
+ 0, 0, 0, bind);
+ pipe_resource_reference(&textures[natt], NULL);
+
+ return psurf;
+}
+
+static EGLBoolean
+egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+ EGLNativePixmapType target)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *ctx = _eglGetCurrentContext();
+ struct egl_g3d_config *gconf;
+ struct native_surface *nsurf;
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_surface *psurf;
+
+ if (!gsurf->render_texture)
+ return EGL_TRUE;
+
+ gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
+ if (!gconf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ target, gconf->native);
+ if (!nsurf)
+ return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
+
+ /* flush if the surface is current */
+ if (ctx && ctx->DrawSurface == &gsurf->base) {
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ /* create a pipe context to copy surfaces */
+ if (!gdpy->pipe) {
+ gdpy->pipe =
+ gdpy->native->screen->context_create(gdpy->native->screen, NULL);
+ if (!gdpy->pipe)
+ return EGL_FALSE;
+ }
+
+ psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT,
+ PIPE_BIND_BLIT_DESTINATION);
+ if (psurf) {
+ struct pipe_surface *psrc;
+
+ psrc = screen->get_tex_surface(screen, gsurf->render_texture,
+ 0, 0, 0, PIPE_BIND_BLIT_SOURCE);
+ if (psrc) {
+ gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0,
+ psrc, 0, 0, psurf->width, psurf->height);
+ pipe_surface_reference(&psrc, NULL);
+
+ nsurf->flush_frontbuffer(nsurf);
+ }
+
+ pipe_surface_reference(&psurf, NULL);
+ }
+
+ nsurf->destroy(nsurf);
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ screen->fence_finish(screen, fence, 0);
+ screen->fence_reference(screen, &fence, NULL);
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
+{
+ _EGLContext *ctx = _eglGetCurrentContext();
+
+ if (engine != EGL_CORE_NATIVE_ENGINE)
+ return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
+
+ if (ctx && ctx->DrawSurface) {
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(ctx->DrawSurface);
+
+ if (gsurf->native)
+ gsurf->native->wait(gsurf->native);
+ }
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint buffer)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx;
+ enum pipe_format internal_format;
+ enum st_texture_type target;
+
+ if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
+ return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ if (gsurf->base.BoundToTexture)
+ return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+ switch (gsurf->base.TextureFormat) {
+ case EGL_TEXTURE_RGB:
+ internal_format = PIPE_FORMAT_R8G8B8_UNORM;
+ break;
+ case EGL_TEXTURE_RGBA:
+ internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ switch (gsurf->base.TextureTarget) {
+ case EGL_TEXTURE_2D:
+ target = ST_TEXTURE_2D;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ if (!es1)
+ return EGL_TRUE;
+ if (!gsurf->render_texture)
+ return EGL_FALSE;
+
+ /* flush properly if the surface is bound */
+ if (gsurf->base.CurrentContext) {
+ gctx = egl_g3d_context(gsurf->base.CurrentContext);
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
+
+ gctx = egl_g3d_context(es1);
+ if (gctx->stctxi->teximage) {
+ if (!gctx->stctxi->teximage(gctx->stctxi, target,
+ gsurf->base.MipmapLevel, internal_format,
+ gsurf->render_texture, gsurf->base.MipmapTexture))
+ return EGL_FALSE;
+ gsurf->base.BoundToTexture = EGL_TRUE;
+ }
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surf, EGLint buffer)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT ||
+ !gsurf->base.BoundToTexture)
+ return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+ if (gsurf->render_texture) {
+ _EGLContext *ctx = _eglGetAPIContext(EGL_OPENGL_ES_API);
+ struct egl_g3d_context *gctx = egl_g3d_context(ctx);
+
+ /* what if the context the surface binds to is no longer current? */
+ if (gctx) {
+ gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
+ gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
+ }
+ }
+
+ gsurf->base.BoundToTexture = EGL_FALSE;
+
+ return EGL_TRUE;
+}
+
+#ifdef EGL_MESA_screen_surface
+
+static _EGLSurface *
+egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const EGLint *attribs)
+{
+ struct egl_g3d_create_surface_arg arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_SCREEN_BIT_MESA;
+
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
+}
+
+static EGLBoolean
+egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scr, _EGLSurface *surf,
+ _EGLMode *mode)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_screen *gscr = egl_g3d_screen(scr);
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct native_surface *nsurf;
+ const struct native_mode *nmode;
+ EGLBoolean changed;
+
+ if (gsurf) {
+ EGLint idx;
+
+ if (!mode)
+ return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+ if (gsurf->base.Type != EGL_SCREEN_BIT_MESA)
+ return _eglError(EGL_BAD_SURFACE, "eglShowScreenSurfaceMESA");
+ if (gsurf->base.Width < mode->Width || gsurf->base.Height < mode->Height)
+ return _eglError(EGL_BAD_MATCH,
+ "eglShowSurfaceMESA(surface smaller than mode size)");
+
+ /* find the index of the mode */
+ for (idx = 0; idx < gscr->base.NumModes; idx++)
+ if (mode == &gscr->base.Modes[idx])
+ break;
+ if (idx >= gscr->base.NumModes) {
+ return _eglError(EGL_BAD_MODE_MESA,
+ "eglShowSurfaceMESA(unknown mode)");
+ }
+
+ nsurf = gsurf->native;
+ nmode = gscr->native_modes[idx];
+ }
+ else {
+ if (mode)
+ return _eglError(EGL_BAD_MATCH, "eglShowSurfaceMESA");
+
+ /* disable the screen */
+ nsurf = NULL;
+ nmode = NULL;
+ }
+
+ /* TODO surface panning by CRTC choosing */
+ changed = gdpy->native->modeset->program(gdpy->native, 0, nsurf,
+ gscr->base.OriginX, gscr->base.OriginY, &gscr->native, 1, nmode);
+ if (changed) {
+ gscr->base.CurrentSurface = &gsurf->base;
+ gscr->base.CurrentMode = mode;
+ }
+
+ return changed;
+}
+
+#endif /* EGL_MESA_screen_surface */
+
+/**
+ * Find a config that supports the pixmap.
+ */
+_EGLConfig *
+egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf;
+ EGLint i;
+
+ for (i = 0; i < dpy->NumConfigs; i++) {
+ gconf = egl_g3d_config(dpy->Configs[i]);
+ if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
+ break;
+ }
+
+ return (i < dpy->NumConfigs) ? &gconf->base : NULL;
+}
+
+void
+egl_g3d_init_driver_api(_EGLDriver *drv)
+{
+ _eglInitDriverFallbacks(drv);
+
+ drv->API.CreateContext = egl_g3d_create_context;
+ drv->API.DestroyContext = egl_g3d_destroy_context;
+ 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.DestroySurface = egl_g3d_destroy_surface;
+ drv->API.MakeCurrent = egl_g3d_make_current;
+ drv->API.SwapBuffers = egl_g3d_swap_buffers;
+ drv->API.CopyBuffers = egl_g3d_copy_buffers;
+ drv->API.WaitClient = egl_g3d_wait_client;
+ drv->API.WaitNative = egl_g3d_wait_native;
+
+ drv->API.BindTexImage = egl_g3d_bind_tex_image;
+ drv->API.ReleaseTexImage = egl_g3d_release_tex_image;
+
+ drv->API.CreateImageKHR = egl_g3d_create_image;
+ drv->API.DestroyImageKHR = egl_g3d_destroy_image;
+
+#ifdef EGL_MESA_screen_surface
+ drv->API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
+ drv->API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
+#endif
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.h b/src/gallium/state_trackers/egl/common/egl_g3d_api.h
new file mode 100644
index 00000000000..d5196c12fe9
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.h
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef _EGL_G3D_API_H_
+#define _EGL_G3D_API_H_
+
+#include "egl_g3d.h"
+
+void
+egl_g3d_init_driver_api(_EGLDriver *drv);
+
+_EGLConfig *
+egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix);
+
+#endif /* _EGL_G3D_API_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
new file mode 100644
index 00000000000..b1fe30a776c
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -0,0 +1,136 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * 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 <[email protected]>
+ */
+
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "eglcurrent.h"
+
+#include "native.h"
+#include "egl_g3d.h"
+#include "egl_g3d_api.h"
+#include "egl_g3d_image.h"
+
+/**
+ * Reference and return the front left buffer of the native pixmap.
+ */
+static struct pipe_resource *
+egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf;
+ struct native_surface *nsurf;
+ struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
+ enum native_attachment natt;
+
+ gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, pix));
+ if (!gconf)
+ return NULL;
+
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ pix, gconf->native);
+ if (!nsurf)
+ return NULL;
+
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ if (!nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL))
+ textures[natt] = NULL;
+
+ nsurf->destroy(nsurf);
+
+ return textures[natt];
+}
+
+_EGLImage *
+egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
+ EGLenum target, EGLClientBuffer buffer,
+ const EGLint *attribs)
+{
+ struct pipe_resource *ptex;
+ struct egl_g3d_image *gimg;
+ unsigned face = 0, level = 0, zslice = 0;
+
+ gimg = CALLOC_STRUCT(egl_g3d_image);
+ if (!gimg) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&gimg->base, dpy, attribs)) {
+ FREE(gimg);
+ return NULL;
+ }
+
+ switch (target) {
+ case EGL_NATIVE_PIXMAP_KHR:
+ ptex = egl_g3d_reference_native_pixmap(dpy,
+ (EGLNativePixmapType) buffer);
+ break;
+ default:
+ ptex = NULL;
+ break;
+ }
+
+ if (!ptex) {
+ FREE(gimg);
+ return NULL;
+ }
+
+ if (level > ptex->last_level) {
+ _eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR");
+ pipe_resource_reference(&gimg->texture, NULL);
+ FREE(gimg);
+ return NULL;
+ }
+ if (zslice > ptex->depth0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ pipe_resource_reference(&gimg->texture, NULL);
+ FREE(gimg);
+ return NULL;
+ }
+
+ /* transfer the ownership to the image */
+ gimg->texture = ptex;
+ gimg->face = face;
+ gimg->level = level;
+ gimg->zslice = zslice;
+
+ return &gimg->base;
+}
+
+EGLBoolean
+egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
+{
+ struct egl_g3d_image *gimg = egl_g3d_image(img);
+
+ pipe_resource_reference(&gimg->texture, NULL);
+ FREE(gimg);
+
+ 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
new file mode 100644
index 00000000000..adda9333715
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
@@ -0,0 +1,42 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * 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 <[email protected]>
+ */
+
+#ifndef _EGL_G3D_IMAGE_H_
+#define _EGL_G3D_IMAGE_H_
+
+#include "egl_g3d.h"
+
+_EGLImage *
+egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
+ EGLenum target, EGLClientBuffer buffer,
+ const EGLint *attribs);
+
+EGLBoolean
+egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
+
+#endif /* _EGL_G3D_IMAGE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
new file mode 100644
index 00000000000..97445478684
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -0,0 +1,312 @@
+/*
+ * 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 <[email protected]>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_dl.h"
+#include "eglimage.h"
+#include "eglmutex.h"
+
+#include "egl_g3d.h"
+#include "egl_g3d_st.h"
+
+struct egl_g3d_st_manager {
+ struct st_manager base;
+ _EGLDisplay *display;
+};
+
+static INLINE struct egl_g3d_st_manager *
+egl_g3d_st_manager(struct st_manager *smapi)
+{
+ return (struct egl_g3d_st_manager *) smapi;
+}
+
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api)
+{
+ struct util_dl_library *lib;
+ const char *proc_name;
+ struct st_api * (*proc)(void) = NULL;
+
+ switch (api) {
+ case ST_API_OPENGL:
+ proc_name = ST_CREATE_OPENGL_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES1:
+ proc_name = ST_CREATE_OPENGL_ES1_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES2:
+ proc_name = ST_CREATE_OPENGL_ES2_SYMBOL;
+ break;
+ case ST_API_OPENVG:
+ proc_name = ST_CREATE_OPENVG_SYMBOL;
+ break;
+ default:
+ assert(!"Unknown API Type\n");
+ return NULL;
+ }
+
+ lib = util_dl_open(NULL);
+ if (lib) {
+ proc = util_dl_get_proc_address(lib, proc_name);
+ debug_printf("%s: %s %p\n", __func__, proc_name, proc);
+ util_dl_close(lib);
+ }
+
+ if (!proc)
+ return NULL;
+
+ return proc();
+}
+
+static boolean
+egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
+ struct st_egl_image *stimg)
+{
+ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
+ EGLImageKHR handle = (EGLImageKHR) stimg->egl_image;
+ _EGLImage *img;
+ struct egl_g3d_image *gimg;
+
+ /* this is called from state trackers */
+ _eglLockMutex(&gsmapi->display->Mutex);
+
+ img = _eglLookupImage(handle, gsmapi->display);
+ if (!img) {
+ _eglUnlockMutex(&gsmapi->display->Mutex);
+ return FALSE;
+ }
+
+ gimg = egl_g3d_image(img);
+
+ stimg->texture = NULL;
+ pipe_resource_reference(&stimg->texture, gimg->texture);
+ stimg->face = gimg->face;
+ stimg->level = gimg->level;
+ stimg->zslice = gimg->zslice;
+
+ _eglUnlockMutex(&gsmapi->display->Mutex);
+
+ return TRUE;
+}
+
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_st_manager *gsmapi;
+
+ gsmapi = CALLOC_STRUCT(egl_g3d_st_manager);
+ if (gsmapi) {
+ gsmapi->display = dpy;
+
+ gsmapi->base.screen = gdpy->native->screen;
+ gsmapi->base.get_egl_image = egl_g3d_st_manager_get_egl_image;
+ }
+
+ return &gsmapi->base;;
+}
+
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi)
+{
+ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi);
+ FREE(gsmapi);
+}
+
+static boolean
+egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ return TRUE;
+}
+
+static boolean
+egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_resource **out)
+{
+ _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++) {
+ out[i] = NULL;
+
+ if (gsurf->stvis.render_buffer != statts[i])
+ 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);
+ }
+
+ pipe_resource_reference(&out[i], gsurf->render_texture);
+ }
+
+ return TRUE;
+}
+
+static boolean
+egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+
+ return gsurf->native->flush_frontbuffer(gsurf->native);
+}
+
+static boolean
+egl_g3d_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_resource **out)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
+ uint attachment_mask = 0;
+ unsigned i;
+
+ for (i = 0; i < count; i++) {
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ break;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0)
+ attachment_mask |= 1 << natt;
+ }
+
+ if (!gsurf->native->validate(gsurf->native, attachment_mask,
+ &gsurf->sequence_number, textures, &gsurf->base.Width,
+ &gsurf->base.Height))
+ return FALSE;
+
+ for (i = 0; i < count; i++) {
+ struct pipe_resource *tex;
+ int natt;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ natt = NATIVE_ATTACHMENT_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ natt = NATIVE_ATTACHMENT_BACK_RIGHT;
+ break;
+ default:
+ natt = -1;
+ break;
+ }
+
+ if (natt >= 0) {
+ tex = textures[natt];
+
+ if (statts[i] == stfbi->visual->render_buffer)
+ pipe_resource_reference(&gsurf->render_texture, tex);
+
+ if (attachment_mask & (1 << natt)) {
+ /* transfer the ownership to the caller */
+ out[i] = tex;
+ attachment_mask &= ~(1 << natt);
+ }
+ else {
+ /* the attachment is listed more than once */
+ pipe_resource_reference(&out[i], tex);
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf)
+{
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (!stfbi)
+ return NULL;
+
+ stfbi->visual = &gsurf->stvis;
+ if (gsurf->base.Type != EGL_PBUFFER_BIT) {
+ stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
+ stfbi->validate = egl_g3d_st_framebuffer_validate;
+ }
+ else {
+ stfbi->flush_front = egl_g3d_st_framebuffer_flush_front_pbuffer;
+ stfbi->validate = egl_g3d_st_framebuffer_validate_pbuffer;
+ }
+ stfbi->st_manager_private = (void *) &gsurf->base;
+
+ return stfbi;
+}
+
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ FREE(stfbi);
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
new file mode 100644
index 00000000000..c82681a22d8
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -0,0 +1,80 @@
+/*
+ * 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 <[email protected]>
+ */
+
+#ifndef _EGL_G3D_ST_H_
+#define _EGL_G3D_ST_H_
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/st_api.h"
+#include "egltypedefs.h"
+
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api);
+
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy);
+
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi);
+
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf);
+
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+/**
+ * Return the EGL_<api>_BIT of the st api.
+ */
+static INLINE int
+egl_g3d_st_api_bit(enum st_api_type api)
+{
+ int bit;
+
+ switch (api) {
+ case ST_API_OPENGL:
+ bit = EGL_OPENGL_BIT;
+ break;
+ case ST_API_OPENGL_ES1:
+ bit = EGL_OPENGL_ES_BIT;
+ break;
+ case ST_API_OPENGL_ES2:
+ bit = EGL_OPENGL_ES2_BIT;
+ break;
+ case ST_API_OPENVG:
+ bit = EGL_OPENVG_BIT;
+ break;
+ default:
+ bit = 0;
+ break;
+ }
+
+ return bit;
+}
+
+#endif /* _EGL_G3D_ST_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c
deleted file mode 100644
index a88ff911cd5..00000000000
--- a/src/gallium/state_trackers/egl/common/egl_st.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.8
- *
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dlfcn.h>
-#include "pipe/p_compiler.h"
-#include "util/u_memory.h"
-#include "egllog.h"
-#include "EGL/egl.h" /* for EGL_api_BIT */
-
-#include "egl_st.h"
-
-#ifndef HAVE_DLADDR
-#define HAVE_DLADDR 1
-#endif
-
-#if HAVE_DLADDR
-
-static const char *
-egl_g3d_st_names[] = {
-#define ST_PUBLIC(name, ...) #name,
-#include "st_public_tmp.h"
- NULL
-};
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
- st_proc *procs = (st_proc *) stapi;
- void *handle;
- Dl_info info;
- const char **name;
-
- if (!dladdr(sym, &info))
- return FALSE;
- handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
- if (!handle)
- return FALSE;
-
- for (name = egl_g3d_st_names; *name; name++) {
- st_proc proc = (st_proc) dlsym(handle, *name);
- if (!proc) {
- _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
- memset(stapi, 0, sizeof(*stapi));
- dlclose(handle);
- return FALSE;
- }
- *procs++ = proc;
- }
-
- dlclose(handle);
- return TRUE;
-}
-
-#else /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
-#define ST_PUBLIC(name, ...) stapi->name = name;
-#include "st_public_tmp.h"
- return TRUE;
-}
-
-#endif /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
-{
- void *handle, *sym;
- boolean res = FALSE;
-
- /* already initialized */
- if (stapi->st_notify_swapbuffers != NULL)
- return TRUE;
-
- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
- if (!handle)
- return FALSE;
-
- sym = dlsym(handle, api);
- if (sym && egl_g3d_fill_st(stapi, sym))
- res = TRUE;
-
- dlclose(handle);
- return res;
-}
-
-static struct {
- const char *symbol;
- EGLint api_bit;
-} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
- { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
- { "st_api_OpenVG", EGL_OPENVG_BIT },
- { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
- { "st_api_OpenGL", EGL_OPENGL_BIT },
-};
-
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api)
-{
- static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
-
- if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
- all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
- return &all_trackers[api];
- }
- else {
- return NULL;
- }
-}
diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h
deleted file mode 100644
index 8fb464bd3d7..00000000000
--- a/src/gallium/state_trackers/egl/common/egl_st.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.8
- *
- * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _EGL_ST_H_
-#define _EGL_ST_H_
-
-#include "GL/gl.h" /* for GL types */
-#include "GL/internal/glcore.h" /* for __GLcontextModes */
-
-#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-
-/* avoid calling st functions directly */
-#if 1
-
-#define ST_SURFACE_FRONT_LEFT 0
-#define ST_SURFACE_BACK_LEFT 1
-#define ST_SURFACE_FRONT_RIGHT 2
-#define ST_SURFACE_BACK_RIGHT 3
-
-#define ST_TEXTURE_2D 0x2
-
-struct st_context;
-struct st_framebuffer;
-typedef void (*st_proc)();
-
-#else
-#include "state_tracker/st_public.h"
-#endif
-
-/* remember to update egl_g3d_get_st() when update the enums */
-enum egl_g3d_st_api {
- EGL_G3D_ST_OPENGL_ES = 0,
- EGL_G3D_ST_OPENVG,
- EGL_G3D_ST_OPENGL_ES2,
- EGL_G3D_ST_OPENGL,
-
- NUM_EGL_G3D_STS
-};
-
-struct egl_g3d_st {
-#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__);
-#include "st_public_tmp.h"
- /* fields must be added here */
- EGLint api_bit;
-};
-
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api);
-
-#endif /* _EGL_ST_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 4f9758545ab..3f60348c489 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -14,26 +14,28 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#ifndef _NATIVE_H_
#define _NATIVE_H_
#include "EGL/egl.h" /* for EGL native types */
-#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
-#include "GL/internal/glcore.h" /* for __GLcontextModes */
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "native_probe.h"
+#include "native_modeset.h"
+
/**
* Only color buffers are listed. The others are allocated privately through,
* for example, st_renderbuffer_alloc_storage().
@@ -47,28 +49,20 @@ enum native_attachment {
NUM_NATIVE_ATTACHMENTS
};
-/**
- * Enumerations for probe results.
- */
-enum native_probe_result {
- NATIVE_PROBE_UNKNOWN,
- NATIVE_PROBE_FALLBACK,
- NATIVE_PROBE_SUPPORTED,
- NATIVE_PROBE_EXACT,
-};
-
-/**
- * A probe object for display probe.
- */
-struct native_probe {
- int magic;
- EGLNativeDisplayType display;
- void *data;
-
- void (*destroy)(struct native_probe *nprobe);
+enum native_param_type {
+ /*
+ * Return TRUE if window/pixmap surfaces use the buffers of the native
+ * types.
+ */
+ NATIVE_PARAM_USE_NATIVE_BUFFER
};
struct native_surface {
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_surface *nsurf);
/**
@@ -97,7 +91,7 @@ struct native_surface {
* behavior might change in the future.
*/
boolean (*validate)(struct native_surface *nsurf, uint attachment_mask,
- unsigned int *seq_num, struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height);
/**
@@ -106,29 +100,28 @@ struct native_surface {
void (*wait)(struct native_surface *nsurf);
};
+/**
+ * Describe a native display config.
+ */
struct native_config {
- /* __GLcontextModes should go away some day */
- __GLcontextModes mode;
+ /* available buffers and their format */
+ uint buffer_mask;
enum pipe_format color_format;
- enum pipe_format depth_format;
- enum pipe_format stencil_format;
- /* treat it as an additional flag to mode.drawableType */
+ /* supported surface types */
+ boolean window_bit;
+ boolean pixmap_bit;
boolean scanout_bit;
-};
-struct native_connector {
- int dummy;
+ int native_visual_id;
+ int native_visual_type;
+ int level;
+ int samples;
+ boolean slow_config;
+ boolean transparent_rgb;
+ int transparent_rgb_values[3];
};
-struct native_mode {
- const char *desc;
- int width, height;
- int refresh_rate;
-};
-
-struct native_display_modeset;
-
/**
* A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis
* hardware. A native display consists of a pipe winsys, a pipe screen, and
@@ -137,28 +130,34 @@ struct native_display_modeset;
struct native_display {
/**
* The pipe screen of the native display.
- *
- * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be
- * overridden.
*/
struct pipe_screen *screen;
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_display *ndpy);
/**
- * Get the supported configs. The configs are owned by the display, but
- * the returned array should be free()ed.
+ * Query the parameters of the native display.
*
- * The configs will be converted to EGL config by
- * _eglConfigFromContextModesRec and validated by _eglValidateConfig.
- * Those failing to pass the test will be skipped.
+ * The return value is defined by the parameter.
+ */
+ int (*get_param)(struct native_display *ndpy,
+ enum native_param_type param);
+
+ /**
+ * Get the supported configs. The configs are owned by the display, but
+ * the returned array should be FREE()ed.
*/
const struct native_config **(*get_configs)(struct native_display *ndpy,
int *num_configs);
/**
* Test if a pixmap is supported by the given config. Required unless no
- * config has GLX_PIXMAP_BIT set.
+ * config has pixmap_bit set.
*
* This function is usually called to find a config that supports a given
* pixmap. Thus, it is usually called with the same pixmap in a row.
@@ -169,73 +168,34 @@ struct native_display {
/**
- * Create a window surface. Required unless no config has GLX_WINDOW_BIT
- * set.
+ * Create a window surface. Required unless no config has window_bit set.
*/
struct native_surface *(*create_window_surface)(struct native_display *ndpy,
EGLNativeWindowType win,
const struct native_config *nconf);
/**
- * Create a pixmap surface. Required unless no config has GLX_PIXMAP_BIT
- * set.
+ * Create a pixmap surface. Required unless no config has pixmap_bit set.
*/
struct native_surface *(*create_pixmap_surface)(struct native_display *ndpy,
EGLNativePixmapType pix,
const struct native_config *nconf);
- /**
- * Create a pbuffer surface. Required unless no config has GLX_PBUFFER_BIT
- * set.
- */
- struct native_surface *(*create_pbuffer_surface)(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height);
-
const struct native_display_modeset *modeset;
};
/**
- * Mode setting interface of the native display. It exposes the mode setting
- * capabilities of the underlying graphics hardware.
+ * The handler for events that a native display may generate. The events are
+ * generated asynchronously and the handler may be called by any thread at any
+ * time.
*/
-struct native_display_modeset {
- /**
- * Get the available physical connectors and the number of CRTCs.
- */
- const struct native_connector **(*get_connectors)(struct native_display *ndpy,
- int *num_connectors,
- int *num_crtcs);
-
- /**
- * Get the current supported modes of a connector. The returned modes may
- * change every time this function is called and those from previous calls
- * might become invalid.
- */
- const struct native_mode **(*get_modes)(struct native_display *ndpy,
- const struct native_connector *nconn,
- int *num_modes);
-
+struct native_event_handler {
/**
- * Create a scan-out surface. Required unless no config has
- * GLX_SCREEN_BIT_MESA set.
+ * This function is called when a surface needs to be validated.
*/
- struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height);
-
- /**
- * Program the CRTC to output the surface to the given connectors with the
- * given mode. When surface is not given, the CRTC is disabled.
- *
- * This interface does not export a way to query capabilities of the CRTCs.
- * The native display usually needs to dynamically map the index to a CRTC
- * that supports the given connectors.
- */
- boolean (*program)(struct native_display *ndpy, int crtc_idx,
- struct native_surface *nsurf, uint x, uint y,
- const struct native_connector **nconns, int num_nconns,
- const struct native_mode *nmode);
+ void (*invalid_surface)(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num);
};
/**
@@ -247,26 +207,11 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
return !!(mask & (1 << att));
}
-/**
- * Return a probe object for the given display.
- *
- * Note that the returned object may be cached and used by different native
- * display modules. It allows fast probing when multiple modules probe the
- * same display.
- */
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy);
-
-/**
- * Probe the probe object.
- */
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe);
-
const char *
native_get_name(void);
struct native_display *
-native_create_display(EGLNativeDisplayType dpy);
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *handler);
#endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native_modeset.h b/src/gallium/state_trackers/egl/common/native_modeset.h
new file mode 100644
index 00000000000..dee757b3a88
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_modeset.h
@@ -0,0 +1,88 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef _NATIVE_MODESET_H_
+#define _NATIVE_MODESET_H_
+
+#include "pipe/p_compiler.h"
+
+struct native_display;
+struct native_surface;
+struct native_config;
+
+struct native_connector {
+ int dummy;
+};
+
+struct native_mode {
+ const char *desc;
+ int width, height;
+ int refresh_rate;
+};
+
+/**
+ * Mode setting interface of the native display. It exposes the mode setting
+ * capabilities of the underlying graphics hardware.
+ */
+struct native_display_modeset {
+ /**
+ * Get the available physical connectors and the number of CRTCs.
+ */
+ const struct native_connector **(*get_connectors)(struct native_display *ndpy,
+ int *num_connectors,
+ int *num_crtcs);
+
+ /**
+ * Get the current supported modes of a connector. The returned modes may
+ * change every time this function is called and those from previous calls
+ * might become invalid.
+ */
+ const struct native_mode **(*get_modes)(struct native_display *ndpy,
+ const struct native_connector *nconn,
+ int *num_modes);
+
+ /**
+ * Create a scan-out surface. Required unless no config has scanout_bit
+ * set.
+ */
+ struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height);
+
+ /**
+ * Program the CRTC to output the surface to the given connectors with the
+ * given mode. When surface is not given, the CRTC is disabled.
+ *
+ * This interface does not export a way to query capabilities of the CRTCs.
+ * The native display usually needs to dynamically map the index to a CRTC
+ * that supports the given connectors.
+ */
+ boolean (*program)(struct native_display *ndpy, int crtc_idx,
+ struct native_surface *nsurf, uint x, uint y,
+ const struct native_connector **nconns, int num_nconns,
+ const struct native_mode *nmode);
+};
+
+#endif /* _NATIVE_MODESET_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native_probe.h b/src/gallium/state_trackers/egl/common/native_probe.h
new file mode 100644
index 00000000000..aeed9f85dd5
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_probe.h
@@ -0,0 +1,68 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef _NATIVE_PROBE_H_
+#define _NATIVE_PROBE_H_
+
+#include "EGL/egl.h" /* for EGL native types */
+
+/**
+ * Enumerations for probe results.
+ */
+enum native_probe_result {
+ NATIVE_PROBE_UNKNOWN,
+ NATIVE_PROBE_FALLBACK,
+ NATIVE_PROBE_SUPPORTED,
+ NATIVE_PROBE_EXACT,
+};
+
+/**
+ * A probe object for display probe.
+ */
+struct native_probe {
+ int magic;
+ EGLNativeDisplayType display;
+ void *data;
+
+ void (*destroy)(struct native_probe *nprobe);
+};
+
+/**
+ * Return a probe object for the given display.
+ *
+ * Note that the returned object may be cached and used by different native
+ * display modules. It allows fast probing when multiple modules probe the
+ * same display.
+ */
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy);
+
+/**
+ * Probe the probe object.
+ */
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe);
+
+#endif /* _NATIVE_PROBE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
deleted file mode 100644
index 507a0ec4027..00000000000
--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h
+++ /dev/null
@@ -1,20 +0,0 @@
-ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share)
-ST_PUBLIC(st_destroy_context, void, struct st_context *st)
-ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask)
-ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData)
-ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height)
-ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf)
-ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height)
-ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface)
-ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
-ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
-ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read)
-ST_PUBLIC(st_get_current, struct st_context *, void)
-ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
-ST_PUBLIC(st_finish, void, struct st_context *st)
-ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format)
-ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level)
-ST_PUBLIC(st_get_proc_address, st_proc, const char *procname)
-#undef ST_PUBLIC
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index aedf3d430ca..cf7188dfdb7 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -14,35 +14,34 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
-#include <stdio.h>
-#include <string.h>
-
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_string.h"
#include "egllog.h"
#include "native_kms.h"
static boolean
kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
- unsigned int *seq_num, struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct kms_surface *ksurf = kms_surface(nsurf);
struct kms_display *kdpy = ksurf->kdpy;
struct pipe_screen *screen = kdpy->base.screen;
- struct pipe_texture templ, *ptex;
+ struct pipe_resource templ, *ptex;
int att;
if (attachment_mask) {
@@ -53,9 +52,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
templ.height0 = ksurf->height;
templ.depth0 = 1;
templ.format = ksurf->color_format;
- templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
- templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SCANOUT;
}
/* create textures */
@@ -66,13 +63,13 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
ptex = ksurf->textures[att];
if (!ptex) {
- ptex = screen->texture_create(screen, &templ);
+ ptex = screen->resource_create(screen, &templ);
ksurf->textures[att] = ptex;
}
if (textures) {
textures[att] = NULL;
- pipe_texture_reference(&textures[att], ptex);
+ pipe_resource_reference(&textures[att], ptex);
}
}
@@ -100,7 +97,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
for (i = 0; i < num_framebuffers; i++) {
struct kms_framebuffer *fb;
enum native_attachment natt;
- unsigned int handle, stride;
+ struct winsys_handle whandle;
uint block_bits;
if (i == 0) {
@@ -118,7 +115,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
if (!ksurf->textures[natt])
return FALSE;
- pipe_texture_reference(&fb->texture, ksurf->textures[natt]);
+ pipe_resource_reference(&fb->texture, ksurf->textures[natt]);
}
/* already initialized */
@@ -128,13 +125,17 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
/* TODO detect the real value */
fb->is_passive = TRUE;
- if (!kdpy->api->local_handle_from_texture(kdpy->api,
- kdpy->base.screen, fb->texture, &stride, &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!kdpy->base.screen->resource_get_handle(kdpy->base.screen,
+ fb->texture, &whandle))
return FALSE;
block_bits = util_format_get_blocksizebits(ksurf->color_format);
err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
- block_bits, block_bits, stride, handle, &fb->buffer_id);
+ block_bits, block_bits, whandle.stride, whandle.handle,
+ &fb->buffer_id);
if (err) {
fb->buffer_id = 0;
return FALSE;
@@ -151,10 +152,6 @@ kms_surface_flush_frontbuffer(struct native_surface *nsurf)
struct kms_surface *ksurf = kms_surface(nsurf);
struct kms_display *kdpy = ksurf->kdpy;
- /* pbuffer is private */
- if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
- return TRUE;
-
if (ksurf->front_fb.is_passive)
drmModeDirtyFB(kdpy->fd, ksurf->front_fb.buffer_id, NULL, 0);
#endif
@@ -169,13 +166,9 @@ 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_texture *tmp_texture;
+ struct pipe_resource *tmp_texture;
int err;
- /* pbuffer is private */
- if (ksurf->type == KMS_SURFACE_TYPE_PBUFFER)
- return TRUE;
-
if (!ksurf->back_fb.buffer_id) {
if (!kms_surface_init_framebuffers(&ksurf->base, TRUE))
return FALSE;
@@ -201,6 +194,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
/* the front/back textures are swapped */
ksurf->sequence_number++;
+ kdpy->event_handler->invalid_surface(&kdpy->base,
+ &ksurf->base, ksurf->sequence_number);
return TRUE;
}
@@ -222,23 +217,22 @@ kms_surface_destroy(struct native_surface *nsurf)
if (ksurf->front_fb.buffer_id)
drmModeRmFB(ksurf->kdpy->fd, ksurf->front_fb.buffer_id);
- pipe_texture_reference(&ksurf->front_fb.texture, NULL);
+ pipe_resource_reference(&ksurf->front_fb.texture, NULL);
if (ksurf->back_fb.buffer_id)
drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
- pipe_texture_reference(&ksurf->back_fb.texture, NULL);
+ pipe_resource_reference(&ksurf->back_fb.texture, NULL);
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct pipe_texture *ptex = ksurf->textures[i];
- pipe_texture_reference(&ptex, NULL);
+ struct pipe_resource *ptex = ksurf->textures[i];
+ pipe_resource_reference(&ptex, NULL);
}
- free(ksurf);
+ FREE(ksurf);
}
static struct kms_surface *
kms_display_create_surface(struct native_display *ndpy,
- enum kms_surface_type type,
const struct native_config *nconf,
uint width, uint height)
{
@@ -251,7 +245,6 @@ kms_display_create_surface(struct native_display *ndpy,
return NULL;
ksurf->kdpy = kdpy;
- ksurf->type = type;
ksurf->color_format = kconf->base.color_format;
ksurf->width = width;
ksurf->height = height;
@@ -469,7 +462,7 @@ kms_display_get_modes(struct native_display *ndpy,
/* delete old data */
if (kconn->connector) {
drmModeFreeConnector(kconn->connector);
- free(kconn->kms_modes);
+ FREE(kconn->kms_modes);
kconn->connector = NULL;
kconn->kms_modes = NULL;
@@ -482,7 +475,7 @@ kms_display_get_modes(struct native_display *ndpy,
return NULL;
count = kconn->connector->count_modes;
- kconn->kms_modes = calloc(count, sizeof(*kconn->kms_modes));
+ kconn->kms_modes = CALLOC(count, sizeof(*kconn->kms_modes));
if (!kconn->kms_modes) {
drmModeFreeConnector(kconn->connector);
kconn->connector = NULL;
@@ -505,7 +498,7 @@ kms_display_get_modes(struct native_display *ndpy,
kmode->base.refresh_rate = (kmode->base.refresh_rate + 500) / 1000;
}
- nmodes_return = malloc(count * sizeof(*nmodes_return));
+ nmodes_return = MALLOC(count * sizeof(*nmodes_return));
if (nmodes_return) {
for (i = 0; i < count; i++)
nmodes_return[i] = &kconn->kms_modes[i].base;
@@ -526,7 +519,7 @@ kms_display_get_connectors(struct native_display *ndpy, int *num_connectors,
if (!kdpy->connectors) {
kdpy->connectors =
- calloc(kdpy->resources->count_connectors, sizeof(*kdpy->connectors));
+ CALLOC(kdpy->resources->count_connectors, sizeof(*kdpy->connectors));
if (!kdpy->connectors)
return NULL;
@@ -540,7 +533,7 @@ kms_display_get_connectors(struct native_display *ndpy, int *num_connectors,
kdpy->num_connectors = kdpy->resources->count_connectors;
}
- connectors = malloc(kdpy->num_connectors * sizeof(*connectors));
+ connectors = MALLOC(kdpy->num_connectors * sizeof(*connectors));
if (connectors) {
for (i = 0; i < kdpy->num_connectors; i++)
connectors[i] = &kdpy->connectors[i].base;
@@ -561,32 +554,18 @@ kms_display_create_scanout_surface(struct native_display *ndpy,
{
struct kms_surface *ksurf;
- ksurf = kms_display_create_surface(ndpy,
- KMS_SURFACE_TYPE_SCANOUT, nconf, width, height);
- return &ksurf->base;
-}
-
-static struct native_surface *
-kms_display_create_pbuffer_surface(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height)
-{
- struct kms_surface *ksurf;
-
- ksurf = kms_display_create_surface(ndpy,
- KMS_SURFACE_TYPE_PBUFFER, nconf, width, height);
+ ksurf = kms_display_create_surface(ndpy, nconf, width, height);
return &ksurf->base;
}
-
static boolean
kms_display_is_format_supported(struct native_display *ndpy,
enum pipe_format fmt, boolean is_color)
{
return ndpy->screen->is_format_supported(ndpy->screen,
fmt, PIPE_TEXTURE_2D,
- (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ (is_color) ? PIPE_BIND_RENDER_TARGET :
+ PIPE_BIND_DEPTH_STENCIL, 0);
}
static const struct native_config **
@@ -600,14 +579,15 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
struct native_config *nconf;
enum pipe_format format;
- kdpy->config = calloc(1, sizeof(*kdpy->config));
+ kdpy->config = CALLOC(1, sizeof(*kdpy->config));
if (!kdpy->config)
return NULL;
nconf = &kdpy->config->base;
- /* always double-buffered */
- nconf->mode.doubleBufferMode = TRUE;
+ nconf->buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
format = PIPE_FORMAT_B8G8R8A8_UNORM;
if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) {
@@ -615,45 +595,18 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
if (!kms_display_is_format_supported(&kdpy->base, format, TRUE))
format = PIPE_FORMAT_NONE;
}
- if (format == PIPE_FORMAT_NONE)
+ if (format == PIPE_FORMAT_NONE) {
+ FREE(kdpy->config);
+ kdpy->config = NULL;
return NULL;
+ }
nconf->color_format = format;
- nconf->mode.redBits = 8;
- nconf->mode.greenBits = 8;
- nconf->mode.blueBits = 8;
- nconf->mode.alphaBits = 8;
- nconf->mode.rgbBits = 32;
-
- format = PIPE_FORMAT_Z24S8_UNORM;
- if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) {
- format = PIPE_FORMAT_S8Z24_UNORM;
- if (!kms_display_is_format_supported(&kdpy->base, format, FALSE))
- format = PIPE_FORMAT_NONE;
- }
- if (format != PIPE_FORMAT_NONE) {
- nconf->depth_format = format;
- nconf->stencil_format = format;
-
- nconf->mode.depthBits = 24;
- nconf->mode.stencilBits = 8;
- nconf->mode.haveDepthBuffer = TRUE;
- nconf->mode.haveStencilBuffer = TRUE;
- }
nconf->scanout_bit = TRUE;
- nconf->mode.drawableType = GLX_PBUFFER_BIT;
- nconf->mode.swapMethod = GLX_SWAP_EXCHANGE_OML;
-
- nconf->mode.visualID = 0;
- nconf->mode.visualType = EGL_NONE;
-
- nconf->mode.renderType = GLX_RGBA_BIT;
- nconf->mode.rgbMode = TRUE;
- nconf->mode.xRenderable = FALSE;
}
- configs = malloc(sizeof(*configs));
+ configs = MALLOC(sizeof(*configs));
if (configs) {
configs[0] = &kdpy->config->base;
if (num_configs)
@@ -663,6 +616,21 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
return configs;
}
+static int
+kms_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
static void
kms_display_destroy(struct native_display *ndpy)
{
@@ -670,21 +638,21 @@ kms_display_destroy(struct native_display *ndpy)
int i;
if (kdpy->config)
- free(kdpy->config);
+ FREE(kdpy->config);
if (kdpy->connectors) {
for (i = 0; i < kdpy->num_connectors; i++) {
struct kms_connector *kconn = &kdpy->connectors[i];
if (kconn->connector) {
drmModeFreeConnector(kconn->connector);
- free(kconn->kms_modes);
+ FREE(kconn->kms_modes);
}
}
- free(kdpy->connectors);
+ FREE(kdpy->connectors);
}
if (kdpy->shown_surfaces)
- free(kdpy->shown_surfaces);
+ FREE(kdpy->shown_surfaces);
if (kdpy->saved_crtcs) {
for (i = 0; i < kdpy->resources->count_crtcs; i++) {
@@ -700,7 +668,7 @@ kms_display_destroy(struct native_display *ndpy)
drmModeFreeCrtc(kcrtc->crtc);
}
}
- free(kdpy->saved_crtcs);
+ FREE(kdpy->saved_crtcs);
}
if (kdpy->resources)
@@ -712,9 +680,9 @@ kms_display_destroy(struct native_display *ndpy)
if (kdpy->fd >= 0)
drmClose(kdpy->fd);
- if (kdpy->api)
+ if (kdpy->api && kdpy->api->destroy)
kdpy->api->destroy(kdpy->api);
- free(kdpy);
+ FREE(kdpy);
}
/**
@@ -724,10 +692,9 @@ static boolean
kms_display_init_screen(struct native_display *ndpy)
{
struct kms_display *kdpy = kms_display(ndpy);
- struct drm_create_screen_arg arg;
int fd;
- fd = drmOpen(kdpy->api->name, NULL);
+ fd = drmOpen(kdpy->api->driver_name, NULL);
if (fd < 0) {
_eglLog(_EGL_WARNING, "failed to open DRM device");
return FALSE;
@@ -740,9 +707,7 @@ kms_display_init_screen(struct native_display *ndpy)
}
#endif
- memset(&arg, 0, sizeof(arg));
- arg.mode = DRM_CREATE_NORMAL;
- kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, &arg);
+ kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, NULL);
if (!kdpy->base.screen) {
_eglLog(_EGL_WARNING, "failed to create DRM screen");
drmClose(fd);
@@ -762,7 +727,9 @@ static struct native_display_modeset kms_display_modeset = {
};
static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
+kms_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct kms_display *kdpy;
@@ -770,10 +737,12 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!kdpy)
return NULL;
+ kdpy->event_handler = event_handler;
+
kdpy->api = api;
if (!kdpy->api) {
_eglLog(_EGL_WARNING, "failed to create DRM API");
- free(kdpy);
+ FREE(kdpy);
return NULL;
}
@@ -791,22 +760,22 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
}
kdpy->saved_crtcs =
- calloc(kdpy->resources->count_crtcs, sizeof(*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));
+ CALLOC(kdpy->resources->count_crtcs, sizeof(*kdpy->shown_surfaces));
if (!kdpy->shown_surfaces) {
kms_display_destroy(&kdpy->base);
return NULL;
}
kdpy->base.destroy = kms_display_destroy;
+ kdpy->base.get_param = kms_display_get_param;
kdpy->base.get_configs = kms_display_get_configs;
- kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface;
kdpy->base.modeset = &kms_display_modeset;
@@ -837,15 +806,16 @@ native_get_name(void)
drm_api = drm_api_create();
if (drm_api)
- snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
+ util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
else
- snprintf(kms_name, sizeof(kms_name), "KMS");
+ util_snprintf(kms_name, sizeof(kms_name), "KMS");
return kms_name;
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
@@ -853,7 +823,7 @@ native_create_display(EGLNativeDisplayType dpy)
drm_api = drm_api_create();
if (drm_api)
- ndpy = kms_create_display(dpy, drm_api);
+ ndpy = kms_create_display(dpy, 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 095186e3cf3..3b08e930c52 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -14,12 +14,13 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#ifndef _NATIVE_KMS_H_
@@ -35,11 +36,6 @@
#include "common/native.h"
-enum kms_surface_type {
- KMS_SURFACE_TYPE_PBUFFER,
- KMS_SURFACE_TYPE_SCANOUT
-};
-
struct kms_config;
struct kms_connector;
struct kms_mode;
@@ -53,6 +49,8 @@ struct kms_crtc {
struct kms_display {
struct native_display base;
+ struct native_event_handler *event_handler;
+
int fd;
struct drm_api *api;
drmModeResPtr resources;
@@ -67,7 +65,7 @@ struct kms_display {
};
struct kms_framebuffer {
- struct pipe_texture *texture;
+ struct pipe_resource *texture;
boolean is_passive;
uint32_t buffer_id;
@@ -75,12 +73,11 @@ struct kms_framebuffer {
struct kms_surface {
struct native_surface base;
- enum kms_surface_type type;
enum pipe_format color_format;
struct kms_display *kdpy;
int width, height;
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ 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_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 74d3d104b94..d37f66da07e 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -14,12 +14,13 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#include "util/u_memory.h"
@@ -40,7 +41,6 @@
enum dri2_surface_type {
DRI2_SURFACE_TYPE_WINDOW,
DRI2_SURFACE_TYPE_PIXMAP,
- DRI2_SURFACE_TYPE_PBUFFER
};
struct dri2_display {
@@ -48,6 +48,8 @@ struct dri2_display {
Display *dpy;
boolean own_dpy;
+ struct native_event_handler *event_handler;
+
struct drm_api *api;
struct x11_screen *xscr;
int xscr_number;
@@ -70,7 +72,7 @@ struct dri2_surface {
unsigned int server_stamp;
unsigned int client_stamp;
int width, height;
- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
uint valid_mask;
boolean have_back, have_fake;
@@ -111,13 +113,14 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
- struct pipe_texture templ;
+ struct pipe_resource templ;
+ struct winsys_handle whandle;
uint valid_mask;
int i;
/* free the old textures */
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
- pipe_texture_reference(&dri2surf->textures[i], NULL);
+ pipe_resource_reference(&dri2surf->textures[i], NULL);
dri2surf->valid_mask = 0x0;
dri2surf->have_back = FALSE;
@@ -133,7 +136,7 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
templ.height0 = dri2surf->height;
templ.depth0 = 1;
templ.format = dri2surf->color_format;
- templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templ.bind = PIPE_BIND_RENDER_TARGET;
valid_mask = 0x0;
for (i = 0; i < num_xbufs; i++) {
@@ -169,9 +172,11 @@ dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
continue;
}
- dri2surf->textures[natt] =
- dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
- dri2dpy->base.screen, &templ, desc, xbuf->pitch, xbuf->name);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = xbuf->pitch;
+ whandle.handle = xbuf->name;
+ dri2surf->textures[natt] = dri2dpy->base.screen->resource_from_handle(
+ dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
@@ -187,9 +192,19 @@ dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
- unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
+ unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS * 2];
int num_ins, num_outs, att;
struct x11_drawable_buffer *xbufs;
+ uint bpp = util_format_get_blocksizebits(dri2surf->color_format);
+ boolean with_format = FALSE; /* never ask for depth/stencil */
+
+ /* We must get the front on servers which doesn't support with format
+ * due to a silly bug in core dri2. You can't copy to/from a buffer
+ * that you haven't requested and you recive BadValue errors */
+ if (dri2surf->dri2dpy->dri_minor < 1) {
+ with_format = FALSE;
+ buffer_mask |= (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
+ }
/* prepare the attachments */
num_ins = 0;
@@ -216,19 +231,22 @@ dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
break;
}
- dri2atts[num_ins] = dri2att;
- num_ins++;
+ dri2atts[num_ins++] = dri2att;
+ if (with_format)
+ dri2atts[num_ins++] = bpp;
}
}
+ if (with_format)
+ num_ins /= 2;
xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
&dri2surf->width, &dri2surf->height,
- dri2atts, FALSE, num_ins, &num_outs);
+ dri2atts, with_format, num_ins, &num_outs);
/* we should be able to do better... */
if (xbufs && dri2surf->last_num_xbufs == num_outs &&
memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
- free(xbufs);
+ FREE(xbufs);
dri2surf->client_stamp = dri2surf->server_stamp;
return;
}
@@ -239,7 +257,7 @@ dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
dri2surf->client_stamp = dri2surf->server_stamp;
if (dri2surf->last_xbufs)
- free(dri2surf->last_xbufs);
+ FREE(dri2surf->last_xbufs);
dri2surf->last_xbufs = xbufs;
dri2surf->last_num_xbufs = num_outs;
}
@@ -252,47 +270,8 @@ static boolean
dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
- struct dri2_display *dri2dpy = dri2surf->dri2dpy;
-
- /* create textures for pbuffer */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
- struct pipe_screen *screen = dri2dpy->base.screen;
- struct pipe_texture templ;
- uint new_valid = 0x0;
- int att;
-
- buffer_mask &= ~dri2surf->valid_mask;
- if (!buffer_mask)
- return TRUE;
-
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = dri2surf->width;
- templ.height0 = dri2surf->height;
- templ.depth0 = 1;
- templ.format = dri2surf->color_format;
- templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
-
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(buffer_mask, att)) {
- assert(!dri2surf->textures[att]);
- dri2surf->textures[att] = screen->texture_create(screen, &templ);
- if (!dri2surf->textures[att])
- break;
-
- new_valid |= 1 << att;
- if (new_valid == buffer_mask)
- break;
- }
- }
- dri2surf->valid_mask |= new_valid;
- /* no need to update the stamps */
- }
- else {
- dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
- }
+ dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
}
@@ -313,10 +292,6 @@ dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
- /* pbuffer is private */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
- return TRUE;
-
/* copy to real front buffer */
if (dri2surf->have_fake)
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
@@ -324,8 +299,11 @@ dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
/* force buffers to be updated in next validation call */
- if (!dri2_surface_receive_events(&dri2surf->base))
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+ }
return TRUE;
}
@@ -336,10 +314,6 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
- /* pbuffer is private */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
- return TRUE;
-
/* copy to front buffer */
if (dri2surf->have_back)
x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
@@ -353,15 +327,18 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
/* force buffers to be updated in next validation call */
- if (!dri2_surface_receive_events(&dri2surf->base))
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+ }
return TRUE;
}
static boolean
dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
- unsigned int *seq_num, struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
@@ -379,10 +356,10 @@ dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int att;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(attachment_mask, att)) {
- struct pipe_texture *ptex = dri2surf->textures[att];
+ struct pipe_resource *ptex = dri2surf->textures[att];
textures[att] = NULL;
- pipe_texture_reference(&textures[att], ptex);
+ pipe_resource_reference(&textures[att], ptex);
}
}
}
@@ -415,11 +392,11 @@ dri2_surface_destroy(struct native_surface *nsurf)
int i;
if (dri2surf->last_xbufs)
- free(dri2surf->last_xbufs);
+ FREE(dri2surf->last_xbufs);
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct pipe_texture *ptex = dri2surf->textures[i];
- pipe_texture_reference(&ptex, NULL);
+ struct pipe_resource *ptex = dri2surf->textures[i];
+ pipe_resource_reference(&ptex, NULL);
}
if (dri2surf->drawable) {
@@ -429,7 +406,7 @@ dri2_surface_destroy(struct native_surface *nsurf)
util_hash_table_remove(dri2surf->dri2dpy->surfaces,
(void *) dri2surf->drawable);
}
- free(dri2surf);
+ FREE(dri2surf);
}
static struct dri2_surface *
@@ -493,22 +470,6 @@ dri2_display_create_pixmap_surface(struct native_display *ndpy,
return (dri2surf) ? &dri2surf->base : NULL;
}
-static struct native_surface *
-dri2_display_create_pbuffer_surface(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height)
-{
- struct dri2_surface *dri2surf;
-
- dri2surf = dri2_display_create_surface(ndpy, DRI2_SURFACE_TYPE_PBUFFER,
- (Drawable) None, nconf);
- if (dri2surf) {
- dri2surf->width = width;
- dri2surf->height = height;
- }
- return (dri2surf) ? &dri2surf->base : NULL;
-}
-
static int
choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
{
@@ -535,43 +496,13 @@ choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
return count;
}
-static int
-choose_depth_stencil_format(const __GLcontextModes *mode,
- enum pipe_format formats[32])
-{
- int count = 0;
-
- switch (mode->depthBits) {
- case 32:
- formats[count++] = PIPE_FORMAT_Z32_UNORM;
- break;
- case 24:
- if (mode->stencilBits) {
- formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
- formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
- }
- else {
- formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
- formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
- }
- break;
- case 16:
- formats[count++] = PIPE_FORMAT_Z16_UNORM;
- break;
- default:
- break;
- }
-
- return count;
-}
-
static boolean
is_format_supported(struct pipe_screen *screen,
enum pipe_format fmt, boolean is_color)
{
return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
- (is_color) ? PIPE_TEXTURE_USAGE_RENDER_TARGET :
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ (is_color) ? PIPE_BIND_RENDER_TARGET :
+ PIPE_BIND_DEPTH_STENCIL, 0);
}
static boolean
@@ -589,30 +520,18 @@ dri2_display_convert_config(struct native_display *ndpy,
if (!mode->doubleBufferMode)
return FALSE;
- nconf->mode = *mode;
- nconf->mode.renderType = GLX_RGBA_BIT;
- nconf->mode.rgbMode = TRUE;
- /* pbuffer is allocated locally and is always supported */
- nconf->mode.drawableType |= GLX_PBUFFER_BIT;
- /* the swap method is always copy */
- nconf->mode.swapMethod = GLX_SWAP_COPY_OML;
-
- /* fix up */
- nconf->mode.rgbBits =
- nconf->mode.redBits + nconf->mode.greenBits +
- nconf->mode.blueBits + nconf->mode.alphaBits;
- if (!(nconf->mode.drawableType & GLX_WINDOW_BIT)) {
- nconf->mode.visualID = 0;
- nconf->mode.visualType = GLX_NONE;
- }
- if (!(nconf->mode.drawableType & GLX_PBUFFER_BIT)) {
- nconf->mode.bindToTextureRgb = FALSE;
- nconf->mode.bindToTextureRgba = FALSE;
- }
+ /* only interested in native renderable configs */
+ if (!mode->xRenderable || !mode->drawableType)
+ return FALSE;
- nconf->color_format = PIPE_FORMAT_NONE;
- nconf->depth_format = PIPE_FORMAT_NONE;
- nconf->stencil_format = PIPE_FORMAT_NONE;
+ nconf->buffer_mask = 1 << NATIVE_ATTACHMENT_FRONT_LEFT;
+ if (mode->doubleBufferMode)
+ nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_LEFT;
+ if (mode->stereoMode) {
+ nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_FRONT_RIGHT;
+ if (mode->doubleBufferMode)
+ nconf->buffer_mask |= 1 << NATIVE_ATTACHMENT_BACK_RIGHT;
+ }
/* choose color format */
num_formats = choose_color_format(mode, formats);
@@ -625,18 +544,24 @@ dri2_display_convert_config(struct native_display *ndpy,
if (nconf->color_format == PIPE_FORMAT_NONE)
return FALSE;
- /* choose depth/stencil format */
- num_formats = choose_depth_stencil_format(mode, formats);
- for (i = 0; i < num_formats; i++) {
- if (is_format_supported(ndpy->screen, formats[i], FALSE)) {
- nconf->depth_format = formats[i];
- nconf->stencil_format = formats[i];
- break;
- }
+ if (mode->drawableType & GLX_WINDOW_BIT)
+ nconf->window_bit = TRUE;
+ if (mode->drawableType & GLX_PIXMAP_BIT)
+ nconf->pixmap_bit = TRUE;
+
+ nconf->native_visual_id = mode->visualID;
+ nconf->native_visual_type = mode->visualType;
+ nconf->level = mode->level;
+ nconf->samples = mode->samples;
+
+ nconf->slow_config = (mode->visualRating == GLX_SLOW_CONFIG);
+
+ if (mode->transparentPixel == GLX_TRANSPARENT_RGB) {
+ nconf->transparent_rgb = TRUE;
+ nconf->transparent_rgb_values[0] = mode->transparentRed;
+ nconf->transparent_rgb_values[1] = mode->transparentGreen;
+ nconf->transparent_rgb_values[2] = mode->transparentBlue;
}
- if ((nconf->mode.depthBits && nconf->depth_format == PIPE_FORMAT_NONE) ||
- (nconf->mode.stencilBits && nconf->stencil_format == PIPE_FORMAT_NONE))
- return FALSE;
return TRUE;
}
@@ -658,7 +583,7 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
return NULL;
num_modes = x11_context_modes_count(modes);
- dri2dpy->configs = calloc(num_modes, sizeof(*dri2dpy->configs));
+ dri2dpy->configs = CALLOC(num_modes, sizeof(*dri2dpy->configs));
if (!dri2dpy->configs)
return NULL;
@@ -673,7 +598,7 @@ dri2_display_get_configs(struct native_display *ndpy, int *num_configs)
dri2dpy->num_configs = count;
}
- configs = malloc(dri2dpy->num_configs * sizeof(*configs));
+ configs = MALLOC(dri2dpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < dri2dpy->num_configs; i++)
configs[i] = (const struct native_config *) &dri2dpy->configs[i];
@@ -699,13 +624,32 @@ dri2_display_is_pixmap_supported(struct native_display *ndpy,
return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
}
+static int
+dri2_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ /* DRI2GetBuffers use the native buffers */
+ val = TRUE;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
static void
dri2_display_destroy(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
if (dri2dpy->configs)
- free(dri2dpy->configs);
+ FREE(dri2dpy->configs);
if (dri2dpy->base.screen)
dri2dpy->base.screen->destroy(dri2dpy->base.screen);
@@ -719,7 +663,7 @@ dri2_display_destroy(struct native_display *ndpy)
XCloseDisplay(dri2dpy->dpy);
if (dri2dpy->api && dri2dpy->api->destroy)
dri2dpy->api->destroy(dri2dpy->api);
- free(dri2dpy);
+ FREE(dri2dpy);
}
static void
@@ -737,7 +681,10 @@ dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
return;
dri2surf = dri2_surface(nsurf);
+
dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
}
/**
@@ -748,7 +695,6 @@ dri2_display_init_screen(struct native_display *ndpy)
{
struct dri2_display *dri2dpy = dri2_display(ndpy);
const char *driver = dri2dpy->api->name;
- struct drm_create_screen_arg arg;
int fd;
if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
@@ -771,9 +717,7 @@ dri2_display_init_screen(struct native_display *ndpy)
if (fd < 0)
return FALSE;
- memset(&arg, 0, sizeof(arg));
- arg.mode = DRM_CREATE_NORMAL;
- dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, &arg);
+ dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd, NULL);
if (!dri2dpy->base.screen) {
_eglLog(_EGL_WARNING, "failed to create DRM screen");
return FALSE;
@@ -796,7 +740,9 @@ dri2_display_hash_table_compare(void *key1, void *key2)
}
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct dri2_display *dri2dpy;
@@ -804,6 +750,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!dri2dpy)
return NULL;
+ dri2dpy->event_handler = event_handler;
dri2dpy->api = api;
dri2dpy->dpy = dpy;
@@ -836,11 +783,11 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
}
dri2dpy->base.destroy = dri2_display_destroy;
+ dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface;
- dri2dpy->base.create_pbuffer_surface = dri2_display_create_pbuffer_surface;
return &dri2dpy->base;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 3add95d0aca..b6d51bbf9fb 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -14,18 +14,19 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
-#include <stdio.h>
#include <string.h>
#include "util/u_debug.h"
#include "util/u_memory.h"
+#include "util/u_string.h"
#include "state_tracker/drm_api.h"
#include "egllog.h"
@@ -40,8 +41,8 @@ static void
x11_probe_destroy(struct native_probe *nprobe)
{
if (nprobe->data)
- free(nprobe->data);
- free(nprobe);
+ FREE(nprobe->data);
+ FREE(nprobe);
}
struct native_probe *
@@ -61,7 +62,7 @@ native_create_probe(EGLNativeDisplayType dpy)
if (!xdpy) {
xdpy = XOpenDisplay(NULL);
if (!xdpy) {
- free(nprobe);
+ FREE(nprobe);
return NULL;
}
}
@@ -118,15 +119,16 @@ native_get_name(void)
api = drm_api_create();
if (api)
- snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
+ util_snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
else
- snprintf(x11_name, sizeof(x11_name), "X11");
+ util_snprintf(x11_name, sizeof(x11_name), "X11");
return x11_name;
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
boolean force_sw;
@@ -136,21 +138,14 @@ native_create_display(EGLNativeDisplayType dpy)
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
if (api && !force_sw) {
- ndpy = x11_create_dri2_display(dpy, api);
+ ndpy = x11_create_dri2_display(dpy, event_handler, api);
}
if (!ndpy) {
EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
- boolean use_shm;
-
- /*
- * XXX st/mesa calls pipe_screen::update_buffer in st_validate_state.
- * When SHM is used, there is a good chance that the shared memory
- * segment is detached before the softpipe tile cache is flushed.
- */
- use_shm = FALSE;
- _eglLog(level, "use software%s fallback", (use_shm) ? " (SHM)" : "");
- ndpy = x11_create_ximage_display(dpy, use_shm);
+
+ _eglLog(level, "use software fallback");
+ ndpy = x11_create_ximage_display(dpy, event_handler);
}
return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 622ddac5df6..1678403b459 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -14,12 +14,13 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#ifndef _NATIVE_X11_H_
@@ -29,9 +30,12 @@
#include "common/native.h"
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm);
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler);
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api);
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api);
#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index a8633b1501e..47f5423b67e 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -14,38 +14,35 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
-#include <assert.h>
-#include <sys/ipc.h>
-#include <sys/types.h>
-#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
-#include "softpipe/sp_winsys.h"
+#include "state_tracker/xlib_sw_winsys.h"
+#include "target-helpers/wrap_screen.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
#include "egllog.h"
-#include "sw_winsys.h"
#include "native_x11.h"
#include "x11_screen.h"
enum ximage_surface_type {
XIMAGE_SURFACE_TYPE_WINDOW,
XIMAGE_SURFACE_TYPE_PIXMAP,
- XIMAGE_SURFACE_TYPE_PBUFFER
};
struct ximage_display {
@@ -53,22 +50,18 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
+ struct native_event_handler *event_handler;
+
struct x11_screen *xscr;
int xscr_number;
- boolean use_xshm;
-
- struct pipe_winsys *winsys;
struct ximage_config *configs;
int num_configs;
};
struct ximage_buffer {
- XImage *ximage;
-
- struct pipe_texture *texture;
- XShmSegmentInfo *shm_info;
- boolean xshm_attached;
+ struct pipe_resource *texture;
+ struct xlib_drawable xdraw;
};
struct ximage_surface {
@@ -79,13 +72,13 @@ struct ximage_surface {
XVisualInfo visual;
struct ximage_display *xdpy;
- GC gc;
-
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 ximage_config {
@@ -118,19 +111,7 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xbuf = &xsurf->buffers[which];
- pipe_texture_reference(&xbuf->texture, NULL);
-
- if (xbuf->shm_info) {
- if (xbuf->xshm_attached)
- XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
- if (xbuf->shm_info->shmaddr != (void *) -1)
- shmdt(xbuf->shm_info->shmaddr);
- if (xbuf->shm_info->shmid != -1)
- shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
-
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->shmid = -1;
- }
+ pipe_resource_reference(&xbuf->texture, NULL);
}
static boolean
@@ -140,7 +121,7 @@ ximage_surface_alloc_buffer(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_texture templ;
+ struct pipe_resource templ;
/* free old data */
if (xbuf->texture)
@@ -152,42 +133,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
templ.width0 = xsurf->width;
templ.height0 = xsurf->height;
templ.depth0 = 1;
- templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
-
- if (xbuf->shm_info) {
- struct pipe_buffer *pbuf;
- unsigned stride, size;
- void *addr = NULL;
-
- stride = util_format_get_stride(xsurf->color_format, xsurf->width);
- /* alignment should depend on visual? */
- stride = align(stride, 4);
- size = stride * xsurf->height;
-
- /* create and attach shm object */
- xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
- if (xbuf->shm_info->shmid != -1) {
- xbuf->shm_info->shmaddr =
- shmat(xbuf->shm_info->shmid, NULL, 0);
- if (xbuf->shm_info->shmaddr != (void *) -1) {
- if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
- addr = xbuf->shm_info->shmaddr;
- xbuf->xshm_attached = TRUE;
- }
- }
- }
+ templ.bind = PIPE_BIND_RENDER_TARGET;
- if (addr) {
- pbuf = screen->user_buffer_create(screen, addr, size);
- if (pbuf) {
- xbuf->texture =
- screen->texture_blanket(screen, &templ, &stride, pbuf);
- pipe_buffer_reference(&pbuf, NULL);
- }
- }
+ 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;
}
- else {
- xbuf->texture = screen->texture_create(screen, &templ);
+ 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 */
@@ -211,10 +175,6 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
unsigned int w, h, border, depth;
boolean updated = FALSE;
- /* pbuffer has fixed geometry */
- if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
- return FALSE;
-
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
if (ok && (xsurf->width != w || xsurf->height != h)) {
@@ -228,6 +188,16 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
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.
@@ -257,18 +227,10 @@ ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
new_valid = 0x0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
if (native_attachment_mask_test(buffer_mask, att)) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
/* reallocate the texture */
if (!ximage_surface_alloc_buffer(&xsurf->base, att))
break;
- /* update ximage */
- if (xbuf->ximage) {
- xbuf->ximage->width = xsurf->width;
- xbuf->ximage->height = xsurf->height;
- }
-
new_valid |= (1 << att);
if (buffer_mask == new_valid)
break;
@@ -288,43 +250,23 @@ ximage_surface_draw_buffer(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_transfer *transfer;
+ struct pipe_surface *psurf;
- if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
- return TRUE;
+ assert(xsurf->drawable && xbuf->texture);
- assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+ psurf = xsurf->draw_surface;
+ if (!psurf || psurf->texture != xbuf->texture) {
+ pipe_surface_reference(&xsurf->draw_surface, NULL);
- transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!transfer)
- return FALSE;
+ psurf = screen->get_tex_surface(screen,
+ xbuf->texture, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
+ if (!psurf)
+ return FALSE;
- xbuf->ximage->bytes_per_line = transfer->stride;
- xbuf->ximage->data = screen->transfer_map(screen, transfer);
- if (!xbuf->ximage->data) {
- screen->tex_transfer_destroy(transfer);
- return FALSE;
+ xsurf->draw_surface = psurf;
}
-
- if (xbuf->shm_info)
- XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
- else
- XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
-
- xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, transfer);
-
- /*
- * softpipe allows the pipe transfer to be re-used, but we don't want to
- * rely on that behavior.
- */
- screen->tex_transfer_destroy(transfer);
-
- XSync(xsurf->xdpy->dpy, FALSE);
+ screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
return TRUE;
}
@@ -339,6 +281,7 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
NATIVE_ATTACHMENT_FRONT_LEFT);
/* force buffers to be updated in next validation call */
xsurf->server_stamp++;
+ ximage_surface_notify_invalid(&xsurf->base);
return ret;
}
@@ -351,27 +294,28 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
boolean ret;
/* display the back buffer first */
- ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
+ 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);
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
- /* skip swapping so that the front buffer is allocated only when needed */
- if (!xfront->texture)
- return ret;
-
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
+ /* skip swapping unless there is a front buffer */
+ if (xfront->texture) {
+ xtmp = *xfront;
+ *xfront = *xback;
+ *xback = xtmp;
+ }
return ret;
}
static boolean
ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
- unsigned int *seq_num, struct pipe_texture **textures,
+ unsigned int *seq_num, struct pipe_resource **textures,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
@@ -392,7 +336,7 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
struct ximage_buffer *xbuf = &xsurf->buffers[att];
textures[att] = NULL;
- pipe_texture_reference(&textures[att], xbuf->texture);
+ pipe_resource_reference(&textures[att], xbuf->texture);
}
}
}
@@ -419,19 +363,12 @@ ximage_surface_destroy(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
int i;
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
+ pipe_surface_reference(&xsurf->draw_surface, NULL);
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
ximage_surface_free_buffer(&xsurf->base, i);
- /* xbuf->shm_info is owned by xbuf->ximage? */
- if (xbuf->ximage) {
- XDestroyImage(xbuf->ximage);
- xbuf->ximage = NULL;
- }
- }
- if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
- XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
- free(xsurf);
+ FREE(xsurf);
}
static struct ximage_surface *
@@ -443,7 +380,6 @@ ximage_display_create_surface(struct native_display *ndpy,
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
- int i;
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
@@ -454,56 +390,10 @@ ximage_display_create_surface(struct native_display *ndpy,
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
- if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
- xsurf->drawable = drawable;
- xsurf->visual = *xconf->visual;
-
- xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
- if (!xsurf->gc) {
- free(xsurf);
- return NULL;
- }
-
- /* initialize the geometry */
- ximage_surface_update_buffers(&xsurf->base, 0x0);
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
-
- if (xdpy->use_xshm) {
- xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
- if (xbuf->shm_info) {
- /* initialize shm info */
- xbuf->shm_info->shmid = -1;
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->readOnly = TRUE;
-
- xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, NULL,
- xbuf->shm_info,
- 0, 0);
- }
- }
- else {
- xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 8, /* bitmap_pad */
- 0); /* bytes_per_line */
- }
-
- if (!xbuf->ximage) {
- XFreeGC(xdpy->dpy, xsurf->gc);
- free(xsurf);
- return NULL;
- }
- }
- }
+ xsurf->drawable = drawable;
+ xsurf->visual = *xconf->visual;
+ /* initialize the geometry */
+ ximage_surface_update_buffers(&xsurf->base, 0x0);
xsurf->base.destroy = ximage_surface_destroy;
xsurf->base.swap_buffers = ximage_surface_swap_buffers;
@@ -538,22 +428,6 @@ ximage_display_create_pixmap_surface(struct native_display *ndpy,
return (xsurf) ? &xsurf->base : NULL;
}
-static struct native_surface *
-ximage_display_create_pbuffer_surface(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height)
-{
- struct ximage_surface *xsurf;
-
- xsurf = ximage_display_create_surface(ndpy, XIMAGE_SURFACE_TYPE_PBUFFER,
- (Drawable) None, nconf);
- if (xsurf) {
- xsurf->width = width;
- xsurf->height = height;
- }
- return (xsurf) ? &xsurf->base : NULL;
-}
-
static enum pipe_format
choose_format(const XVisualInfo *vinfo)
{
@@ -587,7 +461,7 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
/* first time */
if (!xdpy->configs) {
const XVisualInfo *visuals;
- int num_visuals, count, j;
+ int num_visuals, count;
visuals = x11_screen_get_visuals(xdpy->xscr, &num_visuals);
if (!visuals)
@@ -597,57 +471,42 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
* Create two configs for each visual.
* One with depth/stencil buffer; one without
*/
- xdpy->configs = calloc(num_visuals * 2, sizeof(*xdpy->configs));
+ xdpy->configs = CALLOC(num_visuals * 2, sizeof(*xdpy->configs));
if (!xdpy->configs)
return NULL;
count = 0;
for (i = 0; i < num_visuals; i++) {
- for (j = 0; j < 2; j++) {
- struct ximage_config *xconf = &xdpy->configs[count];
- __GLcontextModes *mode = &xconf->base.mode;
-
- xconf->visual = &visuals[i];
- xconf->base.color_format = choose_format(xconf->visual);
- if (xconf->base.color_format == PIPE_FORMAT_NONE)
- continue;
-
- x11_screen_convert_visual(xdpy->xscr, xconf->visual, mode);
- /* support double buffer mode */
- mode->doubleBufferMode = TRUE;
-
- xconf->base.depth_format = PIPE_FORMAT_NONE;
- xconf->base.stencil_format = PIPE_FORMAT_NONE;
- /* create the second config with depth/stencil buffer */
- if (j == 1) {
- xconf->base.depth_format = PIPE_FORMAT_Z24S8_UNORM;
- xconf->base.stencil_format = PIPE_FORMAT_Z24S8_UNORM;
- mode->depthBits = 24;
- mode->stencilBits = 8;
- mode->haveDepthBuffer = TRUE;
- mode->haveStencilBuffer = TRUE;
- }
-
- mode->maxPbufferWidth = 4096;
- mode->maxPbufferHeight = 4096;
- mode->maxPbufferPixels = 4096 * 4096;
- mode->drawableType =
- GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
- mode->swapMethod = GLX_SWAP_EXCHANGE_OML;
-
- if (mode->alphaBits)
- mode->bindToTextureRgba = TRUE;
- else
- mode->bindToTextureRgb = TRUE;
-
- count++;
- }
+ struct ximage_config *xconf = &xdpy->configs[count];
+
+ xconf->visual = &visuals[i];
+ xconf->base.color_format = choose_format(xconf->visual);
+ if (xconf->base.color_format == PIPE_FORMAT_NONE)
+ continue;
+
+ xconf->base.buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+
+ xconf->base.window_bit = TRUE;
+ xconf->base.pixmap_bit = TRUE;
+
+ xconf->base.native_visual_id = xconf->visual->visualid;
+#if defined(__cplusplus) || defined(c_plusplus)
+ xconf->base.native_visual_type = xconf->visual->c_class;
+#else
+ xconf->base.native_visual_type = xconf->visual->class;
+#endif
+
+ xconf->base.slow_config = TRUE;
+
+ count++;
}
xdpy->num_configs = count;
}
- configs = malloc(xdpy->num_configs * sizeof(*configs));
+ configs = MALLOC(xdpy->num_configs * sizeof(*configs));
if (configs) {
for (i = 0; i < xdpy->num_configs; i++)
configs[i] = (const struct native_config *) &xdpy->configs[i];
@@ -685,25 +544,98 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy,
return (fmt == nconf->color_format);
}
+static int
+ximage_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
ximage_display_destroy(struct native_display *ndpy)
{
struct ximage_display *xdpy = ximage_display(ndpy);
if (xdpy->configs)
- free(xdpy->configs);
+ FREE(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
- free(xdpy->winsys);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
XCloseDisplay(xdpy->dpy);
- free(xdpy);
+ FREE(xdpy);
+}
+
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try.
+ *
+ * Long term, want to avoid having global #defines for things like
+ * GALLIUM_LLVMPIPE, GALLIUM_CELL, etc. Scons already eliminates
+ * those #defines, so things that are painful for it now are likely to
+ * be painful for other build systems in the future.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( display );
+ if (winsys == NULL)
+ return NULL;
+
+ /* Create a software rasterizer on top of that winsys. Use
+ * llvmpipe if it is available.
+ */
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
}
+
+
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
@@ -715,32 +647,30 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
if (!xdpy->dpy) {
xdpy->dpy = XOpenDisplay(NULL);
if (!xdpy->dpy) {
- free(xdpy);
+ FREE(xdpy);
return NULL;
}
xdpy->own_dpy = TRUE;
}
+ xdpy->event_handler = event_handler;
+
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
- free(xdpy);
+ FREE(xdpy);
return NULL;
}
- xdpy->use_xshm =
- (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
-
- xdpy->winsys = create_sw_winsys();
- xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+ xdpy->base.screen = swrast_xlib_create_screen(xdpy->dpy);
xdpy->base.destroy = ximage_display_destroy;
+ xdpy->base.get_param = ximage_display_get_param;
xdpy->base.get_configs = ximage_display_get_configs;
xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
xdpy->base.create_window_surface = ximage_display_create_window_surface;
xdpy->base.create_pixmap_surface = ximage_display_create_pixmap_surface;
- xdpy->base.create_pbuffer_surface = ximage_display_create_pbuffer_surface;
return &xdpy->base;
}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
deleted file mode 100644
index 33328aadf26..00000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * Totally software-based winsys layer.
- * Note that the one winsys function that we can't implement here
- * is flush_frontbuffer().
- * Whoever uses this code will have to provide that.
- *
- * Authors: Brian Paul
- */
-
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "sw_winsys.h"
-
-
-
-/** Subclass of pipe_winsys */
-struct sw_pipe_winsys
-{
- struct pipe_winsys Base;
- /* no extra fields for now */
-};
-
-
-/** subclass of pipe_buffer */
-struct sw_pipe_buffer
-{
- struct pipe_buffer Base;
- boolean UserBuffer; /** Is this a user-space buffer? */
- void *Data;
- void *Mapped;
-};
-
-
-/** cast wrapper */
-static INLINE struct sw_pipe_buffer *
-sw_pipe_buffer(struct pipe_buffer *b)
-{
- return (struct sw_pipe_buffer *) b;
-}
-
-
-static const char *
-get_name(struct pipe_winsys *pws)
-{
- return "software";
-}
-
-
-/** Create new pipe_buffer and allocate storage of given size */
-static struct pipe_buffer *
-buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.alignment = alignment;
- buffer->Base.usage = usage;
- buffer->Base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->Data = align_malloc(size, MAX2(alignment, 16));
-
- return &buffer->Base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.size = bytes;
- buffer->UserBuffer = TRUE;
- buffer->Data = ptr;
-
- return &buffer->Base;
-}
-
-
-static void *
-buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = buffer->Data;
- return buffer->Mapped;
-}
-
-
-static void
-buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = NULL;
-}
-
-
-static void
-buffer_destroy(struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
-
- if (buffer->Data && !buffer->UserBuffer) {
- align_free(buffer->Data);
- buffer->Data = NULL;
- }
-
- free(buffer);
-}
-
-
-static struct pipe_buffer *
-surface_buffer_create(struct pipe_winsys *winsys,
- unsigned width, unsigned height,
- enum pipe_format format,
- unsigned usage,
- unsigned tex_usage,
- unsigned *stride)
-{
- const unsigned alignment = 64;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- /* no-op */
-}
-
-
-static int
-fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-static int
-fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-/**
- * Create/return a new pipe_winsys object.
- */
-struct pipe_winsys *
-create_sw_winsys(void)
-{
- struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
- if (!ws)
- return NULL;
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->Base.buffer_create = buffer_create;
- ws->Base.user_buffer_create = user_buffer_create;
- ws->Base.buffer_map = buffer_map;
- ws->Base.buffer_unmap = buffer_unmap;
- ws->Base.buffer_destroy = buffer_destroy;
-
- ws->Base.surface_buffer_create = surface_buffer_create;
-
- ws->Base.fence_reference = fence_reference;
- ws->Base.fence_signalled = fence_signalled;
- ws->Base.fence_finish = fence_finish;
-
- ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
-
- ws->Base.get_name = get_name;
-
- return &ws->Base;
-}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h
deleted file mode 100644
index f96c5a14b0a..00000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
-
-
-struct pipe_winsys;
-
-
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index f4096114844..6bdff26ec08 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -14,24 +14,24 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <xf86drm.h>
#include <X11/Xlibint.h>
#include <X11/extensions/XShm.h>
+
#include "util/u_memory.h"
-#include "util/u_math.h"
-#include "util/u_format.h"
-#include "xf86drm.h"
#include "egllog.h"
#include "x11_screen.h"
@@ -109,7 +109,7 @@ x11_screen_destroy(struct x11_screen *xscr)
if (xscr->visuals)
XFree(xscr->visuals);
- free(xscr);
+ FREE(xscr);
}
static boolean
@@ -176,63 +176,6 @@ x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
return xscr->visuals;
}
-void
-x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
- __GLcontextModes *mode)
-{
- int r, g, b, a;
- int visual_type;
-
- r = util_bitcount(visual->red_mask);
- g = util_bitcount(visual->green_mask);
- b = util_bitcount(visual->blue_mask);
- a = visual->depth - (r + g + b);
-#if defined(__cplusplus) || defined(c_plusplus)
- visual_type = visual->c_class;
-#else
- visual_type = visual->class;
-#endif
-
- /* convert to GLX visual type */
- switch (visual_type) {
- case TrueColor:
- visual_type = GLX_TRUE_COLOR;
- break;
- case DirectColor:
- visual_type = GLX_DIRECT_COLOR;
- break;
- case PseudoColor:
- visual_type = GLX_PSEUDO_COLOR;
- break;
- case StaticColor:
- visual_type = GLX_STATIC_COLOR;
- break;
- case GrayScale:
- visual_type = GLX_GRAY_SCALE;
- break;
- case StaticGray:
- visual_type = GLX_STATIC_GRAY;
- break;
- default:
- visual_type = GLX_NONE;
- break;
- }
-
- mode->rgbBits = r + g + b + a;
- mode->redBits = r;
- mode->greenBits = g;
- mode->blueBits = b;
- mode->alphaBits = a;
- mode->visualID = visual->visualid;
- mode->visualType = visual_type;
-
- /* sane defaults */
- mode->renderType = GLX_RGBA_BIT;
- mode->rgbMode = TRUE;
- mode->visualRating = GLX_SLOW_CONFIG;
- mode->xRenderable = TRUE;
-}
-
/**
* Return the GLX fbconfigs.
*/
@@ -435,7 +378,7 @@ x11_context_modes_create(unsigned count)
next = &base;
for (i = 0; i < count; i++) {
- *next = (__GLcontextModes *) calloc(1, size);
+ *next = (__GLcontextModes *) CALLOC(1, size);
if (*next == NULL) {
x11_context_modes_destroy(base);
base = NULL;
@@ -455,7 +398,7 @@ x11_context_modes_destroy(__GLcontextModes *modes)
{
while (modes != NULL) {
__GLcontextModes *next = modes->next;
- free(modes);
+ FREE(modes);
modes = next;
}
}
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h
index 37e8d5a40e6..a3c5ee1491e 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -14,12 +14,13 @@
* 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,
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 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.
*/
#ifndef _X11_SCREEN_H_
@@ -28,6 +29,8 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/dri2tokens.h>
+#include "GL/gl.h" /* for GL types needed by __GLcontextModes */
+#include "GL/internal/glcore.h" /* for __GLcontextModes */
#include "pipe/p_compiler.h"
#include "common/native.h"
@@ -64,10 +67,6 @@ x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
const XVisualInfo *
x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
-void
-x11_screen_convert_visual(struct x11_screen *xscr, const XVisualInfo *visual,
- __GLcontextModes *mode);
-
const __GLcontextModes *
x11_screen_get_glx_configs(struct x11_screen *xscr);