summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2010-01-18 12:11:15 +0800
committerChia-I Wu <olvaffe@gmail.com>2010-01-18 14:28:13 +0800
commitfda897ad71738dd76a218280fd2e635d5dcdcee1 (patch)
tree68464fd349728431c9a1175fdbf92a63829192a9
parent1ed63119452396e764a0f5b11db78903a2594df1 (diff)
st/egl_g3d: Update validate to use an attachment mask.
A validate call asks for the buffers of a native surface. Using a mask to represent the interested buffers is more intuitive. It also rules out corner cases such as a single attachment being listed multiple times.
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/egl_g3d.c51
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/egl_g3d.h4
-rw-r--r--src/gallium/state_trackers/egl_g3d/common/native.h29
-rw-r--r--src/gallium/state_trackers/egl_g3d/kms/native_kms.c29
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/native_dri2.c89
-rw-r--r--src/gallium/state_trackers/egl_g3d/x11/native_ximage.c43
6 files changed, 116 insertions, 129 deletions
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
index 51da8e19f5e..08f796d0836 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.c
@@ -44,8 +44,13 @@ 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);
- EGLint num_surfaces;
- EGLint s, i;
+ 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;
@@ -53,6 +58,7 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
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);
@@ -66,30 +72,31 @@ egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!gctx->force_validate) {
unsigned int seq_num;
- gsurf->native->validate(gsurf->native,
- gbuf->native_atts, gbuf->num_atts,
+ gsurf->native->validate(gsurf->native, gbuf->attachment_mask,
&seq_num, NULL, NULL, NULL);
/* skip validation */
if (gsurf->sequence_number == seq_num)
continue;
}
- gsurf->native->validate(gsurf->native,
- gbuf->native_atts, gbuf->num_atts,
+ 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 (i = 0; i < gbuf->num_atts; i++) {
- struct pipe_texture *pt = textures[i];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *pt = textures[att];
struct pipe_surface *ps;
- if (pt) {
+ 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,
- gbuf->st_atts[i], ps);
+ st_att_map[att], ps);
- if (gbuf->native_atts[i] == gsurf->render_att)
+ if (gsurf->render_att == att)
pipe_surface_reference(&gsurf->render_surface, ps);
pipe_surface_reference(&ps, NULL);
@@ -128,13 +135,7 @@ static void
egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
{
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 s, i;
+ EGLint s;
/* route draw and read buffers' attachments */
for (s = 0; s < 2; s++) {
@@ -150,11 +151,7 @@ egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx)
gbuf = &gctx->read;
}
- gbuf->native_atts[0] = gsurf->render_att;
- gbuf->num_atts = 1;
-
- for (i = 0; i < gbuf->num_atts; i++)
- gbuf->st_atts[i] = st_att_map[gbuf->native_atts[i]];
+ 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,
@@ -196,19 +193,19 @@ egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx)
if (!gdraw || priv != (void *) &gdraw->base) {
gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb);
gctx->draw.st_fb = NULL;
- gctx->draw.num_atts = 0;
+ gctx->draw.attachment_mask = 0x0;
}
if (is_equal) {
gctx->read.st_fb = NULL;
- gctx->draw.num_atts = 0;
+ 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.num_atts = 0;
+ gctx->draw.attachment_mask = 0x0;
}
}
}
@@ -628,7 +625,7 @@ init_surface_geometry(_EGLSurface *surf)
{
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- return gsurf->native->validate(gsurf->native, NULL, 0,
+ return gsurf->native->validate(gsurf->native, 0x0,
&gsurf->sequence_number, NULL,
&gsurf->base.Width, &gsurf->base.Height);
}
diff --git a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
index 4c8b8dfe9e0..1da8af495b1 100644
--- a/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl_g3d/common/egl_g3d.h
@@ -52,9 +52,7 @@ struct egl_g3d_display {
struct egl_g3d_buffer {
struct st_framebuffer *st_fb;
- EGLint num_atts;
- enum native_attachment native_atts[NUM_NATIVE_ATTACHMENTS];
- uint st_atts[NUM_NATIVE_ATTACHMENTS];
+ uint attachment_mask;
};
struct egl_g3d_context {
diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h
index 76f0e0c78ac..6cd161bdf6c 100644
--- a/src/gallium/state_trackers/egl_g3d/common/native.h
+++ b/src/gallium/state_trackers/egl_g3d/common/native.h
@@ -64,18 +64,18 @@ struct native_surface {
boolean (*flush_frontbuffer)(struct native_surface *nsurf);
/**
- * Validate the buffers of the surface. The returned textures are owned by
- * the caller. A sequence number is also returned. The caller can use it
- * to check if anything has changed since the last call. Any of the pointers
- * may be NULL and it indicates the caller has no interest in those values.
+ * Validate the buffers of the surface. textures, if not NULL, points to an
+ * array of size NUM_NATIVE_ATTACHMENTS and the returned textures are owned
+ * by the caller. A sequence number is also returned. The caller can use
+ * it to check if anything has changed since the last call. Any of the
+ * pointers may be NULL and it indicates the caller has no interest in those
+ * values.
*
- * If this function is called multiple times with different attachments,
- * those not listed in the latest call might be destroyed. This behavior
- * might change in the future.
+ * If this function is called multiple times with different attachment
+ * masks, those not listed in the latest call might be destroyed. This
+ * behavior might change in the future.
*/
- boolean (*validate)(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
+ boolean (*validate)(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height);
@@ -211,6 +211,15 @@ struct native_display_modeset {
const struct native_mode *nmode);
};
+/**
+ * Test whether an attachment is set in the mask.
+ */
+static INLINE boolean
+native_attachment_mask_test(uint mask, enum native_attachment att)
+{
+ return !!(mask & (1 << att));
+}
+
const char *
native_get_name(void);
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
index 65829fc7b3d..dc664366305 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
@@ -33,9 +33,7 @@
#include "native_kms.h"
static boolean
-kms_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
+kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
unsigned int *seq_num, struct pipe_texture **textures,
int *width, int *height)
{
@@ -43,12 +41,9 @@ kms_surface_validate(struct native_surface *nsurf,
struct kms_display *kdpy = ksurf->kdpy;
struct pipe_screen *screen = kdpy->base.screen;
struct pipe_texture templ, *ptex;
- int i;
-
- if (num_natts) {
- if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
+ int att;
+ if (attachment_mask) {
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
@@ -62,17 +57,21 @@ kms_surface_validate(struct native_surface *nsurf,
}
/* create textures */
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
- ptex = ksurf->textures[natt];
+ ptex = ksurf->textures[att];
if (!ptex) {
ptex = screen->texture_create(screen, &templ);
- ksurf->textures[natt] = ptex;
+ ksurf->textures[att] = ptex;
}
- if (textures)
- pipe_texture_reference(&textures[i], ptex);
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], ptex);
+ }
}
if (seq_num)
@@ -113,7 +112,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
if (!fb->texture) {
/* make sure the texture has been allocated */
- kms_surface_validate(&ksurf->base, &natt, 1, NULL, NULL, NULL, NULL);
+ kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL);
if (!ksurf->textures[natt])
return FALSE;
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
index f497d8c1c77..f675a8e6861 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_dri2.c
@@ -134,22 +134,18 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
}
static boolean
-dri2_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
- unsigned int *seq_num,
- struct pipe_texture **textures,
- int *width, int *height)
+dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
- EGLint texture_indices[NUM_NATIVE_ATTACHMENTS];
struct pipe_texture templ;
struct x11_drawable_buffer *xbufs;
- int num_ins, num_outs, i;
+ int num_ins, num_outs, att, i;
- if (num_natts) {
+ if (attachment_mask) {
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.last_level = 0;
@@ -160,24 +156,27 @@ dri2_surface_validate(struct native_surface *nsurf,
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
+ memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS);
}
/* create textures for pbuffer */
if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
struct pipe_screen *screen = dri2dpy->base.screen;
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
- struct pipe_texture *ptex = dri2surf->pbuffer_textures[natt];
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct pipe_texture *ptex = dri2surf->pbuffer_textures[att];
+
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
+ continue;
if (!ptex) {
ptex = screen->texture_create(screen, &templ);
- dri2surf->pbuffer_textures[natt] = ptex;
+ dri2surf->pbuffer_textures[att] = ptex;
}
if (textures)
- pipe_texture_reference(&textures[i], ptex);
+ pipe_texture_reference(&textures[att], ptex);
}
if (seq_num)
@@ -190,34 +189,34 @@ dri2_surface_validate(struct native_surface *nsurf,
return TRUE;
}
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
- texture_indices[i] = -1;
-
/* prepare the attachments */
- num_ins = num_natts;
- for (i = 0; i < num_natts; i++) {
- unsigned int dri2att;
+ num_ins = 0;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(attachment_mask, att)) {
+ unsigned int dri2att;
+
+ switch (att) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ dri2att = DRI2BufferFrontLeft;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ dri2att = DRI2BufferBackLeft;
+ break;
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ dri2att = DRI2BufferFrontRight;
+ break;
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ dri2att = DRI2BufferBackRight;
+ break;
+ default:
+ assert(0);
+ dri2att = 0;
+ break;
+ }
- switch (natts[i]) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- dri2att = DRI2BufferFrontLeft;
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- dri2att = DRI2BufferBackLeft;
- break;
- case NATIVE_ATTACHMENT_FRONT_RIGHT:
- dri2att = DRI2BufferFrontRight;
- break;
- case NATIVE_ATTACHMENT_BACK_RIGHT:
- dri2att = DRI2BufferBackRight;
- break;
- default:
- assert(0);
- dri2att = 0;
- break;
+ dri2atts[num_ins] = dri2att;
+ num_ins++;
}
- dri2atts[i] = dri2att;
- texture_indices[natts[i]] = i;
}
dri2surf->have_back = FALSE;
@@ -266,13 +265,13 @@ dri2_surface_validate(struct native_surface *nsurf,
break;
}
- if (!desc || texture_indices[natt] < 0 ||
- (textures && textures[texture_indices[natt]])) {
+ if (!desc || !native_attachment_mask_test(attachment_mask, natt) ||
+ (textures && textures[natt])) {
if (!desc)
_eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
- else if (texture_indices[natt] < 0)
+ else if (!native_attachment_mask_test(attachment_mask, natt))
_eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
- else if (textures && textures[texture_indices[natt]])
+ else
_eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
continue;
}
@@ -284,7 +283,7 @@ dri2_surface_validate(struct native_surface *nsurf,
desc, xbuf->pitch, xbuf->name);
if (ptex) {
/* the caller owns the textures */
- textures[texture_indices[natt]] = ptex;
+ textures[natt] = ptex;
}
}
}
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
index 24a50df7a0a..1f136235c0c 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_ximage.c
@@ -289,27 +289,21 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
}
static boolean
-ximage_surface_validate(struct native_surface *nsurf,
- const enum native_attachment *natts,
- unsigned num_natts,
- unsigned int *seq_num,
- struct pipe_texture **textures,
- int *width, int *height)
+ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean new_buffers = FALSE, error = FALSE;
- unsigned i;
+ boolean new_buffers = FALSE;
+ int att;
ximage_surface_update_geometry(&xsurf->base);
- if (textures)
- memset(textures, 0, sizeof(*textures) * num_natts);
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[att];
- for (i = 0; i < num_natts; i++) {
- enum native_attachment natt = natts[i];
- struct ximage_buffer *xbuf = &xsurf->buffers[natt];
-
- if (!xbuf)
+ /* delay the allocation */
+ if (!native_attachment_mask_test(attachment_mask, att))
continue;
/* reallocate the texture */
@@ -317,7 +311,7 @@ ximage_surface_validate(struct native_surface *nsurf,
xsurf->width != xbuf->texture->width0 ||
xsurf->height != xbuf->texture->height0) {
new_buffers = TRUE;
- if (ximage_surface_alloc_buffer(&xsurf->base, natt)) {
+ if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
/* update ximage */
if (xbuf->ximage) {
xbuf->ximage->width = xbuf->transfer->width;
@@ -327,19 +321,10 @@ ximage_surface_validate(struct native_surface *nsurf,
}
}
- /* allocation failed */
- if (!xbuf->texture) {
- unsigned j;
- for (j = 0; j < i; j++)
- pipe_texture_reference(&textures[j], NULL);
- for (j = i; j < num_natts; j++)
- textures[j] = NULL;
- error = TRUE;
- break;
+ if (textures) {
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], xbuf->texture);
}
-
- if (textures)
- pipe_texture_reference(&textures[i], xbuf->texture);
}
/* increase the sequence number so that caller knows */
@@ -353,7 +338,7 @@ ximage_surface_validate(struct native_surface *nsurf,
if (height)
*height = xsurf->height;
- return !error;
+ return TRUE;
}
static void