freedreno: add support for conditional rendering, required for GL3.0
A smarter implementation would make it possible to attach this to emit state for the BY_REGION versions to avoid breaking the tiling. But this is a start. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Signed-off-by: Rob Clark <robclark@freedesktop.org>
This commit is contained in:
parent
059da344ec
commit
d69e557f2a
|
@ -61,6 +61,7 @@ Note: some of the new features are only available with certain drivers.
|
||||||
<li>GL_EXT_buffer_storage implemented for when ES 3.1 support is gained</li>
|
<li>GL_EXT_buffer_storage implemented for when ES 3.1 support is gained</li>
|
||||||
<li>GL_EXT_draw_elements_base_vertex on all drivers</li>
|
<li>GL_EXT_draw_elements_base_vertex on all drivers</li>
|
||||||
<li>GL_EXT_texture_compression_rgtc / latc on freedreno (a3xx)</li>
|
<li>GL_EXT_texture_compression_rgtc / latc on freedreno (a3xx)</li>
|
||||||
|
<li>GL_NV_conditional_render on freedreno</li>
|
||||||
<li>GL_OES_draw_elements_base_vertex on all drivers</li>
|
<li>GL_OES_draw_elements_base_vertex on all drivers</li>
|
||||||
<li>EGL_KHR_create_context on softpipe, llvmpipe</li>
|
<li>EGL_KHR_create_context on softpipe, llvmpipe</li>
|
||||||
<li>EGL_KHR_gl_colorspace on softpipe, llvmpipe</li>
|
<li>EGL_KHR_gl_colorspace on softpipe, llvmpipe</li>
|
||||||
|
|
|
@ -359,6 +359,10 @@ struct fd_context {
|
||||||
struct fd_streamout_stateobj streamout;
|
struct fd_streamout_stateobj streamout;
|
||||||
struct pipe_clip_state ucp;
|
struct pipe_clip_state ucp;
|
||||||
|
|
||||||
|
struct pipe_query *cond_query;
|
||||||
|
bool cond_cond; /* inverted rendering condition */
|
||||||
|
uint cond_mode;
|
||||||
|
|
||||||
/* GMEM/tile handling fxns: */
|
/* GMEM/tile handling fxns: */
|
||||||
void (*emit_tile_init)(struct fd_context *ctx);
|
void (*emit_tile_init)(struct fd_context *ctx);
|
||||||
void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);
|
void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);
|
||||||
|
|
|
@ -88,6 +88,10 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: push down the region versions into the tiles */
|
||||||
|
if (!fd_render_condition_check(pctx))
|
||||||
|
return;
|
||||||
|
|
||||||
/* emulate unsupported primitives: */
|
/* emulate unsupported primitives: */
|
||||||
if (!fd_supported_prim(ctx, info->mode)) {
|
if (!fd_supported_prim(ctx, info->mode)) {
|
||||||
if (ctx->streamout.num_targets > 0)
|
if (ctx->streamout.num_targets > 0)
|
||||||
|
@ -220,6 +224,10 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
||||||
unsigned cleared_buffers;
|
unsigned cleared_buffers;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* TODO: push down the region versions into the tiles */
|
||||||
|
if (!fd_render_condition_check(pctx))
|
||||||
|
return;
|
||||||
|
|
||||||
/* for bookkeeping about which buffers have been cleared (and thus
|
/* for bookkeeping about which buffers have been cleared (and thus
|
||||||
* can fully or partially skip mem2gmem) we need to ignore buffers
|
* can fully or partially skip mem2gmem) we need to ignore buffers
|
||||||
* that have already had a draw, in case apps do silly things like
|
* that have already had a draw, in case apps do silly things like
|
||||||
|
|
|
@ -81,6 +81,16 @@ fd_get_query_result(struct pipe_context *pctx, struct pipe_query *pq,
|
||||||
return q->funcs->get_query_result(fd_context(pctx), q, wait, result);
|
return q->funcs->get_query_result(fd_context(pctx), q, wait, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fd_render_condition(struct pipe_context *pctx, struct pipe_query *pq,
|
||||||
|
boolean condition, uint mode)
|
||||||
|
{
|
||||||
|
struct fd_context *ctx = fd_context(pctx);
|
||||||
|
ctx->cond_query = pq;
|
||||||
|
ctx->cond_cond = condition;
|
||||||
|
ctx->cond_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fd_get_driver_query_info(struct pipe_screen *pscreen,
|
fd_get_driver_query_info(struct pipe_screen *pscreen,
|
||||||
unsigned index, struct pipe_driver_query_info *info)
|
unsigned index, struct pipe_driver_query_info *info)
|
||||||
|
@ -118,4 +128,5 @@ fd_query_context_init(struct pipe_context *pctx)
|
||||||
pctx->begin_query = fd_begin_query;
|
pctx->begin_query = fd_begin_query;
|
||||||
pctx->end_query = fd_end_query;
|
pctx->end_query = fd_end_query;
|
||||||
pctx->get_query_result = fd_get_query_result;
|
pctx->get_query_result = fd_get_query_result;
|
||||||
|
pctx->render_condition = fd_render_condition;
|
||||||
}
|
}
|
||||||
|
|
|
@ -671,7 +671,7 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fd_blitter_pipe_begin(struct fd_context *ctx);
|
static void fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond);
|
||||||
static void fd_blitter_pipe_end(struct fd_context *ctx);
|
static void fd_blitter_pipe_end(struct fd_context *ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -693,7 +693,7 @@ fd_blitter_pipe_copy_region(struct fd_context *ctx,
|
||||||
if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
|
if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fd_blitter_pipe_begin(ctx);
|
fd_blitter_pipe_begin(ctx, false);
|
||||||
util_blitter_copy_texture(ctx->blitter,
|
util_blitter_copy_texture(ctx->blitter,
|
||||||
dst, dst_level, dstx, dsty, dstz,
|
dst, dst_level, dstx, dsty, dstz,
|
||||||
src, src_level, src_box);
|
src, src_level, src_box);
|
||||||
|
@ -735,6 +735,25 @@ fd_resource_copy_region(struct pipe_context *pctx,
|
||||||
src, src_level, src_box);
|
src, src_level, src_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fd_render_condition_check(struct pipe_context *pctx)
|
||||||
|
{
|
||||||
|
struct fd_context *ctx = fd_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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optimal hardware path for blitting pixels.
|
* Optimal hardware path for blitting pixels.
|
||||||
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
|
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
|
||||||
|
@ -753,6 +772,9 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.render_condition_enable && !fd_render_condition_check(pctx))
|
||||||
|
return;
|
||||||
|
|
||||||
if (util_try_blit_via_copy_region(pctx, &info)) {
|
if (util_try_blit_via_copy_region(pctx, &info)) {
|
||||||
return; /* done */
|
return; /* done */
|
||||||
}
|
}
|
||||||
|
@ -769,13 +791,13 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_blitter_pipe_begin(ctx);
|
fd_blitter_pipe_begin(ctx, info.render_condition_enable);
|
||||||
util_blitter_blit(ctx->blitter, &info);
|
util_blitter_blit(ctx->blitter, &info);
|
||||||
fd_blitter_pipe_end(ctx);
|
fd_blitter_pipe_end(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fd_blitter_pipe_begin(struct fd_context *ctx)
|
fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond)
|
||||||
{
|
{
|
||||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
||||||
util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
|
util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
|
||||||
|
@ -796,6 +818,9 @@ fd_blitter_pipe_begin(struct fd_context *ctx)
|
||||||
(void **)ctx->fragtex.samplers);
|
(void **)ctx->fragtex.samplers);
|
||||||
util_blitter_save_fragment_sampler_views(ctx->blitter,
|
util_blitter_save_fragment_sampler_views(ctx->blitter,
|
||||||
ctx->fragtex.num_textures, ctx->fragtex.textures);
|
ctx->fragtex.num_textures, ctx->fragtex.textures);
|
||||||
|
if (!render_cond)
|
||||||
|
util_blitter_save_render_condition(ctx->blitter,
|
||||||
|
ctx->cond_query, ctx->cond_cond, ctx->cond_mode);
|
||||||
|
|
||||||
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_BLIT);
|
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_BLIT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,4 +135,6 @@ fd_resource_offset(struct fd_resource *rsc, unsigned level, unsigned layer)
|
||||||
void fd_resource_screen_init(struct pipe_screen *pscreen);
|
void fd_resource_screen_init(struct pipe_screen *pscreen);
|
||||||
void fd_resource_context_init(struct pipe_context *pctx);
|
void fd_resource_context_init(struct pipe_context *pctx);
|
||||||
|
|
||||||
|
bool fd_render_condition_check(struct pipe_context *pctx);
|
||||||
|
|
||||||
#endif /* FREEDRENO_RESOURCE_H_ */
|
#endif /* FREEDRENO_RESOURCE_H_ */
|
||||||
|
|
|
@ -160,7 +160,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||||
case PIPE_CAP_SHADER_STENCIL_EXPORT:
|
case PIPE_CAP_SHADER_STENCIL_EXPORT:
|
||||||
case PIPE_CAP_TGSI_TEXCOORD:
|
case PIPE_CAP_TGSI_TEXCOORD:
|
||||||
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
||||||
case PIPE_CAP_CONDITIONAL_RENDER:
|
|
||||||
case PIPE_CAP_TEXTURE_MULTISAMPLE:
|
case PIPE_CAP_TEXTURE_MULTISAMPLE:
|
||||||
case PIPE_CAP_TEXTURE_BARRIER:
|
case PIPE_CAP_TEXTURE_BARRIER:
|
||||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
||||||
|
@ -176,6 +175,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||||
case PIPE_CAP_INDEP_BLEND_FUNC:
|
case PIPE_CAP_INDEP_BLEND_FUNC:
|
||||||
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
|
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
|
||||||
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
|
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
|
||||||
|
case PIPE_CAP_CONDITIONAL_RENDER:
|
||||||
|
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
||||||
return is_a3xx(screen) || is_a4xx(screen);
|
return is_a3xx(screen) || is_a4xx(screen);
|
||||||
|
|
||||||
case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
|
case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
|
||||||
|
@ -227,7 +228,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||||
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
|
||||||
case PIPE_CAP_DRAW_INDIRECT:
|
case PIPE_CAP_DRAW_INDIRECT:
|
||||||
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
|
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
|
||||||
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
|
||||||
case PIPE_CAP_SAMPLER_VIEW_TARGET:
|
case PIPE_CAP_SAMPLER_VIEW_TARGET:
|
||||||
case PIPE_CAP_POLYGON_OFFSET_CLAMP:
|
case PIPE_CAP_POLYGON_OFFSET_CLAMP:
|
||||||
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
|
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
|
||||||
|
|
Loading…
Reference in New Issue