summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/include/state_tracker/dri1_api.h8
-rw-r--r--src/gallium/include/state_tracker/drisw_api.h35
-rw-r--r--src/gallium/state_trackers/dri/common/dri_st_api.c2
-rw-r--r--src/gallium/state_trackers/dri/drm/dri1.c30
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c100
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.h2
-rw-r--r--src/gallium/targets/dri-swrast/swrast_drm_api.c17
-rw-r--r--src/gallium/targets/libgl-xlib/xlib.c8
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c37
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.h4
10 files changed, 141 insertions, 102 deletions
diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h
index 27b7a28c467..bb1cd6d1d82 100644
--- a/src/gallium/include/state_tracker/dri1_api.h
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -7,14 +7,14 @@
#include "state_tracker/drm_api.h"
-struct drm_clip_rect;
-
struct pipe_screen;
struct pipe_winsys;
struct pipe_buffer;
struct pipe_context;
struct pipe_texture;
+struct drm_clip_rect;
+
struct dri1_api_version
{
int major;
@@ -31,8 +31,8 @@ struct dri1_api_lock_funcs
{
void (*lock) (struct pipe_context * pipe);
void (*unlock) (struct pipe_context * locked_pipe);
- boolean(*is_locked) (struct pipe_context * locked_pipe);
- boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
+ boolean(*is_locked) (struct pipe_context * locked_pipe);
+ boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
void (*clear_lost_lock) (struct pipe_context * locked_pipe);
};
diff --git a/src/gallium/include/state_tracker/drisw_api.h b/src/gallium/include/state_tracker/drisw_api.h
new file mode 100644
index 00000000000..c6adebb4ec5
--- /dev/null
+++ b/src/gallium/include/state_tracker/drisw_api.h
@@ -0,0 +1,35 @@
+#ifndef _DRISW_API_H_
+#define _DRISW_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_format.h"
+
+#include "state_tracker/drm_api.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_buffer;
+struct pipe_context;
+struct pipe_texture;
+
+struct dri_drawable;
+
+/**
+ * This callback struct is intended for the winsys to call the loader.
+ */
+
+struct drisw_loader_funcs
+{
+ void (*put_image) (struct dri_drawable *dri_drawable,
+ void *data, unsigned width, unsigned height);
+};
+
+struct drisw_create_screen_arg
+{
+ struct drm_create_screen_arg base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+#endif
diff --git a/src/gallium/state_trackers/dri/common/dri_st_api.c b/src/gallium/state_trackers/dri/common/dri_st_api.c
index 40b24b18e9f..7ba7ec383d8 100644
--- a/src/gallium/state_trackers/dri/common/dri_st_api.c
+++ b/src/gallium/state_trackers/dri/common/dri_st_api.c
@@ -80,7 +80,7 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
}
#else
if (new_stamp)
- drisw_update_drawable_info(drawable->dPriv);
+ drisw_update_drawable_info(drawable);
drisw_allocate_textures(drawable, statt_mask);
#endif
diff --git a/src/gallium/state_trackers/dri/drm/dri1.c b/src/gallium/state_trackers/dri/drm/dri1.c
index aad098bb301..9b5842ba2bf 100644
--- a/src/gallium/state_trackers/dri/drm/dri1.c
+++ b/src/gallium/state_trackers/dri/drm/dri1.c
@@ -404,6 +404,19 @@ dri1_allocate_textures(struct dri_drawable *drawable,
drawable->old_h = height;
}
+/*
+ * Backend function for init_screen.
+ */
+
+static const __DRIextension *dri1_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+};
+
static void
st_dri_lock(struct pipe_context *pipe)
{
@@ -442,21 +455,6 @@ static struct dri1_api_lock_funcs dri1_lf = {
.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)
@@ -466,6 +464,8 @@ dri1_copy_version(struct dri1_api_version *dst,
dst->patch_level = src->patch;
}
+struct dri1_api *__dri1_api_hooks = NULL;
+
const __DRIconfig **
dri1_init_screen(__DRIscreen * sPriv)
{
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index b7eba63bcb9..b8256710972 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -28,37 +28,17 @@
/* 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 dri1_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 / texture_from_pixmap / EGLImage:
*
* 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 other issues.
- *
- * fences:
- *
- * No fences are used, are they needed for llvmpipe / cell ?
+ * for createImage/destroyImage similar to DRI2 getBuffers.
*/
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "pipe/p_context.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drisw_api.h"
#include "dri_screen.h"
#include "dri_context.h"
@@ -80,60 +60,47 @@ get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
dPriv->loaderPrivate);
}
-/*
- * Set the width to 'stride / cpp'. PutImage seems to correctly clip the width
- * to the actual width of the dst drawable. Even if this is not specified but
- * an implementation detail, it is the correct thing to do, so rely on it. XXX
- */
static INLINE void
-put_image(__DRIdrawable *dPriv, void *data, unsigned width)
+put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
{
__DRIscreen *sPriv = dPriv->driScreenPriv;
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
- 0, 0, width, dPriv->h,
+ 0, 0, width, height,
data, dPriv->loaderPrivate);
}
void
-drisw_update_drawable_info(__DRIdrawable *dPriv)
+drisw_update_drawable_info(struct dri_drawable *drawable)
{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
}
+static void
+drisw_put_image(struct dri_drawable *drawable,
+ void *data, unsigned width, unsigned height)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+
+ put_image(dPriv, data, width, height);
+}
+
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;
- unsigned width;
- pipe = dri1_get_pipe_context(screen);
psurf = dri1_get_pipe_surface(drawable, ptex);
- if (!pipe || !psurf)
+ if (!psurf)
return;
- ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
- PIPE_TRANSFER_READ,
- 0, 0, dPriv->w, dPriv->h);
-
- width = ptrans->stride / util_format_get_blocksize(ptex->format);
-
- pmap = pipe->transfer_map(pipe, ptrans);
-
- assert(pmap);
-
- put_image(dPriv, pmap, width);
-
- pipe->transfer_unmap(pipe, ptrans);
-
- pipe->tex_transfer_destroy(pipe, ptrans);
+ screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable);
}
static INLINE void
@@ -163,38 +130,38 @@ drisw_copy_to_front(__DRIdrawable * dPriv,
*/
void
-drisw_flush_frontbuffer(struct dri_drawable *drawable,
- enum st_attachment_type statt)
+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[statt];
+ ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
- drisw_copy_to_front(ctx->dPriv, ptex);
+ ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ drisw_copy_to_front(dPriv, ptex);
}
}
void
-drisw_swap_buffers(__DRIdrawable *dPriv)
+drisw_flush_frontbuffer(struct dri_drawable *drawable,
+ enum st_attachment_type statt)
{
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];
+ ptex = drawable->textures[statt];
if (ptex) {
- ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-
- drisw_copy_to_front(dPriv, ptex);
+ drisw_copy_to_front(ctx->dPriv, ptex);
}
}
@@ -286,12 +253,16 @@ static const __DRIextension *drisw_screen_extensions[] = {
NULL
};
+static struct drisw_loader_funcs drisw_lf = {
+ .put_image = drisw_put_image
+};
+
const __DRIconfig **
drisw_init_screen(__DRIscreen * sPriv)
{
const __DRIconfig **configs;
struct dri_screen *screen;
- struct drm_create_screen_arg arg;
+ struct drisw_create_screen_arg arg;
screen = CALLOC_STRUCT(dri_screen);
if (!screen)
@@ -304,9 +275,10 @@ drisw_init_screen(__DRIscreen * sPriv)
sPriv->private = (void *)screen;
sPriv->extensions = drisw_screen_extensions;
- arg.mode = DRM_CREATE_DRISW;
+ arg.base.mode = DRM_CREATE_DRISW;
+ arg.lf = &drisw_lf;
- configs = dri_init_screen_helper(screen, &arg, 32);
+ configs = dri_init_screen_helper(screen, &arg.base, 32);
if (!configs)
goto fail;
diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h
index 2c0d5610fac..c0c874f7326 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.h
+++ b/src/gallium/state_trackers/dri/sw/drisw.h
@@ -39,7 +39,7 @@ const __DRIconfig **
drisw_init_screen(__DRIscreen * sPriv);
void
-drisw_update_drawable_info(__DRIdrawable *dPriv);
+drisw_update_drawable_info(struct dri_drawable *drawable);
void
drisw_flush_frontbuffer(struct dri_drawable *drawable,
diff --git a/src/gallium/targets/dri-swrast/swrast_drm_api.c b/src/gallium/targets/dri-swrast/swrast_drm_api.c
index 1f24d7650d7..63b935bb07b 100644
--- a/src/gallium/targets/dri-swrast/swrast_drm_api.c
+++ b/src/gallium/targets/dri-swrast/swrast_drm_api.c
@@ -32,15 +32,7 @@
#include "state_tracker/sw_winsys.h"
#include "dri_sw_winsys.h"
-/* Copied from targets/libgl-xlib.
- *
- * TODO:
- * This function should be put in targets/common or winsys/sw/common and shared
- * with targets/libgl-xlib and winsys/sw/drm.
- *
- * For targets/common, you get layering violations unless all of drm_api's are
- * moved under targets.
- */
+/* Copied from targets/libgl-xlib */
#ifdef GALLIUM_SOFTPIPE
#include "softpipe/sp_public.h"
@@ -98,19 +90,24 @@ swrast_drm_create_screen(struct drm_api *api,
{
struct sw_winsys *winsys = NULL;
struct pipe_screen *screen = NULL;
+ struct drisw_create_screen_arg *drisw;
(void) drmFD;
if (arg != NULL) {
switch(arg->mode) {
case DRM_CREATE_DRISW:
+ drisw = (struct drisw_create_screen_arg *)arg;
break;
default:
return NULL;
}
}
+ else {
+ return NULL;
+ }
- winsys = dri_create_sw_winsys();
+ winsys = dri_create_sw_winsys(drisw->lf);
if (winsys == NULL)
return NULL;
diff --git a/src/gallium/targets/libgl-xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c
index 4a8366280d8..48e5bdff429 100644
--- a/src/gallium/targets/libgl-xlib/xlib.c
+++ b/src/gallium/targets/libgl-xlib/xlib.c
@@ -55,6 +55,14 @@ PUBLIC const struct st_module st_module_OpenGL = {
* 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.
+ *
+ * Copies (full or partial):
+ * targets/libgl-xlib
+ * targets/graw-xlib
+ * targets/dri-swrast
+ * winsys/sw/drm
+ * drivers/sw
+ *
*/
#ifdef GALLIUM_SOFTPIPE
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
index fb4722fc75f..870c6afc124 100644
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -39,6 +39,11 @@
struct dri_sw_displaytarget
{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
void *data;
void *mapped;
};
@@ -46,6 +51,8 @@ struct dri_sw_displaytarget
struct dri_sw_winsys
{
struct sw_winsys base;
+
+ struct drisw_loader_funcs *lf;
};
static INLINE struct dri_sw_displaytarget *
@@ -79,23 +86,27 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
unsigned *stride)
{
struct dri_sw_displaytarget *dri_sw_dt;
- unsigned nblocksy, size, dri_sw_stride, format_stride;
+ unsigned nblocksy, size, format_stride;
dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
if(!dri_sw_dt)
goto no_dt;
+ dri_sw_dt->format = format;
+ dri_sw_dt->width = width;
+ dri_sw_dt->height = height;
+
format_stride = util_format_get_stride(format, width);
- dri_sw_stride = align(format_stride, alignment);
+ dri_sw_dt->stride = align(format_stride, alignment);
nblocksy = util_format_get_nblocksy(format, height);
- size = dri_sw_stride * nblocksy;
+ size = dri_sw_dt->stride * nblocksy;
dri_sw_dt->data = align_malloc(size, alignment);
if(!dri_sw_dt->data)
goto no_data;
- *stride = dri_sw_stride;
+ *stride = dri_sw_dt->stride;
return (struct sw_displaytarget *)dri_sw_dt;
no_data:
@@ -159,7 +170,20 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
struct sw_displaytarget *dt,
void *context_private)
{
- assert(0);
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
+ unsigned width, height;
+
+ /* Set the width to 'stride / cpp'.
+ *
+ * PutImage correctly clips to the width of the dst drawable.
+ */
+ width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
+
+ height = dri_sw_dt->height;
+
+ dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
}
@@ -170,7 +194,7 @@ dri_destroy_sw_winsys(struct sw_winsys *winsys)
}
struct sw_winsys *
-dri_create_sw_winsys(void)
+dri_create_sw_winsys(struct drisw_loader_funcs *lf)
{
struct dri_sw_winsys *ws;
@@ -178,6 +202,7 @@ dri_create_sw_winsys(void)
if (!ws)
return NULL;
+ ws->lf = lf;
ws->base.destroy = dri_destroy_sw_winsys;
ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
index c2382a68d78..329ac06a05b 100644
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.h
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
@@ -29,8 +29,10 @@
#ifndef DRI_SW_WINSYS
#define DRI_SW_WINSYS
+#include "state_tracker/drisw_api.h"
+
struct sw_winsys;
-struct sw_winsys *dri_create_sw_winsys(void);
+struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
#endif