Henri Verbeet : d3d8: Improve ValidateVertexShader().
Alexandre Julliard
julliard at winehq.org
Fri Feb 8 16:16:27 CST 2019
Module: wine
Branch: master
Commit: 3ccbb762d2982ca3cf3117b3cc4dd0cd92855593
URL: https://source.winehq.org/git/wine.git/?a=commit;h=3ccbb762d2982ca3cf3117b3cc4dd0cd92855593
Author: Henri Verbeet <hverbeet at codeweavers.com>
Date: Fri Feb 8 02:27:37 2019 +0330
d3d8: Improve ValidateVertexShader().
Based largely on a patch by Sebastian Lackner.
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/d3d8/d3d8_main.c | 64 +++++++++++++++++-------------
dlls/d3d8/tests/device.c | 100 +++++++++++++++++++++++++++++++++++------------
2 files changed, 113 insertions(+), 51 deletions(-)
diff --git a/dlls/d3d8/d3d8_main.c b/dlls/d3d8/d3d8_main.c
index 5fbd165..17f35c9 100644
--- a/dlls/d3d8/d3d8_main.c
+++ b/dlls/d3d8/d3d8_main.c
@@ -57,40 +57,50 @@ IDirect3D8 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate8(UINT sdk_version)
return &object->IDirect3D8_iface;
}
-/***********************************************************************
- * ValidateVertexShader (D3D8.@)
- *
- * I've seen reserved1 and reserved2 always passed as 0's
- * boolean seems always passed as 0 or 1, but other values work as well...
- * toto result?
- */
-HRESULT WINAPI ValidateVertexShader(DWORD* vertexshader, DWORD* reserved1, DWORD* reserved2, BOOL boolean, DWORD* toto)
+/* FIXME: We should probably use libvkd3d-shader for validation. */
+HRESULT WINAPI ValidateVertexShader(const DWORD *vs_code, const DWORD *declaration,
+ const D3DCAPS8 *caps, BOOL return_error, char **errors)
{
- HRESULT ret;
- static BOOL warned;
+ const char *message = "";
+ SIZE_T message_size;
+ HRESULT hr = E_FAIL;
- if (TRACE_ON(d3d8) || !warned) {
- FIXME("(%p %p %p %d %p): stub\n", vertexshader, reserved1, reserved2, boolean, toto);
- warned = TRUE;
- }
-
- if (!vertexshader)
- return E_FAIL;
+ TRACE("vs_code %p, declaration %p, caps %p, return_error %#x, errors %p.\n",
+ vs_code, declaration, caps, return_error, errors);
- if (reserved1 || reserved2)
- return E_FAIL;
+ if (!vs_code)
+ {
+ message = "Invalid code pointer.\n";
+ goto done;
+ }
- switch(*vertexshader) {
- case 0xFFFE0101:
- case 0xFFFE0100:
- ret=S_OK;
+ switch (*vs_code)
+ {
+ case D3DVS_VERSION(1, 1):
+ case D3DVS_VERSION(1, 0):
break;
+
default:
- WARN("Invalid shader version token %#x.\n", *vertexshader);
- ret=E_FAIL;
- }
+ message = "Unsupported shader version.\n";
+ goto done;
+ }
- return ret;
+ if (caps && *vs_code > caps->VertexShaderVersion)
+ {
+ message = "Shader version not supported by caps.\n";
+ goto done;
+ }
+
+ hr = S_OK;
+
+done:
+ if (!return_error)
+ message = "";
+ message_size = strlen(message) + 1;
+ if (errors && (*errors = heap_alloc(message_size)))
+ memcpy(*errors, message, message_size);
+
+ return hr;
}
/***********************************************************************
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index b57be7a..315640d 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -27,6 +27,7 @@
#include <initguid.h>
#include <d3d8.h>
#include "wine/test.h"
+#include "wine/heap.h"
struct vec3
{
@@ -51,7 +52,7 @@ struct device_desc
static DEVMODEW registry_mode;
-static HRESULT (WINAPI *ValidateVertexShader)(DWORD *, DWORD *, DWORD *, int, DWORD *);
+static HRESULT (WINAPI *ValidateVertexShader)(const DWORD *, const DWORD *, const D3DCAPS8 *, BOOL, char **);
static HRESULT (WINAPI *ValidatePixelShader)(DWORD *, DWORD *, int, DWORD *);
static BOOL (WINAPI *pGetCursorInfo)(PCURSORINFO);
@@ -4365,7 +4366,7 @@ static void test_set_rt_vp_scissor(void)
static void test_validate_vs(void)
{
- static DWORD vs[] =
+ static DWORD vs_code[] =
{
0xfffe0101, /* vs_1_1 */
0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
@@ -4374,40 +4375,91 @@ static void test_validate_vs(void)
0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
0x0000ffff, /* end */
};
+ D3DCAPS8 caps;
+ char *errors;
HRESULT hr;
- hr = ValidateVertexShader(0, 0, 0, 0, 0);
+ static DWORD declaration_valid1[] =
+ {
+ D3DVSD_STREAM(0),
+ D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT4),
+ D3DVSD_END()
+ };
+ static DWORD declaration_valid2[] =
+ {
+ D3DVSD_STREAM(0),
+ D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT2),
+ D3DVSD_END()
+ };
+ static DWORD declaration_invalid[] =
+ {
+ D3DVSD_STREAM(0),
+ D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT4),
+ D3DVSD_END()
+ };
+
+ hr = ValidateVertexShader(NULL, NULL, NULL, FALSE, NULL);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- hr = ValidateVertexShader(0, 0, 0, 1, 0);
+ hr = ValidateVertexShader(NULL, NULL, NULL, TRUE, NULL);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- hr = ValidateVertexShader(vs, 0, 0, 0, 0);
- ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(NULL, NULL, NULL, FALSE, &errors);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ ok(!*errors, "Got unexpected string \"%s\".\n", errors);
+ heap_free(errors);
+ hr = ValidateVertexShader(NULL, NULL, NULL, TRUE, &errors);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ ok(!!*errors, "Got unexpected empty string.\n");
+ heap_free(errors);
- hr = ValidateVertexShader(vs, 0, 0, 1, 0);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- /* Seems to do some version checking. */
- *vs = 0xfffe0100; /* vs_1_0 */
- hr = ValidateVertexShader(vs, 0, 0, 0, 0);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, TRUE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, TRUE, &errors);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!*errors, "Got unexpected string \"%s\".\n", errors);
+ heap_free(errors);
- *vs = 0xfffe0102; /* bogus version */
- hr = ValidateVertexShader(vs, 0, 0, 1, 0);
- ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- /* I've seen that applications always pass the 2nd and 3rd parameter as 0.
- * Simple test with non-zero parameters. */
- *vs = 0xfffe0101; /* vs_1_1 */
- hr = ValidateVertexShader(vs, vs, 0, 1, 0);
- ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(vs_code, declaration_valid1, NULL, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(vs_code, declaration_valid2, NULL, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(vs_code, declaration_invalid, NULL, FALSE, NULL);
+ todo_wine ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- hr = ValidateVertexShader(vs, 0, vs, 1, 0);
+ memset(&caps, 0, sizeof(caps));
+ caps.VertexShaderVersion = D3DVS_VERSION(1, 1);
+ caps.MaxVertexShaderConst = 4;
+ hr = ValidateVertexShader(vs_code, NULL, &caps, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ caps.VertexShaderVersion = D3DVS_VERSION(1, 0);
+ hr = ValidateVertexShader(vs_code, NULL, &caps, FALSE, NULL);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- /* I've seen the 4th parameter always passed as either 0 or 1, but passing
- * other values doesn't seem to hurt. */
- hr = ValidateVertexShader(vs, 0, 0, 12345, 0);
+ caps.VertexShaderVersion = D3DVS_VERSION(1, 2);
+ hr = ValidateVertexShader(vs_code, NULL, &caps, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- /* What is the 5th parameter? The following seems to work ok. */
- hr = ValidateVertexShader(vs, 0, 0, 1, vs);
+ caps.VertexShaderVersion = D3DVS_VERSION(8, 8);
+ hr = ValidateVertexShader(vs_code, NULL, &caps, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ caps.VertexShaderVersion = D3DVS_VERSION(1, 1);
+ caps.MaxVertexShaderConst = 3;
+ hr = ValidateVertexShader(vs_code, NULL, &caps, FALSE, NULL);
+ todo_wine ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+
+ *vs_code = D3DVS_VERSION(1, 0);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ *vs_code = D3DVS_VERSION(1, 2);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, TRUE, NULL);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, FALSE, &errors);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ ok(!*errors, "Got unexpected string \"%s\".\n", errors);
+ heap_free(errors);
+ hr = ValidateVertexShader(vs_code, NULL, NULL, TRUE, &errors);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ ok(!!*errors, "Got unexpected empty string.\n");
+ heap_free(errors);
}
static void test_validate_ps(void)
More information about the wine-cvs
mailing list