Spurred by !6925
-- v2: d3dcompiler/tests: Test the 'double' HLSL data type. d3dx9/tests: Test the 'double' HLSL data type. d3dx9/tests: Add d3dx9_43 tests.
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/d3dx9_43/Makefile.in | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/d3dx9_43/Makefile.in b/dlls/d3dx9_43/Makefile.in index e28429c5236..1d661859876 100644 --- a/dlls/d3dx9_43/Makefile.in +++ b/dlls/d3dx9_43/Makefile.in @@ -1,5 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=43 MODULE = d3dx9_43.dll +IMPORTLIB = d3dx9_43 IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
From: Matteo Bruni mbruni@codeweavers.com
Share the code with the existing d3dx9_36 tests. --- configure | 1 + configure.ac | 1 + dlls/d3dx9_36/tests/effect.c | 10 +++++++--- dlls/d3dx9_36/tests/shader.c | 4 ++++ dlls/d3dx9_43/tests/Makefile.in | 18 ++++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 dlls/d3dx9_43/tests/Makefile.in
diff --git a/configure b/configure index fb4163f70d4..e444808110b 100755 --- a/configure +++ b/configure @@ -22165,6 +22165,7 @@ wine_fn_config_makefile dlls/d3dx9_40 enable_d3dx9_40 wine_fn_config_makefile dlls/d3dx9_41 enable_d3dx9_41 wine_fn_config_makefile dlls/d3dx9_42 enable_d3dx9_42 wine_fn_config_makefile dlls/d3dx9_43 enable_d3dx9_43 +wine_fn_config_makefile dlls/d3dx9_43/tests enable_tests wine_fn_config_makefile dlls/d3dxof enable_d3dxof wine_fn_config_makefile dlls/d3dxof/tests enable_tests wine_fn_config_makefile dlls/dataexchange enable_dataexchange diff --git a/configure.ac b/configure.ac index ac710721ae6..18b8c1018eb 100644 --- a/configure.ac +++ b/configure.ac @@ -2563,6 +2563,7 @@ WINE_CONFIG_MAKEFILE(dlls/d3dx9_40) WINE_CONFIG_MAKEFILE(dlls/d3dx9_41) WINE_CONFIG_MAKEFILE(dlls/d3dx9_42) WINE_CONFIG_MAKEFILE(dlls/d3dx9_43) +WINE_CONFIG_MAKEFILE(dlls/d3dx9_43/tests) WINE_CONFIG_MAKEFILE(dlls/d3dxof) WINE_CONFIG_MAKEFILE(dlls/d3dxof/tests) WINE_CONFIG_MAKEFILE(dlls/dataexchange) diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c index 24f306b30e8..be0a181885d 100644 --- a/dlls/d3dx9_36/tests/effect.c +++ b/dlls/d3dx9_36/tests/effect.c @@ -8065,8 +8065,11 @@ static HRESULT WINAPI d3dxinclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE inc "}\n"; char *buffer;
- trace("filename %s.\n", filename); - trace("parent_data %p: %s.\n", parent_data, parent_data ? (char *)parent_data : "(null)"); + if (winetest_debug > 1) + { + trace("filename %s.\n", filename); + trace("parent_data %p: %s.\n", parent_data, parent_data ? (char *)parent_data : "(null)"); + }
if (!strcmp(filename, "effect2.fx")) { @@ -8087,7 +8090,8 @@ static HRESULT WINAPI d3dxinclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE inc buffer = malloc(sizeof(include2)); memcpy(buffer, include2, sizeof(include2)); *bytes = sizeof(include2); - todo_wine ok(parent_data && !strncmp(parent_data, effect2, strlen(effect2)), + /* d3dx9_36 passes parent_data even for includes from the main file. */ + ok(!parent_data || (parent_data && !strncmp(parent_data, effect2, strlen(effect2))), "unexpected parent_data value.\n"); } else diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index f0c03052404..bba4d60244a 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -6597,6 +6597,7 @@ static void test_shader_semantics(void) } }
+#if D3DX_SDK_VERSION <= 41 static void test_fragment_linker(void) { ID3DXFragmentLinker *linker; @@ -6644,6 +6645,7 @@ static void test_fragment_linker(void) ok(!refcount, "The D3D object has %lu references left.\n", refcount); DestroyWindow(window); } +#endif
START_TEST(shader) { @@ -6659,5 +6661,7 @@ START_TEST(shader) test_registerset(); test_registerset_defaults(); test_shader_semantics(); +#if D3DX_SDK_VERSION <= 41 test_fragment_linker(); +#endif } diff --git a/dlls/d3dx9_43/tests/Makefile.in b/dlls/d3dx9_43/tests/Makefile.in new file mode 100644 index 00000000000..5a0e4338ebe --- /dev/null +++ b/dlls/d3dx9_43/tests/Makefile.in @@ -0,0 +1,18 @@ +TESTDLL = d3dx9_43.dll +IMPORTS = d3dx9_43 d3d9 user32 gdi32 +EXTRADEFS = -DD3DX_SDK_VERSION=43 +PARENTSRC = ../../d3dx9_36/tests + +SOURCES = \ + asm.c \ + core.c \ + effect.c \ + line.c \ + math.c \ + mesh.c \ + rsrc.rc \ + shader.c \ + surface.c \ + texture.c \ + volume.c \ + xfile.c
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/d3dx9_36/tests/shader.c | 251 +++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+)
diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c index bba4d60244a..4ce668b92c3 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -18,6 +18,8 @@ */
#define COBJMACROS +#include <stdbool.h> +#include <stdint.h> #include "wine/test.h" #include "d3dx9.h"
@@ -300,6 +302,195 @@ static const DWORD fx_shader_with_ctab[] = 0x0000ffff /* END */ };
+struct d3d9_test_context +{ + HWND window; + IDirect3D9 *d3d; + IDirect3DDevice9 *device; + IDirect3DSurface9 *backbuffer; +}; + +static HWND create_window(void) +{ + HWND hwnd; + RECT rect; + + SetRect(&rect, 0, 0, 640, 480); + AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0); + return hwnd; +} + +static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DDevice9 *device; + + present_parameters.Windowed = windowed; + present_parameters.hDeviceWindow = device_window; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device))) + return device; + + return NULL; +} + +static bool init_test_context(struct d3d9_test_context *context) +{ + HRESULT hr; + + memset(context, 0, sizeof(*context)); + + context->window = create_window(); + context->d3d = Direct3DCreate9(D3D_SDK_VERSION); + ok(!!context->d3d, "Failed to create a D3D object.\n"); + if (!(context->device = create_device(context->d3d, context->window, context->window, TRUE))) + { + skip("Failed to create a D3D device.\n"); + IDirect3D9_Release(context->d3d); + DestroyWindow(context->window); + return false; + } + + hr = IDirect3DDevice9_GetRenderTarget(context->device, 0, &context->backbuffer); + ok(hr == S_OK, "Failed to get backbuffer, hr %#lx.\n", hr); + + return true; +} + +#define release_test_context(a) release_test_context_(__LINE__, a) +static void release_test_context_(unsigned int line, struct d3d9_test_context *context) +{ + ULONG refcount; + + IDirect3DSurface9_Release(context->backbuffer); + refcount = IDirect3DDevice9_Release(context->device); + ok(!refcount, "Device has %lu references left.\n", refcount); + refcount = IDirect3D9_Release(context->d3d); + ok(!refcount, "D3D object has %lu references left.\n", refcount); + DestroyWindow(context->window); +} + +struct vec3 +{ + float x, y, z; +}; + +static void draw_quad(struct d3d9_test_context *context) +{ + IDirect3DDevice9 *device = context->device; + HRESULT hr; + + static const struct + { + struct vec3 position; + } + quad[] = + { + {{-1.0f, -1.0f, 0.0f}}, + {{-1.0f, 1.0f, 0.0f}}, + {{ 1.0f, -1.0f, 0.0f}}, + {{ 1.0f, 1.0f, 0.0f}}, + }; + + hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_BeginScene(device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_EndScene(device); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + +struct surface_readback +{ + IDirect3DSurface9 *surface; + D3DLOCKED_RECT locked_rect; +}; + +static uint32_t get_readback_color(struct surface_readback *rb, uint32_t x, uint32_t y) +{ + return rb->locked_rect.pBits + ? ((uint32_t *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(uint32_t) + x] : 0xdeadbeef; +} + +static void release_surface_readback(struct surface_readback *rb) +{ + HRESULT hr; + + if (!rb->surface) + return; + if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface))) + trace("Can't unlock the readback surface, hr %#lx.\n", hr); + IDirect3DSurface9_Release(rb->surface); +} + +static void get_surface_readback(IDirect3DDevice9 *device, IDirect3DSurface9 *surface, struct surface_readback *rb) +{ + D3DSURFACE_DESC desc; + HRESULT hr; + + hr = IDirect3DSurface9_GetDesc(surface, &desc); + if (FAILED(hr)) + { + trace("Failed to get surface description, hr %#lx.\n", hr); + goto exit; + } + + hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, + &rb->surface, NULL); + if (FAILED(hr)) + { + trace("Can't create the readback surface, hr %#lx.\n", hr); + goto exit; + } + + hr = D3DXLoadSurfaceFromSurface(rb->surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0); + if (FAILED(hr)) + { + trace("Can't load the readback surface, hr %#lx.\n", hr); + goto exit; + } + + hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY); + if (FAILED(hr)) + trace("Can't lock the readback surface, hr %#lx.\n", hr); + +exit: + if (FAILED(hr)) + { + if (rb->surface) + IDirect3DSurface9_Release(rb->surface); + rb->surface = NULL; + } +} + +static bool compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) +{ + unsigned int diff = x > y ? x - y : y - x; + + return diff <= max_diff; +} + +static bool color_match(uint32_t c1, uint32_t c2, unsigned int max_diff) +{ + return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) + && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff) + && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff) + && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); +} + static void test_get_shader_size(void) { UINT shader_size, expected; @@ -6647,6 +6838,65 @@ static void test_fragment_linker(void) } #endif
+static void test_hlsl_double(void) +{ + static const char vs_hlsl[] = + "float4 main(in float4 pos : POSITION) : POSITION\n" + "{\n" + " return pos;\n" + "}\n"; + static const char ps_hlsl[] = + "float func(float x){return 0.1;}\n" + "float func(half x){return 0.2;}\n" + "float func(double x){return 0.3;}\n" + "\n" + "float4 main(uniform double u) : COLOR\n" + "{\n" + " return func(u);\n" + "}\n"; + ID3DXBuffer *vs_bytecode, *ps_bytecode, *errors; + struct d3d9_test_context context; + struct surface_readback rb; + IDirect3DVertexShader9 *vs; + IDirect3DPixelShader9 *ps; + uint32_t color; + HRESULT hr; + + if (!init_test_context(&context)) + return; + + hr = D3DXCompileShader(vs_hlsl, sizeof(vs_hlsl), NULL, NULL, "main", "vs_2_0", 0, &vs_bytecode, &errors, NULL); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + + hr = D3DXCompileShader(ps_hlsl, sizeof(ps_hlsl), NULL, NULL, "main", "ps_2_0", 0, &ps_bytecode, &errors, NULL); + todo_wine ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + if (errors) + trace("%s", (char *)ID3DXBuffer_GetBufferPointer(errors)); + release_test_context(&context); + return; + } + + hr = IDirect3DDevice9_CreateVertexShader(context.device, ID3DXBuffer_GetBufferPointer(vs_bytecode), &vs); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_SetVertexShader(context.device, vs); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_CreatePixelShader(context.device, ID3DXBuffer_GetBufferPointer(ps_bytecode), &ps); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDevice9_SetPixelShader(context.device, ps); + ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr); + draw_quad(&context); + + get_surface_readback(context.device, context.backbuffer, &rb); + color = get_readback_color(&rb, 320, 240); + ok(color_match(color, 0x4c4c4c4c, 0), "Unexpected color %#x.\n", color); + release_surface_readback(&rb); + IDirect3DPixelShader9_Release(ps); + IDirect3DVertexShader9_Release(vs); + release_test_context(&context); +} + START_TEST(shader) { test_get_shader_size(); @@ -6664,4 +6914,5 @@ START_TEST(shader) #if D3DX_SDK_VERSION <= 41 test_fragment_linker(); #endif + test_hlsl_double(); }
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/d3dcompiler_43/tests/hlsl_d3d9.c | 42 ++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c index 2f7b90b2346..6a1e6482334 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d9.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d9.c @@ -1829,6 +1829,46 @@ static void test_no_output_blob(void) ok(!errors, "Unexpected errors blob.\n"); }
+static void test_hlsl_double(void) +{ + static const char ps_hlsl[] = + "float func(float x){return 0.1;}\n" + "float func(half x){return 0.2;}\n" + "float func(double x){return 0.3;}\n" + "\n" + "float4 main(uniform double u) : COLOR\n" + "{\n" + " return func(u);\n" + "}\n"; + ID3DBlob *ps_bytecode, *errors; + struct test_context context; + struct vec4 color; + HRESULT hr; + + if (!init_test_context(&context)) + return; + + hr = D3DCompile(ps_hlsl, sizeof(ps_hlsl), NULL, NULL, NULL, "main", "ps_2_0", 0, 0, &ps_bytecode, &errors); +#if D3D_COMPILER_VERSION >= 46 + todo_wine ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); +#else + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +#endif + if (FAILED(hr)) + { + trace("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors)); + release_test_context(&context); + return; + } + + draw_quad(context.device, ps_bytecode); + + color = get_color_vec4(context.device, 320, 240); + ok(compare_vec4(&color, 0.3, 0.3, 0.3, 0.3, 0), "Unexpected color {%.8e, %.8e, %.8e, %.8e}.\n", + color.x, color.y, color.z, color.w); + release_test_context(&context); +} + START_TEST(hlsl_d3d9) { char buffer[20]; @@ -1858,9 +1898,9 @@ START_TEST(hlsl_d3d9) test_struct_semantics(); test_global_initializer(); test_samplers(); - test_constant_table(); test_fail(); test_include(); test_no_output_blob(); + test_hlsl_double(); }