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(); }