[virglrenderer-devel] [PATCH] vrend: Copy from iovec to avoid needing glGetTexImage
Tomeu Vizoso
tomeu.vizoso at collabora.com
Fri May 25 06:58:01 UTC 2018
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.
Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>
---
src/vrend_renderer.c | 92 +++++++++++++++++++++++++++-----------------
1 file changed, 57 insertions(+), 35 deletions(-)
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 862a873cd812..1fccccbc28de 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,51 @@ 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);
+ } 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 = 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 +5942,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, src_level, 0, false);
+
free(tptr);
}
--
2.17.0
More information about the virglrenderer-devel
mailing list