From 2d4d9e65962f93d9aabea0aa891cc95fa1b8ccdc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20D=C3=B6singer?= <stefan@codeweavers.com>
Date: Thu, 19 Sep 2013 14:22:24 +0200
Subject: wined3d: Merge get_pitch functions.

---
 dlls/wined3d/resource.c        | 31 +++++++++++++++++++++++++++++++
 dlls/wined3d/surface.c         | 22 +++++++++++-----------
 dlls/wined3d/texture.c         |  2 +-
 dlls/wined3d/volume.c          |  2 +-
 dlls/wined3d/wined3d_private.h |  4 +++-
 5 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 44cdb43..ed598cc 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -440,3 +440,34 @@ void wined3d_resource_update_draw_binding(struct wined3d_resource *resource)
     else
         resource->draw_binding = WINED3D_LOCATION_TEXTURE_RGB;
 }
+
+void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
+        UINT *slice_pitch)
+{
+    unsigned int alignment;
+    const struct wined3d_format *format = resource->format;
+
+    if (resource->custom_row_pitch)
+    {
+        *row_pitch = resource->custom_row_pitch;
+        *slice_pitch = resource->custom_slice_pitch;
+        return;
+    }
+
+    alignment = resource->device->surface_alignment;
+    *row_pitch = wined3d_format_calculate_pitch(resource->format, resource->width);
+    *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1);
+    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS)
+    {
+        /* Since compressed formats are block based, pitch means the amount of
+         * bytes to the next row of block rather than the next row of pixels. */
+        UINT slice_block_count = (resource->height + format->block_height - 1) / format->block_height;
+        *slice_pitch = *row_pitch * slice_block_count;
+    }
+    else
+    {
+        *slice_pitch = *row_pitch * resource->height;
+    }
+
+    TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch);
+}
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index aff6162..418efa3 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -395,7 +395,7 @@ HRESULT surface_create_dib_section(struct wined3d_surface *surface)
         return E_OUTOFMEMORY;
 
     b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-    wined3d_texture_get_pitch(surface->container, surface->texture_level, &row_pitch, &slice_pitch);
+    wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch);
     b_info->bmiHeader.biWidth = row_pitch / format->byte_count;
     b_info->bmiHeader.biHeight = 0 - surface->resource.height;
     b_info->bmiHeader.biSizeImage = slice_pitch;
@@ -1319,7 +1319,7 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
         {
             unsigned char alignment = surface->resource.device->surface_alignment;
             src_pitch = format->byte_count * surface->pow2Width;
-            wined3d_texture_get_pitch(surface->container, surface->texture_level, &dst_row_pitch, &dst_slice_pitch);
+            wined3d_resource_get_pitch(&surface->resource, &dst_row_pitch, &dst_slice_pitch);
             src_pitch = (src_pitch + alignment - 1) & ~(alignment - 1);
             mem = HeapAlloc(GetProcessHeap(), 0, src_pitch * surface->pow2Height);
         }
@@ -1667,7 +1667,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     wined3d_texture_bind_and_dirtify(dst_surface->container, context, FALSE);
 
     surface_get_memory(src_surface, &data, src_surface->locations);
-    wined3d_texture_get_pitch(src_surface->container, src_surface->texture_level, &src_row_pitch, &src_slice_pitch);
+    wined3d_resource_get_pitch(&src_surface->resource, &src_row_pitch, &src_slice_pitch);
 
     wined3d_surface_upload_data(dst_surface, gl_info, src_format, src_rect,
             src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
@@ -1908,20 +1908,21 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface,
         surface->resource.map_binding = WINED3D_LOCATION_USER_MEMORY;
         valid_location = WINED3D_LOCATION_USER_MEMORY;
     }
-    surface->pitch = pitch;
+    surface->resource.custom_row_pitch = pitch;
+    surface->resource.custom_slice_pitch = pitch * surface->resource.height;
     surface->resource.format = texture_resource->format;
     surface->resource.multisample_type = texture_resource->multisample_type;
     surface->resource.multisample_quality = texture_resource->multisample_quality;
