Gijs Vermeulen : d3d8: Improve ValidatePixelShader().
Alexandre Julliard
julliard at winehq.org
Mon Mar 4 15:08:26 CST 2019
Module: wine
Branch: master
Commit: 740102f33256c0274f6dfb4a357e2127705c487e
URL: https://source.winehq.org/git/wine.git/?a=commit;h=740102f33256c0274f6dfb4a357e2127705c487e
Author: Gijs Vermeulen <gijsvrm at gmail.com>
Date: Mon Mar 4 22:18:06 2019 +0330
d3d8: Improve ValidatePixelShader().
Based largely on a patch by Sebastian Lackner.
Adapted from "Improve ValidateVertexShader()" by Henri Verbeet.
Signed-off-by: Gijs Vermeulen <gijsvrm at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/d3d8/d3d8_main.c | 72 +++++++++++++++++++++------------------
dlls/d3d8/tests/device.c | 87 ++++++++++++++++++++++++++++++++++--------------
2 files changed, 102 insertions(+), 57 deletions(-)
diff --git a/dlls/d3d8/d3d8_main.c b/dlls/d3d8/d3d8_main.c
index 17f35c9..62e8d31 100644
--- a/dlls/d3d8/d3d8_main.c
+++ b/dlls/d3d8/d3d8_main.c
@@ -103,41 +103,49 @@ done:
return hr;
}
-/***********************************************************************
- * ValidatePixelShader (D3D8.@)
- *
- * PARAMS
- * toto result?
- */
-HRESULT WINAPI ValidatePixelShader(DWORD* pixelshader, DWORD* reserved1, BOOL boolean, DWORD* toto)
+HRESULT WINAPI ValidatePixelShader(const DWORD *ps_code,
+ const D3DCAPS8 *caps, BOOL return_error, char **errors)
{
- HRESULT ret;
- static BOOL warned;
-
- if (TRACE_ON(d3d8) || !warned) {
- FIXME("(%p %p %d %p): stub\n", pixelshader, reserved1, boolean, toto);
- warned = TRUE;
- }
-
- if (!pixelshader)
- return E_FAIL;
-
- if (reserved1)
- return E_FAIL;
-
- switch(*pixelshader) {
- case 0xFFFF0100:
- case 0xFFFF0101:
- case 0xFFFF0102:
- case 0xFFFF0103:
- case 0xFFFF0104:
- ret=S_OK;
+ const char *message = "";
+ SIZE_T message_size;
+ HRESULT hr = E_FAIL;
+
+ TRACE("ps_code %p, caps %p, return_error %#x, errors %p.\n",
+ ps_code, caps, return_error, errors);
+
+ if (!ps_code)
+ return E_FAIL;
+
+ switch (*ps_code)
+ {
+ case D3DPS_VERSION(1, 4):
+ case D3DPS_VERSION(1, 3):
+ case D3DPS_VERSION(1, 2):
+ case D3DPS_VERSION(1, 1):
+ case D3DPS_VERSION(1, 0):
break;
+
default:
- WARN("Invalid shader version token %#x.\n", *pixelshader);
- ret=E_FAIL;
- }
- return ret;
+ message = "Unsupported shader version.\n";
+ goto done;
+ }
+
+ if (caps && *ps_code > caps->PixelShaderVersion)
+ {
+ 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;
}
void d3d8_resource_cleanup(struct d3d8_resource *resource)
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index a647369..51dd3ae 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -53,7 +53,7 @@ struct device_desc
static DEVMODEW registry_mode;
static HRESULT (WINAPI *ValidateVertexShader)(const DWORD *, const DWORD *, const D3DCAPS8 *, BOOL, char **);
-static HRESULT (WINAPI *ValidatePixelShader)(DWORD *, DWORD *, int, DWORD *);
+static HRESULT (WINAPI *ValidatePixelShader)(const DWORD *, const D3DCAPS8 *, BOOL, char **);
static BOOL (WINAPI *pGetCursorInfo)(PCURSORINFO);
@@ -4506,43 +4506,80 @@ static void test_validate_vs(void)
static void test_validate_ps(void)
{
- static DWORD ps[] =
+ static DWORD ps_1_1_code[] =
{
0xffff0101, /* ps_1_1 */
- 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
- 0x00000042, 0xb00f0000, /* tex t0 */
- 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
- 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
- 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
- 0x0000ffff, /* end */
+ 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
+ 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
+ 0x0000ffff /* end */
+ };
+ static const DWORD ps_2_0_code[] =
+ {
+ 0xffff0200, /* ps_2_0 */
+ 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
+ 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
+ 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
+ 0x0000ffff /* end */
};
+ D3DCAPS8 caps;
+ char *errors;
HRESULT hr;
- hr = ValidatePixelShader(0, 0, 0, 0);
+ hr = ValidatePixelShader(NULL, NULL, FALSE, NULL);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ hr = ValidatePixelShader(NULL, NULL, TRUE, NULL);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ errors = (void *)0xcafeface;
+ hr = ValidatePixelShader(NULL, NULL, FALSE, &errors);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- hr = ValidatePixelShader(0, 0, 1, 0);
+ ok(errors == (void *)0xcafeface, "Got unexpected errors %p.\n", errors);
+ errors = (void *)0xcafeface;
+ hr = ValidatePixelShader(NULL, NULL, TRUE, &errors);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- hr = ValidatePixelShader(ps, 0, 0, 0);
+ ok(errors == (void *)0xcafeface, "Got unexpected errors %p.\n", errors);
+
+ hr = ValidatePixelShader(ps_1_1_code, NULL, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidatePixelShader(ps_1_1_code, NULL, TRUE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidatePixelShader(ps_1_1_code, NULL, TRUE, &errors);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ ok(!*errors, "Got unexpected string \"%s\".\n", errors);
+ heap_free(errors);
- hr = ValidatePixelShader(ps, 0, 1, 0);
+ memset(&caps, 0, sizeof(caps));
+ caps.PixelShaderVersion = D3DPS_VERSION(1, 1);
+ hr = ValidatePixelShader(ps_1_1_code, &caps, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- /* Seems to do some version checking. */
- *ps = 0xffff0105; /* bogus version */
- hr = ValidatePixelShader(ps, 0, 1, 0);
+ caps.PixelShaderVersion = D3DPS_VERSION(1, 0);
+ hr = ValidatePixelShader(ps_1_1_code, &caps, FALSE, NULL);
ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- /* I've seen that applications always pass the 2nd parameter as 0.
- * Simple test with a non-zero parameter. */
- *ps = 0xffff0101; /* ps_1_1 */
- hr = ValidatePixelShader(ps, ps, 1, 0);
- ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
- /* I've seen the 3rd parameter always passed as either 0 or 1, but passing
- * other values doesn't seem to hurt. */
- hr = ValidatePixelShader(ps, 0, 12345, 0);
+ caps.PixelShaderVersion = D3DPS_VERSION(1, 2);
+ hr = ValidatePixelShader(ps_1_1_code, &caps, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ caps.PixelShaderVersion = D3DPS_VERSION(8, 8);
+ hr = ValidatePixelShader(ps_1_1_code, &caps, FALSE, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+
+ *ps_1_1_code = D3DPS_VERSION(1, 0);
+ hr = ValidatePixelShader(ps_1_1_code, NULL, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
- /* What is the 4th parameter? The following seems to work ok. */
- hr = ValidatePixelShader(ps, 0, 1, ps);
+ *ps_1_1_code = D3DPS_VERSION(1, 4);
+ hr = ValidatePixelShader(ps_1_1_code, NULL, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ hr = ValidatePixelShader(ps_2_0_code, NULL, FALSE, NULL);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ *ps_1_1_code = D3DPS_VERSION(1, 5);
+ hr = ValidatePixelShader(ps_1_1_code, NULL, TRUE, NULL);
+ ok(hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
+ hr = ValidatePixelShader(ps_1_1_code, 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 = ValidatePixelShader(ps_1_1_code, 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_volume_get_container(void)
More information about the wine-cvs
mailing list