[PATCH v2 7/9] wined3d: Use ARB_get_texture_sub_image for surface data readback when available.

Józef Kucia jkucia at codeweavers.com
Wed Apr 20 02:09:46 CDT 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
Version 2: Rebased.
---
 dlls/wined3d/surface.c | 51 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 08312e6..0d983c5 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -979,12 +979,14 @@ static void surface_download_data(struct wined3d_surface *surface, struct wined3
     struct wined3d_texture *texture = surface->container;
     const struct wined3d_format *format = texture->resource.format;
     struct wined3d_texture_sub_resource *sub_resource;
+    unsigned int width, height, sub_resource_size;
     unsigned int dst_row_pitch, dst_slice_pitch;
     unsigned int src_row_pitch, src_slice_pitch;
-    unsigned int sub_resource_size;
+    struct gl_texture *gl_texture = NULL;
     struct wined3d_bo_address data;
     BYTE *temporary_mem = NULL;
     void *mem;
+    BOOL srgb;
 
     /* Only support read back of converted P8 surfaces. */
     if (texture->flags & WINED3D_TEXTURE_CONVERTED && format->id != WINED3DFMT_P8_UINT)
@@ -995,8 +997,11 @@ static void surface_download_data(struct wined3d_surface *surface, struct wined3
 
     sub_resource = wined3d_texture_get_sub_resource(texture, sub_resource_idx);
     sub_resource_size = sub_resource->resource->size;
+    width = wined3d_texture_get_level_width(texture, surface->texture_level);
+    height = wined3d_texture_get_level_height(texture, surface->texture_level);
+    srgb = !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB);
 
-    if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+    if (surface->texture_target == GL_TEXTURE_2D_ARRAY && !gl_info->supported[ARB_GET_TEXTURE_SUB_IMAGE])
     {
         /* Try to avoid using glGetTexImage() for layered textures. */
         if ((texture->resource.draw_binding & sub_resource->locations)
@@ -1024,7 +1029,10 @@ static void surface_download_data(struct wined3d_surface *surface, struct wined3
         }
     }
 
-    wined3d_texture_bind_and_dirtify(texture, context, !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
+    if (gl_info->supported[ARB_GET_TEXTURE_SUB_IMAGE])
+        gl_texture = wined3d_texture_get_gl_texture(texture, srgb);
+    else
+        wined3d_texture_bind_and_dirtify(texture, context, srgb);
 
     wined3d_texture_get_memory(texture, sub_resource_idx, &data, dst_location);
 
@@ -1064,20 +1072,39 @@ static void surface_download_data(struct wined3d_surface *surface, struct wined3
 
     if (texture->resource.format_flags & WINED3DFMT_FLAG_COMPRESSED)
     {
-        TRACE("Downloading compressed surface %p, level %u, format %#x, type %#x, data %p.\n",
-                surface, surface->texture_level, format->glFormat, format->glType, mem);
+        TRACE("Downloading compressed surface %p, level %u, layer %u, format %#x, type %#x, data %p.\n",
+                surface, surface->texture_level, surface->texture_layer, format->glFormat, format->glType, mem);
 
-        GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, mem));
-        checkGLcall("glGetCompressedTexImage");
+        if (gl_info->supported[ARB_GET_TEXTURE_SUB_IMAGE])
+        {
+            GL_EXTCALL(glGetCompressedTextureSubImage(gl_texture->name, surface->texture_level,
+                        0, 0, surface->texture_layer, width, height, 1, sub_resource_size, mem));
+            checkGLcall("glGetCompressedTextureSubImage");
+        }
+        else
+        {
+            GL_EXTCALL(glGetCompressedTexImage(surface->texture_target, surface->texture_level, mem));
+            checkGLcall("glGetCompressedTexImage");
+        }
     }
     else
     {
-        TRACE("Downloading surface %p, level %u, format %#x, type %#x, data %p.\n",
-                surface, surface->texture_level, format->glFormat, format->glType, mem);
+        TRACE("Downloading surface %p, level %u, layer %u, format %#x, type %#x, data %p.\n",
+                surface, surface->texture_level, surface->texture_layer, format->glFormat, format->glType, mem);
 
-        gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
-                format->glFormat, format->glType, mem);
-        checkGLcall("glGetTexImage");
+        if (gl_info->supported[ARB_GET_TEXTURE_SUB_IMAGE])
+        {
+            GL_EXTCALL(glGetTextureSubImage(gl_texture->name, surface->texture_level,
+                        0, 0, surface->texture_layer, width, height, 1,
+                        format->glFormat, format->glType, sub_resource_size, mem));
+            checkGLcall("glGetTextureSubImage");
+        }
+        else
+        {
+            gl_info->gl_ops.gl.p_glGetTexImage(surface->texture_target, surface->texture_level,
+                    format->glFormat, format->glType, mem);
+            checkGLcall("glGetTexImage");
+        }
     }
 
     if (texture->flags & WINED3D_TEXTURE_COND_NP2_EMULATED)
-- 
2.4.10




More information about the wine-patches mailing list