dxgi/tests: Test presentation parameter combinations.
This commit is contained in:
parent
142bcb5d3c
commit
f805fb11f6
|
@ -190,9 +190,36 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
|
||||||
struct wined3d_swapchain_desc wined3d_desc;
|
struct wined3d_swapchain_desc wined3d_desc;
|
||||||
IWineDXGIDevice *dxgi_device;
|
IWineDXGIDevice *dxgi_device;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
UINT min_buffer_count;
|
||||||
|
|
||||||
FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain);
|
FIXME("iface %p, device %p, desc %p, swapchain %p partial stub!\n", iface, device, desc, swapchain);
|
||||||
|
|
||||||
|
switch (desc->SwapEffect)
|
||||||
|
{
|
||||||
|
case DXGI_SWAP_EFFECT_DISCARD:
|
||||||
|
case DXGI_SWAP_EFFECT_SEQUENTIAL:
|
||||||
|
min_buffer_count = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL:
|
||||||
|
min_buffer_count = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WARN("Invalid swap effect %u used, returning DXGI_ERROR_INVALID_CALL.\n", desc->SwapEffect);
|
||||||
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc->BufferCount < min_buffer_count || desc->BufferCount > 16)
|
||||||
|
{
|
||||||
|
WARN("BufferCount is %u, returning DXGI_ERROR_INVALID_CALL.\n", desc->BufferCount);
|
||||||
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
|
}
|
||||||
|
if (!desc->OutputWindow)
|
||||||
|
{
|
||||||
|
FIXME("No output window, should use factory output window\n");
|
||||||
|
}
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device);
|
hr = IUnknown_QueryInterface(device, &IID_IWineDXGIDevice, (void **)&dxgi_device);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
|
@ -200,11 +227,6 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_CreateSwapChain(IDXGIFactory1 *ifa
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!desc->OutputWindow)
|
|
||||||
{
|
|
||||||
FIXME("No output window, should use factory output window\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME("Ignoring SwapEffect and Flags\n");
|
FIXME("Ignoring SwapEffect and Flags\n");
|
||||||
|
|
||||||
wined3d_desc.backbuffer_width = desc->BufferDesc.Width;
|
wined3d_desc.backbuffer_width = desc->BufferDesc.Width;
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include "d3d11.h"
|
#include "d3d11.h"
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static DEVMODEW registry_mode;
|
||||||
|
|
||||||
static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory);
|
static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory);
|
||||||
|
|
||||||
static ULONG get_refcount(IUnknown *iface)
|
static ULONG get_refcount(IUnknown *iface)
|
||||||
|
@ -1018,10 +1020,194 @@ static void test_swapchain_resize(void)
|
||||||
DestroyWindow(window);
|
DestroyWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_swapchain_parameters(void)
|
||||||
|
{
|
||||||
|
IDXGISwapChain *swapchain;
|
||||||
|
IUnknown *obj;
|
||||||
|
IDXGIAdapter *adapter;
|
||||||
|
IDXGIFactory *factory;
|
||||||
|
IDXGIDevice *device;
|
||||||
|
IDXGIResource *resource;
|
||||||
|
DXGI_SWAP_CHAIN_DESC desc;
|
||||||
|
HRESULT hr;
|
||||||
|
unsigned int i, j;
|
||||||
|
ULONG refcount;
|
||||||
|
DXGI_USAGE usage, expected_usage;
|
||||||
|
HWND window;
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
BOOL windowed;
|
||||||
|
UINT buffer_count;
|
||||||
|
DXGI_SWAP_EFFECT swap_effect;
|
||||||
|
HRESULT hr, vista_hr;
|
||||||
|
UINT highest_accessible_buffer;
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
{TRUE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
|
||||||
|
{TRUE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
|
||||||
|
{TRUE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0},
|
||||||
|
{TRUE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1},
|
||||||
|
{TRUE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2},
|
||||||
|
{TRUE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, /*10 */
|
||||||
|
{TRUE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1},
|
||||||
|
{TRUE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2},
|
||||||
|
{TRUE, 0, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 1, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 2, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
|
||||||
|
{TRUE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15},
|
||||||
|
{TRUE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15},
|
||||||
|
{TRUE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, /*20 */
|
||||||
|
{TRUE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{TRUE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
|
||||||
|
{FALSE, 0, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 1, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, /*24 */
|
||||||
|
{FALSE, 2, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0},
|
||||||
|
{FALSE, 0, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 1, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 0},
|
||||||
|
{FALSE, 2, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 1},
|
||||||
|
{FALSE, 3, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 2},
|
||||||
|
{FALSE, 0, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0}, //30
|
||||||
|
{FALSE, 1, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 2, 2 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 0, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 1, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 2, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 1},
|
||||||
|
{FALSE, 3, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 2},
|
||||||
|
{FALSE, 0, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 1, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 2, 4 /* undefined */, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 16, DXGI_SWAP_EFFECT_DISCARD, S_OK, S_OK, 0}, /*40 */
|
||||||
|
{FALSE, 16, DXGI_SWAP_EFFECT_SEQUENTIAL, S_OK, S_OK, 15},
|
||||||
|
{FALSE, 16, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, S_OK, DXGI_ERROR_INVALID_CALL, 15},
|
||||||
|
{FALSE, 17, DXGI_SWAP_EFFECT_DISCARD, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 17, DXGI_SWAP_EFFECT_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
{FALSE, 17, DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL, DXGI_ERROR_INVALID_CALL, DXGI_ERROR_INVALID_CALL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!(device = create_device()))
|
||||||
|
{
|
||||||
|
skip("Failed to create device, skipping tests.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window = CreateWindowA("static", "dxgi_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
0, 0, 640, 480, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
hr = IDXGIDevice_QueryInterface(device, &IID_IUnknown, (void **)&obj);
|
||||||
|
ok(SUCCEEDED(hr), "IDXGIDevice does not implement IUnknown\n");
|
||||||
|
|
||||||
|
hr = IDXGIDevice_GetAdapter(device, &adapter);
|
||||||
|
ok(SUCCEEDED(hr), "GetAdapter failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
|
||||||
|
ok(SUCCEEDED(hr), "GetParent failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
|
||||||
|
{
|
||||||
|
memset(&desc, 0, sizeof(desc));
|
||||||
|
desc.BufferDesc.Width = registry_mode.dmPelsWidth;
|
||||||
|
desc.BufferDesc.Height = registry_mode.dmPelsHeight;
|
||||||
|
desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
desc.OutputWindow = window;
|
||||||
|
|
||||||
|
desc.Windowed = tests[i].windowed;
|
||||||
|
desc.BufferCount = tests[i].buffer_count;
|
||||||
|
desc.SwapEffect = tests[i].swap_effect;
|
||||||
|
|
||||||
|
hr = IDXGIFactory_CreateSwapChain(factory, obj, &desc, &swapchain);
|
||||||
|
ok(hr == tests[i].hr || broken(hr == tests[i].vista_hr)
|
||||||
|
|| (SUCCEEDED(tests[i].hr) && hr == DXGI_STATUS_OCCLUDED),
|
||||||
|
"Got unexpected hr %#x, test %u.\n", hr, i);
|
||||||
|
if (FAILED(hr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGIResource, (void **)&resource);
|
||||||
|
todo_wine ok(SUCCEEDED(hr), "GetBuffer(0) failed, hr %#x, test %u.\n", hr, i);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
|
||||||
|
todo_wine ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
IDXGISwapChain_Release(swapchain);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||||
|
if (tests[i].swap_effect == DXGI_SWAP_EFFECT_DISCARD)
|
||||||
|
expected_usage |= DXGI_USAGE_DISCARD_ON_PRESENT;
|
||||||
|
hr = IDXGIResource_GetUsage(resource, &usage);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u.\n", hr, i);
|
||||||
|
ok(usage == expected_usage, "Got usage %x, expected %x, test %u.\n", usage, expected_usage, i);
|
||||||
|
|
||||||
|
IDXGIResource_Release(resource);
|
||||||
|
|
||||||
|
hr = IDXGISwapChain_GetDesc(swapchain, &desc);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get swapchain desc, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
for (j = 1; j <= tests[i].highest_accessible_buffer; j++)
|
||||||
|
{
|
||||||
|
hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
|
||||||
|
ok(SUCCEEDED(hr), "GetBuffer(%u) failed, hr %#x, test %u.\n", hr, i, j);
|
||||||
|
|
||||||
|
expected_usage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
|
||||||
|
|
||||||
|
/* Buffers > 0 are supposed to be read only. This is the case except that in
|
||||||
|
* fullscreen mode the last backbuffer (BufferCount - 1) is writeable. This
|
||||||
|
* is not the case if an unsupported refresh rate is passed for some reason,
|
||||||
|
* probably because the invalid refresh rate triggers a kinda-sorta windowed
|
||||||
|
* mode.
|
||||||
|
*
|
||||||
|
* This last buffer acts as a shadow frontbuffer. Writing to it doesn't show
|
||||||
|
* the draw on the screen right away (Aero on or off doesn't matter), but
|
||||||
|
* Present with DXGI_PRESENT_DO_NOT_SEQUENCE will show the modifications.
|
||||||
|
*
|
||||||
|
* Note that if the application doesn't have focused creating a fullscreen
|
||||||
|
* swapchain returns DXGI_STATUS_OCCLUDED and we get a windowed swapchain,
|
||||||
|
* so use the Windowed property of the swapchain that was actually created. */
|
||||||
|
if (desc.Windowed || j < tests[i].highest_accessible_buffer)
|
||||||
|
expected_usage |= DXGI_USAGE_READ_ONLY;
|
||||||
|
|
||||||
|
hr = IDXGIResource_GetUsage(resource, &usage);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get resource usage, hr %#x, test %u, buffer %u.\n", hr, i, j);
|
||||||
|
ok(usage == expected_usage, "Got usage %x, expected %x, test %u, buffer %u.\n",
|
||||||
|
usage, expected_usage, i, j);
|
||||||
|
|
||||||
|
IDXGIResource_Release(resource);
|
||||||
|
}
|
||||||
|
hr = IDXGISwapChain_GetBuffer(swapchain, j, &IID_IDXGIResource, (void **)&resource);
|
||||||
|
ok(hr == DXGI_ERROR_INVALID_CALL, "GetBuffer(%u) returned unexpected hr %#x, test %u.\n", j, hr, i);
|
||||||
|
|
||||||
|
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
|
||||||
|
todo_wine ok(SUCCEEDED(hr), "SetFullscreenState failed, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
IDXGISwapChain_Release(swapchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGIFactory_Release(factory);
|
||||||
|
IDXGIAdapter_Release(adapter);
|
||||||
|
IUnknown_Release(obj);
|
||||||
|
refcount = IDXGIDevice_Release(device);
|
||||||
|
ok(!refcount, "Device has %u references left.\n", refcount);
|
||||||
|
DestroyWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(device)
|
START_TEST(device)
|
||||||
{
|
{
|
||||||
pCreateDXGIFactory1 = (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
pCreateDXGIFactory1 = (void *)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||||
|
|
||||||
|
registry_mode.dmSize = sizeof(registry_mode);
|
||||||
|
ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, ®istry_mode), "Failed to get display mode.\n");
|
||||||
|
|
||||||
test_adapter_desc();
|
test_adapter_desc();
|
||||||
test_device_interfaces();
|
test_device_interfaces();
|
||||||
test_create_surface();
|
test_create_surface();
|
||||||
|
@ -1031,4 +1217,5 @@ START_TEST(device)
|
||||||
test_create_factory();
|
test_create_factory();
|
||||||
test_private_data();
|
test_private_data();
|
||||||
test_swapchain_resize();
|
test_swapchain_resize();
|
||||||
|
test_swapchain_parameters();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,8 @@ const DXGI_USAGE DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x20L;
|
||||||
const DXGI_USAGE DXGI_USAGE_BACK_BUFFER = 0x40L;
|
const DXGI_USAGE DXGI_USAGE_BACK_BUFFER = 0x40L;
|
||||||
const DXGI_USAGE DXGI_USAGE_SHARED = 0x80L;
|
const DXGI_USAGE DXGI_USAGE_SHARED = 0x80L;
|
||||||
const DXGI_USAGE DXGI_USAGE_READ_ONLY = 0x100L;
|
const DXGI_USAGE DXGI_USAGE_READ_ONLY = 0x100L;
|
||||||
|
const DXGI_USAGE DXGI_USAGE_DISCARD_ON_PRESENT = 0x200L;
|
||||||
|
const DXGI_USAGE DXGI_USAGE_UNORDERED_ACCESS = 0x400L;
|
||||||
|
|
||||||
const UINT DXGI_ENUM_MODES_INTERLACED = 1;
|
const UINT DXGI_ENUM_MODES_INTERLACED = 1;
|
||||||
const UINT DXGI_ENUM_MODES_SCALING = 2;
|
const UINT DXGI_ENUM_MODES_SCALING = 2;
|
||||||
|
|
Loading…
Reference in New Issue