[PATCH] d3dx9_36: Implement ID3DXEffect_FindNextValidTechnique + add tests. (try 2)
Christian Costa
titan.costa at gmail.com
Fri Aug 2 02:44:24 CDT 2013
This patch fixes bug 34101.
Thanks to Rico Schüller for review.
Try 2:
- Fix error message
---
dlls/d3dx9_36/effect.c | 34 ++++++++++++++++++++++--
dlls/d3dx9_36/tests/effect.c | 60 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index 0be0d1e..80c15f7 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -3433,13 +3433,41 @@ static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DX
return D3D_OK;
}
-static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
+static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface,
+ D3DXHANDLE technique, D3DXHANDLE *next_technique)
{
struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
+ struct ID3DXBaseEffectImpl *base_effect = impl_from_ID3DXBaseEffect(This->base_effect);
+ UINT i = 0;
- FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
+ TRACE("iface %p, technique %p, next_technique %p\n", iface, technique, next_technique);
- return E_NOTIMPL;
+ if (!next_technique)
+ return D3DERR_INVALIDCALL;
+
+ if (technique)
+ {
+ for (; i < base_effect->technique_count; i++)
+ {
+ if (technique == get_technique_handle(&base_effect->techniques[i]))
+ {
+ i++; /* Go to next technique */
+ break;
+ }
+ }
+ }
+
+ for (; i < base_effect->technique_count; i++)
+ {
+ if (SUCCEEDED(iface->lpVtbl->ValidateTechnique(iface, get_technique_handle(&base_effect->techniques[i]))))
+ {
+ *next_technique = get_technique_handle(&base_effect->techniques[i]);
+ return D3D_OK;
+ }
+ }
+
+ *next_technique = NULL;
+ return S_FALSE;
}
static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index c67e863..a4ebf52 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -2682,6 +2682,65 @@ static void test_effect_compilation_errors(IDirect3DDevice9 *device)
effect->lpVtbl->Release(effect);
}
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+technique t1 { pass p { ZEnable = TRUE; } }
+technique t2 { pass p { ZEnable = FALSE; } }
+#endif
+static const DWORD test_effect_technique_validation_blob[] =
+{
+0xfeff0901, 0x00000064, 0x00000000, 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
+0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x00000070, 0x00000003, 0x00003174, 0x00000000,
+0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002,
+0x00000070, 0x00000003, 0x00003274, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x0000002c,
+0x00000000, 0x00000001, 0x00000024, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000008,
+0x00000004, 0x0000005c, 0x00000000, 0x00000001, 0x00000054, 0x00000000, 0x00000001, 0x00000000,
+0x00000000, 0x00000038, 0x00000034, 0x00000000, 0x00000000
+};
+
+static void test_effect_technique_validation(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect;
+ ULONG count;
+ D3DXHANDLE technique1, technique2, technique;
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_technique_validation_blob,
+ sizeof(test_effect_technique_validation_blob), NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "D3DXCreateEffect failed, got %#x, expected %#x\n", hr, D3D_OK);
+
+ technique1 = effect->lpVtbl->GetTechniqueByName(effect, "t1");
+ ok(technique1 != NULL, "Failed to get technique\n");
+ technique2 = effect->lpVtbl->GetTechniqueByName(effect, "t2");
+ ok(technique2 != NULL, "Failed to get technique\n");
+
+#if 0 /* This crashes on Windows */
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, (D3DXHANDLE)0xdeadbeef, &technique);
+#endif
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "FindNextValidTechnique, got %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ technique = (D3DXHANDLE)0xdeadbeef;
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, &technique);
+ ok(hr == D3D_OK, "FindNextValidTechnique failed, got %#x, expected %#x\n", hr, D3D_OK);
+ ok(technique == technique1, "Technique returned %p, expected %p\n", technique, technique1);
+
+ technique = (D3DXHANDLE)0xdeadbeef;
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, technique1, &technique);
+ ok(hr == D3D_OK, "FindNextValidTechnique failed, got %#x, expected %#x\n", hr, D3D_OK);
+ ok(technique == technique2, "Technique returned %p, expected %p\n", technique, technique2);
+
+ technique = (D3DXHANDLE)0xdeadbeef;
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, technique2, &technique);
+ ok(hr == S_FALSE, "FindNextValidTechnique failed, got %#x, expected %#x\n", hr, S_FALSE);
+ ok(technique == NULL, "Technique returned %p, expected %p\n", technique, NULL);
+
+ count = effect->lpVtbl->Release(effect);
+ ok(!count, "Release failed %u\n", count);
+}
+
START_TEST(effect)
{
HWND wnd;
@@ -2719,6 +2778,7 @@ START_TEST(effect)
test_effect_parameter_value(device);
test_effect_variable_names(device);
test_effect_compilation_errors(device);
+ test_effect_technique_validation(device);
count = IDirect3DDevice9_Release(device);
ok(count == 0, "The device was not properly freed: refcount %u\n", count);
More information about the wine-patches
mailing list