wined3d: Make format conversion functions work on volumes.

This commit is contained in:
Stefan Dösinger 2013-09-23 13:29:13 +02:00 committed by Alexandre Julliard
parent bb172d2a38
commit 5e89689bcd
4 changed files with 225 additions and 181 deletions

View File

@ -5524,7 +5524,8 @@ static HRESULT surface_load_texture(struct wined3d_surface *surface,
context_release(context);
return E_OUTOFMEMORY;
}
format.convert(surface->resource.allocatedMemory, mem, src_pitch, dst_pitch, width, height);
format.convert(surface->resource.allocatedMemory, mem, src_pitch, src_pitch * height,
dst_pitch, dst_pitch * height, width, height, 1);
format.byte_count = format.conv_byte_count;
src_pitch = dst_pitch;
}

View File

@ -253,24 +253,29 @@ struct wined3d_format_texture_info
unsigned int conv_byte_count;
unsigned int flags;
enum wined3d_gl_extension extension;
void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT dst_pitch, UINT width, UINT height);
void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
};
static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
/* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
* format+type combination to load it. Thus convert it to A8L8, then load it
* with A4L4 internal, but A8L8 format+type
*/
unsigned int x, y;
unsigned int x, y, z;
const unsigned char *Source;
unsigned char *Dest;
for(y = 0; y < height; y++) {
Source = src + y * pitch;
Dest = dst + y * dst_pitch;
for (x = 0; x < width; x++ ) {
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = src + z * src_slice_pitch + y * src_row_pitch;
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
unsigned char color = (*Source++);
/* A */ Dest[1] = (color & 0xf0) << 0;
/* L */ Dest[0] = (color & 0x0f) << 4;
@ -278,17 +283,20 @@ static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const WORD *Source;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
unsigned short *Dest_s = (unsigned short *) (dst + y * dst_pitch);
Source = (const WORD *)(src + y * pitch);
unsigned short *Dest_s = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
for (x = 0; x < width; x++ )
{
short color = (*Source++);
@ -303,11 +311,12 @@ static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const WORD *Source;
unsigned char *Dest;
@ -315,10 +324,14 @@ static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitc
* fixed function and shaders without further conversion once the surface is
* loaded
*/
for(y = 0; y < height; y++) {
Source = (const WORD *)(src + y * pitch);
Dest = dst + y * dst_pitch;
for (x = 0; x < width; x++ ) {
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
short color = (*Source++);
unsigned char l = ((color >> 10) & 0xfc);
char v = ((color >> 5) & 0x3e);
@ -339,18 +352,21 @@ static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitc
}
}
}
}
static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const short *Source;
unsigned char *Dest;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const short *)(src + y * pitch);
Dest = dst + y * dst_pitch;
Source = (const short *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
const short color = (*Source++);
@ -361,11 +377,12 @@ static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const DWORD *Source;
unsigned char *Dest;
@ -373,10 +390,12 @@ static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch
* shaders if the shader is adjusted. (There's no use for this format in gl's
* standard fixed function pipeline anyway).
*/
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const DWORD *)(src + y * pitch);
Dest = dst + y * dst_pitch;
Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
LONG color = (*Source++);
@ -387,21 +406,24 @@ static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch
}
}
}
}
static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const DWORD *Source;
unsigned char *Dest;
/* This implementation works with the fixed function pipeline and shaders
* without further modification after converting the surface.
*/
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const DWORD *)(src + y * pitch);
Dest = dst + y * dst_pitch;
Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
LONG color = (*Source++);
@ -413,18 +435,21 @@ static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pi
}
}
}
}
static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const DWORD *Source;
unsigned char *Dest;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const DWORD *)(src + y * pitch);
Dest = dst + y * dst_pitch;
Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = dst + z * dst_slice_pitch + y * dst_row_pitch;
for (x = 0; x < width; x++ )
{
LONG color = (*Source++);
@ -436,18 +461,21 @@ static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const DWORD *Source;
unsigned short *Dest;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const DWORD *)(src + y * pitch);
Dest = (unsigned short *) (dst + y * dst_pitch);
Source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = (unsigned short *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
for (x = 0; x < width; x++ )
{
const DWORD color = (*Source++);
@ -458,18 +486,21 @@ static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r16g16(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const WORD *Source;
WORD *Dest;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const WORD *)(src + y * pitch);
Dest = (WORD *) (dst + y * dst_pitch);
Source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = (WORD *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
for (x = 0; x < width; x++ )
{
WORD green = (*Source++);
@ -477,25 +508,27 @@ static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch,
Dest[0] = green;
Dest[1] = red;
/* Strictly speaking not correct for R16G16F, but it doesn't matter because the
* shader overwrites it anyway
*/
* shader overwrites it anyway */
Dest[2] = 0xffff;
Dest += 3;
}
}
}
}
static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
const float *Source;
float *Dest;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; y++)
{
Source = (const float *)(src + y * pitch);
Dest = (float *) (dst + y * dst_pitch);
Source = (const float *)(src + z * src_slice_pitch + y * src_row_pitch);
Dest = (float *) (dst + z * dst_slice_pitch + y * dst_row_pitch);
for (x = 0; x < width; x++ )
{
float green = (*Source++);
@ -507,16 +540,19 @@ static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; ++y)
{
const WORD *source = (const WORD *)(src + y * pitch);
DWORD *dest = (DWORD *)(dst + y * dst_pitch);
const WORD *source = (const WORD *)(src + z * src_slice_pitch + y * src_row_pitch);
DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
for (x = 0; x < width; ++x)
{
@ -529,16 +565,19 @@ static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; ++y)
{
const DWORD *source = (const DWORD *)(src + y * pitch);
DWORD *dest = (DWORD *)(dst + y * dst_pitch);
const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
DWORD *dest = (DWORD *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
for (x = 0; x < width; ++x)
{
@ -547,17 +586,20 @@ static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch,
UINT dst_pitch, UINT width, UINT height)
static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
{
unsigned int x, y;
unsigned int x, y, z;
for (z = 0; z < depth; z++)
{
for (y = 0; y < height; ++y)
{
const DWORD *source = (const DWORD *)(src + y * pitch);
float *dest_f = (float *)(dst + y * dst_pitch);
DWORD *dest_s = (DWORD *)(dst + y * dst_pitch);
const DWORD *source = (const DWORD *)(src + z * src_slice_pitch + y * src_row_pitch);
float *dest_f = (float *)(dst + z * dst_slice_pitch + y * dst_row_pitch);
DWORD *dest_s = (DWORD *)dest_f;
for (x = 0; x < width; ++x)
{
@ -566,6 +608,7 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch,
}
}
}
}
/* The following formats explicitly don't have WINED3DFMT_FLAG_TEXTURE set:
*

View File

@ -104,7 +104,7 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
const struct wined3d_format *format = volume->resource.format;
UINT width = volume->resource.width;
UINT height = volume->resource.height;
UINT depth = volume->resource.depth, z;
UINT depth = volume->resource.depth;
BYTE *mem = data->addr;
TRACE("volume %p, context %p, level %u, format %s (%#x).\n",
@ -129,9 +129,8 @@ void wined3d_volume_upload_data(struct wined3d_volume *volume, const struct wine
wined3d_volume_get_pitch(volume, &src_row_pitch, &src_slice_pitch);
mem = HeapAlloc(GetProcessHeap(), 0, dst_slice_pitch * depth);
for (z = 0; z < depth; z++)
format->convert(data->addr + z * src_slice_pitch, mem + z * dst_slice_pitch,
src_row_pitch, dst_row_pitch, width, height);
format->convert(data->addr, mem, src_row_pitch, src_slice_pitch,
dst_row_pitch, dst_slice_pitch, width, height, depth);
}
if (data->buffer_object)

View File

@ -2970,7 +2970,8 @@ struct wined3d_format
unsigned int flags;
struct wined3d_rational height_scale;
struct color_fixup_desc color_fixup;
void (*convert)(const BYTE *src, BYTE *dst, UINT src_pitch, UINT dst_pitch, UINT width, UINT height);
void (*convert)(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth);
};
const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,