mirror of https://gitlab.freedesktop.org/mesa/mesa
etnaviv: Add support for conditional rendering
The hardware doesn't support native conditional rendering, so it is implemented by software. Code borrowed from Freedreno and Panfrost. Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23392>
This commit is contained in:
parent
a603413eb8
commit
62e0f6bf32
|
@ -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, asahi
|
||||
|
||||
glBindFragDataLocation, glGetFragDataLocation DONE
|
||||
GL_NV_conditional_render (Conditional rendering) DONE (v3d)
|
||||
GL_NV_conditional_render (Conditional rendering) DONE (v3d, etnaviv/HALTI0)
|
||||
GL_ARB_map_buffer_range (Map buffer subranges) DONE (v3d, vc4, lima)
|
||||
GL_ARB_color_buffer_float (Clamping controls) DONE (v3d, vc4, lima)
|
||||
GL_ARB_texture_float (Float textures, renderbuffers) DONE (v3d)
|
||||
|
|
|
@ -360,6 +360,9 @@ etna_clear_blt(struct pipe_context *pctx, unsigned buffers, const struct pipe_sc
|
|||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (!etna_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, 0x00000c23);
|
||||
etna_set_state(ctx->stream, VIVS_TS_FLUSH_CACHE, VIVS_TS_FLUSH_CACHE_FLUSH);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
/* Save current state for blitter operation */
|
||||
void
|
||||
etna_blit_save_state(struct etna_context *ctx)
|
||||
etna_blit_save_state(struct etna_context *ctx, bool render_cond)
|
||||
{
|
||||
util_blitter_save_fragment_constant_buffer_slot(ctx->blitter,
|
||||
ctx->constant_buffer[PIPE_SHADER_FRAGMENT].cb);
|
||||
|
@ -68,6 +68,10 @@ etna_blit_save_state(struct etna_context *ctx)
|
|||
util_blitter_save_fragment_sampler_views(ctx->blitter,
|
||||
ctx->num_fragment_sampler_views, ctx->sampler_view);
|
||||
|
||||
if (!render_cond)
|
||||
util_blitter_save_render_condition(ctx->blitter,
|
||||
ctx->cond_query, ctx->cond_cond, ctx->cond_mode);
|
||||
|
||||
if (DBG_ENABLED(ETNA_DBG_DEQP))
|
||||
util_blitter_save_so_targets(ctx->blitter, 0, NULL);
|
||||
}
|
||||
|
@ -100,6 +104,8 @@ etna_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
|||
struct etna_context *ctx = etna_context(pctx);
|
||||
struct pipe_blit_info info = *blit_info;
|
||||
|
||||
if (info.render_condition_enable && !etna_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
if (ctx->blit(pctx, &info))
|
||||
goto success;
|
||||
|
@ -119,7 +125,7 @@ etna_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
|||
return;
|
||||
}
|
||||
|
||||
etna_blit_save_state(ctx);
|
||||
etna_blit_save_state(ctx, info.render_condition_enable);
|
||||
util_blitter_blit(ctx->blitter, &info);
|
||||
|
||||
success:
|
||||
|
@ -137,7 +143,7 @@ etna_clear_render_target(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
|
||||
/* XXX could fall back to RS when target area is full screen / resolveable
|
||||
* and no TS. */
|
||||
etna_blit_save_state(ctx);
|
||||
etna_blit_save_state(ctx, false);
|
||||
util_blitter_clear_render_target(ctx->blitter, dst, color, dstx, dsty, width, height);
|
||||
}
|
||||
|
||||
|
@ -151,7 +157,7 @@ etna_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *dst,
|
|||
|
||||
/* XXX could fall back to RS when target area is full screen / resolveable
|
||||
* and no TS. */
|
||||
etna_blit_save_state(ctx);
|
||||
etna_blit_save_state(ctx, false);
|
||||
util_blitter_clear_depth_stencil(ctx->blitter, dst, clear_flags, depth,
|
||||
stencil, dstx, dsty, width, height);
|
||||
}
|
||||
|
@ -166,7 +172,7 @@ etna_resource_copy_region(struct pipe_context *pctx, struct pipe_resource *dst,
|
|||
|
||||
if (src->target != PIPE_BUFFER && dst->target != PIPE_BUFFER &&
|
||||
util_blitter_is_copy_supported(ctx->blitter, dst, src)) {
|
||||
etna_blit_save_state(ctx);
|
||||
etna_blit_save_state(ctx, false);
|
||||
util_blitter_copy_texture(ctx->blitter, dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
} else {
|
||||
|
|
|
@ -48,7 +48,7 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst,
|
|||
struct pipe_box *box);
|
||||
|
||||
void
|
||||
etna_blit_save_state(struct etna_context *ctx);
|
||||
etna_blit_save_state(struct etna_context *ctx, bool render_cond);
|
||||
|
||||
uint64_t
|
||||
etna_clear_blit_pack_rgba(enum pipe_format format, const union pipe_color_union *color);
|
||||
|
|
|
@ -248,6 +248,9 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
|||
u_decomposed_prim(info->mode) == MESA_PRIM_TRIANGLES))
|
||||
return;
|
||||
|
||||
if (!etna_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
int prims = u_decomposed_prims_for_vertices(info->mode, draws[0].count);
|
||||
if (unlikely(prims <= 0)) {
|
||||
DBG("Invalid draw primitive mode=%i or no primitives to be drawn", info->mode);
|
||||
|
@ -664,3 +667,22 @@ fail:
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
etna_render_condition_check(struct pipe_context *pctx)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (!ctx->cond_query)
|
||||
return true;
|
||||
|
||||
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;
|
||||
|
||||
if (pctx->get_query_result(pctx, ctx->cond_query, wait, &res))
|
||||
return (bool)res.u64 != ctx->cond_cond;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -199,6 +199,11 @@ struct etna_context {
|
|||
struct set *flush_resources;
|
||||
|
||||
bool is_noop;
|
||||
|
||||
/* conditional rendering */
|
||||
struct pipe_query *cond_query;
|
||||
bool cond_cond; /* inverted rendering condition */
|
||||
uint cond_mode;
|
||||
};
|
||||
|
||||
static inline struct etna_context *
|
||||
|
@ -224,4 +229,7 @@ void
|
|||
etna_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
|
||||
enum pipe_flush_flags flags, bool internal);
|
||||
|
||||
bool
|
||||
etna_render_condition_check(struct pipe_context *pctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -119,6 +119,17 @@ etna_get_driver_query_group_info(struct pipe_screen *pscreen, unsigned index,
|
|||
return etna_pm_get_driver_query_group_info(pscreen, index, info);
|
||||
}
|
||||
|
||||
static void
|
||||
etna_render_condition(struct pipe_context *pctx, struct pipe_query *pq,
|
||||
bool condition, enum pipe_render_cond_flag mode)
|
||||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
ctx->cond_query = pq;
|
||||
ctx->cond_cond = condition;
|
||||
ctx->cond_mode = mode;
|
||||
}
|
||||
|
||||
static void
|
||||
etna_set_active_query_state(struct pipe_context *pctx, bool enable)
|
||||
{
|
||||
|
@ -149,4 +160,5 @@ etna_query_context_init(struct pipe_context *pctx)
|
|||
pctx->end_query = etna_end_query;
|
||||
pctx->get_query_result = etna_get_query_result;
|
||||
pctx->set_active_query_state = etna_set_active_query_state;
|
||||
pctx->render_condition = etna_render_condition;
|
||||
}
|
||||
|
|
|
@ -431,6 +431,9 @@ etna_clear_rs(struct pipe_context *pctx, unsigned buffers, const struct pipe_sci
|
|||
{
|
||||
struct etna_context *ctx = etna_context(pctx);
|
||||
|
||||
if (!etna_render_condition_check(pctx))
|
||||
return;
|
||||
|
||||
/* Flush color and depth cache before clearing anything.
|
||||
* This is especially important when coming from another surface, as
|
||||
* otherwise it may clear part of the old surface instead. */
|
||||
|
|
|
@ -241,6 +241,8 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||
|
||||
/* Queries. */
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
case PIPE_CAP_CONDITIONAL_RENDER:
|
||||
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
||||
return VIV_FEATURE(screen, chipMinorFeatures1, HALTI0);
|
||||
|
||||
/* Preferences */
|
||||
|
|
Loading…
Reference in New Issue