diff --git a/docs/features.txt b/docs/features.txt index 97d7b6bf4fe..ce1a0438d4f 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -39,7 +39,7 @@ Feature Status GL 3.0, GLSL 1.30 --- all DONE: freedreno, i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, virgl, zink, d3d12, panfrost glBindFragDataLocation, glGetFragDataLocation DONE - GL_NV_conditional_render (Conditional rendering) DONE () + GL_NV_conditional_render (Conditional rendering) DONE (asahi) GL_ARB_map_buffer_range (Map buffer subranges) DONE (v3d, vc4, lima, asahi) GL_ARB_color_buffer_float (Clamping controls) DONE (v3d, vc4, lima, asahi) GL_ARB_texture_float (Float textures, renderbuffers) DONE (v3d, asahi) diff --git a/src/gallium/drivers/asahi/agx_blit.c b/src/gallium/drivers/asahi/agx_blit.c index 06abe4e2b20..ea27c81701d 100644 --- a/src/gallium/drivers/asahi/agx_blit.c +++ b/src/gallium/drivers/asahi/agx_blit.c @@ -68,12 +68,11 @@ agx_blitter_save(struct agx_context *ctx, struct blitter_context *blitter, void agx_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) { - // if (info->render_condition_enable && - // !agx_render_condition_check(pan_context(pipe))) - // return; - struct agx_context *ctx = agx_context(pipe); + if (info->render_condition_enable && !agx_render_condition_check(ctx)) + return; + if (!util_blitter_is_blit_supported(ctx->blitter, info)) { fprintf(stderr, "\n"); util_dump_blit_info(stderr, info); diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 7bf8d57acf1..d465979a3e1 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -870,6 +870,9 @@ agx_clear(struct pipe_context *pctx, unsigned buffers, struct agx_context *ctx = agx_context(pctx); struct agx_batch *batch = agx_get_batch(ctx); + if (unlikely(!agx_render_condition_check(ctx))) + return; + unsigned fastclear = buffers & ~(batch->draw | batch->load); unsigned slowclear = buffers & ~fastclear; @@ -1239,6 +1242,8 @@ agx_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: case PIPE_CAP_VS_INSTANCEID: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: + case PIPE_CAP_CONDITIONAL_RENDER: + case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: return 1; case PIPE_CAP_TEXTURE_MULTISAMPLE: diff --git a/src/gallium/drivers/asahi/agx_query.c b/src/gallium/drivers/asahi/agx_query.c index 71f5eac5b34..44df4d12406 100644 --- a/src/gallium/drivers/asahi/agx_query.c +++ b/src/gallium/drivers/asahi/agx_query.c @@ -176,6 +176,36 @@ agx_finish_batch_occlusion_queries(struct agx_batch *batch) } } +static void +agx_render_condition(struct pipe_context *pipe, struct pipe_query *query, + bool condition, enum pipe_render_cond_flag mode) +{ + struct agx_context *ctx = agx_context(pipe); + + ctx->cond_query = query; + ctx->cond_cond = condition; + ctx->cond_mode = mode; +} + +bool +agx_render_condition_check_inner(struct agx_context *ctx) +{ + assert(ctx->cond_query != NULL && "precondition"); + + perf_debug_ctx(ctx, "Implementing conditional rendering on the CPU"); + + union pipe_query_result res = {0}; + bool wait = ctx->cond_mode != PIPE_RENDER_COND_NO_WAIT && + ctx->cond_mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT; + + struct pipe_query *pq = (struct pipe_query *)ctx->cond_query; + + if (agx_get_query_result(&ctx->base, pq, wait, &res)) + return res.u64 != ctx->cond_cond; + + return true; +} + void agx_init_query_functions(struct pipe_context *pctx) { @@ -185,6 +215,7 @@ agx_init_query_functions(struct pipe_context *pctx) pctx->end_query = agx_end_query; pctx->get_query_result = agx_get_query_result; pctx->set_active_query_state = agx_set_active_query_state; + pctx->render_condition = agx_render_condition; /* By default queries are active */ agx_context(pctx)->active_queries = true; diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 0eefe1d046c..9526d395a94 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -2157,12 +2157,16 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count_bias *draws, unsigned num_draws) { + struct agx_context *ctx = agx_context(pctx); + + if (unlikely(!agx_render_condition_check(ctx))) + return; + if (num_draws > 1) { util_draw_multi(pctx, info, drawid_offset, indirect, draws, num_draws); return; } - struct agx_context *ctx = agx_context(pctx); struct agx_batch *batch = agx_get_batch(ctx); #ifndef NDEBUG diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index c98a7538abb..a0be811b4f9 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -505,4 +505,15 @@ uint16_t agx_get_oq_index(struct agx_batch *batch, struct agx_query *query); void agx_finish_batch_occlusion_queries(struct agx_batch *batch); +bool agx_render_condition_check_inner(struct agx_context *ctx); + +static inline bool +agx_render_condition_check(struct agx_context *ctx) +{ + if (likely(!ctx->cond_query)) + return true; + else + return agx_render_condition_check_inner(ctx); +} + #endif