Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v2: using separate device now, added GetDevice() test.
dlls/d3dx9_36/effect.c | 9 +++ dlls/d3dx9_36/tests/effect.c | 189 ++++++++++++++++++++++++++++--------------- 2 files changed, 135 insertions(+), 63 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index f8c480303c..a98495e555 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -4367,6 +4367,15 @@ static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
+ if (!effect) + return D3DERR_INVALIDCALL; + + if (This->base_effect.flags & D3DXFX_NOT_CLONEABLE) + return E_FAIL; + + if (!device) + return D3DERR_INVALIDCALL; + return E_NOTIMPL; }
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 1900f3eac1..5efc117a13 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -149,6 +149,44 @@ static void set_number(void *outdata, D3DXPARAMETER_TYPE outtype, const void *in } }
+static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND *window) +{ + D3DPRESENT_PARAMETERS present_parameters = { 0 }; + IDirect3DDevice9 *device; + HRESULT hr; + + if (!(*window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, + 640, 480, NULL, NULL, NULL, NULL))) + { + skip("Couldn't create application window\n"); + return NULL; + } + + if (d3d) + IDirect3D9_AddRef(d3d); + + if (!d3d && !(d3d = Direct3DCreate9(D3D_SDK_VERSION))) + { + skip("Couldn't create IDirect3D9 object\n"); + DestroyWindow(*window); + return NULL; + } + + present_parameters.Windowed = TRUE; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, *window, D3DCREATE_HARDWARE_VERTEXPROCESSING, + &present_parameters, &device); + IDirect3D9_Release(d3d); + if (FAILED(hr)) + { + skip("Failed to create IDirect3DDevice9 object %#x\n", hr); + DestroyWindow(*window); + return NULL; + } + + return device; +} + static const char effect_desc[] = "Technique\n" "{\n" @@ -7063,40 +7101,18 @@ static const DWORD test_effect_unsupported_shader_blob[] =
static void test_effect_unsupported_shader(void) { - D3DPRESENT_PARAMETERS present_parameters = {0}; IDirect3DVertexShader9 *vshader; unsigned int passes_count; IDirect3DDevice9 *device; UINT byte_code_size; ID3DXEffect *effect; - IDirect3D9 *d3d; void *byte_code; ULONG refcount; HWND window; HRESULT hr;
- if (!(window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, - 640, 480, NULL, NULL, NULL, NULL))) - { - skip("Couldn't create application window\n"); - return; - } - if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) - { - skip("Couldn't create IDirect3D9 object\n"); - DestroyWindow(window); - return; - } - present_parameters.Windowed = TRUE; - present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; - hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device); - if (FAILED(hr)) { - skip("Failed to create IDirect3DDevice9 object, hr %#x\n", hr); - IDirect3D9_Release(d3d); - DestroyWindow(window); + if (!(device = create_device(NULL, &window))) return; - }
hr = D3DXCreateEffectEx(device, test_effect_unsupported_shader_blob, sizeof(test_effect_unsupported_shader_blob), NULL, NULL, NULL, 0, NULL, &effect, NULL); @@ -7168,7 +7184,6 @@ static void test_effect_unsupported_shader(void)
refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); - IDirect3D9_Release(d3d); DestroyWindow(window); }
@@ -7217,11 +7232,9 @@ static const DWORD test_effect_null_shader_blob[] =
static void test_effect_null_shader(void) { - D3DPRESENT_PARAMETERS present_parameters = {0}; IDirect3DDevice9 *device; ID3DXEffect *effect; D3DXPASS_DESC desc; - IDirect3D9 *d3d; D3DXHANDLE pass; ULONG refcount; HWND window; @@ -7230,29 +7243,8 @@ static void test_effect_null_shader(void) /* Creating a fresh device because the existing device can have invalid * render states from previous tests. If IDirect3DDevice9_ValidateDevice() * returns certain error codes, native ValidateTechnique() fails. */ - if (!(window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, - 640, 480, NULL, NULL, NULL, NULL))) - { - skip("Failed to create window.\n"); - return; - } - if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) - { - skip("Failed to create IDirect3D9 object.\n"); - DestroyWindow(window); - return; - } - present_parameters.Windowed = TRUE; - present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; - hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device); - if (FAILED(hr)) - { - skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr); - IDirect3D9_Release(d3d); - DestroyWindow(window); + if (!(device = create_device(NULL, &window))) return; - }
hr = D3DXCreateEffectEx(device, test_effect_null_shader_blob, sizeof(test_effect_null_shader_blob), NULL, NULL, NULL, 0, NULL, &effect, NULL); @@ -7290,8 +7282,91 @@ static void test_effect_null_shader(void)
refcount = IDirect3DDevice9_Release(device); ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + +static void test_effect_clone(void) +{ + IDirect3DDevice9 *device, *device2, *device3; + ID3DXEffect *effect, *cloned; + HWND window, window2; + IDirect3D9 *d3d; + HRESULT hr; + + if (!(device = create_device(NULL, &window))) + return; + + /* D3DXFX_NOT_CLONEABLE */ + hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob), + NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &effect, NULL); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + + hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); + + cloned = (void *)0xdeadbeef; + hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned); + ok(hr == E_FAIL, "Got result %#x.\n", hr); + ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n"); + + hr = effect->lpVtbl->CloneEffect(effect, device, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); + + cloned = (void *)0xdeadbeef; + hr = effect->lpVtbl->CloneEffect(effect, device, &cloned); + ok(hr == E_FAIL, "Got result %#x.\n", hr); + ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n"); + + effect->lpVtbl->Release(effect); + + hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob), + NULL, NULL, 0, NULL, &effect, NULL); + ok(hr == D3D_OK, "Got result %#x.\n", hr); + + hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); + + cloned = (void *)0xdeadbeef; + hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned); + ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); + ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n"); + + hr = effect->lpVtbl->CloneEffect(effect, device, NULL); + ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr); + + hr = effect->lpVtbl->CloneEffect(effect, device, &cloned); +todo_wine + ok(hr == D3D_OK, "Got result %#x.\n", hr); +if (hr == D3D_OK) +{ + ok(cloned != effect, "Expected new effect instance.\n"); + cloned->lpVtbl->Release(cloned); +} + /* Try with different device. */ + hr = IDirect3DDevice9_GetDirect3D(device, &d3d); + ok(hr == D3D_OK, "Failed to get IDirect3D9 pointer.\n"); + + device2 = create_device(d3d, &window2); + hr = effect->lpVtbl->CloneEffect(effect, device2, &cloned); +todo_wine + ok(hr == D3D_OK, "Got result %#x.\n", hr); +if (hr == D3D_OK) +{ + ok(cloned != effect, "Expected new effect instance.\n"); + + hr = cloned->lpVtbl->GetDevice(cloned, &device3); + ok(hr == S_OK, "Failed to get effect device.\n"); + ok(device3 == device2, "Unexpected device instance.\n"); + IDirect3DDevice9_Release(device3); + + cloned->lpVtbl->Release(cloned); +} + IDirect3DDevice9_Release(device2); IDirect3D9_Release(d3d); + DestroyWindow(window2); DestroyWindow(window); + + effect->lpVtbl->Release(effect); }
START_TEST(effect) @@ -7299,16 +7374,8 @@ START_TEST(effect) HWND wnd; IDirect3D9 *d3d; IDirect3DDevice9 *device; - D3DPRESENT_PARAMETERS d3dpp; - HRESULT hr; ULONG refcount;
- if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, - 640, 480, NULL, NULL, NULL, NULL))) - { - skip("Couldn't create application window\n"); - return; - } if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) { skip("Couldn't create IDirect3D9 object\n"); @@ -7316,14 +7383,9 @@ START_TEST(effect) return; }
- ZeroMemory(&d3dpp, sizeof(d3dpp)); - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device); - if (FAILED(hr)) { - skip("Failed to create IDirect3DDevice9 object %#x\n", hr); + if (!(device = create_device(d3d, &wnd))) + { IDirect3D9_Release(d3d); - DestroyWindow(wnd); return; }
@@ -7355,4 +7417,5 @@ START_TEST(effect)
test_effect_unsupported_shader(); test_effect_null_shader(); + test_effect_clone(); }
2018-03-02 14:58 GMT+01:00 Nikolay Sivov nsivov@codeweavers.com:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
v2: using separate device now, added GetDevice() test.
Thanks, I like it but I still found something to complain about.
@@ -7299,16 +7374,8 @@ START_TEST(effect) HWND wnd; IDirect3D9 *d3d; IDirect3DDevice9 *device;
D3DPRESENT_PARAMETERS d3dpp;
HRESULT hr; ULONG refcount;
if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
640, 480, NULL, NULL, NULL, NULL)))
{
skip("Couldn't create application window\n");
return;
} if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) { skip("Couldn't create IDirect3D9 object\n");
A few more lines of context:
DestroyWindow(wnd); return; }
where wnd is now uninitialized.
FWIW I'd simplify it further, getting rid of the d3d argument and the related refcount check in START_TEST. If you feel particularly fancy you could introduce a struct test_context for storing both the device and the window, along the lines of the d3d11 tests. That's not required by any means though.
Ah, given that you need to resend anyway, can you please add a period at the end of the skip() messages in create_device()?