#include "freedreno_util.h"
static void
-resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
+resource_used(struct fd_context *ctx, struct pipe_resource *prsc,
+ enum fd_resource_status status)
{
struct fd_resource *rsc;
return;
rsc = fd_resource(prsc);
- rsc->reading = true;
+ rsc->status |= status;
+ if (rsc->stencil)
+ rsc->stencil->status |= status;
+
+ /* TODO resources can actually be shared across contexts,
+ * so I'm not sure a single list-head will do the trick?
+ */
+ debug_assert((rsc->pending_ctx == ctx) || !rsc->pending_ctx);
list_delinit(&rsc->list);
list_addtail(&rsc->list, &ctx->used_resources);
+ rsc->pending_ctx = ctx;
+}
+
+static void
+resource_read(struct fd_context *ctx, struct pipe_resource *prsc)
+{
+ resource_used(ctx, prsc, FD_PENDING_READ);
+}
+
+static void
+resource_written(struct fd_context *ctx, struct pipe_resource *prsc)
+{
+ resource_used(ctx, prsc, FD_PENDING_WRITE);
}
static void
struct fd_context *ctx = fd_context(pctx);
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
- unsigned i, buffers = 0;
+ unsigned i, prims, buffers = 0;
/* if we supported transform feedback, we'd have to disable this: */
if (((scissor->maxx - scissor->minx) *
return;
}
+ /* TODO: push down the region versions into the tiles */
+ if (!fd_render_condition_check(pctx))
+ return;
+
/* emulate unsupported primitives: */
if (!fd_supported_prim(ctx, info->mode)) {
+ if (ctx->streamout.num_targets > 0)
+ debug_error("stream-out with emulated prims");
util_primconvert_save_index_buffer(ctx->primconvert, &ctx->indexbuf);
util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
util_primconvert_draw_vbo(ctx->primconvert, info);
if (fd_depth_enabled(ctx)) {
buffers |= FD_BUFFER_DEPTH;
- fd_resource(pfb->zsbuf->texture)->dirty = true;
+ resource_written(ctx, pfb->zsbuf->texture);
ctx->gmem_reason |= FD_GMEM_DEPTH_ENABLED;
}
if (fd_stencil_enabled(ctx)) {
- struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
buffers |= FD_BUFFER_STENCIL;
- if (rsc->stencil)
- rsc->stencil->dirty = true;
- else
- rsc->dirty = true;
+ resource_written(ctx, pfb->zsbuf->texture);
ctx->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
}
surf = pfb->cbufs[i]->texture;
- fd_resource(surf)->dirty = true;
+ resource_written(ctx, surf);
buffers |= PIPE_CLEAR_COLOR0 << i;
if (surf->nr_samples > 1)
/* Skip over buffer 0, that is sent along with the command stream */
for (i = 1; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
- resource_reading(ctx, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
- resource_reading(ctx, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
+ resource_read(ctx, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
+ resource_read(ctx, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
}
/* Mark VBOs as being read */
for (i = 0; i < ctx->vtx.vertexbuf.count; i++) {
assert(!ctx->vtx.vertexbuf.vb[i].user_buffer);
- resource_reading(ctx, ctx->vtx.vertexbuf.vb[i].buffer);
+ resource_read(ctx, ctx->vtx.vertexbuf.vb[i].buffer);
}
/* Mark index buffer as being read */
- resource_reading(ctx, ctx->indexbuf.buffer);
+ resource_read(ctx, ctx->indexbuf.buffer);
/* Mark textures as being read */
for (i = 0; i < ctx->verttex.num_textures; i++)
if (ctx->verttex.textures[i])
- resource_reading(ctx, ctx->verttex.textures[i]->texture);
+ resource_read(ctx, ctx->verttex.textures[i]->texture);
for (i = 0; i < ctx->fragtex.num_textures; i++)
if (ctx->fragtex.textures[i])
- resource_reading(ctx, ctx->fragtex.textures[i]->texture);
+ resource_read(ctx, ctx->fragtex.textures[i]->texture);
+
+ /* Mark streamout buffers as being written.. */
+ for (i = 0; i < ctx->streamout.num_targets; i++)
+ if (ctx->streamout.targets[i])
+ resource_written(ctx, ctx->streamout.targets[i]->buffer);
ctx->num_draws++;
+ prims = u_reduced_prims_for_vertices(info->mode, info->count);
+
ctx->stats.draw_calls++;
- ctx->stats.prims_emitted +=
- u_reduced_prims_for_vertices(info->mode, info->count);
+ ctx->stats.prims_emitted += prims;
/* any buffers that haven't been cleared yet, we need to restore: */
ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared);
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_DRAW);
ctx->draw_vbo(ctx, info);
+ for (i = 0; i < ctx->streamout.num_targets; i++)
+ ctx->streamout.offsets[i] += prims;
+
+ if (fd_mesa_debug & FD_DBG_DDRAW)
+ ctx->dirty = 0xffffffff;
+
/* if an app (or, well, piglit test) does many thousands of draws
* without flush (or anything which implicitly flushes, like
* changing render targets), we can exceed the ringbuffer size.
unsigned cleared_buffers;
int i;
+ /* TODO: push down the region versions into the tiles */
+ if (!fd_render_condition_check(pctx))
+ return;
+
/* for bookkeeping about which buffers have been cleared (and thus
* can fully or partially skip mem2gmem) we need to ignore buffers
* that have already had a draw, in case apps do silly things like
if (buffers & PIPE_CLEAR_COLOR)
for (i = 0; i < pfb->nr_cbufs; i++)
if (buffers & (PIPE_CLEAR_COLOR0 << i))
- fd_resource(pfb->cbufs[i]->texture)->dirty = true;
+ resource_written(ctx, pfb->cbufs[i]->texture);
if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
- struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
- if (rsc->stencil && buffers & PIPE_CLEAR_STENCIL)
- rsc->stencil->dirty = true;
- if (!rsc->stencil || buffers & PIPE_CLEAR_DEPTH)
- rsc->dirty = true;
-
+ resource_written(ctx, pfb->zsbuf->texture);
ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL;
}
FD_DIRTY_SAMPLE_MASK |
FD_DIRTY_PROG |
FD_DIRTY_CONSTBUF |
- FD_DIRTY_BLEND;
+ FD_DIRTY_BLEND |
+ FD_DIRTY_FRAMEBUFFER;
if (fd_mesa_debug & FD_DBG_DCLEAR)
ctx->dirty = 0xffffffff;