From 429d2f5f7f32f0703b910f27a534cb06d9b6f722 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         | 75 +++++++++++++++++++-----------------------
 dlls/wined3d/texture.c         |  2 +-
 dlls/wined3d/volume.c          | 28 ++--------------
 dlls/wined3d/wined3d_private.h |  5 +--
 5 files changed, 70 insertions(+), 71 deletions(-)

diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 74be48d..7922433 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -430,3 +430,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 39a2c3b..2e7f0f8 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -364,6 +364,7 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
     BITMAPINFO *b_info;
     int extraline = 0;
     DWORD *masks;
+    UINT row_pitch, slice_pitch;
 
     TRACE("surface %p.\n", surface);
 
@@ -409,10 +410,11 @@ static HRESULT surface_create_dib_section(struct wined3d_surface *surface)
 
     b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
     /* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */
-    b_info->bmiHeader.biWidth = wined3d_surface_get_pitch(surface) / format->byte_count;
+    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 - extraline;
     b_info->bmiHeader.biSizeImage = (surface->resource.height + extraline)
-            * wined3d_surface_get_pitch(surface);
+            * row_pitch;
     b_info->bmiHeader.biPlanes = 1;
     b_info->bmiHeader.biBitCount = format->byte_count * 8;
 
@@ -1330,14 +1332,14 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
         void *mem;
         GLenum gl_format = format->glFormat;
         GLenum gl_type = format->glType;
-        int src_pitch = 0;
-        int dst_pitch = 0;
+        UINT src_pitch = 0;
+        UINT dst_row_pitch, dst_slice_pitch;
 
         if (surface->flags & SFLAG_NONPOW2)
         {
             unsigned char alignment = surface->resource.device->surface_alignment;
             src_pitch = format->byte_count * surface->pow2Width;
-            dst_pitch = wined3d_surface_get_pitch(surface);
+            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);
         }
@@ -1424,12 +1426,12 @@ static void surface_download_data(struct wined3d_surface *surface, const struct
              * won't be released, and doesn't have to be re-read. */
             src_data = mem;
             dst_data = data.addr;
-            TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_pitch);
+            TRACE("(%p) : Repacking the surface data from pitch %d to pitch %d\n", surface, src_pitch, dst_row_pitch);
             for (y = 0; y < surface->resource.height; ++y)
             {
-                memcpy(dst_data, src_data, dst_pitch);
+                memcpy(dst_data, src_data, dst_row_pitch);
                 src_data += src_pitch;
-                dst_data += dst_pitch;
+                dst_data += dst_row_pitch;
             }
 
             HeapFree(GetProcessHeap(), 0, mem);
@@ -1591,7 +1593,7 @@ HRESULT surface_upload_from_surface(struct wined3d_surface *dst_surface, const P
     UINT update_w, update_h;
     UINT dst_w, dst_h;
     RECT r, dst_rect;
-    UINT src_pitch;
+    UINT src_row_pitch, src_slice_pitch;
     POINT p;
 
     TRACE("dst_surface %p, dst_point %s, src_surface %p, src_rect %s.\n",
@@ -1679,10 +1681,10 @@ 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);
-    src_pitch = wined3d_surface_get_pitch(src_surface);
+    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_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
+            src_row_pitch, dst_point, FALSE, wined3d_const_bo_address(&data));
 
     context_release(context);
 
@@ -1934,21 +1936,10 @@ HRESULT CDECL wined3d_surface_restore(struct wined3d_surface *surface)
 
 DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
 {
-    unsigned int alignment;
-    DWORD pitch;
-
-    TRACE("surface %p.\n", surface);
-
-    if (surface->pitch)
-        return surface->pitch;
-
-    alignment = surface->resource.device->surface_alignment;
-    pitch = wined3d_format_calculate_pitch(surface->resource.format, surface->resource.width);
-    pitch = (pitch + alignment - 1) & ~(alignment - 1);
-
-    TRACE("Returning %u.\n", pitch);
-
-    return pitch;
+    UINT row_pitch, slice_pitch;
+    const struct wined3d_resource *resource = &surface->resource;
+    wined3d_resource_get_pitch(resource, &row_pitch, &slice_pitch);
+    return row_pitch;
 }
 
 HRESULT CDECL wined3d_surface_set_overlay_position(struct wined3d_surface *surface, LONG x, LONG y)
@@ -2110,20 +2101,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.
@@ -2749,7 +2741,7 @@ HRESULT CDECL wined3d_surface_map(struct wined3d_surface *surface,
     if (fmt_flags & WINED3DFMT_FLAG_BROKEN_PITCH)
         map_desc->row_pitch = surface->resource.width * format->byte_count;
     else
-        map_desc->row_pitch = wined3d_surface_get_pitch(surface);
+        wined3d_resource_get_pitch(&surface->resource, &map_desc->row_pitch, &map_desc->slice_pitch);
     map_desc->slice_pitch = surface->resource.height * map_desc->row_pitch;
 
     if (!box)
@@ -2898,6 +2890,7 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
     int i;
     BOOL srcIsUpsideDown;
     struct wined3d_bo_address data;
+    DWORD slice_pitch, pitch;
 
     surface_get_memory(surface, &data, dst_location);
 
@@ -2939,8 +2932,8 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
     }
 
     /* Setup pixel store pack state -- to glReadPixels into the correct place */
-    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH,
-            wined3d_surface_get_pitch(surface) / surface->resource.format->byte_count);
+    wined3d_resource_get_pitch(&surface->resource, &pitch, &slice_pitch);
+    gl_info->gl_ops.gl.p_glPixelStorei(GL_PACK_ROW_LENGTH, pitch / surface->resource.format->byte_count);
     checkGLcall("glPixelStorei");
 
     gl_info->gl_ops.gl.p_glReadPixels(0, 0,
@@ -2957,8 +2950,6 @@ static void read_from_framebuffer(struct wined3d_surface *surface,
     {
         /* glReadPixels returns the image upside down, and there is no way to prevent this.
          * Flip the lines in software. */
-        UINT pitch = wined3d_surface_get_pitch(surface);
-
         if (!(row = HeapAlloc(GetProcessHeap(), 0, pitch)))
             goto error;
 
@@ -4077,7 +4068,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     struct wined3d_device *device = surface->resource.device;
     const struct wined3d_color_key_conversion *conversion;
     struct wined3d_texture *texture = surface->container;
-    UINT width, src_pitch, dst_pitch;
+    UINT width, src_row_pitch, src_slice_pitch, dst_pitch;
     struct wined3d_bo_address data;
     struct wined3d_format format;
     POINT dst_point = {0, 0};
@@ -4162,7 +4153,7 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
     wined3d_texture_bind_and_dirtify(texture, context, srgb);
 
     width = surface->resource.width;
-    src_pitch = wined3d_surface_get_pitch(surface);
+    wined3d_resource_get_pitch(&surface->resource, &src_row_pitch, &src_slice_pitch);
 
     format = *texture->resource.format;
     if ((conversion = wined3d_format_get_color_key_conversion(texture, TRUE)))
@@ -4200,9 +4191,9 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
             context_release(context);
             return E_OUTOFMEMORY;
         }
-        format.convert(data.addr, mem, src_pitch, src_pitch * height,
+        format.convert(data.addr, mem, src_row_pitch, src_row_pitch * height,
                 dst_pitch, dst_pitch * height, width, height, 1);
-        src_pitch = dst_pitch;
+        src_row_pitch = dst_pitch;
         data.addr = mem;
     }
     else if (conversion)
@@ -4222,14 +4213,14 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
         }
         if (texture->swapchain && texture->swapchain->palette)
             palette = texture->swapchain->palette;
-        conversion->convert(data.addr, src_pitch, mem, dst_pitch,
+        conversion->convert(data.addr, src_row_pitch, mem, dst_pitch,
                 width, height, palette, &texture->async.gl_color_key);
-        src_pitch = dst_pitch;
+        src_row_pitch = dst_pitch;
         data.addr = mem;
     }
 
     wined3d_surface_upload_data(surface, gl_info, &format, &src_rect,
-            src_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
+            src_row_pitch, &dst_point, srgb, wined3d_const_bo_address(&data));
 
     HeapFree(GetProcessHeap(), 0, mem);
 
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 4380e5f..6511d2e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1269,7 +1269,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_volume_get_pitch(volume, &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 0231c23..7be9ff5 100644
--- a/dlls/wined3d/volume.c
+++ b/dlls/wined3d/volume.c
@@ -40,30 +40,6 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
     return TRUE;
 }
 
-void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch)
-{
-    const struct wined3d_format *format = volume->resource.format;
-
-    if (volume->container->resource.format_flags & 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 row_block_count = (volume->resource.width + format->block_width - 1) / format->block_width;
-        UINT slice_block_count = (volume->resource.height + format->block_height - 1) / format->block_height;
-        *row_pitch = row_block_count * format->block_byte_count;
-        *slice_pitch = *row_pitch * slice_block_count;
-    }
-    else
-    {
-        unsigned char alignment = volume->resource.device->surface_alignment;
-        *row_pitch = format->byte_count * volume->resource.width;  /* Bytes / row */
-        *row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1);
-        *slice_pitch = *row_pitch * volume->resource.height;
-    }
-
-    TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch);
-}
-
 /* This call just uploads data, the caller is responsible for binding the
  * correct texture. */
 /* Context activation is done by the caller. */
@@ -95,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_volume_get_pitch(volume, &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,
@@ -610,7 +586,7 @@ HRESULT wined3d_volume_map(struct wined3d_volume *volume,
     }
     else
     {
-        wined3d_volume_get_pitch(volume, &map_desc->row_pitch, &map_desc->slice_pitch);
+        wined3d_resource_get_pitch(&volume->resource, &map_desc->row_pitch, &map_desc->slice_pitch);
     }
 
     if (!box)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 4c4a58a..17ccabd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2184,6 +2184,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;
@@ -2211,6 +2212,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;
@@ -2348,7 +2351,6 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume) DECLSPEC_HIDDEN
 HRESULT wined3d_volume_create(struct wined3d_texture *container, const struct wined3d_resource_desc *desc,
         unsigned int level, struct wined3d_volume **volume) DECLSPEC_HIDDEN;
 void wined3d_volume_destroy(struct wined3d_volume *volume) DECLSPEC_HIDDEN;
-void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) DECLSPEC_HIDDEN;
 void wined3d_volume_load(struct wined3d_volume *volume, struct wined3d_context *context,
         BOOL srgb_mode) DECLSPEC_HIDDEN;
 void wined3d_volume_invalidate_location(struct wined3d_volume *volume, DWORD location) DECLSPEC_HIDDEN;
@@ -2401,7 +2403,6 @@ struct wined3d_surface
 
     DWORD flags;
 
-    UINT pitch;
     UINT pow2Width;
     UINT pow2Height;
 
-- 
2.6.2

