wined3d: Add format conversions for some depth stencil formats.

Although these formats aren't lockable, we still explicitly set the initial
surface data when creating the texture. Unfortunately that means we'll need
the conversion functions, even though all they'll ever convert will be zeroes.
This commit is contained in:
Henri Verbeet 2009-06-16 09:38:25 +02:00 committed by Alexandre Julliard
parent 7dd5cc8749
commit 23231d5a62
2 changed files with 105 additions and 0 deletions

View File

@ -1975,6 +1975,29 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*target_bpp = 12;
break;
case WINED3DFMT_D15S1:
if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
{
*convert = CONVERT_D15S1;
*target_bpp = 4;
}
break;
case WINED3DFMT_D24X4S4:
if (GL_SUPPORT(EXT_PACKED_DEPTH_STENCIL))
{
*convert = CONVERT_D24X4S4;
}
break;
case WINED3DFMT_D24FS8:
if (GL_SUPPORT(ARB_DEPTH_BUFFER_FLOAT))
{
*convert = CONVERT_D24FS8;
*target_bpp = 8;
}
break;
default:
break;
}
@ -2427,6 +2450,63 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
break;
}
case CONVERT_D15S1:
{
unsigned int x, y;
for (y = 0; y < height; ++y)
{
const WORD *source = (const WORD *)(src + y * pitch);
DWORD *dest = (DWORD *)(dst + y * outpitch);
for (x = 0; x < width; ++x)
{
/* The depth data is normalized, so needs to be scaled, the stencil data isn't. */
WORD d15 = source[x] & 0xfffe;
DWORD d24 = d15 * 0x100 + (d15 * 0xff80 + 0x3fff80) / 0x7fff00;
dest[x] = (d24 << 8) | (source[x] & 0x1);
}
}
break;
}
case CONVERT_D24X4S4:
{
unsigned int x, y;
for (y = 0; y < height; ++y)
{
const DWORD *source = (const DWORD *)(src + y * pitch);
DWORD *dest = (DWORD *)(dst + y * outpitch);
for (x = 0; x < width; ++x)
{
/* Just need to clear out the X4 part. */
dest[x] = source[x] & ~0xf0;
}
}
break;
}
case CONVERT_D24FS8:
{
unsigned int x, y;
for (y = 0; y < height; ++y)
{
const DWORD *source = (const DWORD *)(src + y * pitch);
float *dest_f = (float *)(dst + y * outpitch);
DWORD *dest_s = (DWORD *)(dst + y * outpitch);
for (x = 0; x < width; ++x)
{
dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
dest_s[x * 2 + 1] = source[x] & 0xff;
}
}
break;
}
default:
ERR("Unsupported conversation type %d\n", convert);
}

View File

@ -205,6 +205,28 @@ static inline float float_16_to_32(const unsigned short *in) {
}
}
static inline float float_24_to_32(DWORD in)
{
const float sgn = in & 0x800000 ? -1.0f : 1.0f;
const unsigned short e = (in & 0x780000) >> 19;
const unsigned short m = in & 0x7ffff;
if (e == 0)
{
if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
else return sgn * pow(2, -6.0f) * ((float)m / 524288.0f);
}
else if (e < 15)
{
return sgn * pow(2, (float)e - 7.0f) * (1.0f + ((float)m / 524288.0f));
}
else
{
if (m == 0) return sgn / 0.0; /* +INF / -INF */
else return 0.0 / 0.0; /* NAN */
}
}
/**
* Settings
*/
@ -2053,6 +2075,9 @@ typedef enum {
CONVERT_G16R16,
CONVERT_R16G16F,
CONVERT_R32G32F,
CONVERT_D15S1,
CONVERT_D24X4S4,
CONVERT_D24FS8,
} CONVERT_TYPES;
HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode);