aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorGeorge Sapountzis <[email protected]>2010-03-25 17:01:53 +0200
committerGeorge Sapountzis <[email protected]>2010-03-25 17:01:53 +0200
commit5b75e12f9165c890fd14b22983d6289be8f20abc (patch)
treeb0e4eb57f76b15c8e4702ce44d1932ffb1ef38c2 /src/gallium/state_trackers
parent1bed0eb98e00ed9ea7431f19ab3bed8860864264 (diff)
st/dri: add drisw
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c33
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h12
-rw-r--r--src/gallium/state_trackers/dri/dri_st_api.c12
-rw-r--r--src/gallium/state_trackers/dri/drisw.c288
-rw-r--r--src/gallium/state_trackers/dri/drisw.h54
5 files changed, 399 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 1d808f0f7f9..ae311641042 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -30,7 +30,9 @@
*/
#include "utils.h"
+#ifndef __NOT_HAVE_DRM_H
#include "vblank.h"
+#endif
#include "xmlpool.h"
#include "dri_screen.h"
@@ -40,6 +42,7 @@
#include "dri1_helper.h"
#include "dri1.h"
#include "dri2.h"
+#include "drisw.h"
#include "util/u_inlines.h"
#include "pipe/p_screen.h"
@@ -262,6 +265,8 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
/* let the state tracker allocate the accum buffer */
}
+#ifndef __NOT_HAVE_DRM_H
+
/**
* Get information about previous buffer swaps.
*/
@@ -274,6 +279,8 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo)
return 0;
}
+#endif
+
static void
dri_destroy_option_cache(struct dri_screen * screen)
{
@@ -308,6 +315,8 @@ dri_destroy_screen(__DRIscreen * sPriv)
sPriv->extensions = NULL;
}
+#ifndef __NOT_HAVE_DRM_H
+
const struct __DriverAPIRec driDriverAPI = {
.DestroyScreen = dri_destroy_screen,
.CreateContext = dri_create_context,
@@ -334,4 +343,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 639d48661e2..4f59db37cfa 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -75,6 +75,8 @@ dri_screen(__DRIscreen * sPriv)
return (struct dri_screen *)sPriv->private;
}
+#ifndef __NOT_HAVE_DRM_H
+
static INLINE boolean
dri_with_format(__DRIscreen * sPriv)
{
@@ -85,6 +87,16 @@ dri_with_format(__DRIscreen * sPriv)
&& (loader->getBuffersWithFormat != NULL);
}
+#else
+
+static INLINE boolean
+dri_with_format(__DRIscreen * sPriv)
+{
+ return TRUE;
+}
+
+#endif
+
extern const uint __driNConfigOptions;
const __DRIconfig **
diff --git a/src/gallium/state_trackers/dri/dri_st_api.c b/src/gallium/state_trackers/dri/dri_st_api.c
index 3592a782229..2b98c487c84 100644
--- a/src/gallium/state_trackers/dri/dri_st_api.c
+++ b/src/gallium/state_trackers/dri/dri_st_api.c
@@ -38,6 +38,7 @@
#include "dri1_helper.h"
#include "dri1.h"
#include "dri2.h"
+#include "drisw.h"
static boolean
dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
@@ -67,12 +68,19 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
if (new_stamp || new_mask) {
+#ifndef __NOT_HAVE_DRM_H
if (__dri1_api_hooks) {
dri1_allocate_textures(drawable, statt_mask);
}
else {
dri_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++) {
@@ -102,12 +110,16 @@ dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
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 {
dri_flush_frontbuffer(drawable, statt);
}
+#else
+ drisw_flush_frontbuffer(drawable, statt);
+#endif
return TRUE;
}
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
new file mode 100644
index 00000000000..b3d65df8815
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drisw.c
@@ -0,0 +1,288 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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.
+ *
+ **************************************************************************/
+
+#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 00000000000..2c0d5610fac
--- /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 <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 */