diff options
Diffstat (limited to 'src/gallium/state_trackers/dri/common/dri_drawable.c')
-rw-r--r-- | src/gallium/state_trackers/dri/common/dri_drawable.c | 61 |
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; |