summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/Makefile6
-rw-r--r--src/gallium/state_trackers/dri/SConscript4
-rw-r--r--src/gallium/state_trackers/dri/dri1.c526
-rw-r--r--src/gallium/state_trackers/dri/dri1.h59
-rw-r--r--src/gallium/state_trackers/dri/dri1_helper.c129
-rw-r--r--src/gallium/state_trackers/dri/dri1_helper.h61
-rw-r--r--src/gallium/state_trackers/dri/dri2.c413
-rw-r--r--src/gallium/state_trackers/dri/dri2.h (renamed from src/gallium/state_trackers/egl/x11/sw_winsys.h)36
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c111
-rw-r--r--src/gallium/state_trackers/dri/dri_context.h36
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c685
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h45
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c104
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c284
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h48
-rw-r--r--src/gallium/state_trackers/dri/dri_st_api.c263
-rw-r--r--src/gallium/state_trackers/dri/dri_st_api.h55
-rw-r--r--src/gallium/state_trackers/dri/dri_wrapper.h10
-rw-r--r--src/gallium/state_trackers/dri/drisw.c318
-rw-r--r--src/gallium/state_trackers/dri/drisw.h54
-rw-r--r--src/gallium/state_trackers/drisw/Makefile26
l---------src/gallium/state_trackers/drisw/dri1_helper.c1
l---------src/gallium/state_trackers/drisw/dri_context.c1
l---------src/gallium/state_trackers/drisw/dri_drawable.c1
l---------src/gallium/state_trackers/drisw/dri_extensions.c1
l---------src/gallium/state_trackers/drisw/dri_screen.c1
l---------src/gallium/state_trackers/drisw/dri_st_api.c1
l---------src/gallium/state_trackers/drisw/drisw.c1
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c596
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h25
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c227
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.h (renamed from src/gallium/state_trackers/egl/common/egl_st.h)86
-rw-r--r--src/gallium/state_trackers/egl/common/egl_st.c131
-rw-r--r--src/gallium/state_trackers/egl/common/native.h3
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h20
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c14
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c9
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c13
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h3
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c278
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/es/Makefile2
-rw-r--r--src/gallium/state_trackers/es/st_es1.c7
-rw-r--r--src/gallium/state_trackers/es/st_es2.c7
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile6
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript3
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c7
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c410
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h73
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_public.h (renamed from src/gallium/state_trackers/glx/xlib/xm_winsys.h)24
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.c332
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_st.h51
-rw-r--r--src/gallium/state_trackers/python/SConscript34
-rw-r--r--src/gallium/state_trackers/python/gallium.i1
-rw-r--r--src/gallium/state_trackers/python/p_context.i41
-rw-r--r--src/gallium/state_trackers/python/st_device.c84
-rw-r--r--src/gallium/state_trackers/python/st_device.h13
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c16
-rw-r--r--src/gallium/state_trackers/python/st_llvmpipe_winsys.c141
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c55
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h14
-rw-r--r--src/gallium/state_trackers/vega/Makefile3
-rw-r--r--src/gallium/state_trackers/vega/api_context.c3
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c87
-rw-r--r--src/gallium/state_trackers/vega/api_images.c7
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c6
-rw-r--r--src/gallium/state_trackers/vega/image.c54
-rw-r--r--src/gallium/state_trackers/vega/image.h4
-rw-r--r--src/gallium/state_trackers/vega/mask.c66
-rw-r--r--src/gallium/state_trackers/vega/mask.h2
-rw-r--r--src/gallium/state_trackers/vega/paint.c68
-rw-r--r--src/gallium/state_trackers/vega/paint.h2
-rw-r--r--src/gallium/state_trackers/vega/polygon.c4
-rw-r--r--src/gallium/state_trackers/vega/renderer.c42
-rw-r--r--src/gallium/state_trackers/vega/renderer.h3
-rw-r--r--src/gallium/state_trackers/vega/shader.c34
-rw-r--r--src/gallium/state_trackers/vega/st_inlines.h9
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c27
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h13
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.c373
-rw-r--r--src/gallium/state_trackers/vega/vg_manager.h40
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c64
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h3
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c14
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c19
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c37
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c29
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c15
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c50
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c34
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c88
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c2
98 files changed, 4467 insertions, 3010 deletions
diff --git a/src/gallium/state_trackers/dri/Makefile b/src/gallium/state_trackers/dri/Makefile
index ef8f19709a..f1a54e80b6 100644
--- a/src/gallium/state_trackers/dri/Makefile
+++ b/src/gallium/state_trackers/dri/Makefile
@@ -15,7 +15,11 @@ C_SOURCES = \
dri_context.c \
dri_screen.c \
dri_drawable.c \
- dri_extensions.c
+ dri_extensions.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ dri1.c \
+ dri2.c
# $(TOP)/src/mesa/drivers/dri/common/utils.c \
$(TOP)/src/mesa/drivers/dri/common/vblank.c \
diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript
index ce2c273597..2ca9f42068 100644
--- a/src/gallium/state_trackers/dri/SConscript
+++ b/src/gallium/state_trackers/dri/SConscript
@@ -18,6 +18,10 @@ if env['dri']:
'dri_drawable.c',
'dri_extensions.c',
'dri_screen.c',
+ 'dri_st_api.c',
+ 'dri1_helper.c',
+ 'dri1.c',
+ 'dri2.c',
]
)
Export('st_dri')
diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c
new file mode 100644
index 0000000000..98bdb2936a
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri1.c
@@ -0,0 +1,526 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * 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 VMWARE 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <keithw@vmware.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+/* XXX DRI1 is untested after the switch to st_api.h */
+
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/dri1_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#include "dri1.h"
+
+static INLINE void
+dri1_lock(struct dri_context *ctx)
+{
+ drm_context_t hw_context = ctx->cPriv->hHWContext;
+ char ret = 0;
+
+ DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
+ if (ret) {
+ drmGetLock(ctx->sPriv->fd, hw_context, 0);
+ ctx->stLostLock = TRUE;
+ ctx->wsLostLock = TRUE;
+ }
+ ctx->isLocked = TRUE;
+}
+
+static INLINE void
+dri1_unlock(struct dri_context *ctx)
+{
+ ctx->isLocked = FALSE;
+ DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
+}
+
+static void
+dri1_update_drawables_locked(struct dri_context *ctx,
+ __DRIdrawable * driDrawPriv,
+ __DRIdrawable * driReadPriv)
+{
+ if (ctx->stLostLock) {
+ ctx->stLostLock = FALSE;
+ if (driDrawPriv == driReadPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
+ else
+ DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
+ driReadPriv);
+ }
+}
+
+/**
+ * This ensures all contexts which bind to a drawable pick up the
+ * drawable change and signal new buffer state.
+ */
+static void
+dri1_propagate_drawable_change(struct dri_context *ctx)
+{
+ __DRIdrawable *dPriv = ctx->dPriv;
+ __DRIdrawable *rPriv = ctx->rPriv;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_drawable *read = dri_drawable(rPriv);
+ boolean flushed = FALSE;
+
+ if (dPriv && draw->texture_stamp != dPriv->lastStamp) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ flushed = TRUE;
+ ctx->st->notify_invalid_framebuffer(ctx->st, draw->stfb);
+ }
+
+ if (rPriv && dPriv != rPriv && read->texture_stamp != rPriv->lastStamp) {
+ if (!flushed)
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->notify_invalid_framebuffer(ctx->st, read->stfb);
+ }
+}
+
+static INLINE boolean
+dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+static void
+dri1_swap_copy(struct pipe_context *pipe,
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
+{
+ struct drm_clip_rect clip;
+ struct drm_clip_rect *cur;
+ int i;
+
+ cur = dPriv->pClipRects;
+
+ for (i = 0; i < dPriv->numClipRects; ++i) {
+ if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
+ if (pipe->surface_copy) {
+ pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ } else {
+ util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ }
+ }
+ }
+}
+
+static void
+dri1_present_texture_locked(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_context *pipe;
+ struct pipe_surface *psurf;
+ struct drm_clip_rect bbox;
+ boolean visible = TRUE;
+
+ *fence = NULL;
+
+ bbox.x1 = 0;
+ bbox.x2 = ptex->width0;
+ bbox.y1 = 0;
+ bbox.y2 = ptex->height0;
+
+ if (sub_box)
+ visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
+ if (!visible)
+ return;
+
+ pipe = dri1_get_pipe_context(screen);
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!pipe || !psurf)
+ return;
+
+ if (__dri1_api_hooks->present_locked) {
+ __dri1_api_hooks->present_locked(pipe, psurf,
+ dPriv->pClipRects, dPriv->numClipRects,
+ dPriv->x, dPriv->y, &bbox, fence);
+ } else if (__dri1_api_hooks->front_srf_locked) {
+ struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
+
+ if (front)
+ dri1_swap_copy(pipe, front, psurf, dPriv, &bbox);
+
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, fence);
+ }
+}
+
+static void
+dri1_copy_to_front(struct dri_context *ctx,
+ struct pipe_texture *ptex,
+ __DRIdrawable * dPriv,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ boolean save_lost_lock;
+
+ dri1_lock(ctx);
+ save_lost_lock = ctx->stLostLock;
+ dri1_update_drawables_locked(ctx, dPriv, dPriv);
+
+ dri1_present_texture_locked(dPriv, ptex, sub_box, fence);
+
+ ctx->stLostLock = save_lost_lock;
+
+ /**
+ * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
+ */
+
+ if (!sub_box)
+ dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
+
+ dri1_unlock(ctx);
+ dri1_propagate_drawable_change(ctx);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *draw,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[statt];
+ if (ptex) {
+ dri1_copy_to_front(ctx, ptex, ctx->dPriv, NULL, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+
+ /**
+ * FIXME: Do we need swap throttling here?
+ */
+}
+
+void
+dri1_swap_buffers(__DRIdrawable * dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(draw->sPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct pipe_fence_handle *fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return; /* For now */
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ fence = dri1_swap_fences_pop_front(draw);
+ if (fence) {
+ (void)pipe_screen->fence_finish(pipe_screen, fence, 0);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+ dri1_copy_to_front(ctx, ptex, dPriv, NULL, &fence);
+ dri1_swap_fences_push_back(draw, fence);
+ pipe_screen->fence_reference(pipe_screen, &fence, NULL);
+ }
+}
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_screen *screen = dri_screen(dPriv->driScreenPriv);
+ struct pipe_screen *pipe_screen = screen->pipe_screen;
+ struct drm_clip_rect sub_bbox;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct pipe_fence_handle *dummy_fence;
+ struct pipe_texture *ptex;
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!ctx)
+ return;
+
+ sub_bbox.x1 = x;
+ sub_bbox.x2 = x + w;
+ sub_bbox.y1 = y;
+ sub_bbox.y2 = y + h;
+
+ ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT];
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ dri1_copy_to_front(ctx, ptex, dPriv, &sub_bbox, &dummy_fence);
+ pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ */
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+static void
+st_dri_lock(struct pipe_context *pipe)
+{
+ dri1_lock((struct dri_context *)pipe->priv);
+}
+
+static void
+st_dri_unlock(struct pipe_context *pipe)
+{
+ dri1_unlock((struct dri_context *)pipe->priv);
+}
+
+static boolean
+st_dri_is_locked(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->isLocked;
+}
+
+static boolean
+st_dri_lost_lock(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->wsLostLock;
+}
+
+static void
+st_dri_clear_lost_lock(struct pipe_context *pipe)
+{
+ ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
+}
+
+static struct dri1_api_lock_funcs dri1_lf = {
+ .lock = st_dri_lock,
+ .unlock = st_dri_unlock,
+ .is_locked = st_dri_is_locked,
+ .is_lock_lost = st_dri_lost_lock,
+ .clear_lost_lock = st_dri_clear_lost_lock
+};
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *dri1_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
+
+struct dri1_api *__dri1_api_hooks = NULL;
+
+static INLINE void
+dri1_copy_version(struct dri1_api_version *dst,
+ const struct __DRIversionRec *src)
+{
+ dst->major = src->major;
+ dst->minor = src->minor;
+ dst->patch_level = src->patch;
+}
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv)
+{
+ struct dri_screen *screen;
+ const __DRIconfig **configs;
+ struct dri1_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+ screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri1_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRI1;
+ arg.lf = &dri1_lf;
+ arg.ddx_info = sPriv->pDevPriv;
+ arg.ddx_info_size = sPriv->devPrivSize;
+ arg.sarea = sPriv->pSAREA;
+ dri1_copy_version(&arg.ddx_version, &sPriv->ddx_version);
+ dri1_copy_version(&arg.dri_version, &sPriv->dri_version);
+ dri1_copy_version(&arg.drm_version, &sPriv->drm_version);
+ arg.api = NULL;
+
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
+
+ if (!screen->pipe_screen || !arg.api) {
+ debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
+ goto out_no_screen;
+ }
+
+ __dri1_api_hooks = arg.api;
+
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ /**
+ * FIXME: If the driver supports format conversion swapbuffer blits, we might
+ * want to support other color bit depths than the server is currently
+ * using.
+ */
+
+ configs = dri_fill_in_modes(screen, sPriv->fbBPP);
+ if (!configs)
+ goto out_no_configs;
+
+ return configs;
+ out_no_configs:
+ screen->pipe_screen->destroy(screen->pipe_screen);
+ out_no_screen:
+ FREE(screen);
+ return NULL;
+}
diff --git a/src/gallium/state_trackers/dri/dri1.h b/src/gallium/state_trackers/dri/dri1.h
new file mode 100644
index 0000000000..f7441f98ab
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri1.h
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * 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 VMWARE 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <keithw@vmware.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+#ifndef DRI1_H
+#define DRI1_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+extern struct dri1_api *__dri1_api_hooks;
+
+const __DRIconfig **
+dri1_init_screen(__DRIscreen * sPriv);
+
+void
+dri1_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+dri1_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void dri1_swap_buffers(__DRIdrawable * dPriv);
+
+void
+dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
+
+#endif /* DRI1_H */
diff --git a/src/gallium/state_trackers/dri/dri1_helper.c b/src/gallium/state_trackers/dri/dri1_helper.c
new file mode 100644
index 0000000000..7eeb868d42
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri1_helper.c
@@ -0,0 +1,129 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * 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 VMWARE 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.
+ *
+ **************************************************************************/
+/*
+ * Management of pipe objects (surface / pipe / fences) used by DRI1 and DRISW.
+ *
+ * Author: Keith Whitwell <keithw@vmware.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri1_helper.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (draw->cur_fences >= draw->desired_fences) {
+ screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
+ screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
+ --draw->cur_fences;
+ draw->tail &= DRI_SWAP_FENCES_MASK;
+ }
+ return fence;
+}
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+
+ if (!fence)
+ return;
+
+ if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
+ draw->cur_fences++;
+ screen->fence_reference(screen, &draw->swap_fences[draw->head++],
+ fence);
+ draw->head &= DRI_SWAP_FENCES_MASK;
+ }
+}
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable)
+{
+ struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence;
+
+ while (drawable->cur_fences) {
+ fence = dri1_swap_fences_pop_front(drawable);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+}
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex)
+{
+ struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->pipe_screen;
+ struct pipe_surface *psurf = drawable->dri1_surface;
+
+ if (!psurf || psurf->texture != ptex) {
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+
+ drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen,
+ ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+
+ psurf = drawable->dri1_surface;
+ }
+
+ return psurf;
+}
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable)
+{
+ pipe_surface_reference(&drawable->dri1_surface, NULL);
+}
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen)
+{
+ struct pipe_context *pipe = screen->dri1_pipe;
+
+ if (!pipe) {
+ screen->dri1_pipe =
+ screen->pipe_screen->context_create(screen->pipe_screen, NULL);
+ pipe = screen->dri1_pipe;
+ }
+
+ return pipe;
+}
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen)
+{
+ if (screen->dri1_pipe)
+ screen->dri1_pipe->destroy(screen->dri1_pipe);
+}
diff --git a/src/gallium/state_trackers/dri/dri1_helper.h b/src/gallium/state_trackers/dri/dri1_helper.h
new file mode 100644
index 0000000000..3254b7ff87
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri1_helper.h
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * 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 VMWARE 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.
+ *
+ **************************************************************************/
+/*
+ * Author: Keith Whitwell <keithw@vmware.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+#ifndef DRI1_HELPER_H
+#define DRI1_HELPER_H
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+struct pipe_fence_handle *
+dri1_swap_fences_pop_front(struct dri_drawable *draw);
+
+void
+dri1_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence);
+
+void
+dri1_swap_fences_clear(struct dri_drawable *drawable);
+
+struct pipe_surface *
+dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex);
+
+void
+dri1_destroy_pipe_surface(struct dri_drawable *drawable);
+
+struct pipe_context *
+dri1_get_pipe_context(struct dri_screen *screen);
+
+void
+dri1_destroy_pipe_context(struct dri_screen *screen);
+
+#endif /* DRI1_HELPER_H */
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
new file mode 100644
index 0000000000..108b18e9d3
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -0,0 +1,413 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Keith Whitwell <keithw@vmware.com>
+ * Jakob Bornecrantz <wallbraker@gmail.com>
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri2.h"
+
+/**
+ * DRI2 flush extension.
+ */
+static void
+dri2_flush_drawable(__DRIdrawable *draw)
+{
+}
+
+static void
+dri2_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_context *ctx = dri_context(dPriv->driContextPriv);
+
+ dri2InvalidateDrawable(dPriv);
+ drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
+
+ if (ctx)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static const __DRI2flushExtension dri2FlushExtension = {
+ { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
+ dri2_flush_drawable,
+ dri2_invalidate_drawable,
+};
+
+/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+static void
+dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_context(pDRICtx);
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *pt;
+
+ dri_st_framebuffer_validate_att(drawable->stfb, ST_ATTACHMENT_FRONT_LEFT);
+
+ pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];
+
+ if (pt) {
+ ctx->st->teximage(ctx->st,
+ (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
+ 0, drawable->stvis.color_format, pt, FALSE);
+ }
+}
+
+static void
+dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension dri2TexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri2_set_tex_buffer,
+ dri2_set_tex_buffer2,
+};
+
+/**
+ * Get the format of an attachment.
+ */
+static INLINE enum pipe_format
+dri2_drawable_get_format(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ enum pipe_format format;
+
+ switch (statt) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ return format;
+}
+
+/**
+ * Retrieve __DRIbuffer from the DRI loader.
+ */
+static __DRIbuffer *
+dri2_drawable_get_buffers(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned *count)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+ boolean with_format;
+ __DRIbuffer *buffers;
+ int num_buffers;
+ unsigned attachments[10];
+ unsigned num_attachments, i;
+
+ assert(loader);
+ with_format = dri_with_format(drawable->sPriv);
+
+ num_attachments = 0;
+
+ /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
+ if (!with_format)
+ attachments[num_attachments++] = __DRI_BUFFER_FRONT_LEFT;
+
+ for (i = 0; i < *count; i++) {
+ enum pipe_format format;
+ int att, bpp;
+
+ format = dri2_drawable_get_format(drawable, statts[i]);
+ if (format == PIPE_FORMAT_NONE)
+ continue;
+
+ switch (statts[i]) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ /* already added */
+ if (!with_format)
+ continue;
+ att = __DRI_BUFFER_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_LEFT:
+ att = __DRI_BUFFER_BACK_LEFT;
+ break;
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ att = __DRI_BUFFER_FRONT_RIGHT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ att = __DRI_BUFFER_BACK_RIGHT;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ att = __DRI_BUFFER_DEPTH_STENCIL;
+ break;
+ default:
+ att = -1;
+ break;
+ }
+
+ bpp = util_format_get_blocksizebits(format);
+
+ if (att >= 0) {
+ attachments[num_attachments++] = att;
+ if (with_format) {
+ attachments[num_attachments++] = bpp;
+ }
+ }
+ }
+
+ if (with_format) {
+ num_attachments /= 2;
+ buffers = loader->getBuffersWithFormat(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+ else {
+ buffers = loader->getBuffers(dri_drawable,
+ &dri_drawable->w, &dri_drawable->h,
+ attachments, num_attachments,
+ &num_buffers, dri_drawable->loaderPrivate);
+ }
+
+ if (buffers) {
+ /* set one cliprect to cover the whole dri_drawable */
+ dri_drawable->x = 0;
+ dri_drawable->y = 0;
+ dri_drawable->backX = 0;
+ dri_drawable->backY = 0;
+ dri_drawable->numClipRects = 1;
+ dri_drawable->pClipRects[0].x1 = 0;
+ dri_drawable->pClipRects[0].y1 = 0;
+ dri_drawable->pClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pClipRects[0].y2 = dri_drawable->h;
+ dri_drawable->numBackClipRects = 1;
+ dri_drawable->pBackClipRects[0].x1 = 0;
+ dri_drawable->pBackClipRects[0].y1 = 0;
+ dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+
+ *count = num_buffers;
+ }
+
+ return buffers;
+}
+
+/**
+ * Process __DRIbuffer and convert them into pipe_textures.
+ */
+static void
+dri2_drawable_process_buffers(struct dri_drawable *drawable,
+ __DRIbuffer *buffers, unsigned count)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct pipe_texture templ;
+ struct winsys_handle whandle;
+ boolean have_depth = FALSE;
+ unsigned i;
+
+ if (drawable->old_num == count &&
+ drawable->old_w == dri_drawable->w &&
+ drawable->old_h == dri_drawable->h &&
+ memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0)
+ return;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ memset(&templ, 0, sizeof(templ));
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = dri_drawable->w;
+ templ.height0 = dri_drawable->h;
+ templ.depth0 = 1;
+
+ memset(&whandle, 0, sizeof(whandle));
+
+ for (i = 0; i < count; i++) {
+ __DRIbuffer *buf = &buffers[i];
+ enum st_attachment_type statt;
+ enum pipe_format format;
+
+ switch (buf->attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ if (!screen->auto_fake_front) {
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+ /* fallthrough */
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case __DRI_BUFFER_BACK_LEFT:
+ statt = ST_ATTACHMENT_BACK_LEFT;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_STENCIL:
+ /* use only the first depth/stencil buffer */
+ if (!have_depth) {
+ have_depth = TRUE;
+ statt = ST_ATTACHMENT_DEPTH_STENCIL;
+ }
+ else {
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ break;
+ default:
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+
+ format = dri2_drawable_get_format(drawable, statt);
+ if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE)
+ continue;
+
+ templ.format = format;
+ whandle.handle = buf->name;
+ whandle.stride = buf->pitch;
+
+ drawable->textures[statt] =
+ screen->pipe_screen->texture_from_handle(screen->pipe_screen,
+ &templ, &whandle);
+ }
+
+ drawable->old_num = count;
+ drawable->old_w = dri_drawable->w;
+ drawable->old_h = dri_drawable->h;
+ memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
+}
+
+/*
+ * Backend functions for st_framebuffer interface.
+ */
+
+void
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count)
+{
+ __DRIbuffer *buffers;
+ unsigned num_buffers = count;
+
+ buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers);
+ dri2_drawable_process_buffers(drawable, buffers, num_buffers);
+}
+
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader;
+
+ if (loader->flushFrontBuffer == NULL)
+ return;
+
+ if (statt == ST_ATTACHMENT_FRONT_LEFT) {
+ loader->flushFrontBuffer(dri_drawable, dri_drawable->loaderPrivate);
+ }
+}
+
+/*
+ * Backend function init_screen.
+ */
+
+static const __DRIextension *dri_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ &dri2TexBufferExtension.base,
+ &dri2FlushExtension.base,
+ NULL
+};
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ *
+ * Returns the __GLcontextModes supported by this driver.
+ */
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv)
+{
+ struct dri_screen *screen;
+ struct drm_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri_screen_extensions;
+ arg.mode = DRM_CREATE_NORMAL;
+
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg);
+ if (!screen->pipe_screen) {
+ debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
+ goto fail;
+ }
+
+ screen->smapi = dri_create_st_manager(screen);
+ if (!screen->smapi)
+ goto fail;
+
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ screen->auto_fake_front = dri_with_format(sPriv);
+
+ return dri_fill_in_modes(screen, 32);
+fail:
+ dri_destroy_screen(sPriv);
+ return NULL;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/state_trackers/dri/dri2.h
index f96c5a14b0..379963431f 100644
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.h
+++ b/src/gallium/state_trackers/dri/dri2.h
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2009, VMware, Inc.
* 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
@@ -10,31 +10,37 @@
* 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
+ * IN NO EVENT SHALL VMWARE 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 DRI2_H
+#define DRI2_H
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
+#include "dri_drawable.h"
+#include "dri_wrapper.h"
+const __DRIconfig **
+dri2_init_screen(__DRIscreen * sPriv);
-struct pipe_winsys;
+void
+dri2_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+void
+dri2_allocate_textures(struct dri_drawable *drawable,
+ const enum st_attachment_type *statts,
+ unsigned count);
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
+#endif /* DRI2_H */
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 908cef454e..34d9a932ea 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -30,26 +30,23 @@
*/
#include "dri_screen.h"
-
#include "dri_drawable.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "pipe/p_context.h"
-
#include "dri_context.h"
+#include "dri_st_api.h"
+#include "pipe/p_context.h"
#include "util/u_memory.h"
GLboolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * cPriv, void *sharedContextPrivate)
{
+ struct st_api *stapi = dri_get_st_api();
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
- struct st_context *st_share = NULL;
+ struct st_context_iface *st_share = NULL;
+ struct st_visual stvis;
if (sharedContextPrivate) {
st_share = ((struct dri_context *)sharedContextPrivate)->st;
@@ -63,21 +60,15 @@ dri_create_context(const __GLcontextModes * visual,
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->lock = screen->drmLock;
- ctx->d_stamp = -1;
- ctx->r_stamp = -1;
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen,
- ctx );
-
- if (ctx->pipe == NULL)
- goto fail;
-
- ctx->st = st_create_context(ctx->pipe, visual, st_share);
+ dri_fill_st_visual(&stvis, screen, visual);
+ ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share);
if (ctx->st == NULL)
goto fail;
+ ctx->st->st_manager_private = (void *) ctx;
dri_init_extensions(ctx);
@@ -85,10 +76,7 @@ dri_create_context(const __GLcontextModes * visual,
fail:
if (ctx && ctx->st)
- st_destroy_context(ctx->st);
-
- if (ctx && ctx->pipe)
- ctx->pipe->destroy(ctx->pipe);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
return FALSE;
@@ -110,11 +98,8 @@ dri_destroy_context(__DRIcontext * cPriv)
* to avoid having to add code elsewhere to cope with flushing a
* partially destroyed context.
*/
- st_flush(ctx->st, 0, NULL);
-
- /* Also frees ctx->pipe?
- */
- st_destroy_context(ctx->st);
+ ctx->st->flush(ctx->st, 0, NULL);
+ ctx->st->destroy(ctx->st);
FREE(ctx);
}
@@ -122,14 +107,16 @@ dri_destroy_context(__DRIcontext * cPriv)
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
if (--ctx->bind_count == 0) {
- if (ctx->st && ctx->st == st_get_current()) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- st_make_current(NULL, NULL, NULL);
- }
+ if (ctx->st == stapi->get_current(stapi)) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ stapi->make_current(stapi, NULL, NULL, NULL);
+ }
}
}
@@ -141,77 +128,47 @@ dri_make_current(__DRIcontext * cPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv)
{
+ struct st_api *stapi = dri_get_st_api();
+
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
- struct st_context *old_st = st_get_current();
+ struct st_context_iface *old_st;
+ old_st = stapi->get_current(stapi);
if (old_st && old_st != ctx->st)
- st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
++ctx->bind_count;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
- ctx->d_stamp = driDrawPriv->lastStamp - 1;
+ draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
- ctx->r_stamp = driReadPriv->lastStamp - 1;
+ read->texture_stamp = driReadPriv->lastStamp - 1;
}
- st_make_current(ctx->st, draw->stfb, read->stfb);
-
- if (__dri1_api_hooks) {
- dri1_update_drawables(ctx, draw, read);
- } else {
- dri_update_buffer(ctx->pipe->screen,
- ctx->pipe->priv);
- }
- } else {
- st_make_current(NULL, NULL, NULL);
+ stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb);
+ }
+ else {
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
}
-static void
-st_dri_lock(struct pipe_context *pipe)
+struct dri_context *
+dri_get_current(void)
{
- dri_lock((struct dri_context *)pipe->priv);
-}
+ struct st_api *stapi = dri_get_st_api();
+ struct st_context_iface *st;
-static void
-st_dri_unlock(struct pipe_context *pipe)
-{
- dri_unlock((struct dri_context *)pipe->priv);
-}
+ st = stapi->get_current(stapi);
-static boolean
-st_dri_is_locked(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->isLocked;
+ return (struct dri_context *) (st) ? st->st_manager_private : NULL;
}
-static boolean
-st_dri_lost_lock(struct pipe_context *pipe)
-{
- return ((struct dri_context *)pipe->priv)->wsLostLock;
-}
-
-static void
-st_dri_clear_lost_lock(struct pipe_context *pipe)
-{
- ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
-}
-
-struct dri1_api_lock_funcs dri1_lf = {
- .lock = st_dri_lock,
- .unlock = st_dri_unlock,
- .is_locked = st_dri_is_locked,
- .is_lock_lost = st_dri_lost_lock,
- .clear_lost_lock = st_dri_clear_lost_lock
-};
-
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h
index 13f497462f..24d3d0368a 100644
--- a/src/gallium/state_trackers/dri/dri_context.h
+++ b/src/gallium/state_trackers/dri/dri_context.h
@@ -33,8 +33,7 @@
#define DRI_CONTEXT_H
#include "pipe/p_compiler.h"
-#include "drm.h"
-#include "dri_util.h"
+#include "dri_wrapper.h"
struct pipe_context;
struct pipe_fence;
@@ -51,9 +50,6 @@ struct dri_context
driOptionCache optionCache;
- unsigned int d_stamp;
- unsigned int r_stamp;
-
drmLock *lock;
boolean isLocked;
boolean stLostLock;
@@ -62,8 +58,7 @@ struct dri_context
unsigned int bind_count;
/* gallium */
- struct st_context *st;
- struct pipe_context *pipe;
+ struct st_context_iface *st;
};
static INLINE struct dri_context *
@@ -72,33 +67,9 @@ dri_context(__DRIcontext * driContextPriv)
return (struct dri_context *)driContextPriv->driverPrivate;
}
-static INLINE void
-dri_lock(struct dri_context *ctx)
-{
- drm_context_t hw_context = ctx->cPriv->hHWContext;
- char ret = 0;
-
- DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
- if (ret) {
- drmGetLock(ctx->sPriv->fd, hw_context, 0);
- ctx->stLostLock = TRUE;
- ctx->wsLostLock = TRUE;
- }
- ctx->isLocked = TRUE;
-}
-
-static INLINE void
-dri_unlock(struct dri_context *ctx)
-{
- ctx->isLocked = FALSE;
- DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
-}
-
/***********************************************************************
* dri_context.c
*/
-extern struct dri1_api_lock_funcs dri1_lf;
-
void dri_destroy_context(__DRIcontext * driContextPriv);
boolean dri_unbind_context(__DRIcontext * driContextPriv);
@@ -108,6 +79,9 @@ dri_make_current(__DRIcontext * driContextPriv,
__DRIdrawable * driDrawPriv,
__DRIdrawable * driReadPriv);
+struct dri_context *
+dri_get_current(void);
+
boolean
dri_create_context(const __GLcontextModes * visual,
__DRIcontext * driContextPriv,
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 173f4041c8..75b4cc5628 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -32,302 +32,14 @@
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
-#include "pipe/p_context.h"
#include "pipe/p_screen.h"
-#include "main/mtypes.h"
-#include "main/renderbuffer.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
#include "util/u_format.h"
#include "util/u_memory.h"
-#include "util/u_rect.h"
#include "util/u_inlines.h"
-static struct pipe_surface *
-dri_surface_from_handle(struct drm_api *api,
- struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width, unsigned height, unsigned pitch)
-{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth0 = 1;
- templat.format = format;
- templat.width0 = width;
- templat.height0 = height;
-
- texture = api->texture_from_shared_handle(api, screen, &templat,
- "dri2 buffer", pitch, handle);
-
- if (!texture) {
- debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
- return NULL;
- }
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
-}
-
-/**
- * Pixmaps have will have the same name of fake front and front.
- */
-static boolean
-dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
-{
- boolean found = FALSE;
- boolean is_pixmap = FALSE;
- unsigned name;
- int i;
-
- for (i = 0; i < count; i++) {
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- if (found) {
- is_pixmap = buffers[i].name == name;
- } else {
- name = buffers[i].name;
- found = TRUE;
- }
- default:
- continue;
- }
- }
-
- return is_pixmap;
-}
-
-/**
- * This will be called a drawable is known to have been resized.
- */
-void
-dri_get_buffers(__DRIdrawable * dPriv)
-{
-
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *surface = NULL;
- struct dri_screen *st_screen = dri_screen(drawable->sPriv);
- struct pipe_screen *screen = st_screen->pipe_screen;
- __DRIbuffer *buffers = NULL;
- __DRIscreen *dri_screen = drawable->sPriv;
- __DRIdrawable *dri_drawable = drawable->dPriv;
- struct drm_api *api = st_screen->api;
- boolean have_depth = FALSE;
- int i, count;
-
- if ((dri_screen->dri2.loader
- && (dri_screen->dri2.loader->base.version > 2)
- && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) {
- buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
- (dri_drawable, &dri_drawable->w, &dri_drawable->h,
- drawable->attachments, drawable->num_attachments,
- &count, dri_drawable->loaderPrivate);
- } else {
- assert(dri_screen->dri2.loader);
- buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
- &dri_drawable->w,
- &dri_drawable->h,
- drawable->attachments,
- drawable->
- num_attachments, &count,
- dri_drawable->
- loaderPrivate);
- }
-
- if (buffers == NULL) {
- return;
- }
-
- /* set one cliprect to cover the whole dri_drawable */
- dri_drawable->x = 0;
- dri_drawable->y = 0;
- dri_drawable->backX = 0;
- dri_drawable->backY = 0;
- dri_drawable->numClipRects = 1;
- dri_drawable->pClipRects[0].x1 = 0;
- dri_drawable->pClipRects[0].y1 = 0;
- dri_drawable->pClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pClipRects[0].y2 = dri_drawable->h;
- dri_drawable->numBackClipRects = 1;
- dri_drawable->pBackClipRects[0].x1 = 0;
- dri_drawable->pBackClipRects[0].y1 = 0;
- dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
-
- if (drawable->old_num == count &&
- drawable->old_w == dri_drawable->w &&
- drawable->old_h == dri_drawable->h &&
- memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
- return;
- } else {
- drawable->old_num = count;
- drawable->old_w = dri_drawable->w;
- drawable->old_h = dri_drawable->h;
- memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
- }
-
- drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
-
- for (i = 0; i < count; i++) {
- enum pipe_format format = 0;
- int index = 0;
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- if (!st_screen->auto_fake_front)
- continue;
- /* fallthrough */
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_BACK_LEFT:
- index = ST_SURFACE_BACK_LEFT;
- format = drawable->color_format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- index = ST_SURFACE_DEPTH;
- format = drawable->depth_stencil_format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- if (index == ST_SURFACE_DEPTH) {
- if (have_depth)
- continue;
- else
- have_depth = TRUE;
- }
-
- surface = dri_surface_from_handle(api,
- screen,
- buffers[i].name,
- format,
- dri_drawable->w,
- dri_drawable->h, buffers[i].pitch);
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- case __DRI_BUFFER_BACK_LEFT:
- drawable->color_format = surface->format;
- break;
- case __DRI_BUFFER_DEPTH:
- case __DRI_BUFFER_DEPTH_STENCIL:
- case __DRI_BUFFER_STENCIL:
- drawable->depth_stencil_format = surface->format;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
-
- st_set_framebuffer_surface(drawable->stfb, index, surface);
- pipe_surface_reference(&surface, NULL);
- }
- /* this needed, or else the state tracker fails to pick the new buffers */
- st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
-}
-
-/**
- * These are used for GLX_EXT_texture_from_pixmap
- */
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint format, __DRIdrawable *dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *ps;
-
- if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
- struct gl_renderbuffer *rb =
- st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
- _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
- }
-
- dri_get_buffers(drawable->dPriv);
- st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
-
- if (!ps)
- return;
-
- st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
- ST_TEXTURE_RECT, 0, drawable->color_format);
-}
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv)
-{
- dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
-}
-
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
-
- if (ctx->d_stamp == *ctx->dPriv->pStamp &&
- ctx->r_stamp == *ctx->rPriv->pStamp)
- return;
-
- ctx->d_stamp = *ctx->dPriv->pStamp;
- ctx->r_stamp = *ctx->rPriv->pStamp;
-
- /* Ask the X server for new renderbuffers. */
- dri_get_buffers(ctx->dPriv);
- if (ctx->dPriv != ctx->rPriv)
- dri_get_buffers(ctx->rPriv);
-
-}
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
- __DRIdrawable *dri_drawable = ctx->dPriv;
- __DRIscreen *dri_screen = ctx->sPriv;
-
- /* XXX Does this function get called with DRI1? */
-
- if (ctx->dPriv == NULL) {
- debug_printf("%s: no drawable bound to context\n", __func__);
- return;
- }
-
-#if 0
- /* TODO if rendering to pixmaps is slow enable this code. */
- if (drawable->is_pixmap)
- return;
-#else
- (void)drawable;
-#endif
-
- (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
- dri_drawable->loaderPrivate);
-}
-
/**
* This is called when we need to set up GL rendering to a new X window.
*/
@@ -338,7 +50,6 @@ dri_create_buffer(__DRIscreen * sPriv,
{
struct dri_screen *screen = sPriv->private;
struct dri_drawable *drawable = NULL;
- int i;
if (isPixmap)
goto fail; /* not implemented */
@@ -347,45 +58,8 @@ dri_create_buffer(__DRIscreen * sPriv,
if (drawable == NULL)
goto fail;
- if (visual->redBits == 8) {
- if (visual->alphaBits == 8)
- drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- else
- drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
- } else {
- drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM;
- }
-
- switch(visual->depthBits) {
- default:
- case 0:
- drawable->depth_stencil_format = PIPE_FORMAT_NONE;
- break;
- case 16:
- drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
- break;
- case 24:
- if (visual->stencilBits == 0) {
- drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
- PIPE_FORMAT_Z24X8_UNORM:
- PIPE_FORMAT_X8Z24_UNORM;
- } else {
- drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
- PIPE_FORMAT_Z24S8_UNORM:
- PIPE_FORMAT_S8Z24_UNORM;
- }
- break;
- case 32:
- drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- break;
- }
-
- drawable->stfb = st_create_framebuffer(visual,
- drawable->color_format,
- drawable->depth_stencil_format,
- drawable->depth_stencil_format,
- dPriv->w,
- dPriv->h, (void *)drawable);
+ dri_fill_st_visual(&drawable->stvis, screen, visual);
+ drawable->stfb = dri_create_st_framebuffer(drawable);
if (drawable->stfb == NULL)
goto fail;
@@ -393,48 +67,6 @@ dri_create_buffer(__DRIscreen * sPriv,
drawable->dPriv = dPriv;
dPriv->driverPrivate = (void *)drawable;
- /* setup dri2 buffers information */
- /* TODO incase of double buffer visual, delay fake creation */
- i = 0;
- if (sPriv->dri2.loader
- && (sPriv->dri2.loader->base.version > 2)
- && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- if (!screen->auto_fake_front) {
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->doubleBufferMode) {
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- drawable->attachments[i++] = visual->rgbBits;
- }
- if (visual->depthBits && visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
- } else if (visual->depthBits) {
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- drawable->attachments[i++] = visual->depthBits;
- } else if (visual->stencilBits) {
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->attachments[i++] = visual->stencilBits;
- }
- drawable->num_attachments = i / 2;
- } else {
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- if (!screen->auto_fake_front)
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
- if (visual->doubleBufferMode)
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (visual->depthBits && visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
- else if (visual->depthBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- else if (visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->num_attachments = i;
- }
-
drawable->desired_fences = 2;
return GL_TRUE;
@@ -443,319 +75,20 @@ fail:
return GL_FALSE;
}
-static struct pipe_fence_handle *
-dri_swap_fences_pop_front(struct dri_drawable *draw)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence = NULL;
-
- if (draw->cur_fences >= draw->desired_fences) {
- screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
- screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
- --draw->cur_fences;
- draw->tail &= DRI_SWAP_FENCES_MASK;
- }
- return fence;
-}
-
-static void
-dri_swap_fences_push_back(struct dri_drawable *draw,
- struct pipe_fence_handle *fence)
-{
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
-
- if (!fence)
- return;
-
- if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
- draw->cur_fences++;
- screen->fence_reference(screen, &draw->swap_fences[draw->head++],
- fence);
- draw->head &= DRI_SWAP_FENCES_MASK;
- }
-}
-
void
dri_destroy_buffer(__DRIdrawable * dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_fence_handle *fence;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
- st_unreference_framebuffer(drawable->stfb);
- drawable->desired_fences = 0;
- while (drawable->cur_fences) {
- fence = dri_swap_fences_pop_front(drawable);
- screen->fence_reference(screen, &fence, NULL);
- }
-
- FREE(drawable);
-}
-
-static void
-dri1_update_drawables_locked(struct dri_context *ctx,
- __DRIdrawable * driDrawPriv,
- __DRIdrawable * driReadPriv)
-{
- if (ctx->stLostLock) {
- ctx->stLostLock = FALSE;
- if (driDrawPriv == driReadPriv)
- DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
- else
- DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
- driReadPriv);
- }
-}
-
-/**
- * This ensures all contexts which bind to a drawable pick up the
- * drawable change and signal new buffer state.
- * Calling st_resize_framebuffer for each context may seem like overkill,
- * but no new buffers will actually be allocated if the dimensions don't
- * change.
- */
-
-static void
-dri1_propagate_drawable_change(struct dri_context *ctx)
-{
- __DRIdrawable *dPriv = ctx->dPriv;
- __DRIdrawable *rPriv = ctx->rPriv;
- boolean flushed = FALSE;
-
- if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- flushed = TRUE;
- ctx->d_stamp = dPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h);
-
- }
-
- if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) {
-
- if (!flushed)
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->r_stamp = rPriv->lastStamp;
- st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h);
-
- } else if (rPriv && dPriv == rPriv) {
-
- ctx->r_stamp = ctx->d_stamp;
+ dri1_swap_fences_clear(drawable);
- }
-}
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read)
-{
- dri_lock(ctx);
- dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv);
- dri_unlock(ctx);
-
- dri1_propagate_drawable_change(ctx);
-}
-
-static INLINE boolean
-dri1_intersect_src_bbox(struct drm_clip_rect *dst,
- int dst_x,
- int dst_y,
- const struct drm_clip_rect *src,
- const struct drm_clip_rect *bbox)
-{
- int xy1;
- int xy2;
-
- xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
- (int)bbox->x1 + dst_x;
- xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
- (int)bbox->x2 + dst_x;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->x1 = xy1;
- dst->x2 = xy2;
+ dri1_destroy_pipe_surface(drawable);
- xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
- (int)bbox->y1 + dst_y;
- xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
- (int)bbox->y2 + dst_y;
- if (xy1 >= xy2 || xy1 < 0)
- return FALSE;
-
- dst->y1 = xy1;
- dst->y2 = xy2;
- return TRUE;
-}
-
-static void
-dri1_swap_copy(struct dri_context *ctx,
- struct pipe_surface *dst,
- struct pipe_surface *src,
- __DRIdrawable * dPriv, const struct drm_clip_rect *bbox)
-{
- struct pipe_context *pipe = ctx->pipe;
- struct drm_clip_rect clip;
- struct drm_clip_rect *cur;
- int i;
-
- cur = dPriv->pClipRects;
-
- for (i = 0; i < dPriv->numClipRects; ++i) {
- if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) {
- if (pipe->surface_copy) {
- pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- } else {
- util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1,
- src,
- (int)clip.x1 - dPriv->x,
- (int)clip.y1 - dPriv->y,
- clip.x2 - clip.x1, clip.y2 - clip.y1);
- }
- }
- }
-}
-
-static void
-dri1_copy_to_front(struct dri_context *ctx,
- struct pipe_surface *surf,
- __DRIdrawable * dPriv,
- const struct drm_clip_rect *sub_box,
- struct pipe_fence_handle **fence)
-{
- struct pipe_context *pipe = ctx->pipe;
- boolean save_lost_lock;
- uint cur_w;
- uint cur_h;
- struct drm_clip_rect bbox;
- boolean visible = TRUE;
+ dri_destroy_st_framebuffer(drawable->stfb);
- *fence = NULL;
-
- dri_lock(ctx);
- save_lost_lock = ctx->stLostLock;
- dri1_update_drawables_locked(ctx, dPriv, dPriv);
- st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h);
-
- bbox.x1 = 0;
- bbox.x2 = cur_w;
- bbox.y1 = 0;
- bbox.y2 = cur_h;
-
- if (sub_box)
- visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
-
- if (visible && __dri1_api_hooks->present_locked) {
-
- __dri1_api_hooks->present_locked(pipe,
- surf,
- dPriv->pClipRects,
- dPriv->numClipRects,
- dPriv->x, dPriv->y, &bbox, fence);
-
- } else if (visible && __dri1_api_hooks->front_srf_locked) {
-
- struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
-
- if (front)
- dri1_swap_copy(ctx, front, surf, dPriv, &bbox);
-
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
- }
-
- ctx->stLostLock = save_lost_lock;
-
- /**
- * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
- */
-
- if (!sub_box)
- dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
-
- dri_unlock(ctx);
- dri1_propagate_drawable_change(ctx);
-}
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- struct pipe_fence_handle *dummy_fence;
-
- dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
-
- /**
- * FIXME: Do we need swap throttling here?
- */
-}
-
-void
-dri_swap_buffers(__DRIdrawable * dPriv)
-{
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
- struct pipe_fence_handle *fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return; /* For now */
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_notify_swapbuffers(draw->stfb);
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- fence = dri_swap_fences_pop_front(draw);
- if (fence) {
- (void)screen->fence_finish(screen, fence, 0);
- screen->fence_reference(screen, &fence, NULL);
- }
- dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence);
- dri_swap_fences_push_back(draw, fence);
- screen->fence_reference(screen, &fence, NULL);
- }
-}
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h)
-{
- struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
- struct drm_clip_rect sub_bbox;
- struct dri_context *ctx;
- struct pipe_surface *back_surf;
- struct dri_drawable *draw = dri_drawable(dPriv);
- struct pipe_fence_handle *dummy_fence;
- struct st_context *st = st_get_current();
-
- assert(__dri1_api_hooks != NULL);
-
- if (!st)
- return;
-
- ctx = (struct dri_context *)st->pipe->priv;
-
- sub_bbox.x1 = x;
- sub_bbox.x2 = x + w;
- sub_bbox.y1 = y;
- sub_bbox.y2 = y + h;
+ drawable->desired_fences = 0;
- st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
- if (back_surf) {
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence);
- screen->fence_reference(screen, &dummy_fence, NULL);
- }
+ FREE(drawable);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 8bc59cb4c3..98abeb9ec0 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -29,6 +29,8 @@
#define DRI_DRAWABLE_H
#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "state_tracker/st_api.h"
struct pipe_surface;
struct pipe_fence_handle;
@@ -44,26 +46,26 @@ struct dri_drawable
__DRIdrawable *dPriv;
__DRIscreen *sPriv;
- unsigned attachments[8];
- unsigned num_attachments;
-
- boolean is_pixmap;
+ /* gallium */
+ struct st_framebuffer_iface *stfb;
+ struct st_visual stvis;
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
unsigned old_h;
- /* gallium */
- struct st_framebuffer *stfb;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+ unsigned int texture_mask, texture_stamp;
+
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
unsigned int cur_fences;
- enum pipe_format color_format;
- enum pipe_format depth_stencil_format;
+ /* used only by DRI1 */
+ struct pipe_surface *dri1_surface;
};
static INLINE struct dri_drawable *
@@ -80,35 +82,8 @@ dri_create_buffer(__DRIscreen * sPriv,
__DRIdrawable * dPriv,
const __GLcontextModes * visual, boolean isPixmap);
-void
-dri_update_buffer(struct pipe_screen *screen, void *context_private);
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
-
-void dri_swap_buffers(__DRIdrawable * dPriv);
-
-void
-dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h);
-
-void dri_get_buffers(__DRIdrawable * dPriv);
-
void dri_destroy_buffer(__DRIdrawable * dPriv);
-void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
- GLint glx_texture_format, __DRIdrawable *dPriv);
-
-void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
- __DRIdrawable *dPriv);
-
-void
-dri1_update_drawables(struct dri_context *ctx,
- struct dri_drawable *draw, struct dri_drawable *read);
-
-void
-dri1_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 1259813a41..df458e1eb0 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -33,110 +33,16 @@
#include "dri_context.h"
#include "state_tracker/st_context.h"
-#define need_GL_ARB_map_buffer_range
-#define need_GL_ARB_multisample
-#define need_GL_ARB_occlusion_query
-#define need_GL_ARB_point_parameters
-#define need_GL_ARB_provoking_vertex
-#define need_GL_ARB_shader_objects
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_array_object
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_vertex_program
-#define need_GL_ARB_vertex_shader
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_blend_color
-#define need_GL_EXT_blend_equation_separate
-#define need_GL_EXT_blend_func_separate
-#define need_GL_EXT_blend_minmax
-#define need_GL_EXT_cull_vertex
-#define need_GL_EXT_draw_buffers2
-#define need_GL_EXT_fog_coord
-#define need_GL_EXT_framebuffer_object
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_provoking_vertex
-#define need_GL_EXT_secondary_color
-#define need_GL_EXT_stencil_two_side
-#define need_GL_APPLE_vertex_array_object
-#define need_GL_NV_vertex_program
-#define need_GL_VERSION_2_0
-#define need_GL_VERSION_2_1
-#include "main/remap_helper.h"
#include "utils.h"
-/**
- * Extension strings exported by the driver.
- */
-static const struct dri_extension card_extensions[] = {
- {"GL_ARB_fragment_shader", NULL},
- {"GL_ARB_map_buffer_range", GL_ARB_map_buffer_range_functions},
- {"GL_ARB_multisample", GL_ARB_multisample_functions},
- {"GL_ARB_multitexture", NULL},
- {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
- {"GL_ARB_pixel_buffer_object", NULL},
- {"GL_ARB_provoking_vertex", GL_ARB_provoking_vertex_functions},
- {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
- {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
- {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
- {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions},
- {"GL_ARB_texture_border_clamp", NULL},
- {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
- {"GL_ARB_texture_cube_map", NULL},
- {"GL_ARB_texture_env_add", NULL},
- {"GL_ARB_texture_env_combine", NULL},
- {"GL_ARB_texture_env_dot3", NULL},
- {"GL_ARB_texture_mirrored_repeat", NULL},
- {"GL_ARB_texture_non_power_of_two", NULL},
- {"GL_ARB_texture_rectangle", NULL},
- {"GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions},
- {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
- {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
- {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
- {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
- {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
- {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
- {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
- {"GL_EXT_blend_subtract", NULL},
- {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
- {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions},
- {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
- {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
- {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
- {"GL_EXT_packed_depth_stencil", NULL},
- {"GL_EXT_pixel_buffer_object", NULL},
- {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions},
- {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
- {"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
- {"GL_EXT_stencil_wrap", NULL},
- {"GL_EXT_texture_edge_clamp", NULL},
- {"GL_EXT_texture_env_combine", NULL},
- {"GL_EXT_texture_env_dot3", NULL},
- {"GL_EXT_texture_filter_anisotropic", NULL},
- {"GL_EXT_texture_lod_bias", NULL},
- {"GL_3DFX_texture_compression_FXT1", NULL},
- {"GL_APPLE_client_storage", NULL},
- {"GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions},
- {"GL_MESA_pack_invert", NULL},
- {"GL_MESA_ycbcr_texture", NULL},
- {"GL_NV_blend_square", NULL},
- {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
- {"GL_NV_vertex_program1_1", NULL},
- {"GL_SGIS_generate_mipmap", NULL},
- {NULL, NULL}
-};
-
void
dri_init_extensions(struct dri_context *ctx)
{
- /* The card_extensions list should be pruned according to the
- * capabilities of the pipe_screen. This is actually something
- * that can/should be done inside st_create_context().
- * XXX Not pruning is very bogus. Always all these extensions above
- * will be advertized, regardless what st_init_extensions
- * (which depends on the pipe cap bits) does.
- */
- driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE);
+ struct st_context *st = (struct st_context *) ctx->st;
+
+ /* New extensions should be added in mesa/state_tracker/st_extensions.c
+ * and not in this file. */
+ driInitExtensions(st->ctx, NULL, GL_FALSE);
}
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 7ccad8f5dd..598a07bb64 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -30,17 +30,27 @@
*/
#include "utils.h"
+#ifndef __NOT_HAVE_DRM_H
#include "vblank.h"
+#endif
#include "xmlpool.h"
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
-
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_format.h"
#include "state_tracker/drm_api.h"
-#include "state_tracker/dri1_api.h"
#include "util/u_debug.h"
@@ -49,43 +59,13 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY
- /*DRI_CONF_FORCE_S3TC_ENABLE(false) */
+/* DRI_CONF_FORCE_S3TC_ENABLE(false) */
DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
- const uint __driNConfigOptions = 3;
-
-static const __DRItexBufferExtension dri2TexBufferExtension = {
- { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
- dri2_set_tex_buffer,
- dri2_set_tex_buffer2,
-};
-
-static void
-dri2_flush_drawable(__DRIdrawable *draw)
-{
-}
-
-static const __DRI2flushExtension dri2FlushExtension = {
- { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
- dri2_flush_drawable,
- dri2InvalidateDrawable,
-};
-
- static const __DRIextension *dri_screen_extensions[] = {
- &driReadDrawableExtension,
- &driCopySubBufferExtension.base,
- &driSwapControlExtension.base,
- &driFrameTrackingExtension.base,
- &driMediaStreamCounterExtension.base,
- &dri2TexBufferExtension.base,
- &dri2FlushExtension.base,
- NULL
- };
-
-struct dri1_api *__dri1_api_hooks = NULL;
+const uint __driNConfigOptions = 3;
-static const __DRIconfig **
+const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen,
unsigned pixel_bits)
{
@@ -135,9 +115,7 @@ dri_fill_in_modes(struct dri_screen *screen,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
- if (screen->sPriv->dri2.loader &&
- (screen->sPriv->dri2.loader->base.version > 2) &&
- (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
+ if (dri_with_format(screen->sPriv)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
@@ -229,139 +207,88 @@ dri_fill_in_modes(struct dri_screen *screen,
}
/**
- * Get information about previous buffer swaps.
+ * Roughly the converse of dri_fill_in_modes.
*/
-static int
-dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode)
{
- if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL)
- return -1;
- else
- return 0;
-}
+ memset(stvis, 0, sizeof(*stvis));
-static INLINE void
-dri_copy_version(struct dri1_api_version *dst,
- const struct __DRIversionRec *src)
-{
- dst->major = src->major;
- dst->minor = src->minor;
- dst->patch_level = src->patch;
-}
-
-static const __DRIconfig **
-dri_init_screen(__DRIscreen * sPriv)
-{
- struct dri_screen *screen;
- const __DRIconfig **configs;
- struct dri1_create_screen_arg arg;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- return NULL;
+ stvis->samples = mode->samples;
+ stvis->render_buffer = ST_ATTACHMENT_INVALID;
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
-
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
-
- arg.base.mode = DRM_CREATE_DRI1;
- arg.lf = &dri1_lf;
- arg.ddx_info = sPriv->pDevPriv;
- arg.ddx_info_size = sPriv->devPrivSize;
- arg.sarea = sPriv->pSAREA;
- dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
- dri_copy_version(&arg.dri_version, &sPriv->dri_version);
- dri_copy_version(&arg.drm_version, &sPriv->drm_version);
- arg.api = NULL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
-
- if (!screen->pipe_screen || !arg.api) {
- debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
- goto out_no_screen;
+ if (mode->redBits == 8) {
+ if (mode->alphaBits == 8)
+ stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ else
+ stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ } else {
+ stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
}
- __dri1_api_hooks = arg.api;
-
- screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
+ switch (mode->depthBits) {
+ default:
+ case 0:
+ stvis->depth_stencil_format = PIPE_FORMAT_NONE;
+ break;
+ case 16:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
+ break;
+ case 24:
+ if (mode->stencilBits == 0) {
+ stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
+ PIPE_FORMAT_Z24X8_UNORM:
+ PIPE_FORMAT_X8Z24_UNORM;
+ } else {
+ stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
+ PIPE_FORMAT_Z24S8_UNORM:
+ PIPE_FORMAT_S8Z24_UNORM;
+ }
+ break;
+ case 32:
+ stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
+ break;
+ }
- /**
- * FIXME: If the driver supports format conversion swapbuffer blits, we might
- * want to support other color bit depths than the server is currently
- * using.
- */
+ stvis->accum_format = (mode->haveAccumBuffer) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
- configs = dri_fill_in_modes(screen, sPriv->fbBPP);
- if (!configs)
- goto out_no_configs;
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
- return configs;
- out_no_configs:
- screen->pipe_screen->destroy(screen->pipe_screen);
- out_no_screen:
- FREE(screen);
- return NULL;
+ if (mode->haveDepthBuffer || mode->haveStencilBuffer)
+ stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
+ /* let the state tracker allocate the accum buffer */
}
+#ifndef __NOT_HAVE_DRM_H
+
/**
- * This is the driver specific part of the createNewScreen entry point.
- *
- * Returns the __GLcontextModes supported by this driver.
+ * Get information about previous buffer swaps.
*/
-static const __DRIconfig **
-dri_init_screen2(__DRIscreen * sPriv)
+static int
+dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
{
- struct dri_screen *screen;
- struct drm_create_screen_arg arg;
- const __DRIdri2LoaderExtension *dri2_ext =
- sPriv->dri2.loader;
-
- screen = CALLOC_STRUCT(dri_screen);
- if (!screen)
- goto fail;
-
- screen->api = drm_api_create();
- screen->sPriv = sPriv;
- screen->fd = sPriv->fd;
- sPriv->private = (void *)screen;
- sPriv->extensions = dri_screen_extensions;
- arg.mode = DRM_CREATE_NORMAL;
-
- screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg);
- if (!screen->pipe_screen) {
- debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
- goto fail;
- }
-
- /* We need to hook in here */
- screen->pipe_screen->update_buffer = dri_update_buffer;
- screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
-
- driParseOptionInfo(&screen->optionCache,
- __driConfigOptions, __driNConfigOptions);
-
- screen->auto_fake_front = dri2_ext->base.version >= 3 &&
- dri2_ext->getBuffersWithFormat != NULL;
-
- return dri_fill_in_modes(screen, 32);
- fail:
- return NULL;
+ if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL)
+ return -1;
+ else
+ return 0;
}
+#endif
+
static void
-dri_destroy_screen(__DRIscreen * sPriv)
+dri_destroy_option_cache(struct dri_screen * screen)
{
- struct dri_screen *screen = dri_screen(sPriv);
int i;
- screen->pipe_screen->destroy(screen->pipe_screen);
-
for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
FREE(screen->optionCache.info[i].name);
FREE(screen->optionCache.info[i].ranges);
@@ -369,27 +296,46 @@ dri_destroy_screen(__DRIscreen * sPriv)
FREE(screen->optionCache.info);
FREE(screen->optionCache.values);
+}
+
+void
+dri_destroy_screen(__DRIscreen * sPriv)
+{
+ struct dri_screen *screen = dri_screen(sPriv);
+
+ dri1_destroy_pipe_context(screen);
+
+ if (screen->smapi)
+ dri_destroy_st_manager(screen->smapi);
+
+ if (screen->pipe_screen)
+ screen->pipe_screen->destroy(screen->pipe_screen);
+
+ dri_destroy_option_cache(screen);
FREE(screen);
sPriv->private = NULL;
+ sPriv->extensions = NULL;
}
-PUBLIC const struct __DriverAPIRec driDriverAPI = {
- .InitScreen = dri_init_screen,
+#ifndef __NOT_HAVE_DRM_H
+
+const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
.DestroyContext = dri_destroy_context,
.CreateBuffer = dri_create_buffer,
.DestroyBuffer = dri_destroy_buffer,
- .SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
.GetSwapInfo = dri_get_swap_info,
.GetDrawableMSC = driDrawableGetMSC32,
.WaitForMSC = driWaitForMSC32,
- .CopySubBuffer = dri_copy_sub_buffer,
- .InitScreen = dri_init_screen,
- .InitScreen2 = dri_init_screen2,
+ .InitScreen2 = dri2_init_screen,
+
+ .InitScreen = dri1_init_screen,
+ .SwapBuffers = dri1_swap_buffers,
+ .CopySubBuffer = dri1_copy_sub_buffer,
};
/* This is the table of extensions that the loader will dlsym() for. */
@@ -400,4 +346,28 @@ PUBLIC const __DRIextension *__driDriverExtensions[] = {
NULL
};
+#else
+
+const struct __DriverAPIRec driDriverAPI = {
+ .DestroyScreen = dri_destroy_screen,
+ .CreateContext = dri_create_context,
+ .DestroyContext = dri_destroy_context,
+ .CreateBuffer = dri_create_buffer,
+ .DestroyBuffer = dri_destroy_buffer,
+ .MakeCurrent = dri_make_current,
+ .UnbindContext = dri_unbind_context,
+
+ .InitScreen = drisw_init_screen,
+ .SwapBuffers = drisw_swap_buffers,
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driSWRastExtension.base,
+ NULL
+};
+
+#endif
+
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 75a0ee4250..4f59db37cf 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -32,12 +32,13 @@
#ifndef DRI_SCREEN_H
#define DRI_SCREEN_H
-#include "dri_util.h"
+#include "dri_wrapper.h"
#include "xmlconfig.h"
#include "pipe/p_compiler.h"
-
-#include "state_tracker/dri1_api.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "state_tracker/st_api.h"
struct dri_screen
{
@@ -60,6 +61,11 @@ struct dri_screen
boolean d_depth_bits_last;
boolean sd_depth_bits_last;
boolean auto_fake_front;
+
+ struct st_manager *smapi;
+
+ /* used only by DRI1 */
+ struct pipe_context *dri1_pipe;
};
/** cast wrapper */
@@ -69,11 +75,39 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->private;
}
-/***********************************************************************
- * dri_screen.c
- */
+#ifndef __NOT_HAVE_DRM_H
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ const __DRIdri2LoaderExtension *loader = sPriv->dri2.loader;
+
+ return loader
+ && (loader->base.version >= 3)
+ && (loader->getBuffersWithFormat != NULL);
+}
+
+#else
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ return TRUE;
+}
+
+#endif
+
+extern const uint __driNConfigOptions;
+
+const __DRIconfig **
+dri_fill_in_modes(struct dri_screen *screen, unsigned pixel_bits);
+
+void
+dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
+ const __GLcontextModes *mode);
-extern struct dri1_api *__dri1_api_hooks;
+void
+dri_destroy_screen(__DRIscreen * sPriv);
#endif
diff --git a/src/gallium/state_trackers/dri/dri_st_api.c b/src/gallium/state_trackers/dri/dri_st_api.c
new file mode 100644
index 0000000000..40b24b18e9
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri_st_api.c
@@ -0,0 +1,263 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_debug.h"
+#include "state_tracker/st_manager.h" /* for st_manager_create_api */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#ifndef __NOT_HAVE_DRM_H
+#include "dri1.h"
+#include "dri2.h"
+#else
+#include "drisw.h"
+#endif
+
+static boolean
+dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ unsigned statt_mask, new_mask;
+ boolean new_stamp;
+ int i;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= (1 << statts[i]);
+
+ /* record newly allocated textures */
+ new_mask = (statt_mask & ~drawable->texture_mask);
+
+ /*
+ * dPriv->pStamp is the server stamp. It should be accessed with a lock, at
+ * least for DRI1. dPriv->lastStamp is the client stamp. It has the value
+ * of the server stamp when last checked.
+ */
+ new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp);
+
+ if (new_stamp || new_mask) {
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_allocate_textures(drawable, statt_mask);
+ }
+ else {
+ dri2_allocate_textures(drawable, statts, count);
+ }
+#else
+ if (new_stamp)
+ drisw_update_drawable_info(drawable->dPriv);
+
+ drisw_allocate_textures(drawable, statt_mask);
+#endif
+
+ /* add existing textures */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->textures[i])
+ statt_mask |= (1 << i);
+ }
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp;
+ drawable->texture_mask = statt_mask;
+ }
+
+ if (!out)
+ return TRUE;
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], drawable->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+
+#ifndef __NOT_HAVE_DRM_H
+ if (__dri1_api_hooks) {
+ dri1_flush_frontbuffer(drawable, statt);
+ }
+ else {
+ dri2_flush_frontbuffer(drawable, statt);
+ }
+#else
+ drisw_flush_frontbuffer(drawable, statt);
+#endif
+
+ return TRUE;
+}
+
+/**
+ * Create a framebuffer from the given drawable.
+ */
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable)
+{
+ struct st_framebuffer_iface *stfbi;
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ if (stfbi) {
+ stfbi->visual = &drawable->stvis;
+ stfbi->flush_front = dri_st_framebuffer_flush_front;
+ stfbi->validate = dri_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) drawable;
+ }
+
+ return stfbi;
+}
+
+/**
+ * Destroy a framebuffer.
+ */
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ int i;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+
+ FREE(stfbi);
+}
+
+/**
+ * Validate the texture at an attachment. Allocate the texture if it does not
+ * exist.
+ */
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct dri_drawable *drawable =
+ (struct dri_drawable *) stfbi->st_manager_private;
+ enum st_attachment_type statts[ST_ATTACHMENT_COUNT];
+ unsigned i, count = 0;
+
+ /* check if buffer already exists */
+ if (drawable->texture_mask & (1 << statt))
+ return;
+
+ /* make sure DRI2 does not destroy existing buffers */
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ if (drawable->texture_mask & (1 << i)) {
+ statts[count++] = i;
+ }
+ }
+ statts[count++] = statt;
+
+ drawable->texture_stamp = drawable->dPriv->lastStamp - 1;
+
+ stfbi->validate(stfbi, statts, count, NULL);
+}
+
+/**
+ * Reference counted st_api.
+ */
+static struct {
+ int32_t refcnt;
+ struct st_api *stapi;
+} dri_st_api;
+
+/**
+ * Add a reference to the st_api of the state tracker.
+ */
+static void
+_dri_get_st_api(void)
+{
+ p_atomic_inc(&dri_st_api.refcnt);
+ if (p_atomic_read(&dri_st_api.refcnt) == 1)
+ dri_st_api.stapi = st_manager_create_api();
+}
+
+/**
+ * Remove a reference to the st_api of the state tracker.
+ */
+static void
+_dri_put_st_api(void)
+{
+ struct st_api *stapi = dri_st_api.stapi;
+
+ if (p_atomic_dec_zero(&dri_st_api.refcnt)) {
+ stapi->destroy(dri_st_api.stapi);
+ dri_st_api.stapi = NULL;
+ }
+}
+
+/**
+ * Create a state tracker manager from the given screen.
+ */
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen)
+{
+ struct st_manager *smapi;
+
+ smapi = CALLOC_STRUCT(st_manager);
+ if (smapi) {
+ smapi->screen = screen->pipe_screen;
+ _dri_get_st_api();
+ }
+
+ return smapi;
+}
+
+/**
+ * Destroy a state tracker manager.
+ */
+void
+dri_destroy_st_manager(struct st_manager *smapi)
+{
+ _dri_put_st_api();
+ FREE(smapi);
+}
+
+/**
+ * Return the st_api of OpenGL state tracker.
+ */
+struct st_api *
+dri_get_st_api(void)
+{
+ assert(dri_st_api.stapi);
+ return dri_st_api.stapi;
+}
diff --git a/src/gallium/state_trackers/dri/dri_st_api.h b/src/gallium/state_trackers/dri/dri_st_api.h
new file mode 100644
index 0000000000..99a217bfa7
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri_st_api.h
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _DRI_ST_API_H_
+#define _DRI_ST_API_H_
+
+#include "state_tracker/st_api.h"
+
+struct dri_screen;
+struct dri_drawable;
+
+struct st_api *
+dri_get_st_api(void);
+
+struct st_manager *
+dri_create_st_manager(struct dri_screen *screen);
+
+void
+dri_destroy_st_manager(struct st_manager *smapi);
+
+struct st_framebuffer_iface *
+dri_create_st_framebuffer(struct dri_drawable *drawable);
+
+void
+dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+dri_st_framebuffer_validate_att(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt);
+
+#endif /* _DRI_ST_API_H_ */
diff --git a/src/gallium/state_trackers/dri/dri_wrapper.h b/src/gallium/state_trackers/dri/dri_wrapper.h
new file mode 100644
index 0000000000..141ba02706
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri_wrapper.h
@@ -0,0 +1,10 @@
+#ifndef DRI_WRAPPER_H
+#define DRI_WRAPPER_H
+
+#ifndef __NOT_HAVE_DRM_H
+#include "dri_util.h"
+#else
+#include "drisw_util.h"
+#endif
+
+#endif
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
new file mode 100644
index 0000000000..73bc45d906
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drisw.c
@@ -0,0 +1,318 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
+ *
+ * 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 VMWARE 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.
+ *
+ **************************************************************************/
+
+/* TODO:
+ *
+ * stride:
+ *
+ * The driver and the loaders (libGL, xserver/glx) compute the stride from the
+ * width independently. winsys has a workaround that works for softpipe but may
+ * explode for other drivers or platforms, rendering- or performance-wise.
+ * Solving this issue properly requires extending the DRISW loader extension,
+ * in order to make the stride available to the putImage callback.
+ *
+ * drisw_api:
+ *
+ * Define drisw_api similarly to dri_api and use it to call the loader. This is
+ * predicated on support for calling the loader from the winsys, which has to
+ * grow for DRI2 as well.
+ *
+ * xshm:
+ *
+ * Allow the loaders to use the XSHM extension. It probably requires callbacks
+ * for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth
+ * it, given the scope of DRISW, unless it falls naturally from properly
+ * solving the above two issues.
+ *
+ * swrast_create_screen:
+ *
+ * Allow for any software renderer to be used. Factor out the code from
+ * targets/libgl-xlib/xlib.c, put it in targets/common or winsys/sw/common and
+ * use it in all software targets.
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "pipe/p_context.h"
+#include "state_tracker/drm_api.h"
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+#include "dri_st_api.h"
+#include "dri1_helper.h"
+#include "drisw.h"
+
+
+static INLINE void
+get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+ int x, y;
+
+ loader->getDrawableInfo(dPriv,
+ &x, &y, w, h,
+ dPriv->loaderPrivate);
+}
+
+static INLINE void
+put_image(__DRIdrawable *dPriv, void *data)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+ 0, 0, dPriv->w, dPriv->h,
+ data, dPriv->loaderPrivate);
+}
+
+void
+drisw_update_drawable_info(__DRIdrawable *dPriv)
+{
+ get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
+}
+
+static INLINE void
+drisw_present_texture(__DRIdrawable *dPriv,
+ struct pipe_texture *ptex)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_context *pipe;
+ struct pipe_surface *psurf;
+ struct pipe_transfer *ptrans;
+ void *pmap;
+
+ pipe = dri1_get_pipe_context(screen);
+ psurf = dri1_get_pipe_surface(drawable, ptex);
+ if (!pipe || !psurf)
+ return;
+
+ ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
+ PIPE_TRANSFER_READ,
+ 0, 0, dPriv->w, dPriv->h);
+
+ pmap = pipe->transfer_map(pipe, ptrans);
+
+ assert(pmap);
+
+ put_image(dPriv, pmap);
+
+ pipe->transfer_unmap(pipe, ptrans);
+
+ pipe->tex_transfer_destroy(pipe, ptrans);
+}
+
+static INLINE void
+drisw_invalidate_drawable(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+
+ drawable->texture_stamp = dPriv->lastStamp - 1;
+
+ /* check if swapping currently bound buffer */
+ if (ctx && ctx->dPriv == dPriv)
+ ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
+}
+
+static INLINE void
+drisw_copy_to_front(__DRIdrawable * dPriv,
+ struct pipe_texture *ptex)
+{
+ drisw_present_texture(dPriv, ptex);
+
+ drisw_invalidate_drawable(dPriv);
+}
+
+/*
+ * Backend functions for st_framebuffer interface and swap_buffers.
+ */
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[statt];
+
+ if (ptex) {
+ drisw_copy_to_front(ctx->dPriv, ptex);
+ }
+}
+
+void
+drisw_swap_buffers(__DRIdrawable *dPriv)
+{
+ struct dri_context *ctx = dri_get_current();
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_texture *ptex;
+
+ if (!ctx)
+ return;
+
+ ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+
+ if (ptex) {
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ drisw_copy_to_front(dPriv, ptex);
+ }
+}
+
+/**
+ * Allocate framebuffer attachments.
+ *
+ * During fixed-size operation, the function keeps allocating new attachments
+ * as they are requested. Unused attachments are not removed, not until the
+ * framebuffer is resized or destroyed.
+ *
+ * It should be possible for DRI1 and DRISW to share this function, but it
+ * seems a better seperation and safer for each DRI version to provide its own
+ * function.
+ */
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask)
+{
+ struct dri_screen *screen = dri_screen(drawable->sPriv);
+ struct pipe_texture templ;
+ unsigned width, height;
+ boolean resized;
+ int i;
+
+ width = drawable->dPriv->w;
+ height = drawable->dPriv->h;
+
+ resized = (drawable->old_w != width ||
+ drawable->old_h != height);
+
+ /* remove outdated textures */
+ if (resized) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&drawable->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (drawable->textures[i] || !(mask & (1 << i))) {
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = drawable->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = drawable->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ drawable->textures[i] =
+ screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
+ }
+ }
+
+ drawable->old_w = width;
+ drawable->old_h = height;
+}
+
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *drisw_screen_extensions[] = {
+ NULL
+};
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv)
+{
+ struct dri_screen *screen;
+ struct drm_create_screen_arg arg;
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->api = drm_api_create();
+ screen->sPriv = sPriv;
+ screen->fd = -1;
+ sPriv->private = (void *)screen;
+ sPriv->extensions = drisw_screen_extensions;
+ arg.mode = DRM_CREATE_DRISW;
+
+ screen->pipe_screen = screen->api->create_screen(screen->api, -1, &arg);
+ if (!screen->pipe_screen) {
+ debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
+ goto fail;
+ }
+
+ screen->smapi = dri_create_st_manager(screen);
+ if (!screen->smapi)
+ goto fail;
+
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ return dri_fill_in_modes(screen, 32);
+fail:
+ dri_destroy_screen(sPriv);
+ return NULL;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/drisw.h b/src/gallium/state_trackers/dri/drisw.h
new file mode 100644
index 0000000000..2c0d5610fa
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drisw.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
+ *
+ * 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 VMWARE 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 DRISW_H
+#define DRISW_H
+
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "state_tracker/st_api.h"
+#include "dri_wrapper.h"
+
+const __DRIconfig **
+drisw_init_screen(__DRIscreen * sPriv);
+
+void
+drisw_update_drawable_info(__DRIdrawable *dPriv);
+
+void
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt);
+
+void
+drisw_allocate_textures(struct dri_drawable *drawable,
+ unsigned mask);
+
+void drisw_swap_buffers(__DRIdrawable * dPriv);
+
+#endif /* DRISW_H */
diff --git a/src/gallium/state_trackers/drisw/Makefile b/src/gallium/state_trackers/drisw/Makefile
new file mode 100644
index 0000000000..dec9a39ede
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/Makefile
@@ -0,0 +1,26 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = drisw
+
+LIBRARY_DEFINES = -D__NOT_HAVE_DRM_H
+
+LIBRARY_INCLUDES = \
+ -I../dri \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa/main \
+ -D__NOT_HAVE_DRM_H
+
+
+C_SOURCES = \
+ dri_context.c \
+ dri_screen.c \
+ dri_drawable.c \
+ dri_extensions.c \
+ dri_st_api.c \
+ dri1_helper.c \
+ drisw.c
+
+include ../../Makefile.template
diff --git a/src/gallium/state_trackers/drisw/dri1_helper.c b/src/gallium/state_trackers/drisw/dri1_helper.c
new file mode 120000
index 0000000000..e704e382e0
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri1_helper.c
@@ -0,0 +1 @@
+../dri/dri1_helper.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/dri_context.c b/src/gallium/state_trackers/drisw/dri_context.c
new file mode 120000
index 0000000000..e4e879dc86
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri_context.c
@@ -0,0 +1 @@
+../dri/dri_context.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/dri_drawable.c b/src/gallium/state_trackers/drisw/dri_drawable.c
new file mode 120000
index 0000000000..d7f65c85d2
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri_drawable.c
@@ -0,0 +1 @@
+../dri/dri_drawable.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/dri_extensions.c b/src/gallium/state_trackers/drisw/dri_extensions.c
new file mode 120000
index 0000000000..60ecde9547
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri_extensions.c
@@ -0,0 +1 @@
+../dri/dri_extensions.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/dri_screen.c b/src/gallium/state_trackers/drisw/dri_screen.c
new file mode 120000
index 0000000000..f22c562c84
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri_screen.c
@@ -0,0 +1 @@
+../dri/dri_screen.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/dri_st_api.c b/src/gallium/state_trackers/drisw/dri_st_api.c
new file mode 120000
index 0000000000..eac8ec6690
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/dri_st_api.c
@@ -0,0 +1 @@
+../dri/dri_st_api.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/drisw/drisw.c b/src/gallium/state_trackers/drisw/drisw.c
new file mode 120000
index 0000000000..258a79021e
--- /dev/null
+++ b/src/gallium/state_trackers/drisw/drisw.c
@@ -0,0 +1 @@
+../dri/drisw.c \ No newline at end of file
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 50774b03f3..5eabe10558 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -36,234 +36,27 @@
#include "native.h"
#include "egl_g3d.h"
+#include "egl_g3d_st.h"
#include "egl_g3d_image.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 *
+static struct st_api *
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
{
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
- const struct egl_g3d_st *stapi;
+ struct st_api *stapi;
EGLint idx = -1;
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
switch (ctx->ClientVersion) {
case 1:
- idx = EGL_G3D_ST_OPENGL_ES;
+ idx = ST_API_OPENGL_ES1;
break;
case 2:
- idx = EGL_G3D_ST_OPENGL_ES2;
+ idx = ST_API_OPENGL_ES2;
break;
default:
_eglLog(_EGL_WARNING, "unknown client version %d",
@@ -272,10 +65,10 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
}
break;
case EGL_OPENVG_API:
- idx = EGL_G3D_ST_OPENVG;
+ idx = ST_API_OPENVG;
break;
case EGL_OPENGL_API:
- idx = EGL_G3D_ST_OPENGL;
+ idx = ST_API_OPENGL;
break;
default:
_eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI);
@@ -299,10 +92,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)
@@ -351,35 +144,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
@@ -444,18 +208,88 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
#endif /* EGL_MESA_screen_surface */
/**
+ * 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)
+{
+ struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+ struct egl_g3d_config *gconf = egl_g3d_config(conf);
+ const __GLcontextModes *mode = &nconf->mode;
+ EGLint buffer_mask, api_mask;
+ EGLBoolean valid;
+ EGLint i;
+
+ buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (mode->doubleBufferMode)
+ buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (mode->stereoMode) {
+ buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (mode->doubleBufferMode)
+ 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 = nconf->depth_format;
+ gconf->stvis.accum_format = PIPE_FORMAT_NONE;
+ gconf->stvis.samples = 0;
+
+ gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT) ?
+ 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 ((mode->drawableType & GLX_WINDOW_BIT) && !mode->doubleBufferMode)
+ api_mask &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
+
+ if (!api_mask) {
+ _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
+ mode->visualID);
+ }
+
+ valid = _eglConfigFromContextModesRec(&gconf->base,
+ mode, api_mask, api_mask);
+ if (valid) {
+#ifdef EGL_MESA_screen_surface
+ /* check if scanout surface bit is set */
+ if (nconf->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", mode->visualID);
+ return EGL_FALSE;
+ }
+
+ gconf->native = nconf;
+
+ return EGL_TRUE;
+}
+
+/**
* Add configs to display and return the next config ID.
*/
static EGLint
egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
{
- struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
const struct native_config **native_configs;
int num_configs, i;
- native_configs = gdpy->native->get_configs(gdpy->native,
- &num_configs);
+ native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
if (!num_configs) {
if (native_configs)
free(native_configs);
@@ -463,75 +297,25 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
for (i = 0; i < num_configs; i++) {
- EGLint api_mask;
struct egl_g3d_config *gconf;
- EGLBoolean valid;
gconf = CALLOC_STRUCT(egl_g3d_config);
- if (!gconf)
- continue;
-
- _eglInitConfig(&gconf->base, dpy, id);
-
- api_mask = get_mode_api_mask(&native_configs[i]->mode, gdrv->api_mask);
- if (!api_mask) {
- _eglLog(_EGL_DEBUG, "no state tracker supports config 0x%x",
- native_configs[i]->mode.visualID);
- }
-
- valid = _eglConfigFromContextModesRec(&gconf->base,
- &native_configs[i]->mode, api_mask, api_mask);
- if (valid) {
-#ifdef EGL_MESA_screen_surface
- /* check if scanout surface bit is set */
- if (native_configs[i]->scanout_bit) {
- EGLint val = GET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE);
- val |= EGL_SCREEN_BIT_MESA;
- SET_CONFIG_ATTRIB(&gconf->base, EGL_SURFACE_TYPE, val);
+ if (gconf) {
+ _eglInitConfig(&gconf->base, dpy, id);
+ if (!egl_g3d_init_config(drv, dpy, &gconf->base, native_configs[i])) {
+ free(gconf);
+ continue;
}
-#endif
- valid = _eglValidateConfig(&gconf->base, EGL_FALSE);
- }
- if (!valid) {
- _eglLog(_EGL_DEBUG, "skip invalid config 0x%x",
- native_configs[i]->mode.visualID);
- free(gconf);
- continue;
- }
- gconf->native = native_configs[i];
- _eglAddConfig(dpy, &gconf->base);
- id++;
+ _eglAddConfig(dpy, &gconf->base);
+ id++;
+ }
}
free(native_configs);
return id;
}
-/**
- * Flush the front buffer of the context's draw surface.
- */
-static void
-egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
-
- if (gsurf)
- gsurf->native->flush_frontbuffer(gsurf->native);
-}
-
-/**
- * Re-validate the context.
- */
-static void
-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
-{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
-}
-
static void
egl_g3d_invalid_surface(struct native_display *ndpy,
struct native_surface *nsurf,
@@ -539,11 +323,15 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
{
/* XXX not thread safe? */
struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
- struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
-
- /* set force_validate to skip an unnecessary check */
+ 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->force_validate = TRUE;
+ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
}
static struct native_event_handler egl_g3d_native_event_handler = {
@@ -559,6 +347,9 @@ 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]);
@@ -568,6 +359,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
free(dpy->Screens);
}
+ if (gdpy->smapi)
+ egl_g3d_destroy_st_manager(gdpy->smapi);
+
if (gdpy->native)
gdpy->native->destroy(gdpy->native);
@@ -602,12 +396,17 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
gdpy->native->user_data = (void *) dpy;
- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
- gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;
+ 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) {
@@ -644,7 +443,6 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
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) {
@@ -663,24 +461,14 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
return NULL;
}
- mode = &gconf->native->mode;
-
- gctx->pipe = gdpy->native->screen->context_create(
- gdpy->native->screen,
- (void *) &gctx->base);
-
- if (!gctx->pipe) {
+ gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi,
+ &gconf->stvis, (gshare) ? gshare->stctxi : NULL);
+ if (!gctx->stctxi) {
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;
- }
+ gctx->stctxi->st_manager_private = (void *) &gctx->base;
return &gctx->base;
}
@@ -697,9 +485,7 @@ destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
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);
+ gctx->stctxi->destroy(gctx->stctxi);
free(gctx);
}
@@ -801,14 +587,20 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
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) {
+ gsurf->native->destroy(gsurf->native);
+ free(gsurf);
+ return NULL;
+ }
+
nsurf->user_data = &gsurf->base;
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;
}
@@ -864,7 +656,8 @@ destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
if (!dpy->Initialized)
_eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
- pipe_surface_reference(&gsurf->render_surface, NULL);
+ pipe_texture_reference(&gsurf->render_texture, NULL);
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
gsurf->native->destroy(gsurf->native);
free(gsurf);
}
@@ -883,6 +676,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
{
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;
@@ -893,34 +687,29 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
if (old_gctx) {
/* flush old context */
- old_gctx->stapi->st_flush(old_gctx->st_ctx,
+ old_gctx->stctxi->flush(old_gctx->stctxi,
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);
+ ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi,
+ (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL);
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;
- }
+ 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->st_make_current(NULL, NULL, NULL);
+ ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
@@ -947,15 +736,17 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;
/* or when the surface is single-buffered */
- if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT)
+ 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->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
+ if (gctx) {
+ gctx->stctxi->flush(gctx->stctxi,
+ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+ }
return gsurf->native->swap_buffers(gsurf->native);
}
@@ -995,7 +786,7 @@ get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf,
return NULL;
psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE);
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
pipe_texture_reference(&textures[natt], NULL);
return psurf;
@@ -1013,7 +804,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
struct pipe_screen *screen = gdpy->native->screen;
struct pipe_surface *psurf;
- if (!gsurf->render_surface)
+ if (!gsurf->render_texture)
return EGL_TRUE;
gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
@@ -1028,26 +819,33 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
/* 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,
+ 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);
if (psurf) {
- struct pipe_context pipe;
+ struct pipe_surface *psrc;
- /**
- * 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;
+ psrc = screen->get_tex_surface(screen, gsurf->render_texture,
+ 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ if (psrc) {
+ gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0,
+ psrc, 0, 0, psurf->width, psurf->height);
+ pipe_surface_reference(&psrc, NULL);
- util_surface_copy(&pipe, FALSE, psurf, 0, 0,
- gsurf->render_surface, 0, 0, psurf->width, psurf->height);
+ nsurf->flush_frontbuffer(nsurf);
+ }
pipe_surface_reference(&psurf, NULL);
- nsurf->flush_frontbuffer(nsurf);
}
nsurf->destroy(nsurf);
@@ -1058,8 +856,16 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
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);
- gctx->stapi->st_finish(gctx->st_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;
}
@@ -1089,10 +895,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;
}
@@ -1108,8 +914,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
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;
+ enum pipe_format internal_format;
+ enum st_texture_type target;
if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT)
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
@@ -1120,10 +926,10 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
switch (gsurf->base.TextureFormat) {
case EGL_TEXTURE_RGB:
- target_format = PIPE_FORMAT_R8G8B8_UNORM;
+ internal_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
- target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ internal_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
@@ -1139,21 +945,24 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (!es1)
return EGL_TRUE;
- if (!gsurf->render_surface)
+ 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->stapi->st_flush(gctx->st_ctx,
+ gctx->stctxi->flush(gctx->stctxi,
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;
+ 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;
}
@@ -1170,14 +979,15 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
- if (gsurf->render_surface) {
+ 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->stapi->st_unbind_texture_surface(gsurf->render_surface,
- ST_TEXTURE_2D, gsurf->base.MipmapLevel);
+ if (gctx) {
+ gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D,
+ gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE);
+ }
}
gsurf->base.BoundToTexture = EGL_FALSE;
@@ -1289,6 +1099,12 @@ 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);
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index e3e55e46d3..2788f1bf4a 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -39,11 +39,11 @@
#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;
@@ -51,35 +51,34 @@ 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;
+
struct native_surface *native;
- enum native_attachment render_att;
- struct pipe_surface *render_surface;
+ struct pipe_texture *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 {
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 0000000000..36094096d3
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -0,0 +1,227 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#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)
+{
+ const char *stmod_name;
+ struct util_dl_library *lib;
+ const struct st_module *mod;
+
+ switch (api) {
+ case ST_API_OPENGL:
+ stmod_name = ST_MODULE_OPENGL_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES1:
+ stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL;
+ break;
+ case ST_API_OPENGL_ES2:
+ stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL;
+ break;
+ case ST_API_OPENVG:
+ stmod_name = ST_MODULE_OPENVG_SYMBOL;
+ break;
+ default:
+ stmod_name = NULL;
+ break;
+ }
+ if (!stmod_name)
+ return NULL;
+
+ mod = NULL;
+ lib = util_dl_open(NULL);
+ if (lib) {
+ mod = (const struct st_module *)
+ util_dl_get_proc_address(lib, stmod_name);
+ util_dl_close(lib);
+ }
+ if (!mod || mod->api != api)
+ return NULL;
+
+ return mod->create_api();
+}
+
+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;
+ }
+
+ 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(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_texture **out)
+{
+ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
+ struct pipe_texture *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;
+ 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_texture *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_texture_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_texture_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;
+ stfbi->flush_front = egl_g3d_st_framebuffer_flush_front;
+ stfbi->validate = egl_g3d_st_framebuffer_validate;
+ 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_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
index 8fb464bd3d..ea8b4068cd 100644
--- a/src/gallium/state_trackers/egl/common/egl_st.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 7.8
+ * Version: 7.9
*
- * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
+ * 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"),
@@ -20,54 +20,60 @@
* 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
*/
-#ifndef _EGL_ST_H_
-#define _EGL_ST_H_
-
-#include "GL/gl.h" /* for GL types */
-#include "GL/internal/glcore.h" /* for __GLcontextModes */
+#ifndef _EGL_G3D_ST_H_
+#define _EGL_G3D_ST_H_
#include "pipe/p_compiler.h"
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
+#include "state_tracker/st_api.h"
+#include "egltypedefs.h"
-/* avoid calling st functions directly */
-#if 1
+struct st_api *
+egl_g3d_create_st_api(enum st_api_type api);
-#define ST_SURFACE_FRONT_LEFT 0
-#define ST_SURFACE_BACK_LEFT 1
-#define ST_SURFACE_FRONT_RIGHT 2
-#define ST_SURFACE_BACK_RIGHT 3
+struct st_manager *
+egl_g3d_create_st_manager(_EGLDisplay *dpy);
-#define ST_TEXTURE_2D 0x2
+void
+egl_g3d_destroy_st_manager(struct st_manager *smapi);
-struct st_context;
-struct st_framebuffer;
-typedef void (*st_proc)();
+struct st_framebuffer_iface *
+egl_g3d_create_st_framebuffer(_EGLSurface *surf);
-#else
-#include "state_tracker/st_public.h"
-#endif
+void
+egl_g3d_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
-/* 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
-};
+/**
+ * Return the EGL_<api>_BIT of the st api.
+ */
+static INLINE int
+egl_g3d_st_api_bit(enum st_api_type api)
+{
+ int bit;
-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;
-};
+ 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;
+ }
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api);
+ return bit;
+}
-#endif /* _EGL_ST_H_ */
+#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 a88ff911cd..0000000000
--- 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 <olv@0xlab.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <dlfcn.h>
-#include "pipe/p_compiler.h"
-#include "util/u_memory.h"
-#include "egllog.h"
-#include "EGL/egl.h" /* for EGL_api_BIT */
-
-#include "egl_st.h"
-
-#ifndef HAVE_DLADDR
-#define HAVE_DLADDR 1
-#endif
-
-#if HAVE_DLADDR
-
-static const char *
-egl_g3d_st_names[] = {
-#define ST_PUBLIC(name, ...) #name,
-#include "st_public_tmp.h"
- NULL
-};
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
- st_proc *procs = (st_proc *) stapi;
- void *handle;
- Dl_info info;
- const char **name;
-
- if (!dladdr(sym, &info))
- return FALSE;
- handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
- if (!handle)
- return FALSE;
-
- for (name = egl_g3d_st_names; *name; name++) {
- st_proc proc = (st_proc) dlsym(handle, *name);
- if (!proc) {
- _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname);
- memset(stapi, 0, sizeof(*stapi));
- dlclose(handle);
- return FALSE;
- }
- *procs++ = proc;
- }
-
- dlclose(handle);
- return TRUE;
-}
-
-#else /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym)
-{
-#define ST_PUBLIC(name, ...) stapi->name = name;
-#include "st_public_tmp.h"
- return TRUE;
-}
-
-#endif /* HAVE_DLADDR */
-
-static boolean
-egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api)
-{
- void *handle, *sym;
- boolean res = FALSE;
-
- /* already initialized */
- if (stapi->st_notify_swapbuffers != NULL)
- return TRUE;
-
- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
- if (!handle)
- return FALSE;
-
- sym = dlsym(handle, api);
- if (sym && egl_g3d_fill_st(stapi, sym))
- res = TRUE;
-
- dlclose(handle);
- return res;
-}
-
-static struct {
- const char *symbol;
- EGLint api_bit;
-} egl_g3d_st_info[NUM_EGL_G3D_STS] = {
- { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT },
- { "st_api_OpenVG", EGL_OPENVG_BIT },
- { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT },
- { "st_api_OpenGL", EGL_OPENGL_BIT },
-};
-
-const struct egl_g3d_st *
-egl_g3d_get_st(enum egl_g3d_st_api api)
-{
- static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS];
-
- if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) {
- all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit;
- return &all_trackers[api];
- }
- else {
- return NULL;
- }
-}
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 9c22ff3e43..93c81b26e1 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -140,9 +140,6 @@ struct native_config {
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;
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 507a0ec402..0000000000
--- 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 94588bfa74..7322240856 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
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.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
}
/* create textures */
@@ -100,7 +100,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) {
@@ -128,13 +128,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->texture_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;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 8d2a8b1dff..9839979231 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -114,6 +114,7 @@ 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 winsys_handle whandle;
uint valid_mask;
int i;
@@ -171,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->texture_from_handle(
+ dri2dpy->base.screen, &templ, &whandle);
if (dri2surf->textures[natt])
valid_mask |= 1 << natt;
}
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 7b4fe63fa0..c6eb17ab1a 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -142,16 +142,9 @@ native_create_display(EGLNativeDisplayType dpy,
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, event_handler, 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 8c6a7d9349..1566524926 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -30,8 +30,7 @@
struct native_display *
x11_create_ximage_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
- boolean use_xshm);
+ struct native_event_handler *event_handler);
struct native_display *
x11_create_dri2_display(EGLNativeDisplayType dpy,
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 3421c1951a..c6b16354f9 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -28,17 +28,19 @@
#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 "cell/ppu/cell_public.h"
#include "egllog.h"
-#include "sw_winsys.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -53,24 +55,18 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
- struct x11_screen *xscr;
- int xscr_number;
-
struct native_event_handler *event_handler;
- boolean use_xshm;
+ struct x11_screen *xscr;
+ int xscr_number;
- 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 xlib_drawable xdraw;
};
struct ximage_surface {
@@ -81,13 +77,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 {
@@ -121,18 +117,6 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
struct ximage_buffer *xbuf = &xsurf->buffers[which];
pipe_texture_reference(&xbuf->texture, NULL);
-
- if (xbuf->shm_info) {
- if (xbuf->xshm_attached)
- XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
- if (xbuf->shm_info->shmaddr != (void *) -1)
- shmdt(xbuf->shm_info->shmaddr);
- if (xbuf->shm_info->shmid != -1)
- shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
-
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->shmid = -1;
- }
}
static boolean
@@ -156,40 +140,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- if (xbuf->shm_info) {
- struct pipe_buffer *pbuf;
- unsigned stride, size;
- void *addr = NULL;
-
- stride = util_format_get_stride(xsurf->color_format, xsurf->width);
- /* alignment should depend on visual? */
- stride = align(stride, 4);
- size = stride * xsurf->height;
-
- /* create and attach shm object */
- xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
- if (xbuf->shm_info->shmid != -1) {
- xbuf->shm_info->shmaddr =
- shmat(xbuf->shm_info->shmid, NULL, 0);
- if (xbuf->shm_info->shmaddr != (void *) -1) {
- if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
- addr = xbuf->shm_info->shmaddr;
- xbuf->xshm_attached = TRUE;
- }
- }
- }
-
- if (addr) {
- pbuf = screen->user_buffer_create(screen, addr, size);
- if (pbuf) {
- xbuf->texture =
- screen->texture_blanket(screen, &templ, &stride, pbuf);
- pipe_buffer_reference(&pbuf, NULL);
- }
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+ switch (which) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ break;
+ default:
+ break;
}
}
- else {
- xbuf->texture = screen->texture_create(screen, &templ);
+ xbuf->texture = screen->texture_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 */
@@ -269,18 +238,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;
@@ -300,43 +261,26 @@ 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->ximage && xbuf->texture);
+ assert(xsurf->drawable && xbuf->texture);
- transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!transfer)
- return FALSE;
+ psurf = xsurf->draw_surface;
+ if (!psurf || psurf->texture != xbuf->texture) {
+ pipe_surface_reference(&xsurf->draw_surface, NULL);
- xbuf->ximage->bytes_per_line = transfer->stride;
- xbuf->ximage->data = screen->transfer_map(screen, transfer);
- if (!xbuf->ximage->data) {
- screen->tex_transfer_destroy(transfer);
- return FALSE;
- }
-
-
- if (xbuf->shm_info)
- XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
- else
- XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
-
- xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, transfer);
+ psurf = screen->get_tex_surface(screen,
+ xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
+ return FALSE;
- /*
- * softpipe allows the pipe transfer to be re-used, but we don't want to
- * rely on that behavior.
- */
- screen->tex_transfer_destroy(transfer);
+ xsurf->draw_surface = psurf;
+ }
- XSync(xsurf->xdpy->dpy, FALSE);
+ screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
return TRUE;
}
@@ -364,7 +308,8 @@ 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);
@@ -372,13 +317,12 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
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;
}
@@ -433,18 +377,11 @@ 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);
}
@@ -457,7 +394,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)
@@ -471,52 +407,8 @@ ximage_display_create_surface(struct native_display *ndpy,
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->base.destroy = ximage_surface_destroy;
@@ -727,7 +619,6 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
- free(xdpy->winsys);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
@@ -735,10 +626,63 @@ ximage_display_destroy(struct native_display *ndpy)
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,
- struct native_event_handler *event_handler,
- boolean use_xshm)
+ struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
@@ -756,6 +700,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
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) {
@@ -763,13 +709,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
return NULL;
}
- xdpy->event_handler = event_handler;
-
- 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;
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 33328aadf2..0000000000
--- 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/es/Makefile b/src/gallium/state_trackers/es/Makefile
index b036551271..089d441167 100644
--- a/src/gallium/state_trackers/es/Makefile
+++ b/src/gallium/state_trackers/es/Makefile
@@ -38,6 +38,8 @@ SYS_LIBS = -lm -pthread
INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
-I$(TOP)/src/gallium/include
.c.o:
diff --git a/src/gallium/state_trackers/es/st_es1.c b/src/gallium/state_trackers/es/st_es1.c
index 25bc53b21e..4e89e06b34 100644
--- a/src/gallium/state_trackers/es/st_es1.c
+++ b/src/gallium/state_trackers/es/st_es1.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES1 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES1 = {
+ .api = ST_API_OPENGL_ES1,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/es/st_es2.c b/src/gallium/state_trackers/es/st_es2.c
index 171ea62b97..82e88b176a 100644
--- a/src/gallium/state_trackers/es/st_es2.c
+++ b/src/gallium/state_trackers/es/st_es2.c
@@ -1,3 +1,8 @@
-#include "pipe/p_compiler.h"
+#include "state_tracker/st_manager.h"
PUBLIC const int st_api_OpenGL_ES2 = 1;
+
+PUBLIC const struct st_module st_module_OpenGL_ES2 = {
+ .api = ST_API_OPENGL_ES2,
+ .create_api = st_manager_create_api
+};
diff --git a/src/gallium/state_trackers/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 7b2adc62c3..35509fd708 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -5,12 +5,14 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
- -I$(TOP)/src/mesa
+ -I$(TOP)/src/mesa \
+ $(X11_CFLAGS)
C_SOURCES = \
glx_api.c \
glx_getproc.c \
glx_usefont.c \
- xm_api.c
+ xm_api.c \
+ xm_st.c
include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index fa96df357d..d6c16ad2f5 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -13,8 +13,6 @@ if env['platform'] == 'linux' \
'#/src/mesa/main',
])
- env.Append(CPPDEFINES = ['USE_XSHM'])
-
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
source = [
@@ -22,6 +20,7 @@ if env['platform'] == 'linux' \
'glx_getproc.c',
'glx_usefont.c',
'xm_api.c',
+ 'xm_st.c',
]
)
Export('st_xlib')
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 08bf624b5c..4930cd6cd5 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -35,12 +35,9 @@
#include "xm_api.h"
#include "main/context.h"
-#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/version.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
/* This indicates the client-side GLX API and GLX encoder version. */
@@ -689,7 +686,7 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
int desiredVisualID = -1;
int numAux = 0;
- xmesa_init();
+ xmesa_init( dpy );
parselist = list;
@@ -1304,7 +1301,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
}
- st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
+ XMesaCopyContext(xm_src, xm_dst, mask);
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index e8524a21c2..3022d45157 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -35,10 +35,6 @@
* corner of the window. Therefore, most drawing functions in this
* file have to flip Y coordinates.
*
- * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
- * in support for the MIT Shared Memory extension. If enabled, when you
- * use an Ximage for the back buffer in double buffered mode, the "swap"
- * operation will be faster. You must also link with -lXext.
*
* Byte swapping: If the Mesa host and the X display use a different
* byte order then there's some trickiness to be aware of when using
@@ -58,20 +54,14 @@
#endif
#include "xm_api.h"
-#include "main/context.h"
-#include "main/framebuffer.h"
+#include "xm_st.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
+#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#include "trace/tr_texture.h"
-
-#include "xm_winsys.h"
+#include "xm_public.h"
#include <GL/glx.h>
@@ -80,20 +70,78 @@
* global.
*/
static struct xm_driver driver;
+static struct st_api *stapi;
void xmesa_set_driver( const struct xm_driver *templ )
{
driver = *templ;
+ stapi = driver.create_st_api();
}
-/**
- * Global X driver lock
+
+/*
+ * XXX replace this with a linked list, or better yet, try to attach the
+ * gallium/mesa extra bits to the X Display object with XAddExtension().
*/
-pipe_mutex _xmesa_lock;
+#define MAX_DISPLAYS 10
+static struct xmesa_display Displays[MAX_DISPLAYS];
+static int NumDisplays = 0;
+
+
+static XMesaDisplay
+xmesa_init_display( Display *display )
+{
+ pipe_static_mutex(init_mutex);
+ XMesaDisplay xmdpy;
+ int i;
+
+ pipe_mutex_lock(init_mutex);
+
+ /* Look for XMesaDisplay which corresponds to 'display' */
+ for (i = 0; i < NumDisplays; i++) {
+ if (Displays[i].display == display) {
+ /* Found it */
+ pipe_mutex_unlock(init_mutex);
+ return &Displays[i];
+ }
+ }
+
+ /* Create new XMesaDisplay */
+
+ assert(NumDisplays < MAX_DISPLAYS);
+ xmdpy = &Displays[NumDisplays];
+ NumDisplays++;
-static struct pipe_screen *_screen = NULL;
-static struct pipe_screen *screen = NULL;
+ if (!xmdpy->display && display) {
+ xmdpy->display = display;
+ xmdpy->screen = driver.create_pipe_screen(display);
+ xmdpy->smapi = CALLOC_STRUCT(st_manager);
+ if (xmdpy->smapi)
+ xmdpy->smapi->screen = xmdpy->screen;
+ if (xmdpy->screen && xmdpy->smapi) {
+ pipe_mutex_init(xmdpy->mutex);
+ }
+ else {
+ if (xmdpy->screen) {
+ xmdpy->screen->destroy(xmdpy->screen);
+ xmdpy->screen = NULL;
+ }
+ if (xmdpy->smapi) {
+ FREE(xmdpy->smapi);
+ xmdpy->smapi = NULL;
+ }
+
+ xmdpy->display = NULL;
+ }
+ }
+ if (!xmdpy->display || xmdpy->display != display)
+ xmdpy = NULL;
+
+ pipe_mutex_unlock(init_mutex);
+
+ return xmdpy;
+}
/**********************************************************************/
/***** X Utility Functions *****/
@@ -111,41 +159,6 @@ static int host_byte_order( void )
}
-/**
- * Check if the X Shared Memory extension is available.
- * Return: 0 = not available
- * 1 = shared XImage support available
- * 2 = shared Pixmap support available also
- */
-int xmesa_check_for_xshm( Display *display )
-{
-#if defined(USE_XSHM)
- int major, minor, ignore;
- Bool pixmaps;
-
- if (getenv("SP_NO_RAST"))
- return 0;
-
- if (getenv("MESA_NOSHM")) {
- return 0;
- }
-
- if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
- if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
- return (pixmaps==True) ? 2 : 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
- }
-#else
- /* No XSHM support */
- return 0;
-#endif
-}
/**
@@ -238,12 +251,13 @@ void
xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height)
{
+ XMesaDisplay xmdpy = xmesa_init_display(dpy);
Status stat;
- pipe_mutex_lock(_xmesa_lock);
+ pipe_mutex_lock(xmdpy->mutex);
XSync(b->xm_visual->display, 0); /* added for Chromium */
- stat = get_drawable_size(dpy, b->drawable, width, height);
- pipe_mutex_unlock(_xmesa_lock);
+ stat = get_drawable_size(dpy, b->ws.drawable, width, height);
+ pipe_mutex_unlock(xmdpy->mutex);
if (!stat) {
/* probably querying a window that's recently been destroyed */
@@ -318,21 +332,18 @@ choose_pixel_format(XMesaVisual v)
}
-
/**
- * Query the default gallium screen for a Z/Stencil format that
- * at least matches the given depthBits and stencilBits.
+ * Choose a depth/stencil format that satisfies the given depth and
+ * stencil sizes.
*/
-static void
-xmesa_choose_z_stencil_format(int depth, int stencil,
- enum pipe_format *depthFormat,
- enum pipe_format *stencilFormat)
+static enum pipe_format
+choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
- enum pipe_format formats[8];
+ enum pipe_format formats[8], fmt;
int count, i;
count = 0;
@@ -352,21 +363,16 @@ xmesa_choose_z_stencil_format(int depth, int stencil,
formats[count++] = PIPE_FORMAT_Z32_UNORM;
}
- *depthFormat = PIPE_FORMAT_NONE;
+ fmt = PIPE_FORMAT_NONE;
for (i = 0; i < count; i++) {
- if (screen->is_format_supported(screen, formats[i],
+ if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i],
target, tex_usage, geom_flags)) {
- *depthFormat = formats[i];
+ fmt = formats[i];
break;
}
}
- if (stencil) {
- *stencilFormat = *depthFormat;
- }
- else {
- *stencilFormat = PIPE_FORMAT_NONE;
- }
+ return fmt;
}
@@ -375,7 +381,7 @@ xmesa_choose_z_stencil_format(int depth, int stencil,
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/
-XMesaBuffer XMesaBufferList = NULL;
+static XMesaBuffer XMesaBufferList = NULL;
/**
@@ -393,53 +399,33 @@ static XMesaBuffer
create_xmesa_buffer(Drawable d, BufferType type,
XMesaVisual vis, Colormap cmap)
{
+ XMesaDisplay xmdpy = xmesa_init_display(vis->display);
XMesaBuffer b;
- GLframebuffer *fb;
- enum pipe_format colorFormat, depthFormat, stencilFormat;
uint width, height;
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
+ if (!xmdpy)
+ return NULL;
+
b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
- b->drawable = d;
+ b->ws.drawable = d;
+ b->ws.visual = vis->visinfo->visual;
+ b->ws.depth = vis->visinfo->depth;
b->xm_visual = vis;
b->type = type;
b->cmap = cmap;
- /* determine PIPE_FORMATs for buffers */
- colorFormat = choose_pixel_format(vis);
-
- xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
- vis->mesa_visual.stencilBits,
- &depthFormat, &stencilFormat);
-
-
get_drawable_size(vis->display, d, &width, &height);
/*
* Create framebuffer, but we'll plug in our own renderbuffers below.
*/
- b->stfb = st_create_framebuffer(&vis->mesa_visual,
- colorFormat, depthFormat, stencilFormat,
- width, height,
- (void *) b);
- fb = &b->stfb->Base;
-
- /*
- * Create scratch XImage for xmesa_display_surface()
- */
- b->tempImage = XCreateImage(vis->display,
- vis->visinfo->visual,
- vis->visinfo->depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 32, /* bitmap_pad */
- 0); /* bytes_per_line */
+ b->stfb = xmesa_create_st_framebuffer(xmdpy, b);
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
@@ -483,29 +469,21 @@ xmesa_free_buffer(XMesaBuffer buffer)
for (b = XMesaBufferList; b; b = b->Next) {
if (b == buffer) {
- struct gl_framebuffer *fb = &buffer->stfb->Base;
-
/* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;
- /* mark as delete pending */
- fb->DeletePending = GL_TRUE;
-
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
- b->drawable = 0;
+ b->ws.drawable = 0;
- buffer->tempImage->data = NULL;
- XDestroyImage(buffer->tempImage);
-
- /* Unreference. If count = zero we'll really delete the buffer */
- _mesa_reference_framebuffer(&fb, NULL);
-
- XFreeGC(b->xm_visual->display, b->gc);
+ /* XXX we should move the buffer to a delete-pending list and destroy
+ * the buffer until it is no longer current.
+ */
+ xmesa_destroy_st_framebuffer(buffer->stfb);
free(buffer);
@@ -583,21 +561,6 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
}
- if (b && window) {
- /* these should have been set in create_xmesa_buffer */
- ASSERT(b->drawable == window);
-
- /* Setup for single/double buffering */
- if (v->mesa_visual.doubleBufferMode) {
- /* Double buffered */
- b->shm = xmesa_check_for_xshm( v->display );
- }
-
- /* X11 graphics context */
- b->gc = XCreateGC( v->display, window, 0, NULL );
- XSetFunction( v->display, b->gc, GXcopy );
- }
-
return GL_TRUE;
}
@@ -677,10 +640,12 @@ XMesaVisual XMesaCreateVisual( Display *display,
GLint level,
GLint visualCaveat )
{
+ XMesaDisplay xmdpy = xmesa_init_display(display);
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
- xmesa_init();
+ if (!xmdpy)
+ return NULL;
/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
@@ -762,6 +727,26 @@ XMesaVisual XMesaCreateVisual( Display *display,
accum_blue_size, accum_alpha_size,
0 );
+ v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ if (stereo_flag) {
+ v->stvis.buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
+ if (db_flag)
+ v->stvis.buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
+ }
+
+ v->stvis.color_format = choose_pixel_format(v);
+ v->stvis.depth_stencil_format =
+ choose_depth_stencil_format(xmdpy, depth_size, stencil_size);
+
+ v->stvis.accum_format = (accum_red_size +
+ accum_green_size + accum_blue_size + accum_alpha_size) ?
+ PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
+
+ v->stvis.samples = num_samples;
+ v->stvis.render_buffer = ST_ATTACHMENT_INVALID;
+
/* XXX minor hack */
v->mesa_visual.level = level;
return v;
@@ -777,18 +762,12 @@ void XMesaDestroyVisual( XMesaVisual v )
/**
- * Do one-time initializations.
+ * Do per-display initializations.
*/
void
-xmesa_init(void)
+xmesa_init( Display *display )
{
- static GLboolean firstTime = GL_TRUE;
- if (firstTime) {
- pipe_mutex_init(_xmesa_lock);
- _screen = driver.create_pipe_screen();
- screen = trace_screen_create( _screen );
- firstTime = GL_FALSE;
- }
+ xmesa_init_display(display);
}
@@ -802,51 +781,33 @@ xmesa_init(void)
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
- struct pipe_context *pipe = NULL;
+ XMesaDisplay xmdpy = xmesa_init_display(v->display);
XMesaContext c;
- GLcontext *mesaCtx;
- uint pf;
- xmesa_init();
+ if (!xmdpy)
+ return NULL;
/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
if (!c)
return NULL;
- pf = choose_pixel_format(v);
- assert(pf);
-
c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
- if (screen == NULL)
- goto fail;
-
- /* Trace screen knows how to properly wrap context creation in the
- * wrapped screen, so nothing special to do here:
- */
- pipe = screen->context_create(screen, (void *) c);
- if (pipe == NULL)
- goto fail;
-
- c->st = st_create_context(pipe,
- &v->mesa_visual,
- share_list ? share_list->st : NULL);
+ c->st = stapi->create_context(stapi, xmdpy->smapi,
+ &v->stvis, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
- mesaCtx = c->st->ctx;
- c->st->ctx->DriverCtx = c;
+ c->st->st_manager_private = (void *) c;
return c;
fail:
if (c->st)
- st_destroy_context(c->st);
- else if (pipe)
- pipe->destroy(pipe);
+ c->st->destroy(c->st);
free(c);
return NULL;
@@ -857,7 +818,7 @@ fail:
PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
- st_destroy_context(c->st);
+ c->st->destroy(c->st);
/* FIXME: We should destroy the screen here, but if we do so, surfaces may
* outlive it, causing segfaults
@@ -963,7 +924,6 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
{
GET_CURRENT_CONTEXT(ctx);
XMesaBuffer b;
- GLuint width, height;
assert(v);
@@ -971,19 +931,18 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
if (!b)
return NULL;
- /* get pixmap size, update framebuffer/renderbuffer dims */
- xmesa_get_window_size(v->display, b, &width, &height);
- _mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
+ /* get pixmap size */
+ xmesa_get_window_size(v->display, b, &b->width, &b->height);
if (target == 0) {
/* examine dims */
if (ctx->Extensions.ARB_texture_non_power_of_two) {
target = GLX_TEXTURE_2D_EXT;
}
- else if ( _mesa_bitcount(width) == 1
- && _mesa_bitcount(height) == 1) {
+ else if ( _mesa_bitcount(b->width) == 1
+ && _mesa_bitcount(b->height) == 1) {
/* power of two size */
- if (height == 1) {
+ if (b->height == 1) {
target = GLX_TEXTURE_1D_EXT;
}
else {
@@ -1056,23 +1015,20 @@ XMesaDestroyBuffer(XMesaBuffer b)
/**
- * Query the current window size and update the corresponding GLframebuffer
- * and all attached renderbuffers.
- * Called when:
- * 1. the first time a buffer is bound to a context.
- * 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
- * Note: it's possible (and legal) for xmctx to be NULL. That can happen
- * when resizing a buffer when no rendering context is bound.
+ * Query the current drawable size and notify the binding context.
*/
void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
+xmesa_check_buffer_size(XMesaBuffer b)
{
- GLuint width, height;
- xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
- st_resize_framebuffer(drawBuffer->stfb, width, height);
-}
+ XMesaContext xmctx = XMesaGetCurrentContext();
+ if (b->type == PBUFFER)
+ return;
+ xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
+ if (xmctx && xmctx->xm_buffer == b)
+ xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
+}
/*
@@ -1099,21 +1055,21 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_read_buffer == readBuffer)
return GL_TRUE;
+ xmesa_check_buffer_size(drawBuffer);
+ if (readBuffer != drawBuffer)
+ xmesa_check_buffer_size(readBuffer);
+
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
- st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
-
- xmesa_check_and_update_buffer_size(c, drawBuffer);
- if (readBuffer != drawBuffer)
- xmesa_check_and_update_buffer_size(c, readBuffer);
+ stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb);
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
- st_make_current( NULL, NULL, NULL );
+ stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
@@ -1132,14 +1088,8 @@ GLboolean XMesaUnbindContext( XMesaContext c )
XMesaContext XMesaGetCurrentContext( void )
{
- GET_CURRENT_CONTEXT(ctx);
- if (ctx) {
- XMesaContext xmesa = xmesa_context(ctx);
- return xmesa;
- }
- else {
- return 0;
- }
+ struct st_context_iface *st = stapi->get_current(stapi);
+ return (XMesaContext) (st) ? st->st_manager_private : NULL;
}
@@ -1151,21 +1101,17 @@ XMesaContext XMesaGetCurrentContext( void )
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
- struct pipe_surface *frontLeftSurf;
-
- st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
-
- if (frontLeftSurf) {
- if (_screen != screen) {
- struct trace_surface *tr_surf = trace_surface( frontLeftSurf );
- struct pipe_surface *surf = tr_surf->surface;
- frontLeftSurf = surf;
- }
-
- driver.display_surface(b, frontLeftSurf);
+ XMesaContext xmctx = XMesaGetCurrentContext();
+
+ if (xmctx && xmctx->xm_buffer == b) {
+ xmctx->st->flush( xmctx->st,
+ PIPE_FLUSH_RENDER_CACHE |
+ PIPE_FLUSH_SWAPBUFFERS |
+ PIPE_FLUSH_FRAME,
+ NULL);
}
- xmesa_check_and_update_buffer_size(NULL, b);
+ xmesa_swap_st_framebuffer(b->stfb);
}
@@ -1175,21 +1121,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
*/
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
- struct pipe_surface *surf_front;
- struct pipe_surface *surf_back;
- struct pipe_context *pipe = NULL; /* XXX fix */
-
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back);
-
- if (!surf_front || !surf_back)
- return;
-
- assert(pipe);
- pipe->surface_copy(pipe,
- surf_front, x, y, /* dest */
- surf_back, x, y, /* src */
- width, height);
+ xmesa_copy_st_framebuffer(b->stfb,
+ ST_ATTACHMENT_BACK_LEFT, ST_ATTACHMENT_FRONT_LEFT,
+ x, y, width, height);
}
@@ -1197,7 +1131,14 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
void XMesaFlush( XMesaContext c )
{
if (c && c->xm_visual->display) {
- st_finish(c->st);
+ XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display);
+ struct pipe_fence_handle *fence = NULL;
+
+ c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
+ if (fence) {
+ xmdpy->screen->fence_finish(xmdpy->screen, fence, 0);
+ xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL);
+ }
XSync( c->xm_visual->display, False );
}
}
@@ -1210,7 +1151,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
for (b = XMesaBufferList; b; b = b->Next) {
- if (b->drawable == d && b->xm_visual->display == dpy) {
+ if (b->ws.drawable == d && b->xm_visual->display == dpy) {
return b;
}
}
@@ -1244,10 +1185,10 @@ void XMesaGarbageCollect( void )
next = b->Next;
if (b->xm_visual &&
b->xm_visual->display &&
- b->drawable &&
+ b->ws.drawable &&
b->type == WINDOW) {
XSync(b->xm_visual->display, False);
- if (!window_exists( b->xm_visual->display, b->drawable )) {
+ if (!window_exists( b->xm_visual->display, b->ws.drawable )) {
/* found a dead window, free the ancillary info */
XMesaDestroyBuffer( b );
}
@@ -1271,3 +1212,10 @@ XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
{
}
+
+void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask)
+{
+ if (dst->st->copy)
+ dst->st->copy(dst->st, src->st, mask);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 004cb260dc..4f2c8a6e6a 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -58,25 +58,31 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "main/mtypes.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
+#include "state_tracker/st_api.h"
#include "os/os_thread.h"
+#include "state_tracker/xlib_sw_winsys.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
-# ifdef USE_XSHM /* was SHM */
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-# endif
+typedef struct xmesa_display *XMesaDisplay;
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
typedef struct xmesa_visual *XMesaVisual;
+struct xmesa_display {
+ pipe_mutex mutex;
+
+ Display *display;
+ struct pipe_screen *screen;
+ struct st_manager *smapi;
+
+ struct pipe_context *pipe;
+};
+
/*
* Create a new X/Mesa visual.
@@ -262,16 +268,13 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
int format, int target, int mipmap);
+extern void
+XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
/***********************************************************************
*/
-extern pipe_mutex _xmesa_lock;
-
-extern struct xmesa_buffer *XMesaBufferList;
-
-
/**
* Visual inforation, derived from GLvisual.
* Basically corresponds to an XVisualInfo.
@@ -284,6 +287,8 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
+
+ struct st_visual stvis;
};
@@ -292,7 +297,7 @@ struct xmesa_visual {
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
- struct st_context *st;
+ struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
@@ -315,7 +320,8 @@ typedef enum {
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
- struct st_framebuffer *stfb;
+ struct st_framebuffer_iface *stfb;
+ struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
@@ -329,13 +335,6 @@ struct xmesa_buffer {
XImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
- GLuint shm; /* X Shared Memory extension status: */
- /* 0 = not available */
- /* 1 = XImage support available */
- /* 2 = Pixmap support available too */
-#if defined(USE_XSHM)
- XShmSegmentInfo shminfo;
-#endif
GC gc; /* scratch GC for span, line, tri drawing */
@@ -345,32 +344,14 @@ struct xmesa_buffer {
GLint TextureMipmap; /** 0 or 1 */
struct xmesa_buffer *Next; /* Linked list pointer: */
-};
+ unsigned width, height;
+};
-/** cast wrapper */
-static INLINE XMesaContext
-xmesa_context(GLcontext *ctx)
-{
- return (XMesaContext) ctx->DriverCtx;
-}
-
-
-/** cast wrapper */
-static INLINE XMesaBuffer
-xmesa_buffer(GLframebuffer *fb)
-{
- struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
- return (XMesaBuffer) st_framebuffer_private(stfb);
-}
-
-
-extern void
-xmesa_init(void);
extern void
-xmesa_delete_framebuffer(struct gl_framebuffer *fb);
+xmesa_init(Display *dpy);
extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);
@@ -380,7 +361,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
-xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
+xmesa_check_buffer_size(XMesaBuffer b);
extern void
xmesa_destroy_buffers_on_display(Display *dpy);
@@ -388,17 +369,15 @@ xmesa_destroy_buffers_on_display(Display *dpy);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
{
- return b->stfb->Base.Width;
+ return b->width;
}
static INLINE GLuint
xmesa_buffer_height(XMesaBuffer b)
{
- return b->stfb->Base.Height;
+ return b->height;
}
-extern int
-xmesa_check_for_xshm(Display *display);
#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_public.h
index 4bd5b5c8d3..950eb21521 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_public.h
@@ -26,27 +26,23 @@
*
**************************************************************************/
-#ifndef XM_WINSYS_H
-#define XM_WINSYS_H
+#ifndef XM_PUBLIC_H
+#define XM_PUBLIC_H
-struct pipe_context;
-struct pipe_screen;
-struct pipe_surface;
-struct xmesa_buffer;
+#include <X11/Xlib.h>
+struct pipe_screen;
+struct st_api;
+/* This is the driver interface required by the glx/xlib state tracker.
+ */
struct xm_driver {
-
- struct pipe_screen *(*create_pipe_screen)( void );
-
- void (*display_surface)( struct xmesa_buffer *,
- struct pipe_surface * );
-
+ struct pipe_screen *(*create_pipe_screen)( Display *display );
+ struct st_api *(*create_st_api)( void );
};
-
extern void
xmesa_set_driver( const struct xm_driver *driver );
-#endif
+#endif /* XM_PUBLIC_H */
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c
new file mode 100644
index 0000000000..b6ed7e8e1e
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.c
@@ -0,0 +1,332 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "xm_api.h"
+#include "xm_st.h"
+
+struct xmesa_st_framebuffer {
+ XMesaDisplay display;
+ XMesaBuffer buffer;
+ struct pipe_screen *screen;
+
+ struct st_visual stvis;
+
+ unsigned texture_width, texture_height, texture_mask;
+ struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
+
+ struct pipe_surface *display_surface;
+};
+
+static INLINE struct xmesa_st_framebuffer *
+xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
+}
+
+/**
+ * Display an attachment to the xlib_drawable of the framebuffer.
+ */
+static boolean
+xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *ptex = xstfb->textures[statt];
+ struct pipe_surface *psurf;
+
+ if (!ptex)
+ return TRUE;
+
+ psurf = xstfb->display_surface;
+ /* (re)allocate the surface for the texture to be displayed */
+ if (!psurf || psurf->texture != ptex) {
+ pipe_surface_reference(&xstfb->display_surface, NULL);
+
+ psurf = xstfb->screen->get_tex_surface(xstfb->screen,
+ ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
+ return FALSE;
+
+ xstfb->display_surface = psurf;
+ }
+
+ xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+
+ return TRUE;
+}
+
+/**
+ * Copy the contents between the attachments.
+ */
+static void
+xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src_statt,
+ enum st_attachment_type dst_statt,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture *src_ptex = xstfb->textures[src_statt];
+ struct pipe_texture *dst_ptex = xstfb->textures[dst_statt];
+ struct pipe_surface *src, *dst;
+ struct pipe_context *pipe;
+
+ if (!src_ptex || !dst_ptex)
+ return;
+
+ pipe = xstfb->display->pipe;
+ if (!pipe) {
+ pipe = xstfb->screen->context_create(xstfb->screen, NULL);
+ if (!pipe)
+ return;
+ xstfb->display->pipe = pipe;
+ }
+
+ src = xstfb->screen->get_tex_surface(xstfb->screen,
+ src_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ dst = xstfb->screen->get_tex_surface(xstfb->screen,
+ dst_ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ if (src && dst)
+ pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height);
+
+ pipe_surface_reference(&src, NULL);
+ pipe_surface_reference(&dst, NULL);
+}
+
+/**
+ * Remove outdated textures and create the requested ones.
+ */
+static void
+xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
+ unsigned width, unsigned height,
+ unsigned mask)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ struct pipe_texture templ;
+ unsigned i;
+
+ /* remove outdated textures */
+ if (xstfb->texture_width != width || xstfb->texture_height != height) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+ }
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned tex_usage;
+
+ /* the texture already exists or not requested */
+ if (xstfb->textures[i] || !(mask & (1 << i))) {
+ /* remember the texture */
+ if (xstfb->textures[i])
+ mask |= (1 << i);
+ continue;
+ }
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = xstfb->stvis.color_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = xstfb->stvis.depth_stencil_format;
+ tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templ.format = format;
+ templ.tex_usage = tex_usage;
+
+ xstfb->textures[i] =
+ xstfb->screen->texture_create(xstfb->screen, &templ);
+ }
+ }
+
+ xstfb->texture_width = width;
+ xstfb->texture_height = height;
+ xstfb->texture_mask = mask;
+}
+
+static boolean
+xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
+ const enum st_attachment_type *statts,
+ unsigned count,
+ struct pipe_texture **out)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ unsigned statt_mask, new_mask, i;
+ boolean resized;
+
+ statt_mask = 0x0;
+ for (i = 0; i < count; i++)
+ statt_mask |= 1 << statts[i];
+ /* record newly allocated textures */
+ new_mask = statt_mask & ~xstfb->texture_mask;
+
+ resized = (xstfb->buffer->width != xstfb->texture_width ||
+ xstfb->buffer->height != xstfb->texture_height);
+
+ /* revalidate textures */
+ if (resized || new_mask) {
+ xmesa_st_framebuffer_validate_textures(stfbi,
+ xstfb->buffer->width, xstfb->buffer->height, statt_mask);
+
+ if (!resized) {
+ enum st_attachment_type back, front;
+
+ back = ST_ATTACHMENT_BACK_LEFT;
+ front = ST_ATTACHMENT_FRONT_LEFT;
+ /* copy the contents if front is newly allocated and back is not */
+ if ((statt_mask & (1 << back)) &&
+ (new_mask & (1 << front)) &&
+ !(new_mask & (1 << back))) {
+ xmesa_st_framebuffer_copy_textures(stfbi, back, front,
+ 0, 0, xstfb->texture_width, xstfb->texture_height);
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_texture_reference(&out[i], xstfb->textures[statts[i]]);
+ }
+
+ return TRUE;
+}
+
+static boolean
+xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type statt)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, statt);
+ if (ret)
+ xmesa_check_buffer_size(xstfb->buffer);
+
+ return ret;
+}
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b)
+{
+ struct st_framebuffer_iface *stfbi;
+ struct xmesa_st_framebuffer *xstfb;
+
+ assert(xmdpy->display == b->xm_visual->display);
+
+ stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
+ if (!stfbi || !xstfb) {
+ if (stfbi)
+ FREE(stfbi);
+ if (xstfb)
+ FREE(xstfb);
+ return NULL;
+ }
+
+ xstfb->display = xmdpy;
+ xstfb->buffer = b;
+ xstfb->screen = xmdpy->screen;
+ xstfb->stvis = b->xm_visual->stvis;
+
+ stfbi->visual = &xstfb->stvis;
+ stfbi->flush_front = xmesa_st_framebuffer_flush_front;
+ stfbi->validate = xmesa_st_framebuffer_validate;
+ stfbi->st_manager_private = (void *) xstfb;
+
+ return stfbi;
+}
+
+void
+xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ int i;
+
+ pipe_surface_reference(&xstfb->display_surface, NULL);
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_texture_reference(&xstfb->textures[i], NULL);
+
+ FREE(xstfb);
+ FREE(stfbi);
+}
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
+ boolean ret;
+
+ ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT);
+ if (ret) {
+ struct pipe_texture **front, **back, *tmp;
+
+ front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
+ back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
+ /* swap textures only if the front texture has been allocated */
+ if (*front) {
+ tmp = *front;
+ *front = *back;
+ *back = tmp;
+ }
+
+ xmesa_check_buffer_size(xstfb->buffer);
+ }
+}
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h)
+{
+ xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
+ if (dst == ST_ATTACHMENT_FRONT_LEFT)
+ xmesa_st_framebuffer_display(stfbi, dst);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.h b/src/gallium/state_trackers/glx/xlib/xm_st.h
new file mode 100644
index 0000000000..396495c189
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/xm_st.h
@@ -0,0 +1,51 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _XM_ST_H_
+#define _XM_ST_H_
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/st_api.h"
+
+#include "xm_api.h"
+
+struct st_framebuffer_iface *
+xmesa_create_st_framebuffer(XMesaDisplay xmdpy, XMesaBuffer b);
+
+void
+xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi);
+
+void
+xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
+ enum st_attachment_type src,
+ enum st_attachment_type dst,
+ int x, int y, int w, int h);
+
+#endif /* _XM_ST_H_ */
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 527e065cd9..d0d141fd24 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -3,7 +3,8 @@ import os.path
Import('*')
-if 'python' in env['statetrackers']:
+if 'python' in env['statetrackers'] and 0:
+ # FIXME: Disable python state tracker until transfers are done by contexts
env = env.Clone()
@@ -24,6 +25,7 @@ if 'python' in env['statetrackers']:
'ws2_32',
])
else:
+ env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY'])
env.Append(LIBS = [
'GL',
'X11',
@@ -33,31 +35,27 @@ if 'python' in env['statetrackers']:
'gallium.i',
'st_device.c',
'st_sample.c',
+ 'st_hardpipe_winsys.c',
+ 'st_softpipe_winsys.c',
]
- drivers = [
- trace
- ]
+ env.Prepend(LIBS = [
+ ws_null,
+ trace,
+ gallium,
+ ])
if 'llvmpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_LLVMPIPE'])
env.Tool('llvm')
- sources += ['st_llvmpipe_winsys.c']
- drivers += [llvmpipe]
- else:
- sources += ['st_softpipe_winsys.c']
- drivers += [softpipe]
-
- pyst = env.ConvenienceLibrary(
- target = 'pyst',
- source = sources,
- )
+ env.Prepend(LIBS = [llvmpipe])
+ if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_SOFTPIPE'])
+ env.Prepend(LIBS = [softpipe])
env['no_import_lib'] = 1
env.SharedLibrary(
target = '_gallium',
- source = [
- 'st_hardpipe_winsys.c',
- ],
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
+ source = sources,
)
diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i
index ffb084e358..632d71ccbe 100644
--- a/src/gallium/state_trackers/python/gallium.i
+++ b/src/gallium/state_trackers/python/gallium.i
@@ -49,6 +49,7 @@
#include "util/u_format.h"
#include "util/u_dump.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
#include "tgsi/tgsi_text.h"
#include "tgsi/tgsi_dump.h"
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 3f36ccb621..df700bc663 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -51,7 +51,7 @@ struct st_context {
void set_blend( const struct pipe_blend_state *state ) {
cso_set_blend($self->cso, state);
}
-
+
void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) {
cso_single_sampler($self->cso, index, state);
cso_single_sampler_done($self->cso);
@@ -169,22 +169,39 @@ struct st_context {
void set_fragment_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->fragment_sampler_textures[index], texture);
- $self->pipe->set_fragment_sampler_textures($self->pipe,
- PIPE_MAX_SAMPLERS,
- $self->fragment_sampler_textures);
+ pipe_sampler_view_reference(&$self->fragment_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->fragment_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+ $self->pipe->set_fragment_sampler_views($self->pipe,
+ PIPE_MAX_SAMPLERS,
+ $self->fragment_sampler_views);
}
void set_vertex_sampler_texture(unsigned index,
struct pipe_texture *texture) {
+ struct pipe_sampler_view templ;
+
if(!texture)
texture = $self->default_texture;
- pipe_texture_reference(&$self->vertex_sampler_textures[index], texture);
- $self->pipe->set_vertex_sampler_textures($self->pipe,
- PIPE_MAX_VERTEX_SAMPLERS,
- $self->vertex_sampler_textures);
+ pipe_sampler_view_reference(&$self->vertex_sampler_views[index], NULL);
+ u_sampler_view_default_template(&templ,
+ texture,
+ texture->format);
+ $self->vertex_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe,
+ texture,
+ &templ);
+
+ $self->pipe->set_vertex_sampler_views($self->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ $self->vertex_sampler_views);
}
void set_vertex_buffer(unsigned index,
@@ -222,9 +239,9 @@ struct st_context {
void set_vertex_elements(unsigned num)
{
$self->num_vertex_elements = num;
- $self->pipe->set_vertex_elements($self->pipe,
- $self->num_vertex_elements,
- $self->vertex_elements);
+ cso_set_vertex_elements($self->cso,
+ $self->num_vertex_elements,
+ $self->vertex_elements);
}
/*
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index 45e7841750..0d87c705e7 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -33,9 +33,9 @@
#include "cso_cache/cso_context.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
+#include "trace/tr_public.h"
#include "st_device.h"
#include "st_winsys.h"
@@ -75,43 +75,34 @@ st_device_destroy(struct st_device *st_dev)
}
-static struct st_device *
-st_device_create_from_st_winsys(const struct st_winsys *st_ws)
+struct st_device *
+st_device_create(boolean hardware)
{
+ struct pipe_screen *screen;
struct st_device *st_dev;
-
- if(!st_ws->screen_create)
- return NULL;
-
+
+ if (hardware)
+ screen = st_hardware_screen_create();
+ else
+ screen = st_software_screen_create();
+
+ screen = trace_screen_create(screen);
+ if (!screen)
+ goto no_screen;
+
st_dev = CALLOC_STRUCT(st_device);
- if(!st_dev)
- return NULL;
+ if (!st_dev)
+ goto no_device;
pipe_reference_init(&st_dev->reference, 1);
- st_dev->st_ws = st_ws;
-
- st_dev->real_screen = st_ws->screen_create();
- if(!st_dev->real_screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
-
- st_dev->screen = trace_screen_create(st_dev->real_screen);
- if(!st_dev->screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
+ st_dev->screen = screen;
return st_dev;
-}
-
-struct st_device *
-st_device_create(boolean hardware) {
- if(hardware)
- return st_device_create_from_st_winsys(&st_hardpipe_winsys);
- else
- return st_device_create_from_st_winsys(&st_softpipe_winsys);
+no_device:
+ screen->destroy(screen);
+no_screen:
+ return NULL;
}
@@ -134,9 +125,9 @@ st_context_destroy(struct st_context *st_ctx)
st_ctx->pipe->destroy(st_ctx->pipe);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], NULL);
for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], NULL);
pipe_texture_reference(&st_ctx->default_texture, NULL);
FREE(st_ctx);
@@ -240,6 +231,8 @@ st_context_create(struct st_device *st_dev)
struct pipe_screen *screen = st_dev->screen;
struct pipe_texture templat;
struct pipe_transfer *transfer;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
unsigned i;
memset( &templat, 0, sizeof( templat ) );
@@ -269,14 +262,27 @@ st_context_create(struct st_device *st_dev)
screen->tex_transfer_destroy(transfer);
}
}
-
+
+ u_sampler_view_default_template(&view_templ,
+ st_ctx->default_texture,
+ st_ctx->default_texture->format);
+ view = st_ctx->pipe->create_sampler_view(st_ctx->pipe,
+ st_ctx->default_texture,
+ &view_templ);
+
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture);
+ pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], view);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
- pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture);
-
- cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures);
- cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures);
+ pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], view);
+
+ st_ctx->pipe->set_fragment_sampler_views(st_ctx->pipe,
+ PIPE_MAX_SAMPLERS,
+ st_ctx->fragment_sampler_views);
+ st_ctx->pipe->set_vertex_sampler_views(st_ctx->pipe,
+ PIPE_MAX_VERTEX_SAMPLERS,
+ st_ctx->vertex_sampler_views);
+
+ pipe_sampler_view_reference(&view, NULL);
}
/* vertex shader */
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index de9e0215d8..dcd0dc6e27 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -47,7 +47,8 @@ struct st_surface
};
-struct st_context {
+struct st_context
+{
struct st_device *st_dev;
struct pipe_context *pipe;
@@ -59,8 +60,8 @@ struct st_context {
void *gs;
struct pipe_texture *default_texture;
- struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS];
- struct pipe_texture *vertex_sampler_textures[PIPE_MAX_VERTEX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
unsigned num_vertex_buffers;
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
@@ -72,13 +73,11 @@ struct st_context {
};
-struct st_device {
+struct st_device
+{
/* FIXME: we also need to refcount for textures and surfaces... */
struct pipe_reference reference;
- const struct st_winsys *st_ws;
-
- struct pipe_screen *real_screen;
struct pipe_screen *screen;
};
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index a3110a19d5..b141177b79 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -54,11 +54,6 @@ static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
#ifdef PIPE_OS_WINDOWS
static INLINE boolean
@@ -207,16 +202,11 @@ st_hardpipe_load(void)
#endif
-static struct pipe_screen *
-st_hardpipe_screen_create(void)
+struct pipe_screen *
+st_hardware_screen_create(void)
{
if(st_hardpipe_load())
return pfnGetGalliumScreenMESA();
else
- return st_softpipe_winsys.screen_create();
+ return st_software_screen_create();
}
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &st_hardpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
deleted file mode 100644
index 5d83b5a9e1..0000000000
--- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * 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 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
- * THE COPYRIGHT HOLDERS, AUTHORS 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.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Llvmpipe support.
- *
- * @author Jose Fonseca
- */
-
-
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "st_winsys.h"
-
-
-static boolean
-llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
- enum pipe_format format )
-{
- return FALSE;
-}
-
-
-static void *
-llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags )
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
-{
- assert(0);
-}
-
-
-static struct llvmpipe_displaytarget *
-llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride)
-{
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-st_llvmpipe_screen_create(void)
-{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if (!winsys)
- goto no_winsys;
-
- winsys->destroy = llvmpipe_ws_destroy;
- winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported;
- winsys->displaytarget_create = llvmpipe_ws_displaytarget_create;
- winsys->displaytarget_map = llvmpipe_ws_displaytarget_map;
- winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap;
- winsys->displaytarget_display = llvmpipe_ws_displaytarget_display;
- winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy;
-
- screen = llvmpipe_create_screen(winsys);
- if (!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
-}
-
-
-
-const struct st_winsys st_softpipe_winsys = {
- &st_llvmpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 81676bc3a4..985374190c 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -26,18 +26,47 @@
*
**************************************************************************/
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-#include "softpipe/sp_winsys.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "state_tracker/sw_winsys.h"
+#include "null/null_sw_winsys.h"
#include "st_winsys.h"
-const struct st_winsys st_softpipe_winsys = {
- &softpipe_create_screen_malloc
-};
+
+struct pipe_screen *
+st_software_screen_create(void)
+{
+ struct sw_winsys *ws;
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(HAVE_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(HAVE_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ ws = null_sw_create();
+ if(!ws)
+ return NULL;
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#ifdef HAVE_LLVMPIPE
+ if (strcmp(driver, "llvmpipe") == 0) {
+ screen = llvmpipe_create_screen(ws);
+ }
+#endif
+
+#ifdef HAVE_SOFTPIPE
+ if (strcmp(driver, "softpipe") == 0) {
+ screen = softpipe_create_screen(ws);
+ }
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index 0c7b6a200e..e1a99383a4 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -31,19 +31,13 @@
struct pipe_screen;
-struct pipe_context;
-struct st_winsys
-{
- struct pipe_screen *
- (*screen_create)(void);
-};
+struct pipe_screen *
+st_hardware_screen_create(void);
-
-extern const struct st_winsys st_softpipe_winsys;
-
-extern const struct st_winsys st_hardpipe_winsys;
+struct pipe_screen *
+st_software_screen_create(void);
#endif /* ST_WINSYS_H_ */
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 037d8dc911..7c315de827 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -25,6 +25,7 @@ VG_SOURCES = \
api_transform.c \
vgu.c \
vg_context.c \
+ vg_manager.c \
vg_state.c \
vg_tracker.c \
vg_translate.c \
@@ -53,7 +54,7 @@ INCLUDE_DIRS = \
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c
index 47db102dd2..eb2fbe26e7 100644
--- a/src/gallium/state_trackers/vega/api_context.c
+++ b/src/gallium/state_trackers/vega/api_context.c
@@ -26,6 +26,7 @@
#include "VG/openvg.h"
+#include "vg_manager.h"
#include "vg_context.h"
#include "pipe/p_context.h"
@@ -55,6 +56,8 @@ void vgFlush(void)
pipe = ctx->pipe;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ vg_manager_flush_frontbuffer(ctx);
}
void vgFinish(void)
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 02248ad433..a643f38624 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -40,6 +40,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_sampler.h"
#include "asm_filters.h"
@@ -53,7 +54,7 @@ struct filter_info {
const void *const_buffer;
VGint const_buffer_len;
VGTilingMode tiling_mode;
- struct pipe_texture *extra_texture;
+ struct pipe_sampler_view *extra_texture_view;
};
static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
@@ -78,26 +79,48 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
{ /* upload color_data */
struct pipe_transfer *transfer =
- screen->get_tex_transfer(screen, tex,
- 0, 0, 0,
- PIPE_TRANSFER_READ_WRITE ,
- 0, 0, tex->width0, tex->height0);
- void *map = screen->transfer_map(screen, transfer);
+ pipe->get_tex_transfer(pipe, tex,
+ 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE ,
+ 0, 0, tex->width0, tex->height0);
+ void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, color_data, sizeof(VGint)*color_data_len);
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
return tex;
}
+static INLINE struct pipe_sampler_view *create_texture_1d_view(struct vg_context *ctx,
+ const VGuint *color_data,
+ const VGint color_data_len)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_texture_1d(ctx, color_data, color_data_len);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
static INLINE struct pipe_surface * setup_framebuffer(struct vg_image *dst)
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
struct pipe_framebuffer_state fb;
struct pipe_surface *dst_surf = pipe->screen->get_tex_surface(
- pipe->screen, dst->texture, 0, 0, 0,
+ pipe->screen, dst->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* drawing dest */
@@ -168,7 +191,7 @@ static void setup_constant_buffer(struct vg_context *ctx, const void *buffer,
static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state sampler[3];
int num_samplers = 0;
int num_textures = 0;
@@ -177,10 +200,10 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
+ sampler_views[2] = NULL;
+ sampler_views[3] = NULL;
memset(&sampler[0], 0, sizeof(struct pipe_sampler_state));
sampler[0].wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -215,21 +238,21 @@ static void setup_samplers(struct vg_context *ctx, struct filter_info *info)
}
samplers[0] = &sampler[0];
- textures[0] = info->src->texture;
+ sampler_views[0] = info->src->sampler_view;
++num_samplers;
++num_textures;
- if (info->extra_texture) {
+ if (info->extra_texture_view) {
memcpy(&sampler[1], &sampler[0], sizeof(struct pipe_sampler_state));
samplers[1] = &sampler[1];
- textures[1] = info->extra_texture;
+ sampler_views[1] = info->extra_texture_view;
++num_samplers;
++num_textures;
}
cso_set_samplers(ctx->cso_context, num_samplers, (const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, num_textures, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, num_textures, sampler_views);
}
static struct vg_shader * setup_color_matrix(struct vg_context *ctx, void *user_data)
@@ -308,7 +331,7 @@ static void execute_filter(struct vg_context *ctx,
cso_save_viewport(ctx->cso_context);
cso_save_blend(ctx->cso_context);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
+ cso_save_fragment_sampler_views(ctx->cso_context);
dst_surf = setup_framebuffer(info->dst);
setup_viewport(info->dst);
@@ -318,7 +341,7 @@ static void execute_filter(struct vg_context *ctx,
setup_samplers(ctx, info);
renderer_draw_texture(ctx->renderer,
- info->src->texture,
+ info->src->sampler_view->texture,
info->dst->x, info->dst->y,
info->dst->x + info->dst->width,
info->dst->y + info->dst->height,
@@ -331,7 +354,7 @@ static void execute_filter(struct vg_context *ctx,
cso_restore_viewport(ctx->cso_context);
cso_restore_blend(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
vg_shader_destroy(ctx, shader);
@@ -369,7 +392,7 @@ void vgColorMatrix(VGImage dst, VGImage src,
info.const_buffer = matrix;
info.const_buffer_len = 20 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
}
@@ -479,7 +502,7 @@ void vgConvolve(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -669,7 +692,7 @@ void vgGaussianBlur(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = buffer_len * sizeof(VGfloat);
info.tiling_mode = tilingMode;
- info.extra_texture = 0;
+ info.extra_texture_view = NULL;
execute_filter(ctx, &info);
free(buffer);
@@ -688,7 +711,7 @@ void vgLookup(VGImage dst, VGImage src,
struct vg_image *d, *s;
VGuint color_data[256];
VGint i;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
@@ -714,7 +737,7 @@ void vgLookup(VGImage dst, VGImage src,
color_data[i] = blueLUT[i] << 24 | greenLUT[i] << 16 |
redLUT[i] << 8 | alphaLUT[i];
}
- lut_texture = create_texture_1d(ctx, color_data, 255);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 255);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -728,11 +751,11 @@ void vgLookup(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
void vgLookupSingle(VGImage dst, VGImage src,
@@ -743,7 +766,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
{
struct vg_context *ctx = vg_current_context();
struct vg_image *d, *s;
- struct pipe_texture *lut_texture;
+ struct pipe_sampler_view *lut_texture_view;
VGfloat buffer[4];
struct filter_info info;
VGuint color_data[256];
@@ -783,7 +806,7 @@ void vgLookupSingle(VGImage dst, VGImage src,
color_data[i] = blue << 24 | green << 16 |
red << 8 | alpha;
}
- lut_texture = create_texture_1d(ctx, color_data, 256);
+ lut_texture_view = create_texture_1d_view(ctx, color_data, 256);
buffer[0] = 0.f;
buffer[1] = 0.f;
@@ -797,9 +820,9 @@ void vgLookupSingle(VGImage dst, VGImage src,
info.const_buffer = buffer;
info.const_buffer_len = 4 * sizeof(VGfloat);
info.tiling_mode = VG_TILE_PAD;
- info.extra_texture = lut_texture;
+ info.extra_texture_view = lut_texture_view;
execute_filter(ctx, &info);
- pipe_texture_reference(&lut_texture, NULL);
+ pipe_sampler_view_reference(&lut_texture_view, NULL);
}
diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c
index 015241498e..fec473d9d2 100644
--- a/src/gallium/state_trackers/vega/api_images.c
+++ b/src/gallium/state_trackers/vega/api_images.c
@@ -397,7 +397,6 @@ void vgReadPixels(void * data, VGint dataStride,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
@@ -442,7 +441,7 @@ void vgReadPixels(void * data, VGint dataStride,
{
struct pipe_transfer *transfer;
- transfer = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0,
+ transfer = pipe->get_tex_transfer(pipe, strb->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0, width, height);
@@ -451,14 +450,14 @@ void vgReadPixels(void * data, VGint dataStride,
#if 0
debug_printf("%d-%d == %d\n", sy, height, y);
#endif
- pipe_get_tile_rgba(transfer, sx, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, transfer, sx, y, width, 1, df);
y += yStep;
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat,
dst + yoffset + xoffset);
dst += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 9c123a4cf9..2f2d925252 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st,
/* draw */
if (buf) {
+ cso_set_vertex_elements(st->cso_context, 2, st->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -115,10 +117,6 @@ clear_with_quad(struct vg_context *st, float x0, float y0,
x1, y1);
*/
- if (st->pipe->screen && st->pipe->screen->update_buffer)
- st->pipe->screen->update_buffer( st->pipe->screen,
- st->pipe->priv );
-
cso_save_blend(st->cso_context);
cso_save_rasterizer(st->cso_context);
cso_save_fragment_shader(st->cso_context);
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 41c979bfec..c3268a84a6 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -43,6 +43,7 @@
#include "util/u_tile.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
static enum pipe_format vg_format_to_pipe(VGImageFormat format)
{
@@ -81,7 +82,7 @@ static INLINE void vg_sync_size(VGfloat *src_loc, VGfloat *dst_loc)
static void vg_copy_texture(struct vg_context *ctx,
struct pipe_texture *dst, VGint dx, VGint dy,
- struct pipe_texture *src, VGint sx, VGint sy,
+ struct pipe_sampler_view *src, VGint sx, VGint sy,
VGint width, VGint height)
{
VGfloat dst_loc[4], src_loc[4];
@@ -103,8 +104,8 @@ static void vg_copy_texture(struct vg_context *ctx,
src_loc[3] = height;
src_bounds[0] = 0.f;
src_bounds[1] = 0.f;
- src_bounds[2] = src->width0;
- src_bounds[3] = src->height0;
+ src_bounds[2] = src->texture->width0;
+ src_bounds[3] = src->texture->height0;
vg_bound_rect(src_loc, src_bounds, src_shift);
vg_bound_rect(dst_loc, dst_bounds, dst_shift);
@@ -218,7 +219,7 @@ void vg_copy_surface(struct vg_context *ctx,
static struct pipe_texture *image_texture(struct vg_image *img)
{
- struct pipe_texture *tex = img->texture;
+ struct pipe_texture *tex = img->sampler_view->texture;
return tex;
}
@@ -247,9 +248,12 @@ struct vg_image * image_create(VGImageFormat format,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_context *pipe = ctx->pipe;
struct vg_image *image = CALLOC_STRUCT(vg_image);
enum pipe_format pformat = vg_format_to_pipe(format);
struct pipe_texture pt, *newtex;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_screen *screen = ctx->pipe->screen;
vg_init_object(&image->base, ctx, VG_OBJECT_IMAGE);
@@ -281,7 +285,12 @@ struct vg_image * image_create(VGImageFormat format,
debug_assert(newtex);
- image->texture = newtex;
+ u_sampler_view_default_template(&view_templ, newtex, newtex->format);
+ view = pipe->create_sampler_view(pipe, newtex, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&newtex, NULL);
+
+ image->sampler_view = view;
vg_context_add_object(ctx, VG_OBJECT_IMAGE, image);
@@ -345,7 +354,7 @@ void image_destroy(struct vg_image *img)
array_destroy(img->children_array);
}
- pipe_texture_reference(&img->texture, NULL);
+ pipe_sampler_view_reference(&img->sampler_view, NULL);
free(img);
}
@@ -378,7 +387,7 @@ void image_sub_data(struct vg_image *image,
VGfloat *df = (VGfloat*)temp;
VGint i;
struct vg_context *ctx = vg_current_context();
- struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_context *pipe = ctx->pipe;
struct pipe_texture *texture = image_texture(image);
VGint xoffset = 0, yoffset = 0;
@@ -412,17 +421,17 @@ void image_sub_data(struct vg_image *image,
}
{ /* upload color_data */
- struct pipe_transfer *transfer = screen->get_tex_transfer(
- screen, texture, 0, 0, 0,
+ struct pipe_transfer *transfer = pipe->get_tex_transfer(
+ pipe, texture, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, texture->width0, texture->height0);
src += (dataStride * yoffset);
for (i = 0; i < height; i++) {
_vega_unpack_float_span_rgba(ctx, width, xoffset, src, dataFormat, temp);
- pipe_put_tile_rgba(transfer, x+image->x, y+image->y, width, 1, df);
+ pipe_put_tile_rgba(pipe, transfer, x+image->x, y+image->y, width, 1, df);
y += yStep;
src += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
@@ -435,7 +444,6 @@ void image_get_sub_data(struct vg_image * image,
{
struct vg_context *ctx = vg_current_context();
struct pipe_context *pipe = ctx->pipe;
- struct pipe_screen *screen = pipe->screen;
VGfloat temp[VEGA_MAX_IMAGE_WIDTH][4];
VGfloat *df = (VGfloat*)temp;
VGint y = 0, yStep = 1;
@@ -444,8 +452,8 @@ void image_get_sub_data(struct vg_image * image,
{
struct pipe_transfer *transfer =
- screen->get_tex_transfer(screen,
- image->texture, 0, 0, 0,
+ pipe->get_tex_transfer(pipe,
+ image->sampler_view->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0,
image->x + image->width,
@@ -455,13 +463,13 @@ void image_get_sub_data(struct vg_image * image,
#if 0
debug_printf("%d-%d == %d\n", sy, height, y);
#endif
- pipe_get_tile_rgba(transfer, sx+image->x, y, width, 1, df);
+ pipe_get_tile_rgba(pipe, transfer, sx+image->x, y, width, 1, df);
y += yStep;
_vega_pack_rgba_span_float(ctx, width, temp, dataFormat, dst);
dst += dataStride;
}
- screen->tex_transfer_destroy(transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
}
@@ -479,9 +487,9 @@ struct vg_image * image_child_image(struct vg_image *parent,
image->width = width;
image->height = height;
image->parent = parent;
- image->texture = 0;
- pipe_texture_reference(&image->texture,
- parent->texture);
+ image->sampler_view = NULL;
+ pipe_sampler_view_reference(&image->sampler_view,
+ parent->sampler_view);
image->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
image->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -515,8 +523,8 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy,
}
/* make sure rendering has completed */
ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
- vg_copy_texture(ctx, dst->texture, dst->x + dx, dst->y + dy,
- src->texture, src->x + sx, src->y + sy, width, height);
+ vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy,
+ src->sampler_view, src->x + sx, src->y + sy, width, height);
}
void image_draw(struct vg_image *img)
@@ -625,12 +633,12 @@ VGboolean vg_image_overlaps(struct vg_image *dst,
}
VGint image_bind_samplers(struct vg_image *img, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
img->sampler.min_img_filter = image_sampler_filter(img->base.ctx);
img->sampler.mag_img_filter = image_sampler_filter(img->base.ctx);
samplers[3] = &img->sampler;
- textures[3] = img->texture;
+ sampler_views[3] = img->sampler_view;
return 1;
}
diff --git a/src/gallium/state_trackers/vega/image.h b/src/gallium/state_trackers/vega/image.h
index 78e17cffa6..805b35fab9 100644
--- a/src/gallium/state_trackers/vega/image.h
+++ b/src/gallium/state_trackers/vega/image.h
@@ -43,7 +43,7 @@ struct vg_image {
struct vg_image *parent;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
struct array *children_array;
@@ -89,7 +89,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy,
VGint width, VGint height);
VGint image_bind_samplers(struct vg_image *dst, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGboolean vg_image_overlaps(struct vg_image *dst,
struct vg_image *src);
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 839dc19a3b..316ea7a9c9 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -45,7 +45,7 @@ struct vg_mask_layer {
VGint width;
VGint height;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
};
static INLINE struct pipe_surface *
@@ -54,7 +54,7 @@ alpha_mask_surface(struct vg_context *ctx, int usage)
struct pipe_screen *screen = ctx->pipe->screen;
struct st_framebuffer *stfb = ctx->draw_buffer;
return screen->get_tex_surface(screen,
- stfb->alpha_mask,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
usage);
}
@@ -284,35 +284,33 @@ static void setup_mask_operation(VGMaskOperation operation)
cso_set_fragment_shader_handle(ctx->cso_context, shader);
}
-static void setup_mask_samplers(struct pipe_texture *umask)
+static void setup_mask_samplers(struct pipe_sampler_view *umask)
{
struct vg_context *ctx = vg_current_context();
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
- struct pipe_texture *uprev = NULL;
+ struct pipe_sampler_view *uprev = NULL;
struct pipe_sampler_state sampler;
- uprev = fb_buffers->blend_texture;
+ uprev = fb_buffers->blend_texture_view;
sampler = ctx->mask.sampler;
sampler.normalized_coords = 1;
samplers[0] = NULL;
samplers[1] = NULL;
- samplers[2] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
samplers[0] = &sampler;
samplers[1] = &ctx->mask.sampler;
- textures[0] = umask;
- textures[1] = uprev;
+ sampler_views[0] = umask;
+ sampler_views[1] = uprev;
cso_set_samplers(ctx->cso_context, 2,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, 2, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 2, sampler_views);
}
@@ -411,12 +409,13 @@ static void surface_fill(struct pipe_surface *surf,
}
-static void mask_using_texture(struct pipe_texture *texture,
+static void mask_using_texture(struct pipe_sampler_view *sampler_view,
VGMaskOperation operation,
VGint x, VGint y,
VGint width, VGint height)
{
struct vg_context *ctx = vg_current_context();
+ struct pipe_texture *texture = sampler_view->texture;
struct pipe_surface *surface =
alpha_mask_surface(ctx, PIPE_BUFFER_USAGE_GPU_WRITE);
VGint offsets[4], loc[4];
@@ -439,13 +438,13 @@ static void mask_using_texture(struct pipe_texture *texture,
vg_prepare_blend_surface_from_mask(ctx);
cso_save_samplers(ctx->cso_context);
- cso_save_sampler_textures(ctx->cso_context);
+ cso_save_fragment_sampler_views(ctx->cso_context);
cso_save_framebuffer(ctx->cso_context);
cso_save_blend(ctx->cso_context);
cso_save_fragment_shader(ctx->cso_context);
cso_save_viewport(ctx->cso_context);
- setup_mask_samplers(texture);
+ setup_mask_samplers(sampler_view);
setup_mask_blend();
setup_mask_operation(operation);
setup_mask_framebuffer(surface, surface->width, surface->height);
@@ -463,7 +462,7 @@ static void mask_using_texture(struct pipe_texture *texture,
cso_restore_framebuffer(ctx->cso_context);
cso_restore_fragment_shader(ctx->cso_context);
cso_restore_samplers(ctx->cso_context);
- cso_restore_sampler_textures(ctx->cso_context);
+ cso_restore_fragment_sampler_views(ctx->cso_context);
cso_restore_viewport(ctx->cso_context);
pipe_surface_reference(&surface, NULL);
@@ -484,7 +483,11 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
{
struct pipe_texture pt;
+ struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = ctx->pipe->screen;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view = NULL;
+ struct pipe_texture *texture;
memset(&pt, 0, sizeof(pt));
pt.target = PIPE_TEXTURE_2D;
@@ -496,7 +499,14 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
pt.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
pt.compressed = 0;
- mask->texture = screen->texture_create(screen, &pt);
+ texture = screen->texture_create(screen, &pt);
+
+ if (texture) {
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ }
+ pipe_texture_reference(&texture, NULL);
+ mask->sampler_view = view;
}
vg_context_add_object(ctx, VG_OBJECT_MASK, mask);
@@ -525,7 +535,7 @@ void mask_layer_fill(struct vg_mask_layer *layer,
alpha_color[3] = value;
surface = ctx->pipe->screen->get_tex_surface(
- ctx->pipe->screen, layer->texture,
+ ctx->pipe->screen, layer->sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -545,10 +555,10 @@ void mask_copy(struct vg_mask_layer *layer,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
renderer_copy_texture(ctx->renderer,
- layer->texture,
+ layer->sampler_view,
sx, sy,
sx + width, sy + height,
- fb_buffers->alpha_mask,
+ fb_buffers->alpha_mask_view->texture,
dx, dy,
dx + width, dy + height);
}
@@ -562,7 +572,7 @@ static void mask_layer_render_to(struct vg_mask_layer *layer,
struct pipe_screen *screen = ctx->pipe->screen;
struct pipe_surface *surface;
- surface = screen->get_tex_surface(screen, layer->texture, 0, 0, 0,
+ surface = screen->get_tex_surface(screen, layer->sampler_view->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
cso_save_framebuffer(ctx->cso_context);
@@ -604,8 +614,8 @@ void mask_render_to(struct path *path,
struct vg_mask_layer *temp_layer;
VGint width, height;
- width = fb_buffers->alpha_mask->width0;
- height = fb_buffers->alpha_mask->width0;
+ width = fb_buffers->alpha_mask_view->texture->width0;
+ height = fb_buffers->alpha_mask_view->texture->width0;
temp_layer = mask_layer_create(width, height);
@@ -622,7 +632,7 @@ void mask_using_layer(struct vg_mask_layer *layer,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(layer->texture, operation,
+ mask_using_texture(layer->sampler_view, operation,
x, y, width, height);
}
@@ -644,7 +654,7 @@ void mask_using_image(struct vg_image *image,
VGint x, VGint y,
VGint width, VGint height)
{
- mask_using_texture(image->texture, operation,
+ mask_using_texture(image->sampler_view, operation,
x, y, width, height);
}
@@ -672,7 +682,7 @@ void mask_fill(VGint x, VGint y, VGint width, VGint height,
}
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
@@ -680,7 +690,7 @@ VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
struct st_framebuffer *fb_buffers = ctx->draw_buffer;
samplers[1] = &ctx->mask.sampler;
- textures[1] = fb_buffers->alpha_mask;
+ sampler_views[1] = fb_buffers->alpha_mask_view;
return 1;
} else
return 0;
diff --git a/src/gallium/state_trackers/vega/mask.h b/src/gallium/state_trackers/vega/mask.h
index 5eaaede0e3..4feacbefda 100644
--- a/src/gallium/state_trackers/vega/mask.h
+++ b/src/gallium/state_trackers/vega/mask.h
@@ -63,6 +63,6 @@ void mask_fill(VGint x, VGint y,
VGfloat value);
VGint mask_bind_samplers(struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
#endif
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index cdb87d3bf6..508e1863a5 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -37,6 +37,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -61,7 +62,7 @@ struct vg_paint {
VGfloat vals[5];
VGint valsi[5];
} radial;
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
struct pipe_sampler_state sampler;
VGfloat *ramp_stops;
@@ -72,7 +73,7 @@ struct vg_paint {
} gradient;
struct {
- struct pipe_texture *texture;
+ struct pipe_sampler_view *sampler_view;
VGTilingMode tiling_mode;
struct pipe_sampler_state sampler;
} pattern;
@@ -164,15 +165,35 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p)
struct pipe_transfer *transfer =
st_no_flush_get_tex_transfer(p->base.ctx, tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0, 1024, 1);
- void *map = screen->transfer_map(screen, transfer);
+ void *map = pipe->transfer_map(pipe, transfer);
memcpy(map, p->gradient.color_data, sizeof(VGint)*1024);
- screen->transfer_unmap(screen, transfer);
- screen->tex_transfer_destroy(transfer);
+ pipe->transfer_unmap(pipe, transfer);
+ pipe->tex_transfer_destroy(pipe, transfer);
}
return tex;
}
+static INLINE struct pipe_sampler_view *create_gradient_sampler_view(struct vg_paint *p)
+{
+ struct pipe_context *pipe = p->base.ctx->pipe;
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_gradient_texture(p);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
struct vg_paint * paint_create(struct vg_context *ctx)
{
struct vg_paint *paint = CALLOC_STRUCT(vg_paint);
@@ -207,8 +228,9 @@ struct vg_paint * paint_create(struct vg_context *ctx)
void paint_destroy(struct vg_paint *paint)
{
struct vg_context *ctx = paint->base.ctx;
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
if (ctx)
vg_context_remove_object(ctx, VG_OBJECT_PAINT, paint);
@@ -329,8 +351,8 @@ static INLINE void paint_pattern_buffer(struct vg_paint *paint, void *buffer)
map[4] = 0.f;
map[5] = 1.f;
- map[6] = paint->pattern.texture->width0;
- map[7] = paint->pattern.texture->height0;
+ map[6] = paint->pattern.sampler_view->texture->width0;
+ map[7] = paint->pattern.sampler_view->texture->height0;
{
struct matrix mat;
memcpy(&mat, &ctx->state.vg.fill_paint_to_user_matrix,
@@ -394,12 +416,12 @@ void paint_set_ramp_stops(struct vg_paint *paint, const VGfloat *stops,
create_gradient_data(stops, num / 5, paint->gradient.color_data,
1024);
- if (paint->gradient.texture) {
- pipe_texture_reference(&paint->gradient.texture, NULL);
- paint->gradient.texture = 0;
+ if (paint->gradient.sampler_view) {
+ pipe_sampler_view_reference(&paint->gradient.sampler_view, NULL);
+ paint->gradient.sampler_view = NULL;
}
- paint->gradient.texture = create_gradient_texture(paint);
+ paint->gradient.sampler_view = create_gradient_sampler_view(paint);
}
void paint_set_colori(struct vg_paint *p,
@@ -459,12 +481,12 @@ void paint_set_radial_gradient(struct vg_paint *paint,
void paint_set_pattern(struct vg_paint *paint,
struct vg_image *img)
{
- if (paint->pattern.texture)
- pipe_texture_reference(&paint->pattern.texture, NULL);
+ if (paint->pattern.sampler_view)
+ pipe_sampler_view_reference(&paint->pattern.sampler_view, NULL);
- paint->pattern.texture = 0;
- pipe_texture_reference(&paint->pattern.texture,
- img->texture);
+ paint->pattern.sampler_view = NULL;
+ pipe_sampler_view_reference(&paint->pattern.sampler_view,
+ img->sampler_view);
}
void paint_set_pattern_tiling(struct vg_paint *paint,
@@ -611,18 +633,18 @@ VGTilingMode paint_pattern_tiling(struct vg_paint *paint)
}
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
struct vg_context *ctx = vg_current_context();
switch(paint->type) {
case VG_PAINT_TYPE_LINEAR_GRADIENT:
case VG_PAINT_TYPE_RADIAL_GRADIENT: {
- if (paint->gradient.texture) {
+ if (paint->gradient.sampler_view) {
paint->gradient.sampler.min_img_filter = image_sampler_filter(ctx);
paint->gradient.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->gradient.sampler;
- textures[0] = paint->gradient.texture;
+ sampler_views[0] = paint->gradient.sampler_view;
return 1;
}
}
@@ -634,7 +656,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
paint->pattern.sampler.min_img_filter = image_sampler_filter(ctx);
paint->pattern.sampler.mag_img_filter = image_sampler_filter(ctx);
samplers[0] = &paint->pattern.sampler;
- textures[0] = paint->pattern.texture;
+ sampler_views[0] = paint->pattern.sampler_view;
return 1;
}
break;
@@ -647,7 +669,7 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
void paint_resolve_type(struct vg_paint *paint)
{
if (paint->type == VG_PAINT_TYPE_PATTERN &&
- !paint->pattern.texture) {
+ !paint->pattern.sampler_view) {
paint->type = VG_PAINT_TYPE_COLOR;
}
}
diff --git a/src/gallium/state_trackers/vega/paint.h b/src/gallium/state_trackers/vega/paint.h
index 999b5c167c..9ea67c4b1e 100644
--- a/src/gallium/state_trackers/vega/paint.h
+++ b/src/gallium/state_trackers/vega/paint.h
@@ -108,7 +108,7 @@ VGboolean paint_color_ramp_premultiplied(struct vg_paint *paint);
VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **samplers,
- struct pipe_texture **textures);
+ struct pipe_sampler_view **sampler_views);
VGint paint_constant_buffer_size(struct vg_paint *paint);
void paint_fill_constant_buffer(struct vg_paint *paint,
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index c06dbf5206..eef2c1eb87 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx,
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
velement.src_offset = 0;
velement.instance_divisor = 0;
velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
- velement.nr_components = COMPONENTS;
- pipe->set_vertex_elements(pipe, 1, &velement);
+ cso_set_vertex_elements(ctx->cso_context, 1, &velement);
/* draw */
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 05620efa9c..2bb4c8bc75 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -39,6 +39,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "cso_cache/cso_context.h"
@@ -210,6 +211,7 @@ void renderer_draw_quad(struct renderer *r,
buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -248,6 +250,7 @@ void renderer_draw_texture(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -261,7 +264,7 @@ void renderer_draw_texture(struct renderer *r,
}
void renderer_copy_texture(struct renderer *ctx,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
@@ -270,6 +273,7 @@ void renderer_copy_texture(struct renderer *ctx,
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
+ struct pipe_texture *tex = src->texture;
struct pipe_buffer *buf;
struct pipe_surface *dst_surf = screen->get_tex_surface(
screen, dst, 0, 0, 0,
@@ -277,8 +281,8 @@ void renderer_copy_texture(struct renderer *ctx,
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
- assert(src->width0 != 0);
- assert(src->height0 != 0);
+ assert(tex->width0 != 0);
+ assert(tex->height0 != 0);
assert(dst->width0 != 0);
assert(dst->height0 != 0);
@@ -288,10 +292,10 @@ void renderer_copy_texture(struct renderer *ctx,
#endif
#if 1
- s0 = sx1 / src->width0;
- s1 = sx2 / src->width0;
- t0 = sy1 / src->height0;
- t1 = sy2 / src->height0;
+ s0 = sx1 / tex->width0;
+ s1 = sx2 / tex->width0;
+ t0 = sy1 / tex->height0;
+ t1 = sy2 / tex->height0;
#else
s0 = 0;
s1 = 1;
@@ -305,7 +309,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
@@ -343,7 +347,7 @@ void renderer_copy_texture(struct renderer *ctx,
vg_set_viewport(ctx->owner, VEGA_Y0_TOP);
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &src);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &src);
/* shaders */
cso_set_vertex_shader_handle(ctx->cso, vg_texture_vs(ctx->owner));
@@ -370,6 +374,7 @@ void renderer_copy_texture(struct renderer *ctx,
0.0f);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -382,7 +387,7 @@ void renderer_copy_texture(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
@@ -403,6 +408,8 @@ void renderer_copy_surface(struct renderer *ctx,
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_buffer *buf;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
struct pipe_texture texTemp, *tex;
struct pipe_surface *texSurf;
struct pipe_framebuffer_state fb;
@@ -454,6 +461,12 @@ void renderer_copy_surface(struct renderer *ctx,
if (!tex)
return;
+ u_sampler_view_default_template(&view_templ, tex, tex->format);
+ view = pipe->create_sampler_view(pipe, tex, &view_templ);
+
+ if (!view)
+ return;
+
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
@@ -476,7 +489,7 @@ void renderer_copy_surface(struct renderer *ctx,
/* save state (restored below) */
cso_save_blend(ctx->cso);
cso_save_samplers(ctx->cso);
- cso_save_sampler_textures(ctx->cso);
+ cso_save_fragment_sampler_views(ctx->cso);
cso_save_framebuffer(ctx->cso);
cso_save_fragment_shader(ctx->cso);
cso_save_vertex_shader(ctx->cso);
@@ -512,7 +525,7 @@ void renderer_copy_surface(struct renderer *ctx,
}
/* texture */
- cso_set_sampler_textures(ctx->cso, 1, &tex);
+ cso_set_fragment_sampler_views(ctx->cso, 1, &view);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
@@ -535,6 +548,7 @@ void renderer_copy_surface(struct renderer *ctx,
(float) dstX1, (float) dstY1, z);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -548,13 +562,14 @@ void renderer_copy_surface(struct renderer *ctx,
/* restore state we changed */
cso_restore_blend(ctx->cso);
cso_restore_samplers(ctx->cso);
- cso_restore_sampler_textures(ctx->cso);
+ cso_restore_fragment_sampler_views(ctx->cso);
cso_restore_framebuffer(ctx->cso);
cso_restore_fragment_shader(ctx->cso);
cso_restore_vertex_shader(ctx->cso);
cso_restore_viewport(ctx->cso);
pipe_texture_reference(&tex, NULL);
+ pipe_sampler_view_reference(&view, NULL);
}
void renderer_texture_quad(struct renderer *r,
@@ -587,6 +602,7 @@ void renderer_texture_quad(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/renderer.h b/src/gallium/state_trackers/vega/renderer.h
index 990cd32c31..03366f1361 100644
--- a/src/gallium/state_trackers/vega/renderer.h
+++ b/src/gallium/state_trackers/vega/renderer.h
@@ -33,6 +33,7 @@ struct renderer;
struct vg_context;
struct pipe_texture;
+struct pipe_sampler_view;
struct pipe_surface;
struct renderer *renderer_create(struct vg_context *owner);
@@ -57,7 +58,7 @@ void renderer_texture_quad(struct renderer *,
VGfloat x3, VGfloat y3,
VGfloat x4, VGfloat y4);
void renderer_copy_texture(struct renderer *r,
- struct pipe_texture *src,
+ struct pipe_sampler_view *src,
VGfloat sx1, VGfloat sy1,
VGfloat sx2, VGfloat sy2,
struct pipe_texture *dst,
diff --git a/src/gallium/state_trackers/vega/shader.c b/src/gallium/state_trackers/vega/shader.c
index 0e71a507bf..f2ec24c57f 100644
--- a/src/gallium/state_trackers/vega/shader.c
+++ b/src/gallium/state_trackers/vega/shader.c
@@ -119,7 +119,7 @@ static void setup_constant_buffer(struct shader *shader)
static VGint blend_bind_samplers(struct vg_context *ctx,
struct pipe_sampler_state **samplers,
- struct pipe_texture **textures)
+ struct pipe_sampler_view **sampler_views)
{
VGBlendMode bmode = ctx->state.vg.blend_mode;
@@ -132,15 +132,15 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
vg_prepare_blend_surface(ctx);
samplers[2] = &ctx->blend_sampler;
- textures[2] = stfb->blend_texture;
+ sampler_views[2] = stfb->blend_texture_view;
- if (!samplers[0] || !textures[0]) {
+ if (!samplers[0] || !sampler_views[0]) {
samplers[0] = samplers[2];
- textures[0] = textures[2];
+ sampler_views[0] = sampler_views[2];
}
- if (!samplers[1] || !textures[1]) {
+ if (!samplers[1] || !sampler_views[1]) {
samplers[1] = samplers[0];
- textures[1] = textures[0];
+ sampler_views[1] = sampler_views[0];
}
return 1;
@@ -151,7 +151,7 @@ static VGint blend_bind_samplers(struct vg_context *ctx,
static void setup_samplers(struct shader *shader)
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
- struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
struct vg_context *ctx = shader->context;
/* a little wonky: we use the num as a boolean that just says
* whether any sampler/textures have been set. the actual numbering
@@ -167,20 +167,20 @@ static void setup_samplers(struct shader *shader)
samplers[1] = NULL;
samplers[2] = NULL;
samplers[3] = NULL;
- textures[0] = NULL;
- textures[1] = NULL;
- textures[2] = NULL;
- textures[3] = NULL;
-
- num += paint_bind_samplers(shader->paint, samplers, textures);
- num += mask_bind_samplers(samplers, textures);
- num += blend_bind_samplers(ctx, samplers, textures);
+ sampler_views[0] = NULL;
+ sampler_views[1] = NULL;
+ sampler_views[2] = NULL;
+ sampler_views[3] = NULL;
+
+ num += paint_bind_samplers(shader->paint, samplers, sampler_views);
+ num += mask_bind_samplers(samplers, sampler_views);
+ num += blend_bind_samplers(ctx, samplers, sampler_views);
if (shader->drawing_image && shader->image)
- num += image_bind_samplers(shader->image, samplers, textures);
+ num += image_bind_samplers(shader->image, samplers, sampler_views);
if (num) {
cso_set_samplers(ctx->cso_context, 4, (const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(ctx->cso_context, 4, textures);
+ cso_set_fragment_sampler_views(ctx->cso_context, 4, sampler_views);
}
}
diff --git a/src/gallium/state_trackers/vega/st_inlines.h b/src/gallium/state_trackers/vega/st_inlines.h
index 419151c3ae..4d12a4efdd 100644
--- a/src/gallium/state_trackers/vega/st_inlines.h
+++ b/src/gallium/state_trackers/vega/st_inlines.h
@@ -51,7 +51,6 @@ st_cond_flush_get_tex_transfer(struct vg_context *st,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
- struct pipe_screen *screen = st->pipe->screen;
struct pipe_context *pipe = st->pipe;
unsigned referenced =
pipe->is_texture_referenced(pipe, pt, face, level);
@@ -60,7 +59,7 @@ st_cond_flush_get_tex_transfer(struct vg_context *st,
(usage & PIPE_TRANSFER_WRITE)))
vgFlush();
- return screen->get_tex_transfer(screen, pt, face, level, zslice, usage,
+ return pipe->get_tex_transfer(pipe, pt, face, level, zslice, usage,
x, y, w, h);
}
@@ -74,10 +73,10 @@ st_no_flush_get_tex_transfer(struct vg_context *st,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
- struct pipe_screen *screen = st->pipe->screen;
+ struct pipe_context *pipe = st->pipe;
- return screen->get_tex_transfer(screen, pt, face, level,
- zslice, usage, x, y, w, h);
+ return pipe->get_tex_transfer(pipe, pt, face, level,
+ zslice, usage, x, y, w, h);
}
static INLINE void *
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 426bf9bc62..11ebbbe544 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -32,6 +32,7 @@
#include "shader.h"
#include "asm_util.h"
#include "st_inlines.h"
+#include "vg_manager.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
@@ -42,6 +43,7 @@
#include "util/u_simple_shaders.h"
#include "util/u_memory.h"
#include "util/u_blit.h"
+#include "util/u_sampler.h"
struct vg_context *_vg_context = 0;
@@ -72,6 +74,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share)
{
struct vg_context *ctx;
+ unsigned i;
ctx = CALLOC_STRUCT(vg_context);
@@ -103,6 +106,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0;
+ for (i = 0; i < 2; i++) {
+ ctx->velems[i].src_offset = i * 4 * sizeof(float);
+ ctx->velems[i].instance_divisor = 0;
+ ctx->velems[i].vertex_buffer_index = 0;
+ ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
@@ -297,6 +307,8 @@ static void update_clip_state(struct vg_context *ctx)
void vg_validate_state(struct vg_context *ctx)
{
+ vg_manager_validate_framebuffer(ctx);
+
if ((ctx->state.dirty & BLEND_DIRTY)) {
struct pipe_blend_state *blend = &ctx->state.g3d.blend;
memset(blend, 0, sizeof(struct pipe_blend_state));
@@ -425,19 +437,24 @@ void vg_prepare_blend_surface(struct vg_context *ctx)
{
struct pipe_surface *dest_surface = NULL;
struct pipe_context *pipe = ctx->pipe;
+ struct pipe_sampler_view *view;
+ struct pipe_sampler_view view_templ;
struct st_framebuffer *stfb = ctx->draw_buffer;
struct st_renderbuffer *strb = stfb->strb;
/* first finish all pending rendering */
vgFinish();
+ u_sampler_view_default_template(&view_templ, strb->texture, strb->texture->format);
+ view = pipe->create_sampler_view(pipe, strb->texture, &view_templ);
+
dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- strb->texture,
+ view,
0, strb->height,
strb->width, 0,
dest_surface,
@@ -450,6 +467,8 @@ void vg_prepare_blend_surface(struct vg_context *ctx)
/* make sure it's complete */
vgFinish();
+
+ pipe_sampler_view_reference(&view, NULL);
}
@@ -466,13 +485,13 @@ void vg_prepare_blend_surface_from_mask(struct vg_context *ctx)
vgFinish();
dest_surface = pipe->screen->get_tex_surface(pipe->screen,
- stfb->blend_texture,
+ stfb->blend_texture_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
/* flip it, because we want to use it as a sampler */
util_blit_pixels_tex(ctx->blit,
- stfb->alpha_mask,
+ stfb->alpha_mask_view,
0, strb->height,
strb->width, 0,
dest_surface,
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index bc88c8d139..c9e36d7d76 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -33,6 +33,7 @@
#include "pipe/p_state.h"
#include "util/u_pointer.h"
#include "util/u_math.h"
+#include "state_tracker/st_api.h"
#include "cso_cache/cso_hash.h"
#include "cso_cache/cso_context.h"
@@ -54,9 +55,13 @@ struct st_framebuffer {
struct st_renderbuffer *strb;
struct st_renderbuffer *dsrb;
- struct pipe_texture *alpha_mask;
+ struct pipe_sampler_view *alpha_mask_view;
- struct pipe_texture *blend_texture;
+ struct pipe_sampler_view *blend_texture_view;
+
+
+ struct st_framebuffer_iface *iface;
+ enum st_attachment_type strb_att;
void *privateData;
};
@@ -84,6 +89,8 @@ enum dirty_state {
struct vg_context
{
+ struct st_context_iface iface;
+
struct pipe_context *pipe;
struct {
@@ -101,6 +108,7 @@ struct vg_context
VGErrorCode _error;
struct st_framebuffer *draw_buffer;
+ int32_t draw_buffer_invalid;
struct cso_hash *owned_objects[VG_OBJECT_LAST];
@@ -146,6 +154,7 @@ struct vg_context
struct vg_shader *clear_vs;
struct vg_shader *texture_vs;
struct pipe_buffer *vs_const_buffer;
+ struct pipe_vertex_element velems[2];
};
struct vg_object {
diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c
new file mode 100644
index 0000000000..25c2e853f2
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.c
@@ -0,0 +1,373 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "state_tracker/st_api.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "vg_manager.h"
+#include "vg_context.h"
+#include "vg_tracker.h" /* for st_resize_framebuffer */
+#include "image.h"
+
+/**
+ * Flush the front buffer if the current context renders to the front buffer.
+ */
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx)
+{
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->flush_frontbuffer) {
+ screen->flush_frontbuffer(screen,
+ stfb->strb->surface, ctx->pipe->priv);
+ }
+ return;
+ }
+
+ switch (stfb->strb_att) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ stfb->iface->flush_front(stfb->iface, stfb->strb_att);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Re-validate the framebuffer.
+ */
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx)
+{
+ struct pipe_screen *screen = ctx->pipe->screen;
+ struct st_framebuffer *stfb = ctx->draw_buffer;
+ struct st_renderbuffer *rb;
+ struct pipe_texture *pt;
+
+ /* no binding surface */
+ if (!stfb)
+ return;
+
+ /* st_public.h is used */
+ if (!stfb->iface) {
+ struct pipe_screen *screen = ctx->pipe->screen;
+ if (screen->update_buffer)
+ screen->update_buffer(screen, ctx->pipe->priv);
+ return;
+ }
+
+ if (!p_atomic_read(&ctx->draw_buffer_invalid))
+ return;
+
+ /* validate the fb */
+ if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
+ return;
+
+ rb = stfb->strb;
+ if (rb->texture == pt) {
+ pipe_texture_reference(&pt, NULL);
+ return;
+ }
+
+ /* unreference existing ones */
+ pipe_surface_reference(&rb->surface, NULL);
+ pipe_texture_reference(&rb->texture, NULL);
+
+ rb->texture = pt;
+ rb->surface = screen->get_tex_surface(screen, rb->texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ rb->width = rb->surface->width;
+ rb->height = rb->surface->height;
+
+ st_resize_framebuffer(stfb, rb->width, rb->height);
+
+ p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
+}
+
+
+static void
+vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stfbi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+}
+
+static void
+vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ ctx->pipe->flush(ctx->pipe, flags, fence);
+ if (flags & PIPE_FLUSH_RENDER_CACHE)
+ vg_manager_flush_frontbuffer(ctx);
+}
+
+static void
+vg_context_destroy(struct st_context_iface *stctxi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ vg_destroy_context(ctx);
+}
+
+static struct st_context_iface *
+vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+ const struct st_visual *visual,
+ struct st_context_iface *shared_stctxi)
+{
+ struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
+ struct vg_context *ctx;
+ struct pipe_context *pipe;
+
+ pipe = smapi->screen->context_create(smapi->screen, NULL);
+ if (!pipe)
+ return NULL;
+ ctx = vg_create_context(pipe, NULL, shared_ctx);
+ if (!ctx) {
+ pipe->destroy(pipe);
+ return NULL;
+ }
+
+ ctx->iface.destroy = vg_context_destroy;
+
+ ctx->iface.notify_invalid_framebuffer =
+ vg_context_notify_invalid_framebuffer;
+ ctx->iface.flush = vg_context_flush;
+
+ ctx->iface.teximage = NULL;
+ ctx->iface.copy = NULL;
+
+ ctx->iface.st_context_private = (void *) smapi;
+
+ return &ctx->iface;
+}
+
+static struct st_renderbuffer *
+create_renderbuffer(enum pipe_format format)
+{
+ struct st_renderbuffer *strb;
+
+ strb = CALLOC_STRUCT(st_renderbuffer);
+ if (strb)
+ strb->format = format;
+
+ return strb;
+}
+
+static void
+destroy_renderbuffer(struct st_renderbuffer *strb)
+{
+ pipe_surface_reference(&strb->surface, NULL);
+ pipe_texture_reference(&strb->texture, NULL);
+ free(strb);
+}
+
+/**
+ * Decide the buffer to render to.
+ */
+static enum st_attachment_type
+choose_attachment(struct st_framebuffer_iface *stfbi)
+{
+ enum st_attachment_type statt;
+
+ statt = stfbi->visual->render_buffer;
+ if (statt != ST_ATTACHMENT_INVALID) {
+ /* use the buffer given by the visual, unless it is unavailable */
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) {
+ switch (statt) {
+ case ST_ATTACHMENT_BACK_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ break;
+ case ST_ATTACHMENT_BACK_RIGHT:
+ statt = ST_ATTACHMENT_FRONT_RIGHT;
+ break;
+ default:
+ break;
+ }
+
+ if (!st_visual_have_buffers(stfbi->visual, 1 << statt))
+ statt = ST_ATTACHMENT_INVALID;
+ }
+ }
+
+ return statt;
+}
+
+/**
+ * Bind the context to the given framebuffers.
+ */
+static boolean
+vg_context_bind_framebuffers(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+ struct st_framebuffer *stfb;
+ enum st_attachment_type strb_att;
+
+ /* the draw and read framebuffers must be the same */
+ if (stdrawi != streadi)
+ return FALSE;
+
+ p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+
+ strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
+
+ if (ctx->draw_buffer) {
+ stfb = ctx->draw_buffer;
+
+ /* free the existing fb */
+ if (!stdrawi ||
+ stfb->strb_att != strb_att ||
+ stfb->strb->format != stdrawi->visual->color_format ||
+ stfb->dsrb->format != stdrawi->visual->depth_stencil_format) {
+ destroy_renderbuffer(stfb->strb);
+ destroy_renderbuffer(stfb->dsrb);
+ free(stfb);
+
+ ctx->draw_buffer = NULL;
+ }
+ }
+
+ if (!stdrawi)
+ return TRUE;
+
+ if (strb_att == ST_ATTACHMENT_INVALID)
+ return FALSE;
+
+ /* create a new fb */
+ if (!ctx->draw_buffer) {
+ stfb = CALLOC_STRUCT(st_framebuffer);
+ if (!stfb)
+ return FALSE;
+
+ stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
+ if (!stfb->strb) {
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format);
+ if (!stfb->dsrb) {
+ free(stfb->strb);
+ free(stfb);
+ return FALSE;
+ }
+
+ stfb->width = 0;
+ stfb->height = 0;
+ stfb->strb_att = strb_att;
+
+ ctx->draw_buffer = stfb;
+ }
+
+ ctx->draw_buffer->iface = stdrawi;
+
+ return TRUE;
+}
+
+static boolean
+vg_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
+ struct st_framebuffer_iface *stdrawi,
+ struct st_framebuffer_iface *streadi)
+{
+ struct vg_context *ctx = (struct vg_context *) stctxi;
+
+ if (stctxi)
+ vg_context_bind_framebuffers(stctxi, stdrawi, streadi);
+ vg_set_current_context(ctx);
+
+ return TRUE;
+}
+
+static struct st_context_iface *
+vg_api_get_current(struct st_api *stapi)
+{
+ struct vg_context *ctx = vg_current_context();
+
+ return (ctx) ? &ctx->iface : NULL;
+}
+
+static boolean
+vg_api_is_visual_supported(struct st_api *stapi,
+ const struct st_visual *visual)
+{
+ /* the impl requires a depth/stencil buffer */
+ if (visual->depth_stencil_format == PIPE_FORMAT_NONE)
+ return FALSE;
+
+ return TRUE;
+}
+
+static st_proc_t
+vg_api_get_proc_address(struct st_api *stapi, const char *procname)
+{
+ /* TODO */
+ return (st_proc_t) NULL;
+}
+
+static void
+vg_api_destroy(struct st_api *stapi)
+{
+ free(stapi);
+}
+
+static struct st_api *
+vg_module_create_api(void)
+{
+ struct st_api *stapi;
+
+ stapi = CALLOC_STRUCT(st_api);
+ if (stapi) {
+ stapi->destroy = vg_api_destroy;
+ stapi->get_proc_address = vg_api_get_proc_address;
+ stapi->is_visual_supported = vg_api_is_visual_supported;
+
+ stapi->create_context = vg_api_create_context;
+ stapi->make_current = vg_api_make_current;
+ stapi->get_current = vg_api_get_current;
+ }
+
+ return stapi;
+}
+
+PUBLIC const struct st_module st_module_OpenVG = {
+ .api = ST_API_OPENVG,
+ .create_api = vg_module_create_api,
+};
diff --git a/src/gallium/state_trackers/vega/vg_manager.h b/src/gallium/state_trackers/vega/vg_manager.h
new file mode 100644
index 0000000000..1a276c0f35
--- /dev/null
+++ b/src/gallium/state_trackers/vega/vg_manager.h
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * 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.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef VG_MANAGER_H
+#define VG_MANAGER_H
+
+#include "state_tracker/st_api.h"
+#include "vg_context.h"
+
+void
+vg_manager_flush_frontbuffer(struct vg_context *ctx);
+
+void
+vg_manager_validate_framebuffer(struct vg_context *ctx);
+
+#endif /* VG_MANAGER_H */
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index 57d3baad7f..f438e34087 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -32,6 +32,7 @@
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
#include "util/u_format.h"
+#include "util/u_sampler.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_rect.h"
@@ -41,7 +42,7 @@ PUBLIC const int st_api_OpenVG = 1;
static struct pipe_texture *
create_texture(struct pipe_context *pipe, enum pipe_format format,
- VGint width, VGint height)
+ VGint width, VGint height)
{
struct pipe_texture templ;
@@ -71,6 +72,27 @@ create_texture(struct pipe_context *pipe, enum pipe_format format,
return pipe->screen->texture_create(pipe->screen, &templ);
}
+static struct pipe_sampler_view *
+create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
+ VGint width, VGint height)
+{
+ struct pipe_texture *texture;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *view;
+
+ texture = create_texture(pipe, format, width, height);
+
+ if (!texture)
+ return NULL;
+
+ u_sampler_view_default_template(&view_templ, texture, texture->format);
+ view = pipe->create_sampler_view(pipe, texture, &view_templ);
+ /* want the texture to go away if the view is freed */
+ pipe_texture_reference(&texture, NULL);
+
+ return view;
+}
+
/**
* Allocate a renderbuffer for a an on-screen window (not a user-created
* renderbuffer). The window system code determines the format.
@@ -115,8 +137,8 @@ st_renderbuffer_alloc_storage(struct vg_context * ctx,
surface_usage = (PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
- strb->texture = create_texture(pipe, strb->format,
- width, height);
+ strb->texture = create_texture(pipe, strb->format, width, height);
+
if (!strb->texture)
return FALSE;
@@ -191,7 +213,7 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
/*### currently we always allocate it but it's possible it's
not necessary if EGL_ALPHA_MASK_SIZE was 0
*/
- stfb->alpha_mask = 0;
+ stfb->alpha_mask_view = NULL;
stfb->width = width;
stfb->height = height;
@@ -206,19 +228,19 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
uint width, uint height)
{
struct pipe_context *pipe = ctx->pipe;
- struct pipe_texture *old_texture = stfb->alpha_mask;
+ struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
/*
we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
this texture and use it as a sampler, so while this wastes some
space it makes both of those a lot simpler
*/
- stfb->alpha_mask =
- create_texture(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
+ stfb->alpha_mask_view =
+ create_tex_and_view(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
- if (!stfb->alpha_mask) {
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (!stfb->alpha_mask_view) {
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
return;
}
@@ -228,15 +250,15 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
mask_fill(0, 0, width, height, 1.f);
/* if we had an old surface copy it over */
- if (old_texture) {
+ if (old_sampler_view) {
struct pipe_surface *surface = pipe->screen->get_tex_surface(
pipe->screen,
- stfb->alpha_mask,
+ stfb->alpha_mask_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_WRITE);
struct pipe_surface *old_surface = pipe->screen->get_tex_surface(
pipe->screen,
- old_texture,
+ old_sampler_view->texture,
0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ);
if (pipe->surface_copy) {
@@ -264,8 +286,8 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
/* Free the old texture
*/
- if (old_texture)
- pipe_texture_reference(&old_texture, NULL);
+ if (old_sampler_view)
+ pipe_sampler_view_reference(&old_sampler_view, NULL);
}
void st_resize_framebuffer(struct st_framebuffer *stfb,
@@ -326,9 +348,9 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
setup_new_alpha_mask(ctx, stfb, width, height);
- pipe_texture_reference( &stfb->blend_texture, NULL );
- stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
- width, height);
+ pipe_sampler_view_reference( &stfb->blend_texture_view, NULL );
+ stfb->blend_texture_view = create_tex_and_view(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
+ width, height);
}
void st_set_framebuffer_surface(struct st_framebuffer *stfb,
@@ -376,12 +398,12 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb)
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read)
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle)
{
vg_set_current_context(st);
- if (st) {
+ if (st)
st->draw_buffer = draw;
- }
return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index c1196954a7..165a6b7a33 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -101,7 +101,8 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb);
PUBLIC
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read);
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle);
PUBLIC
struct vg_context *st_get_current(void);
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 05ccd5febc..1f11b649c3 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -226,7 +226,7 @@ DrvDeleteContext(
/* Unbind current if deleting current context. */
if (curctx == ctx)
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
st_destroy_context(ctx->st);
FREE(ctx);
@@ -317,7 +317,7 @@ stw_make_current(
}
if (hdc == NULL || dhglrc == 0) {
- return st_make_current( NULL, NULL, NULL );
+ return st_make_current( NULL, NULL, NULL, NULL );
}
pipe_mutex_lock( stw_dev->ctx_mutex );
@@ -352,7 +352,7 @@ stw_make_current(
/* pass to stw_flush_frontbuffer as context_private */
ctx->st->pipe->priv = hdc;
- if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc ))
goto fail;
success:
@@ -367,7 +367,7 @@ success:
fail:
if(fb)
stw_framebuffer_release(fb);
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 472a2a5379..ea300f27cb 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -33,11 +33,6 @@
#include "pipe/p_screen.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_device.h"
#include "stw_winsys.h"
#include "stw_pixelformat.h"
@@ -107,13 +102,10 @@ stw_init(const struct stw_winsys *stw_winsys)
if(stw_winsys->get_adapter_luid)
stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
-#ifdef DEBUG
- stw_dev->screen = trace_screen_create(screen);
- stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
-#else
stw_dev->screen = screen;
-#endif
-
+
+ /* XXX
+ */
stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->ctx_mutex );
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index a83841f6b7..2e9ba197df 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -48,10 +48,6 @@ struct stw_device
struct pipe_screen *screen;
-#ifdef DEBUG
- boolean trace_running;
-#endif
-
LUID AdapterLuid;
struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index 8dd63f124a..5ecbd8048d 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -31,11 +31,6 @@
#include "stw_winsys.h"
#include "stw_ext_gallium.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
struct pipe_screen * APIENTRY
wglGetGalliumScreenMESA(void)
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 02de21ccb2..4f1629de2f 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -34,11 +34,6 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_icd.h"
#include "stw_framebuffer.h"
#include "stw_device.h"
@@ -495,13 +490,6 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
surface = (struct pipe_surface *)data->pPrivateData;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
if(data->hSharedSurface != fb->hSharedSurface) {
if(fb->shared_surface) {
stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
@@ -563,13 +551,6 @@ stw_framebuffer_present_locked(HDC hdc,
else {
struct pipe_screen *screen = stw_dev->screen;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
stw_dev->stw_winsys->present( screen, surface, hdc );
stw_framebuffer_update(fb);
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index c50873c150..4ff48026e5 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -4,6 +4,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
/*XXX also in Xrender.h but the including it here breaks compilition */
@@ -356,17 +357,12 @@ bind_samplers(struct exa_context *exa, int op,
{
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state src_sampler, mask_sampler;
+ struct pipe_sampler_view view_templ;
+ struct pipe_sampler_view *src_view;
+ struct pipe_context *pipe = exa->pipe;
exa->num_bound_samplers = 0;
-#if 0
- if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)) ||
- (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)))
- xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#endif
-
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
@@ -374,7 +370,7 @@ bind_samplers(struct exa_context *exa, int op,
if (exa->has_solid_color) {
debug_assert(!"solid color with textures");
samplers[0] = NULL;
- exa->bound_textures[0] = NULL;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
} else {
unsigned src_wrap = render_repeat_to_gallium(
pSrcPicture->repeatType);
@@ -389,8 +385,13 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
src_sampler.normalized_coords = 1;
samplers[0] = &src_sampler;
- exa->bound_textures[0] = pSrc->tex;
exa->num_bound_samplers = 1;
+ u_sampler_view_default_template(&view_templ,
+ pSrc->tex,
+ pSrc->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pSrc->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ exa->bound_sampler_views[0] = src_view;
}
}
@@ -408,14 +409,19 @@ bind_samplers(struct exa_context *exa, int op,
src_sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
mask_sampler.normalized_coords = 1;
samplers[1] = &mask_sampler;
- exa->bound_textures[1] = pMask->tex;
exa->num_bound_samplers = 2;
+ u_sampler_view_default_template(&view_templ,
+ pMask->tex,
+ pMask->tex->format);
+ src_view = pipe->create_sampler_view(pipe, pMask->tex, &view_templ);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+ exa->bound_sampler_views[1] = src_view;
}
cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
- exa->bound_textures);
+ cso_set_fragment_sampler_views(exa->renderer->cso, exa->num_bound_samplers,
+ exa->bound_sampler_views);
}
@@ -484,7 +490,6 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
renderer_begin_solid(exa->renderer);
} else {
renderer_begin_textures(exa->renderer,
- exa->bound_textures,
exa->num_bound_samplers);
}
@@ -514,7 +519,7 @@ void xorg_composite(struct exa_context *exa,
renderer_texture(exa->renderer,
pos, width, height,
- exa->bound_textures,
+ exa->bound_sampler_views,
exa->num_bound_samplers,
src_matrix, mask_matrix);
}
@@ -546,7 +551,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
pixmap->width, pixmap->height);
bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
cso_set_samplers(exa->renderer->cso, 0, NULL);
- cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
+ cso_set_fragment_sampler_views(exa->renderer->cso, 0, NULL);
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index a428fa8d94..eef428232b 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -198,11 +198,11 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
if (!crtcp->cursor_tex) {
struct pipe_texture templat;
- unsigned pitch;
+ struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
@@ -210,25 +210,26 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
templat.width0 = 64;
templat.height0 = 64;
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
- ms->api->local_handle_from_texture(ms->api,
- ms->screen,
- crtcp->cursor_tex,
- &pitch,
- &crtcp->cursor_handle);
+ ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
+
+ crtcp->cursor_handle = whandle.handle;
}
- transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, 64, 64);
- ptr = ms->screen->transfer_map(ms->screen, transfer);
+ transfer = ms->ctx->get_tex_transfer(ms->ctx, crtcp->cursor_tex,
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, 64, 64);
+ ptr = ms->ctx->transfer_map(ms->ctx, transfer);
util_copy_rect(ptr, crtcp->cursor_tex->format,
transfer->stride, 0, 0,
64, 64, (void*)image, 64 * 4, 0, 0);
- ms->screen->transfer_unmap(ms->screen, transfer);
- ms->screen->tex_transfer_destroy(transfer);
+ ms->ctx->transfer_unmap(ms->ctx, transfer);
+ ms->ctx->tex_transfer_destroy(ms->ctx, transfer);
}
#if HAVE_LIBKMS
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 5fc85c0e98..f23e4c6cc7 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
- unsigned stride, handle;
+ struct winsys_handle whandle;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
@@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
+
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
@@ -128,7 +129,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ PIPE_TEXTURE_USAGE_SHARED;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
@@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
- ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+
+ ms->screen->texture_get_handle(ms->screen, tex, &whandle);
- buffer->name = handle;
- buffer->pitch = stride;
+ buffer->name = whandle.handle;
+ buffer->pitch = whandle.stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index d7c67463d2..8ac5179545 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -994,8 +994,9 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride, fb_id;
struct pipe_texture *tex;
+ struct winsys_handle whandle;
+ unsigned fb_id;
int ret;
ms->noEvict = TRUE;
@@ -1006,10 +1007,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
if (!tex)
return FALSE;
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle))
goto err_destroy;
ret = drmModeAddFB(ms->fd,
@@ -1017,8 +1018,8 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- stride,
- handle,
+ whandle.stride,
+ whandle.handle,
&fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)\n",
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index a242e02ee7..76e6411bb8 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -188,11 +188,7 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
if (!priv || !priv->tex)
return FALSE;
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- exa->pipe->flush(exa->pipe, 0, NULL);
-
- transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ transfer = exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
PIPE_TRANSFER_READ, x, y, w, h);
if (!transfer)
return FALSE;
@@ -203,11 +199,11 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
#endif
util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
- w, h, exa->scrn->transfer_map(exa->scrn, transfer),
+ w, h, exa->pipe->transfer_map(exa->pipe, transfer),
transfer->stride, 0, 0);
- exa->scrn->transfer_unmap(exa->scrn, transfer);
- exa->scrn->tex_transfer_destroy(transfer);
+ exa->pipe->transfer_unmap(exa->pipe, transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, transfer);
return TRUE;
}
@@ -226,12 +222,7 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
if (!priv || !priv->tex)
return FALSE;
- /* make sure that any pending operations are flushed to hardware */
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- (PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
- xorg_exa_flush(exa, 0, NULL);
-
- transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ transfer = exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
return FALSE;
@@ -241,12 +232,12 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
x, y, w, h, src_pitch);
#endif
- util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+ util_copy_rect(exa->pipe->transfer_map(exa->pipe, transfer),
priv->tex->format, transfer->stride, 0, 0, w, h,
(unsigned char*)src, src_pitch, 0, 0);
- exa->scrn->transfer_unmap(exa->scrn, transfer);
- exa->scrn->tex_transfer_destroy(transfer);
+ exa->pipe->transfer_unmap(exa->pipe, transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, transfer);
return TRUE;
}
@@ -270,15 +261,11 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
if (priv->map_count == 0)
{
- if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- exa->pipe->flush(exa->pipe, 0, NULL);
-
assert(pPix->drawable.width <= priv->tex->width0);
assert(pPix->drawable.height <= priv->tex->height0);
priv->map_transfer =
- exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
@@ -294,7 +281,7 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
#endif
pPix->devPrivate.ptr =
- exa->scrn->transfer_map(exa->scrn, priv->map_transfer);
+ exa->pipe->transfer_map(exa->pipe, priv->map_transfer);
pPix->devKind = priv->map_transfer->stride;
}
@@ -321,8 +308,8 @@ ExaFinishAccess(PixmapPtr pPix, int index)
if (--priv->map_count == 0) {
assert(priv->map_transfer);
- exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
- exa->scrn->tex_transfer_destroy(priv->map_transfer);
+ exa->pipe->transfer_unmap(exa->pipe, priv->map_transfer);
+ exa->pipe->tex_transfer_destroy(exa->pipe, priv->map_transfer);
priv->map_transfer = NULL;
pPix->devPrivate.ptr = NULL;
}
@@ -789,7 +776,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+ priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT;
return 0;
}
@@ -805,7 +792,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ priv->flags |= PIPE_TEXTURE_USAGE_SHARED;
return 0;
}
@@ -943,7 +930,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
{
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT;
if (!priv)
return FALSE;
@@ -976,8 +963,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED;
return exa->scrn->texture_create(exa->scrn, &template);
}
@@ -988,6 +975,9 @@ xorg_exa_close(ScrnInfoPtr pScrn)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
+ pipe_sampler_view_reference(&exa->bound_sampler_views[0], NULL);
+ pipe_sampler_view_reference(&exa->bound_sampler_views[1], NULL);
+
renderer_destroy(exa->renderer);
if (exa->pipe)
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index f2cefe23b9..41b1906159 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -18,7 +18,7 @@ struct exa_context
struct pipe_screen *scrn;
struct xorg_renderer *renderer;
- struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
+ struct pipe_sampler_view *bound_sampler_views[MAX_EXA_SAMPLERS];
int num_bound_samplers;
float solid_color[4];
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 83b0d31e38..81b0dcf656 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -8,6 +8,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
+#include "util/u_sampler.h"
#include "util/u_inlines.h"
@@ -68,6 +69,8 @@ renderer_draw(struct xorg_renderer *r)
if (buf) {
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
num_verts, /* verts */
@@ -92,6 +95,7 @@ renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state raster;
+ unsigned i;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
@@ -103,6 +107,14 @@ renderer_init_state(struct xorg_renderer *r)
raster.gl_rasterization_rules = 1;
cso_set_rasterizer(r->cso, &raster);
+ /* vertex elements state */
+ memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
+ for (i = 0; i < 3; i++) {
+ r->velems[i].src_offset = i * 4 * sizeof(float);
+ r->velems[i].instance_divisor = 0;
+ r->velems[i].vertex_buffer_index = 0;
+ r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
}
@@ -471,8 +483,17 @@ void renderer_copy_prepare(struct xorg_renderer *r,
dst_surface->width,
dst_surface->height);
- /* texture */
- cso_set_sampler_textures(r->cso, 1, &src_texture);
+ /* texture/sampler view */
+ {
+ struct pipe_sampler_view templ;
+ struct pipe_sampler_view *src_view;
+ u_sampler_view_default_template(&templ,
+ src_texture,
+ src_texture->format);
+ src_view = pipe->create_sampler_view(pipe, src_texture, &templ);
+ cso_set_fragment_sampler_views(r->cso, 1, &src_view);
+ pipe_sampler_view_reference(&src_view, NULL);
+ }
/* shaders */
shader = xorg_shaders_get(r->shaders,
@@ -600,6 +621,8 @@ void renderer_draw_yuv(struct xorg_renderer *r,
if (buf) {
const int num_attribs = 2; /*pos + tex coord*/
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
@@ -642,7 +665,6 @@ void renderer_draw_flush(struct xorg_renderer *r)
}
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures)
{
r->attrs_per_vertex = 1 + num_textures;
@@ -652,7 +674,7 @@ void renderer_begin_textures(struct xorg_renderer *r,
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **sampler_view,
int num_textures,
float *src_matrix,
float *mask_matrix)
@@ -680,7 +702,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[0], pos[1], /* src */
pos[4], pos[5], /* dst */
width, height,
- textures[0], src_matrix);
+ sampler_view[0]->texture, src_matrix);
break;
case 3:
renderer_draw_conditional(r, 4 * 12);
@@ -689,7 +711,7 @@ void renderer_texture(struct xorg_renderer *r,
pos[2], pos[3], /* mask */
pos[4], pos[5], /* dst */
width, height,
- textures[0], textures[1],
+ sampler_view[0]->texture, sampler_view[1]->texture,
src_matrix, mask_matrix);
break;
default:
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index af6aa0567d..cc5802e79b 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -28,6 +28,7 @@ struct xorg_renderer {
float buffer[BUF_SIZE];
int buffer_size;
+ struct pipe_vertex_element velems[3];
/* number of attributes per vertex for the current
* draw operation */
@@ -64,12 +65,12 @@ void renderer_solid(struct xorg_renderer *r,
float *color);
void renderer_begin_textures(struct xorg_renderer *r,
- struct pipe_texture **textures,
int num_textures);
+
void renderer_texture(struct xorg_renderer *r,
int *pos,
int width, int height,
- struct pipe_texture **textures,
+ struct pipe_sampler_view **textures,
int num_textures,
float *src_matrix,
float *mask_matrix);
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index e37a1c3959..5efda6837d 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -9,6 +9,7 @@
#include "xorg_exa_tgsi.h"
#include "cso_cache/cso_context.h"
+#include "util/u_sampler.h"
#include "pipe/p_screen.h"
@@ -91,6 +92,7 @@ struct xorg_xv_port_priv {
/* juggle two sets of seperate Y, U and V
* textures */
struct pipe_texture *yuv[2][3];
+ struct pipe_sampler_view *yuv_views[2][3];
};
@@ -180,32 +182,60 @@ static int
check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
{
struct pipe_texture **dst = priv->yuv[priv->current_set];
+ struct pipe_sampler_view **dst_view = priv->yuv_views[priv->current_set];
+ struct pipe_sampler_view view_templ;
+ struct pipe_context *pipe = priv->r->pipe;
+
if (!dst[0] ||
dst[0]->width0 != width ||
dst[0]->height0 != height) {
pipe_texture_reference(&dst[0], NULL);
+ pipe_sampler_view_reference(&dst_view[0], NULL);
}
if (!dst[1] ||
dst[1]->width0 != width ||
dst[1]->height0 != height) {
pipe_texture_reference(&dst[1], NULL);
+ pipe_sampler_view_reference(&dst_view[1], NULL);
}
if (!dst[2] ||
dst[2]->width0 != width ||
dst[2]->height0 != height) {
pipe_texture_reference(&dst[2], NULL);
+ pipe_sampler_view_reference(&dst_view[2], NULL);
}
- if (!dst[0])
+ if (!dst[0]) {
dst[0] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[0]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[0],
+ dst[0]->format);
+ dst_view[0] = pipe->create_sampler_view(pipe, dst[0], &view_templ);
+ }
+ }
- if (!dst[1])
+ if (!dst[1]) {
dst[1] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[1]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[1],
+ dst[1]->format);
+ dst_view[1] = pipe->create_sampler_view(pipe, dst[1], &view_templ);
+ }
+ }
- if (!dst[2])
+ if (!dst[2]) {
dst[2] = create_component_texture(priv->r->pipe, width, height);
+ if (dst[2]) {
+ u_sampler_view_default_template(&view_templ,
+ dst[2],
+ dst[2]->format);
+ dst_view[2] = pipe->create_sampler_view(pipe, dst[2], &view_templ);
+ }
+ }
- if (!dst[0] || !dst[1] || !dst[2])
+ if (!dst[0] || !dst[1] || !dst[2] || !dst_view[0] || !dst_view[1] || !dst_view[2] )
return BadAlloc;
return Success;
@@ -275,28 +305,28 @@ copy_packed_data(ScrnInfoPtr pScrn,
int i, j;
struct pipe_texture **dst = port->yuv[port->current_set];
struct pipe_transfer *ytrans, *utrans, *vtrans;
- struct pipe_screen *screen = port->r->pipe->screen;
+ struct pipe_context *pipe = port->r->pipe;
char *ymap, *vmap, *umap;
unsigned char y1, y2, u, v;
int yidx, uidx, vidx;
int y_array_size = w * h;
- ytrans = screen->get_tex_transfer(screen, dst[0],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
- utrans = screen->get_tex_transfer(screen, dst[1],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
- vtrans = screen->get_tex_transfer(screen, dst[2],
- 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- left, top, w, h);
-
- ymap = (char*)screen->transfer_map(screen, ytrans);
- umap = (char*)screen->transfer_map(screen, utrans);
- vmap = (char*)screen->transfer_map(screen, vtrans);
+ ytrans = pipe->get_tex_transfer(pipe, dst[0],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+ utrans = pipe->get_tex_transfer(pipe, dst[1],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+ vtrans = pipe->get_tex_transfer(pipe, dst[2],
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ left, top, w, h);
+
+ ymap = (char*)pipe->transfer_map(pipe, ytrans);
+ umap = (char*)pipe->transfer_map(pipe, utrans);
+ vmap = (char*)pipe->transfer_map(pipe, vtrans);
yidx = uidx = vidx = 0;
@@ -362,12 +392,12 @@ copy_packed_data(ScrnInfoPtr pScrn,
break;
}
- screen->transfer_unmap(screen, ytrans);
- screen->transfer_unmap(screen, utrans);
- screen->transfer_unmap(screen, vtrans);
- screen->tex_transfer_destroy(ytrans);
- screen->tex_transfer_destroy(utrans);
- screen->tex_transfer_destroy(vtrans);
+ pipe->transfer_unmap(pipe, ytrans);
+ pipe->transfer_unmap(pipe, utrans);
+ pipe->transfer_unmap(pipe, vtrans);
+ pipe->tex_transfer_destroy(pipe, ytrans);
+ pipe->tex_transfer_destroy(pipe, utrans);
+ pipe->tex_transfer_destroy(pipe, vtrans);
}
@@ -450,6 +480,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state sampler;
struct pipe_texture **dst = port->yuv[port->current_set];
+ struct pipe_sampler_view **dst_views = port->yuv_views[port->current_set];
memset(&sampler, 0, sizeof(struct pipe_sampler_state));
@@ -469,8 +500,7 @@ bind_samplers(struct xorg_xv_port_priv *port)
cso_set_samplers(port->r->cso, 3,
(const struct pipe_sampler_state **)samplers);
- cso_set_sampler_textures(port->r->cso, 3,
- dst);
+ cso_set_fragment_sampler_views(port->r->cso, 3, dst_views);
}
static int
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 87d1dfaace..12d94e0c5c 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -106,7 +106,7 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
- template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_SHARED;
tex = vpipe->screen->texture_create(vpipe->screen, &template);
if (!tex)