summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/dri/common/dri_drawable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/dri/common/dri_drawable.c')
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c61
1 files changed, 56 insertions, 5 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index dca6def284c..ee4d11d1495 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -51,12 +51,15 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
(struct dri_drawable *) stfbi->st_manager_private;
struct dri_screen *screen = dri_screen(drawable->sPriv);
unsigned statt_mask, new_mask;
boolean new_stamp;
int i;
unsigned int lastStamp;
+ struct pipe_resource **textures =
+ drawable->stvis.samples > 1 ? drawable->msaa_textures
+ : drawable->textures;
statt_mask = 0x0;
for (i = 0; i < count; i++)
statt_mask |= (1 << statts[i]);
/* record newly allocated textures */
@@ -76,27 +79,28 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
drawable->update_drawable_info(drawable);
drawable->allocate_textures(drawable, statts, count);
/* add existing textures */
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
- if (drawable->textures[i])
+ if (textures[i])
statt_mask |= (1 << i);
}
drawable->texture_stamp = lastStamp;
drawable->texture_mask = statt_mask;
}
} while (lastStamp != drawable->dPriv->lastStamp);
if (!out)
return TRUE;
+ /* Set the window-system buffers for the state tracker. */
for (i = 0; i < count; i++) {
out[i] = NULL;
- pipe_resource_reference(&out[i], drawable->textures[statts[i]]);
+ pipe_resource_reference(&out[i], textures[statts[i]]);
}
return TRUE;
}
static boolean
@@ -163,12 +167,14 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
int i;
pipe_surface_reference(&drawable->drisw_surface, NULL);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&drawable->textures[i], NULL);
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_resource_reference(&drawable->msaa_textures[i], NULL);
swap_fences_unref(drawable);
FREE(drawable);
}
@@ -349,12 +355,54 @@ swap_fences_unref(struct dri_drawable *draw)
screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
draw->tail &= DRI_SWAP_FENCES_MASK;
--draw->cur_fences;
}
}
+void
+dri_msaa_resolve(struct dri_context *ctx,
+ struct dri_drawable *drawable,
+ enum st_attachment_type att)
+{
+ struct pipe_context *pipe = ctx->st->pipe;
+ struct pipe_resource *dst = drawable->textures[att];
+ struct pipe_resource *src = drawable->msaa_textures[att];
+ struct pipe_blit_info blit;
+
+ if (!dst || !src)
+ return;
+
+ memset(&blit, 0, sizeof(blit));
+ blit.dst.resource = dst;
+ blit.dst.box.width = dst->width0;
+ blit.dst.box.height = dst->width0;
+ blit.dst.box.depth = 1;
+ blit.dst.format = util_format_linear(dst->format);
+ blit.src.resource = src;
+ blit.src.box.width = src->width0;
+ blit.src.box.height = src->width0;
+ blit.src.box.depth = 1;
+ blit.src.format = util_format_linear(src->format);
+ blit.mask = PIPE_MASK_RGBA;
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+
+ pipe->blit(pipe, &blit);
+}
+
+static void
+dri_postprocessing(struct dri_context *ctx,
+ struct dri_drawable *drawable,
+ enum st_attachment_type att)
+{
+ struct pipe_resource *src = drawable->textures[att];
+ struct pipe_resource *zsbuf = drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL];
+
+ if (ctx->pp && src && zsbuf)
+ pp_run(ctx->pp, src, src, zsbuf);
+}
+
/**
* DRI2 flush extension, the flush_with_flags function.
*
* \param context the context
* \param drawable the drawable to flush
* \param flags a combination of _DRI2_FLUSH_xxx flags
@@ -378,16 +426,19 @@ dri_flush(__DRIcontext *cPriv,
if (!drawable) {
flags &= ~__DRI2_FLUSH_DRAWABLE;
}
/* Flush the drawable. */
if (flags & __DRI2_FLUSH_DRAWABLE) {
- struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
+ /* Resolve MSAA buffers. */
+ if (drawable->stvis.samples > 1) {
+ dri_msaa_resolve(ctx, drawable, ST_ATTACHMENT_BACK_LEFT);
+ /* FRONT_LEFT is resolved in drawable->flush_frontbuffer. */
+ }
- if (ptex && ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
- pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);
+ dri_postprocessing(ctx, drawable, ST_ATTACHMENT_BACK_LEFT);
}
flush_flags = 0;
if (flags & __DRI2_FLUSH_CONTEXT)
flush_flags |= ST_FLUSH_FRONT;