From d787ce7288d63923dd8211e117baea86faaf3539 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 28 Oct 2016 11:33:53 -0700 Subject: [PATCH] svga: Implement the pipe clear_render_target functionality v2 v2: Accounted for the fact that svga_try_clear_render_target also honors conditional rendering. Testing done: Excercised all functions in a separate feature branch. Forced emission of conditional rendering commands when necessary. Signed-off-by: Thomas Hellstrom Reviewed-by: Brian Paul --- src/gallium/drivers/svga/svga_context.c | 1 + src/gallium/drivers/svga/svga_context.h | 7 +- src/gallium/drivers/svga/svga_pipe_clear.c | 129 +++++++++++++++++++++ src/gallium/drivers/svga/svga_pipe_query.c | 2 + 4 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index 52fc654cf3e..21ce5089052 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -273,6 +273,7 @@ struct pipe_context *svga_context_create(struct pipe_screen *screen, } svga->dirty = ~0; + svga->pred.query_id = SVGA3D_INVALID_ID; return &svga->pipe; diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 5148372753d..3e65384a07a 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -583,6 +583,12 @@ struct svga_context /** Alternate rasterizer states created for point sprite */ struct svga_rasterizer_state *rasterizer_no_cull[2]; + + /** Current conditional rendering predicate */ + struct { + SVGA3dQueryId query_id; + boolean cond; + } pred; }; /* A flag for each state_tracker state object: @@ -622,7 +628,6 @@ struct svga_context - /*********************************************************************** * svga_screen_texture.c: */ diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index 12f3050f569..803afc60ff8 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -451,9 +451,138 @@ svga_clear_texture(struct pipe_context *pipe, } } +/** + * \brief Clear the whole render target using vgpu10 functionality + * + * \param svga[in] The svga context + * \param dst[in] The surface to clear + * \param color[in] Clear color + * \return PIPE_OK if all well, PIPE_ERROR_OUT_OF_MEMORY if ran out of + * command submission resources. + */ +static enum pipe_error +svga_try_clear_render_target(struct svga_context *svga, + struct pipe_surface *dst, + const union pipe_color_union *color) +{ + struct pipe_surface *rtv = + svga_validate_surface_view(svga, svga_surface(dst)); + + if (!rtv) + return PIPE_ERROR_OUT_OF_MEMORY; + + return SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, color->f); + } + +/** + * \brief Clear part of render target using gallium blitter utilities + * + * \param svga[in] The svga context + * \param dst[in] The surface to clear + * \param color[in] Clear color + * \param dstx[in] Clear region left + * \param dsty[in] Clear region top + * \param width[in] Clear region width + * \param height[in] Clear region height + */ +static void +svga_blitter_clear_render_target(struct svga_context *svga, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + begin_blit(svga); + util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer); + + util_blitter_clear_render_target(svga->blitter, dst, color, + dstx, dsty, width, height); +} + +/** + * \brief Toggle conditional rendering if already enabled + * + * \param svga[in] The svga context + * \param render_condition_enabled[in] Whether to ignore requests to turn + * conditional rendering off + * \param on[in] Whether to turn conditional rendering on or off + */ +static void +svga_toggle_render_condition(struct svga_context *svga, + boolean render_condition_enabled, + boolean on) +{ + SVGA3dQueryId query_id; + enum pipe_error ret; + + if (render_condition_enabled || + svga->pred.query_id == SVGA3D_INVALID_ID) { + return; + } + + /* + * If we get here, it means that the system supports + * conditional rendering since svga->pred.query_id has already been + * modified for this context and thus support has already been + * verified. + */ + query_id = on ? svga->pred.query_id : SVGA3D_INVALID_ID; + + ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id, + (uint32) svga->pred.cond); + if (ret == PIPE_ERROR_OUT_OF_MEMORY) { + svga_context_flush(svga, NULL); + ret = SVGA3D_vgpu10_SetPredication(svga->swc, query_id, + (uint32) svga->pred.cond); + assert(ret == PIPE_OK); + } +} + +/** + * \brief Clear render target pipe callback + * + * \param pipe[in] The pipe context + * \param dst[in] The surface to clear + * \param color[in] Clear color + * \param dstx[in] Clear region left + * \param dsty[in] Clear region top + * \param width[in] Clear region width + * \param height[in] Clear region height + * \param render_condition_enabled[in] Whether to use conditional rendering + * to clear (if elsewhere enabled). + */ +static void +svga_clear_render_target(struct pipe_context *pipe, + struct pipe_surface *dst, + const union pipe_color_union *color, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + bool render_condition_enabled) +{ + struct svga_context *svga = svga_context( pipe ); + + svga_toggle_render_condition(svga, render_condition_enabled, FALSE); + if (!svga_have_vgpu10(svga) || dstx != 0 || dsty != 0 || + width != dst->width || height != dst->height) { + svga_blitter_clear_render_target(svga, dst, color, dstx, dsty, width, + height); + } else { + enum pipe_error ret; + + ret = svga_try_clear_render_target(svga, dst, color); + if (ret == PIPE_ERROR_OUT_OF_MEMORY) { + svga_context_flush( svga, NULL ); + ret = svga_try_clear_render_target(svga, dst, color); + } + + assert (ret == PIPE_OK); + } + svga_toggle_render_condition(svga, render_condition_enabled, TRUE); +} void svga_init_clear_functions(struct svga_context *svga) { + svga->pipe.clear_render_target = svga_clear_render_target; svga->pipe.clear_texture = svga_clear_texture; svga->pipe.clear = svga_clear; } diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 5de3937474e..a7bfb4ea265 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -1239,6 +1239,8 @@ svga_render_condition(struct pipe_context *pipe, struct pipe_query *q, ret = SVGA3D_vgpu10_SetPredication(svga->swc, queryId, (uint32) condition); } + svga->pred.query_id = queryId; + svga->pred.cond = condition; } } -- 2.30.2