[virglrenderer-devel] [PATCH v2] vrend: Copy from iovec to avoid needing glGetTexImage
Gert Wollny
gert.wollny at collabora.com
Fri May 25 14:39:30 UTC 2018
Am Freitag, den 25.05.2018, 14:11 +0200 schrieb Tomeu Vizoso:
> GLES doesn't have glGetTexImage, so this is a way to get around that.
>
> We rely on the existing assumption that a resource's backing iovec is
> always in sync with the texture data if it isn't renderable.
>
> v2: * Special-case VIRGL_FORMAT_Z24X8_UNORM (Gert Wollny)
>
You might want to add
Fixes on GLES 3 host:
dEQP-GLES3.functional.texture.shadow.*
dEQP-GLES3.functional.texture.wrap.etc2_*.
dEQP-GLES3.functional.texture.units.*
Best,
Gert
> Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
> ---
> src/vrend_renderer.c | 100 ++++++++++++++++++++++++++++-------------
> --
> 1 file changed, 65 insertions(+), 35 deletions(-)
>
> diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
> index 862a873cd812..c37dfb914f2f 100644
> --- a/src/vrend_renderer.c
> +++ b/src/vrend_renderer.c
> @@ -5809,13 +5809,15 @@ static void
> vrend_resource_copy_fallback(struct vrend_context *ctx,
> const struct pipe_box
> *src_box)
> {
> char *tptr;
> - uint32_t transfer_size;
> + uint32_t transfer_size, src_stride, dst_stride;
> GLenum glformat, gltype;
> int elsize = util_format_get_blocksize(dst_res->base.format);
> int compressed = util_format_is_compressed(dst_res->base.format);
> int cube_slice = 1;
> uint32_t slice_size, slice_offset;
> int i;
> + struct pipe_box box;
> +
> if (src_res->target == GL_TEXTURE_CUBE_MAP)
> cube_slice = 6;
>
> @@ -5824,6 +5826,12 @@ static void
> vrend_resource_copy_fallback(struct vrend_context *ctx,
> return;
> }
>
> + box = *src_box;
> + box.depth = vrend_get_texture_depth(src_res, src_level);
> +
> + src_stride = util_format_get_stride(src_res->base.format,
> src_res->base.width0);
> + dst_stride = util_format_get_stride(dst_res->base.format,
> dst_res->base.width0);
> +
> /* this is ugly need to do a full GetTexImage */
> slice_size = util_format_get_nblocks(src_res->base.format,
> u_minify(src_res->base.width0, src_level), u_minify(src_res-
> >base.height0, src_level)) *
> util_format_get_blocksize(src_res->base.format);
> @@ -5839,42 +5847,59 @@ static void
> vrend_resource_copy_fallback(struct vrend_context *ctx,
> if (compressed)
> glformat = tex_conv_table[src_res-
> >base.format].internalformat;
>
> - switch (elsize) {
> - case 1:
> - glPixelStorei(GL_PACK_ALIGNMENT, 1);
> - break;
> - case 2:
> - glPixelStorei(GL_PACK_ALIGNMENT, 2);
> - break;
> - case 4:
> - default:
> - glPixelStorei(GL_PACK_ALIGNMENT, 4);
> - break;
> - case 8:
> - glPixelStorei(GL_PACK_ALIGNMENT, 8);
> - break;
> - }
> - glBindTexture(src_res->target, src_res->id);
> + if (!vrend_format_can_render(src_res->base.format)) {
> + /*
> + * If the src resource isn't renderable, we can rely on its
> backing
> + * iovec having the data we need.
> + */
> + read_transfer_data(&src_res->base, src_res->iov, src_res-
> >num_iovs,
> + tptr, src_stride, &box, src_level, 0,
> false);
>
> - slice_offset = 0;
> - for (i = 0; i < cube_slice; i++) {
> - GLenum ctarget = src_res->target == GL_TEXTURE_CUBE_MAP ?
> GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : src_res->target;
> - if (compressed) {
> - if (vrend_state.have_arb_robustness)
> - glGetnCompressedTexImageARB(ctarget, src_level,
> transfer_size, tptr + slice_offset);
> - else if (vrend_state.use_gles)
> - report_gles_missing_func(ctx,
> "glGetCompressedTexImage");
> - else
> - glGetCompressedTexImage(ctarget, src_level, tptr +
> slice_offset);
> - } else {
> - if (vrend_state.have_arb_robustness)
> - glGetnTexImageARB(ctarget, src_level, glformat, gltype,
> transfer_size, tptr + slice_offset);
> - else if (vrend_state.use_gles)
> - report_gles_missing_func(ctx, "glGetTexImage");
> - else
> - glGetTexImage(ctarget, src_level, glformat, gltype, tptr
> + slice_offset);
> + if (dst_res->base.format == (enum
> pipe_format)VIRGL_FORMAT_Z24X8_UNORM) {
> + /* we get values from the guest as 24-bit scaled integers
> + but we give them to the host GL and it interprets them
> + as 32-bit scaled integers, so we need to scale them here
> */
> + float depth_scale = 256.0;
> + vrend_scale_depth(tptr, transfer_size, depth_scale);
> + }
> + } else {
> + switch (elsize) {
> + case 1:
> + glPixelStorei(GL_PACK_ALIGNMENT, 1);
> + break;
> + case 2:
> + glPixelStorei(GL_PACK_ALIGNMENT, 2);
> + break;
> + case 4:
> + default:
> + glPixelStorei(GL_PACK_ALIGNMENT, 4);
> + break;
> + case 8:
> + glPixelStorei(GL_PACK_ALIGNMENT, 8);
> + break;
> + }
> + glBindTexture(src_res->target, src_res->id);
> +
> + slice_offset = 0;
> + for (i = 0; i < cube_slice; i++) {
> + GLenum ctarget = src_res->target == GL_TEXTURE_CUBE_MAP ?
> GL_TEXTURE_CUBE_MAP_POSITIVE_X + i : src_res->target;
> + if (compressed) {
> + if (vrend_state.have_arb_robustness)
> + glGetnCompressedTexImageARB(ctarget, src_level,
> transfer_size, tptr + slice_offset);
> + else if (vrend_state.use_gles)
> + report_gles_missing_func(ctx,
> "glGetCompressedTexImage");
> + else
> + glGetCompressedTexImage(ctarget, src_level, tptr +
> slice_offset);
> + } else {
> + if (vrend_state.have_arb_robustness)
> + glGetnTexImageARB(ctarget, src_level, glformat,
> gltype, transfer_size, tptr + slice_offset);
> + else if (vrend_state.use_gles)
> + report_gles_missing_func(ctx, "glGetTexImage");
> + else
> + glGetTexImage(ctarget, src_level, glformat, gltype,
> tptr + slice_offset);
> + }
> + slice_offset += slice_size;
> }
> - slice_offset += slice_size;
> }
>
> glPixelStorei(GL_PACK_ALIGNMENT, 4);
> @@ -5925,6 +5950,11 @@ static void
> vrend_resource_copy_fallback(struct vrend_context *ctx,
> }
>
> glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
> +
> + /* Sync the iov that backs the dst resource */
> + write_transfer_data(&dst_res->base, dst_res->iov, dst_res-
> >num_iovs, tptr,
> + dst_stride, &box, dst_level, 0, false);
> +
> free(tptr);
> }
>
More information about the virglrenderer-devel
mailing list