freedreno: use CXX linker rather than explicit link against libstdc++
[mesa.git] / src / gallium / drivers / freedreno / freedreno_draw.c
index 213bad84e84ad1e6109fcb28214d58c7e192bd11..c9e317c7dc949e96781986a59cecc7565e77575f 100644 (file)
 #include "freedreno_query_hw.h"
 #include "freedreno_util.h"
 
+static void
+resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
+{
+       struct fd_resource *rsc;
+
+       if (!prsc)
+               return;
+
+       rsc = fd_resource(prsc);
+       rsc->reading = true;
+       list_delinit(&rsc->list);
+       list_addtail(&rsc->list, &ctx->used_resources);
+}
 
 static void
 fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
@@ -75,8 +88,12 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        }
 
        if (fd_stencil_enabled(ctx)) {
+               struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
                buffers |= FD_BUFFER_STENCIL;
-               fd_resource(pfb->zsbuf->texture)->dirty = true;
+               if (rsc->stencil)
+                       rsc->stencil->dirty = true;
+               else
+                       rsc->dirty = true;
                ctx->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
        }
 
@@ -92,7 +109,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                surf = pfb->cbufs[i]->texture;
 
                fd_resource(surf)->dirty = true;
-               buffers |= FD_BUFFER_COLOR;
+               buffers |= PIPE_CLEAR_COLOR0 << i;
 
                if (surf->nr_samples > 1)
                        ctx->gmem_reason |= FD_GMEM_MSAA_ENABLED;
@@ -101,6 +118,29 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                        ctx->gmem_reason |= FD_GMEM_BLEND_ENABLED;
        }
 
+       /* 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);
+       }
+
+       /* 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);
+       }
+
+       /* Mark index buffer as being read */
+       resource_reading(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);
+       for (i = 0; i < ctx->fragtex.num_textures; i++)
+               if (ctx->fragtex.textures[i])
+                       resource_reading(ctx, ctx->fragtex.textures[i]->texture);
+
        ctx->num_draws++;
 
        ctx->stats.draw_calls++;
@@ -147,6 +187,7 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
        struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
        struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
        unsigned cleared_buffers;
+       int i;
 
        /* for bookkeeping about which buffers have been cleared (and thus
         * can fully or partially skip mem2gmem) we need to ignore buffers
@@ -173,10 +214,17 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
        ctx->needs_flush = true;
 
        if (buffers & PIPE_CLEAR_COLOR)
-               fd_resource(pfb->cbufs[0]->texture)->dirty = true;
+               for (i = 0; i < pfb->nr_cbufs; i++)
+                       if (buffers & (PIPE_CLEAR_COLOR0 << i))
+                               fd_resource(pfb->cbufs[i]->texture)->dirty = true;
 
        if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
-               fd_resource(pfb->zsbuf->texture)->dirty = true;
+               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;
+
                ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL;
        }
 
@@ -220,6 +268,8 @@ fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
 void
 fd_draw_init(struct pipe_context *pctx)
 {
+       list_inithead(&fd_context(pctx)->used_resources);
+
        pctx->draw_vbo = fd_draw_vbo;
        pctx->clear = fd_clear;
        pctx->clear_render_target = fd_clear_render_target;