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:

Reply via email to