From 2e117a7649c1972cf36ec874d852a3e85d4750fa Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 3 May 2016 18:36:52 -0400 Subject: [PATCH] freedreno: allow ctx->draw_vbo to fail 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 --- src/gallium/drivers/freedreno/a2xx/fd2_draw.c | 4 ++- src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 27 +++++++++-------- src/gallium/drivers/freedreno/a4xx/fd4_draw.c | 29 ++++++++++--------- .../drivers/freedreno/freedreno_context.h | 2 +- .../drivers/freedreno/freedreno_draw.c | 5 ++-- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c index f2efd5f2eb0..14620acbc85 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c @@ -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; } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index dc4558e9644..67239414393 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -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 diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c index af02d31fb91..b9bae8adc54 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c @@ -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 diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 80c638a7e38..5861fbe8b06 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -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); diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 66bb1163df2..34b1ff6010c 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -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; -- 2.30.2