-    if (surface->pitch)
+    if (surface->resource.custom_row_pitch)
     {
-        surface->resource.size = height * surface->pitch;
+        surface->resource.size = height * surface->resource.custom_row_pitch;
     }
     else
     {
         /* User memory surfaces don't have the regular surface alignment. */
         surface->resource.size = wined3d_format_calculate_size(texture_resource->format,
                 1, width, height, 1);
-        surface->pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
+        surface->resource.custom_row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
     }
 
     /* The format might be changed to a format that needs conversion.
@@ -2547,8 +2548,7 @@ HRESULT wined3d_surface_map(struct wined3d_surface *surface, struct wined3d_map_
     }
     else
     {
-        wined3d_texture_get_pitch(surface->container, surface->texture_level,
-                &map_desc->row_pitch, &map_desc->slice_pitch);
+        wined3d_resource_get_pitch(&surface->resource, &map_desc->row_pitch, &map_desc->slice_pitch);
     }
 
     if (!box)
@@ -2640,7 +2640,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
         checkGLcall("glBindBuffer");
     }
 
-    wined3d_texture_get_pitch(surface->container, surface->texture_level, &row_pitch, &slice_pitch);
+    wined3d_resource_get_pitch(&surface->resource, &row_pitch, &slice_pitch);
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
     gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, row_pitch / surface->resource.format->byte_count);
@@ -3897,7 +3897,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
 
     wined3d_texture_prepare_texture(texture, context, srgb);
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
-    wined3d_texture_get_pitch(texture, surface->texture_level, &src_row_pitch, &src_slice_pitch);
+    wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch);
 
     width = surface->resource.width;
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index a443b5d..cb7ae9c 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1180,7 +1180,7 @@ static void texture3d_sub_resource_upload_data(struct wined3d_resource *sub_reso
     struct wined3d_const_bo_address addr;
     unsigned int row_pitch, slice_pitch;
 
-    wined3d_texture_get_pitch(volume->container, volume->texture_level, &row_pitch, &slice_pitch);
+    wined3d_resource_get_pitch(sub_resource, &row_pitch, &slice_pitch);
     if (row_pitch != data->row_pitch || slice_pitch != data->slice_pitch)
         FIXME("Ignoring row/slice pitch (%u/%u).\n", data->row_pitch, data->slice_pitch);
 
diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c
index 75585d8..d97db80 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -71,7 +71,7 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
         dst_row_pitch = width * format->conv_byte_count;
         dst_slice_pitch = dst_row_pitch * height;
 
-        wined3d_texture_get_pitch(volume->container, volume->texture_level, &src_row_pitch, &src_slice_pitch);
+        wined3d_resource_get_pitch(&volume->resource, &src_row_pitch, &src_slice_pitch);
 
         converted_mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
         format->convert(data->addr, converted_mem, src_row_pitch, src_slice_pitch,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1dc499e..90a489e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2277,6 +2277,7 @@ struct wined3d_resource
     UINT size;
     DWORD priority;
     void *heap_memory;
+    UINT custom_row_pitch, custom_slice_pitch;
     struct list resource_list_entry;
 
     void *parent;
@@ -2304,6 +2305,8 @@ HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *
 void resource_unload(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_allocate_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_resource_free_sysmem(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void wined3d_resource_get_pitch(const struct wined3d_resource *resource, UINT *row_pitch,
+        UINT *slice_pitch) DECLSPEC_HIDDEN;
 GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
 GLenum wined3d_resource_gl_legacy_map_flags(DWORD d3d_flags) DECLSPEC_HIDDEN;
 BOOL wined3d_resource_is_offscreen(struct wined3d_resource *resource) DECLSPEC_HIDDEN;
@@ -2498,7 +2501,6 @@ struct wined3d_surface
 
     DWORD flags;
 
-    UINT pitch;
     UINT pow2Width;
     UINT pow2Height;
 
-- 
2.7.1

