Module: Mesa Branch: main Commit: 28386d0db552d3e71b096068b4cd050123c623fc URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=28386d0db552d3e71b096068b4cd050123c623fc
Author: Mike Blumenkrantz <[email protected]> Date: Thu Sep 9 14:02:16 2021 -0400 zink: unconditionally support conditional rendering this lets drivers that don't support the vk ext provide support Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12801> --- src/gallium/drivers/zink/zink_blit.c | 5 +++++ src/gallium/drivers/zink/zink_clear.c | 3 +++ src/gallium/drivers/zink/zink_draw.cpp | 33 +++++++++++++++++++++++++++++++++ src/gallium/drivers/zink/zink_query.c | 18 ++++++++++++++++++ src/gallium/drivers/zink/zink_query.h | 5 +++++ src/gallium/drivers/zink/zink_screen.c | 2 +- 6 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/zink/zink_blit.c b/src/gallium/drivers/zink/zink_blit.c index 56a55b22d39..7085c8e033c 100644 --- a/src/gallium/drivers/zink/zink_blit.c +++ b/src/gallium/drivers/zink/zink_blit.c @@ -253,6 +253,11 @@ zink_blit(struct pipe_context *pctx, struct zink_context *ctx = zink_context(pctx); const struct util_format_description *src_desc = util_format_description(info->src.format); const struct util_format_description *dst_desc = util_format_description(info->dst.format); + + if (info->render_condition_enable && + unlikely(!zink_screen(pctx->screen)->info.have_EXT_conditional_rendering && !zink_check_conditional_render(ctx))) + return; + if (src_desc == dst_desc || src_desc->nr_channels != 4 || src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || (src_desc->nr_channels == 4 && src_desc->channel[3].type != UTIL_FORMAT_TYPE_VOID)) { diff --git a/src/gallium/drivers/zink/zink_clear.c b/src/gallium/drivers/zink/zink_clear.c index ae2c1278df4..660203f7f07 100644 --- a/src/gallium/drivers/zink/zink_clear.c +++ b/src/gallium/drivers/zink/zink_clear.c @@ -200,6 +200,9 @@ zink_clear(struct pipe_context *pctx, struct zink_batch *batch = &ctx->batch; bool needs_rp = false; + if (unlikely(!zink_screen(pctx->screen)->info.have_EXT_conditional_rendering && !zink_check_conditional_render(ctx))) + return; + if (scissor_state) { struct u_rect scissor = {scissor_state->minx, scissor_state->maxx, scissor_state->miny, scissor_state->maxy}; needs_rp = !zink_blit_region_fills(scissor, fb->width, fb->height); diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 6f487486ee9..545eaf5ef59 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -423,6 +423,34 @@ update_gfx_pipeline(struct zink_context *ctx, struct zink_batch_state *bs, enum return pipeline_changed; } +static bool +hack_conditional_render(struct pipe_context *pctx, + const struct pipe_draw_info *dinfo, + unsigned drawid_offset, + const struct pipe_draw_indirect_info *dindirect, + const struct pipe_draw_start_count_bias *draws, + unsigned num_draws) +{ + struct zink_context *ctx = zink_context(pctx); + struct zink_batch_state *bs = ctx->batch.state; + static bool warned; + if (!warned) { + fprintf(stderr, "ZINK: warning, this is cpu-based conditional rendering, say bye-bye to fps\n"); + warned = true; + } + if (!zink_check_conditional_render(ctx)) + return false; + if (bs != ctx->batch.state) { + bool prev = ctx->render_condition_active; + ctx->render_condition_active = false; + zink_select_draw_vbo(ctx); + pctx->draw_vbo(pctx, dinfo, drawid_offset, dindirect, draws, num_draws); + ctx->render_condition_active = prev; + return false; + } + return true; +} + template <zink_multidraw HAS_MULTIDRAW, zink_dynamic_state HAS_DYNAMIC_STATE, zink_dynamic_state2 HAS_DYNAMIC_STATE2, zink_dynamic_vertex_input HAS_VERTEX_INPUT, bool BATCH_CHANGED> void @@ -450,6 +478,11 @@ zink_draw_vbo(struct pipe_context *pctx, unsigned work_count = ctx->batch.work_count; enum pipe_prim_type mode = (enum pipe_prim_type)dinfo->mode; + if (unlikely(!screen->info.have_EXT_conditional_rendering)) { + if (!hack_conditional_render(pctx, dinfo, drawid_offset, dindirect, draws, num_draws)) + return; + } + zink_flush_memory_barrier(ctx, false); update_barriers(ctx, false); diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c index 87f79e31b37..8b8d1cc44c3 100644 --- a/src/gallium/drivers/zink/zink_query.c +++ b/src/gallium/drivers/zink/zink_query.c @@ -892,6 +892,8 @@ zink_set_active_query_state(struct pipe_context *pctx, bool enable) void zink_start_conditional_render(struct zink_context *ctx) { + if (unlikely(!zink_screen(ctx->base.screen)->info.have_EXT_conditional_rendering)) + return; struct zink_batch *batch = &ctx->batch; VkConditionalRenderingFlagsEXT begin_flags = 0; if (ctx->render_condition.inverted) @@ -909,9 +911,25 @@ zink_stop_conditional_render(struct zink_context *ctx) { struct zink_batch *batch = &ctx->batch; zink_clear_apply_conditionals(ctx); + if (unlikely(!zink_screen(ctx->base.screen)->info.have_EXT_conditional_rendering)) + return; VKCTX(CmdEndConditionalRenderingEXT)(batch->state->cmdbuf); } +bool +zink_check_conditional_render(struct zink_context *ctx) +{ + if (!ctx->render_condition_active) + return true; + assert(ctx->render_condition.query); + + union pipe_query_result result; + zink_get_query_result(&ctx->base, (struct pipe_query*)ctx->render_condition.query, true, &result); + return is_bool_query(ctx->render_condition.query) ? + ctx->render_condition.inverted != result.b : + ctx->render_condition.inverted != !!result.u64; +} + static void zink_render_condition(struct pipe_context *pctx, struct pipe_query *pquery, diff --git a/src/gallium/drivers/zink/zink_query.h b/src/gallium/drivers/zink/zink_query.h index e6fb7b894c2..73fd31eeda7 100644 --- a/src/gallium/drivers/zink/zink_query.h +++ b/src/gallium/drivers/zink/zink_query.h @@ -24,6 +24,8 @@ #ifndef ZINK_QUERY_H #define ZINK_QUERY_H +#include <stdbool.h> + struct zink_batch; struct zink_batch_state; struct zink_context; @@ -51,6 +53,9 @@ zink_start_conditional_render(struct zink_context *ctx); void zink_stop_conditional_render(struct zink_context *ctx); + +bool +zink_check_conditional_render(struct zink_context *ctx); #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 4a1a219f2f9..3d674510c47 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -489,7 +489,7 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_CONDITIONAL_RENDER: - return screen->info.have_EXT_conditional_rendering; + return 1; case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY: case PIPE_CAP_GLSL_FEATURE_LEVEL:
