freedreno: add support for conditional rendering, required for GL3.0
authorIlia Mirkin <imirkin@alum.mit.edu>
Sun, 8 Nov 2015 04:20:31 +0000 (23:20 -0500)
committerRob Clark <robclark@freedesktop.org>
Wed, 18 Nov 2015 19:31:13 +0000 (14:31 -0500)
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>
docs/relnotes/11.1.0.html
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_draw.c
src/gallium/drivers/freedreno/freedreno_query.c
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_resource.h
src/gallium/drivers/freedreno/freedreno_screen.c

index 28fec7e89c4109179b1a1185c5e0e009878378f4..00d517706b5ba713cce6fc3c6d036997d6ce837c 100644 (file)
@@ -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_draw_elements_base_vertex on all drivers</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>EGL_KHR_create_context on softpipe, llvmpipe</li>
 <li>EGL_KHR_gl_colorspace on softpipe, llvmpipe</li>
index 61c4c6d6e240b615479f2d5f29818ac13cb4aa36..571c8142bf7730b866f0f2edb5c1776d029c2c45 100644 (file)
@@ -359,6 +359,10 @@ struct fd_context {
        struct fd_streamout_stateobj streamout;
        struct pipe_clip_state ucp;
 
+       struct pipe_query *cond_query;
+       bool cond_cond; /* inverted rendering condition */
+       uint cond_mode;
+
        /* GMEM/tile handling fxns: */
        void (*emit_tile_init)(struct fd_context *ctx);
        void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);
index 7bf3343f43a229b60731fe16ba4304725e3785cc..bf803cc77bc6137ec109530a8fcadc2ef2285a0c 100644 (file)
@@ -88,6 +88,10 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                return;
        }
 
+       /* TODO: push down the region versions into the tiles */
+       if (!fd_render_condition_check(pctx))
+               return;
+
        /* emulate unsupported primitives: */
        if (!fd_supported_prim(ctx, info->mode)) {
                if (ctx->streamout.num_targets > 0)
@@ -220,6 +224,10 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
        unsigned cleared_buffers;
        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
         * can fully or partially skip mem2gmem) we need to ignore buffers
         * that have already had a draw, in case apps do silly things like
index db2683c9b6fd99f8336cd0cecf1a81aad2b9d0d7..b87e825071941df80dd7e981f7bb85c2bb0a961f 100644 (file)
@@ -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);
 }
 
+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
 fd_get_driver_query_info(struct pipe_screen *pscreen,
                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->end_query = fd_end_query;
        pctx->get_query_result = fd_get_query_result;
+       pctx->render_condition = fd_render_condition;
 }
index 6e22e39f52ea91c2378722a7fd4a51fc77197074..5b1cee8d18d17ca9d58abba2e30322616fc77e50 100644 (file)
@@ -671,7 +671,7 @@ fail:
        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);
 
 /**
@@ -693,7 +693,7 @@ fd_blitter_pipe_copy_region(struct fd_context *ctx,
        if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
                return false;
 
-       fd_blitter_pipe_begin(ctx);
+       fd_blitter_pipe_begin(ctx, false);
        util_blitter_copy_texture(ctx->blitter,
                        dst, dst_level, dstx, dsty, dstz,
                        src, src_level, src_box);
@@ -735,6 +735,25 @@ fd_resource_copy_region(struct pipe_context *pctx,
                        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.
  * 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;
        }
 
+       if (info.render_condition_enable && !fd_render_condition_check(pctx))
+               return;
+
        if (util_try_blit_via_copy_region(pctx, &info)) {
                return; /* done */
        }
@@ -769,13 +791,13 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
                return;
        }
 
-       fd_blitter_pipe_begin(ctx);
+       fd_blitter_pipe_begin(ctx, info.render_condition_enable);
        util_blitter_blit(ctx->blitter, &info);
        fd_blitter_pipe_end(ctx);
 }
 
 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_elements(ctx->blitter, ctx->vtx.vtx);
@@ -796,6 +818,9 @@ fd_blitter_pipe_begin(struct fd_context *ctx)
                        (void **)ctx->fragtex.samplers);
        util_blitter_save_fragment_sampler_views(ctx->blitter,
                        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);
 }
index 7549becaa1f84b682c4c2d70ec024f8aa66ca857..10f5242da57a403dbb8306c7be646b7b3e06c3fb 100644 (file)
@@ -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_context_init(struct pipe_context *pctx);
 
+bool fd_render_condition_check(struct pipe_context *pctx);
+
 #endif /* FREEDRENO_RESOURCE_H_ */
index 56d1834ef9c36dab02113e7bcb5f6d5978d33246..1e124592a801930cc2a28ef9667e31e13b24e3f2 100644 (file)
@@ -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_TGSI_TEXCOORD:
        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
-       case PIPE_CAP_CONDITIONAL_RENDER:
        case PIPE_CAP_TEXTURE_MULTISAMPLE:
        case PIPE_CAP_TEXTURE_BARRIER:
        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_TEXTURE_BUFFER_OBJECTS:
        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);
 
        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_DRAW_INDIRECT:
        case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
-       case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
        case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: