=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Implement creating 2D array textures.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Apr 26 10:33:42 CDT 2016


Module: wine
Branch: master
Commit: 64da6b05260ab8bea430872b47783d469dcddeeb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=64da6b05260ab8bea430872b47783d469dcddeeb

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Mon Apr 25 12:25:30 2016 +0200

wined3d: Implement creating 2D array textures.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/surface.c | 57 ++++++++++++++++++++++++++++++++++++++------------
 dlls/wined3d/texture.c | 35 ++++++++++++++++++++++++-------
 2 files changed, 71 insertions(+), 21 deletions(-)

diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 9c12f48..28da2eb 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -993,14 +993,25 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         else
             internal = format->glInternal;
 
-        TRACE("glCompressedTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, "
-                "format %#x, image_size %#x, addr %p.\n", surface->texture_target, surface->texture_level,
+        TRACE("Uploading compressed data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
+                "format %#x, image_size %#x, addr %p.\n",
+                surface->texture_target, surface->texture_level, surface->texture_layer,
                 dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr);
 
         if (row_length == src_pitch)
         {
-            GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
-                    dst_point->x, dst_point->y, update_w, update_h, internal, row_count * row_length, addr));
+            if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+            {
+                GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level,
+                            dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1,
+                            internal, row_count * row_length, addr));
+            }
+            else
+            {
+                GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
+                            dst_point->x, dst_point->y, update_w, update_h,
+                            internal, row_count * row_length, addr));
+            }
         }
         else
         {
@@ -1010,13 +1021,23 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
              * can't use the unpack row length like for glTexSubImage2D. */
             for (row = 0, y = dst_point->y; row < row_count; ++row)
             {
-                GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
-                        dst_point->x, y, update_w, format->block_height, internal, row_length, addr));
+                if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+                {
+                    GL_EXTCALL(glCompressedTexSubImage3D(surface->texture_target, surface->texture_level,
+                            dst_point->x, y, surface->texture_layer, update_w, format->block_height, 1,
+                            internal, row_length, addr));
+                }
+                else
+                {
+                    GL_EXTCALL(glCompressedTexSubImage2D(surface->texture_target, surface->texture_level,
+                            dst_point->x, y, update_w, format->block_height, internal, row_length, addr));
+                }
+
                 y += format->block_height;
                 addr += src_pitch;
             }
         }
-        checkGLcall("glCompressedTexSubImage2D");
+        checkGLcall("Upload compressed surface data");
     }
     else
     {
@@ -1025,15 +1046,25 @@ void wined3d_surface_upload_data(struct wined3d_surface *surface, const struct w
         addr += src_rect->top * src_pitch;
         addr += src_rect->left * format->byte_count;
 
-        TRACE("glTexSubImage2D, target %#x, level %d, x %d, y %d, w %d, h %d, format %#x, type %#x, addr %p.\n",
-                surface->texture_target, surface->texture_level, dst_point->x, dst_point->y,
-                update_w, update_h, format->glFormat, format->glType, addr);
+        TRACE("Uploading data, target %#x, level %u, layer %u, x %d, y %d, w %u, h %u, "
+                "format %#x, type %#x, addr %p.\n",
+                surface->texture_target, surface->texture_level, surface->texture_layer,
+                dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
 
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_pitch / format->byte_count);
-        gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level,
-                dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
+        if (surface->texture_target == GL_TEXTURE_2D_ARRAY)
+        {
+            GL_EXTCALL(glTexSubImage3D(surface->texture_target, surface->texture_level,
+                    dst_point->x, dst_point->y, surface->texture_layer, update_w, update_h, 1,
+                    format->glFormat, format->glType, addr));
+        }
+        else
+        {
+            gl_info->gl_ops.gl.p_glTexSubImage2D(surface->texture_target, surface->texture_level,
+                    dst_point->x, dst_point->y, update_w, update_h, format->glFormat, format->glType, addr);
+        }
         gl_info->gl_ops.gl.p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-        checkGLcall("glTexSubImage2D");
+        checkGLcall("Upload surface data");
     }
 
     if (data->buffer_object)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 5e18c4c..3a03bb6 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1359,10 +1359,10 @@ static BOOL texture2d_load_location(struct wined3d_texture *texture, unsigned in
 /* Context activation is done by the caller. */
 static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wined3d_context *context, BOOL srgb)
 {
-    UINT sub_count = texture->level_count * texture->layer_count;
     const struct wined3d_format *format = texture->resource.format;
     const struct wined3d_gl_info *gl_info = context->gl_info;
     const struct wined3d_color_key_conversion *conversion;
+    unsigned int sub_call_count;
     GLenum internal;
     UINT i;
 
@@ -1394,7 +1394,10 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi
 
     TRACE("internal %#x, format %#x, type %#x.\n", internal, format->glFormat, format->glType);
 
-    for (i = 0; i < sub_count; ++i)
+    sub_call_count = texture->level_count;
+    if (texture->target != GL_TEXTURE_2D_ARRAY)
+        sub_call_count *= texture->layer_count;
+    for (i = 0; i < sub_call_count; ++i)
     {
         struct wined3d_surface *surface = texture->sub_resources[i].u.surface;
         GLsizei width, height;
@@ -1407,12 +1410,22 @@ static void texture2d_prepare_texture(struct wined3d_texture *texture, struct wi
             height /= format->height_scale.denominator;
         }
 
-        TRACE("surface %p, target %#x, level %d, width %d, height %d.\n",
+        TRACE("surface %p, target %#x, level %u, width %u, height %u.\n",
                 surface, surface->texture_target, surface->texture_level, width, height);
 
-        gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
-                internal, width, height, 0, format->glFormat, format->glType, NULL);
-        checkGLcall("glTexImage2D");
+        if (texture->target == GL_TEXTURE_2D_ARRAY)
+        {
+            GL_EXTCALL(glTexImage3D(surface->texture_target, surface->texture_level,
+                    internal, width, height, texture->layer_count, 0,
+                    format->glFormat, format->glType, NULL));
+            checkGLcall("glTexImage3D");
+        }
+        else
+        {
+            gl_info->gl_ops.gl.p_glTexImage2D(surface->texture_target, surface->texture_level,
+                    internal, width, height, 0, format->glFormat, format->glType, NULL);
+            checkGLcall("glTexImage2D");
+        }
     }
 }
 
@@ -1778,8 +1791,12 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
     unsigned int i, j;
     HRESULT hr;
 
-    if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count != 1)
-        FIXME("Array textures not implemented.\n");
+    if (!(desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP) && layer_count > 1
+            && !gl_info->supported[EXT_TEXTURE_ARRAY])
+    {
+        WARN("OpenGL implementation does not support array textures.\n");
+        return WINED3DERR_INVALIDCALL;
+    }
 
     /* TODO: It should only be possible to create textures for formats
      * that are reported as supported. */
@@ -1909,6 +1926,8 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3
         }
         if (desc->usage & WINED3DUSAGE_LEGACY_CUBEMAP)
             texture->target = GL_TEXTURE_CUBE_MAP_ARB;
+        else if (layer_count > 1)
+            texture->target = GL_TEXTURE_2D_ARRAY;
         else
             texture->target = GL_TEXTURE_2D;
     }




More information about the wine-cvs mailing list