Commit 23231d5a authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

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.
parent 7dd5cc87
...@@ -1975,6 +1975,29 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_ ...@@ -1975,6 +1975,29 @@ HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_
*target_bpp = 12; *target_bpp = 12;
break; 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: default:
break; break;
} }
...@@ -2427,6 +2450,63 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI ...@@ -2427,6 +2450,63 @@ static HRESULT d3dfmt_convert_surface(const BYTE *src, BYTE *dst, UINT pitch, UI
break; 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: default:
ERR("Unsupported conversation type %d\n", convert); ERR("Unsupported conversation type %d\n", convert);
} }
......
...@@ -205,6 +205,28 @@ static inline float float_16_to_32(const unsigned short *in) { ...@@ -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 * Settings
*/ */
...@@ -2053,6 +2075,9 @@ typedef enum { ...@@ -2053,6 +2075,9 @@ typedef enum {
CONVERT_G16R16, CONVERT_G16R16,
CONVERT_R16G16F, CONVERT_R16G16F,
CONVERT_R32G32F, CONVERT_R32G32F,
CONVERT_D15S1,
CONVERT_D24X4S4,
CONVERT_D24FS8,
} CONVERT_TYPES; } 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); 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);
......
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