vrend: Copy from iovec on GLES host since glGetTexImage is not available (v3)

GLES doesn't have glGetTexImage, so we rely on the assumption that a
resource's backing iovec is always in sync with the texture data if it
isn't renderable.

Fixes on GLES host:
  dEQP-GLES3.functional.texture.shadow.*
  dEQP-GLES3.functional.texture.wrap.etc2_*.
  dEQP-GLES3.functional.texture.units.*

v2: * Special-case VIRGL_FORMAT_Z24X8_UNORM (Gert Wollny)

v3: * Use IOV backing store as data source only on GLES
    * Keep backing store only up to date only on GLES
      (both Gurchetan Singh)
    * copy the backing store data before it is corrected for the Z24X8
      format upload
    * remove test whether the src surface is renderable, because at this
      point it is only relevant whether glGetTexImage is available (i.e.
      whether we are on a GLES host)
    * Reword commit message

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
macos/master
Tomeu Vizoso 7 years ago committed by Jakob Bornecrantz
parent 35b3cad630
commit a4bc271f8d
  1. 100
      src/vrend_renderer.c

@ -6079,13 +6079,15 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
const struct pipe_box *src_box) const struct pipe_box *src_box)
{ {
char *tptr; char *tptr;
uint32_t transfer_size; uint32_t transfer_size, src_stride, dst_stride;
GLenum glformat, gltype; GLenum glformat, gltype;
int elsize = util_format_get_blocksize(dst_res->base.format); int elsize = util_format_get_blocksize(dst_res->base.format);
int compressed = util_format_is_compressed(dst_res->base.format); int compressed = util_format_is_compressed(dst_res->base.format);
int cube_slice = 1; int cube_slice = 1;
uint32_t slice_size, slice_offset; uint32_t slice_size, slice_offset;
int i; int i;
struct pipe_box box;
if (src_res->target == GL_TEXTURE_CUBE_MAP) if (src_res->target == GL_TEXTURE_CUBE_MAP)
cube_slice = 6; cube_slice = 6;
@ -6094,6 +6096,12 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
return; 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 */ /* 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)) * 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); util_format_get_blocksize(src_res->base.format);
@ -6109,43 +6117,61 @@ static void vrend_resource_copy_fallback(struct vrend_context *ctx,
if (compressed) if (compressed)
glformat = tex_conv_table[src_res->base.format].internalformat; glformat = tex_conv_table[src_res->base.format].internalformat;
switch (elsize) { /* If we are on gles we need to rely on the textures backing
case 1: * iovec to have the data we need, otherwise we can use glGetTexture
glPixelStorei(GL_PACK_ALIGNMENT, 1); */
break; if (vrend_state.use_gles) {
case 2: read_transfer_data(&src_res->base, src_res->iov, src_res->num_iovs,
glPixelStorei(GL_PACK_ALIGNMENT, 2); tptr, src_stride, &box, src_level, 0, false);
break; /* Sync the dst iovec backing store because
case 4: * we might need it in a chain copy A->B, B->C */
default: write_transfer_data(&dst_res->base, dst_res->iov, dst_res->num_iovs, tptr,
glPixelStorei(GL_PACK_ALIGNMENT, 4); dst_stride, &box, src_level, 0, false);
break; /* we get values from the guest as 24-bit scaled integers
case 8: but we give them to the host GL and it interprets them
glPixelStorei(GL_PACK_ALIGNMENT, 8); as 32-bit scaled integers, so we need to scale them here */
break; if (dst_res->base.format == (enum pipe_format)VIRGL_FORMAT_Z24X8_UNORM) {
} float depth_scale = 256.0;
glBindTexture(src_res->target, src_res->id); vrend_scale_depth(tptr, transfer_size, depth_scale);
}
slice_offset = 0; } else {
for (i = 0; i < cube_slice; i++) { switch (elsize) {
GLenum ctarget = src_res->target == GL_TEXTURE_CUBE_MAP ? case 1:
(GLenum)(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : src_res->target; glPixelStorei(GL_PACK_ALIGNMENT, 1);
if (compressed) { break;
if (vrend_state.have_arb_robustness) case 2:
glGetnCompressedTexImageARB(ctarget, src_level, transfer_size, tptr + slice_offset); glPixelStorei(GL_PACK_ALIGNMENT, 2);
else if (vrend_state.use_gles) break;
report_gles_missing_func(ctx, "glGetCompressedTexImage"); case 4:
else default:
glGetCompressedTexImage(ctarget, src_level, tptr + slice_offset); glPixelStorei(GL_PACK_ALIGNMENT, 4);
} else { break;
if (vrend_state.have_arb_robustness) case 8:
glGetnTexImageARB(ctarget, src_level, glformat, gltype, transfer_size, tptr + slice_offset); glPixelStorei(GL_PACK_ALIGNMENT, 8);
else if (vrend_state.use_gles) break;
report_gles_missing_func(ctx, "glGetTexImage"); }
else glBindTexture(src_res->target, src_res->id);
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 ?
(GLenum)(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); glPixelStorei(GL_PACK_ALIGNMENT, 4);

Loading…
Cancel
Save