wined3d: Allow setting user memory for mipmapped textures in wined3d_texture_update_desc().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49105 Signed-off-by: Paul Gofman <pgofman@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ac06731e49
commit
f02b0226ca
|
@ -7126,6 +7126,64 @@ static void test_set_surface_desc(void)
|
||||||
|
|
||||||
IDirectDrawSurface7_Release(surface);
|
IDirectDrawSurface7_Release(surface);
|
||||||
|
|
||||||
|
/* Test mipmap texture. */
|
||||||
|
reset_ddsd(&ddsd);
|
||||||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_MIPMAPCOUNT;
|
||||||
|
ddsd.dwWidth = 8;
|
||||||
|
ddsd.dwHeight = 8;
|
||||||
|
U2(ddsd).dwMipMapCount = 3;
|
||||||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
|
||||||
|
|
||||||
|
hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL);
|
||||||
|
ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWHW || hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
skip("Mipmaps are not supported.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Changing surface desc for mipmap fails even without changing any
|
||||||
|
* parameters. */
|
||||||
|
hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0);
|
||||||
|
ok(hr == DDERR_INVALIDSURFACETYPE, "Got unexpected hr %#x.\n", hr);
|
||||||
|
IDirectDrawSurface7_Release(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test surface created with DDSD_LPSURFACE. */
|
||||||
|
reset_ddsd(&ddsd);
|
||||||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_LPSURFACE | DDSD_PITCH;
|
||||||
|
ddsd.dwWidth = 8;
|
||||||
|
ddsd.dwHeight = 8;
|
||||||
|
ddsd.lpSurface = data;
|
||||||
|
U1(ddsd).lPitch = 8 * 4;
|
||||||
|
ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
|
||||||
|
hr = IDirectDraw7_CreateSurface(ddraw, &ddsd, &surface, NULL);
|
||||||
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0);
|
||||||
|
ok(hr == DDERR_INVALIDCAPS, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
reset_ddsd(&ddsd);
|
||||||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
|
||||||
|
ddsd.dwWidth = 8;
|
||||||
|
ddsd.dwHeight = 8;
|
||||||
|
/* Cannot reset lpSurface. */
|
||||||
|
hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0);
|
||||||
|
ok(hr == DDERR_INVALIDPARAMS, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
reset_ddsd(&ddsd);
|
||||||
|
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE | DDSD_PITCH;
|
||||||
|
ddsd.dwWidth = 4;
|
||||||
|
ddsd.dwHeight = 4;
|
||||||
|
ddsd.lpSurface = data;
|
||||||
|
U1(ddsd).lPitch = 8 * 4;
|
||||||
|
/* Can change the parameters of surface created with DDSD_LPSURFACE. */
|
||||||
|
hr = IDirectDrawSurface7_SetSurfaceDesc(surface, &ddsd, 0);
|
||||||
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
IDirectDrawSurface7_Release(surface);
|
||||||
|
|
||||||
/* SetSurfaceDesc needs systemmemory surfaces.
|
/* SetSurfaceDesc needs systemmemory surfaces.
|
||||||
*
|
*
|
||||||
* As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing
|
* As a sidenote, fourcc surfaces aren't allowed in sysmem, thus testing
|
||||||
|
@ -13347,14 +13405,14 @@ static void test_display_mode_surface_pixel_format(void)
|
||||||
|
|
||||||
surface_desc.dwSize = sizeof(surface_desc);
|
surface_desc.dwSize = sizeof(surface_desc);
|
||||||
hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc);
|
hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc);
|
||||||
ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
width = surface_desc.dwWidth;
|
width = surface_desc.dwWidth;
|
||||||
height = surface_desc.dwHeight;
|
height = surface_desc.dwHeight;
|
||||||
|
|
||||||
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
|
window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW,
|
||||||
0, 0, width, height, NULL, NULL, NULL, NULL);
|
0, 0, width, height, NULL, NULL, NULL, NULL);
|
||||||
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
|
||||||
ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
bpp = 0;
|
bpp = 0;
|
||||||
if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw, width, height, 16, 0, 0)))
|
if (SUCCEEDED(IDirectDraw7_SetDisplayMode(ddraw, width, height, 16, 0, 0)))
|
||||||
|
@ -13367,7 +13425,7 @@ static void test_display_mode_surface_pixel_format(void)
|
||||||
|
|
||||||
surface_desc.dwSize = sizeof(surface_desc);
|
surface_desc.dwSize = sizeof(surface_desc);
|
||||||
hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc);
|
hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc);
|
||||||
ok(SUCCEEDED(hr), "Failed to get display mode, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
ok(surface_desc.dwWidth == width, "Got width %u, expected %u.\n", surface_desc.dwWidth, width);
|
ok(surface_desc.dwWidth == width, "Got width %u, expected %u.\n", surface_desc.dwWidth, width);
|
||||||
ok(surface_desc.dwHeight == height, "Got height %u, expected %u.\n", surface_desc.dwHeight, height);
|
ok(surface_desc.dwHeight == height, "Got height %u, expected %u.\n", surface_desc.dwHeight, height);
|
||||||
ok(U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount == bpp, "Got bpp %u, expected %u.\n",
|
ok(U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount == bpp, "Got bpp %u, expected %u.\n",
|
||||||
|
@ -13379,9 +13437,9 @@ static void test_display_mode_surface_pixel_format(void)
|
||||||
U5(surface_desc).dwBackBufferCount = 1;
|
U5(surface_desc).dwBackBufferCount = 1;
|
||||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE;
|
surface_desc.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE;
|
||||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||||
ok(hr == D3D_OK, "Failed to create surface, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc);
|
hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc);
|
||||||
ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
ok(surface_desc.dwWidth == width, "Got width %u, expected %u.\n", surface_desc.dwWidth, width);
|
ok(surface_desc.dwWidth == width, "Got width %u, expected %u.\n", surface_desc.dwWidth, width);
|
||||||
ok(surface_desc.dwHeight == height, "Got height %u, expected %u.\n", surface_desc.dwHeight, height);
|
ok(surface_desc.dwHeight == height, "Got height %u, expected %u.\n", surface_desc.dwHeight, height);
|
||||||
ok(U4(surface_desc).ddpfPixelFormat.dwFlags == DDPF_RGB, "Got unexpected pixel format flags %#x.\n",
|
ok(U4(surface_desc).ddpfPixelFormat.dwFlags == DDPF_RGB, "Got unexpected pixel format flags %#x.\n",
|
||||||
|
@ -13397,15 +13455,39 @@ static void test_display_mode_surface_pixel_format(void)
|
||||||
surface_desc.dwHeight = height;
|
surface_desc.dwHeight = height;
|
||||||
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||||
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||||
ok(hr == D3D_OK, "Failed to create surface, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc);
|
hr = IDirectDrawSurface7_GetSurfaceDesc(surface, &surface_desc);
|
||||||
ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
|
ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr);
|
||||||
ok(U4(surface_desc).ddpfPixelFormat.dwFlags == DDPF_RGB, "Got unexpected pixel format flags %#x.\n",
|
ok(U4(surface_desc).ddpfPixelFormat.dwFlags == DDPF_RGB, "Got unexpected pixel format flags %#x.\n",
|
||||||
U4(surface_desc).ddpfPixelFormat.dwFlags);
|
U4(surface_desc).ddpfPixelFormat.dwFlags);
|
||||||
ok(U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount == bpp, "Got bpp %u, expected %u.\n",
|
ok(U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount == bpp, "Got bpp %u, expected %u.\n",
|
||||||
U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, bpp);
|
U1(U4(surface_desc).ddpfPixelFormat).dwRGBBitCount, bpp);
|
||||||
IDirectDrawSurface7_Release(surface);
|
IDirectDrawSurface7_Release(surface);
|
||||||
|
|
||||||
|
/* Test compatibility mode mipmap texture creation. */
|
||||||
|
hr = IDirectDraw7_SetDisplayMode(ddraw, width, height, 16, 0, 0);
|
||||||
|
ok(hr == DD_OK || hr == E_NOTIMPL, "Got unexpected hr %#x.\n", hr);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
win_skip("SetDisplayMode failed, skipping test.");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
bpp = 16;
|
||||||
|
|
||||||
|
memset(&surface_desc, 0, sizeof(surface_desc));
|
||||||
|
surface_desc.dwSize = sizeof(surface_desc);
|
||||||
|
surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_MIPMAPCOUNT | DDSD_PITCH;
|
||||||
|
U2(surface_desc).dwMipMapCount = 2;
|
||||||
|
surface_desc.dwWidth = 4;
|
||||||
|
surface_desc.dwHeight = 4;
|
||||||
|
U1(surface_desc).lPitch = surface_desc.dwWidth * bpp / 8;
|
||||||
|
surface_desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_COMPLEX | DDSCAPS_MIPMAP | DDSCAPS_VIDEOMEMORY;
|
||||||
|
hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL);
|
||||||
|
ok(hr == DD_OK || hr == DDERR_NODIRECTDRAWHW, "Got unexpected hr %#x.\n", hr);
|
||||||
|
if (surface)
|
||||||
|
IDirectDrawSurface7_Release(surface);
|
||||||
|
|
||||||
|
done:
|
||||||
refcount = IDirectDraw7_Release(ddraw);
|
refcount = IDirectDraw7_Release(ddraw);
|
||||||
ok(!refcount, "DirectDraw has %u references left.\n", refcount);
|
ok(!refcount, "DirectDraw has %u references left.\n", refcount);
|
||||||
DestroyWindow(window);
|
DestroyWindow(window);
|
||||||
|
|
|
@ -1748,11 +1748,13 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
||||||
const struct wined3d_d3d_info *d3d_info;
|
const struct wined3d_d3d_info *d3d_info;
|
||||||
const struct wined3d_gl_info *gl_info;
|
const struct wined3d_gl_info *gl_info;
|
||||||
const struct wined3d_format *format;
|
const struct wined3d_format *format;
|
||||||
const struct wined3d *d3d;
|
|
||||||
struct wined3d_device *device;
|
struct wined3d_device *device;
|
||||||
unsigned int resource_size;
|
unsigned int resource_size;
|
||||||
|
const struct wined3d *d3d;
|
||||||
|
unsigned int slice_pitch;
|
||||||
DWORD valid_location = 0;
|
DWORD valid_location = 0;
|
||||||
BOOL create_dib = FALSE;
|
bool update_memory_only;
|
||||||
|
bool create_dib = false;
|
||||||
|
|
||||||
TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
|
TRACE("texture %p, width %u, height %u, format %s, multisample_type %#x, multisample_quality %u, "
|
||||||
"mem %p, pitch %u.\n",
|
"mem %p, pitch %u.\n",
|
||||||
|
@ -1765,10 +1767,27 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
||||||
format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags);
|
format = wined3d_get_format(device->adapter, format_id, texture->resource.bind_flags);
|
||||||
resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
|
resource_size = wined3d_format_calculate_size(format, device->surface_alignment, width, height, 1);
|
||||||
|
|
||||||
|
update_memory_only = width == texture->resource.width && height == texture->resource.height
|
||||||
|
&& format_id == texture->resource.format->id && multisample_type == texture->resource.multisample_type
|
||||||
|
&& multisample_quality == texture->resource.multisample_quality;
|
||||||
|
|
||||||
|
if (pitch)
|
||||||
|
slice_pitch = height * pitch;
|
||||||
|
else
|
||||||
|
wined3d_format_calculate_pitch(format, 1, width, height, &pitch, &slice_pitch);
|
||||||
|
|
||||||
|
if (update_memory_only)
|
||||||
|
{
|
||||||
|
unsigned int current_row_pitch, current_slice_pitch;
|
||||||
|
|
||||||
|
wined3d_texture_get_pitch(texture, 0, ¤t_row_pitch, ¤t_slice_pitch);
|
||||||
|
update_memory_only = pitch == current_row_pitch && slice_pitch == current_slice_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
if (!resource_size)
|
if (!resource_size)
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
|
|
||||||
if (texture->level_count * texture->layer_count > 1)
|
if (texture->level_count * texture->layer_count > 1 && !update_memory_only)
|
||||||
{
|
{
|
||||||
WARN("Texture has multiple sub-resources, not supported.\n");
|
WARN("Texture has multiple sub-resources, not supported.\n");
|
||||||
return WINED3DERR_INVALIDCALL;
|
return WINED3DERR_INVALIDCALL;
|
||||||
|
@ -1803,24 +1822,23 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
||||||
wined3d_cs_emit_unload_resource(device->cs, &texture->resource);
|
wined3d_cs_emit_unload_resource(device->cs, &texture->resource);
|
||||||
wined3d_resource_wait_idle(&texture->resource);
|
wined3d_resource_wait_idle(&texture->resource);
|
||||||
|
|
||||||
sub_resource = &texture->sub_resources[0];
|
|
||||||
if (texture->dc_info && texture->dc_info[0].dc)
|
if (texture->dc_info && texture->dc_info[0].dc)
|
||||||
{
|
{
|
||||||
struct wined3d_texture_idx texture_idx = {texture, 0};
|
struct wined3d_texture_idx texture_idx = {texture, 0};
|
||||||
|
|
||||||
wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx);
|
wined3d_cs_destroy_object(device->cs, wined3d_texture_destroy_dc, &texture_idx);
|
||||||
wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
|
wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
|
||||||
create_dib = TRUE;
|
create_dib = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
wined3d_resource_free_sysmem(&texture->resource);
|
wined3d_resource_free_sysmem(&texture->resource);
|
||||||
|
|
||||||
if ((texture->row_pitch = pitch))
|
if (!update_memory_only)
|
||||||
texture->slice_pitch = height * pitch;
|
{
|
||||||
else
|
sub_resource = &texture->sub_resources[0];
|
||||||
/* User memory surfaces don't have the regular surface alignment. */
|
|
||||||
wined3d_format_calculate_pitch(format, 1, width, height,
|
texture->row_pitch = pitch;
|
||||||
&texture->row_pitch, &texture->slice_pitch);
|
texture->slice_pitch = slice_pitch;
|
||||||
|
|
||||||
texture->resource.format = format;
|
texture->resource.format = format;
|
||||||
texture->resource.multisample_type = multisample_type;
|
texture->resource.multisample_type = multisample_type;
|
||||||
|
@ -1863,6 +1881,7 @@ HRESULT CDECL wined3d_texture_update_desc(struct wined3d_texture *texture, UINT
|
||||||
texture->pow2_width = width;
|
texture->pow2_width = width;
|
||||||
texture->pow2_height = height;
|
texture->pow2_height = height;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((texture->user_memory = mem))
|
if ((texture->user_memory = mem))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue