Commit a0beaa40 authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Handle slice pitch and alignment as well in wined3d_format_calculate_pitch().

parent 1b106fe8
...@@ -4756,6 +4756,7 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad ...@@ -4756,6 +4756,7 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad
enum wined3d_format_id format_id, UINT width) enum wined3d_format_id format_id, UINT width)
{ {
const struct wined3d_gl_info *gl_info; const struct wined3d_gl_info *gl_info;
unsigned int row_pitch, slice_pitch;
TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n", TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n",
wined3d, adapter_idx, debug_d3dformat(format_id), width); wined3d, adapter_idx, debug_d3dformat(format_id), width);
...@@ -4764,7 +4765,10 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad ...@@ -4764,7 +4765,10 @@ UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT ad
return ~0u; return ~0u;
gl_info = &wined3d->adapters[adapter_idx].gl_info; gl_info = &wined3d->adapters[adapter_idx].gl_info;
return wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id), width); wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id),
1, width, 1, &row_pitch, &slice_pitch);
return row_pitch;
} }
HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx, HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
......
...@@ -1885,21 +1885,19 @@ static inline unsigned short float_32_to_16(const float *in) ...@@ -1885,21 +1885,19 @@ static inline unsigned short float_32_to_16(const float *in)
DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface) DWORD CDECL wined3d_surface_get_pitch(const struct wined3d_surface *surface)
{ {
unsigned int alignment; unsigned int row_pitch, slice_pitch;
DWORD pitch;
TRACE("surface %p.\n", surface); TRACE("surface %p.\n", surface);
if (surface->container->row_pitch) if (surface->container->row_pitch)
return surface->container->row_pitch; return surface->container->row_pitch;
alignment = surface->resource.device->surface_alignment; wined3d_format_calculate_pitch(surface->resource.format, surface->resource.device->surface_alignment,
pitch = wined3d_format_calculate_pitch(surface->resource.format, surface->resource.width); surface->resource.width, surface->resource.height, &row_pitch, &slice_pitch);
pitch = (pitch + alignment - 1) & ~(alignment - 1);
TRACE("Returning %u.\n", pitch); TRACE("Returning %u.\n", row_pitch);
return pitch; return row_pitch;
} }
HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info) HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struct wined3d_gl_info *gl_info)
...@@ -1961,9 +1959,8 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struc ...@@ -1961,9 +1959,8 @@ HRESULT wined3d_surface_update_desc(struct wined3d_surface *surface, const struc
else else
{ {
/* User memory surfaces don't have the regular surface alignment. */ /* User memory surfaces don't have the regular surface alignment. */
surface->resource.size = wined3d_format_calculate_size(texture_resource->format, wined3d_format_calculate_pitch(texture_resource->format, 1, width, height,
1, width, height, 1); &surface->container->row_pitch, &surface->resource.size);
surface->container->row_pitch = wined3d_format_calculate_pitch(texture_resource->format, width);
} }
/* The format might be changed to a format that needs conversion. /* The format might be changed to a format that needs conversion.
...@@ -3694,10 +3691,10 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, ...@@ -3694,10 +3691,10 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
{ {
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
RECT src_rect = {0, 0, surface->resource.width, surface->resource.height}; RECT src_rect = {0, 0, surface->resource.width, surface->resource.height};
unsigned int width, src_pitch, dst_row_pitch, dst_slice_pitch;
struct wined3d_device *device = surface->resource.device; struct wined3d_device *device = surface->resource.device;
const struct wined3d_color_key_conversion *conversion; const struct wined3d_color_key_conversion *conversion;
struct wined3d_texture *texture = surface->container; struct wined3d_texture *texture = surface->container;
UINT width, src_pitch, dst_pitch;
struct wined3d_bo_address data; struct wined3d_bo_address data;
struct wined3d_format format; struct wined3d_format format;
POINT dst_point = {0, 0}; POINT dst_point = {0, 0};
...@@ -3812,17 +3809,17 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, ...@@ -3812,17 +3809,17 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
UINT height = surface->resource.height; UINT height = surface->resource.height;
format.byte_count = format.conv_byte_count; format.byte_count = format.conv_byte_count;
dst_pitch = wined3d_format_calculate_pitch(&format, width); wined3d_format_calculate_pitch(&format, 1, width, height, &dst_row_pitch, &dst_slice_pitch);
if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
{ {
ERR("Out of memory (%u).\n", dst_pitch * height); ERR("Out of memory (%u).\n", dst_slice_pitch);
context_release(context); context_release(context);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
format.convert(data.addr, mem, src_pitch, src_pitch * height, format.convert(data.addr, mem, src_pitch, src_pitch * height,
dst_pitch, dst_pitch * height, width, height, 1); dst_row_pitch, dst_slice_pitch, width, height, 1);
src_pitch = dst_pitch; src_pitch = dst_row_pitch;
data.addr = mem; data.addr = mem;
} }
else if (conversion) else if (conversion)
...@@ -3831,20 +3828,20 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface, ...@@ -3831,20 +3828,20 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
struct wined3d_palette *palette = NULL; struct wined3d_palette *palette = NULL;
UINT height = surface->resource.height; UINT height = surface->resource.height;
dst_pitch = wined3d_format_calculate_pitch(&format, width); wined3d_format_calculate_pitch(&format, device->surface_alignment,
dst_pitch = (dst_pitch + device->surface_alignment - 1) & ~(device->surface_alignment - 1); width, height, &dst_row_pitch, &dst_slice_pitch);
if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_pitch * height))) if (!(mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch)))
{ {
ERR("Out of memory (%u).\n", dst_pitch * height); ERR("Out of memory (%u).\n", dst_slice_pitch);
context_release(context); context_release(context);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (texture->swapchain && texture->swapchain->palette) if (texture->swapchain && texture->swapchain->palette)
palette = texture->swapchain->palette; palette = texture->swapchain->palette;
conversion->convert(data.addr, src_pitch, mem, dst_pitch, conversion->convert(data.addr, src_pitch, mem, dst_row_pitch,
width, height, palette, &texture->async.gl_color_key); width, height, palette, &texture->async.gl_color_key);
src_pitch = dst_pitch; src_pitch = dst_row_pitch;
data.addr = mem; data.addr = mem;
} }
......
...@@ -3083,46 +3083,47 @@ const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl ...@@ -3083,46 +3083,47 @@ const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl
return &gl_info->formats[idx]; return &gl_info->formats[idx];
} }
UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width) void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment,
unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch)
{ {
/* For block based formats, pitch means the amount of bytes to the next /* For block based formats, pitch means the amount of bytes to the next
* row of blocks rather than the next row of pixels. */ * row of blocks rather than the next row of pixels. */
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS) if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS)
return format->block_byte_count * ((width + format->block_width - 1) / format->block_width);
return format->byte_count * width;
}
UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
UINT width, UINT height, UINT depth)
{
UINT pitch = wined3d_format_calculate_pitch(format, width);
UINT size;
if (format->id == WINED3DFMT_UNKNOWN)
{
size = 0;
}
else if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BLOCKS)
{ {
UINT row_count = (height + format->block_height - 1) / format->block_height; unsigned int row_block_count = (width + format->block_width - 1) / format->block_width;
size = row_count * ((pitch + alignment - 1) & ~(alignment - 1)); unsigned int slice_block_count = (height + format->block_height - 1) / format->block_height;
*row_pitch = row_block_count * format->block_byte_count;
*row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1);
*slice_pitch = *row_pitch * slice_block_count;
} }
else else
{ {
size = height * ((pitch + alignment - 1) & ~(alignment - 1)); *row_pitch = format->byte_count * width; /* Bytes / row */
*row_pitch = (*row_pitch + alignment - 1) & ~(alignment - 1);
*slice_pitch = *row_pitch * height;
} }
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE) if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_HEIGHT_SCALE)
{ {
/* The D3D format requirements make sure that the resulting format is an integer again */ /* The D3D format requirements make sure that the resulting format is an integer again */
size *= format->height_scale.numerator; *slice_pitch *= format->height_scale.numerator;
size /= format->height_scale.denominator; *slice_pitch /= format->height_scale.denominator;
} }
size *= depth; TRACE("Returning row pitch %u, slice pitch %u.\n", *row_pitch, *slice_pitch);
}
return size; UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment,
UINT width, UINT height, UINT depth)
{
unsigned int row_pitch, slice_pitch;
if (format->id == WINED3DFMT_UNKNOWN)
return 0;
wined3d_format_calculate_pitch(format, alignment, width, height, &row_pitch, &slice_pitch);
return slice_pitch * depth;
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -42,26 +42,8 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume) ...@@ -42,26 +42,8 @@ BOOL volume_prepare_system_memory(struct wined3d_volume *volume)
void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch) void wined3d_volume_get_pitch(const struct wined3d_volume *volume, UINT *row_pitch, UINT *slice_pitch)
{ {
const struct wined3d_format *format = volume->resource.format; wined3d_format_calculate_pitch(volume->resource.format, volume->resource.device->surface_alignment,
volume->resource.width, volume->resource.height, row_pitch, slice_pitch);
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 /* This call just uploads data, the caller is responsible for binding the
......
...@@ -3347,7 +3347,8 @@ struct wined3d_format ...@@ -3347,7 +3347,8 @@ struct wined3d_format
const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info, const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
enum wined3d_format_id format_id) DECLSPEC_HIDDEN; enum wined3d_format_id format_id) DECLSPEC_HIDDEN;
UINT wined3d_format_calculate_pitch(const struct wined3d_format *format, UINT width) DECLSPEC_HIDDEN; void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment,
unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN;
UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT wined3d_format_calculate_size(const struct wined3d_format *format,
UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN; UINT alignment, UINT width, UINT height, UINT depth) DECLSPEC_HIDDEN;
DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment