[virglrenderer-devel] [PATCH 1/5] vrend: Copy from iovec on GLES host since glGetTexImage is not available (v3)

Gert Wollny gert.wollny at collabora.com
Fri Jun 15 17:50:53 UTC 2018


From: Tomeu Vizoso <tomeu.vizoso at collabora.com>

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

Signed-off-by: Tomeu Vizoso <tomeu.vizoso at collabora.com>(v2)
Signed-off-by: Jakob Bornecrantz <jakob at collabora.com>(v2)
Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
---
 src/vrend_renderer.c | 100 +++++++++++++++++++++++++++----------------
 1 file changed, 63 insertions(+), 37 deletions(-)

diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 8f8eb74..3af5216 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -6070,13 +6070,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;
 
@@ -6085,6 +6087,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);
@@ -6100,43 +6108,61 @@ 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);
-
-   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);
+   /* If we are on gles we need to rely on the textures backing
+    * iovec to have the data we need, otherwise we can use glGetTexture
+    */
+   if (vrend_state.use_gles) {
+      read_transfer_data(&src_res->base, src_res->iov, src_res->num_iovs,
+                         tptr, src_stride, &box, src_level, 0, false);
+      /* Sync the dst iovec backing store because
+       * we might need it in a chain copy A->B, B->C */
+      write_transfer_data(&dst_res->base, dst_res->iov, dst_res->num_iovs, tptr,
+                          dst_stride, &box, src_level, 0, false);
+      /* 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 */
+      if (dst_res->base.format == (enum pipe_format)VIRGL_FORMAT_Z24X8_UNORM) {
+         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 ?
+                            (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);
-- 
2.17.1



More information about the virglrenderer-devel mailing list