Zebediah Figura : d3d9: Return a stub interface from Direct3DShaderValidatorCreate9().

Alexandre Julliard julliard at winehq.org
Mon Feb 10 16:32:46 CST 2020


Module: wine
Branch: master
Commit: 2a4a8a5cf34e9697a976a8272a1c93e5660cbea6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2a4a8a5cf34e9697a976a8272a1c93e5660cbea6

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Mon Feb 10 18:44:31 2020 +0330

d3d9: Return a stub interface from Direct3DShaderValidatorCreate9().

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46735
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d9/d3d9_main.c    | 124 +++++++++++++++++++++++++++++++++++++++++++----
 dlls/d3d9/tests/device.c |  66 +++++++++++++++++++++++++
 2 files changed, 181 insertions(+), 9 deletions(-)

diff --git a/dlls/d3d9/d3d9_main.c b/dlls/d3d9/d3d9_main.c
index 21df2a34cd..75e627dd76 100644
--- a/dlls/d3d9/d3d9_main.c
+++ b/dlls/d3d9/d3d9_main.c
@@ -75,18 +75,124 @@ HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9E
     return D3D_OK;
 }
 
-/*******************************************************************
- *       Direct3DShaderValidatorCreate9 (D3D9.@)
+/* The callback is called on any error encountered during validation, including
+ * improper IDirect3DShaderValidator9 method calls.
+ * - "file" and "line" are passed through directly from Instruction(). "line"
+ *   is provably 32-bit, as 64-bit values passed to Instruction() will be
+ *   truncated.
+ * - "arg3" has been observed to be at least 0, 2, and 6. The integer size is
+ *   not known.
+ * - "message_id" is a numeric error code. fxc.exe adds 5000 before printing
+ *   it. The integer size is not known.
+ * - "context" is passed through directly from Begin().
  *
- * No documentation available for this function.
- * SDK only says it is internal and shouldn't be used.
- */
-void* WINAPI Direct3DShaderValidatorCreate9(void)
+ * Improper calls to IDirect3DShaderValidator9 methods, or other errors not
+ * generated by specific Instruction() calls, yield NULL as the file, and
+ * either 0 or -1 as the line.
+ *
+ * The callback return type is not known, but programs (fxc.exe, The Sims 2)
+ * seem to consistently return 0.
+ *
+ * The interface and method names below are derived from the messages that
+ * native d3d9 prints on said improper method calls.
+ *
+ * Calls to Begin(), Instruction(), End() have been observed to return S_OK and
+ * E_FAIL. E_FAIL is not always returned if an error message is handed to the
+ * callback. */
+
+typedef HRESULT (WINAPI *shader_validator_cb)(const char *file, int line,
+        DWORD_PTR arg3, DWORD_PTR message_id, const char *message, void *context);
+
+typedef struct IDirect3DShaderValidator9 IDirect3DShaderValidator9;
+
+struct IDirect3DShaderValidator9Vtbl
+{
+    HRESULT (WINAPI *QueryInterface)(IDirect3DShaderValidator9 *iface, REFIID iid, void **out);
+    ULONG (WINAPI *AddRef)(IDirect3DShaderValidator9 *iface);
+    ULONG (WINAPI *Release)(IDirect3DShaderValidator9 *iface);
+    HRESULT (WINAPI *Begin)(IDirect3DShaderValidator9 *iface,
+            shader_validator_cb callback, void *context, DWORD_PTR arg3);
+    HRESULT (WINAPI *Instruction)(IDirect3DShaderValidator9 *iface,
+            const char *file, int line, const DWORD *tokens, DWORD token_count);
+    HRESULT (WINAPI *End)(IDirect3DShaderValidator9 *iface);
+};
+
+struct IDirect3DShaderValidator9
+{
+    const struct IDirect3DShaderValidator9Vtbl *vtbl;
+};
+
+static HRESULT WINAPI shader_validator_QueryInterface(IDirect3DShaderValidator9 *iface, REFIID iid, void **out)
+{
+    TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
+
+    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+    *out = NULL;
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI shader_validator_AddRef(IDirect3DShaderValidator9 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return 2;
+}
+
+static ULONG WINAPI shader_validator_Release(IDirect3DShaderValidator9 *iface)
+{
+    TRACE("iface %p.\n", iface);
+
+    return 1;
+}
+
+/* The size and type of the third argument is not known. The Sims 2 passes 0;
+ * fxc.exe passes 1. */
+static HRESULT WINAPI shader_validator_Begin(IDirect3DShaderValidator9 *iface,
+        shader_validator_cb callback, void *context, DWORD_PTR arg3)
+{
+    FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
+
+    return S_OK;
+}
+
+/* - "file" and "line" are passed directly through to the callback.
+ * - "tokens" comprises a single instruction; the caller must determine its
+ *   length.
+ * - "token_count" is in DWORDs. */
+static HRESULT WINAPI shader_validator_Instruction(IDirect3DShaderValidator9 *iface,
+        const char *file, int line, const DWORD *tokens, DWORD token_count)
+{
+    FIXME("iface %p, file %s, line %u, tokens %p, token_count %u, stub!\n",
+            iface, debugstr_a(file), line, tokens, token_count);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI shader_validator_End(IDirect3DShaderValidator9 *iface)
+{
+    FIXME("iface %p, stub!\n", iface);
+
+    return S_OK;
+}
+
+static const struct IDirect3DShaderValidator9Vtbl shader_validator_vtbl =
+{
+    shader_validator_QueryInterface,
+    shader_validator_AddRef,
+    shader_validator_Release,
+    shader_validator_Begin,
+    shader_validator_Instruction,
+    shader_validator_End,
+};
+
+static IDirect3DShaderValidator9 shader_validator = {&shader_validator_vtbl};
+
+IDirect3DShaderValidator9 * WINAPI Direct3DShaderValidatorCreate9(void)
 {
-    static int once;
+    TRACE("Returning validator %p.\n", &shader_validator);
 
-    if (!once++) FIXME("stub\n");
-    return NULL;
+    return &shader_validator;
 }
 
 /***********************************************************************
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 156cb188f0..8c1ebc1719 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -53,6 +53,8 @@ struct device_desc
 
 static DEVMODEW registry_mode;
 
+static void *(WINAPI *Direct3DShaderValidatorCreate9)(void);
+
 static const DWORD simple_vs[] =
 {
     0xfffe0101,                                                             /* vs_1_1                       */
@@ -13447,8 +13449,69 @@ static void test_multi_adapter(void)
     IDirect3D9_Release(d3d);
 }
 
+typedef HRESULT (WINAPI *shader_validator_cb)(const char *file, int line,
+        DWORD_PTR arg3, DWORD_PTR message_id, const char *message, void *context);
+
+typedef struct IDirect3DShaderValidator9 IDirect3DShaderValidator9;
+
+struct IDirect3DShaderValidator9Vtbl
+{
+    HRESULT (WINAPI *QueryInterface)(IDirect3DShaderValidator9 *iface, REFIID iid, void **out);
+    ULONG (WINAPI *AddRef)(IDirect3DShaderValidator9 *iface);
+    ULONG (WINAPI *Release)(IDirect3DShaderValidator9 *iface);
+    HRESULT (WINAPI *Begin)(IDirect3DShaderValidator9 *iface,
+            shader_validator_cb callback, void *context, DWORD_PTR arg3);
+    HRESULT (WINAPI *Instruction)(IDirect3DShaderValidator9 *iface,
+            const char *file, int line, const DWORD *tokens, DWORD token_count);
+    HRESULT (WINAPI *End)(IDirect3DShaderValidator9 *iface);
+};
+
+struct IDirect3DShaderValidator9
+{
+    const struct IDirect3DShaderValidator9Vtbl *vtbl;
+};
+
+HRESULT WINAPI test_shader_validator_cb(const char *file, int line, DWORD_PTR arg3,
+        DWORD_PTR message_id, const char *message, void *context)
+{
+    ok(0, "Unexpected call.\n");
+    return S_OK;
+}
+
+static void test_shader_validator(void)
+{
+    IDirect3DShaderValidator9 *validator;
+    ULONG refcount;
+    HRESULT hr;
+
+    validator = Direct3DShaderValidatorCreate9();
+
+    hr = validator->vtbl->Begin(validator, test_shader_validator_cb, NULL, 0);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[0], 1);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[1], 3);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[4], 4);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[8], 4);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[12], 4);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[16], 4);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->Instruction(validator, NULL, 0, &simple_vs[20], 1);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+    hr = validator->vtbl->End(validator);
+    ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+    refcount = validator->vtbl->Release(validator);
+    todo_wine ok(!refcount, "Validator has %u references left.\n", refcount);
+}
+
 START_TEST(device)
 {
+    HMODULE d3d9_handle = GetModuleHandleA("d3d9.dll");
     WNDCLASSA wc = {0};
     IDirect3D9 *d3d9;
     DEVMODEW current_mode;
@@ -13476,6 +13539,8 @@ START_TEST(device)
     wc.lpszClassName = "d3d9_test_wc";
     RegisterClassA(&wc);
 
+    Direct3DShaderValidatorCreate9 = (void *)GetProcAddress(d3d9_handle, "Direct3DShaderValidatorCreate9");
+
     test_get_set_vertex_declaration();
     test_get_declaration();
     test_fvf_decl_conversion();
@@ -13575,6 +13640,7 @@ START_TEST(device)
     test_vertex_buffer_read_write();
     test_get_display_mode();
     test_multi_adapter();
+    test_shader_validator();
 
     UnregisterClassA("d3d9_test_wc", GetModuleHandleA(NULL));
 }




More information about the wine-cvs mailing list