freedreno: allow ctx->draw_vbo to fail
authorRob Clark <robclark@freedesktop.org>
Tue, 3 May 2016 22:36:52 +0000 (18:36 -0400)
committerRob Clark <robclark@freedesktop.org>
Wed, 4 May 2016 15:25:55 +0000 (11:25 -0400)
Pretty much only happens if shader variant compile fails.  But in this
case, if we haven't emitted cmdstream, we don't want to set needs_flush.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a2xx/fd2_draw.c
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_draw.c

index f2efd5f2eb0ad22a57d6ecab568569804ad8db9f..14620acbc85e65a9be1deada26d29428e0221d30 100644 (file)
@@ -79,7 +79,7 @@ emit_vertexbufs(struct fd_context *ctx)
        fd2_emit_vertex_bufs(ctx->ring, 0x78, bufs, vtx->num_elements);
 }
 
-static void
+static bool
 fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
 {
        struct fd_ringbuffer *ring = ctx->ring;
@@ -115,6 +115,8 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
        OUT_RING(ring, 0x00000000);
 
        emit_cacheflush(ring);
+
+       return true;
 }
 
 
index dc4558e964407287c2f7e4a5daa591dd7512a153..67239414393bb2f1c32b6651575074c1562e0c33 100644 (file)
@@ -60,9 +60,6 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
        const struct pipe_draw_info *info = emit->info;
        enum pc_di_primtype primtype = ctx->primtypes[info->mode];
 
-       if (!(fd3_emit_get_vp(emit) && fd3_emit_get_fp(emit)))
-               return;
-
        fd3_emit_state(ctx, ring, emit);
 
        if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
@@ -132,7 +129,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
        }
 }
 
-static void
+static bool
 fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
 {
        struct fd3_context *fd3_ctx = fd3_context(ctx);
@@ -142,8 +139,6 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                .prog = &ctx->prog,
                .info = info,
                .key = {
-                       /* do binning pass first: */
-                       .binning_pass = true,
                        .color_two_side = ctx->rasterizer->light_twoside,
                        .vclamp_color = ctx->rasterizer->clamp_vertex_color,
                        .fclamp_color = ctx->rasterizer->clamp_fragment_color,
@@ -162,20 +157,28 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable,
                .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode,
        };
-       unsigned dirty;
 
        fixup_shader_state(ctx, &emit.key);
 
-       dirty = ctx->dirty;
-       emit.dirty = dirty & ~(FD_DIRTY_BLEND);
-       draw_impl(ctx, ctx->binning_ring, &emit);
+       unsigned dirty = ctx->dirty;
+
+       /* do regular pass first, since that is more likely to fail compiling: */
+
+       if (!(fd3_emit_get_vp(&emit) && fd3_emit_get_fp(&emit)))
+               return false;
 
-       /* and now regular (non-binning) pass: */
        emit.key.binning_pass = false;
        emit.dirty = dirty;
+       draw_impl(ctx, ctx->ring, &emit);
+
+       /* and now binning pass: */
+       emit.key.binning_pass = true;
+       emit.dirty = dirty & ~(FD_DIRTY_BLEND);
        emit.vp = NULL;   /* we changed key so need to refetch vp */
        emit.fp = NULL;
-       draw_impl(ctx, ctx->ring, &emit);
+       draw_impl(ctx, ctx->binning_ring, &emit);
+
+       return true;
 }
 
 /* clear operations ignore viewport state, so we need to reset it
index af02d31fb913cbbb61b9d2eaf4bd49d42fe22dd7..b9bae8adc546d60ede9db0c1c21d34032c3f6818 100644 (file)
@@ -49,9 +49,6 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
        const struct pipe_draw_info *info = emit->info;
        enum pc_di_primtype primtype = ctx->primtypes[info->mode];
 
-       if (!(fd4_emit_get_vp(emit) && fd4_emit_get_fp(emit)))
-               return;
-
        fd4_emit_state(ctx, ring, emit);
 
        if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
@@ -121,7 +118,7 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
        }
 }
 
-static void
+static bool
 fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
 {
        struct fd4_context *fd4_ctx = fd4_context(ctx);
@@ -131,8 +128,6 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                .prog = &ctx->prog,
                .info = info,
                .key = {
-                       /* do binning pass first: */
-                       .binning_pass = true,
                        .color_two_side = ctx->rasterizer->light_twoside,
                        .vclamp_color = ctx->rasterizer->clamp_vertex_color,
                        .fclamp_color = ctx->rasterizer->clamp_fragment_color,
@@ -156,19 +151,18 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable,
                .sprite_coord_mode = ctx->rasterizer->sprite_coord_mode,
        };
-       unsigned dirty;
 
        fixup_shader_state(ctx, &emit.key);
 
-       dirty = ctx->dirty;
-       emit.dirty = dirty & ~(FD_DIRTY_BLEND);
-       draw_impl(ctx, ctx->binning_ring, &emit);
+       unsigned dirty = ctx->dirty;
+
+       /* do regular pass first, since that is more likely to fail compiling: */
+
+       if (!(fd4_emit_get_vp(&emit) && fd4_emit_get_fp(&emit)))
+               return false;
 
-       /* and now regular (non-binning) pass: */
        emit.key.binning_pass = false;
        emit.dirty = dirty;
-       emit.vp = NULL;   /* we changed key so need to refetch vp */
-       emit.fp = NULL;
 
        if (ctx->rasterizer->rasterizer_discard) {
                fd_wfi(ctx, ctx->ring);
@@ -187,6 +181,15 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
                OUT_RING(ctx->ring, ~A4XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE);
                OUT_RING(ctx->ring, 0);
        }
+
+       /* and now binning pass: */
+       emit.key.binning_pass = true;
+       emit.dirty = dirty & ~(FD_DIRTY_BLEND);
+       emit.vp = NULL;   /* we changed key so need to refetch vp */
+       emit.fp = NULL;
+       draw_impl(ctx, ctx->binning_ring, &emit);
+
+       return true;
 }
 
 /* clear operations ignore viewport state, so we need to reset it
index 80c638a7e38e6258650a777f1ca1e7995ce0997c..5861fbe8b06991f741f3175804fb72dbd676da5d 100644 (file)
@@ -385,7 +385,7 @@ struct fd_context {
        void (*emit_sysmem_prep)(struct fd_context *ctx);
 
        /* draw: */
-       void (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info);
+       bool (*draw_vbo)(struct fd_context *ctx, const struct pipe_draw_info *info);
        void (*clear)(struct fd_context *ctx, unsigned buffers,
                        const union pipe_color_union *color, double depth, unsigned stencil);
 
index 66bb1163df234cfc4c5049a4cb6c891aa3242640..34b1ff6010c97df047d86be9a5fbac5856fee877 100644 (file)
@@ -102,8 +102,6 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                return;
        }
 
-       ctx->needs_flush = true;
-
        /*
         * Figure out the buffers/features we need:
         */
@@ -195,7 +193,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                util_format_short_name(pipe_surface_format(pfb->zsbuf)));
 
        fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_DRAW);
-       ctx->draw_vbo(ctx, info);
+       if (ctx->draw_vbo(ctx, info))
+               ctx->needs_flush = true;
 
        for (i = 0; i < ctx->streamout.num_targets; i++)
                ctx->streamout.offsets[i] += info->count;