ddraw: Convert dwZBufferBitDepth into a DDPIXELFORMAT.

This commit is contained in:
Stefan Dösinger 2011-08-30 12:45:41 +02:00 committed by Alexandre Julliard
parent c42277883a
commit 42b7ad4fd4
3 changed files with 195 additions and 30 deletions

View File

@ -3074,31 +3074,7 @@ static HRESULT CreateSurface(IDirectDrawImpl *ddraw, DDSURFACEDESC2 *DDSD,
desc2.dwFlags |= DDSD_PIXELFORMAT;
desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT);
/* Wait: It could be a Z buffer */
if(desc2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER)
{
switch(desc2.u2.dwMipMapCount) /* Who had this glorious idea? */
{
case 15:
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_S1_UINT_D15_UNORM);
break;
case 16:
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D16_UNORM);
break;
case 24:
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_X8D24_UNORM);
break;
case 32:
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D32_UNORM);
break;
default:
ERR("Unknown Z buffer bit depth\n");
}
}
else
{
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, Mode.Format);
}
PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, Mode.Format);
}
/* No Width or no Height? Use the original screen size

View File

@ -3845,6 +3845,188 @@ static void no_ddsd_caps_test(void)
ok(hr == DDERR_INVALIDCAPS, "IDirectDraw_CreateSurface returned %#x, expected DDERR_INVALIDCAPS.\n", hr);
}
static void dump_format(const DDPIXELFORMAT *fmt)
{
trace("dwFlags %08x, FourCC %08x, dwZBufferBitDepth %u, stencil %u\n", fmt->dwFlags, fmt->dwFourCC,
fmt->dwZBufferBitDepth, fmt->dwStencilBitDepth);
trace("dwZBitMask %08x, dwStencilBitMask %08x, dwRGBZBitMask %08x\n", fmt->dwZBitMask,
fmt->dwStencilBitMask, fmt->dwRGBZBitMask);
}
static void zbufferbitdepth_test(void)
{
enum zfmt_succeed
{
ZFMT_SUPPORTED_ALWAYS,
ZFMT_SUPPORTED_NEVER,
ZFMT_SUPPORTED_HWDEPENDENT
};
struct
{
DWORD depth;
enum zfmt_succeed supported;
DDPIXELFORMAT pf;
}
test_data[] =
{
{
16, ZFMT_SUPPORTED_ALWAYS,
{
sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
{16}, {0}, {0x0000ffff}, {0x00000000}, {0x00000000}
}
},
{
24, ZFMT_SUPPORTED_ALWAYS,
{
sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
{24}, {0}, {0x00ffffff}, {0x00000000}, {0x00000000}
}
},
{
32, ZFMT_SUPPORTED_HWDEPENDENT,
{
sizeof(DDPIXELFORMAT), DDPF_ZBUFFER, 0,
{32}, {0}, {0xffffffff}, {0x00000000}, {0x00000000}
}
},
/* Returns DDERR_INVALIDPARAMS instead of DDERR_INVALIDPIXELFORMAT.
* Disabled for now
{
0, ZFMT_SUPPORTED_NEVER
},
*/
{
15, ZFMT_SUPPORTED_NEVER
},
{
28, ZFMT_SUPPORTED_NEVER
},
{
40, ZFMT_SUPPORTED_NEVER
},
};
DDSURFACEDESC ddsd;
IDirectDrawSurface *surface;
HRESULT hr;
unsigned int i;
DDCAPS caps;
memset(&caps, 0, sizeof(caps));
caps.dwSize = sizeof(caps);
hr = IDirectDraw_GetCaps(lpDD, &caps, NULL);
ok(SUCCEEDED(hr), "IDirectDraw_GetCaps failed, hr %#x.\n", hr);
if (!(caps.ddsCaps.dwCaps & DDSCAPS_ZBUFFER))
{
skip("Z buffers not supported, skipping DDSD_ZBUFFERBITDEPTH test\n");
return;
}
for (i = 0; i < (sizeof(test_data) / sizeof(*test_data)); i++)
{
reset_ddsd(&ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 256;
ddsd.dwHeight = 256;
ddsd.dwZBufferBitDepth = test_data[i].depth;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
if (test_data[i].supported == ZFMT_SUPPORTED_ALWAYS)
{
ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
}
else if (test_data[i].supported == ZFMT_SUPPORTED_NEVER)
{
ok(hr == DDERR_INVALIDPIXELFORMAT, "IDirectDraw_CreateSurface returned %#x, expected %x.\n",
hr, DDERR_INVALIDPIXELFORMAT);
}
if (!surface) continue;
reset_ddsd(&ddsd);
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
todo_wine ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
/* Yet the ddpfPixelFormat member contains valid data */
if (memcmp(&ddsd.ddpfPixelFormat, &test_data[i].pf, ddsd.ddpfPixelFormat.dwSize))
{
ok(0, "Unexpected format for depth %u\n", test_data[i].depth);
dump_format(&ddsd.ddpfPixelFormat);
}
}
/* DDSD_ZBUFFERBITDEPTH vs DDSD_PIXELFORMAT? */
reset_ddsd(&ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_ZBUFFERBITDEPTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 256;
ddsd.dwHeight = 256;
ddsd.dwZBufferBitDepth = 24;
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
ddsd.ddpfPixelFormat.dwZBufferBitDepth = 16;
ddsd.ddpfPixelFormat.dwZBitMask = 0x0000ffff;
surface = NULL;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
if (!surface) return;
reset_ddsd(&ddsd);
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
ok(ddsd.ddpfPixelFormat.dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
ddsd.ddpfPixelFormat.dwZBufferBitDepth);
ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
todo_wine ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
todo_wine ok(ddsd.dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
ddsd.dwZBufferBitDepth);
/* DDSD_PIXELFORMAT vs invalid ZBUFFERBITDEPTH */
reset_ddsd(&ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 256;
ddsd.dwHeight = 256;
ddsd.dwZBufferBitDepth = 40;
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
ddsd.ddpfPixelFormat.dwZBufferBitDepth = 16;
ddsd.ddpfPixelFormat.dwZBitMask = 0x0000ffff;
surface = NULL;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
ok(SUCCEEDED(hr), "IDirectDraw_CreateSurface failed, hr %#x.\n", hr);
if (surface) IDirectDrawSurface_Release(surface);
/* Create a PIXELFORMAT-only surface, see if ZBUFFERBITDEPTH is set */
reset_ddsd(&ddsd);
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 256;
ddsd.dwHeight = 256;
ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
ddsd.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
ddsd.ddpfPixelFormat.dwZBufferBitDepth = 16;
ddsd.ddpfPixelFormat.dwZBitMask = 0x0000ffff;
surface = NULL;
hr = IDirectDraw_CreateSurface(lpDD, &ddsd, &surface, NULL);
ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
reset_ddsd(&ddsd);
hr = IDirectDrawSurface_GetSurfaceDesc(surface, &ddsd);
ok(SUCCEEDED(hr), "IDirectDrawSurface_GetSurfaceDesc failed, hr %#x.\n", hr);
IDirectDrawSurface_Release(surface);
ok(ddsd.ddpfPixelFormat.dwZBufferBitDepth == 16, "Expected a 16bpp depth buffer, got %ubpp\n",
ddsd.ddpfPixelFormat.dwZBufferBitDepth);
todo_wine ok(ddsd.dwFlags & DDSD_ZBUFFERBITDEPTH, "DDSD_ZBUFFERBITDEPTH is not set\n");
todo_wine ok(!(ddsd.dwFlags & DDSD_PIXELFORMAT), "DDSD_PIXELFORMAT is set\n");
todo_wine ok(ddsd.dwZBufferBitDepth == 16, "Expected dwZBufferBitDepth=16, got %u\n",
ddsd.dwZBufferBitDepth);
}
START_TEST(dsurface)
{
HRESULT ret;
@ -3902,5 +4084,6 @@ START_TEST(dsurface)
BackBufferAttachmentFlipTest();
CreateSurfaceBadCapsSizeTest();
no_ddsd_caps_test();
zbufferbitdepth_test();
ReleaseDirectDraw();
}

View File

@ -1196,15 +1196,21 @@ void DDSD_to_DDSD2(const DDSURFACEDESC *in, DDSURFACEDESC2 *out)
if (in->dwFlags & DDSD_WIDTH) out->dwWidth = in->dwWidth;
if (in->dwFlags & DDSD_HEIGHT) out->dwHeight = in->dwHeight;
if (in->dwFlags & DDSD_PIXELFORMAT) out->u4.ddpfPixelFormat = in->ddpfPixelFormat;
else if(in->dwFlags & DDSD_ZBUFFERBITDEPTH)
{
out->dwFlags |= DDSD_PIXELFORMAT;
memset(&out->u4.ddpfPixelFormat, 0, sizeof(out->u4.ddpfPixelFormat));
out->u4.ddpfPixelFormat.dwSize = sizeof(out->u4.ddpfPixelFormat);
out->u4.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER;
out->u4.ddpfPixelFormat.u1.dwZBufferBitDepth = in->u2.dwZBufferBitDepth;
/* 0 is not a valid DDSURFACEDESC / DDPIXELFORMAT on either side of the
* conversion */
out->u4.ddpfPixelFormat.u3.dwZBitMask = ~0U >> (32 - in->u2.dwZBufferBitDepth);
}
/* ddsCaps is read even without DDSD_CAPS set. See dsurface:no_ddsd_caps_test */
out->ddsCaps.dwCaps = in->ddsCaps.dwCaps;
if (in->dwFlags & DDSD_PITCH) out->u1.lPitch = in->u1.lPitch;
if (in->dwFlags & DDSD_BACKBUFFERCOUNT) out->dwBackBufferCount = in->dwBackBufferCount;
if (in->dwFlags & DDSD_ZBUFFERBITDEPTH)
{
/* FIXME: Convert into a DDPIXELFORMAT */
out->u2.dwMipMapCount = in->u2.dwZBufferBitDepth; /* same union */
}
if (in->dwFlags & DDSD_ALPHABITDEPTH) out->dwAlphaBitDepth = in->dwAlphaBitDepth;
/* DDraw(native, and wine) does not set the DDSD_LPSURFACE, so always copy */
out->lpSurface = in->lpSurface;