summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/swr/swr_context.cpp
diff options
context:
space:
mode:
authorBruce Cherniak <[email protected]>2016-03-09 19:30:00 -0600
committerTim Rowley <[email protected]>2016-03-14 14:07:48 -0500
commite9d68cc3da07c4b566799bbaec2434bfc21d3e0c (patch)
treee84d07138133a29b1398de4355cebecf4fae3b1d /src/gallium/drivers/swr/swr_context.cpp
parent7a2333e4efbaefe6bd6db87b9b2443737c89f01e (diff)
gallium/swr: Resource management
Better tracking of resource state and synchronization. A follow on commit will clean up resource functions into a new swr_resource.cpp file. Reviewed-By: George Kyriazis <[email protected]>
Diffstat (limited to 'src/gallium/drivers/swr/swr_context.cpp')
-rw-r--r--src/gallium/drivers/swr/swr_context.cpp103
1 files changed, 39 insertions, 64 deletions
diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp
index 0e7ebb74d92..c8cb145d334 100644
--- a/src/gallium/drivers/swr/swr_context.cpp
+++ b/src/gallium/drivers/swr/swr_context.cpp
@@ -36,6 +36,7 @@ extern "C" {
#include "swr_resource.h"
#include "swr_scratch.h"
#include "swr_query.h"
+#include "swr_fence.h"
#include "api.h"
#include "backend.h"
@@ -85,36 +86,10 @@ swr_surface_destroy(struct pipe_context *pipe, struct pipe_surface *surf)
assert(surf->texture);
struct pipe_resource *resource = surf->texture;
- /* If the surface being destroyed is a current render target,
- * call StoreTiles to resolve the hotTile state then set attachment
- * to NULL.
- */
- if (resource->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL
- | PIPE_BIND_DISPLAY_TARGET)) {
- struct swr_context *ctx = swr_context(pipe);
- struct swr_resource *spr = swr_resource(resource);
- swr_draw_context *pDC = &ctx->swrDC;
- SWR_SURFACE_STATE *renderTargets = pDC->renderTargets;
- for (uint32_t i = 0; i < SWR_NUM_ATTACHMENTS; i++)
- if (renderTargets[i].pBaseAddress == spr->swr.pBaseAddress) {
- swr_store_render_target(ctx, i, SWR_TILE_RESOLVED);
-
- /*
- * Mesa thinks depth/stencil are fused, so we'll never get an
- * explicit resource for stencil. So, if checking depth, then
- * also check for stencil.
- */
- if (spr->has_stencil && (i == SWR_ATTACHMENT_DEPTH)) {
- swr_store_render_target(
- ctx, SWR_ATTACHMENT_STENCIL, SWR_TILE_RESOLVED);
- }
-
- SwrWaitForIdle(ctx->swrContext);
- break;
- }
- }
+ /* If the resource has been drawn to, store tiles. */
+ swr_store_dirty_resource(pipe, resource, SWR_TILE_RESOLVED);
- pipe_resource_reference(&surf->texture, NULL);
+ pipe_resource_reference(&resource, NULL);
FREE(surf);
}
@@ -127,6 +102,7 @@ swr_transfer_map(struct pipe_context *pipe,
const struct pipe_box *box,
struct pipe_transfer **transfer)
{
+ struct swr_screen *screen = swr_screen(pipe->screen);
struct swr_resource *spr = swr_resource(resource);
struct pipe_transfer *pt;
enum pipe_format format = resource->format;
@@ -134,30 +110,28 @@ swr_transfer_map(struct pipe_context *pipe,
assert(resource);
assert(level <= resource->last_level);
- /*
- * If mapping any attached rendertarget, store tiles and wait for idle
- * before giving CPU access to the surface.
- * (set postStoreTileState to SWR_TILE_INVALID so tiles are reloaded)
- */
- if (resource->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL
- | PIPE_BIND_DISPLAY_TARGET)) {
- struct swr_context *ctx = swr_context(pipe);
- swr_draw_context *pDC = &ctx->swrDC;
- SWR_SURFACE_STATE *renderTargets = pDC->renderTargets;
- for (uint32_t i = 0; i < SWR_NUM_ATTACHMENTS; i++)
- if (renderTargets[i].pBaseAddress == spr->swr.pBaseAddress) {
- swr_store_render_target(ctx, i, SWR_TILE_INVALID);
- /*
- * Mesa thinks depth/stencil are fused, so we'll never get an
- * explicit map for stencil. So, if mapping depth, then also
- * store tile for stencil.
- */
- if (spr->has_stencil && (i == SWR_ATTACHMENT_DEPTH))
- swr_store_render_target(
- ctx, SWR_ATTACHMENT_STENCIL, SWR_TILE_INVALID);
- SwrWaitForIdle(ctx->swrContext);
- break;
+ /* If mapping an attached rendertarget, store tiles to surface and set
+ * postStoreTileState to SWR_TILE_INVALID so tiles get reloaded on next use
+ * and nothing needs to be done at unmap. */
+ swr_store_dirty_resource(pipe, resource, SWR_TILE_INVALID);
+
+ if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+ /* If resource is in use, finish fence before mapping.
+ * Unless requested not to block, then if not done return NULL map */
+ if (usage & PIPE_TRANSFER_DONTBLOCK) {
+ if (swr_is_fence_pending(screen->flush_fence))
+ return NULL;
+ } else {
+ if (spr->status) {
+ /* But, if there's no fence pending, submit one.
+ * XXX: Remove once draw timestamps are finished. */
+ if (!swr_is_fence_pending(screen->flush_fence))
+ swr_fence_submit(swr_context(pipe), screen->flush_fence);
+
+ swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+ swr_resource_unused(pipe, spr);
}
+ }
}
pt = CALLOC_STRUCT(pipe_transfer);
@@ -195,16 +169,7 @@ swr_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *transfer)
{
assert(transfer->resource);
- /*
- * XXX TODO: use fences and come up with a real resource manager.
- *
- * If this resource has been mapped/unmapped, it's probably in use. Tag it
- *with this context so
- * we'll know to check dependencies when it's deleted.
- */
struct swr_resource *res = swr_resource(transfer->resource);
- res->bound_to_context = (void *)pipe;
-
/* if we're mapping the depth/stencil, copy out stencil */
if (res->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT
&& res->has_stencil) {
@@ -234,6 +199,16 @@ swr_resource_copy(struct pipe_context *pipe,
unsigned src_level,
const struct pipe_box *src_box)
{
+ struct swr_screen *screen = swr_screen(pipe->screen);
+
+ /* If either the src or dst is a renderTarget, store tiles before copy */
+ swr_store_dirty_resource(pipe, src, SWR_TILE_RESOLVED);
+ swr_store_dirty_resource(pipe, dst, SWR_TILE_RESOLVED);
+
+ swr_fence_finish(pipe->screen, screen->flush_fence, 0);
+ swr_resource_unused(pipe, swr_resource(src));
+ swr_resource_unused(pipe, swr_resource(dst));
+
if ((dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER)
|| (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER)) {
util_resource_copy_region(
@@ -322,6 +297,8 @@ swr_destroy(struct pipe_context *pipe)
if (ctx->blitter)
util_blitter_destroy(ctx->blitter);
+ /* Idle core before deleting context */
+ SwrWaitForIdle(ctx->swrContext);
if (ctx->swrContext)
SwrDestroyContext(ctx->swrContext);
@@ -346,7 +323,6 @@ swr_render_condition(struct pipe_context *pipe,
ctx->render_cond_cond = condition;
}
-
struct pipe_context *
swr_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
{
@@ -392,9 +368,8 @@ swr_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
ctx->pipe.blit = swr_blit;
ctx->blitter = util_blitter_create(&ctx->pipe);
- if (!ctx->blitter) {
+ if (!ctx->blitter)
goto fail;
- }
swr_init_scratch_buffers(ctx);