[Mesa-dev] [PATCH] swr: Add missing break in query switch statement.
Missed a switch break in query stat collection when refactoring queries. --- src/gallium/drivers/swr/swr_query.cpp |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/src/gallium/drivers/swr/swr_query.cpp b/src/gallium/drivers/swr/swr_query.cpp index 5c59965..7867db3 100644 --- a/src/gallium/drivers/swr/swr_query.cpp +++ b/src/gallium/drivers/swr/swr_query.cpp @@ -152,6 +152,7 @@ swr_get_query_result(struct pipe_context *pipe, break; case PIPE_QUERY_PRIMITIVES_GENERATED: result->u64 = end->core.IaPrimitives - start->core.IaPrimitives; + break; case PIPE_QUERY_PRIMITIVES_EMITTED: result->u64 = end->core.SoNumPrimsWritten[index] - start->core.SoNumPrimsWritten[index]; -- 1.7.1 ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] swr: Remove stall waiting for core query counters.
When gathering query results, swr_gather_stats was unnecessarily stalling the entire pipeline. Results are now collected asynchronously, with a fence marking completion. --- src/gallium/drivers/swr/swr_fence.cpp |6 - src/gallium/drivers/swr/swr_fence.h |8 ++ src/gallium/drivers/swr/swr_query.cpp | 180 - src/gallium/drivers/swr/swr_query.h | 11 ++- 4 files changed, 81 insertions(+), 124 deletions(-) diff --git a/src/gallium/drivers/swr/swr_fence.cpp b/src/gallium/drivers/swr/swr_fence.cpp index 2e95b39..8a8e864 100644 --- a/src/gallium/drivers/swr/swr_fence.cpp +++ b/src/gallium/drivers/swr/swr_fence.cpp @@ -105,12 +105,6 @@ swr_fence_reference(struct pipe_screen *screen, swr_fence_destroy(old); } -static INLINE boolean -swr_is_fence_done(struct pipe_fence_handle *fence_handle) -{ - struct swr_fence *fence = swr_fence(fence_handle); - return (fence->read == fence->write); -} /* * Wait for the fence to finish. diff --git a/src/gallium/drivers/swr/swr_fence.h b/src/gallium/drivers/swr/swr_fence.h index df3776e..47f4d2e 100644 --- a/src/gallium/drivers/swr/swr_fence.h +++ b/src/gallium/drivers/swr/swr_fence.h @@ -45,6 +45,14 @@ swr_fence(struct pipe_fence_handle *fence) return (struct swr_fence *)fence; } + +static INLINE boolean +swr_is_fence_done(struct pipe_fence_handle *fence_handle) +{ + struct swr_fence *fence = swr_fence(fence_handle); + return (fence->read == fence->write); +} + static INLINE boolean swr_is_fence_pending(struct pipe_fence_handle *fence_handle) { diff --git a/src/gallium/drivers/swr/swr_query.cpp b/src/gallium/drivers/swr/swr_query.cpp index f038a6e..5c59965 100644 --- a/src/gallium/drivers/swr/swr_query.cpp +++ b/src/gallium/drivers/swr/swr_query.cpp @@ -62,10 +62,8 @@ swr_destroy_query(struct pipe_context *pipe, struct pipe_query *q) struct swr_query *pq = swr_query(q); if (pq->fence) { - if (!swr_is_fence_pending(pq->fence)) { - swr_fence_submit(swr_context(pipe), pq->fence); + if (swr_is_fence_pending(pq->fence)) swr_fence_finish(pipe->screen, pq->fence, 0); - } swr_fence_reference(pipe->screen, >fence, NULL); } @@ -73,100 +71,45 @@ swr_destroy_query(struct pipe_context *pipe, struct pipe_query *q) } -// XXX Create a fence callback, rather than stalling SwrWaitForIdle static void swr_gather_stats(struct pipe_context *pipe, struct swr_query *pq) { struct swr_context *ctx = swr_context(pipe); assert(pq->result); - union pipe_query_result *result = pq->result; + struct swr_query_result *result = pq->result; boolean enable_stats = pq->enable_stats; - SWR_STATS swr_stats = {0}; - - if (pq->fence) { - if (!swr_is_fence_pending(pq->fence)) { - swr_fence_submit(ctx, pq->fence); - swr_fence_finish(pipe->screen, pq->fence, 0); - } - swr_fence_reference(pipe->screen, >fence, NULL); - } - /* -* These queries don't need SWR Stats enabled in the core -* Set and return. -*/ + /* A few results don't require the core, so don't involve it */ switch (pq->type) { case PIPE_QUERY_TIMESTAMP: case PIPE_QUERY_TIME_ELAPSED: - result->u64 = swr_get_timestamp(pipe->screen); - return; + result->timestamp = swr_get_timestamp(pipe->screen); break; case PIPE_QUERY_TIMESTAMP_DISJOINT: - /* nothing to do here */ - return; - break; case PIPE_QUERY_GPU_FINISHED: - result->b = TRUE; /* XXX TODO Add an api func to SWR to compare drawId - vs LastRetiredId? */ - return; + /* nothing to do here */ break; default: - /* Any query that needs SwrCore stats */ - break; - } - - /* -* All other results are collected from SwrCore counters -*/ + /* + * All other results are collected from SwrCore counters via + * SwrGetStats. This returns immediately, but results are later filled + * in by the backend. Fence status is the only indication of + * completion. */ + SwrGetStats(ctx->swrContext, >core); + + if (!pq->fence) { + struct swr_screen *screen = swr_screen(pipe->screen); + swr_fence_reference(pipe->screen, >fence, screen->flush_fence); + } + swr_fence_submit(ctx, pq->fence); - /* XXX, Should turn this into a fence callback and skip the stall */ - SwrGetStats(ctx->swrContext, _stats); - /* SwrGetStats returns immediately, wait for collection */ - SwrWaitForIdle(ctx->swrContext); + /* Only change stat collection if there are no active queries */ + if (ctx->active_queries == 0) + SwrEnableStats(ctx->swrContext, enable_stats); - switch (pq->type) { - case PIPE_QUERY_OCCLUSION_PREDICATE: - case PIPE_QUERY_OCCLUSION_COUNTER: - result->u64 = swr_stats.DepthPassCount; - break; - case PIPE_QUERY_PRIMITIVES_GENERATED: - result->u64 = swr_stats.IaPrimitives; -
[Mesa-dev] [PATCH] gallium/swr: Resource management
From: Bruce CherniakBetter tracking of resource state and synchronization. A follow on commit will clean up resource functions into a new swr_resource.cpp file. --- src/gallium/drivers/swr/swr_clear.cpp |4 +- src/gallium/drivers/swr/swr_context.cpp | 103 --- src/gallium/drivers/swr/swr_draw.cpp| 64 +-- src/gallium/drivers/swr/swr_fence.cpp | 29 ++--- src/gallium/drivers/swr/swr_fence.h |6 +- src/gallium/drivers/swr/swr_query.cpp |6 +- src/gallium/drivers/swr/swr_resource.h | 54 +++- src/gallium/drivers/swr/swr_screen.cpp | 57 - src/gallium/drivers/swr/swr_state.cpp | 83 ++--- src/gallium/drivers/swr/swr_state.h |2 +- 10 files changed, 265 insertions(+), 143 deletions(-) diff --git a/src/gallium/drivers/swr/swr_clear.cpp b/src/gallium/drivers/swr/swr_clear.cpp index 9027f84..103bca9 100644 --- a/src/gallium/drivers/swr/swr_clear.cpp +++ b/src/gallium/drivers/swr/swr_clear.cpp @@ -40,7 +40,7 @@ swr_clear(struct pipe_context *pipe, return; if (ctx->dirty) - swr_update_derived(ctx); + swr_update_derived(pipe); /* Update clearMask/targetMask */ #if 0 /* XXX SWR currently only clears SWR_ATTACHMENT_COLOR0, don't bother \ @@ -76,7 +76,7 @@ swr_clear(struct pipe_context *pipe, vp.height = ctx->framebuffer.height; SwrSetViewports(ctx->swrContext, 1, , NULL); - swr_update_draw_context(ctx); + swr_update_draw_context(ctx); SwrClearRenderTarget(ctx->swrContext, clearMask, color->f, depth, stencil); } diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp index 0e7ebb7..c8cb145 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 = >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(>texture, NULL); + pipe_resource_reference(, 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 = >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