ddraw: Properly support creating compressed user memory surfaces.

This commit is contained in:
Henri Verbeet 2014-06-12 11:52:31 +02:00 committed by Alexandre Julliard
parent e2d9cb69ba
commit b0f1feb4f0
4 changed files with 277 additions and 49 deletions

View File

@ -575,6 +575,13 @@ void DDSD2_to_DDSD(const DDSURFACEDESC2 *in, DDSURFACEDESC *out) DECLSPEC_HIDDEN
void multiply_matrix(D3DMATRIX *dst, const D3DMATRIX *src1, const D3DMATRIX *src2) DECLSPEC_HIDDEN; void multiply_matrix(D3DMATRIX *dst, const D3DMATRIX *src1, const D3DMATRIX *src2) DECLSPEC_HIDDEN;
static inline BOOL format_is_compressed(const DDPIXELFORMAT *format)
{
return (format->dwFlags & DDPF_FOURCC) && (format->dwFourCC == WINED3DFMT_DXT1
|| format->dwFourCC == WINED3DFMT_DXT2 || format->dwFourCC == WINED3DFMT_DXT3
|| format->dwFourCC == WINED3DFMT_DXT4 || format->dwFourCC == WINED3DFMT_DXT5);
}
static inline BOOL format_is_paletteindexed(const DDPIXELFORMAT *fmt) static inline BOOL format_is_paletteindexed(const DDPIXELFORMAT *fmt)
{ {
DWORD flags = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 DWORD flags = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4

View File

@ -5886,11 +5886,30 @@ HRESULT ddraw_surface_create(struct ddraw *ddraw, const DDSURFACEDESC2 *surface_
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
} }
if (!(desc->dwFlags & DDSD_PITCH)) if (format_is_compressed(&desc->u4.ddpfPixelFormat))
{ {
WARN("User memory surfaces should explicitly specify the pitch.\n"); if (version != 4 && (desc->dwFlags & DDSD_PITCH))
HeapFree(GetProcessHeap(), 0, texture); {
return DDERR_INVALIDPARAMS; WARN("Pitch specified on a compressed user memory surface.\n");
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
if (!(desc->dwFlags & (DDSD_LINEARSIZE | DDSD_PITCH)))
{
WARN("Compressed user memory surfaces should explicitly specify the linear size.\n");
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
}
else
{
if (!(desc->dwFlags & DDSD_PITCH))
{
WARN("User memory surfaces should explicitly specify the pitch.\n");
HeapFree(GetProcessHeap(), 0, texture);
return DDERR_INVALIDPARAMS;
}
} }
} }
@ -6112,41 +6131,63 @@ HRESULT ddraw_surface_init(struct ddraw_surface *surface, struct ddraw *ddraw, s
desc->dwHeight = wined3d_desc.height; desc->dwHeight = wined3d_desc.height;
surface->first_attached = surface; surface->first_attached = surface;
/* Anno 1602 stores the pitch right after surface creation, so make sure if (format_is_compressed(&desc->u4.ddpfPixelFormat))
* it's there. TODO: Test other fourcc formats. */
if (wined3d_desc.format == WINED3DFMT_DXT1 || wined3d_desc.format == WINED3DFMT_DXT2
|| wined3d_desc.format == WINED3DFMT_DXT3 || wined3d_desc.format == WINED3DFMT_DXT4
|| wined3d_desc.format == WINED3DFMT_DXT5)
{ {
desc->dwFlags |= DDSD_LINEARSIZE; if (desc->dwFlags & DDSD_LPSURFACE)
desc->dwFlags &= ~DDSD_PITCH;
desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
}
else if (!(desc->dwFlags & DDSD_LPSURFACE))
{
desc->dwFlags |= DDSD_PITCH;
desc->dwFlags &= ~DDSD_LINEARSIZE;
desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
}
if (desc->dwFlags & DDSD_LPSURFACE)
{
if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
{ {
WARN("Invalid pitch %u specified.\n", desc->u1.lPitch); if ((desc->dwFlags & DDSD_LINEARSIZE)
return DDERR_INVALIDPARAMS; && desc->u1.dwLinearSize < wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4))
} {
WARN("Invalid linear size %u specified.\n", desc->u1.dwLinearSize);
return DDERR_INVALIDPARAMS;
}
if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width, if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0, wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
desc->lpSurface, desc->u1.lPitch))) desc->lpSurface, 0)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
return hr;
}
desc->dwFlags |= DDSD_LINEARSIZE;
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_PITCH);
desc->u1.dwLinearSize = ~0u;
}
else
{ {
ERR("Failed to set surface memory, hr %#x.\n", hr); desc->dwFlags |= DDSD_LINEARSIZE;
return hr; desc->dwFlags &= ~DDSD_PITCH;
desc->u1.dwLinearSize = wined3d_surface_get_pitch(wined3d_surface) * ((desc->dwHeight + 3) / 4);
} }
}
else
{
if (desc->dwFlags & DDSD_LPSURFACE)
{
if (desc->u1.lPitch < wined3d_calculate_format_pitch(ddraw->wined3d, WINED3DADAPTER_DEFAULT,
wined3d_desc.format, wined3d_desc.width) || desc->u1.lPitch & 3)
{
WARN("Invalid pitch %u specified.\n", desc->u1.lPitch);
return DDERR_INVALIDPARAMS;
}
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE); if (FAILED(hr = wined3d_surface_update_desc(wined3d_surface, wined3d_desc.width,
wined3d_desc.height, wined3d_desc.format, WINED3D_MULTISAMPLE_NONE, 0,
desc->lpSurface, desc->u1.lPitch)))
{
ERR("Failed to set surface memory, hr %#x.\n", hr);
return hr;
}
desc->dwFlags &= ~(DDSD_LPSURFACE | DDSD_LINEARSIZE);
}
else
{
desc->dwFlags |= DDSD_PITCH;
desc->dwFlags &= ~DDSD_LINEARSIZE;
desc->u1.lPitch = wined3d_surface_get_pitch(wined3d_surface);
}
} }
wined3d_surface_incref(wined3d_surface); wined3d_surface_incref(wined3d_surface);

View File

@ -4107,6 +4107,7 @@ static void test_block_formats_creation(void)
DWORD num_fourcc_codes = 0, *fourcc_codes; DWORD num_fourcc_codes = 0, *fourcc_codes;
DDSURFACEDESC2 ddsd; DDSURFACEDESC2 ddsd;
DDCAPS hal_caps; DDCAPS hal_caps;
void *mem;
static const struct static const struct
{ {
@ -4115,19 +4116,20 @@ static void test_block_formats_creation(void)
DWORD support_flag; DWORD support_flag;
unsigned int block_width; unsigned int block_width;
unsigned int block_height; unsigned int block_height;
unsigned int block_size;
BOOL create_size_checked, overlay; BOOL create_size_checked, overlay;
} }
formats[] = formats[] =
{ {
{MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, 8, TRUE, FALSE},
{MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, FALSE, TRUE }, {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, 4, FALSE, TRUE },
{MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, FALSE, TRUE }, {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, 4, FALSE, TRUE },
}; };
const struct static const struct
{ {
DWORD caps, caps2; DWORD caps, caps2;
const char *name; const char *name;
@ -4158,6 +4160,36 @@ static void test_block_formats_creation(void)
"managed texture", FALSE "managed texture", FALSE
} }
}; };
enum size_type
{
SIZE_TYPE_ZERO,
SIZE_TYPE_PITCH,
SIZE_TYPE_SIZE,
};
static const struct
{
DWORD flags;
enum size_type size_type;
int rel_size;
HRESULT hr;
}
user_mem_tests[] =
{
{DDSD_LINEARSIZE, SIZE_TYPE_ZERO, 0, DD_OK},
{DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DD_OK},
{DDSD_PITCH, SIZE_TYPE_ZERO, 0, DD_OK},
{DDSD_PITCH, SIZE_TYPE_PITCH, 0, DD_OK},
{DDSD_LPSURFACE, SIZE_TYPE_ZERO, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_ZERO, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_PITCH, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DD_OK},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 1, DD_OK},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, -1, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_ZERO, 0, DD_OK},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_PITCH, 0, DD_OK},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_SIZE, 0, DD_OK},
{DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DD_OK},
};
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, 0, 0, 0, 0); 0, 0, 640, 480, 0, 0, 0, 0);
@ -4202,6 +4234,8 @@ static void test_block_formats_creation(void)
hr = IDirectDraw4_GetCaps(ddraw, &hal_caps, NULL); hr = IDirectDraw4_GetCaps(ddraw, &hal_caps, NULL);
ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * 2 * 16 + 1);
for (i = 0; i < sizeof(formats) / sizeof(*formats); i++) for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
{ {
for (j = 0; j < sizeof(types) / sizeof(*types); j++) for (j = 0; j < sizeof(types) / sizeof(*types); j++)
@ -4268,8 +4302,64 @@ static void test_block_formats_creation(void)
} }
} }
} }
if (formats[i].overlay)
continue;
for (j = 0; j < sizeof(user_mem_tests) / sizeof(*user_mem_tests); ++j)
{
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | user_mem_tests[j].flags;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE;
switch (user_mem_tests[j].size_type)
{
case SIZE_TYPE_ZERO:
U1(ddsd).dwLinearSize = 0;
break;
case SIZE_TYPE_PITCH:
U1(ddsd).dwLinearSize = 2 * formats[i].block_size;
break;
case SIZE_TYPE_SIZE:
U1(ddsd).dwLinearSize = 2 * 2 * formats[i].block_size;
break;
}
U1(ddsd).dwLinearSize += user_mem_tests[j].rel_size;
ddsd.lpSurface = mem;
U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
ddsd.dwWidth = 8;
ddsd.dwHeight = 8;
hr = IDirectDraw4_CreateSurface(ddraw, &ddsd, &surface, NULL);
ok(hr == user_mem_tests[j].hr, "Test %u: Got unexpected hr %#x, format %s.\n", j, hr, formats[i].name);
if (FAILED(hr))
continue;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
hr = IDirectDrawSurface4_GetSurfaceDesc(surface, &ddsd);
ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", j, hr);
ok(ddsd.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LINEARSIZE),
"Test %u: Got unexpected flags %#x.\n", j, ddsd.dwFlags);
if (user_mem_tests[j].flags & DDSD_LPSURFACE)
ok(U1(ddsd).dwLinearSize == ~0u, "Test %u: Got unexpected linear size %#x.\n",
j, U1(ddsd).dwLinearSize);
else
ok(U1(ddsd).dwLinearSize == 2 * 2 * formats[i].block_size,
"Test %u: Got unexpected linear size %#x, expected %#x.\n",
j, U1(ddsd).dwLinearSize, 2 * 2 * formats[i].block_size);
IDirectDrawSurface4_Release(surface);
}
} }
HeapFree(GetProcessHeap(), 0, mem);
cleanup: cleanup:
IDirectDraw4_Release(ddraw); IDirectDraw4_Release(ddraw);
IDirect3DDevice3_Release(device); IDirect3DDevice3_Release(device);

View File

@ -3876,6 +3876,7 @@ static void test_block_formats_creation(void)
DWORD num_fourcc_codes = 0, *fourcc_codes; DWORD num_fourcc_codes = 0, *fourcc_codes;
DDSURFACEDESC2 ddsd; DDSURFACEDESC2 ddsd;
DDCAPS hal_caps; DDCAPS hal_caps;
void *mem;
static const struct static const struct
{ {
@ -3884,19 +3885,20 @@ static void test_block_formats_creation(void)
DWORD support_flag; DWORD support_flag;
unsigned int block_width; unsigned int block_width;
unsigned int block_height; unsigned int block_height;
unsigned int block_size;
BOOL create_size_checked, overlay; BOOL create_size_checked, overlay;
} }
formats[] = formats[] =
{ {
{MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','1'), "D3DFMT_DXT1", SUPPORT_DXT1, 4, 4, 8, TRUE, FALSE},
{MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','2'), "D3DFMT_DXT2", SUPPORT_DXT2, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','3'), "D3DFMT_DXT3", SUPPORT_DXT3, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','4'), "D3DFMT_DXT4", SUPPORT_DXT4, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, TRUE, FALSE}, {MAKEFOURCC('D','X','T','5'), "D3DFMT_DXT5", SUPPORT_DXT5, 4, 4, 16, TRUE, FALSE},
{MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, FALSE, TRUE }, {MAKEFOURCC('Y','U','Y','2'), "D3DFMT_YUY2", SUPPORT_YUY2, 2, 1, 4, FALSE, TRUE },
{MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, FALSE, TRUE }, {MAKEFOURCC('U','Y','V','Y'), "D3DFMT_UYVY", SUPPORT_UYVY, 2, 1, 4, FALSE, TRUE },
}; };
const struct static const struct
{ {
DWORD caps, caps2; DWORD caps, caps2;
const char *name; const char *name;
@ -3927,6 +3929,36 @@ static void test_block_formats_creation(void)
"managed texture", FALSE "managed texture", FALSE
} }
}; };
enum size_type
{
SIZE_TYPE_ZERO,
SIZE_TYPE_PITCH,
SIZE_TYPE_SIZE,
};
static const struct
{
DWORD flags;
enum size_type size_type;
int rel_size;
HRESULT hr;
}
user_mem_tests[] =
{
{DDSD_LINEARSIZE, SIZE_TYPE_ZERO, 0, DD_OK},
{DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DD_OK},
{DDSD_PITCH, SIZE_TYPE_ZERO, 0, DD_OK},
{DDSD_PITCH, SIZE_TYPE_PITCH, 0, DD_OK},
{DDSD_LPSURFACE, SIZE_TYPE_ZERO, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_ZERO, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_PITCH, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DD_OK},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 1, DD_OK},
{DDSD_LPSURFACE | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, -1, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_ZERO, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_PITCH, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_PITCH, SIZE_TYPE_SIZE, 0, DDERR_INVALIDPARAMS},
{DDSD_LPSURFACE | DDSD_PITCH | DDSD_LINEARSIZE, SIZE_TYPE_SIZE, 0, DDERR_INVALIDPARAMS},
};
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
0, 0, 640, 480, 0, 0, 0, 0); 0, 0, 640, 480, 0, 0, 0, 0);
@ -3971,6 +4003,8 @@ static void test_block_formats_creation(void)
hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL); hr = IDirectDraw7_GetCaps(ddraw, &hal_caps, NULL);
ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr); ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
mem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 2 * 2 * 16 + 1);
for (i = 0; i < sizeof(formats) / sizeof(*formats); i++) for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
{ {
for (j = 0; j < sizeof(types) / sizeof(*types); j++) for (j = 0; j < sizeof(types) / sizeof(*types); j++)
@ -4037,8 +4071,64 @@ static void test_block_formats_creation(void)
} }
} }
} }
if (formats[i].overlay)
continue;
for (j = 0; j < sizeof(user_mem_tests) / sizeof(*user_mem_tests); ++j)
{
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | user_mem_tests[j].flags;
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_TEXTURE;
switch (user_mem_tests[j].size_type)
{
case SIZE_TYPE_ZERO:
U1(ddsd).dwLinearSize = 0;
break;
case SIZE_TYPE_PITCH:
U1(ddsd).dwLinearSize = 2 * formats[i].block_size;
break;
case SIZE_TYPE_SIZE:
U1(ddsd).dwLinearSize = 2 * 2 * formats[i].block_size;
break;
}
U1(ddsd).dwLinearSize += user_mem_tests[j].rel_size;
ddsd.lpSurface = mem;
U4(ddsd).ddpfPixelFormat.dwSize = sizeof(U4(ddsd).ddpfPixelFormat);
U4(ddsd).ddpfPixelFormat.dwFlags = DDPF_FOURCC;
U4(ddsd).ddpfPixelFormat.dwFourCC = formats[i].fourcc;
ddsd.dwWidth = 8;
ddsd.dwHeight = 8;
hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL);
ok(hr == user_mem_tests[j].hr, "Test %u: Got unexpected hr %#x, format %s.\n", j, hr, formats[i].name);
if (FAILED(hr))
continue;
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &ddsd);
ok(SUCCEEDED(hr), "Test %u: Failed to get surface desc, hr %#x.\n", j, hr);
ok(ddsd.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_LINEARSIZE),
"Test %u: Got unexpected flags %#x.\n", j, ddsd.dwFlags);
if (user_mem_tests[j].flags & DDSD_LPSURFACE)
ok(U1(ddsd).dwLinearSize == ~0u, "Test %u: Got unexpected linear size %#x.\n",
j, U1(ddsd).dwLinearSize);
else
ok(U1(ddsd).dwLinearSize == 2 * 2 * formats[i].block_size,
"Test %u: Got unexpected linear size %#x, expected %#x.\n",
j, U1(ddsd).dwLinearSize, 2 * 2 * formats[i].block_size);
IDirectDrawSurface7_Release(surface);
}
} }
HeapFree(GetProcessHeap(), 0, mem);
cleanup: cleanup:
IDirectDraw7_Release(ddraw); IDirectDraw7_Release(ddraw);
IDirect3DDevice7_Release(device); IDirect3DDevice7_Release(device);