[virglrenderer-devel] [PATCH 2/3] vrend: If available use glCopyImageSubData to execute memcopy like blits
Gurchetan Singh
gurchetansingh at chromium.org
Tue Jun 26 03:52:14 UTC 2018
On Wed, Jun 20, 2018 at 2:03 AM Gert Wollny <gert.wollny at collabora.com> wrote:
>
> When the host is gles >= 3.2, gl >= 4.3 or when the extension
> GL_(ARB|EXT|OES)_copy_image is available, memcopy like blitting and region
> copying can be done for many color format combinations by using
> glCopyImageSubData.
>
> This fixes a number of tests from the subset
> dEQP-GLES31.functional.copy_image.non_compressed.viewclass_*
>
> Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
> ---
> src/vrend_formats.c | 25 ++++++++++++++++++++++
> src/vrend_renderer.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++--
> src/vrend_renderer.h | 2 ++
> 3 files changed, 83 insertions(+), 2 deletions(-)
>
> diff --git a/src/vrend_formats.c b/src/vrend_formats.c
> index eb9f217..d1653a4 100644
> --- a/src/vrend_formats.c
> +++ b/src/vrend_formats.c
> @@ -443,3 +443,28 @@ void vrend_build_format_list_gles(void)
> */
> add_formats(gles_z32_format);
> }
> +
> +bool vrend_is_canonical_format(enum pipe_format format)
> +{
> + /* These are the canonical formats that are set by gallium */
> +
> + switch (format) {
> + case PIPE_FORMAT_R32G32B32A32_UINT:
> + case PIPE_FORMAT_R32G32B32_UINT:
> + case PIPE_FORMAT_R32G32_UINT:
> + case PIPE_FORMAT_R16G16B16A16_UINT:
> + case PIPE_FORMAT_R16G16B16_UINT:
> + case PIPE_FORMAT_R8G8B8A8_UNORM:
> + case PIPE_FORMAT_A8B8G8R8_UNORM:
> + case PIPE_FORMAT_R16G16_UNORM:
> + case PIPE_FORMAT_R32_UINT:
> + case PIPE_FORMAT_R8G8B8_UINT:
> + case PIPE_FORMAT_G8R8_UNORM:
> + case PIPE_FORMAT_R8G8_UNORM:
> + case PIPE_FORMAT_R16_UINT:
> + case PIPE_FORMAT_R8_UINT:
> + return true;
> + default:
> + return false;
> + }
> +}
What do you mean by "canonical" formats? st_cb_copyimage.c makes some
references to canonical formats, but doesn't really list it like this
as this patch does.
> \ No newline at end of file
> diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
> index b769e8a..8690eb2 100644
> --- a/src/vrend_renderer.c
> +++ b/src/vrend_renderer.c
> @@ -118,6 +118,7 @@ struct global_renderer_state {
> bool have_polygon_offset_clamp;
> bool have_texture_storage;
> bool have_tessellation;
> + bool have_copy_image;
>
> /* these appeared broken on at least one driver */
> bool use_explicit_locations;
> @@ -4449,6 +4450,12 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags)
> if (gl_ver >= 46 || epoxy_has_gl_extension("GL_ARB_polygon_offset_clamp"))
> vrend_state.have_polygon_offset_clamp = true;
>
> + if (gl_ver >= 43 || (gles && gl_ver >= 32) ||
> + epoxy_has_gl_extension("GL_ARB_copy_image") ||
> + epoxy_has_gl_extension("GL_EXT_copy_image") ||
> + epoxy_has_gl_extension("GL_OES_copy_image"))
> + vrend_state.have_copy_image = true;
> +
> /* callbacks for when we are cleaning up the object table */
> vrend_resource_set_destroy_callback(vrend_destroy_resource_object);
> vrend_object_set_destroy_callback(VIRGL_OBJECT_QUERY, vrend_destroy_query_object);
> @@ -6260,6 +6269,22 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
> free(tptr);
> }
>
> +
> +static inline void
> +vrend_copy_sub_image(struct vrend_resource* src_res, struct vrend_resource * dst_res,
> + uint32_t src_level, const struct pipe_box *src_box,
> + uint32_t dst_level, uint32_t dstx, uint32_t dsty, uint32_t dstz)
> +{
> + glCopyImageSubData(src_res->id,
> + tgsitargettogltarget(src_res->base.target, src_res->base.nr_samples),
> + src_level, src_box->x, src_box->y, src_box->z,
> + dst_res->id,
> + tgsitargettogltarget(dst_res->base.target, dst_res->base.nr_samples),
> + dst_level, dstx, dsty, dstz,
> + src_box->width, src_box->height,src_box->depth);
> +}
> +
> +
> void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
> uint32_t dst_handle, uint32_t dst_level,
> uint32_t dstx, uint32_t dsty, uint32_t dstz,
> @@ -6292,11 +6317,20 @@ void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
> return;
> }
>
> + if (vrend_state.have_copy_image) {
> + const struct util_format_description *src_desc = util_format_description(src_res->base.format);
> + const struct util_format_description *dst_desc = util_format_description(dst_res->base.format);
> + if (util_is_format_compatible(src_desc,dst_desc)) {
> + vrend_copy_sub_image(src_res, dst_res, src_level, src_box,
> + dst_level, dstx, dsty, dstz);
> + return;
> + }
> + }
> +
> if (!vrend_format_can_render(src_res->base.format) ||
> !vrend_format_can_render(dst_res->base.format)) {
> vrend_resource_copy_fallback(ctx, src_res, dst_res, dst_level, dstx,
> dsty, dstz, src_level, src_box);
> -
> return;
> }
>
> @@ -6568,7 +6602,27 @@ void vrend_renderer_blit(struct vrend_context *ctx,
> if (info->render_condition_enable == false)
> vrend_pause_render_condition(ctx, true);
>
> - vrend_renderer_blit_int(ctx, src_res, dst_res, info);
> + /* The gallium blit function can be called for a general blit that may
> + * scale and convert the data or for a memcopy blit. In the latter case
> + * the info->formats are equal and set to one of the canonical formats.
> + * In addition some other restrictions apply. For this latter case use the
> + * glCopyImageSubData function.
> + */
> + if (vrend_state.have_copy_image &&
> + vrend_is_canonical_format(info->src.format) &&
> + (info->src.format == info->dst.format) &&
> + !info->scissor_enable && (info->filter == PIPE_TEX_FILTER_NEAREST) &&
> + !info->alpha_blend && (info->mask == PIPE_MASK_RGBA) &&
> + (src_res->base.nr_samples == dst_res->base.nr_samples) &&
> + info->src.box.width == info->dst.box.width &&
> + info->src.box.height == info->dst.box.height &&
> + info->src.box.depth == info->dst.box.depth) {
> + vrend_copy_sub_image(src_res, dst_res, info->src.level, &info->src.box,
> + info->dst.level, info->dst.box.x, info->dst.box.y,
> + info->dst.box.z);
> + } else {
> + vrend_renderer_blit_int(ctx, src_res, dst_res, info);
> + }
Hmm, do the GLES31 tests fail when doing blit framebuffer or during
the GL fallback? Since this requires GLES32 features, but an
important use case is GLES31 on GLES31. Would it be possible to fix
those cases without copy_sub_image?? +Alexandros Frantzis who's
worked with this code before and knows where the bodies are buried :-)
>
> if (info->render_condition_enable == false)
> vrend_pause_render_condition(ctx, false);
> diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
> index 258c439..badf2b1 100644
> --- a/src/vrend_renderer.h
> +++ b/src/vrend_renderer.h
> @@ -323,6 +323,8 @@ GLint64 vrend_renderer_get_timestamp(void);
> void vrend_build_format_list_common(void);
> void vrend_build_format_list_gl(void);
> void vrend_build_format_list_gles(void);
> +bool vrend_is_canonical_format(enum pipe_format format);
> +
>
> int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
> int num_iovs);
> --
> 2.16.4
>
> _______________________________________________
> virglrenderer-devel mailing list
> virglrenderer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel
More information about the virglrenderer-devel
mailing list