add_subdirectory(cryptui)
add_subdirectory(d3dcompiler_43)
add_subdirectory(d3drm)
+add_subdirectory(d3dx9_36)
add_subdirectory(devenum)
add_subdirectory(dinput)
add_subdirectory(dinput8)
--- /dev/null
+
+add_executable(d3dx9_36_winetest
+ asm.c
+ core.c
+ effect.c
+ line.c
+ math.c
+ mesh.c
+ shader.c
+ surface.c
+ texture.c
+ volume.c
+ xfile.c
+ testlist.c
+ rsrc.rc)
+target_compile_definitions(d3dx9_36_winetest PRIVATE -DUSE_WINE_TODOS -D__WINESRC__ -Disnan=_isnan)
+if(MSVC)
+ # Disable warning C4477 (printf format warnings)
+ target_compile_options(d3dx9_36_winetest PRIVATE "/wd4477")
+endif()
+
+target_link_libraries(d3dx9_36_winetest uuid dxguid)
+set_module_type(d3dx9_36_winetest win32cui)
+add_importlibs(d3dx9_36_winetest d3dx9_36 d3d9 user32 gdi32 msvcrt kernel32)
+add_rostests_file(TARGET d3dx9_36_winetest)
--- /dev/null
+/*
+ * Copyright (C) 2008 Stefan Dösinger
+ * Copyright (C) 2009 Matteo Bruni
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#define COBJMACROS
+#define CONST_VTABLE
+#include "wine/test.h"
+
+#include <d3dx9.h>
+
+#include "resources.h"
+
+static char temp_path[MAX_PATH];
+
+static BOOL create_file(const char *filename, const char *data, const unsigned int size, char *out_path)
+{
+ DWORD written;
+ HANDLE hfile;
+ char path[MAX_PATH];
+
+ if (!*temp_path)
+ GetTempPathA(sizeof(temp_path), temp_path);
+
+ strcpy(path, temp_path);
+ strcat(path, filename);
+ hfile = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (hfile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ if (WriteFile(hfile, data, size, &written, NULL))
+ {
+ CloseHandle(hfile);
+
+ if (out_path)
+ strcpy(out_path, path);
+ return TRUE;
+ }
+
+ CloseHandle(hfile);
+ return FALSE;
+}
+
+static void delete_file(const char *filename)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, filename);
+ DeleteFileA(path);
+}
+
+static BOOL create_directory(const char *name)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, name);
+ return CreateDirectoryA(path, NULL);
+}
+
+static void delete_directory(const char *name)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, name);
+ RemoveDirectoryA(path);
+}
+
+static HRESULT WINAPI testD3DXInclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type,
+ const char *filename, const void *parent_data, const void **data, UINT *bytes)
+{
+ char *buffer;
+ static const char shader[] =
+ "#include \"incl.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char include[] = "#define REGISTER r0\nvs.1.1\n";
+ static const char include2[] = "#include \"incl3.vsh\"\n";
+ static const char include3[] = "vs.1.1\n";
+
+ trace("filename %s.\n", filename);
+ trace("parent_data %p: %s.\n", parent_data, parent_data ? (char *)parent_data : "(null)");
+
+ if (!strcmp(filename, "shader.vsh"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(shader));
+ memcpy(buffer, shader, sizeof(shader));
+ *bytes = sizeof(shader);
+ }
+ else if (!strcmp(filename, "incl.vsh"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include));
+ memcpy(buffer, include, sizeof(include));
+ *bytes = sizeof(include);
+ /* This is included from the first D3DXAssembleShader with non-null ID3DXInclude test
+ * (parent_data == NULL) and from shader.vsh / shader[] (with matching parent_data).
+ * Allow both cases. */
+ ok(parent_data == NULL || !strncmp(shader, parent_data, strlen(shader)), "wrong parent_data value\n");
+ }
+ else if (!strcmp(filename, "incl2.vsh"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include2));
+ memcpy(buffer, include2, sizeof(include2));
+ *bytes = sizeof(include2);
+ }
+ else if (!strcmp(filename, "incl3.vsh"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include3));
+ memcpy(buffer, include3, sizeof(include3));
+ *bytes = sizeof(include3);
+ /* Also check for the correct parent_data content */
+ ok(parent_data != NULL && !strncmp(include2, parent_data, strlen(include2)), "wrong parent_data value\n");
+ }
+ else if (!strcmp(filename, "include/incl3.vsh"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include));
+ memcpy(buffer, include, sizeof(include));
+ *bytes = sizeof(include);
+ ok(!parent_data, "wrong parent_data value\n");
+ }
+ else
+ {
+ ok(0, "Unexpected #include for file %s.\n", filename);
+ return D3DERR_INVALIDCALL;
+ }
+ *data = buffer;
+ return S_OK;
+}
+
+static HRESULT WINAPI testD3DXInclude_close(ID3DXInclude *iface, const void *data)
+{
+ HeapFree(GetProcessHeap(), 0, (void *)data);
+ return S_OK;
+}
+
+static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = {
+ testD3DXInclude_open,
+ testD3DXInclude_close
+};
+
+struct D3DXIncludeImpl {
+ ID3DXInclude ID3DXInclude_iface;
+};
+
+static void assembleshader_test(void)
+{
+ static const char test1[] =
+ "vs.1.1\n"
+ "mov DEF2, v0\n";
+ static const char testincl[] =
+ "#define REGISTER r0\n"
+ "vs.1.1\n";
+ static const char testshader[] =
+ "#include \"incl.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char testshader2[] =
+ "#include \"incl2.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char testshader3[] =
+ "#include \"include/incl3.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char testincl3[] =
+ "#include \"incl4.vsh\"\n";
+ static const char testincl4_ok[] =
+ "#define REGISTER r0\n"
+ "vs.1.1\n";
+ static const char testincl4_wrong[] =
+ "#error \"wrong include\"\n";
+ HRESULT hr;
+ ID3DXBuffer *shader, *messages;
+ static const D3DXMACRO defines[] = {
+ {
+ "DEF1", "10 + 15"
+ },
+ {
+ "DEF2", "r0"
+ },
+ {
+ NULL, NULL
+ }
+ };
+ struct D3DXIncludeImpl include;
+ char shader_vsh_path[MAX_PATH], shader3_vsh_path[MAX_PATH];
+ static const WCHAR shader_filename_w[] = {'s','h','a','d','e','r','.','v','s','h',0};
+
+ /* pDefines test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShader(test1, strlen(test1),
+ defines, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3D_OK, "pDefines test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* NULL messages test */
+ shader = NULL;
+ hr = D3DXAssembleShader(test1, strlen(test1),
+ defines, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, NULL);
+ ok(hr == D3D_OK, "NULL messages test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* NULL shader test */
+ messages = NULL;
+ hr = D3DXAssembleShader(test1, strlen(test1),
+ defines, NULL, D3DXSHADER_SKIPVALIDATION,
+ NULL, &messages);
+ ok(hr == D3D_OK, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+
+ /* pInclude test */
+ shader = NULL;
+ messages = NULL;
+ include.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
+ hr = D3DXAssembleShader(testshader, strlen(testshader), NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* "unexpected #include file from memory" test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShader(testshader, strlen(testshader),
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* recursive #include test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShader(testshader2, strlen(testshader2), NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("recursive D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* #include with a path. */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShader(testshader3, strlen(testshader3), NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShader test failed with error 0x%x - %d\n", hr, hr & 0x0000ffff);
+ if (messages)
+ {
+ trace("Path search D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (shader)
+ ID3DXBuffer_Release(shader);
+
+ if (create_file("shader.vsh", testshader, sizeof(testshader) - 1, shader_vsh_path))
+ {
+ create_file("incl.vsh", testincl, sizeof(testincl) - 1, NULL);
+
+ /* D3DXAssembleShaderFromFile + #include test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileA(shader_vsh_path,
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromFile test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXAssembleShaderFromFile + pInclude test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileA("shader.vsh", NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ create_file("shader3.vsh", testshader3, sizeof(testshader3) - 1, shader3_vsh_path);
+ create_file("incl4.vsh", testincl4_wrong, sizeof(testincl4_wrong) - 1, NULL);
+ if (create_directory("include"))
+ {
+ create_file("include\\incl3.vsh", testincl3, sizeof(testincl3) - 1, NULL);
+ create_file("include\\incl4.vsh", testincl4_ok, sizeof(testincl4_ok) - 1, NULL);
+
+ /* path search #include test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileA(shader3_vsh_path, NULL, NULL,
+ D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromFile path search test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+ } else skip("Couldn't create \"include\" directory\n");
+
+ delete_file("shader.vsh");
+ delete_file("incl.vsh");
+ delete_file("shader3.vsh");
+ delete_file("incl4.vsh");
+ delete_file("include\\incl3.vsh");
+ delete_file("include\\incl4.vsh");
+ delete_directory("include");
+
+ /* The main shader is also to be loaded through the ID3DXInclude object. */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileA("shader.vsh", NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromFile + pInclude main shader test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000ffff);
+ if (messages)
+ {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (shader)
+ ID3DXBuffer_Release(shader);
+
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileW(shader_filename_w, NULL, &include.ID3DXInclude_iface,
+ D3DXSHADER_SKIPVALIDATION, &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromFile + pInclude main shader test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000ffff);
+ if (messages)
+ {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (shader)
+ ID3DXBuffer_Release(shader);
+ } else skip("Couldn't create \"shader.vsh\"\n");
+
+ /* NULL shader tests */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShader(NULL, 0,
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA, "NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromFileA("nonexistent.vsh",
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA || hr == E_FAIL, /* I get this on WinXP */
+ "D3DXAssembleShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXAssembleShaderFromResource test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromResourceA(NULL, MAKEINTRESOURCEA(IDB_ASMSHADER),
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXAssembleShaderFromResource test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXAssembleShaderFromResource with missing shader resource test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXAssembleShaderFromResourceA(NULL, "notexisting",
+ NULL, NULL, D3DXSHADER_SKIPVALIDATION,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXAssembleShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXAssembleShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+}
+
+static void d3dxpreprocess_test(void)
+{
+ static const char testincl[] =
+ "#define REGISTER r0\n"
+ "vs.1.1\n";
+ static const char testshader[] =
+ "#include \"incl.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char testshader3[] =
+ "#include \"include/incl3.vsh\"\n"
+ "mov REGISTER, v0\n";
+ static const char testincl3[] =
+ "#include \"incl4.vsh\"\n";
+ static const char testincl4_ok[] =
+ "#define REGISTER r0\n"
+ "vs.1.1\n";
+ static const char testincl4_wrong[] =
+ "#error \"wrong include\"\n";
+ HRESULT hr;
+ ID3DXBuffer *shader, *messages;
+ char shader_vsh_path[MAX_PATH], shader3_vsh_path[MAX_PATH];
+ static struct D3DXIncludeImpl include = {{&D3DXInclude_Vtbl}};
+ static const WCHAR shader_filename_w[] = {'s','h','a','d','e','r','.','v','s','h',0};
+
+ if (create_file("shader.vsh", testshader, sizeof(testshader) - 1, shader_vsh_path))
+ {
+ create_file("incl.vsh", testincl, sizeof(testincl) - 1, NULL);
+ create_file("shader3.vsh", testshader3, sizeof(testshader3) - 1, shader3_vsh_path);
+ create_file("incl4.vsh", testincl4_wrong, sizeof(testincl4_wrong) - 1, NULL);
+ if (create_directory("include"))
+ {
+ create_file("include\\incl3.vsh", testincl3, sizeof(testincl3) - 1, NULL);
+ create_file("include\\incl4.vsh", testincl4_ok, sizeof(testincl4_ok) - 1, NULL);
+
+ /* path search #include test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileA(shader3_vsh_path, NULL, NULL,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile path search test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShaderFromFile path search messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+ } else skip("Couldn't create \"include\" directory\n");
+
+ /* D3DXPreprocessShaderFromFile + #include test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileA(shader_vsh_path,
+ NULL, NULL,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXPreprocessShaderFromFile + pInclude test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileA("shader.vsh", NULL, &include.ID3DXInclude_iface,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile + pInclude test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShader messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ delete_file("shader.vsh");
+ delete_file("incl.vsh");
+ delete_file("shader3.vsh");
+ delete_file("incl4.vsh");
+ delete_file("include\\incl3.vsh");
+ delete_file("include\\incl4.vsh");
+ delete_directory("include");
+
+ /* The main shader is also to be loaded through the ID3DXInclude object. */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileA("shader.vsh", NULL, &include.ID3DXInclude_iface,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile + pInclude main shader test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000ffff);
+ if (messages)
+ {
+ trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (shader)
+ ID3DXBuffer_Release(shader);
+
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileW(shader_filename_w, NULL, &include.ID3DXInclude_iface,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromFile + pInclude main shader test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000ffff);
+ if (messages)
+ {
+ trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (shader)
+ ID3DXBuffer_Release(shader);
+ } else skip("Couldn't create \"shader.vsh\"\n");
+
+ /* NULL shader tests */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromFileA("nonexistent.vsh",
+ NULL, NULL,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA || hr == E_FAIL, /* I get this on WinXP */
+ "D3DXPreprocessShaderFromFile nonexistent file test failed with error 0x%x - %d\n",
+ hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShaderFromFile messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXPreprocessShaderFromResource test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromResourceA(NULL, MAKEINTRESOURCEA(IDB_ASMSHADER),
+ NULL, NULL,
+ &shader, &messages);
+ ok(hr == D3D_OK, "D3DXPreprocessShaderFromResource test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+
+ /* D3DXPreprocessShaderFromResource with missing shader resource test */
+ shader = NULL;
+ messages = NULL;
+ hr = D3DXPreprocessShaderFromResourceA(NULL, "notexisting",
+ NULL, NULL,
+ &shader, &messages);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXPreprocessShaderFromResource NULL shader test failed with error 0x%x - %d\n", hr, hr & 0x0000FFFF);
+ if(messages) {
+ trace("D3DXPreprocessShaderFromResource messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if(shader) ID3DXBuffer_Release(shader);
+}
+
+START_TEST(asm)
+{
+ assembleshader_test();
+
+ d3dxpreprocess_test();
+}
--- /dev/null
+/*
+ * Tests for the D3DX9 core interfaces
+ *
+ * Copyright 2009 Tony Wasserka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "wine/test.h"
+#include <dxerr9.h>
+#include "d3dx9core.h"
+
+static inline int get_ref(IUnknown *obj)
+{
+ IUnknown_AddRef(obj);
+ return IUnknown_Release(obj);
+}
+
+#define check_ref(obj, exp) _check_ref(__LINE__, obj, exp)
+static inline void _check_ref(unsigned int line, IUnknown *obj, int exp)
+{
+ int ref = get_ref(obj);
+ ok_(__FILE__, line)(exp == ref, "Invalid refcount. Expected %d, got %d\n", exp, ref);
+}
+
+#define check_release(obj, exp) _check_release(__LINE__, obj, exp)
+static inline void _check_release(unsigned int line, IUnknown *obj, int exp)
+{
+ int ref = IUnknown_Release(obj);
+ ok_(__FILE__, line)(ref == exp, "Invalid refcount. Expected %d, got %d\n", exp, ref);
+}
+
+#define admitted_error 0.0001f
+static inline void check_mat(D3DXMATRIX got, D3DXMATRIX exp)
+{
+ int i, j, equal=1;
+ for (i=0; i<4; i++)
+ for (j=0; j<4; j++)
+ if (fabs(U(exp).m[i][j]-U(got).m[i][j]) > admitted_error)
+ equal=0;
+
+ ok(equal, "Got matrix\n\t(%f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f)\n"
+ "Expected matrix=\n\t(%f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f\n\t %f,%f,%f,%f)\n",
+ U(got).m[0][0],U(got).m[0][1],U(got).m[0][2],U(got).m[0][3],
+ U(got).m[1][0],U(got).m[1][1],U(got).m[1][2],U(got).m[1][3],
+ U(got).m[2][0],U(got).m[2][1],U(got).m[2][2],U(got).m[2][3],
+ U(got).m[3][0],U(got).m[3][1],U(got).m[3][2],U(got).m[3][3],
+ U(exp).m[0][0],U(exp).m[0][1],U(exp).m[0][2],U(exp).m[0][3],
+ U(exp).m[1][0],U(exp).m[1][1],U(exp).m[1][2],U(exp).m[1][3],
+ U(exp).m[2][0],U(exp).m[2][1],U(exp).m[2][2],U(exp).m[2][3],
+ U(exp).m[3][0],U(exp).m[3][1],U(exp).m[3][2],U(exp).m[3][3]);
+}
+
+static void test_ID3DXBuffer(void)
+{
+ ID3DXBuffer *buffer;
+ HRESULT hr;
+ ULONG count;
+ DWORD size;
+
+ hr = D3DXCreateBuffer(10, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateBuffer failed, got %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateBuffer(0, &buffer);
+ ok(hr == D3D_OK, "D3DXCreateBuffer failed, got %#x, expected %#x\n", hr, D3D_OK);
+
+ size = ID3DXBuffer_GetBufferSize(buffer);
+ ok(!size, "GetBufferSize failed, got %u, expected %u\n", size, 0);
+
+ count = ID3DXBuffer_Release(buffer);
+ ok(!count, "ID3DXBuffer has %u references left\n", count);
+
+ hr = D3DXCreateBuffer(3, &buffer);
+ ok(hr == D3D_OK, "D3DXCreateBuffer failed, got %#x, expected %#x\n", hr, D3D_OK);
+
+ size = ID3DXBuffer_GetBufferSize(buffer);
+ ok(size == 3, "GetBufferSize failed, got %u, expected %u\n", size, 3);
+
+ count = ID3DXBuffer_Release(buffer);
+ ok(!count, "ID3DXBuffer has %u references left\n", count);
+}
+
+static void test_ID3DXSprite(IDirect3DDevice9 *device)
+{
+ ID3DXSprite *sprite;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *cmpdev;
+ IDirect3DTexture9 *tex1, *tex2;
+ D3DXMATRIX mat, cmpmat;
+ D3DVIEWPORT9 vp;
+ RECT rect;
+ D3DXVECTOR3 pos, center;
+ HRESULT hr;
+
+ IDirect3DDevice9_GetDirect3D(device, &d3d);
+ hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
+ IDirect3D9_Release(d3d);
+ ok (hr == D3D_OK, "D3DFMT_A8R8G8B8 not supported\n");
+ if (FAILED(hr)) return;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
+ ok (hr == D3D_OK, "Failed to create first texture (error code: %#x)\n", hr);
+ if (FAILED(hr)) return;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
+ ok (hr == D3D_OK, "Failed to create second texture (error code: %#x)\n", hr);
+ if (FAILED(hr)) {
+ IDirect3DTexture9_Release(tex1);
+ return;
+ }
+
+ /* Test D3DXCreateSprite */
+ hr = D3DXCreateSprite(device, NULL);
+ ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSprite(NULL, &sprite);
+ ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSprite(device, &sprite);
+ ok (hr == D3D_OK, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3D_OK);
+
+
+ /* Test ID3DXSprite_GetDevice */
+ hr = ID3DXSprite_GetDevice(sprite, NULL);
+ ok (hr == D3DERR_INVALIDCALL, "GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev == NULL */
+ ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev != NULL */
+ ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DDevice9_Release(device);
+ IDirect3DDevice9_Release(device);
+
+
+ /* Test ID3DXSprite_GetTransform */
+ hr = ID3DXSprite_GetTransform(sprite, NULL);
+ ok (hr == D3DERR_INVALIDCALL, "GetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXSprite_GetTransform(sprite, &mat);
+ ok (hr == D3D_OK, "GetTransform returned %#x, expected %#x\n", hr, D3D_OK);
+ if(SUCCEEDED(hr)) {
+ D3DXMATRIX identity;
+ D3DXMatrixIdentity(&identity);
+ check_mat(mat, identity);
+ }
+
+ /* Test ID3DXSprite_SetTransform */
+ /* Set a transform and test if it gets returned correctly */
+ U(mat).m[0][0]=2.1f; U(mat).m[0][1]=6.5f; U(mat).m[0][2]=-9.6f; U(mat).m[0][3]=1.7f;
+ U(mat).m[1][0]=4.2f; U(mat).m[1][1]=-2.5f; U(mat).m[1][2]=2.1f; U(mat).m[1][3]=5.5f;
+ U(mat).m[2][0]=-2.6f; U(mat).m[2][1]=0.3f; U(mat).m[2][2]=8.6f; U(mat).m[2][3]=8.4f;
+ U(mat).m[3][0]=6.7f; U(mat).m[3][1]=-5.1f; U(mat).m[3][2]=6.1f; U(mat).m[3][3]=2.2f;
+
+ hr = ID3DXSprite_SetTransform(sprite, NULL);
+ ok (hr == D3DERR_INVALIDCALL, "SetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXSprite_SetTransform(sprite, &mat);
+ ok (hr == D3D_OK, "SetTransform returned %#x, expected %#x\n", hr, D3D_OK);
+ if(SUCCEEDED(hr)) {
+ hr=ID3DXSprite_GetTransform(sprite, &cmpmat);
+ if(SUCCEEDED(hr)) check_mat(cmpmat, mat);
+ else skip("GetTransform returned %#x\n", hr);
+ }
+
+ /* Test ID3DXSprite_SetWorldViewLH/RH */
+ todo_wine {
+ hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, &mat);
+ ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, &mat);
+ ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, NULL);
+ ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, NULL);
+ ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, &mat);
+ ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, &mat);
+ ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, NULL);
+ ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, NULL);
+ ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+ IDirect3DDevice9_BeginScene(device);
+
+ /* Test ID3DXSprite_Begin*/
+ hr = ID3DXSprite_Begin(sprite, 0);
+ ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &mat);
+ D3DXMatrixIdentity(&cmpmat);
+ check_mat(mat, cmpmat);
+
+ IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &mat);
+ check_mat(mat, cmpmat);
+
+ IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &mat);
+ IDirect3DDevice9_GetViewport(device, &vp);
+ D3DXMatrixOrthoOffCenterLH(&cmpmat, vp.X+0.5f, (float)vp.Width+vp.X+0.5f, (float)vp.Height+vp.Y+0.5f, vp.Y+0.5f, vp.MinZ, vp.MaxZ);
+ check_mat(mat, cmpmat);
+
+ /* Test ID3DXSprite_Flush and ID3DXSprite_End */
+ hr = ID3DXSprite_Flush(sprite);
+ ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXSprite_Flush(sprite); /* May not be called before next Begin */
+ ok (hr == D3DERR_INVALIDCALL, "Flush returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* Test ID3DXSprite_Draw */
+ hr = ID3DXSprite_Begin(sprite, 0);
+ ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if(FAILED(hr)) skip("Couldn't ID3DXSprite_Begin, can't test ID3DXSprite_Draw\n");
+ else { /* Feed the sprite batch */
+ int texref1, texref2;
+
+ SetRect(&rect, 53, 12, 142, 165);
+ pos.x = 2.2f; pos.y = 4.5f; pos.z = 5.1f;
+ center.x = 11.3f; center.y = 3.4f; center.z = 1.2f;
+
+ texref1 = get_ref((IUnknown*)tex1);
+ texref2 = get_ref((IUnknown*)tex2);
+
+ hr = ID3DXSprite_Draw(sprite, NULL, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3DERR_INVALIDCALL, "Draw returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB( 3, 45, 66));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex1, NULL, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex1, &rect, NULL, &pos, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, NULL, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex1, NULL, NULL, NULL, 0);
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+
+ check_ref((IUnknown*)tex1, texref1+5); check_ref((IUnknown*)tex2, texref2+1);
+ hr = ID3DXSprite_Flush(sprite);
+ ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Flush(sprite); /* Flushing twice should work */
+ ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK);
+ check_ref((IUnknown*)tex1, texref1); check_ref((IUnknown*)tex2, texref2);
+
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+
+ /* Test ID3DXSprite_OnLostDevice and ID3DXSprite_OnResetDevice */
+ /* Both can be called twice */
+ hr = ID3DXSprite_OnLostDevice(sprite);
+ ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_OnLostDevice(sprite);
+ ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_OnResetDevice(sprite);
+ ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_OnResetDevice(sprite);
+ ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+
+ /* Make sure everything works like before */
+ hr = ID3DXSprite_Begin(sprite, 0);
+ ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255));
+ ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_Flush(sprite);
+ ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK);
+
+ /* OnResetDevice makes the interface "forget" the Begin call */
+ hr = ID3DXSprite_Begin(sprite, 0);
+ ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_OnResetDevice(sprite);
+ ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DDevice9_EndScene(device);
+ check_release((IUnknown*)sprite, 0);
+ check_release((IUnknown*)tex2, 0);
+ check_release((IUnknown*)tex1, 0);
+}
+
+static void test_ID3DXFont(IDirect3DDevice9 *device)
+{
+ static const WCHAR testW[] = {'t','e','s','t',0};
+ static const struct
+ {
+ int font_height;
+ unsigned int expected_size;
+ unsigned int expected_levels;
+ }
+ tests[] =
+ {
+ { 6, 128, 4 },
+ { 8, 128, 4 },
+ { 10, 256, 5 },
+ { 12, 256, 5 },
+ { 72, 256, 8 },
+ };
+ const unsigned int size = ARRAY_SIZE(testW);
+ D3DXFONT_DESCA desc;
+ ID3DXSprite *sprite;
+ int ref, i, height;
+ ID3DXFont *font;
+ HRESULT hr;
+ RECT rect;
+
+ /* D3DXCreateFont */
+ ref = get_ref((IUnknown*)device);
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ ok(hr == D3D_OK, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3D_OK);
+ check_ref((IUnknown*)device, ref + 1);
+ check_release((IUnknown*)font, 0);
+ check_ref((IUnknown*)device, ref);
+
+ hr = D3DXCreateFontA(device, 0, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ ok(hr == D3D_OK, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3D_OK);
+ ID3DXFont_Release(font);
+
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, NULL, &font);
+ ok(hr == D3D_OK, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3D_OK);
+ ID3DXFont_Release(font);
+
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "", &font);
+ ok(hr == D3D_OK, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3D_OK);
+ ID3DXFont_Release(font);
+
+ hr = D3DXCreateFontA(NULL, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateFontA(NULL, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFont returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* D3DXCreateFontIndirect */
+ desc.Height = 12;
+ desc.Width = 0;
+ desc.Weight = FW_DONTCARE;
+ desc.MipLevels = 0;
+ desc.Italic = FALSE;
+ desc.CharSet = DEFAULT_CHARSET;
+ desc.OutputPrecision = OUT_DEFAULT_PRECIS;
+ desc.Quality = DEFAULT_QUALITY;
+ desc.PitchAndFamily = DEFAULT_PITCH;
+ strcpy(desc.FaceName, "Arial");
+ hr = D3DXCreateFontIndirectA(device, &desc, &font);
+ ok(hr == D3D_OK, "D3DXCreateFontIndirect returned %#x, expected %#x\n", hr, D3D_OK);
+ ID3DXFont_Release(font);
+
+ hr = D3DXCreateFontIndirectA(NULL, &desc, &font);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFontIndirect returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateFontIndirectA(device, NULL, &font);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFontIndirect returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateFontIndirectA(device, &desc, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateFontIndirect returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* ID3DXFont_GetDevice */
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ if(SUCCEEDED(hr)) {
+ IDirect3DDevice9 *bufdev;
+
+ hr = ID3DXFont_GetDevice(font, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ ref = get_ref((IUnknown*)device);
+ hr = ID3DXFont_GetDevice(font, &bufdev);
+ ok(hr == D3D_OK, "ID3DXFont_GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ check_release((IUnknown*)bufdev, ref);
+
+ ID3DXFont_Release(font);
+ } else skip("Failed to create a ID3DXFont object\n");
+
+
+ /* ID3DXFont_GetDesc */
+ hr = D3DXCreateFontA(device, 12, 8, FW_BOLD, 2, TRUE, ANSI_CHARSET, OUT_RASTER_PRECIS, ANTIALIASED_QUALITY, VARIABLE_PITCH, "Arial", &font);
+ if(SUCCEEDED(hr)) {
+ hr = ID3DXFont_GetDescA(font, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXFont_GetDescA(font, &desc);
+ ok(hr == D3D_OK, "ID3DXFont_GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(desc.Height == 12, "ID3DXFont_GetDesc returned font height %d, expected %d\n", desc.Height, 12);
+ ok(desc.Width == 8, "ID3DXFont_GetDesc returned font width %d, expected %d\n", desc.Width, 8);
+ ok(desc.Weight == FW_BOLD, "ID3DXFont_GetDesc returned font weight %d, expected %d\n", desc.Weight, FW_BOLD);
+ ok(desc.MipLevels == 2, "ID3DXFont_GetDesc returned font miplevels %d, expected %d\n", desc.MipLevels, 2);
+ ok(desc.Italic == TRUE, "ID3DXFont_GetDesc says Italic was %d, but Italic should be %d\n", desc.Italic, TRUE);
+ ok(desc.CharSet == ANSI_CHARSET, "ID3DXFont_GetDesc returned font charset %d, expected %d\n", desc.CharSet, ANSI_CHARSET);
+ ok(desc.OutputPrecision == OUT_RASTER_PRECIS, "ID3DXFont_GetDesc returned an output precision of %d, expected %d\n", desc.OutputPrecision, OUT_RASTER_PRECIS);
+ ok(desc.Quality == ANTIALIASED_QUALITY, "ID3DXFont_GetDesc returned font quality %d, expected %d\n", desc.Quality, ANTIALIASED_QUALITY);
+ ok(desc.PitchAndFamily == VARIABLE_PITCH, "ID3DXFont_GetDesc returned pitch and family %d, expected %d\n", desc.PitchAndFamily, VARIABLE_PITCH);
+ ok(strcmp(desc.FaceName, "Arial") == 0, "ID3DXFont_GetDesc returned facename \"%s\", expected \"%s\"\n", desc.FaceName, "Arial");
+
+ ID3DXFont_Release(font);
+ } else skip("Failed to create a ID3DXFont object\n");
+
+
+ /* ID3DXFont_GetDC + ID3DXFont_GetTextMetrics */
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ if(SUCCEEDED(hr)) {
+ HDC hdc;
+
+ hdc = ID3DXFont_GetDC(font);
+ ok(hdc != NULL, "ID3DXFont_GetDC returned an invalid handle\n");
+ if(hdc) {
+ TEXTMETRICA metrics, expmetrics;
+ BOOL ret;
+
+ ret = ID3DXFont_GetTextMetricsA(font, &metrics);
+ ok(ret, "ID3DXFont_GetTextMetricsA failed\n");
+ ret = GetTextMetricsA(hdc, &expmetrics);
+ ok(ret, "GetTextMetricsA failed\n");
+
+ ok(metrics.tmHeight == expmetrics.tmHeight, "Returned height %d, expected %d\n", metrics.tmHeight, expmetrics.tmHeight);
+ ok(metrics.tmAscent == expmetrics.tmAscent, "Returned ascent %d, expected %d\n", metrics.tmAscent, expmetrics.tmAscent);
+ ok(metrics.tmDescent == expmetrics.tmDescent, "Returned descent %d, expected %d\n", metrics.tmDescent, expmetrics.tmDescent);
+ ok(metrics.tmInternalLeading == expmetrics.tmInternalLeading, "Returned internal leading %d, expected %d\n", metrics.tmInternalLeading, expmetrics.tmInternalLeading);
+ ok(metrics.tmExternalLeading == expmetrics.tmExternalLeading, "Returned external leading %d, expected %d\n", metrics.tmExternalLeading, expmetrics.tmExternalLeading);
+ ok(metrics.tmAveCharWidth == expmetrics.tmAveCharWidth, "Returned average char width %d, expected %d\n", metrics.tmAveCharWidth, expmetrics.tmAveCharWidth);
+ ok(metrics.tmMaxCharWidth == expmetrics.tmMaxCharWidth, "Returned maximum char width %d, expected %d\n", metrics.tmMaxCharWidth, expmetrics.tmMaxCharWidth);
+ ok(metrics.tmWeight == expmetrics.tmWeight, "Returned weight %d, expected %d\n", metrics.tmWeight, expmetrics.tmWeight);
+ ok(metrics.tmOverhang == expmetrics.tmOverhang, "Returned overhang %d, expected %d\n", metrics.tmOverhang, expmetrics.tmOverhang);
+ ok(metrics.tmDigitizedAspectX == expmetrics.tmDigitizedAspectX, "Returned digitized x aspect %d, expected %d\n", metrics.tmDigitizedAspectX, expmetrics.tmDigitizedAspectX);
+ ok(metrics.tmDigitizedAspectY == expmetrics.tmDigitizedAspectY, "Returned digitized y aspect %d, expected %d\n", metrics.tmDigitizedAspectY, expmetrics.tmDigitizedAspectY);
+ ok(metrics.tmFirstChar == expmetrics.tmFirstChar, "Returned first char %d, expected %d\n", metrics.tmFirstChar, expmetrics.tmFirstChar);
+ ok(metrics.tmLastChar == expmetrics.tmLastChar, "Returned last char %d, expected %d\n", metrics.tmLastChar, expmetrics.tmLastChar);
+ ok(metrics.tmDefaultChar == expmetrics.tmDefaultChar, "Returned default char %d, expected %d\n", metrics.tmDefaultChar, expmetrics.tmDefaultChar);
+ ok(metrics.tmBreakChar == expmetrics.tmBreakChar, "Returned break char %d, expected %d\n", metrics.tmBreakChar, expmetrics.tmBreakChar);
+ ok(metrics.tmItalic == expmetrics.tmItalic, "Returned italic %d, expected %d\n", metrics.tmItalic, expmetrics.tmItalic);
+ ok(metrics.tmUnderlined == expmetrics.tmUnderlined, "Returned underlined %d, expected %d\n", metrics.tmUnderlined, expmetrics.tmUnderlined);
+ ok(metrics.tmStruckOut == expmetrics.tmStruckOut, "Returned struck out %d, expected %d\n", metrics.tmStruckOut, expmetrics.tmStruckOut);
+ ok(metrics.tmPitchAndFamily == expmetrics.tmPitchAndFamily, "Returned pitch and family %d, expected %d\n", metrics.tmPitchAndFamily, expmetrics.tmPitchAndFamily);
+ ok(metrics.tmCharSet == expmetrics.tmCharSet, "Returned charset %d, expected %d\n", metrics.tmCharSet, expmetrics.tmCharSet);
+ }
+ ID3DXFont_Release(font);
+ } else skip("Failed to create a ID3DXFont object\n");
+
+
+ /* ID3DXFont_PreloadText */
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ if(SUCCEEDED(hr)) {
+ todo_wine {
+ hr = ID3DXFont_PreloadTextA(font, NULL, -1);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXFont_PreloadTextA(font, NULL, 0);
+ ok(hr == D3D_OK, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXFont_PreloadTextA(font, NULL, 1);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXFont_PreloadTextA(font, "test", -1);
+ ok(hr == D3D_OK, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXFont_PreloadTextW(font, NULL, -1);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXFont_PreloadTextW(font, NULL, 0);
+ ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXFont_PreloadTextW(font, NULL, 1);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXFont_PreloadTextW(font, testW, -1);
+ ok(hr == D3D_OK, "ID3DXFont_PreloadTextW returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+
+ check_release((IUnknown*)font, 0);
+ } else skip("Failed to create a ID3DXFont object\n");
+
+
+ /* ID3DXFont_GetGlyphData, ID3DXFont_PreloadGlyphs, ID3DXFont_PreloadCharacters */
+ hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ if(SUCCEEDED(hr)) {
+ char c;
+ HDC hdc;
+ DWORD ret;
+ HRESULT hr;
+ RECT blackbox;
+ POINT cellinc;
+ IDirect3DTexture9 *texture;
+
+ hdc = ID3DXFont_GetDC(font);
+
+ todo_wine {
+ hr = ID3DXFont_GetGlyphData(font, 0, NULL, &blackbox, &cellinc);
+ ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXFont_GetGlyphData(font, 0, &texture, NULL, &cellinc);
+ if(SUCCEEDED(hr)) check_release((IUnknown*)texture, 1);
+ ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXFont_GetGlyphData(font, 0, &texture, &blackbox, NULL);
+ if(SUCCEEDED(hr)) check_release((IUnknown*)texture, 1);
+ ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+ hr = ID3DXFont_PreloadCharacters(font, 'b', 'a');
+ ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXFont_PreloadGlyphs(font, 1, 0);
+ todo_wine ok(hr == D3D_OK, "ID3DXFont_PreloadGlyphs returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXFont_PreloadCharacters(font, 'a', 'a');
+ ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK);
+
+ for(c = 'b'; c <= 'z'; c++) {
+ WORD glyph;
+
+ ret = GetGlyphIndicesA(hdc, &c, 1, &glyph, 0);
+ ok(ret != GDI_ERROR, "GetGlyphIndicesA failed\n");
+
+ hr = ID3DXFont_GetGlyphData(font, glyph, &texture, &blackbox, &cellinc);
+ todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK);
+ if(SUCCEEDED(hr)) {
+ DWORD levels;
+ D3DSURFACE_DESC desc;
+
+ levels = IDirect3DTexture9_GetLevelCount(texture);
+ ok(levels == 5, "Got levels %u, expected %u\n", levels, 5);
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n");
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8);
+ ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0);
+ ok(desc.Width == 256, "Got width %u, expected %u\n", desc.Width, 256);
+ ok(desc.Height == 256, "Got height %u, expected %u\n", desc.Height, 256);
+ ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED);
+
+ check_release((IUnknown*)texture, 1);
+ }
+ }
+
+ hr = ID3DXFont_PreloadCharacters(font, 'a', 'z');
+ ok(hr == D3D_OK, "ID3DXFont_PreloadCharacters returned %#x, expected %#x\n", hr, D3D_OK);
+
+ check_release((IUnknown*)font, 0);
+ } else skip("Failed to create a ID3DXFont object\n");
+
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
+ HDC hdc;
+ DWORD ret;
+ HRESULT hr;
+ WORD glyph;
+ char c = 'a';
+ IDirect3DTexture9 *texture;
+
+ hr = D3DXCreateFontA(device, tests[i].font_height, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ if(FAILED(hr)) {
+ skip("Failed to create a ID3DXFont object\n");
+ continue;
+ }
+
+ hdc = ID3DXFont_GetDC(font);
+
+ ret = GetGlyphIndicesA(hdc, &c, 1, &glyph, 0);
+ ok(ret != GDI_ERROR, "GetGlyphIndicesA failed\n");
+
+ hr = ID3DXFont_GetGlyphData(font, glyph, &texture, NULL, NULL);
+ todo_wine ok(hr == D3D_OK, "ID3DXFont_GetGlyphData returned %#x, expected %#x\n", hr, D3D_OK);
+ if(SUCCEEDED(hr)) {
+ DWORD levels;
+ D3DSURFACE_DESC desc;
+
+ levels = IDirect3DTexture9_GetLevelCount(texture);
+ ok(levels == tests[i].expected_levels, "Got levels %u, expected %u\n",
+ levels, tests[i].expected_levels);
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n");
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8);
+ ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0);
+ ok(desc.Width == tests[i].expected_size, "Got width %u, expected %u\n",
+ desc.Width, tests[i].expected_size);
+ ok(desc.Height == tests[i].expected_size, "Got height %u, expected %u\n",
+ desc.Height, tests[i].expected_size);
+ ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+ /* ID3DXFontImpl_DrawText */
+ D3DXCreateSprite(device, &sprite);
+ SetRect(&rect, 0, 0, 640, 480);
+
+ IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
+
+ IDirect3DDevice9_BeginScene(device);
+ hr = ID3DXSprite_Begin(sprite, D3DXSPRITE_ALPHABLEND);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ todo_wine
+ {
+ height = ID3DXFont_DrawTextW(font, sprite, testW, -1, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_RIGHT, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_NOCLIP,
+ 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ }
+
+ SetRectEmpty(&rect);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect,
+ DT_LEFT | DT_CALCRECT, 0xffffffff);
+ todo_wine ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ ok(!rect.left, "Got unexpected rect left %d.\n", rect.left);
+ ok(!rect.top, "Got unexpected rect top %d.\n", rect.top);
+ todo_wine ok(rect.right, "Got unexpected rect right %d.\n", rect.right);
+ todo_wine ok(rect.bottom == tests[i].font_height, "Got unexpected rect bottom %d.\n", rect.bottom);
+
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ IDirect3DDevice9_EndScene(device);
+ ID3DXSprite_Release(sprite);
+
+ ID3DXFont_Release(font);
+ }
+}
+
+static void test_D3DXCreateRenderToSurface(IDirect3DDevice9 *device)
+{
+ int i;
+ HRESULT hr;
+ ULONG ref_count;
+ D3DXRTS_DESC desc;
+ ID3DXRenderToSurface *render = (void *)0xdeadbeef;
+ static const D3DXRTS_DESC tests[] =
+ {
+ { 0, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN },
+ { 256, 0, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN },
+ { 256, 0, D3DFMT_A8R8G8B8, FALSE, D3DFMT_D24S8 },
+ { 256, 256, D3DFMT_UNKNOWN, FALSE, D3DFMT_R8G8B8 },
+ { 0, 0, D3DFMT_UNKNOWN, FALSE, D3DFMT_UNKNOWN },
+ { -1, -1, MAKEFOURCC('B','A','D','F'), TRUE, MAKEFOURCC('B','A','D','F') }
+ };
+
+ hr = D3DXCreateRenderToSurface(NULL /* device */, 256, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, &render);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateRenderToSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ ok(render == (void *)0xdeadbeef, "Got %p, expected %p\n", render, (void *)0xdeadbeef);
+
+ hr = D3DXCreateRenderToSurface(device, 256, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, NULL /* out */);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateRenderToSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ hr = D3DXCreateRenderToSurface(device, tests[i].Width, tests[i].Height, tests[i].Format, tests[i].DepthStencil,
+ tests[i].DepthStencilFormat, &render);
+ ok(hr == D3D_OK, "%d: D3DXCreateRenderToSurface returned %#x, expected %#x\n", i, hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ hr = ID3DXRenderToSurface_GetDesc(render, &desc);
+ ok(hr == D3D_OK, "%d: GetDesc failed %#x\n", i, hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(desc.Width == tests[i].Width, "%d: Got width %u, expected %u\n", i, desc.Width, tests[i].Width);
+ ok(desc.Height == tests[i].Height, "%d: Got height %u, expected %u\n", i, desc.Height, tests[i].Height);
+ ok(desc.Format == tests[i].Format, "%d: Got format %#x, expected %#x\n", i, desc.Format, tests[i].Format);
+ ok(desc.DepthStencil == tests[i].DepthStencil, "%d: Got depth stencil %d, expected %d\n",
+ i, desc.DepthStencil, tests[i].DepthStencil);
+ ok(desc.DepthStencilFormat == tests[i].DepthStencilFormat, "%d: Got depth stencil format %#x, expected %#x\n",
+ i, desc.DepthStencilFormat, tests[i].DepthStencilFormat);
+ }
+ ID3DXRenderToSurface_Release(render);
+ }
+ }
+
+ /* check device ref count */
+ ref_count = get_ref((IUnknown *)device);
+ hr = D3DXCreateRenderToSurface(device, 0, 0, D3DFMT_UNKNOWN, FALSE, D3DFMT_UNKNOWN, &render);
+ check_ref((IUnknown *)device, ref_count + 1);
+ if (SUCCEEDED(hr)) ID3DXRenderToSurface_Release(render);
+}
+
+/* runs a set of tests for the ID3DXRenderToSurface interface created with given parameters */
+static void check_ID3DXRenderToSurface(IDirect3DDevice9 *device, UINT width, UINT height, D3DFORMAT format,
+ BOOL depth_stencil, D3DFORMAT depth_stencil_format, BOOL render_target)
+{
+ HRESULT hr;
+ D3DFORMAT fmt;
+ HRESULT expected_value;
+ IDirect3DSurface9 *surface;
+ ID3DXRenderToSurface *render;
+ D3DVIEWPORT9 viewport = { 0, 0, width, height, 0.0, 1.0 };
+
+ hr = D3DXCreateRenderToSurface(device, width, height, format, depth_stencil, depth_stencil_format, &render);
+ if (FAILED(hr))
+ {
+ skip("Failed to create ID3DXRenderToSurface\n");
+ return;
+ }
+
+ if (render_target)
+ hr = IDirect3DDevice9_CreateRenderTarget(device, width, height, format, D3DMULTISAMPLE_NONE, 0, FALSE, &surface, NULL);
+ else
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create surface\n");
+ ID3DXRenderToSurface_Release(render);
+ return;
+ }
+
+ /* viewport */
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3D_OK);
+ check_ref((IUnknown *)surface, 2);
+ if (SUCCEEDED(hr)) ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+
+ /* invalid viewport */
+ viewport.Width = 2 * width;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ viewport.X = width / 2;
+ viewport.Width = width;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ viewport.X = width;
+ viewport.Width = width;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* rendering to a part of a surface is only allowed for render target surfaces */
+ expected_value = render_target ? D3D_OK : D3DERR_INVALIDCALL;
+
+ viewport.X = 0;
+ viewport.Width = width / 2;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == expected_value, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, expected_value);
+ if (SUCCEEDED(hr)) ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+
+ viewport.X = width / 2;
+ viewport.Width = width - width / 2;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == expected_value, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, expected_value);
+ if (SUCCEEDED(hr)) ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+
+ check_release((IUnknown *)surface, 0);
+
+ /* surfaces with different sizes */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width / 2, width / 2, format, D3DPOOL_DEFAULT, &surface, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create surface\n");
+ ID3DXRenderToSurface_Release(render);
+ return;
+ }
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ check_release((IUnknown *)surface, 0);
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2 * width, 2 * height, format, D3DPOOL_DEFAULT, &surface, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create surface\n");
+ ID3DXRenderToSurface_Release(render);
+ return;
+ }
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ viewport.X = 0;
+ viewport.Y = 0;
+ viewport.Width = width;
+ viewport.Height = height;
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, &viewport);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ check_release((IUnknown *)surface, 0);
+
+ /* surfaces with different formats */
+ for (fmt = D3DFMT_A8R8G8B8; fmt <= D3DFMT_X8R8G8B8; fmt++)
+ {
+ HRESULT expected_result = (fmt != format) ? D3DERR_INVALIDCALL : D3D_OK;
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, fmt, D3DPOOL_DEFAULT, &surface, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create surface\n");
+ continue;
+ }
+
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == expected_result, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, expected_result);
+
+ if (SUCCEEDED(hr)) ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+ check_release((IUnknown *)surface, 0);
+ }
+
+ check_release((IUnknown *)render, 0);
+}
+
+struct device_state
+{
+ IDirect3DSurface9 *render_target;
+ IDirect3DSurface9 *depth_stencil;
+ D3DVIEWPORT9 viewport;
+};
+
+static void release_device_state(struct device_state *state)
+{
+ if (state->render_target) IDirect3DSurface9_Release(state->render_target);
+ if (state->depth_stencil) IDirect3DSurface9_Release(state->depth_stencil);
+ memset(state, 0, sizeof(*state));
+}
+
+static HRESULT retrieve_device_state(IDirect3DDevice9 *device, struct device_state *state)
+{
+ HRESULT hr;
+
+ memset(state, 0, sizeof(*state));
+
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &state->render_target);
+ if (FAILED(hr)) goto cleanup;
+
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &state->depth_stencil);
+ if (hr == D3DERR_NOTFOUND)
+ state->depth_stencil = NULL;
+ else if (FAILED(hr))
+ goto cleanup;
+
+ hr = IDirect3DDevice9_GetViewport(device, &state->viewport);
+ if (SUCCEEDED(hr)) return hr;
+
+cleanup:
+ release_device_state(state);
+ return hr;
+}
+
+static HRESULT apply_device_state(IDirect3DDevice9 *device, struct device_state *state)
+{
+ HRESULT hr;
+ HRESULT status = D3D_OK;
+
+ hr = IDirect3DDevice9_SetRenderTarget(device, 0, state->render_target);
+ if (FAILED(hr)) status = hr;
+
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, state->depth_stencil);
+ if (FAILED(hr)) status = hr;
+
+ hr = IDirect3DDevice9_SetViewport(device, &state->viewport);
+ if (FAILED(hr)) status = hr;
+
+ return status;
+}
+
+static void compare_device_state(struct device_state *state1, struct device_state *state2, BOOL equal)
+{
+ BOOL cmp;
+ const char *message = equal ? "differs" : "is the same";
+
+ cmp = state1->render_target == state2->render_target;
+ ok(equal ? cmp : !cmp, "Render target %s %p, %p\n", message, state1->render_target, state2->render_target);
+
+ cmp = state1->depth_stencil == state2->depth_stencil;
+ ok(equal ? cmp : !cmp, "Depth stencil surface %s %p, %p\n", message, state1->depth_stencil, state2->depth_stencil);
+
+ cmp = state1->viewport.X == state2->viewport.X && state1->viewport.Y == state2->viewport.Y
+ && state1->viewport.Width == state2->viewport.Width && state1->viewport.Height == state2->viewport.Height;
+ ok(equal ? cmp : !cmp, "Viewport %s (%u, %u, %u, %u), (%u, %u, %u, %u)\n", message,
+ state1->viewport.X, state1->viewport.Y, state1->viewport.Width, state1->viewport.Height,
+ state2->viewport.X, state2->viewport.Y, state2->viewport.Width, state2->viewport.Height);
+}
+
+static void test_ID3DXRenderToSurface_device_state(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DSurface9 *surface = NULL;
+ ID3DXRenderToSurface *render = NULL;
+ struct device_state pre_state;
+ struct device_state current_state;
+ IDirect3DSurface9 *depth_stencil_surface;
+
+ /* make sure there is a depth stencil surface present */
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &depth_stencil_surface);
+ if (SUCCEEDED(hr))
+ {
+ IDirect3DSurface9_Release(depth_stencil_surface);
+ depth_stencil_surface = NULL;
+ }
+ else if (hr == D3DERR_NOTFOUND)
+ {
+ hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24X8,
+ D3DMULTISAMPLE_NONE, 0, TRUE, &depth_stencil_surface, NULL);
+ if (SUCCEEDED(hr)) IDirect3DDevice9_SetDepthStencilSurface(device, depth_stencil_surface);
+ }
+
+ if (FAILED(hr))
+ {
+ skip("Failed to create depth stencil surface\n");
+ return;
+ }
+
+ hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0,
+ FALSE, &surface, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create render target\n");
+ goto cleanup;
+ }
+
+ hr = retrieve_device_state(device, &pre_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+
+ hr = D3DXCreateRenderToSurface(device, 256, 256, D3DFMT_A8R8G8B8, TRUE, D3DFMT_D24X8, &render);
+ ok(hr == D3D_OK, "D3DXCreateRenderToSurface returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, FALSE);
+ release_device_state(¤t_state);
+
+ hr = ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::EndScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, TRUE);
+ release_device_state(¤t_state);
+
+ check_release((IUnknown *)render, 0);
+ }
+
+ hr = D3DXCreateRenderToSurface(device, 256, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, &render);
+ if (SUCCEEDED(hr))
+ {
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, FALSE);
+ release_device_state(¤t_state);
+
+ hr = ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::EndScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, TRUE);
+ release_device_state(¤t_state);
+
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, FALSE);
+ release_device_state(¤t_state);
+
+ check_release((IUnknown *)render, 0);
+
+ /* if EndScene isn't called, the device state isn't restored */
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, FALSE);
+ release_device_state(¤t_state);
+
+ hr = apply_device_state(device, &pre_state);
+ ok(SUCCEEDED(hr), "Failed to restore previous device state\n");
+
+ IDirect3DDevice9_EndScene(device);
+ }
+
+ release_device_state(&pre_state);
+
+cleanup:
+ if (depth_stencil_surface)
+ {
+ IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
+ IDirect3DSurface9_Release(depth_stencil_surface);
+ }
+
+ if (surface) check_release((IUnknown *)surface, 0);
+}
+
+static void test_ID3DXRenderToSurface(IDirect3DDevice9 *device)
+{
+ int i;
+ HRESULT hr;
+ ULONG ref_count;
+ IDirect3DDevice9 *out_device;
+ ID3DXRenderToSurface *render;
+ IDirect3DSurface9 *surface;
+ D3DVIEWPORT9 viewport = { 0, 0, 256, 256, 0.0, 1.0 };
+ D3DXRTS_DESC tests[] = {
+ { 256, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN },
+ { 256, 256, D3DFMT_A8R8G8B8, TRUE, D3DFMT_D24S8 },
+ { 256, 256, D3DFMT_A8R8G8B8, TRUE, D3DFMT_D24X8 },
+ { 512, 512, D3DFMT_X8R8G8B8, FALSE, D3DFMT_X8R8G8B8 },
+ { 1024, 1024, D3DFMT_X8R8G8B8, TRUE, D3DFMT_D24S8 }
+ };
+
+ hr = D3DXCreateRenderToSurface(device, 256, 256, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, &render);
+ ok(hr == D3D_OK, "D3DXCreateRenderToSurface returned %#x, expected %#x\n", hr, D3D_OK);
+ if (FAILED(hr)) return;
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
+ if (SUCCEEDED(hr))
+ {
+ ID3DXRenderToSurface *render_surface;
+
+ /* GetDevice */
+ hr = ID3DXRenderToSurface_GetDevice(render, NULL /* device */);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ ref_count = get_ref((IUnknown *)device);
+ hr = ID3DXRenderToSurface_GetDevice(render, &out_device);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ check_release((IUnknown *)out_device, ref_count);
+
+ /* BeginScene and EndScene */
+ hr = ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::EndScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToSurface_BeginScene(render, NULL /* surface */, &viewport);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ ref_count = get_ref((IUnknown *)surface);
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ check_ref((IUnknown *)surface, ref_count + 1);
+
+ hr = ID3DXRenderToSurface_BeginScene(render, surface, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToSurface_EndScene(render, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "ID3DXRenderToSurface::EndScene returned %#x, expected %#x\n", hr, D3D_OK);
+
+ check_ref((IUnknown *)surface, ref_count);
+ }
+
+ /* error handling is deferred to BeginScene */
+ hr = D3DXCreateRenderToSurface(device, 256, 256, D3DFMT_A8R8G8B8, TRUE, D3DFMT_UNKNOWN, &render_surface);
+ ok(hr == D3D_OK, "D3DXCreateRenderToSurface returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = ID3DXRenderToSurface_BeginScene(render_surface, surface, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToSurface::BeginScene returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ check_release((IUnknown *)render_surface, 0);
+
+ check_release((IUnknown *)surface, 0);
+ }
+ else skip("Failed to create surface\n");
+
+ check_release((IUnknown *)render, 0);
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ check_ID3DXRenderToSurface(device, tests[i].Width, tests[i].Height, tests[i].Format, tests[i].DepthStencil, tests[i].DepthStencilFormat, TRUE);
+ check_ID3DXRenderToSurface(device, tests[i].Width, tests[i].Height, tests[i].Format, tests[i].DepthStencil, tests[i].DepthStencilFormat, FALSE);
+ }
+
+ test_ID3DXRenderToSurface_device_state(device);
+}
+
+static void test_D3DXCreateRenderToEnvMap(IDirect3DDevice9 *device)
+{
+ int i;
+ HRESULT hr;
+ ULONG ref_count;
+ D3DXRTE_DESC desc;
+ ID3DXRenderToEnvMap *render;
+ static const struct {
+ D3DXRTE_DESC parameters;
+ D3DXRTE_DESC expected_values;
+ } tests[] = {
+ { { 0, 0, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN }, { 1, 1, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN } },
+ { { 256, 0, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN }, { 256, 9, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN } },
+ { { 256, 4, D3DFMT_A8R8G8B8, FALSE, D3DFMT_D24S8 }, { 256, 4, D3DFMT_A8R8G8B8, FALSE, D3DFMT_D24S8 } },
+ { { 256, 256, D3DFMT_UNKNOWN, FALSE, D3DFMT_R8G8B8 }, { 256, 9, D3DFMT_A8R8G8B8, FALSE, D3DFMT_R8G8B8 } },
+ { { -1, -1, D3DFMT_A8R8G8B8, TRUE, D3DFMT_DXT1 }, { 256, 9, D3DFMT_A8R8G8B8, TRUE, D3DFMT_DXT1 } },
+ { { 256, 1, D3DFMT_X8R8G8B8, TRUE, D3DFMT_UNKNOWN }, { 256, 1, D3DFMT_X8R8G8B8, TRUE, D3DFMT_UNKNOWN } }
+ };
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ const D3DXRTE_DESC *parameters = &tests[i].parameters;
+ const D3DXRTE_DESC *expected = &tests[i].expected_values;
+ hr = D3DXCreateRenderToEnvMap(device, parameters->Size, parameters->MipLevels, parameters->Format,
+ parameters->DepthStencil, parameters->DepthStencilFormat, &render);
+ ok(hr == D3D_OK, "%d: D3DXCreateRenderToEnvMap returned %#x, expected %#x\n", i, hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ hr = ID3DXRenderToEnvMap_GetDesc(render, &desc);
+ ok(hr == D3D_OK, "%d: GetDesc failed %#x\n", i, hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(desc.Size == expected->Size, "%d: Got size %u, expected %u\n", i, desc.Size, expected->Size);
+ ok(desc.MipLevels == expected->MipLevels, "%d: Got miplevels %u, expected %u\n", i, desc.MipLevels, expected->MipLevels);
+ ok(desc.Format == expected->Format, "%d: Got format %#x, expected %#x\n", i, desc.Format, expected->Format);
+ ok(desc.DepthStencil == expected->DepthStencil, "%d: Got depth stencil %d, expected %d\n",
+ i, expected->DepthStencil, expected->DepthStencil);
+ ok(desc.DepthStencilFormat == expected->DepthStencilFormat, "%d: Got depth stencil format %#x, expected %#x\n",
+ i, expected->DepthStencilFormat, expected->DepthStencilFormat);
+ }
+ check_release((IUnknown *)render, 0);
+ }
+ }
+
+ /* check device ref count */
+ ref_count = get_ref((IUnknown *)device);
+ hr = D3DXCreateRenderToEnvMap(device, 0, 0, D3DFMT_UNKNOWN, FALSE, D3DFMT_UNKNOWN, &render);
+ check_ref((IUnknown *)device, ref_count + 1);
+ if (SUCCEEDED(hr)) ID3DXRenderToEnvMap_Release(render);
+}
+
+static void test_ID3DXRenderToEnvMap_cube_map(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DCubeTexture9 *cube_texture = NULL;
+ ID3DXRenderToEnvMap *render = NULL;
+ struct device_state pre_state;
+ struct device_state current_state;
+
+ hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 0, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
+ &cube_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create cube texture\n");
+ return;
+ }
+
+ hr = retrieve_device_state(device, &pre_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+
+ hr = D3DXCreateRenderToEnvMap(device, 256, 0, D3DFMT_A8R8G8B8, TRUE, D3DFMT_D24X8, &render);
+ ok(hr == D3D_OK, "D3DCreateRenderToEnvMap returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ DWORD face;
+
+ hr = ID3DXRenderToEnvMap_End(render, D3DX_FILTER_NONE);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToEnvMap_BeginCube(render, cube_texture);
+ ok(hr == D3D_OK, "ID3DXRenderToEnvMap::BeginCube returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, TRUE);
+ release_device_state(¤t_state);
+
+ for (face = D3DCUBEMAP_FACE_POSITIVE_X; face <= D3DCUBEMAP_FACE_NEGATIVE_Z; face++)
+ {
+ hr = ID3DXRenderToEnvMap_Face(render, face, D3DX_FILTER_POINT);
+ ok(hr == D3D_OK, "ID3DXRenderToEnvMap::Face returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, FALSE);
+ release_device_state(¤t_state);
+ }
+
+ hr = ID3DXRenderToEnvMap_End(render, D3DX_FILTER_POINT);
+ ok(hr == D3D_OK, "ID3DXRenderToEnvMap::End returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = retrieve_device_state(device, ¤t_state);
+ ok(SUCCEEDED(hr), "Failed to retrieve device state\n");
+ compare_device_state(¤t_state, &pre_state, TRUE);
+ release_device_state(¤t_state);
+
+ check_release((IUnknown *)render, 0);
+ }
+
+ release_device_state(&pre_state);
+
+ check_release((IUnknown *)cube_texture, 0);
+}
+
+static void test_ID3DXRenderToEnvMap(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ ID3DXRenderToEnvMap *render;
+ IDirect3DSurface9 *depth_stencil_surface;
+
+ hr = D3DXCreateRenderToEnvMap(device, 256, 0, D3DFMT_A8R8G8B8, FALSE, D3DFMT_UNKNOWN, &render);
+ if (SUCCEEDED(hr))
+ {
+ ULONG ref_count;
+ IDirect3DDevice9 *out_device;
+
+ hr = ID3DXRenderToEnvMap_GetDesc(render, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::GetDesc returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToEnvMap_GetDevice(render, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ ref_count = get_ref((IUnknown *)device);
+ hr = ID3DXRenderToEnvMap_GetDevice(render, &out_device);
+ ok(hr == D3D_OK, "ID3DXRenderToEnvMap::GetDevice returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(out_device == device, "ID3DXRenderToEnvMap::GetDevice returned different device\n");
+ check_release((IUnknown *)device, ref_count);
+
+ hr = ID3DXRenderToEnvMap_End(render, D3DX_FILTER_NONE);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::End returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = ID3DXRenderToEnvMap_BeginCube(render, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::BeginCube returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToEnvMap_BeginHemisphere(render, NULL, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::BeginHemisphere returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToEnvMap_BeginParabolic(render, NULL, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::BeginParabolic returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXRenderToEnvMap_BeginSphere(render, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "ID3DXRenderToEnvMap::BeginSphere returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ check_release((IUnknown *)render, 0);
+ } else skip("Failed to create ID3DXRenderToEnvMap\n");
+
+ /* make sure there is a depth stencil surface present */
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &depth_stencil_surface);
+ if (SUCCEEDED(hr))
+ {
+ IDirect3DSurface9_Release(depth_stencil_surface);
+ depth_stencil_surface = NULL;
+ }
+ else if (hr == D3DERR_NOTFOUND)
+ {
+ hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24X8,
+ D3DMULTISAMPLE_NONE, 0, TRUE, &depth_stencil_surface, NULL);
+ if (SUCCEEDED(hr)) IDirect3DDevice9_SetDepthStencilSurface(device, depth_stencil_surface);
+ }
+
+ if (FAILED(hr))
+ {
+ skip("Failed to create depth stencil surface\n");
+ return;
+ }
+
+ test_ID3DXRenderToEnvMap_cube_map(device);
+
+ if (depth_stencil_surface)
+ {
+ IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
+ IDirect3DSurface9_Release(depth_stencil_surface);
+ }
+}
+
+START_TEST(core)
+{
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if(FAILED(hr)) {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ test_ID3DXBuffer();
+ test_ID3DXSprite(device);
+ test_ID3DXFont(device);
+ test_D3DXCreateRenderToSurface(device);
+ test_ID3DXRenderToSurface(device);
+ test_D3DXCreateRenderToEnvMap(device);
+ test_ID3DXRenderToEnvMap(device);
+
+ check_release((IUnknown*)device, 0);
+ check_release((IUnknown*)d3d, 0);
+ if (wnd) DestroyWindow(wnd);
+}
--- /dev/null
+/*
+ * Copyright 2010 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "initguid.h"
+#include <limits.h>
+#include "wine/test.h"
+#include "d3dx9.h"
+
+#ifndef INFINITY
+static inline float __port_infinity(void)
+{
+ static const unsigned __inf_bytes = 0x7f800000;
+ return *(const float *)&__inf_bytes;
+}
+#define INFINITY __port_infinity()
+#endif /* INFINITY */
+
+#ifndef NAN
+static float get_nan(void)
+{
+ DWORD nan = 0x7fc00000;
+
+ return *(float *)&nan;
+}
+#define NAN get_nan()
+#endif
+
+/* helper functions */
+static BOOL compare_float(FLOAT f, FLOAT g, UINT ulps)
+{
+ INT x = *(INT *)&f;
+ INT y = *(INT *)&g;
+
+ if (x < 0)
+ x = INT_MIN - x;
+ if (y < 0)
+ y = INT_MIN - y;
+
+ if (abs(x - y) > ulps)
+ return FALSE;
+
+ return TRUE;
+}
+
+static inline INT get_int(D3DXPARAMETER_TYPE type, const void *data)
+{
+ INT i;
+
+ switch (type)
+ {
+ case D3DXPT_FLOAT:
+ i = *(FLOAT *)data;
+ break;
+
+ case D3DXPT_INT:
+ i = *(INT *)data;
+ break;
+
+ case D3DXPT_BOOL:
+ i = *(BOOL *)data;
+ break;
+
+ default:
+ i = 0;
+ ok(0, "Unhandled type %x.\n", type);
+ break;
+ }
+
+ return i;
+}
+
+static inline float get_float(D3DXPARAMETER_TYPE type, const void *data)
+{
+ float f;
+
+ switch (type)
+ {
+ case D3DXPT_FLOAT:
+ f = *(FLOAT *)data;
+ break;
+
+ case D3DXPT_INT:
+ f = *(INT *)data;
+ break;
+
+ case D3DXPT_BOOL:
+ f = *(BOOL *)data;
+ break;
+
+ default:
+ f = 0.0f;
+ ok(0, "Unhandled type %x.\n", type);
+ break;
+ }
+
+ return f;
+}
+
+static inline BOOL get_bool(const void *data)
+{
+ return !!*(BOOL *)data;
+}
+
+static void set_number(void *outdata, D3DXPARAMETER_TYPE outtype, const void *indata, D3DXPARAMETER_TYPE intype)
+{
+ switch (outtype)
+ {
+ case D3DXPT_FLOAT:
+ *(FLOAT *)outdata = get_float(intype, indata);
+ break;
+
+ case D3DXPT_BOOL:
+ *(BOOL *)outdata = get_bool(indata);
+ break;
+
+ case D3DXPT_INT:
+ *(INT *)outdata = get_int(intype, indata);
+ break;
+
+ case D3DXPT_PIXELSHADER:
+ case D3DXPT_VERTEXSHADER:
+ case D3DXPT_TEXTURE2D:
+ case D3DXPT_STRING:
+ *(INT *)outdata = 0x12345678;
+ break;
+
+ default:
+ ok(0, "Unhandled type %x.\n", outtype);
+ *(INT *)outdata = 0;
+ break;
+ }
+}
+
+static IDirect3DDevice9 *create_device(HWND *window)
+{
+ D3DPRESENT_PARAMETERS present_parameters = { 0 };
+ IDirect3DDevice9 *device;
+ IDirect3D9 *d3d;
+ HRESULT hr;
+ HWND wnd;
+
+ *window = NULL;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window.\n");
+ return NULL;
+ }
+
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object.\n");
+ DestroyWindow(wnd);
+ return NULL;
+ }
+
+ present_parameters.Windowed = TRUE;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
+ &present_parameters, &device);
+ IDirect3D9_Release(d3d);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object %#x.\n", hr);
+ DestroyWindow(wnd);
+ return NULL;
+ }
+
+ *window = wnd;
+ return device;
+}
+
+static char temp_path[MAX_PATH];
+
+static BOOL create_file(const char *filename, const char *data, const unsigned int size, char *out_path)
+{
+ DWORD written;
+ HANDLE hfile;
+ char path[MAX_PATH];
+
+ if (!*temp_path)
+ GetTempPathA(sizeof(temp_path), temp_path);
+
+ strcpy(path, temp_path);
+ strcat(path, filename);
+ hfile = CreateFileA(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (hfile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ if (WriteFile(hfile, data, size, &written, NULL))
+ {
+ CloseHandle(hfile);
+
+ if (out_path)
+ strcpy(out_path, path);
+ return TRUE;
+ }
+
+ CloseHandle(hfile);
+ return FALSE;
+}
+
+static void delete_file(const char *filename)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, filename);
+ DeleteFileA(path);
+}
+
+static BOOL create_directory(const char *name)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, name);
+ return CreateDirectoryA(path, NULL);
+}
+
+static void delete_directory(const char *name)
+{
+ char path[MAX_PATH];
+
+ strcpy(path, temp_path);
+ strcat(path, name);
+ RemoveDirectoryA(path);
+}
+
+static const char effect_desc[] =
+"Technique\n"
+"{\n"
+"}\n";
+
+static void test_create_effect_and_pool(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ ID3DXEffect *effect;
+ ID3DXBaseEffect *base;
+ ULONG count;
+ IDirect3DDevice9 *device2;
+ ID3DXEffectStateManager *manager = (ID3DXEffectStateManager *)0xdeadbeef;
+ ID3DXEffectPool *pool = (ID3DXEffectPool *)0xdeadbeef, *pool2;
+
+ hr = D3DXCreateEffect(NULL, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffect(device, NULL, 0, NULL, NULL, 0, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffect(device, effect_desc, 0, NULL, NULL, 0, NULL, NULL, NULL);
+ ok(hr == E_FAIL, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, E_FAIL);
+
+ hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, &effect, NULL);
+ todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ if (FAILED(hr))
+ {
+ skip("Failed to compile effect, skipping test.\n");
+ return;
+ }
+
+ hr = effect->lpVtbl->QueryInterface(effect, &IID_ID3DXBaseEffect, (void **)&base);
+ ok(hr == E_NOINTERFACE, "QueryInterface failed, got %x, expected %x (E_NOINTERFACE)\n", hr, E_NOINTERFACE);
+
+ hr = effect->lpVtbl->GetStateManager(effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "GetStateManager failed, got %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetStateManager(effect, &manager);
+ ok(hr == D3D_OK, "GetStateManager failed, got %x, expected 0 (D3D_OK)\n", hr);
+ ok(!manager, "GetStateManager failed, got %p\n", manager);
+
+ /* this works, but it is not recommended! */
+ hr = effect->lpVtbl->SetStateManager(effect, (ID3DXEffectStateManager *)device);
+ ok(hr == D3D_OK, "SetStateManager failed, got %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = effect->lpVtbl->GetStateManager(effect, &manager);
+ ok(hr == D3D_OK, "GetStateManager failed, got %x, expected 0 (D3D_OK)\n", hr);
+ ok(manager != NULL, "GetStateManager failed\n");
+
+ IDirect3DDevice9_AddRef(device);
+ count = IDirect3DDevice9_Release(device);
+ ok(count == 4, "Release failed, got %u, expected 4\n", count);
+
+ count = IUnknown_Release(manager);
+ ok(count == 3, "Release failed, got %u, expected 3\n", count);
+
+ hr = effect->lpVtbl->SetStateManager(effect, NULL);
+ ok(hr == D3D_OK, "SetStateManager failed, got %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = effect->lpVtbl->GetPool(effect, &pool);
+ ok(hr == D3D_OK, "GetPool failed, got %x, expected 0 (D3D_OK)\n", hr);
+ ok(!pool, "GetPool failed, got %p\n", pool);
+
+ hr = effect->lpVtbl->GetPool(effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "GetPool failed, got %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetDevice(effect, &device2);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = effect->lpVtbl->GetDevice(effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "GetDevice failed, got %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ count = IDirect3DDevice9_Release(device2);
+ ok(count == 2, "Release failed, got %u, expected 2\n", count);
+
+ count = effect->lpVtbl->Release(effect);
+ ok(count == 0, "Release failed %u\n", count);
+
+ hr = D3DXCreateEffectPool(NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectPool(&pool);
+ ok(hr == S_OK, "Got result %x, expected 0 (S_OK)\n", hr);
+
+ count = pool->lpVtbl->Release(pool);
+ ok(count == 0, "Release failed %u\n", count);
+
+ hr = D3DXCreateEffectPool(&pool);
+ ok(hr == S_OK, "Got result %x, expected 0 (S_OK)\n", hr);
+
+ hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, pool, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = pool->lpVtbl->QueryInterface(pool, &IID_ID3DXEffectPool, (void **)&pool2);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(pool == pool2, "Release failed, got %p, expected %p\n", pool2, pool);
+
+ count = pool2->lpVtbl->Release(pool2);
+ ok(count == 1, "Release failed, got %u, expected 1\n", count);
+
+ hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9, (void **)&device2);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ count = IDirect3DDevice9_Release(device2);
+ ok(count == 1, "Release failed, got %u, expected 1\n", count);
+
+ hr = D3DXCreateEffect(device, effect_desc, sizeof(effect_desc), NULL, NULL, 0, pool, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ hr = effect->lpVtbl->GetPool(effect, &pool);
+ ok(hr == D3D_OK, "GetPool failed, got %x, expected 0 (D3D_OK)\n", hr);
+ ok(pool == pool2, "GetPool failed, got %p, expected %p\n", pool2, pool);
+
+ count = pool2->lpVtbl->Release(pool2);
+ ok(count == 2, "Release failed, got %u, expected 2\n", count);
+
+ count = effect->lpVtbl->Release(effect);
+ ok(count == 0, "Release failed %u\n", count);
+
+ count = pool->lpVtbl->Release(pool);
+ ok(count == 0, "Release failed %u\n", count);
+}
+
+static void test_create_effect_compiler(void)
+{
+ HRESULT hr;
+ ID3DXEffectCompiler *compiler, *compiler2;
+ ID3DXBaseEffect *base;
+ IUnknown *unknown;
+ ULONG count;
+
+ hr = D3DXCreateEffectCompiler(NULL, 0, NULL, NULL, 0, &compiler, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(NULL, 0, NULL, NULL, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(effect_desc, 0, NULL, NULL, 0, &compiler, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (FAILED(hr))
+ {
+ skip("D3DXCreateEffectCompiler failed, skipping test.\n");
+ return;
+ }
+
+ count = compiler->lpVtbl->Release(compiler);
+ ok(count == 0, "Release failed %u\n", count);
+
+ hr = D3DXCreateEffectCompiler(effect_desc, 0, NULL, NULL, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(NULL, sizeof(effect_desc), NULL, NULL, 0, &compiler, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(NULL, sizeof(effect_desc), NULL, NULL, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(effect_desc, sizeof(effect_desc), NULL, NULL, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateEffectCompiler(effect_desc, sizeof(effect_desc), NULL, NULL, 0, &compiler, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = compiler->lpVtbl->QueryInterface(compiler, &IID_ID3DXBaseEffect, (void **)&base);
+ ok(hr == E_NOINTERFACE, "QueryInterface failed, got %x, expected %x (E_NOINTERFACE)\n", hr, E_NOINTERFACE);
+
+ hr = compiler->lpVtbl->QueryInterface(compiler, &IID_ID3DXEffectCompiler, (void **)&compiler2);
+ ok(hr == D3D_OK, "QueryInterface failed, got %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = compiler->lpVtbl->QueryInterface(compiler, &IID_IUnknown, (void **)&unknown);
+ ok(hr == D3D_OK, "QueryInterface failed, got %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ count = unknown->lpVtbl->Release(unknown);
+ ok(count == 2, "Release failed, got %u, expected %u\n", count, 2);
+
+ count = compiler2->lpVtbl->Release(compiler2);
+ ok(count == 1, "Release failed, got %u, expected %u\n", count, 1);
+
+ count = compiler->lpVtbl->Release(compiler);
+ ok(count == 0, "Release failed %u\n", count);
+}
+
+/*
+ * Parameter value test
+ */
+struct test_effect_parameter_value_result
+{
+ const char *full_name;
+ D3DXPARAMETER_DESC desc;
+ UINT value_offset; /* start position for the value in the blob */
+};
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+float f = 0.1;
+float1 f1 = {1.1};
+float2 f2 = {2.1, 2.2};
+float3 f3 = {3.1, 3.2, 3.3};
+float4 f4 = {4.1, 4.2, 4.3, 4.4};
+float1x1 f11 = {11.1};
+float1x2 f12 = {12.1, 12.2};
+float1x3 f13 = {13.1, 13.2, 13.3};
+float1x4 f14 = {14.1, 14.2, 14.3, 14.4};
+float2x1 f21 = {{21.11, 21.21}};
+float2x2 f22 = {{22.11, 22.21}, {22.12, 22.22}};
+float2x3 f23 = {{23.11, 23.21}, {23.12, 23.22}, {23.13, 23.23}};
+float2x4 f24 = {{24.11, 24.21}, {24.12, 24.22}, {24.13, 24.23}, {24.14, 24.24}};
+float3x1 f31 = {{31.11, 31.21, 31.31}};
+float3x2 f32 = {{32.11, 32.21, 32.31}, {32.12, 32.22, 32.32}};
+float3x3 f33 = {{33.11, 33.21, 33.31}, {33.12, 33.22, 33.32},
+ {33.13, 33.23, 33.33}};
+float3x4 f34 = {{34.11, 34.21, 34.31}, {34.12, 34.22, 34.32},
+ {34.13, 34.23, 34.33}, {34.14, 34.24, 34.34}};
+float4x1 f41 = {{41.11, 41.21, 41.31, 41.41}};
+float4x2 f42 = {{42.11, 42.21, 42.31, 42.41}, {42.12, 42.22, 42.32, 42.42}};
+float4x3 f43 = {{43.11, 43.21, 43.31, 43.41}, {43.12, 43.22, 43.32, 43.42},
+ {43.13, 43.23, 43.33, 43.43}};
+float4x4 f44 = {{44.11, 44.21, 44.31, 44.41}, {44.12, 44.22, 44.32, 44.42},
+ {44.13, 44.23, 44.33, 44.43}, {44.14, 44.24, 44.34, 44.44}};
+float f_2[2] = {0.101, 0.102};
+float1 f1_2[2] = {{1.101}, {1.102}};
+float2 f2_2[2] = {{2.101, 2.201}, {2.102, 2.202}};
+float3 f3_2[2] = {{3.101, 3.201, 3.301}, {3.102, 3.202, 3.302}};
+float4 f4_2[2] = {{4.101, 4.201, 4.301, 4.401}, {4.102, 4.202, 4.302, 4.402}};
+float1x1 f11_2[2] = {{11.101}, {11.102}};
+float1x2 f12_2[2] = {{12.101, 12.201}, {12.102, 12.202}};
+float1x3 f13_2[2] = {{13.101, 13.201, 13.301}, {13.102, 13.202, 13.302}};
+float1x4 f14_2[2] = {{14.101, 14.201, 14.301, 14.401}, {14.102, 14.202, 14.302, 14.402}};
+float2x1 f21_2[2] = {{{21.1101, 21.2101}}, {{21.1102, 21.2102}}};
+float2x2 f22_2[2] = {{{22.1101, 22.2101}, {22.1201, 22.2201}}, {{22.1102, 22.2102}, {22.1202, 22.2202}}};
+float2x3 f23_2[2] = {{{23.1101, 23.2101}, {23.1201, 23.2201}, {23.1301, 23.2301}}, {{23.1102, 23.2102},
+ {23.1202, 23.2202}, {23.1302, 23.2302}}};
+float2x4 f24_2[2] = {{{24.1101, 24.2101}, {24.1201, 24.2201}, {24.1301, 24.2301}, {24.1401, 24.2401}},
+ {{24.1102, 24.2102}, {24.1202, 24.2202}, {24.1302, 24.2302}, {24.1402, 24.2402}}};
+float3x1 f31_2[2] = {{{31.1101, 31.2101, 31.3101}}, {{31.1102, 31.2102, 31.3102}}};
+float3x2 f32_2[2] = {{{32.1101, 32.2101, 32.3101}, {32.1201, 32.2201, 32.3201}},
+ {{32.1102, 32.2102, 32.3102}, {32.1202, 32.2202, 32.3202}}};
+float3x3 f33_2[2] = {{{33.1101, 33.2101, 33.3101}, {33.1201, 33.2201, 33.3201},
+ {33.1301, 33.2301, 33.3301}}, {{33.1102, 33.2102, 33.3102}, {33.1202, 33.2202, 33.3202},
+ {33.1302, 33.2302, 33.3302}}};
+float3x4 f34_2[2] = {{{34.1101, 34.2101, 34.3101}, {34.1201, 34.2201, 34.3201},
+ {34.1301, 34.2301, 34.3301}, {34.1401, 34.2401, 34.3401}}, {{34.1102, 34.2102, 34.3102},
+ {34.1202, 34.2202, 34.3202}, {34.1302, 34.2302, 34.3302}, {34.1402, 34.2402, 34.3402}}};
+float4x1 f41_2[2] = {{{41.1101, 41.2101, 41.3101, 41.4101}}, {{41.1102, 41.2102, 41.3102, 41.4102}}};
+float4x2 f42_2[2] = {{{42.1101, 42.2101, 42.3101, 42.4101}, {42.1201, 42.2201, 42.3201, 42.4201}},
+ {{42.1102, 42.2102, 42.3102, 42.4102}, {42.1202, 42.2202, 42.3202, 42.4202}}};
+float4x3 f43_2[2] = {{{43.1101, 43.2101, 43.3101, 43.4101}, {43.1201, 43.2201, 43.3201, 43.4201},
+ {43.1301, 43.2301, 43.3301, 43.4301}}, {{43.1102, 43.2102, 43.3102, 43.4102},
+ {43.1202, 43.2202, 43.3202, 43.4202}, {43.1302, 43.2302, 43.3302, 43.4302}}};
+float4x4 f44_2[2] = {{{44.1101, 44.2101, 44.3101, 44.4101}, {44.1201, 44.2201, 44.3201, 44.4201},
+ {44.1301, 44.2301, 44.3301, 44.4301}, {44.1401, 44.2401, 44.3401, 44.4401}},
+ {{44.1102, 44.2102, 44.3102, 44.4102}, {44.1202, 44.2202, 44.3202, 44.4202},
+ {44.1302, 44.2302, 44.3302, 44.4302}, {44.1402, 44.2402, 44.3402, 44.4402}}};
+technique t { pass p { } }
+#endif
+static const DWORD test_effect_parameter_value_blob_float[] =
+{
+0xfeff0901, 0x00000b80, 0x00000000, 0x00000003, 0x00000000, 0x00000024, 0x00000000, 0x00000000,
+0x00000001, 0x00000001, 0x3dcccccd, 0x00000002, 0x00000066, 0x00000003, 0x00000001, 0x0000004c,
+0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x3f8ccccd, 0x00000003, 0x00003166, 0x00000003,
+0x00000001, 0x00000078, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x40066666, 0x400ccccd,
+0x00000003, 0x00003266, 0x00000003, 0x00000001, 0x000000a8, 0x00000000, 0x00000000, 0x00000003,
+0x00000001, 0x40466666, 0x404ccccd, 0x40533333, 0x00000003, 0x00003366, 0x00000003, 0x00000001,
+0x000000dc, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x40833333, 0x40866666, 0x4089999a,
+0x408ccccd, 0x00000003, 0x00003466, 0x00000003, 0x00000002, 0x00000104, 0x00000000, 0x00000000,
+0x00000001, 0x00000001, 0x4131999a, 0x00000004, 0x00313166, 0x00000003, 0x00000002, 0x00000130,
+0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x4141999a, 0x41433333, 0x00000004, 0x00323166,
+0x00000003, 0x00000002, 0x00000160, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x4151999a,
+0x41533333, 0x4154cccd, 0x00000004, 0x00333166, 0x00000003, 0x00000002, 0x00000194, 0x00000000,
+0x00000000, 0x00000001, 0x00000004, 0x4161999a, 0x41633333, 0x4164cccd, 0x41666666, 0x00000004,
+0x00343166, 0x00000003, 0x00000002, 0x000001c0, 0x00000000, 0x00000000, 0x00000002, 0x00000001,
+0x41a8e148, 0x41a9ae14, 0x00000004, 0x00313266, 0x00000003, 0x00000002, 0x000001f4, 0x00000000,
+0x00000000, 0x00000002, 0x00000002, 0x41b0e148, 0x41b1ae14, 0x41b0f5c3, 0x41b1c28f, 0x00000004,
+0x00323266, 0x00000003, 0x00000002, 0x00000230, 0x00000000, 0x00000000, 0x00000002, 0x00000003,
+0x41b8e148, 0x41b9ae14, 0x41b8f5c3, 0x41b9c28f, 0x41b90a3d, 0x41b9d70a, 0x00000004, 0x00333266,
+0x00000003, 0x00000002, 0x00000274, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x41c0e148,
+0x41c1ae14, 0x41c0f5c3, 0x41c1c28f, 0x41c10a3d, 0x41c1d70a, 0x41c11eb8, 0x41c1eb85, 0x00000004,
+0x00343266, 0x00000003, 0x00000002, 0x000002a4, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
+0x41f8e148, 0x41f9ae14, 0x41fa7ae1, 0x00000004, 0x00313366, 0x00000003, 0x00000002, 0x000002e0,
+0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x420070a4, 0x4200d70a, 0x42013d71, 0x42007ae1,
+0x4200e148, 0x420147ae, 0x00000004, 0x00323366, 0x00000003, 0x00000002, 0x00000328, 0x00000000,
+0x00000000, 0x00000003, 0x00000003, 0x420470a4, 0x4204d70a, 0x42053d71, 0x42047ae1, 0x4204e148,
+0x420547ae, 0x4204851f, 0x4204eb85, 0x420551ec, 0x00000004, 0x00333366, 0x00000003, 0x00000002,
+0x0000037c, 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x420870a4, 0x4208d70a, 0x42093d71,
+0x42087ae1, 0x4208e148, 0x420947ae, 0x4208851f, 0x4208eb85, 0x420951ec, 0x42088f5c, 0x4208f5c3,
+0x42095c29, 0x00000004, 0x00343366, 0x00000003, 0x00000002, 0x000003b0, 0x00000000, 0x00000000,
+0x00000004, 0x00000001, 0x422470a4, 0x4224d70a, 0x42253d71, 0x4225a3d7, 0x00000004, 0x00313466,
+0x00000003, 0x00000002, 0x000003f4, 0x00000000, 0x00000000, 0x00000004, 0x00000002, 0x422870a4,
+0x4228d70a, 0x42293d71, 0x4229a3d7, 0x42287ae1, 0x4228e148, 0x422947ae, 0x4229ae14, 0x00000004,
+0x00323466, 0x00000003, 0x00000002, 0x00000448, 0x00000000, 0x00000000, 0x00000004, 0x00000003,
+0x422c70a4, 0x422cd70a, 0x422d3d71, 0x422da3d7, 0x422c7ae1, 0x422ce148, 0x422d47ae, 0x422dae14,
+0x422c851f, 0x422ceb85, 0x422d51ec, 0x422db852, 0x00000004, 0x00333466, 0x00000003, 0x00000002,
+0x000004ac, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x423070a4, 0x4230d70a, 0x42313d71,
+0x4231a3d7, 0x42307ae1, 0x4230e148, 0x423147ae, 0x4231ae14, 0x4230851f, 0x4230eb85, 0x423151ec,
+0x4231b852, 0x42308f5c, 0x4230f5c3, 0x42315c29, 0x4231c28f, 0x00000004, 0x00343466, 0x00000003,
+0x00000000, 0x000004d8, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x3dced917, 0x3dd0e560,
+0x00000004, 0x00325f66, 0x00000003, 0x00000001, 0x00000504, 0x00000000, 0x00000002, 0x00000001,
+0x00000001, 0x3f8ced91, 0x3f8d0e56, 0x00000005, 0x325f3166, 0x00000000, 0x00000003, 0x00000001,
+0x0000053c, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x400676c9, 0x400cdd2f, 0x4006872b,
+0x400ced91, 0x00000005, 0x325f3266, 0x00000000, 0x00000003, 0x00000001, 0x0000057c, 0x00000000,
+0x00000002, 0x00000003, 0x00000001, 0x404676c9, 0x404cdd2f, 0x40534396, 0x4046872b, 0x404ced91,
+0x405353f8, 0x00000005, 0x325f3366, 0x00000000, 0x00000003, 0x00000001, 0x000005c4, 0x00000000,
+0x00000002, 0x00000004, 0x00000001, 0x40833b64, 0x40866e98, 0x4089a1cb, 0x408cd4fe, 0x40834396,
+0x408676c9, 0x4089a9fc, 0x408cdd2f, 0x00000005, 0x325f3466, 0x00000000, 0x00000003, 0x00000002,
+0x000005f4, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x41319db2, 0x4131a1cb, 0x00000006,
+0x5f313166, 0x00000032, 0x00000003, 0x00000002, 0x0000062c, 0x00000000, 0x00000002, 0x00000001,
+0x00000002, 0x41419db2, 0x4143374c, 0x4141a1cb, 0x41433b64, 0x00000006, 0x5f323166, 0x00000032,
+0x00000003, 0x00000002, 0x0000066c, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x41519db2,
+0x4153374c, 0x4154d0e5, 0x4151a1cb, 0x41533b64, 0x4154d4fe, 0x00000006, 0x5f333166, 0x00000032,
+0x00000003, 0x00000002, 0x000006b4, 0x00000000, 0x00000002, 0x00000001, 0x00000004, 0x41619db2,
+0x4163374c, 0x4164d0e5, 0x41666a7f, 0x4161a1cb, 0x41633b64, 0x4164d4fe, 0x41666e98, 0x00000006,
+0x5f343166, 0x00000032, 0x00000003, 0x00000002, 0x000006ec, 0x00000000, 0x00000002, 0x00000002,
+0x00000001, 0x41a8e17c, 0x41a9ae49, 0x41a8e1b1, 0x41a9ae7d, 0x00000006, 0x5f313266, 0x00000032,
+0x00000003, 0x00000002, 0x00000734, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x41b0e17c,
+0x41b1ae49, 0x41b0f5f7, 0x41b1c2c4, 0x41b0e1b1, 0x41b1ae7d, 0x41b0f62b, 0x41b1c2f8, 0x00000006,
+0x5f323266, 0x00000032, 0x00000003, 0x00000002, 0x0000078c, 0x00000000, 0x00000002, 0x00000002,
+0x00000003, 0x41b8e17c, 0x41b9ae49, 0x41b8f5f7, 0x41b9c2c4, 0x41b90a72, 0x41b9d73f, 0x41b8e1b1,
+0x41b9ae7d, 0x41b8f62b, 0x41b9c2f8, 0x41b90aa6, 0x41b9d773, 0x00000006, 0x5f333266, 0x00000032,
+0x00000003, 0x00000002, 0x000007f4, 0x00000000, 0x00000002, 0x00000002, 0x00000004, 0x41c0e17c,
+0x41c1ae49, 0x41c0f5f7, 0x41c1c2c4, 0x41c10a72, 0x41c1d73f, 0x41c11eed, 0x41c1ebba, 0x41c0e1b1,
+0x41c1ae7d, 0x41c0f62b, 0x41c1c2f8, 0x41c10aa6, 0x41c1d773, 0x41c11f21, 0x41c1ebee, 0x00000006,
+0x5f343266, 0x00000032, 0x00000003, 0x00000002, 0x00000834, 0x00000000, 0x00000002, 0x00000003,
+0x00000001, 0x41f8e17c, 0x41f9ae49, 0x41fa7b16, 0x41f8e1b1, 0x41f9ae7d, 0x41fa7b4a, 0x00000006,
+0x5f313366, 0x00000032, 0x00000003, 0x00000002, 0x0000088c, 0x00000000, 0x00000002, 0x00000003,
+0x00000002, 0x420070be, 0x4200d724, 0x42013d8b, 0x42007afb, 0x4200e162, 0x420147c8, 0x420070d8,
+0x4200d73f, 0x42013da5, 0x42007b16, 0x4200e17c, 0x420147e3, 0x00000006, 0x5f323366, 0x00000032,
+0x00000003, 0x00000002, 0x000008fc, 0x00000000, 0x00000002, 0x00000003, 0x00000003, 0x420470be,
+0x4204d724, 0x42053d8b, 0x42047afb, 0x4204e162, 0x420547c8, 0x42048539, 0x4204eb9f, 0x42055206,
+0x420470d8, 0x4204d73f, 0x42053da5, 0x42047b16, 0x4204e17c, 0x420547e3, 0x42048553, 0x4204ebba,
+0x42055220, 0x00000006, 0x5f333366, 0x00000032, 0x00000003, 0x00000002, 0x00000984, 0x00000000,
+0x00000002, 0x00000003, 0x00000004, 0x420870be, 0x4208d724, 0x42093d8b, 0x42087afb, 0x4208e162,
+0x420947c8, 0x42088539, 0x4208eb9f, 0x42095206, 0x42088f76, 0x4208f5dd, 0x42095c43, 0x420870d8,
+0x4208d73f, 0x42093da5, 0x42087b16, 0x4208e17c, 0x420947e3, 0x42088553, 0x4208ebba, 0x42095220,
+0x42088f91, 0x4208f5f7, 0x42095c5d, 0x00000006, 0x5f343366, 0x00000032, 0x00000003, 0x00000002,
+0x000009cc, 0x00000000, 0x00000002, 0x00000004, 0x00000001, 0x422470be, 0x4224d724, 0x42253d8b,
+0x4225a3f1, 0x422470d8, 0x4224d73f, 0x42253da5, 0x4225a40b, 0x00000006, 0x5f313466, 0x00000032,
+0x00000003, 0x00000002, 0x00000a34, 0x00000000, 0x00000002, 0x00000004, 0x00000002, 0x422870be,
+0x4228d724, 0x42293d8b, 0x4229a3f1, 0x42287afb, 0x4228e162, 0x422947c8, 0x4229ae2f, 0x422870d8,
+0x4228d73f, 0x42293da5, 0x4229a40b, 0x42287b16, 0x4228e17c, 0x422947e3, 0x4229ae49, 0x00000006,
+0x5f323466, 0x00000032, 0x00000003, 0x00000002, 0x00000abc, 0x00000000, 0x00000002, 0x00000004,
+0x00000003, 0x422c70be, 0x422cd724, 0x422d3d8b, 0x422da3f1, 0x422c7afb, 0x422ce162, 0x422d47c8,
+0x422dae2f, 0x422c8539, 0x422ceb9f, 0x422d5206, 0x422db86c, 0x422c70d8, 0x422cd73f, 0x422d3da5,
+0x422da40b, 0x422c7b16, 0x422ce17c, 0x422d47e3, 0x422dae49, 0x422c8553, 0x422cebba, 0x422d5220,
+0x422db886, 0x00000006, 0x5f333466, 0x00000032, 0x00000003, 0x00000002, 0x00000b64, 0x00000000,
+0x00000002, 0x00000004, 0x00000004, 0x423070be, 0x4230d724, 0x42313d8b, 0x4231a3f1, 0x42307afb,
+0x4230e162, 0x423147c8, 0x4231ae2f, 0x42308539, 0x4230eb9f, 0x42315206, 0x4231b86c, 0x42308f76,
+0x4230f5dd, 0x42315c43, 0x4231c2aa, 0x423070d8, 0x4230d73f, 0x42313da5, 0x4231a40b, 0x42307b16,
+0x4230e17c, 0x423147e3, 0x4231ae49, 0x42308553, 0x4230ebba, 0x42315220, 0x4231b886, 0x42308f91,
+0x4230f5f7, 0x42315c5d, 0x4231c2c4, 0x00000006, 0x5f343466, 0x00000032, 0x00000002, 0x00000070,
+0x00000002, 0x00000074, 0x0000002a, 0x00000001, 0x00000001, 0x00000001, 0x00000004, 0x00000020,
+0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000, 0x00000000, 0x00000054, 0x00000070,
+0x00000000, 0x00000000, 0x00000080, 0x0000009c, 0x00000000, 0x00000000, 0x000000b0, 0x000000cc,
+0x00000000, 0x00000000, 0x000000e4, 0x00000100, 0x00000000, 0x00000000, 0x0000010c, 0x00000128,
+0x00000000, 0x00000000, 0x00000138, 0x00000154, 0x00000000, 0x00000000, 0x00000168, 0x00000184,
+0x00000000, 0x00000000, 0x0000019c, 0x000001b8, 0x00000000, 0x00000000, 0x000001c8, 0x000001e4,
+0x00000000, 0x00000000, 0x000001fc, 0x00000218, 0x00000000, 0x00000000, 0x00000238, 0x00000254,
+0x00000000, 0x00000000, 0x0000027c, 0x00000298, 0x00000000, 0x00000000, 0x000002ac, 0x000002c8,
+0x00000000, 0x00000000, 0x000002e8, 0x00000304, 0x00000000, 0x00000000, 0x00000330, 0x0000034c,
+0x00000000, 0x00000000, 0x00000384, 0x000003a0, 0x00000000, 0x00000000, 0x000003b8, 0x000003d4,
+0x00000000, 0x00000000, 0x000003fc, 0x00000418, 0x00000000, 0x00000000, 0x00000450, 0x0000046c,
+0x00000000, 0x00000000, 0x000004b4, 0x000004d0, 0x00000000, 0x00000000, 0x000004e0, 0x000004fc,
+0x00000000, 0x00000000, 0x00000510, 0x0000052c, 0x00000000, 0x00000000, 0x00000548, 0x00000564,
+0x00000000, 0x00000000, 0x00000588, 0x000005a4, 0x00000000, 0x00000000, 0x000005d0, 0x000005ec,
+0x00000000, 0x00000000, 0x00000600, 0x0000061c, 0x00000000, 0x00000000, 0x00000638, 0x00000654,
+0x00000000, 0x00000000, 0x00000678, 0x00000694, 0x00000000, 0x00000000, 0x000006c0, 0x000006dc,
+0x00000000, 0x00000000, 0x000006f8, 0x00000714, 0x00000000, 0x00000000, 0x00000740, 0x0000075c,
+0x00000000, 0x00000000, 0x00000798, 0x000007b4, 0x00000000, 0x00000000, 0x00000800, 0x0000081c,
+0x00000000, 0x00000000, 0x00000840, 0x0000085c, 0x00000000, 0x00000000, 0x00000898, 0x000008b4,
+0x00000000, 0x00000000, 0x00000908, 0x00000924, 0x00000000, 0x00000000, 0x00000990, 0x000009ac,
+0x00000000, 0x00000000, 0x000009d8, 0x000009f4, 0x00000000, 0x00000000, 0x00000a40, 0x00000a5c,
+0x00000000, 0x00000000, 0x00000ac8, 0x00000ae4, 0x00000000, 0x00000000, 0x00000b78, 0x00000000,
+0x00000001, 0x00000b70, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+struct test_effect_parameter_value_result test_effect_parameter_value_result_float[] =
+{
+ {"f", {"f", NULL, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 0, 0, 0, 0, 4}, 10},
+ {"f1", {"f1", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 1, 0, 0, 0, 0, 4}, 20},
+ {"f2", {"f2", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 2, 0, 0, 0, 0, 8}, 30},
+ {"f3", {"f3", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 0, 0, 0, 0, 12}, 41},
+ {"f4", {"f4", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 0, 0, 0, 0, 16}, 53},
+ {"f11", {"f11", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 1, 0, 0, 0, 0, 4}, 66},
+ {"f12", {"f12", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 2, 0, 0, 0, 0, 8}, 76},
+ {"f13", {"f13", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 3, 0, 0, 0, 0, 12}, 87},
+ {"f14", {"f14", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 4, 0, 0, 0, 0, 16}, 99},
+ {"f21", {"f21", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 1, 0, 0, 0, 0, 8}, 112},
+ {"f22", {"f22", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 2, 0, 0, 0, 0, 16}, 123},
+ {"f23", {"f23", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 3, 0, 0, 0, 0, 24}, 136},
+ {"f24", {"f24", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 4, 0, 0, 0, 0, 32}, 151},
+ {"f31", {"f31", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 0, 0, 0, 0, 12}, 168},
+ {"f32", {"f32", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 0, 0, 0, 0, 24}, 180},
+ {"f33", {"f33", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 3, 0, 0, 0, 0, 36}, 195},
+ {"f34", {"f34", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 4, 0, 0, 0, 0, 48}, 213},
+ {"f41", {"f41", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 1, 0, 0, 0, 0, 16}, 234},
+ {"f42", {"f42", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 2, 0, 0, 0, 0, 32}, 247},
+ {"f43", {"f43", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 3, 0, 0, 0, 0, 48}, 264},
+ {"f44", {"f44", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 0, 0, 0, 0, 64}, 285},
+ {"f_2", {"f_2", NULL, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 2, 0, 0, 0, 8}, 310},
+ {"f1_2", {"f1_2", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 1, 2, 0, 0, 0, 8}, 321},
+ {"f2_2", {"f2_2", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 2, 2, 0, 0, 0, 16}, 333},
+ {"f3_2", {"f3_2", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 2, 0, 0, 0, 24}, 347},
+ {"f4_2", {"f4_2", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 2, 0, 0, 0, 32}, 363},
+ {"f11_2", {"f11_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 1, 2, 0, 0, 0, 8}, 381},
+ {"f12_2", {"f12_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 2, 2, 0, 0, 0, 16}, 393},
+ {"f13_2", {"f13_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 3, 2, 0, 0, 0, 24}, 407},
+ {"f14_2", {"f14_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 4, 2, 0, 0, 0, 32}, 423},
+ {"f21_2", {"f21_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 1, 2, 0, 0, 0, 16}, 441},
+ {"f22_2", {"f22_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 2, 2, 0, 0, 0, 32}, 455},
+ {"f23_2", {"f23_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 3, 2, 0, 0, 0, 48}, 473},
+ {"f24_2", {"f24_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 4, 2, 0, 0, 0, 64}, 495},
+ {"f31_2", {"f31_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 2, 0, 0, 0, 24}, 521},
+ {"f32_2", {"f32_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 2, 0, 0, 0, 48}, 537},
+ {"f33_2", {"f33_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 3, 2, 0, 0, 0, 72}, 559},
+ {"f34_2", {"f34_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 4, 2, 0, 0, 0, 96}, 587},
+ {"f41_2", {"f41_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 1, 2, 0, 0, 0, 32}, 621},
+ {"f42_2", {"f42_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 2, 2, 0, 0, 0, 64}, 639},
+ {"f43_2", {"f43_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 3, 2, 0, 0, 0, 96}, 665},
+ {"f44_2", {"f44_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 2, 0, 0, 0, 128}, 699},
+};
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+int i = 1;
+int1 i1 = {11};
+int2 i2 = {21, 22};
+int3 i3 = {31, 32, 33};
+int4 i4 = {41, 42, 43, 44};
+int1x1 i11 = {111};
+int1x2 i12 = {121, 122};
+int1x3 i13 = {131, 132, 133};
+int1x4 i14 = {141, 142, 143, 144};
+int2x1 i21 = {{2111, 2121}};
+int2x2 i22 = {{2211, 2221}, {2212, 2222}};
+int2x3 i23 = {{2311, 2321}, {2312, 2322}, {2313, 2323}};
+int2x4 i24 = {{2411, 2421}, {2412, 2422}, {2413, 2423}, {2414, 2424}};
+int3x1 i31 = {{3111, 3121, 3131}};
+int3x2 i32 = {{3211, 3221, 3231}, {3212, 3222, 3232}};
+int3x3 i33 = {{3311, 3321, 3331}, {3312, 3322, 3332},
+ {3313, 3323, 3333}};
+int3x4 i34 = {{3411, 3421, 3431}, {3412, 3422, 3432},
+ {3413, 3423, 3433}, {3414, 3424, 3434}};
+int4x1 i41 = {{4111, 4121, 4131, 4141}};
+int4x2 i42 = {{4211, 4221, 4231, 4241}, {4212, 4222, 4232, 4242}};
+int4x3 i43 = {{4311, 4321, 4331, 4341}, {4312, 4322, 4332, 4342},
+ {4313, 4323, 4333, 4343}};
+int4x4 i44 = {{4411, 4421, 4431, 4441}, {4412, 4422, 4432, 4442},
+ {4413, 4423, 4433, 4443}, {4414, 4424, 4434, 4444}};
+int i_2[2] = {0101, 0102};
+int1 i1_2[2] = {{1101}, {1102}};
+int2 i2_2[2] = {{2101, 2201}, {2102, 2202}};
+int3 i3_2[2] = {{3101, 3201, 3301}, {3102, 3202, 3302}};
+int4 i4_2[2] = {{4101, 4201, 4301, 4401}, {4102, 4202, 4302, 4402}};
+int1x1 i11_2[2] = {{11101}, {11102}};
+int1x2 i12_2[2] = {{12101, 12201}, {12102, 12202}};
+int1x3 i13_2[2] = {{13101, 13201, 13301}, {13102, 13202, 13302}};
+int1x4 i14_2[2] = {{14101, 14201, 14301, 14401}, {14102, 14202, 14302, 14402}};
+int2x1 i21_2[2] = {{{211101, 212101}}, {{211102, 212102}}};
+int2x2 i22_2[2] = {{{221101, 222101}, {221201, 222201}}, {{221102, 222102}, {221202, 222202}}};
+int2x3 i23_2[2] = {{{231101, 232101}, {231201, 232201}, {231301, 232301}}, {{231102, 232102},
+ {231202, 232202}, {231302, 232302}}};
+int2x4 i24_2[2] = {{{241101, 242101}, {241201, 242201}, {241301, 242301}, {241401, 242401}},
+ {{241102, 242102}, {241202, 242202}, {241302, 242302}, {241402, 242402}}};
+int3x1 i31_2[2] = {{{311101, 312101, 313101}}, {{311102, 312102, 313102}}};
+int3x2 i32_2[2] = {{{321101, 322101, 323101}, {321201, 322201, 323201}},
+ {{321102, 322102, 323102}, {321202, 322202, 323202}}};
+int3x3 i33_2[2] = {{{331101, 332101, 333101}, {331201, 332201, 333201},
+ {331301, 332301, 333301}}, {{331102, 332102, 333102}, {331202, 332202, 333202},
+ {331302, 332302, 333302}}};
+int3x4 i34_2[2] = {{{341101, 342101, 343101}, {341201, 342201, 343201},
+ {341301, 342301, 343301}, {341401, 342401, 343401}}, {{341102, 342102, 343102},
+ {341202, 342202, 343202}, {341302, 342302, 343302}, {341402, 342402, 343402}}};
+int4x1 i41_2[2] = {{{411101, 412101, 413101, 414101}}, {{411102, 412102, 413102, 414102}}};
+int4x2 i42_2[2] = {{{421101, 422101, 423101, 424101}, {421201, 422201, 423201, 424201}},
+ {{421102, 422102, 423102, 424102}, {421202, 422202, 423202, 424202}}};
+int4x3 i43_2[2] = {{{431101, 432101, 433101, 434101}, {431201, 432201, 433201, 434201},
+ {431301, 432301, 433301, 434301}}, {{431102, 432102, 433102, 434102},
+ {431202, 432202, 433202, 434202}, {431302, 432302, 433302, 434302}}};
+int4x4 i44_2[2] = {{{441101, 442101, 443101, 444101}, {441201, 442201, 443201, 444201},
+ {441301, 442301, 443301, 444301}, {441401, 442401, 443401, 444401}},
+ {{441102, 442102, 443102, 444102}, {441202, 442202, 443202, 444202},
+ {441302, 442302, 443302, 444302}, {441402, 442402, 443402, 444402}}};
+technique t { pass p { } }
+#endif
+static const DWORD test_effect_parameter_value_blob_int[] =
+{
+0xfeff0901, 0x00000b80, 0x00000000, 0x00000002, 0x00000000, 0x00000024, 0x00000000, 0x00000000,
+0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000069, 0x00000002, 0x00000001, 0x0000004c,
+0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x0000000b, 0x00000003, 0x00003169, 0x00000002,
+0x00000001, 0x00000078, 0x00000000, 0x00000000, 0x00000002, 0x00000001, 0x00000015, 0x00000016,
+0x00000003, 0x00003269, 0x00000002, 0x00000001, 0x000000a8, 0x00000000, 0x00000000, 0x00000003,
+0x00000001, 0x0000001f, 0x00000020, 0x00000021, 0x00000003, 0x00003369, 0x00000002, 0x00000001,
+0x000000dc, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000029, 0x0000002a, 0x0000002b,
+0x0000002c, 0x00000003, 0x00003469, 0x00000002, 0x00000002, 0x00000104, 0x00000000, 0x00000000,
+0x00000001, 0x00000001, 0x0000006f, 0x00000004, 0x00313169, 0x00000002, 0x00000002, 0x00000130,
+0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000079, 0x0000007a, 0x00000004, 0x00323169,
+0x00000002, 0x00000002, 0x00000160, 0x00000000, 0x00000000, 0x00000001, 0x00000003, 0x00000083,
+0x00000084, 0x00000085, 0x00000004, 0x00333169, 0x00000002, 0x00000002, 0x00000194, 0x00000000,
+0x00000000, 0x00000001, 0x00000004, 0x0000008d, 0x0000008e, 0x0000008f, 0x00000090, 0x00000004,
+0x00343169, 0x00000002, 0x00000002, 0x000001c0, 0x00000000, 0x00000000, 0x00000002, 0x00000001,
+0x0000083f, 0x00000849, 0x00000004, 0x00313269, 0x00000002, 0x00000002, 0x000001f4, 0x00000000,
+0x00000000, 0x00000002, 0x00000002, 0x000008a3, 0x000008ad, 0x000008a4, 0x000008ae, 0x00000004,
+0x00323269, 0x00000002, 0x00000002, 0x00000230, 0x00000000, 0x00000000, 0x00000002, 0x00000003,
+0x00000907, 0x00000911, 0x00000908, 0x00000912, 0x00000909, 0x00000913, 0x00000004, 0x00333269,
+0x00000002, 0x00000002, 0x00000274, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x0000096b,
+0x00000975, 0x0000096c, 0x00000976, 0x0000096d, 0x00000977, 0x0000096e, 0x00000978, 0x00000004,
+0x00343269, 0x00000002, 0x00000002, 0x000002a4, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
+0x00000c27, 0x00000c31, 0x00000c3b, 0x00000004, 0x00313369, 0x00000002, 0x00000002, 0x000002e0,
+0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000c8b, 0x00000c95, 0x00000c9f, 0x00000c8c,
+0x00000c96, 0x00000ca0, 0x00000004, 0x00323369, 0x00000002, 0x00000002, 0x00000328, 0x00000000,
+0x00000000, 0x00000003, 0x00000003, 0x00000cef, 0x00000cf9, 0x00000d03, 0x00000cf0, 0x00000cfa,
+0x00000d04, 0x00000cf1, 0x00000cfb, 0x00000d05, 0x00000004, 0x00333369, 0x00000002, 0x00000002,
+0x0000037c, 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x00000d53, 0x00000d5d, 0x00000d67,
+0x00000d54, 0x00000d5e, 0x00000d68, 0x00000d55, 0x00000d5f, 0x00000d69, 0x00000d56, 0x00000d60,
+0x00000d6a, 0x00000004, 0x00343369, 0x00000002, 0x00000002, 0x000003b0, 0x00000000, 0x00000000,
+0x00000004, 0x00000001, 0x0000100f, 0x00001019, 0x00001023, 0x0000102d, 0x00000004, 0x00313469,
+0x00000002, 0x00000002, 0x000003f4, 0x00000000, 0x00000000, 0x00000004, 0x00000002, 0x00001073,
+0x0000107d, 0x00001087, 0x00001091, 0x00001074, 0x0000107e, 0x00001088, 0x00001092, 0x00000004,
+0x00323469, 0x00000002, 0x00000002, 0x00000448, 0x00000000, 0x00000000, 0x00000004, 0x00000003,
+0x000010d7, 0x000010e1, 0x000010eb, 0x000010f5, 0x000010d8, 0x000010e2, 0x000010ec, 0x000010f6,
+0x000010d9, 0x000010e3, 0x000010ed, 0x000010f7, 0x00000004, 0x00333469, 0x00000002, 0x00000002,
+0x000004ac, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x0000113b, 0x00001145, 0x0000114f,
+0x00001159, 0x0000113c, 0x00001146, 0x00001150, 0x0000115a, 0x0000113d, 0x00001147, 0x00001151,
+0x0000115b, 0x0000113e, 0x00001148, 0x00001152, 0x0000115c, 0x00000004, 0x00343469, 0x00000002,
+0x00000000, 0x000004d8, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00000041, 0x00000042,
+0x00000004, 0x00325f69, 0x00000002, 0x00000001, 0x00000504, 0x00000000, 0x00000002, 0x00000001,
+0x00000001, 0x0000044d, 0x0000044e, 0x00000005, 0x325f3169, 0x00000000, 0x00000002, 0x00000001,
+0x0000053c, 0x00000000, 0x00000002, 0x00000002, 0x00000001, 0x00000835, 0x00000899, 0x00000836,
+0x0000089a, 0x00000005, 0x325f3269, 0x00000000, 0x00000002, 0x00000001, 0x0000057c, 0x00000000,
+0x00000002, 0x00000003, 0x00000001, 0x00000c1d, 0x00000c81, 0x00000ce5, 0x00000c1e, 0x00000c82,
+0x00000ce6, 0x00000005, 0x325f3369, 0x00000000, 0x00000002, 0x00000001, 0x000005c4, 0x00000000,
+0x00000002, 0x00000004, 0x00000001, 0x00001005, 0x00001069, 0x000010cd, 0x00001131, 0x00001006,
+0x0000106a, 0x000010ce, 0x00001132, 0x00000005, 0x325f3469, 0x00000000, 0x00000002, 0x00000002,
+0x000005f4, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x00002b5d, 0x00002b5e, 0x00000006,
+0x5f313169, 0x00000032, 0x00000002, 0x00000002, 0x0000062c, 0x00000000, 0x00000002, 0x00000001,
+0x00000002, 0x00002f45, 0x00002fa9, 0x00002f46, 0x00002faa, 0x00000006, 0x5f323169, 0x00000032,
+0x00000002, 0x00000002, 0x0000066c, 0x00000000, 0x00000002, 0x00000001, 0x00000003, 0x0000332d,
+0x00003391, 0x000033f5, 0x0000332e, 0x00003392, 0x000033f6, 0x00000006, 0x5f333169, 0x00000032,
+0x00000002, 0x00000002, 0x000006b4, 0x00000000, 0x00000002, 0x00000001, 0x00000004, 0x00003715,
+0x00003779, 0x000037dd, 0x00003841, 0x00003716, 0x0000377a, 0x000037de, 0x00003842, 0x00000006,
+0x5f343169, 0x00000032, 0x00000002, 0x00000002, 0x000006ec, 0x00000000, 0x00000002, 0x00000002,
+0x00000001, 0x0003389d, 0x00033c85, 0x0003389e, 0x00033c86, 0x00000006, 0x5f313269, 0x00000032,
+0x00000002, 0x00000002, 0x00000734, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00035fad,
+0x00036395, 0x00036011, 0x000363f9, 0x00035fae, 0x00036396, 0x00036012, 0x000363fa, 0x00000006,
+0x5f323269, 0x00000032, 0x00000002, 0x00000002, 0x0000078c, 0x00000000, 0x00000002, 0x00000002,
+0x00000003, 0x000386bd, 0x00038aa5, 0x00038721, 0x00038b09, 0x00038785, 0x00038b6d, 0x000386be,
+0x00038aa6, 0x00038722, 0x00038b0a, 0x00038786, 0x00038b6e, 0x00000006, 0x5f333269, 0x00000032,
+0x00000002, 0x00000002, 0x000007f4, 0x00000000, 0x00000002, 0x00000002, 0x00000004, 0x0003adcd,
+0x0003b1b5, 0x0003ae31, 0x0003b219, 0x0003ae95, 0x0003b27d, 0x0003aef9, 0x0003b2e1, 0x0003adce,
+0x0003b1b6, 0x0003ae32, 0x0003b21a, 0x0003ae96, 0x0003b27e, 0x0003aefa, 0x0003b2e2, 0x00000006,
+0x5f343269, 0x00000032, 0x00000002, 0x00000002, 0x00000834, 0x00000000, 0x00000002, 0x00000003,
+0x00000001, 0x0004bf3d, 0x0004c325, 0x0004c70d, 0x0004bf3e, 0x0004c326, 0x0004c70e, 0x00000006,
+0x5f313369, 0x00000032, 0x00000002, 0x00000002, 0x0000088c, 0x00000000, 0x00000002, 0x00000003,
+0x00000002, 0x0004e64d, 0x0004ea35, 0x0004ee1d, 0x0004e6b1, 0x0004ea99, 0x0004ee81, 0x0004e64e,
+0x0004ea36, 0x0004ee1e, 0x0004e6b2, 0x0004ea9a, 0x0004ee82, 0x00000006, 0x5f323369, 0x00000032,
+0x00000002, 0x00000002, 0x000008fc, 0x00000000, 0x00000002, 0x00000003, 0x00000003, 0x00050d5d,
+0x00051145, 0x0005152d, 0x00050dc1, 0x000511a9, 0x00051591, 0x00050e25, 0x0005120d, 0x000515f5,
+0x00050d5e, 0x00051146, 0x0005152e, 0x00050dc2, 0x000511aa, 0x00051592, 0x00050e26, 0x0005120e,
+0x000515f6, 0x00000006, 0x5f333369, 0x00000032, 0x00000002, 0x00000002, 0x00000984, 0x00000000,
+0x00000002, 0x00000003, 0x00000004, 0x0005346d, 0x00053855, 0x00053c3d, 0x000534d1, 0x000538b9,
+0x00053ca1, 0x00053535, 0x0005391d, 0x00053d05, 0x00053599, 0x00053981, 0x00053d69, 0x0005346e,
+0x00053856, 0x00053c3e, 0x000534d2, 0x000538ba, 0x00053ca2, 0x00053536, 0x0005391e, 0x00053d06,
+0x0005359a, 0x00053982, 0x00053d6a, 0x00000006, 0x5f343369, 0x00000032, 0x00000002, 0x00000002,
+0x000009cc, 0x00000000, 0x00000002, 0x00000004, 0x00000001, 0x000645dd, 0x000649c5, 0x00064dad,
+0x00065195, 0x000645de, 0x000649c6, 0x00064dae, 0x00065196, 0x00000006, 0x5f313469, 0x00000032,
+0x00000002, 0x00000002, 0x00000a34, 0x00000000, 0x00000002, 0x00000004, 0x00000002, 0x00066ced,
+0x000670d5, 0x000674bd, 0x000678a5, 0x00066d51, 0x00067139, 0x00067521, 0x00067909, 0x00066cee,
+0x000670d6, 0x000674be, 0x000678a6, 0x00066d52, 0x0006713a, 0x00067522, 0x0006790a, 0x00000006,
+0x5f323469, 0x00000032, 0x00000002, 0x00000002, 0x00000abc, 0x00000000, 0x00000002, 0x00000004,
+0x00000003, 0x000693fd, 0x000697e5, 0x00069bcd, 0x00069fb5, 0x00069461, 0x00069849, 0x00069c31,
+0x0006a019, 0x000694c5, 0x000698ad, 0x00069c95, 0x0006a07d, 0x000693fe, 0x000697e6, 0x00069bce,
+0x00069fb6, 0x00069462, 0x0006984a, 0x00069c32, 0x0006a01a, 0x000694c6, 0x000698ae, 0x00069c96,
+0x0006a07e, 0x00000006, 0x5f333469, 0x00000032, 0x00000002, 0x00000002, 0x00000b64, 0x00000000,
+0x00000002, 0x00000004, 0x00000004, 0x0006bb0d, 0x0006bef5, 0x0006c2dd, 0x0006c6c5, 0x0006bb71,
+0x0006bf59, 0x0006c341, 0x0006c729, 0x0006bbd5, 0x0006bfbd, 0x0006c3a5, 0x0006c78d, 0x0006bc39,
+0x0006c021, 0x0006c409, 0x0006c7f1, 0x0006bb0e, 0x0006bef6, 0x0006c2de, 0x0006c6c6, 0x0006bb72,
+0x0006bf5a, 0x0006c342, 0x0006c72a, 0x0006bbd6, 0x0006bfbe, 0x0006c3a6, 0x0006c78e, 0x0006bc3a,
+0x0006c022, 0x0006c40a, 0x0006c7f2, 0x00000006, 0x5f343469, 0x00000032, 0x00000002, 0x00000070,
+0x00000002, 0x00000074, 0x0000002a, 0x00000001, 0x00000001, 0x00000001, 0x00000004, 0x00000020,
+0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000, 0x00000000, 0x00000054, 0x00000070,
+0x00000000, 0x00000000, 0x00000080, 0x0000009c, 0x00000000, 0x00000000, 0x000000b0, 0x000000cc,
+0x00000000, 0x00000000, 0x000000e4, 0x00000100, 0x00000000, 0x00000000, 0x0000010c, 0x00000128,
+0x00000000, 0x00000000, 0x00000138, 0x00000154, 0x00000000, 0x00000000, 0x00000168, 0x00000184,
+0x00000000, 0x00000000, 0x0000019c, 0x000001b8, 0x00000000, 0x00000000, 0x000001c8, 0x000001e4,
+0x00000000, 0x00000000, 0x000001fc, 0x00000218, 0x00000000, 0x00000000, 0x00000238, 0x00000254,
+0x00000000, 0x00000000, 0x0000027c, 0x00000298, 0x00000000, 0x00000000, 0x000002ac, 0x000002c8,
+0x00000000, 0x00000000, 0x000002e8, 0x00000304, 0x00000000, 0x00000000, 0x00000330, 0x0000034c,
+0x00000000, 0x00000000, 0x00000384, 0x000003a0, 0x00000000, 0x00000000, 0x000003b8, 0x000003d4,
+0x00000000, 0x00000000, 0x000003fc, 0x00000418, 0x00000000, 0x00000000, 0x00000450, 0x0000046c,
+0x00000000, 0x00000000, 0x000004b4, 0x000004d0, 0x00000000, 0x00000000, 0x000004e0, 0x000004fc,
+0x00000000, 0x00000000, 0x00000510, 0x0000052c, 0x00000000, 0x00000000, 0x00000548, 0x00000564,
+0x00000000, 0x00000000, 0x00000588, 0x000005a4, 0x00000000, 0x00000000, 0x000005d0, 0x000005ec,
+0x00000000, 0x00000000, 0x00000600, 0x0000061c, 0x00000000, 0x00000000, 0x00000638, 0x00000654,
+0x00000000, 0x00000000, 0x00000678, 0x00000694, 0x00000000, 0x00000000, 0x000006c0, 0x000006dc,
+0x00000000, 0x00000000, 0x000006f8, 0x00000714, 0x00000000, 0x00000000, 0x00000740, 0x0000075c,
+0x00000000, 0x00000000, 0x00000798, 0x000007b4, 0x00000000, 0x00000000, 0x00000800, 0x0000081c,
+0x00000000, 0x00000000, 0x00000840, 0x0000085c, 0x00000000, 0x00000000, 0x00000898, 0x000008b4,
+0x00000000, 0x00000000, 0x00000908, 0x00000924, 0x00000000, 0x00000000, 0x00000990, 0x000009ac,
+0x00000000, 0x00000000, 0x000009d8, 0x000009f4, 0x00000000, 0x00000000, 0x00000a40, 0x00000a5c,
+0x00000000, 0x00000000, 0x00000ac8, 0x00000ae4, 0x00000000, 0x00000000, 0x00000b78, 0x00000000,
+0x00000001, 0x00000b70, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+struct test_effect_parameter_value_result test_effect_parameter_value_result_int[] =
+{
+ {"i", {"i", NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, 4}, 10},
+ {"i1", {"i1", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 1, 0, 0, 0, 0, 4}, 20},
+ {"i2", {"i2", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 2, 0, 0, 0, 0, 8}, 30},
+ {"i3", {"i3", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 0, 0, 0, 0, 12}, 41},
+ {"i4", {"i4", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 4, 0, 0, 0, 0, 16}, 53},
+ {"i11", {"i11", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 1, 0, 0, 0, 0, 4}, 66},
+ {"i12", {"i12", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 2, 0, 0, 0, 0, 8}, 76},
+ {"i13", {"i13", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 3, 0, 0, 0, 0, 12}, 87},
+ {"i14", {"i14", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 4, 0, 0, 0, 0, 16}, 99},
+ {"i21", {"i21", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 1, 0, 0, 0, 0, 8}, 112},
+ {"i22", {"i22", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 2, 0, 0, 0, 0, 16}, 123},
+ {"i23", {"i23", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 3, 0, 0, 0, 0, 24}, 136},
+ {"i24", {"i24", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 4, 0, 0, 0, 0, 32}, 151},
+ {"i31", {"i31", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 1, 0, 0, 0, 0, 12}, 168},
+ {"i32", {"i32", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 0, 0, 0, 0, 24}, 180},
+ {"i33", {"i33", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 3, 0, 0, 0, 0, 36}, 195},
+ {"i34", {"i34", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 4, 0, 0, 0, 0, 48}, 213},
+ {"i41", {"i41", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 1, 0, 0, 0, 0, 16}, 234},
+ {"i42", {"i42", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 2, 0, 0, 0, 0, 32}, 247},
+ {"i43", {"i43", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 3, 0, 0, 0, 0, 48}, 264},
+ {"i44", {"i44", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 4, 0, 0, 0, 0, 64}, 285},
+ {"i_2", {"i_2", NULL, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 2, 0, 0, 0, 8}, 310},
+ {"i1_2", {"i1_2", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 1, 2, 0, 0, 0, 8}, 321},
+ {"i2_2", {"i2_2", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 2, 2, 0, 0, 0, 16}, 333},
+ {"i3_2", {"i3_2", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 2, 0, 0, 0, 24}, 347},
+ {"i4_2", {"i4_2", NULL, D3DXPC_VECTOR, D3DXPT_INT, 1, 4, 2, 0, 0, 0, 32}, 363},
+ {"i11_2", {"i11_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 1, 2, 0, 0, 0, 8}, 381},
+ {"i12_2", {"i12_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 2, 2, 0, 0, 0, 16}, 393},
+ {"i13_2", {"i13_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 3, 2, 0, 0, 0, 24}, 407},
+ {"i14_2", {"i14_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 1, 4, 2, 0, 0, 0, 32}, 423},
+ {"i21_2", {"i21_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 1, 2, 0, 0, 0, 16}, 441},
+ {"i22_2", {"i22_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 2, 2, 0, 0, 0, 32}, 455},
+ {"i23_2", {"i23_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 3, 2, 0, 0, 0, 48}, 473},
+ {"i24_2", {"i24_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 4, 2, 0, 0, 0, 64}, 495},
+ {"i31_2", {"i31_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 1, 2, 0, 0, 0, 24}, 521},
+ {"i32_2", {"i32_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 2, 0, 0, 0, 48}, 537},
+ {"i33_2", {"i33_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 3, 2, 0, 0, 0, 72}, 559},
+ {"i34_2", {"i34_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 4, 2, 0, 0, 0, 96}, 587},
+ {"i41_2", {"i41_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 1, 2, 0, 0, 0, 32}, 621},
+ {"i42_2", {"i42_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 2, 2, 0, 0, 0, 64}, 639},
+ {"i43_2", {"i43_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 3, 2, 0, 0, 0, 96}, 665},
+ {"i44_2", {"i44_2", NULL, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 4, 4, 2, 0, 0, 0, 128}, 699},
+};
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+string s = "test";
+string s_2[2] = {"test1", "test2"};
+texture2D tex;
+Vertexshader v;
+Vertexshader v_2[2];
+Pixelshader p;
+Pixelshader p_2[2];
+technique t { pass p { } }
+#endif
+static const DWORD test_effect_parameter_value_blob_object[] =
+{
+0xfeff0901, 0x00000100, 0x00000000, 0x00000004, 0x00000004, 0x0000001c, 0x00000000, 0x00000000,
+0x00000001, 0x00000002, 0x00000073, 0x00000004, 0x00000004, 0x00000040, 0x00000000, 0x00000002,
+0x00000002, 0x00000003, 0x00000004, 0x00325f73, 0x00000007, 0x00000004, 0x00000060, 0x00000000,
+0x00000000, 0x00000004, 0x00000004, 0x00786574, 0x00000010, 0x00000004, 0x00000080, 0x00000000,
+0x00000000, 0x00000005, 0x00000002, 0x00000076, 0x00000010, 0x00000004, 0x000000a4, 0x00000000,
+0x00000002, 0x00000006, 0x00000007, 0x00000004, 0x00325f76, 0x0000000f, 0x00000004, 0x000000c4,
+0x00000000, 0x00000000, 0x00000008, 0x00000002, 0x00000070, 0x0000000f, 0x00000004, 0x000000e8,
+0x00000000, 0x00000002, 0x00000009, 0x0000000a, 0x00000004, 0x00325f70, 0x00000002, 0x00000070,
+0x00000002, 0x00000074, 0x00000007, 0x00000001, 0x00000007, 0x0000000b, 0x00000004, 0x00000018,
+0x00000000, 0x00000000, 0x00000024, 0x00000038, 0x00000000, 0x00000000, 0x00000048, 0x0000005c,
+0x00000000, 0x00000000, 0x00000068, 0x0000007c, 0x00000000, 0x00000000, 0x00000088, 0x0000009c,
+0x00000000, 0x00000000, 0x000000ac, 0x000000c0, 0x00000000, 0x00000000, 0x000000cc, 0x000000e0,
+0x00000000, 0x00000000, 0x000000f8, 0x00000000, 0x00000001, 0x000000f0, 0x00000000, 0x00000000,
+0x0000000a, 0x00000000, 0x00000009, 0x00000000, 0x0000000a, 0x00000000, 0x00000008, 0x00000000,
+0x00000006, 0x00000000, 0x00000007, 0x00000000, 0x00000005, 0x00000000, 0x00000004, 0x00000000,
+0x00000002, 0x00000006, 0x74736574, 0x00000031, 0x00000003, 0x00000006, 0x74736574, 0x00000032,
+0x00000001, 0x00000005, 0x74736574, 0x00000000,
+};
+
+struct test_effect_parameter_value_result test_effect_parameter_value_result_object[] =
+{
+ {"s", {"s", NULL, D3DXPC_OBJECT, D3DXPT_STRING, 0, 0, 0, 0, 0, 0, sizeof(void *)}, 0},
+ {"s_2", {"s_2", NULL, D3DXPC_OBJECT, D3DXPT_STRING, 0, 0, 2, 0, 0, 0, 2 * sizeof(void *)}, 0},
+ {"tex", {"tex", NULL, D3DXPC_OBJECT, D3DXPT_TEXTURE2D, 0, 0, 0, 0, 0, 0, sizeof(void *)}, 0},
+ {"v", {"v", NULL, D3DXPC_OBJECT, D3DXPT_VERTEXSHADER, 0, 0, 0, 0, 0, 0, sizeof(void *)}, 0},
+ {"v_2", {"v_2", NULL, D3DXPC_OBJECT, D3DXPT_VERTEXSHADER, 0, 0, 2, 0, 0, 0, 2 * sizeof(void *)}, 0},
+ {"p", {"p", NULL, D3DXPC_OBJECT, D3DXPT_PIXELSHADER, 0, 0, 0, 0, 0, 0, sizeof(void *)}, 0},
+ {"p_2", {"p_2", NULL, D3DXPC_OBJECT, D3DXPT_PIXELSHADER, 0, 0, 2, 0, 0, 0, 2 * sizeof(void *)}, 0},
+};
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+float3 f3 = {-3.1, 153.2, 283.3};
+float3 f3min = {-31.1, -31.2, -31.3};
+float3 f3max = {320.1, 320.2, 320.3};
+float4 f4 = {-4.1, 154.2, 284.3, 34.4};
+float4 f4min = {-41.1, -41.2, -41.3, -41.4};
+float4 f4max = {420.1, 42.20, 420.3, 420.4};
+technique t { pass p { } }
+#endif
+static const DWORD test_effect_parameter_value_blob_special[] =
+{
+0xfeff0901, 0x00000150, 0x00000000, 0x00000003, 0x00000001, 0x0000002c, 0x00000000, 0x00000000,
+0x00000003, 0x00000001, 0xc0466666, 0x43193333, 0x438da666, 0x00000003, 0x00003366, 0x00000003,
+0x00000001, 0x0000005c, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0xc1f8cccd, 0xc1f9999a,
+0xc1fa6666, 0x00000006, 0x696d3366, 0x0000006e, 0x00000003, 0x00000001, 0x00000090, 0x00000000,
+0x00000000, 0x00000003, 0x00000001, 0x43a00ccd, 0x43a0199a, 0x43a02666, 0x00000006, 0x616d3366,
+0x00000078, 0x00000003, 0x00000001, 0x000000c8, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+0xc0833333, 0x431a3333, 0x438e2666, 0x4209999a, 0x00000003, 0x00003466, 0x00000003, 0x00000001,
+0x000000fc, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0xc2246666, 0xc224cccd, 0xc2253333,
+0xc225999a, 0x00000006, 0x696d3466, 0x0000006e, 0x00000003, 0x00000001, 0x00000134, 0x00000000,
+0x00000000, 0x00000004, 0x00000001, 0x43d20ccd, 0x4228cccd, 0x43d22666, 0x43d23333, 0x00000006,
+0x616d3466, 0x00000078, 0x00000002, 0x00000070, 0x00000002, 0x00000074, 0x00000006, 0x00000001,
+0x00000001, 0x00000001, 0x00000004, 0x00000020, 0x00000000, 0x00000000, 0x00000034, 0x00000050,
+0x00000000, 0x00000000, 0x00000068, 0x00000084, 0x00000000, 0x00000000, 0x0000009c, 0x000000b8,
+0x00000000, 0x00000000, 0x000000d0, 0x000000ec, 0x00000000, 0x00000000, 0x00000108, 0x00000124,
+0x00000000, 0x00000000, 0x00000148, 0x00000000, 0x00000001, 0x00000140, 0x00000000, 0x00000000,
+0x00000000, 0x00000000,
+};
+
+struct test_effect_parameter_value_result test_effect_parameter_value_result_special[] =
+{
+ {"f3", {"f3", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 0, 0, 0, 0, 12}, 10},
+ {"f3min", {"f3min", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 0, 0, 0, 0, 12}, 22},
+ {"f3max", {"f3max", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 0, 0, 0, 0, 12}, 35},
+ {"f4", {"f4", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 0, 0, 0, 0, 16}, 48},
+ {"f4min", {"f4min", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 0, 0, 0, 0, 16}, 61},
+ {"f4max", {"f4max", NULL, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 0, 0, 0, 0, 16}, 75},
+};
+
+#define ADD_PARAMETER_VALUE(x) {\
+ test_effect_parameter_value_blob_ ## x,\
+ sizeof(test_effect_parameter_value_blob_ ## x),\
+ test_effect_parameter_value_result_ ## x,\
+ ARRAY_SIZE(test_effect_parameter_value_result_ ## x),\
+}
+
+static const struct
+{
+ const DWORD *blob;
+ UINT blob_size;
+ const struct test_effect_parameter_value_result *res;
+ UINT res_count;
+}
+test_effect_parameter_value_data[] =
+{
+ ADD_PARAMETER_VALUE(float),
+ ADD_PARAMETER_VALUE(int),
+ ADD_PARAMETER_VALUE(object),
+ ADD_PARAMETER_VALUE(special),
+};
+
+#undef ADD_PARAMETER_VALUE
+
+/* Multiple of 16 to cover complete matrices */
+#define EFFECT_PARAMETER_VALUE_ARRAY_SIZE 48
+/* Constants for special INT/FLOAT conversation */
+#define INT_FLOAT_MULTI 255.0f
+#define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
+
+static void test_effect_parameter_value_GetValue(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ DWORD value[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ HRESULT hr;
+ UINT l;
+
+ memset(value, 0xab, sizeof(value));
+ hr = effect->lpVtbl->GetValue(effect, parameter, value, res_desc->Bytes);
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetValue failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < res_desc->Bytes / sizeof(*value); ++l)
+ {
+ ok(value[l] == res_value[l], "%u - %s: GetValue value[%u] failed, got %#x, expected %#x\n",
+ i, res_full_name, l, value[l], res_value[l]);
+ }
+
+ for (l = res_desc->Bytes / sizeof(*value); l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ ok(value[l] == 0xabababab, "%u - %s: GetValue value[%u] failed, got %#x, expected %#x\n",
+ i, res_full_name, l, value[l], 0xabababab);
+ }
+ }
+ else if (res_desc->Class == D3DXPC_OBJECT)
+ {
+ switch (res_desc->Type)
+ {
+ case D3DXPT_PIXELSHADER:
+ case D3DXPT_VERTEXSHADER:
+ case D3DXPT_TEXTURE2D:
+ ok(hr == D3D_OK, "%u - %s: GetValue failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < (res_desc->Elements ? res_desc->Elements : 1); ++l)
+ {
+ IUnknown *unk = *((IUnknown **)value + l);
+ if (unk) IUnknown_Release(unk);
+ }
+ break;
+
+ case D3DXPT_STRING:
+ ok(hr == D3D_OK, "%u - %s: GetValue failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ break;
+
+ default:
+ ok(0, "Type is %u, this should not happen!\n", res_desc->Type);
+ break;
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetValue failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ ok(value[l] == 0xabababab, "%u - %s: GetValue value[%u] failed, got %#x, expected %#x\n",
+ i, res_full_name, l, value[l], 0xabababab);
+ }
+ }
+}
+
+static void test_effect_parameter_value_GetBool(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ BOOL bvalue = 0xabababab;
+ HRESULT hr;
+
+ hr = effect->lpVtbl->GetBool(effect, parameter, &bvalue);
+ if (!res_desc->Elements && res_desc->Rows == 1 && res_desc->Columns == 1)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetBool failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(bvalue == get_bool(res_value), "%u - %s: GetBool bvalue failed, got %#x, expected %#x\n",
+ i, res_full_name, bvalue, get_bool(res_value));
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBool failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ ok(bvalue == 0xabababab, "%u - %s: GetBool bvalue failed, got %#x, expected %#x\n",
+ i, res_full_name, bvalue, 0xabababab);
+ }
+}
+
+static void test_effect_parameter_value_GetBoolArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ BOOL bavalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ HRESULT hr;
+ UINT l, err = 0;
+
+ memset(bavalue, 0xab, sizeof(bavalue));
+ hr = effect->lpVtbl->GetBoolArray(effect, parameter, bavalue, res_desc->Bytes / sizeof(*bavalue));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetBoolArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < res_desc->Bytes / sizeof(*bavalue); ++l)
+ {
+ if (bavalue[l] != get_bool(&res_value[l])) ++err;
+ }
+
+ for (l = res_desc->Bytes / sizeof(*bavalue); l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ if (bavalue[l] != 0xabababab) ++err;
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBoolArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (bavalue[l] != 0xabababab) ++err;
+ }
+ ok(!err, "%u - %s: GetBoolArray failed with %u errors\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetInt(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ INT ivalue = 0xabababab;
+ HRESULT hr;
+
+ hr = effect->lpVtbl->GetInt(effect, parameter, &ivalue);
+ if (!res_desc->Elements && res_desc->Columns == 1 && res_desc->Rows == 1)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetInt failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(ivalue == get_int(res_desc->Type, res_value), "%u - %s: GetInt ivalue failed, got %i, expected %i\n",
+ i, res_full_name, ivalue, get_int(res_desc->Type, res_value));
+ }
+ else if(!res_desc->Elements && res_desc->Type == D3DXPT_FLOAT &&
+ ((res_desc->Class == D3DXPC_VECTOR && res_desc->Columns != 2) ||
+ (res_desc->Class == D3DXPC_MATRIX_ROWS && res_desc->Rows != 2 && res_desc->Columns == 1)))
+ {
+ INT tmp;
+
+ ok(hr == D3D_OK, "%u - %s: GetInt failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ tmp = (INT)(min(max(0.0f, *((FLOAT *)res_value + 2)), 1.0f) * INT_FLOAT_MULTI);
+ tmp += ((INT)(min(max(0.0f, *((FLOAT *)res_value + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
+ tmp += ((INT)(min(max(0.0f, *((FLOAT *)res_value + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
+ if (res_desc->Columns * res_desc->Rows > 3)
+ {
+ tmp += ((INT)(min(max(0.0f, *((FLOAT *)res_value + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
+ }
+
+ ok(ivalue == tmp, "%u - %s: GetInt ivalue failed, got %x, expected %x\n",
+ i, res_full_name, ivalue, tmp);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ ok(ivalue == 0xabababab, "%u - %s: GetInt ivalue failed, got %i, expected %i\n",
+ i, res_full_name, ivalue, 0xabababab);
+ }
+}
+
+static void test_effect_parameter_value_GetIntArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ INT iavalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ HRESULT hr;
+ UINT l, err = 0;
+
+ memset(iavalue, 0xab, sizeof(iavalue));
+ hr = effect->lpVtbl->GetIntArray(effect, parameter, iavalue, res_desc->Bytes / sizeof(*iavalue));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetIntArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < res_desc->Bytes / sizeof(*iavalue); ++l)
+ {
+ if (iavalue[l] != get_int(res_desc->Type, &res_value[l])) ++err;
+ }
+
+ for (l = res_desc->Bytes / sizeof(*iavalue); l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ if (iavalue[l] != 0xabababab) ++err;
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetIntArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (iavalue[l] != 0xabababab) ++err;
+ }
+ ok(!err, "%u - %s: GetIntArray failed with %u errors\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetFloat(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue = *(FLOAT *)&cmp;
+
+ hr = effect->lpVtbl->GetFloat(effect, parameter, &fvalue);
+ if (!res_desc->Elements && res_desc->Columns == 1 && res_desc->Rows == 1)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetFloat failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ ok(compare_float(fvalue, get_float(res_desc->Type, res_value), 512), "%u - %s: GetFloat fvalue failed, got %f, expected %f\n",
+ i, res_full_name, fvalue, get_float(res_desc->Type, res_value));
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloat failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ ok(fvalue == *(FLOAT *)&cmp, "%u - %s: GetFloat fvalue failed, got %f, expected %f\n",
+ i, res_full_name, fvalue, *(FLOAT *)&cmp);
+ }
+}
+
+static void test_effect_parameter_value_GetFloatArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ FLOAT favalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ HRESULT hr;
+ UINT l, err = 0;
+ DWORD cmp = 0xabababab;
+
+ memset(favalue, 0xab, sizeof(favalue));
+ hr = effect->lpVtbl->GetFloatArray(effect, parameter, favalue, res_desc->Bytes / sizeof(*favalue));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetFloatArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < res_desc->Bytes / sizeof(*favalue); ++l)
+ {
+ if (!compare_float(favalue[l], get_float(res_desc->Type, &res_value[l]), 512)) ++err;
+ }
+
+ for (l = res_desc->Bytes / sizeof(*favalue); l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ if (favalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloatArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (favalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s: GetFloatArray failed with %u errors\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetVector(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[4];
+ UINT l, err = 0;
+
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetVector(effect, parameter, (D3DXVECTOR4 *)&fvalue);
+ if (!res_desc->Elements &&
+ (res_desc->Class == D3DXPC_SCALAR || res_desc->Class == D3DXPC_VECTOR) &&
+ res_desc->Type == D3DXPT_INT && res_desc->Bytes == 4)
+ {
+ DWORD tmp;
+
+ ok(hr == D3D_OK, "%u - %s: GetVector failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ tmp = (DWORD)(*(fvalue + 2) * INT_FLOAT_MULTI);
+ tmp += ((DWORD)(*(fvalue + 1) * INT_FLOAT_MULTI)) << 8;
+ tmp += ((DWORD)(*fvalue * INT_FLOAT_MULTI)) << 16;
+ tmp += ((DWORD)(*(fvalue + 3) * INT_FLOAT_MULTI)) << 24;
+
+ if (*res_value != tmp) ++err;
+ }
+ else if (!res_desc->Elements && (res_desc->Class == D3DXPC_SCALAR || res_desc->Class == D3DXPC_VECTOR))
+ {
+ ok(hr == D3D_OK, "%u - %s: GetVector failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ for (l = 0; l < res_desc->Columns; ++l)
+ {
+ if (!compare_float(fvalue[l], get_float(res_desc->Type, &res_value[l]), 512)) ++err;
+ }
+
+ for (l = res_desc->Columns; l < 4; ++l) if (fvalue[l] != 0.0f) ++err;
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetVector failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < 4; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s: GetVector failed with %u errors\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetVectorArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ UINT l, k, element, err = 0;
+
+ for (element = 0; element <= res_desc->Elements + 1; ++element)
+ {
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetVectorArray(effect, parameter, (D3DXVECTOR4 *)&fvalue, element);
+ if (!element)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetVectorArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3D_OK);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_VECTOR)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetVectorArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3D_OK);
+
+ for (k = 0; k < element; ++k)
+ {
+ for (l = 0; l < res_desc->Columns; ++l)
+ {
+ if (!compare_float(fvalue[l + k * 4], get_float(res_desc->Type,
+ &res_value[l + k * res_desc->Columns]), 512))
+ ++err;
+ }
+
+ for (l = res_desc->Columns; l < 4; ++l) if (fvalue[l + k * 4] != 0.0f) ++err;
+ }
+
+ for (l = element * 4; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetVectorArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s[%u]: GetVectorArray failed with %u errors\n", i, res_full_name, element, err);
+ }
+}
+
+static void test_effect_parameter_value_GetMatrix(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ union
+ {
+ DWORD d;
+ float f;
+ } cmp;
+ float fvalue[16];
+ UINT l, k, err = 0;
+
+ cmp.d = 0xabababab;
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetMatrix(effect, parameter, (D3DXMATRIX *)&fvalue);
+ if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetMatrix failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
+
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[l * 4 + k], get_float(res_desc->Type,
+ &res_value[l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[l * 4 + k] != 0.0f) ++err;
+ }
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrix failed, got %#x, expected %#x.\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < ARRAY_SIZE(fvalue); ++l)
+ if (fvalue[l] != cmp.f)
+ ++err;
+ }
+ ok(!err, "%u - %s: GetMatrix failed with %u errors.\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetMatrixArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ UINT l, k, m, element, err = 0;
+
+ for (element = 0; element <= res_desc->Elements + 1; ++element)
+ {
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetMatrixArray(effect, parameter, (D3DXMATRIX *)&fvalue, element);
+ if (!element)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3D_OK);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixArray failed, got %#x, expected %#x\n", i, res_full_name, element, hr, D3D_OK);
+
+ for (m = 0; m < element; ++m)
+ {
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[m * 16 + l * 4 + k], get_float(res_desc->Type,
+ &res_value[m * res_desc->Columns * res_desc->Rows + l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[m * 16 + l * 4 + k] != 0.0f) ++err;
+ }
+ }
+ }
+
+ for (l = element * 16; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetMatrixArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s[%u]: GetMatrixArray failed with %u errors\n", i, res_full_name, element, err);
+ }
+}
+
+static void test_effect_parameter_value_GetMatrixPointerArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ D3DXMATRIX *matrix_pointer_array[sizeof(fvalue)/sizeof(D3DXMATRIX)];
+ UINT l, k, m, element, err = 0;
+
+ for (element = 0; element <= res_desc->Elements + 1; ++element)
+ {
+ memset(fvalue, 0xab, sizeof(fvalue));
+ for (l = 0; l < element; ++l)
+ {
+ matrix_pointer_array[l] = (D3DXMATRIX *)&fvalue[l * sizeof(**matrix_pointer_array) / sizeof(FLOAT)];
+ }
+ hr = effect->lpVtbl->GetMatrixPointerArray(effect, parameter, matrix_pointer_array, element);
+ if (!element)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (m = 0; m < element; ++m)
+ {
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[m * 16 + l * 4 + k], get_float(res_desc->Type,
+ &res_value[m * res_desc->Columns * res_desc->Rows + l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[m * 16 + l * 4 + k] != 0.0f) ++err;
+ }
+ }
+ }
+
+ for (l = element * 16; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else
+ {
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3DERR_INVALIDCALL);
+ }
+ ok(!err, "%u - %s[%u]: GetMatrixPointerArray failed with %u errors\n", i, res_full_name, element, err);
+ }
+}
+
+static void test_effect_parameter_value_GetMatrixTranspose(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ union
+ {
+ DWORD d;
+ float f;
+ } cmp;
+ float fvalue[16];
+ UINT l, k, err = 0;
+
+ cmp.d = 0xabababab;
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetMatrixTranspose(effect, parameter, (D3DXMATRIX *)&fvalue);
+ if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
+
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[l + k * 4], get_float(res_desc->Type,
+ &res_value[l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[l + k * 4] != 0.0f) ++err;
+ }
+ }
+ }
+ else if (!res_desc->Elements && (res_desc->Class == D3DXPC_VECTOR || res_desc->Class == D3DXPC_SCALAR))
+ {
+ ok(hr == D3D_OK, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n", i, res_full_name, hr, D3D_OK);
+
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[l * 4 + k], get_float(res_desc->Type,
+ &res_value[l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[l * 4 + k] != 0.0f) ++err;
+ }
+ }
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x.\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < ARRAY_SIZE(fvalue); ++l)
+ if (fvalue[l] != cmp.f)
+ ++err;
+ }
+ ok(!err, "%u - %s: GetMatrixTranspose failed with %u errors.\n", i, res_full_name, err);
+}
+
+static void test_effect_parameter_value_GetMatrixTransposeArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ UINT l, k, m, element, err = 0;
+
+ for (element = 0; element <= res_desc->Elements + 1; ++element)
+ {
+ memset(fvalue, 0xab, sizeof(fvalue));
+ hr = effect->lpVtbl->GetMatrixTransposeArray(effect, parameter, (D3DXMATRIX *)&fvalue, element);
+ if (!element)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (m = 0; m < element; ++m)
+ {
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[m * 16 + l + k * 4], get_float(res_desc->Type,
+ &res_value[m * res_desc->Columns * res_desc->Rows + l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[m * 16 + l + k * 4] != 0.0f) ++err;
+ }
+ }
+ }
+
+ for (l = element * 16; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s[%u]: GetMatrixTransposeArray failed with %u errors\n", i, res_full_name, element, err);
+ }
+}
+
+static void test_effect_parameter_value_GetMatrixTransposePointerArray(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+ DWORD cmp = 0xabababab;
+ FLOAT fvalue[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ D3DXMATRIX *matrix_pointer_array[sizeof(fvalue)/sizeof(D3DXMATRIX)];
+ UINT l, k, m, element, err = 0;
+
+ for (element = 0; element <= res_desc->Elements + 1; ++element)
+ {
+ memset(fvalue, 0xab, sizeof(fvalue));
+ for (l = 0; l < element; ++l)
+ {
+ matrix_pointer_array[l] = (D3DXMATRIX *)&fvalue[l * sizeof(**matrix_pointer_array) / sizeof(FLOAT)];
+ }
+ hr = effect->lpVtbl->GetMatrixTransposePointerArray(effect, parameter, matrix_pointer_array, element);
+ if (!element)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else if (element <= res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ ok(hr == D3D_OK, "%u - %s[%u]: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3D_OK);
+
+ for (m = 0; m < element; ++m)
+ {
+ for (k = 0; k < 4; ++k)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ if (k < res_desc->Columns && l < res_desc->Rows)
+ {
+ if (!compare_float(fvalue[m * 16 + l + k * 4], get_float(res_desc->Type,
+ &res_value[m * res_desc->Columns * res_desc->Rows + l * res_desc->Columns + k]), 512))
+ ++err;
+ }
+ else if (fvalue[m * 16 + l + k * 4] != 0.0f) ++err;
+ }
+ }
+ }
+
+ for (l = element * 16; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s[%u]: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, element, hr, D3DERR_INVALIDCALL);
+
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l) if (fvalue[l] != *(FLOAT *)&cmp) ++err;
+ }
+ ok(!err, "%u - %s[%u]: GetMatrixTransposePointerArray failed with %u errors\n", i, res_full_name, element, err);
+ }
+}
+
+static void test_effect_parameter_value_GetTestGroup(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ test_effect_parameter_value_GetValue(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetBool(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetBoolArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetInt(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetIntArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetFloat(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetFloatArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetVector(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetVectorArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrix(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrixArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrixPointerArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrixTranspose(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrixTransposeArray(res, effect, res_value, parameter, i);
+ test_effect_parameter_value_GetMatrixTransposePointerArray(res, effect, res_value, parameter, i);
+}
+
+static void test_effect_parameter_value_ResetValue(const struct test_effect_parameter_value_result *res,
+ ID3DXEffect *effect, const DWORD *res_value, D3DXHANDLE parameter, UINT i)
+{
+ const D3DXPARAMETER_DESC *res_desc = &res->desc;
+ const char *res_full_name = res->full_name;
+ HRESULT hr;
+
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ hr = effect->lpVtbl->SetValue(effect, parameter, res_value, res_desc->Bytes);
+ ok(hr == D3D_OK, "%u - %s: SetValue failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ /* nothing to do */
+ switch (res_desc->Type)
+ {
+ case D3DXPT_PIXELSHADER:
+ case D3DXPT_VERTEXSHADER:
+ case D3DXPT_TEXTURE2D:
+ case D3DXPT_STRING:
+ break;
+
+ default:
+ ok(0, "Type is %u, this should not happen!\n", res_desc->Type);
+ break;
+ }
+ }
+}
+
+static void test_effect_parameter_value(IDirect3DDevice9 *device)
+{
+ unsigned int effect_count = ARRAY_SIZE(test_effect_parameter_value_data), i;
+
+ for (i = 0; i < effect_count; ++i)
+ {
+ const struct test_effect_parameter_value_result *res = test_effect_parameter_value_data[i].res;
+ UINT res_count = test_effect_parameter_value_data[i].res_count;
+ const DWORD *blob = test_effect_parameter_value_data[i].blob;
+ UINT blob_size = test_effect_parameter_value_data[i].blob_size;
+ HRESULT hr;
+ ID3DXEffect *effect;
+ D3DXEFFECT_DESC edesc;
+ ULONG count;
+ UINT k;
+
+ hr = D3DXCreateEffect(device, blob, blob_size, NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "%u: D3DXCreateEffect failed, got %#x, expected %#x\n", i, hr, D3D_OK);
+
+ hr = effect->lpVtbl->GetDesc(effect, &edesc);
+ ok(hr == D3D_OK, "%u: GetDesc failed, got %#x, expected %#x\n", i, hr, D3D_OK);
+ ok(edesc.Parameters == res_count, "%u: Parameters failed, got %u, expected %u\n",
+ i, edesc.Parameters, res_count);
+
+ for (k = 0; k < res_count; ++k)
+ {
+ const D3DXPARAMETER_DESC *res_desc = &res[k].desc;
+ const char *res_full_name = res[k].full_name;
+ UINT res_value_offset = res[k].value_offset;
+ D3DXHANDLE parameter;
+ D3DXPARAMETER_DESC pdesc;
+ BOOL bvalue = TRUE;
+ INT ivalue = 42;
+ FLOAT fvalue = 2.71828f;
+ DWORD input_value[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ DWORD expected_value[EFFECT_PARAMETER_VALUE_ARRAY_SIZE];
+ UINT l, n, m, element;
+ const D3DXMATRIX *matrix_pointer_array[sizeof(input_value)/sizeof(D3DXMATRIX)];
+
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, res_full_name);
+ ok(parameter != NULL, "%u - %s: GetParameterByName failed\n", i, res_full_name);
+
+ hr = effect->lpVtbl->GetParameterDesc(effect, parameter, &pdesc);
+ ok(hr == D3D_OK, "%u - %s: GetParameterDesc failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+
+ ok(res_desc->Name ? !strcmp(pdesc.Name, res_desc->Name) : !pdesc.Name,
+ "%u - %s: GetParameterDesc Name failed, got \"%s\", expected \"%s\"\n",
+ i, res_full_name, pdesc.Name, res_desc->Name);
+ ok(res_desc->Semantic ? !strcmp(pdesc.Semantic, res_desc->Semantic) : !pdesc.Semantic,
+ "%u - %s: GetParameterDesc Semantic failed, got \"%s\", expected \"%s\"\n",
+ i, res_full_name, pdesc.Semantic, res_desc->Semantic);
+ ok(res_desc->Class == pdesc.Class, "%u - %s: GetParameterDesc Class failed, got %#x, expected %#x\n",
+ i, res_full_name, pdesc.Class, res_desc->Class);
+ ok(res_desc->Type == pdesc.Type, "%u - %s: GetParameterDesc Type failed, got %#x, expected %#x\n",
+ i, res_full_name, pdesc.Type, res_desc->Type);
+ ok(res_desc->Rows == pdesc.Rows, "%u - %s: GetParameterDesc Rows failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.Rows, res_desc->Rows);
+ ok(res_desc->Columns == pdesc.Columns, "%u - %s: GetParameterDesc Columns failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.Columns, res_desc->Columns);
+ ok(res_desc->Elements == pdesc.Elements, "%u - %s: GetParameterDesc Elements failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.Elements, res_desc->Elements);
+ ok(res_desc->Annotations == pdesc.Annotations, "%u - %s: GetParameterDesc Annotations failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.Annotations, res_desc->Annotations);
+ ok(res_desc->StructMembers == pdesc.StructMembers, "%u - %s: GetParameterDesc StructMembers failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.StructMembers, res_desc->StructMembers);
+ ok(res_desc->Flags == pdesc.Flags, "%u - %s: GetParameterDesc Flags failed, got %u, expected %u\n",
+ i, res_full_name, pdesc.Flags, res_desc->Flags);
+ ok(res_desc->Bytes == pdesc.Bytes, "%u - %s: GetParameterDesc Bytes, got %u, expected %u\n",
+ i, res_full_name, pdesc.Bytes, res_desc->Bytes);
+
+ /* check size */
+ ok(EFFECT_PARAMETER_VALUE_ARRAY_SIZE >= res_desc->Bytes / 4 +
+ (res_desc->Elements ? res_desc->Bytes / 4 / res_desc->Elements : 0),
+ "%u - %s: Warning: Array size too small\n", i, res_full_name);
+
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, &blob[res_value_offset], parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /*
+ * check invalid calls
+ * These will crash:
+ * effect->lpVtbl->SetBoolArray(effect, parameter, NULL, res_desc->Bytes / sizeof(BOOL));
+ * effect->lpVtbl->SetIntArray(effect, parameter, NULL, res_desc->Bytes / sizeof(INT));
+ * effect->lpVtbl->SetFloatArray(effect, parameter, NULL, res_desc->Bytes / sizeof(FLOAT));
+ * effect->lpVtbl->SetVector(effect, parameter, NULL);
+ * effect->lpVtbl->SetVectorArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ * effect->lpVtbl->SetMatrix(effect, parameter, NULL);
+ * effect->lpVtbl->GetMatrix(effect, parameter, NULL);
+ * effect->lpVtbl->SetMatrixArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ * effect->lpVtbl->SetMatrixPointerArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ * effect->lpVtbl->SetMatrixTranspose(effect, parameter, NULL);
+ * effect->lpVtbl->SetMatrixTransposeArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ * effect->lpVtbl->SetMatrixTransposePointerArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ * effect->lpVtbl->GetValue(effect, parameter, NULL, res_desc->Bytes);
+ * effect->lpVtbl->SetValue(effect, parameter, NULL, res_desc->Bytes);
+ */
+ hr = effect->lpVtbl->SetBool(effect, NULL, bvalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetBool failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetBool(effect, NULL, &bvalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBool failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetBool(effect, parameter, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBool failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetBoolArray(effect, NULL, (BOOL *)input_value, res_desc->Bytes / sizeof(BOOL));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetBoolArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetBoolArray(effect, NULL, (BOOL *)input_value, res_desc->Bytes / sizeof(BOOL));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBoolArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetBoolArray(effect, parameter, NULL, res_desc->Bytes / sizeof(BOOL));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetBoolArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetInt(effect, NULL, ivalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetInt(effect, NULL, &ivalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetInt(effect, parameter, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetIntArray(effect, NULL, (INT *)input_value, res_desc->Bytes / sizeof(INT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetIntArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetIntArray(effect, NULL, (INT *)input_value, res_desc->Bytes / sizeof(INT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetIntArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetIntArray(effect, parameter, NULL, res_desc->Bytes / sizeof(INT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetIntArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetFloat(effect, NULL, fvalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetFloat failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetFloat(effect, NULL, &fvalue);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloat failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetFloat(effect, parameter, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloat failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetFloatArray(effect, NULL, (FLOAT *)input_value, res_desc->Bytes / sizeof(FLOAT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetFloatArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetFloatArray(effect, NULL, (FLOAT *)input_value, res_desc->Bytes / sizeof(FLOAT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloatArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetFloatArray(effect, parameter, NULL, res_desc->Bytes / sizeof(FLOAT));
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetFloatArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetVector(effect, NULL, (D3DXVECTOR4 *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetVector failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetVector(effect, NULL, (D3DXVECTOR4 *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetVector failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetVector(effect, parameter, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetVector failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetVectorArray(effect, NULL, (D3DXVECTOR4 *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetVectorArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetVectorArray(effect, NULL, (D3DXVECTOR4 *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetVectorArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetVectorArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetVectorArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrix(effect, NULL, (D3DXMATRIX *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrix failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrix(effect, NULL, (D3DXMATRIX *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrix failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixArray(effect, NULL, (D3DXMATRIX *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixArray(effect, NULL, (D3DXMATRIX *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixPointerArray(effect, NULL, matrix_pointer_array, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixPointerArray(effect, NULL, matrix_pointer_array, 0);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixPointerArray(effect, NULL, NULL, 0);
+ ok(hr == D3D_OK, "%u - %s: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3D_OK);
+
+ hr = effect->lpVtbl->GetMatrixPointerArray(effect, NULL, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixPointerArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixTranspose(effect, NULL, (D3DXMATRIX *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTranspose failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTranspose(effect, NULL, (D3DXMATRIX *)input_value);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTranspose(effect, parameter, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTranspose failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixTransposeArray(effect, NULL, (D3DXMATRIX *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTransposeArray(effect, NULL, (D3DXMATRIX *)input_value, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTransposeArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixTransposePointerArray(effect, NULL, matrix_pointer_array, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetMatrixTransposePointerArray(effect, NULL, matrix_pointer_array, 0);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTransposePointerArray(effect, NULL, NULL, 0);
+ ok(hr == D3D_OK, "%u - %s: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3D_OK);
+
+ hr = effect->lpVtbl->GetMatrixTransposePointerArray(effect, NULL, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetMatrixTransposePointerArray(effect, parameter, NULL, res_desc->Elements ? res_desc->Elements : 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetValue(effect, NULL, input_value, res_desc->Bytes);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetValue failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->SetValue(effect, parameter, input_value, res_desc->Bytes - 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetValue failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetValue(effect, NULL, input_value, res_desc->Bytes);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetValue failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ hr = effect->lpVtbl->GetValue(effect, parameter, input_value, res_desc->Bytes - 1);
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: GetValue failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetBool */
+ bvalue = 5;
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetBool(effect, parameter, bvalue);
+ if (!res_desc->Elements && res_desc->Rows == 1 && res_desc->Columns == 1)
+ {
+ bvalue = TRUE;
+ set_number(expected_value, res_desc->Type, &bvalue, D3DXPT_BOOL);
+ ok(hr == D3D_OK, "%u - %s: SetBool failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetBool failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetBoolArray */
+ *input_value = 1;
+ for (l = 1; l < res_desc->Bytes / sizeof(*input_value); ++l)
+ {
+ *(input_value + l) = *(input_value + l - 1) + 1;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetBoolArray(effect, parameter, (BOOL *)input_value, res_desc->Bytes / sizeof(*input_value));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ for (l = 0; l < res_desc->Bytes / sizeof(*input_value); ++l)
+ {
+ set_number(expected_value + l, res_desc->Type, input_value + l, D3DXPT_BOOL);
+ }
+ ok(hr == D3D_OK, "%u - %s: SetBoolArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetBoolArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetInt */
+ ivalue = 0x1fbf02ff;
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetInt(effect, parameter, ivalue);
+ if (!res_desc->Elements && res_desc->Rows == 1 && res_desc->Columns == 1)
+ {
+ set_number(expected_value, res_desc->Type, &ivalue, D3DXPT_INT);
+ ok(hr == D3D_OK, "%u - %s: SetInt failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else if(!res_desc->Elements && res_desc->Type == D3DXPT_FLOAT &&
+ ((res_desc->Class == D3DXPC_VECTOR && res_desc->Columns != 2) ||
+ (res_desc->Class == D3DXPC_MATRIX_ROWS && res_desc->Rows != 2 && res_desc->Columns == 1)))
+ {
+ FLOAT tmp = ((ivalue & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
+ set_number(expected_value, res_desc->Type, &tmp, D3DXPT_FLOAT);
+ tmp = ((ivalue & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
+ set_number(expected_value + 1, res_desc->Type, &tmp, D3DXPT_FLOAT);
+ tmp = (ivalue & 0xff) * INT_FLOAT_MULTI_INVERSE;
+ set_number(expected_value + 2, res_desc->Type, &tmp, D3DXPT_FLOAT);
+ tmp = ((ivalue & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
+ set_number(expected_value + 3, res_desc->Type, &tmp, D3DXPT_FLOAT);
+
+ ok(hr == D3D_OK, "%u - %s: SetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetInt failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetIntArray */
+ *input_value = 123456;
+ for (l = 0; l < res_desc->Bytes / sizeof(*input_value); ++l)
+ {
+ *(input_value + l) = *(input_value + l - 1) + 23;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetIntArray(effect, parameter, (INT *)input_value, res_desc->Bytes / sizeof(*input_value));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ for (l = 0; l < res_desc->Bytes / sizeof(*input_value); ++l)
+ {
+ set_number(expected_value + l, res_desc->Type, input_value + l, D3DXPT_INT);
+ }
+ ok(hr == D3D_OK, "%u - %s: SetIntArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetIntArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetFloat */
+ fvalue = 1.33;
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetFloat(effect, parameter, fvalue);
+ if (!res_desc->Elements && res_desc->Rows == 1 && res_desc->Columns == 1)
+ {
+ set_number(expected_value, res_desc->Type, &fvalue, D3DXPT_FLOAT);
+ ok(hr == D3D_OK, "%u - %s: SetFloat failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetFloat failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetFloatArray */
+ fvalue = 1.33;
+ for (l = 0; l < res_desc->Bytes / sizeof(fvalue); ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetFloatArray(effect, parameter, (FLOAT *)input_value, res_desc->Bytes / sizeof(*input_value));
+ if (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR
+ || res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ for (l = 0; l < res_desc->Bytes / sizeof(*input_value); ++l)
+ {
+ set_number(expected_value + l, res_desc->Type, input_value + l, D3DXPT_FLOAT);
+ }
+ ok(hr == D3D_OK, "%u - %s: SetFloatArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetFloatArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetVector */
+ fvalue = -1.33;
+ for (l = 0; l < 4; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetVector(effect, parameter, (D3DXVECTOR4 *)input_value);
+ if (!res_desc->Elements &&
+ (res_desc->Class == D3DXPC_SCALAR
+ || res_desc->Class == D3DXPC_VECTOR))
+ {
+ /* only values between 0 and INT_FLOAT_MULTI are valid */
+ if (res_desc->Type == D3DXPT_INT && res_desc->Bytes == 4)
+ {
+ *expected_value = (DWORD)(max(min(*(FLOAT *)(input_value + 2), 1.0f), 0.0f) * INT_FLOAT_MULTI);
+ *expected_value += ((DWORD)(max(min(*(FLOAT *)(input_value + 1), 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
+ *expected_value += ((DWORD)(max(min(*(FLOAT *)input_value, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
+ *expected_value += ((DWORD)(max(min(*(FLOAT *)(input_value + 3), 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
+ }
+ else
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ set_number(expected_value + l, res_desc->Type, input_value + l, D3DXPT_FLOAT);
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetVector failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetVector failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetVectorArray */
+ for (element = 0; element < res_desc->Elements + 1; ++element)
+ {
+ fvalue = 1.33;
+ for (l = 0; l < element * 4; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetVectorArray(effect, parameter, (D3DXVECTOR4 *)input_value, element);
+ if (res_desc->Elements && res_desc->Class == D3DXPC_VECTOR && element <= res_desc->Elements)
+ {
+ for (m = 0; m < element; ++m)
+ {
+ for (l = 0; l < res_desc->Columns; ++l)
+ {
+ set_number(expected_value + m * res_desc->Columns + l, res_desc->Type, input_value + m * 4 + l, D3DXPT_FLOAT);
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetVectorArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetVectorArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ }
+
+ /* SetMatrix */
+ fvalue = 1.33;
+ for (l = 0; l < 16; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetMatrix(effect, parameter, (D3DXMATRIX *)input_value);
+ if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns, res_desc->Type,
+ input_value + l + m * 4, D3DXPT_FLOAT);
+ }
+
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrix failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrix failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetMatrixArray */
+ for (element = 0; element < res_desc->Elements + 1; ++element)
+ {
+ fvalue = 1.33;
+ for (l = 0; l < element * 16; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetMatrixArray(effect, parameter, (D3DXMATRIX *)input_value, element);
+ if (res_desc->Class == D3DXPC_MATRIX_ROWS && element <= res_desc->Elements)
+ {
+ for (n = 0; n < element; ++n)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns + n * res_desc->Columns * res_desc->Rows,
+ res_desc->Type, input_value + l + m * 4 + n * 16, D3DXPT_FLOAT);
+ }
+
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrixArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ }
+
+ /* SetMatrixPointerArray */
+ for (element = 0; element < res_desc->Elements + 1; ++element)
+ {
+ fvalue = 1.33;
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ for (l = 0; l < element; ++l)
+ {
+ matrix_pointer_array[l] = (D3DXMATRIX *)&input_value[l * sizeof(**matrix_pointer_array) / sizeof(FLOAT)];
+ }
+ hr = effect->lpVtbl->SetMatrixPointerArray(effect, parameter, matrix_pointer_array, element);
+ if (res_desc->Class == D3DXPC_MATRIX_ROWS && res_desc->Elements >= element)
+ {
+ for (n = 0; n < element; ++n)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns + n * res_desc->Columns * res_desc->Rows,
+ res_desc->Type, input_value + l + m * 4 + n * 16, D3DXPT_FLOAT);
+ }
+
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixPointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ }
+
+ /* SetMatrixTranspose */
+ fvalue = 1.33;
+ for (l = 0; l < 16; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetMatrixTranspose(effect, parameter, (D3DXMATRIX *)input_value);
+ if (!res_desc->Elements && res_desc->Class == D3DXPC_MATRIX_ROWS)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns, res_desc->Type,
+ input_value + l * 4 + m, D3DXPT_FLOAT);
+ }
+
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrixTranspose failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTranspose failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+
+ /* SetMatrixTransposeArray */
+ for (element = 0; element < res_desc->Elements + 1; ++element)
+ {
+ fvalue = 1.33;
+ for (l = 0; l < element * 16; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ hr = effect->lpVtbl->SetMatrixTransposeArray(effect, parameter, (D3DXMATRIX *)input_value, element);
+ if (res_desc->Class == D3DXPC_MATRIX_ROWS && element <= res_desc->Elements)
+ {
+ for (n = 0; n < element; ++n)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns + n * res_desc->Columns * res_desc->Rows,
+ res_desc->Type, input_value + l * 4 + m + n * 16, D3DXPT_FLOAT);
+ }
+
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrixTransposeArray failed, got %#x, expected %#x\n", i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTransposeArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ }
+
+ /* SetMatrixTransposePointerArray */
+ for (element = 0; element < res_desc->Elements + 1; ++element)
+ {
+ fvalue = 1.33;
+ for (l = 0; l < EFFECT_PARAMETER_VALUE_ARRAY_SIZE; ++l)
+ {
+ *(input_value + l) = *(DWORD *)&fvalue;
+ fvalue += 1.12;
+ }
+ memcpy(expected_value, &blob[res_value_offset], res_desc->Bytes);
+ for (l = 0; l < element; ++l)
+ {
+ matrix_pointer_array[l] = (D3DXMATRIX *)&input_value[l * sizeof(**matrix_pointer_array) / sizeof(FLOAT)];
+ }
+ hr = effect->lpVtbl->SetMatrixTransposePointerArray(effect, parameter, matrix_pointer_array, element);
+ if (res_desc->Class == D3DXPC_MATRIX_ROWS && res_desc->Elements >= element)
+ {
+ for (n = 0; n < element; ++n)
+ {
+ for (l = 0; l < 4; ++l)
+ {
+ for (m = 0; m < 4; ++m)
+ {
+ if (m < res_desc->Rows && l < res_desc->Columns)
+ set_number(expected_value + l + m * res_desc->Columns + n * res_desc->Columns * res_desc->Rows,
+ res_desc->Type, input_value + l * 4 + m + n * 16, D3DXPT_FLOAT);
+ }
+
+ }
+ }
+ ok(hr == D3D_OK, "%u - %s: SetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3D_OK);
+ }
+ else
+ {
+ ok(hr == D3DERR_INVALIDCALL, "%u - %s: SetMatrixTransposePointerArray failed, got %#x, expected %#x\n",
+ i, res_full_name, hr, D3DERR_INVALIDCALL);
+ }
+ test_effect_parameter_value_GetTestGroup(&res[k], effect, expected_value, parameter, i);
+ test_effect_parameter_value_ResetValue(&res[k], effect, &blob[res_value_offset], parameter, i);
+ }
+ }
+
+ count = effect->lpVtbl->Release(effect);
+ ok(!count, "Release failed %u\n", count);
+ }
+}
+
+static void test_effect_setvalue_object(IDirect3DDevice9 *device)
+{
+ static const char expected_string[] = "test_string_1";
+ static const char expected_string2[] = "test_longer_string_2";
+ static const char *expected_string_array[] = {expected_string, expected_string2};
+ const char *string_array[ARRAY_SIZE(expected_string_array)];
+ const char *string, *string2;
+ IDirect3DTexture9 *texture_set;
+ IDirect3DTexture9 *texture;
+ D3DXHANDLE parameter;
+ ID3DXEffect *effect;
+ unsigned int i;
+ ULONG count;
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_parameter_value_blob_object,
+ sizeof(test_effect_parameter_value_blob_object), NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK).\n", hr);
+
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "tex");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ texture = NULL;
+ hr = D3DXCreateTexture(device, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK).\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, parameter, &texture, sizeof(texture));
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK).\n", hr);
+ texture_set = NULL;
+ hr = effect->lpVtbl->GetValue(effect, parameter, &texture_set, sizeof(texture_set));
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK).\n", hr);
+ ok(texture == texture_set, "Texture does not match.\n");
+
+ count = IDirect3DTexture9_Release(texture_set);
+ ok(count == 2, "Got reference count %u, expected 2.\n", count);
+ texture_set = NULL;
+ hr = effect->lpVtbl->SetValue(effect, parameter, &texture_set, sizeof(texture_set));
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK).\n", hr);
+ count = IDirect3DTexture9_Release(texture);
+ ok(!count, "Got reference count %u, expected 0.\n", count);
+
+ hr = effect->lpVtbl->SetString(effect, "s", expected_string);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ string = NULL;
+ hr = effect->lpVtbl->GetString(effect, "s", &string);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetString(effect, "s", &string2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(string != expected_string, "String pointers are the same.\n");
+ ok(string == string2, "String pointers differ.\n");
+ ok(!strcmp(string, expected_string), "Unexpected string '%s'.\n", string);
+
+ string = expected_string2;
+ hr = effect->lpVtbl->SetValue(effect, "s", &string, sizeof(string) - 1);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, "s", &string, sizeof(string));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, "s", &string, sizeof(string) * 2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ string = NULL;
+ hr = effect->lpVtbl->GetValue(effect, "s", &string, sizeof(string));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(string != expected_string2, "String pointers are the same.\n");
+ ok(!strcmp(string, expected_string2), "Unexpected string '%s'.\n", string);
+
+ hr = effect->lpVtbl->SetValue(effect, "s_2", expected_string_array,
+ sizeof(expected_string_array));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetValue(effect, "s_2", string_array,
+ sizeof(string_array));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ for (i = 0; i < ARRAY_SIZE(expected_string_array); ++i)
+ {
+ ok(!strcmp(string_array[i], expected_string_array[i]), "Unexpected string '%s', i %u.\n",
+ string_array[i], i);
+ }
+ effect->lpVtbl->Release(effect);
+}
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+float a = 2.1;
+float b[1];
+float c <float d = 3;>;
+struct {float e;} f;
+float g <float h[1] = {3};>;
+struct s {float j;};
+float i <s k[1] = {4};>;
+technique t <s l[1] = {5};> { pass p <s m[1] = {6};> { } }
+#endif
+static const DWORD test_effect_variable_names_blob[] =
+{
+0xfeff0901, 0x0000024c, 0x00000000, 0x00000003, 0x00000000, 0x00000024, 0x00000000, 0x00000000,
+0x00000001, 0x00000001, 0x40066666, 0x00000002, 0x00000061, 0x00000003, 0x00000000, 0x0000004c,
+0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000062, 0x00000003,
+0x00000000, 0x0000009c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x40400000,
+0x00000003, 0x00000000, 0x00000094, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002,
+0x00000064, 0x00000002, 0x00000063, 0x00000000, 0x00000005, 0x000000dc, 0x00000000, 0x00000000,
+0x00000001, 0x00000003, 0x00000000, 0x000000e4, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+0x00000000, 0x00000002, 0x00000066, 0x00000002, 0x00000065, 0x00000003, 0x00000000, 0x00000134,
+0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x40400000, 0x00000003, 0x00000000,
+0x0000012c, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000068, 0x00000002,
+0x00000067, 0x00000003, 0x00000000, 0x000001a4, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+0x00000000, 0x40800000, 0x00000000, 0x00000005, 0x00000194, 0x00000000, 0x00000001, 0x00000001,
+0x00000003, 0x00000000, 0x0000019c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002,
+0x0000006b, 0x00000002, 0x0000006a, 0x00000002, 0x00000069, 0x40a00000, 0x00000000, 0x00000005,
+0x000001e4, 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00000000, 0x000001ec, 0x00000000,
+0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x0000006c, 0x00000002, 0x0000006a, 0x40c00000,
+0x00000000, 0x00000005, 0x0000022c, 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00000000,
+0x00000234, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x0000006d, 0x00000002,
+0x0000006a, 0x00000002, 0x00000070, 0x00000002, 0x00000074, 0x00000006, 0x00000001, 0x00000001,
+0x00000001, 0x00000004, 0x00000020, 0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000,
+0x00000000, 0x00000054, 0x00000070, 0x00000000, 0x00000001, 0x00000078, 0x00000074, 0x000000a4,
+0x000000d8, 0x00000000, 0x00000000, 0x000000ec, 0x00000108, 0x00000000, 0x00000001, 0x00000110,
+0x0000010c, 0x0000013c, 0x00000158, 0x00000000, 0x00000001, 0x00000160, 0x0000015c, 0x00000244,
+0x00000001, 0x00000001, 0x000001b0, 0x000001ac, 0x0000023c, 0x00000001, 0x00000000, 0x000001f8,
+0x000001f4, 0x00000000, 0x00000000,
+};
+
+static void test_effect_variable_names(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect;
+ ULONG count;
+ HRESULT hr;
+ D3DXHANDLE parameter, p;
+
+ hr = D3DXCreateEffect(device, test_effect_variable_names_blob,
+ sizeof(test_effect_variable_names_blob), NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "D3DXCreateEffect failed, got %#x, expected %#x\n", hr, D3D_OK);
+
+ /*
+ * check invalid calls
+ * This will crash:
+ * effect->lpVtbl->GetAnnotationByName(effect, "invalid1", "invalid2");
+ */
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p, expected %p\n", p, NULL);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "invalid1");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "invalid1", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "invalid1", "invalid2");
+ ok(p == NULL, "GetParameterByName failed, got %p, expected %p\n", p, NULL);
+
+ /* float a; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "a");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ /* members */
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a.");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a.", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", ".");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a.invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a.invalid", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", ".invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a.", "invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", "invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ /* elements */
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a[]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a[]", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a[0]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a[0]", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", "[0]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterElement(effect, "a", 0);
+ ok(p == NULL, "GetParameterElement failed, got %p\n", p);
+
+ /* annotations */
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a@");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a@", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a", "@invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a@", "invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "a@invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "a@invalid", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "a", NULL);
+ ok(p == NULL, "GetAnnotationByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "a", "invalid");
+ ok(p == NULL, "GetAnnotationByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetAnnotation(effect, "a", 0);
+ ok(p == NULL, "GetAnnotation failed, got %p\n", p);
+
+ /* float b[1]; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "b");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "b", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ /* elements */
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "b[]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "b[0]");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "b[0]", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterElement(effect, "b", 0);
+ ok(parameter == p, "GetParameterElement failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "b", "[0]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "b[1]");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterElement(effect, "b", 1);
+ ok(p == NULL, "GetParameterElement failed, got %p\n", p);
+
+ /* float c <float d = 3;>; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "c");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "c", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ /* annotations */
+ p = effect->lpVtbl->GetParameterByName(effect, "c", "@d");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "c@", "d");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "c@invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "c@invalid", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "c", NULL);
+ ok(p == NULL, "GetAnnotationByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "c", "invalid");
+ ok(p == NULL, "GetAnnotationByName failed, got %p\n", p);
+
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "c@d");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "c@d", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "c", "d");
+ ok(parameter == p, "GetAnnotationByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetAnnotation(effect, "c", 0);
+ ok(parameter == p, "GetAnnotation failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetAnnotation(effect, "c", 1);
+ ok(p == NULL, "GetAnnotation failed, got %p\n", p);
+
+ /* struct {float e;} f; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "f");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ /* members */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "f.e");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f.e", NULL);
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f", "e");
+ ok(parameter == p, "GetParameterByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f", ".e");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f.", "e");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, "f.invalid", NULL);
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ p = effect->lpVtbl->GetParameterByName(effect, NULL, "f.invalid");
+ ok(p == NULL, "GetParameterByName failed, got %p\n", p);
+
+ /* float g <float h[1] = {3};>; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "g@h[0]");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "g", "h[0]");
+ ok(parameter == p, "GetAnnotationByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterElement(effect, "g@h", 0);
+ ok(parameter == p, "GetParameterElement failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterElement(effect, effect->lpVtbl->GetAnnotation(effect, "g", 0), 0);
+ ok(parameter == p, "GetParameterElement failed, got %p, expected %p\n", p, parameter);
+
+ /* struct s {float j;}; float i <s k[1] = {4};>; */
+ parameter = effect->lpVtbl->GetParameterByName(effect, NULL, "i@k[0].j");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ p = effect->lpVtbl->GetAnnotationByName(effect, "i", "k[0].j");
+ ok(parameter == p, "GetAnnotationByName failed, got %p, expected %p\n", p, parameter);
+
+ p = effect->lpVtbl->GetParameterByName(effect, effect->lpVtbl->GetParameterElement(effect, "i@k", 0), "j");
+ ok(parameter == p, "GetParameterElement failed, got %p, expected %p\n", p, parameter);
+
+ /* technique t <s l[1] = {5};> */
+ parameter = effect->lpVtbl->GetAnnotationByName(effect, "t", "l[0].j");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ /* pass p <s m[1] = {6};> */
+ parameter = effect->lpVtbl->GetAnnotationByName(effect, effect->lpVtbl->GetPassByName(effect, "t", "p"), "m[0].j");
+ ok(parameter != NULL, "GetParameterByName failed, got %p\n", parameter);
+
+ count = effect->lpVtbl->Release(effect);
+ ok(!count, "Release failed %u\n", count);
+}
+
+static void test_effect_compilation_errors(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect;
+ ID3DXBuffer *compilation_errors;
+ HRESULT hr;
+
+ /* Test binary effect */
+ compilation_errors = (ID3DXBuffer*)0xdeadbeef;
+ hr = D3DXCreateEffect(NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, &compilation_errors);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateEffect failed, got %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ ok(!compilation_errors, "Returned %p\n", compilation_errors);
+
+ compilation_errors = (ID3DXBuffer*)0xdeadbeef;
+ hr = D3DXCreateEffect(device, test_effect_variable_names_blob,
+ sizeof(test_effect_variable_names_blob), NULL, NULL, 0, NULL, &effect, &compilation_errors);
+ ok(hr == D3D_OK, "D3DXCreateEffect failed, got %#x, expected %#x\n", hr, D3D_OK);
+ ok(!compilation_errors, "Returned %p\n", compilation_errors);
+ effect->lpVtbl->Release(effect);
+}
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+vertexshader vs_arr1[2] =
+{
+ asm
+ {
+ vs_1_1
+ def c0, 1, 1, 1, 1
+ mov oPos, c0
+ },
+ asm
+ {
+ vs_2_0
+ def c0, 2, 2, 2, 2
+ mov oPos, c0
+ }
+};
+
+sampler sampler1 =
+ sampler_state
+ {
+ MipFilter = LINEAR;
+ };
+
+float4x4 camera : VIEW = {4.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,6.0};
+technique tech0
+{
+ pass p0
+ {
+ vertexshader = vs_arr1[1];
+ VertexShaderConstant1[3] = {2,2,2,2};
+ BlendOp = 2;
+ AlphaOp[3] = 4;
+ ZEnable = true;
+ WorldTransform[1]={2.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0, 0.0,0.0,0.0,4.0};
+ ViewTransform=(camera);
+ LightEnable[2] = TRUE;
+ LightType[2] = POINT;
+ LightPosition[2] = {4.0f, 5.0f, 6.0f};
+ Sampler[1] = sampler1;
+ }
+}
+#endif
+static const DWORD test_effect_states_effect_blob[] =
+{
+ 0xfeff0901, 0x000002e8, 0x00000000, 0x00000010, 0x00000004, 0x00000020, 0x00000000, 0x00000002,
+ 0x00000001, 0x00000002, 0x00000008, 0x615f7376, 0x00317272, 0x0000000a, 0x00000004, 0x00000074,
+ 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000001, 0x000000ab, 0x00000100, 0x00000044, 0x00000040, 0x00000009,
+ 0x706d6173, 0x3172656c, 0x00000000, 0x00000003, 0x00000002, 0x000000e0, 0x000000ec, 0x00000000,
+ 0x00000004, 0x00000004, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40c00000, 0x00000007, 0x656d6163, 0x00006172, 0x00000005, 0x57454956, 0x00000000,
+ 0x00000003, 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x40000000, 0x40000000,
+ 0x40000000, 0x40000000, 0x00000003, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000002, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000001, 0x00000004, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000001, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000001,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x40800000,
+ 0x40a00000, 0x40c00000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000001, 0x00000000, 0x0000000a, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
+ 0x00003070, 0x00000006, 0x68636574, 0x00000030, 0x00000003, 0x00000001, 0x00000005, 0x00000004,
+ 0x00000004, 0x00000018, 0x00000000, 0x00000000, 0x0000002c, 0x00000060, 0x00000000, 0x00000000,
+ 0x00000084, 0x000000a0, 0x00000000, 0x00000000, 0x000002dc, 0x00000000, 0x00000001, 0x000002d4,
+ 0x00000000, 0x0000000b, 0x00000092, 0x00000000, 0x000000fc, 0x000000f8, 0x00000098, 0x00000003,
+ 0x00000120, 0x00000110, 0x0000004b, 0x00000000, 0x00000140, 0x0000013c, 0x0000006b, 0x00000003,
+ 0x00000160, 0x0000015c, 0x00000000, 0x00000000, 0x00000180, 0x0000017c, 0x0000007d, 0x00000001,
+ 0x000001dc, 0x0000019c, 0x0000007c, 0x00000000, 0x00000238, 0x000001f8, 0x00000091, 0x00000002,
+ 0x00000258, 0x00000254, 0x00000084, 0x00000002, 0x00000278, 0x00000274, 0x00000088, 0x00000002,
+ 0x000002a0, 0x00000294, 0x000000b2, 0x00000001, 0x000002c0, 0x000002bc, 0x00000002, 0x00000003,
+ 0x00000001, 0x0000002c, 0xfffe0101, 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0x3f800000, 0x00000001, 0xc00f0000, 0xa0e40000, 0x0000ffff, 0x00000002, 0x0000002c, 0xfffe0200,
+ 0x05000051, 0xa00f0000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x02000001, 0xc00f0000,
+ 0xa0e40000, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000000a, 0x00000001, 0x00000009,
+ 0x706d6173, 0x3172656c, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000006, 0x00000000,
+ 0x0000016c, 0x46580200, 0x0030fffe, 0x42415443, 0x0000001c, 0x0000008b, 0x46580200, 0x00000001,
+ 0x0000001c, 0x20000100, 0x00000088, 0x00000030, 0x00000002, 0x00000004, 0x00000038, 0x00000048,
+ 0x656d6163, 0xab006172, 0x00030003, 0x00040004, 0x00000001, 0x00000000, 0x40800000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x0024fffe, 0x434c5846,
+ 0x00000004, 0x10000004, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000000, 0x10000004, 0x00000001, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000004, 0x10000004, 0x00000001, 0x00000000, 0x00000002, 0x00000008, 0x00000000, 0x00000004,
+ 0x00000008, 0x10000004, 0x00000001, 0x00000000, 0x00000002, 0x0000000c, 0x00000000, 0x00000004,
+ 0x0000000c, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000,
+ 0x00000001, 0x0000000b, 0x615f7376, 0x5b317272, 0x00005d31,
+};
+#define TEST_EFFECT_STATES_VSHADER_POS 271
+
+static void test_effect_states(IDirect3DDevice9 *device)
+{
+ D3DMATRIX test_mat =
+ {{{
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f
+ }}};
+ D3DMATRIX test_mat_camera =
+ {{{
+ 4.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 6.0f
+ }}};
+ D3DMATRIX test_mat_world1 =
+ {{{
+ 2.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 4.0f
+ }}};
+ D3DMATRIX mat;
+ HRESULT hr;
+ ID3DXEffect *effect;
+ UINT npasses;
+ DWORD value;
+ IDirect3DVertexShader9 *vshader;
+ void *byte_code;
+ UINT byte_code_size;
+ BOOL bval;
+ D3DLIGHT9 light;
+ float float_data[4];
+
+ hr = D3DXCreateEffect(device, test_effect_states_effect_blob, sizeof(test_effect_states_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ /* State affected in passes saved/restored even if no pass
+ was performed. States not present in passes are not saved &
+ restored */
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, 1);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, 1);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &npasses, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(npasses == 1, "Expected 1 pass, got %u\n", npasses);
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, 3);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, 2);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_BLENDOP, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == 1, "Got result %u, expected %u.\n", value, 1);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_ALPHAFUNC, &value);
+ ok(value == 2, "Got result %u, expected %u.\n", value, 2);
+
+ /* Test states application in BeginPass. No states are restored
+ on EndPass. */
+ hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_MIPFILTER, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_GetLightEnable(device, 2, &bval);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ if (hr == D3D_OK)
+ ok(!bval, "Got result %u, expected 0.\n", bval);
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &test_mat);
+ hr = effect->lpVtbl->Begin(effect, NULL, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(1), &mat);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!memcmp(mat.m, test_mat.m, sizeof(mat)), "World matrix does not match.\n");
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(1), &mat);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!memcmp(mat.m, test_mat_world1.m, sizeof(mat)), "World matrix does not match.\n");
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &mat);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!memcmp(mat.m, test_mat_camera.m, sizeof(mat)), "View matrix does not match.\n");
+
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_BLENDOP, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == 2, "Got result %u, expected %u\n", value, 2);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(vshader != NULL, "Got NULL vshader.\n");
+ if (vshader)
+ {
+ hr = IDirect3DVertexShader9_GetFunction(vshader, NULL, &byte_code_size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ byte_code = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, byte_code_size);
+ hr = IDirect3DVertexShader9_GetFunction(vshader, byte_code, &byte_code_size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(byte_code_size > 1, "Got unexpected byte code size %u.\n", byte_code_size);
+ ok(!memcmp(byte_code, &test_effect_states_effect_blob[TEST_EFFECT_STATES_VSHADER_POS], byte_code_size),
+ "Incorrect shader selected.\n");
+ HeapFree(GetProcessHeap(), 0, byte_code);
+ IDirect3DVertexShader9_Release(vshader);
+ }
+
+ hr = IDirect3DDevice9_GetLightEnable(device, 2, &bval);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ if (hr == D3D_OK)
+ ok(bval, "Got result %u, expected TRUE.\n", bval);
+ hr = IDirect3DDevice9_GetLight(device, 2, &light);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ if (hr == D3D_OK)
+ ok(light.Position.x == 4.0f && light.Position.y == 5.0f && light.Position.z == 6.0f,
+ "Got unexpected light position (%f, %f, %f).\n", light.Position.x, light.Position.y, light.Position.z);
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 3, float_data, 1);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(float_data[0] == 2.0f && float_data[1] == 2.0f && float_data[2] == 2.0f && float_data[3] == 2.0f,
+ "Got unexpected vertex shader floats: (%f %f %f %f).\n",
+ float_data[0], float_data[1], float_data[2], float_data[3]);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_BLENDOP, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == 2, "Got result %u, expected %u\n", value, 2);
+
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_ZENABLE, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value, "Got result %u, expected TRUE.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, 1, D3DSAMP_MIPFILTER, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == D3DTEXF_LINEAR, "Unexpected sampler 1 mipfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetTextureStageState(device, 3, D3DTSS_ALPHAOP, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == 4, "Unexpected texture stage 3 AlphaOp %u.\n", value);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLDMATRIX(1), &mat);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!memcmp(mat.m, test_mat.m, sizeof(mat)), "World matrix not restored.\n");
+
+ hr = IDirect3DDevice9_GetLightEnable(device, 2, &bval);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ if (hr == D3D_OK)
+ ok(!bval, "Got result %u, expected 0.\n", bval);
+
+ /* State is not restored if effect is released without End call */
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, 1);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &npasses, 0);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, 3);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+
+ effect->lpVtbl->Release(effect);
+
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_BLENDOP, &value);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(value == 3, "Got result %u, expected %u.\n", value, 1);
+}
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+float4 g_Pos1;
+float4 g_Pos2;
+float4 g_Selector[3] = {{0, 0, 0, 0}, {10, 10, 10, 10}, {5001, 5002, 5003, 5004}};
+
+float4 opvect1 = {0.0, -0.0, -2.2, 3.402823466e+38F};
+float4 opvect2 = {1.0, 2.0, -3.0, 4.0};
+float4 opvect3 = {0.0, -0.0, -2.2, 3.402823466e+38F};
+
+float4 vect_sampler = {1, 2, 3, 4};
+
+float3 vec3 = {1001, 1002, 1003};
+
+int4 g_iVect = {4, 3, 2, 1};
+
+vertexshader vs_arr[3] =
+{
+ asm
+ {
+ vs_1_0
+ def c0, 1, 1, 1, 1
+ mov oPos, c0
+ },
+ asm
+ {
+ vs_1_1
+ def c0, 2, 2, 2, 2
+ mov oPos, c0
+ },
+ asm
+ {
+ vs_2_0
+ def c0, 3, 3, 3, 3
+ mov oPos, c0
+ }
+};
+
+float4x4 m4x4 = {{11, 12, 13, 14}, {21, 22, 23, 24}, {31, 32, 33, 34}, {41, 42, 43, 44}};
+
+row_major float4x3 m4x3row = {{11, 12, 13}, {21, 22, 23}, {31, 32, 33}, {41, 42, 43}};
+row_major float3x4 m3x4row = {{11, 12, 13, 14}, {21, 22, 23, 24}, {31, 32, 33, 34}};
+column_major float4x3 m4x3column = {{11, 12, 13},{21, 22, 23},{31, 32, 33},{41, 42, 43}};
+column_major float3x4 m3x4column = {{11, 12, 13, 14}, {21, 22, 23, 24}, {31, 32, 33, 34}};
+row_major float2x2 m2x2row = {{11, 12}, {21, 22}};
+column_major float2x2 m2x2column = {{11, 12}, {21, 22}};
+row_major float2x3 m2x3row = {{11, 12, 13}, {21, 22, 23}};
+column_major float2x3 m2x3column = {{11, 12, 13}, {21, 22, 23}};
+row_major float3x2 m3x2row = {{11, 12}, {21, 22}, {31, 32}};
+column_major float3x2 m3x2column = {{11, 12}, {21, 22}, {31, 32}};
+
+row_major bool2x3 mb2x3row = {{true, false, true}, {false, true, true}};
+column_major bool2x3 mb2x3column = {{true, false, true}, {false, true, true}};
+
+struct test_struct
+{
+ float3 v1;
+ float fv;
+ float4 v2;
+};
+
+struct struct_array
+{
+ test_struct ts[2];
+};
+
+test_struct ts1[1] = {{{9, 10, 11}, 12, {13, 14, 15, 16}}};
+shared test_struct ts2[2] = {{{0, 0, 0}, 0, {0, 0, 0, 0}}, {{1, 2, 3}, 4, {5, 6, 7, 8}}};
+struct_array ts3 = {{{1, 2, 3}, 4, {5, 6, 7, 8}}, {{9, 10, 11}, 12, {13, 14, 15, 16}}};
+
+float arr1[1] = {91};
+shared float arr2[2] = {92, 93};
+
+Texture2D tex1;
+Texture2D tex2;
+sampler sampler1 =
+sampler_state
+{
+ Texture = tex1;
+ MinFilter = g_iVect.y;
+ MagFilter = vect_sampler.x + vect_sampler.y;
+};
+
+sampler samplers_array[2] =
+{
+ sampler_state
+ {
+ MinFilter = 1;
+ MagFilter = vect_sampler.x;
+ },
+ sampler_state
+ {
+ MinFilter = 2;
+ MagFilter = vect_sampler.y;
+ }
+};
+
+struct VS_OUTPUT
+{
+ float4 Position : POSITION;
+ float2 TextureUV : TEXCOORD0;
+ float4 Diffuse : COLOR0;
+};
+VS_OUTPUT RenderSceneVS(float4 vPos : POSITION,
+ float3 vNormal : NORMAL,
+ float2 vTexCoord0 : TEXCOORD0,
+ uniform int nNumLights,
+ uniform bool bTexture)
+{
+ VS_OUTPUT Output;
+
+ if (g_Selector[1].y > float4(0.5, 0.5, 0.5, 0.5).y)
+ Output.Position = -g_Pos1 * 2 - float4(-4, -5, -6, -7);
+ else
+ Output.Position = -g_Pos2 * 3 - float4(-4, -5, -6, -7);
+ Output.TextureUV = float2(0, 0);
+ Output.Diffuse = 0;
+ Output.Diffuse.xyz = mul(vPos, m4x3column);
+ Output.Diffuse += mul(vPos, m3x4column);
+ Output.Diffuse += mul(vPos, m3x4row);
+ Output.Diffuse.xyz += mul(vPos, m4x3row);
+ Output.Diffuse += mul(vPos, ts1[0].fv);
+ Output.Diffuse += mul(vPos, ts1[0].v2);
+ Output.Diffuse += mul(vPos, ts2[1].fv);
+ Output.Diffuse += mul(vPos, ts2[1].v2);
+ Output.Diffuse += mul(vPos, arr1[0]);
+ Output.Diffuse += mul(vPos, arr2[1]);
+ Output.Diffuse += mul(vPos, ts3.ts[1].fv);
+ Output.Diffuse += mul(vPos, ts3.ts[1].v2);
+ Output.Diffuse += tex2Dlod(sampler1, g_Pos1);
+ Output.Diffuse += tex2Dlod(samplers_array[1], g_Pos1);
+ return Output;
+}
+
+VS_OUTPUT RenderSceneVS2(float4 vPos : POSITION)
+{
+ VS_OUTPUT Output;
+
+ Output.Position = g_Pos1;
+ Output.TextureUV = float2(0, 0);
+ Output.Diffuse = 0;
+ return Output;
+}
+
+struct PS_OUTPUT
+{
+ float4 RGBColor : COLOR0; /* Pixel color */
+};
+PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool2x3 mb)
+{
+ PS_OUTPUT Output;
+ int i;
+
+ Output.RGBColor = In.Diffuse;
+ Output.RGBColor.xy += mul(In.Diffuse, m2x2row);
+ Output.RGBColor.xy += mul(In.Diffuse, m2x2column);
+ Output.RGBColor.xy += mul(In.Diffuse, m3x2row);
+ Output.RGBColor.xy += mul(In.Diffuse, m3x2column);
+ Output.RGBColor.xyz += mul(In.Diffuse, m2x3row);
+ Output.RGBColor.xyz += mul(In.Diffuse, m2x3column);
+ for (i = 0; i < g_iVect.x; ++i)
+ Output.RGBColor.xyz += mul(In.Diffuse, m2x3column);
+ if (mb[1][1])
+ {
+ Output.RGBColor += sin(Output.RGBColor);
+ Output.RGBColor += cos(Output.RGBColor);
+ Output.RGBColor.xyz += mul(Output.RGBColor, m2x3column);
+ Output.RGBColor.xyz += mul(Output.RGBColor, m2x3row);
+ Output.RGBColor.xy += mul(Output.RGBColor, m3x2column);
+ Output.RGBColor.xy += mul(Output.RGBColor, m3x2row);
+ }
+ if (mb2x3column[0][0])
+ {
+ Output.RGBColor += sin(Output.RGBColor);
+ Output.RGBColor += cos(Output.RGBColor);
+ Output.RGBColor.xyz += mul(Output.RGBColor, m2x3column);
+ Output.RGBColor.xyz += mul(Output.RGBColor, m2x3row);
+ Output.RGBColor.xy += mul(Output.RGBColor, m3x2column);
+ Output.RGBColor.xy += mul(Output.RGBColor, m3x2row);
+ }
+ Output.RGBColor += tex2D(sampler1, In.TextureUV);
+ Output.RGBColor += tex2D(samplers_array[0], In.TextureUV);
+ return Output;
+}
+
+shared vertexshader vs_arr2[2] = {compile vs_3_0 RenderSceneVS(1, true), compile vs_3_0 RenderSceneVS2()};
+pixelshader ps_arr[1] = {compile ps_3_0 RenderScenePS(mb2x3row)};
+
+technique tech0
+{
+ pass p0
+ {
+ VertexShader = vs_arr2[g_iVect.w - 1];
+ PixelShader = ps_arr[g_iVect.w - 1];
+
+ LightEnable[0] = TRUE;
+ LightEnable[1] = TRUE;
+ LightEnable[2] = TRUE;
+ LightEnable[3] = TRUE;
+ LightEnable[4] = TRUE;
+ LightEnable[5] = TRUE;
+ LightEnable[6] = TRUE;
+ LightEnable[7] = TRUE;
+ LightType[0] = POINT;
+ LightType[1] = POINT;
+ LightType[2] = POINT;
+ LightType[3] = POINT;
+ LightType[4] = POINT;
+ LightType[5] = POINT;
+ LightType[6] = POINT;
+ LightType[7] = POINT;
+ LightDiffuse[0] = 1 / opvect1;
+ LightDiffuse[1] = rsqrt(opvect1);
+ LightDiffuse[2] = opvect1 * opvect2;
+ LightDiffuse[3] = opvect1 + opvect2;
+ LightDiffuse[4] = float4(opvect1 < opvect2);
+ LightDiffuse[5] = float4(opvect1 >= opvect2);
+ LightDiffuse[6] = -opvect1;
+ LightDiffuse[7] = rcp(opvect1);
+
+ LightAmbient[0] = frac(opvect1);
+ LightAmbient[1] = min(opvect1, opvect2);
+ LightAmbient[2] = max(opvect1, opvect2);
+ LightAmbient[3] = sin(opvect1);
+ LightAmbient[4] = cos(opvect1);
+ LightAmbient[5] = 1e-2 / opvect1;
+ LightAmbient[6] = float4(0, dot(opvect1, opvect2), dot(opvect2, opvect2), 0);
+ LightAmbient[7] = opvect1 + 1e-12 * opvect2 - opvect3;
+
+ LightSpecular[0] = float4(dot(opvect1.zx, opvect2.xy), dot(opvect1.zzx, opvect2.xyz),
+ dot(opvect1.zzzx, opvect2.xxyy), 0);
+ LightSpecular[1] = float4(opvect1[g_iVect.z], g_iVect[opvect2.y + 1],
+ g_Selector[4 + g_iVect.w].x + g_Selector[7 + g_iVect.w].y,
+ g_Selector[g_iVect.w].x + g_Selector[g_iVect.x].y);
+ LightSpecular[2] = float4(dot(m4x4[3 + g_iVect.z], m4x4[g_iVect.w * 2]), ts3.ts[g_iVect.x].fv,
+ vec3[g_iVect.z], float3(1, 2, 3)[g_iVect.w]);
+
+ FogEnable = TRUE;
+ FogDensity = ts2[0].fv;
+ FogStart = ts2[1].fv;
+ PointScale_A = ts3.ts[0].fv;
+ PointScale_B = ts3.ts[1].fv;
+ }
+ pass p1
+ {
+ VertexShader = vs_arr[g_iVect.z];
+ }
+}
+#endif
+static const DWORD test_effect_preshader_effect_blob[] =
+{
+ 0xfeff0901, 0x00001160, 0x00000000, 0x00000003, 0x00000001, 0x00000030, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x6f505f67,
+ 0x00003173, 0x00000003, 0x00000001, 0x00000068, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x6f505f67, 0x00003273, 0x00000003,
+ 0x00000001, 0x000000c0, 0x00000000, 0x00000003, 0x00000004, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x41200000, 0x41200000, 0x41200000, 0x41200000, 0x459c4800, 0x459c5000,
+ 0x459c5800, 0x459c6000, 0x0000000b, 0x65535f67, 0x7463656c, 0x0000726f, 0x00000003, 0x00000001,
+ 0x000000fc, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x80000000, 0xc00ccccd,
+ 0x7f7fffff, 0x00000008, 0x6576706f, 0x00317463, 0x00000003, 0x00000001, 0x00000134, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000001, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x00000008,
+ 0x6576706f, 0x00327463, 0x00000003, 0x00000001, 0x0000016c, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x00000008, 0x6576706f, 0x00337463,
+ 0x00000003, 0x00000001, 0x000001a4, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x3f800000,
+ 0x40000000, 0x40400000, 0x40800000, 0x0000000d, 0x74636576, 0x6d61735f, 0x72656c70, 0x00000000,
+ 0x00000003, 0x00000001, 0x000001e0, 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x447a4000,
+ 0x447a8000, 0x447ac000, 0x00000005, 0x33636576, 0x00000000, 0x00000002, 0x00000001, 0x00000218,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000004, 0x00000003, 0x00000002, 0x00000001,
+ 0x00000008, 0x56695f67, 0x00746365, 0x00000010, 0x00000004, 0x00000244, 0x00000000, 0x00000003,
+ 0x00000001, 0x00000002, 0x00000003, 0x00000007, 0x615f7376, 0x00007272, 0x00000003, 0x00000002,
+ 0x000002ac, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x41300000, 0x41400000, 0x41500000,
+ 0x41600000, 0x41a80000, 0x41b00000, 0x41b80000, 0x41c00000, 0x41f80000, 0x42000000, 0x42040000,
+ 0x42080000, 0x42240000, 0x42280000, 0x422c0000, 0x42300000, 0x00000005, 0x3478346d, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000304, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0x41300000,
+ 0x41400000, 0x41500000, 0x41a80000, 0x41b00000, 0x41b80000, 0x41f80000, 0x42000000, 0x42040000,
+ 0x42240000, 0x42280000, 0x422c0000, 0x00000008, 0x3378346d, 0x00776f72, 0x00000003, 0x00000002,
+ 0x0000035c, 0x00000000, 0x00000000, 0x00000003, 0x00000004, 0x41300000, 0x41400000, 0x41500000,
+ 0x41600000, 0x41a80000, 0x41b00000, 0x41b80000, 0x41c00000, 0x41f80000, 0x42000000, 0x42040000,
+ 0x42080000, 0x00000008, 0x3478336d, 0x00776f72, 0x00000003, 0x00000002, 0x000003b4, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000003, 0x41300000, 0x41400000, 0x41500000, 0x41a80000, 0x41b00000,
+ 0x41b80000, 0x41f80000, 0x42000000, 0x42040000, 0x42240000, 0x42280000, 0x422c0000, 0x0000000b,
+ 0x3378346d, 0x756c6f63, 0x00006e6d, 0x00000003, 0x00000002, 0x00000410, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000004, 0x41300000, 0x41400000, 0x41500000, 0x41600000, 0x41a80000, 0x41b00000,
+ 0x41b80000, 0x41c00000, 0x41f80000, 0x42000000, 0x42040000, 0x42080000, 0x0000000b, 0x3478336d,
+ 0x756c6f63, 0x00006e6d, 0x00000003, 0x00000002, 0x0000044c, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000002, 0x41300000, 0x41400000, 0x41a80000, 0x41b00000, 0x00000008, 0x3278326d, 0x00776f72,
+ 0x00000003, 0x00000002, 0x00000484, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x41300000,
+ 0x41400000, 0x41a80000, 0x41b00000, 0x0000000b, 0x3278326d, 0x756c6f63, 0x00006e6d, 0x00000003,
+ 0x00000002, 0x000004c8, 0x00000000, 0x00000000, 0x00000002, 0x00000003, 0x41300000, 0x41400000,
+ 0x41500000, 0x41a80000, 0x41b00000, 0x41b80000, 0x00000008, 0x3378326d, 0x00776f72, 0x00000003,
+ 0x00000002, 0x00000508, 0x00000000, 0x00000000, 0x00000002, 0x00000003, 0x41300000, 0x41400000,
+ 0x41500000, 0x41a80000, 0x41b00000, 0x41b80000, 0x0000000b, 0x3378326d, 0x756c6f63, 0x00006e6d,
+ 0x00000003, 0x00000002, 0x0000054c, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x41300000,
+ 0x41400000, 0x41a80000, 0x41b00000, 0x41f80000, 0x42000000, 0x00000008, 0x3278336d, 0x00776f72,
+ 0x00000003, 0x00000002, 0x0000058c, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x41300000,
+ 0x41400000, 0x41a80000, 0x41b00000, 0x41f80000, 0x42000000, 0x0000000b, 0x3278336d, 0x756c6f63,
+ 0x00006e6d, 0x00000001, 0x00000002, 0x000005d0, 0x00000000, 0x00000000, 0x00000002, 0x00000003,
+ 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000009, 0x7832626d,
+ 0x776f7233, 0x00000000, 0x00000001, 0x00000002, 0x00000614, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000003, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x0000000c,
+ 0x7832626d, 0x6c6f6333, 0x006e6d75, 0x00000000, 0x00000005, 0x000006b0, 0x00000000, 0x00000001,
+ 0x00000003, 0x00000003, 0x00000001, 0x000006b8, 0x00000000, 0x00000000, 0x00000003, 0x00000001,
+ 0x00000003, 0x00000000, 0x000006c0, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000003,
+ 0x00000001, 0x000006c8, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x41100000, 0x41200000,
+ 0x41300000, 0x41400000, 0x41500000, 0x41600000, 0x41700000, 0x41800000, 0x00000004, 0x00317374,
+ 0x00000003, 0x00003176, 0x00000003, 0x00007666, 0x00000003, 0x00003276, 0x00000000, 0x00000005,
+ 0x0000077c, 0x00000000, 0x00000002, 0x00000003, 0x00000003, 0x00000001, 0x00000784, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000000, 0x0000078c, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000003, 0x00000001, 0x00000794, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
+ 0x41000000, 0x00000004, 0x00327374, 0x00000003, 0x00003176, 0x00000003, 0x00007666, 0x00000003,
+ 0x00003276, 0x00000000, 0x00000005, 0x00000860, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000005, 0x00000868, 0x00000000, 0x00000002, 0x00000003, 0x00000003, 0x00000001, 0x00000870,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000000, 0x00000878, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00000001, 0x00000880, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x40a00000, 0x40c00000,
+ 0x40e00000, 0x41000000, 0x41100000, 0x41200000, 0x41300000, 0x41400000, 0x41500000, 0x41600000,
+ 0x41700000, 0x41800000, 0x00000004, 0x00337374, 0x00000003, 0x00007374, 0x00000003, 0x00003176,
+ 0x00000003, 0x00007666, 0x00000003, 0x00003276, 0x00000003, 0x00000000, 0x000008a8, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000001, 0x42b60000, 0x00000005, 0x31727261, 0x00000000, 0x00000003,
+ 0x00000000, 0x000008d8, 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x42b80000, 0x42ba0000,
+ 0x00000005, 0x32727261, 0x00000000, 0x00000007, 0x00000004, 0x000008fc, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000005, 0x31786574, 0x00000000, 0x00000007, 0x00000004, 0x00000920, 0x00000000,
+ 0x00000000, 0x00000005, 0x00000005, 0x32786574, 0x00000000, 0x0000000a, 0x00000004, 0x000009cc,
+ 0x00000000, 0x00000000, 0x00000006, 0x00000007, 0x00000004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000003, 0x000000a4, 0x00000100, 0x00000944, 0x00000940, 0x000000aa, 0x00000100, 0x0000095c,
+ 0x00000958, 0x000000a9, 0x00000100, 0x0000097c, 0x00000978, 0x00000009, 0x706d6173, 0x3172656c,
+ 0x00000000, 0x0000000a, 0x00000004, 0x00000ab8, 0x00000000, 0x00000002, 0x00000001, 0x00000002,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000002, 0x000000aa,
+ 0x00000100, 0x000009f4, 0x000009f0, 0x000000a9, 0x00000100, 0x00000a14, 0x00000a10, 0x00000002,
+ 0x000000aa, 0x00000100, 0x00000a34, 0x00000a30, 0x000000a9, 0x00000100, 0x00000a54, 0x00000a50,
+ 0x0000000f, 0x706d6173, 0x7372656c, 0x7272615f, 0x00007961, 0x00000010, 0x00000004, 0x00000ae8,
+ 0x00000000, 0x00000002, 0x00000007, 0x00000008, 0x00000008, 0x615f7376, 0x00327272, 0x0000000f,
+ 0x00000004, 0x00000b0c, 0x00000000, 0x00000001, 0x00000009, 0x00000007, 0x615f7370, 0x00007272,
+ 0x0000000a, 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x0000000b, 0x0000000f,
+ 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00003070, 0x0000000c,
+ 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003170, 0x00000006,
+ 0x68636574, 0x00000030, 0x00000022, 0x00000001, 0x0000000e, 0x0000000d, 0x00000004, 0x00000020,
+ 0x00000000, 0x00000000, 0x0000003c, 0x00000058, 0x00000000, 0x00000000, 0x00000074, 0x00000090,
+ 0x00000000, 0x00000000, 0x000000d0, 0x000000ec, 0x00000000, 0x00000000, 0x00000108, 0x00000124,
+ 0x00000000, 0x00000000, 0x00000140, 0x0000015c, 0x00000000, 0x00000000, 0x00000178, 0x00000194,
+ 0x00000000, 0x00000000, 0x000001b8, 0x000001d4, 0x00000000, 0x00000000, 0x000001ec, 0x00000208,
+ 0x00000000, 0x00000000, 0x00000224, 0x00000238, 0x00000000, 0x00000000, 0x00000250, 0x0000026c,
+ 0x00000000, 0x00000000, 0x000002b8, 0x000002d4, 0x00000000, 0x00000000, 0x00000310, 0x0000032c,
+ 0x00000000, 0x00000000, 0x00000368, 0x00000384, 0x00000000, 0x00000000, 0x000003c4, 0x000003e0,
+ 0x00000000, 0x00000000, 0x00000420, 0x0000043c, 0x00000000, 0x00000000, 0x00000458, 0x00000474,
+ 0x00000000, 0x00000000, 0x00000494, 0x000004b0, 0x00000000, 0x00000000, 0x000004d4, 0x000004f0,
+ 0x00000000, 0x00000000, 0x00000518, 0x00000534, 0x00000000, 0x00000000, 0x00000558, 0x00000574,
+ 0x00000000, 0x00000000, 0x0000059c, 0x000005b8, 0x00000000, 0x00000000, 0x000005e0, 0x000005fc,
+ 0x00000000, 0x00000000, 0x00000624, 0x00000690, 0x00000000, 0x00000000, 0x000006d0, 0x0000073c,
+ 0x00000001, 0x00000000, 0x0000079c, 0x00000820, 0x00000000, 0x00000000, 0x00000888, 0x000008a4,
+ 0x00000000, 0x00000000, 0x000008b4, 0x000008d0, 0x00000001, 0x00000000, 0x000008e4, 0x000008f8,
+ 0x00000000, 0x00000000, 0x00000908, 0x0000091c, 0x00000000, 0x00000000, 0x0000092c, 0x00000998,
+ 0x00000000, 0x00000000, 0x000009dc, 0x00000a70, 0x00000000, 0x00000000, 0x00000acc, 0x00000ae0,
+ 0x00000001, 0x00000000, 0x00000af4, 0x00000b08, 0x00000000, 0x00000000, 0x00001154, 0x00000000,
+ 0x00000002, 0x0000112c, 0x00000000, 0x0000002a, 0x00000092, 0x00000000, 0x00000b1c, 0x00000b18,
+ 0x00000093, 0x00000000, 0x00000b34, 0x00000b30, 0x00000091, 0x00000000, 0x00000b4c, 0x00000b48,
+ 0x00000091, 0x00000001, 0x00000b6c, 0x00000b68, 0x00000091, 0x00000002, 0x00000b8c, 0x00000b88,
+ 0x00000091, 0x00000003, 0x00000bac, 0x00000ba8, 0x00000091, 0x00000004, 0x00000bcc, 0x00000bc8,
+ 0x00000091, 0x00000005, 0x00000bec, 0x00000be8, 0x00000091, 0x00000006, 0x00000c0c, 0x00000c08,
+ 0x00000091, 0x00000007, 0x00000c2c, 0x00000c28, 0x00000084, 0x00000000, 0x00000c4c, 0x00000c48,
+ 0x00000084, 0x00000001, 0x00000c6c, 0x00000c68, 0x00000084, 0x00000002, 0x00000c8c, 0x00000c88,
+ 0x00000084, 0x00000003, 0x00000cac, 0x00000ca8, 0x00000084, 0x00000004, 0x00000ccc, 0x00000cc8,
+ 0x00000084, 0x00000005, 0x00000cec, 0x00000ce8, 0x00000084, 0x00000006, 0x00000d0c, 0x00000d08,
+ 0x00000084, 0x00000007, 0x00000d2c, 0x00000d28, 0x00000085, 0x00000000, 0x00000d58, 0x00000d48,
+ 0x00000085, 0x00000001, 0x00000d84, 0x00000d74, 0x00000085, 0x00000002, 0x00000db0, 0x00000da0,
+ 0x00000085, 0x00000003, 0x00000ddc, 0x00000dcc, 0x00000085, 0x00000004, 0x00000e08, 0x00000df8,
+ 0x00000085, 0x00000005, 0x00000e34, 0x00000e24, 0x00000085, 0x00000006, 0x00000e60, 0x00000e50,
+ 0x00000085, 0x00000007, 0x00000e8c, 0x00000e7c, 0x00000087, 0x00000000, 0x00000eb8, 0x00000ea8,
+ 0x00000087, 0x00000001, 0x00000ee4, 0x00000ed4, 0x00000087, 0x00000002, 0x00000f10, 0x00000f00,
+ 0x00000087, 0x00000003, 0x00000f3c, 0x00000f2c, 0x00000087, 0x00000004, 0x00000f68, 0x00000f58,
+ 0x00000087, 0x00000005, 0x00000f94, 0x00000f84, 0x00000087, 0x00000006, 0x00000fc0, 0x00000fb0,
+ 0x00000087, 0x00000007, 0x00000fec, 0x00000fdc, 0x00000086, 0x00000000, 0x00001018, 0x00001008,
+ 0x00000086, 0x00000001, 0x00001044, 0x00001034, 0x00000086, 0x00000002, 0x00001070, 0x00001060,
+ 0x0000000e, 0x00000000, 0x00001090, 0x0000108c, 0x00000014, 0x00000000, 0x000010b0, 0x000010ac,
+ 0x00000012, 0x00000000, 0x000010d0, 0x000010cc, 0x00000041, 0x00000000, 0x000010f0, 0x000010ec,
+ 0x00000042, 0x00000000, 0x00001110, 0x0000110c, 0x0000114c, 0x00000000, 0x00000001, 0x00000092,
+ 0x00000000, 0x00001138, 0x00001134, 0x00000008, 0x0000001f, 0x00000009, 0x00000ad0, 0xffff0300,
+ 0x00d9fffe, 0x42415443, 0x0000001c, 0x0000032f, 0xffff0300, 0x0000000b, 0x0000001c, 0x00000000,
+ 0x00000328, 0x000000f8, 0x00000001, 0x00000001, 0x00000100, 0x00000110, 0x00000120, 0x00080002,
+ 0x00000002, 0x0000012c, 0x0000013c, 0x0000015c, 0x00060002, 0x00000002, 0x00000164, 0x00000174,
+ 0x00000194, 0x00000002, 0x00000003, 0x000001a0, 0x000001b0, 0x000001e0, 0x000a0002, 0x00000002,
+ 0x000001e8, 0x000001f8, 0x00000218, 0x000c0002, 0x00000002, 0x00000224, 0x00000234, 0x00000254,
+ 0x00030002, 0x00000003, 0x0000025c, 0x0000026c, 0x0000029c, 0x00050000, 0x00000001, 0x000002a8,
+ 0x000002b8, 0x000002d0, 0x00000000, 0x00000005, 0x000002dc, 0x000002b8, 0x000002ec, 0x00000003,
+ 0x00000001, 0x000002f8, 0x00000000, 0x00000308, 0x00010003, 0x00000001, 0x00000318, 0x00000000,
+ 0x56695f67, 0x00746365, 0x00020001, 0x00040001, 0x00000001, 0x00000000, 0x00000004, 0x00000003,
+ 0x00000002, 0x00000001, 0x3278326d, 0x756c6f63, 0xab006e6d, 0x00030003, 0x00020002, 0x00000001,
+ 0x00000000, 0x41300000, 0x41a80000, 0x00000000, 0x00000000, 0x41400000, 0x41b00000, 0x00000000,
+ 0x00000000, 0x3278326d, 0x00776f72, 0x00030002, 0x00020002, 0x00000001, 0x00000000, 0x41300000,
+ 0x41400000, 0x00000000, 0x00000000, 0x41a80000, 0x41b00000, 0x00000000, 0x00000000, 0x3378326d,
+ 0x756c6f63, 0xab006e6d, 0x00030003, 0x00030002, 0x00000001, 0x00000000, 0x41300000, 0x41a80000,
+ 0x00000000, 0x00000000, 0x41400000, 0x41b00000, 0x00000000, 0x00000000, 0x41500000, 0x41b80000,
+ 0x00000000, 0x00000000, 0x3378326d, 0x00776f72, 0x00030002, 0x00030002, 0x00000001, 0x00000000,
+ 0x41300000, 0x41400000, 0x41500000, 0x00000000, 0x41a80000, 0x41b00000, 0x41b80000, 0x00000000,
+ 0x3278336d, 0x756c6f63, 0xab006e6d, 0x00030003, 0x00020003, 0x00000001, 0x00000000, 0x41300000,
+ 0x41a80000, 0x41f80000, 0x00000000, 0x41400000, 0x41b00000, 0x42000000, 0x00000000, 0x3278336d,
+ 0x00776f72, 0x00030002, 0x00020003, 0x00000001, 0x00000000, 0x41300000, 0x41400000, 0x00000000,
+ 0x00000000, 0x41a80000, 0x41b00000, 0x00000000, 0x00000000, 0x41f80000, 0x42000000, 0x00000000,
+ 0x00000000, 0x7832626d, 0x6c6f6333, 0x006e6d75, 0x00010003, 0x00030002, 0x00000001, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x7832626d, 0x776f7233,
+ 0xababab00, 0x00010002, 0x00030002, 0x00000001, 0x00000000, 0x706d6173, 0x3172656c, 0xababab00,
+ 0x000c0004, 0x00010001, 0x00000001, 0x00000000, 0x706d6173, 0x7372656c, 0x7272615f, 0xab007961,
+ 0x000c0004, 0x00010001, 0x00000002, 0x00000000, 0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x05000051, 0xa00f000e, 0x3d2aaaa4, 0xbf000000, 0x3f800000, 0xbe22f983,
+ 0x05000051, 0xa00f000f, 0x40c90fdb, 0xc0490fdb, 0xb4878163, 0x37cfb5a1, 0x05000051, 0xa00f0010,
+ 0x00000000, 0x3e22f983, 0x3e800000, 0xbab609ba, 0x0200001f, 0x80000005, 0x90030000, 0x0200001f,
+ 0x8000000a, 0x900f0001, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801,
+ 0x03000005, 0x80030000, 0xa0e40007, 0x90550001, 0x04000004, 0x80030000, 0x90000001, 0xa0e40006,
+ 0x80e40000, 0x03000002, 0x80030000, 0x80e40000, 0x90e40001, 0x02000001, 0x80010001, 0xa0000010,
+ 0x0400005a, 0x80010002, 0x90e40001, 0xa0e40008, 0x80000001, 0x0400005a, 0x80020002, 0x90e40001,
+ 0xa0e40009, 0x80000001, 0x03000002, 0x80030000, 0x80e40000, 0x80e40002, 0x03000005, 0x800c0000,
+ 0xa0440004, 0x90550001, 0x04000004, 0x800c0000, 0x90000001, 0xa0440003, 0x80e40000, 0x04000004,
+ 0x800c0000, 0x90aa0001, 0xa0440005, 0x80e40000, 0x03000002, 0x80030000, 0x80ee0000, 0x80e40000,
+ 0x03000008, 0x80010002, 0x90e40001, 0xa0e4000c, 0x03000008, 0x80020002, 0x90e40001, 0xa0e4000d,
+ 0x03000002, 0x80030000, 0x80e40000, 0x80e40002, 0x03000005, 0x800e0001, 0xa090000b, 0x90550001,
+ 0x04000004, 0x800e0001, 0x90000001, 0xa090000a, 0x80e40001, 0x02000001, 0x80040000, 0x90aa0001,
+ 0x03000002, 0x80070000, 0x80e40000, 0x80f90001, 0x0400005a, 0x80010002, 0x90e40001, 0xa0e40000,
+ 0x80000001, 0x0400005a, 0x80020002, 0x90e40001, 0xa0e40001, 0x80000001, 0x0400005a, 0x80040002,
+ 0x90e40001, 0xa0e40002, 0x80000001, 0x03000002, 0x80070000, 0x80e40000, 0x80e40002, 0x02000001,
+ 0x80070003, 0x80e40000, 0x01000026, 0xf0e40000, 0x03000002, 0x80070003, 0x80e40002, 0x80e40003,
+ 0x00000027, 0x01000028, 0xe0e40804, 0x02000001, 0x80080003, 0x90ff0001, 0x04000004, 0x800f0000,
+ 0x80e40003, 0xa0550010, 0xa0aa0010, 0x02000013, 0x800f0000, 0x80e40000, 0x04000004, 0x800f0000,
+ 0x80e40000, 0xa000000f, 0xa055000f, 0x03000005, 0x800f0000, 0x80e40000, 0x80e40000, 0x04000004,
+ 0x800f0002, 0x80e40000, 0xa0aa000f, 0xa0ff000f, 0x04000004, 0x800f0002, 0x80e40000, 0x80e40002,
+ 0xa0ff0010, 0x04000004, 0x800f0002, 0x80e40000, 0x80e40002, 0xa000000e, 0x04000004, 0x800f0002,
+ 0x80e40000, 0x80e40002, 0xa055000e, 0x04000004, 0x800f0000, 0x80e40000, 0x80e40002, 0x80e40003,
+ 0x03000002, 0x800f0000, 0x80e40000, 0xa0aa000e, 0x04000004, 0x800f0002, 0x80e40000, 0xa1ff000e,
+ 0xa155000e, 0x02000013, 0x800f0002, 0x80e40002, 0x04000004, 0x800f0002, 0x80e40002, 0xa000000f,
+ 0xa055000f, 0x03000005, 0x800f0002, 0x80e40002, 0x80e40002, 0x04000004, 0x800f0004, 0x80e40002,
+ 0xa0aa000f, 0xa0ff000f, 0x04000004, 0x800f0004, 0x80e40002, 0x80e40004, 0xa0ff0010, 0x04000004,
+ 0x800f0004, 0x80e40002, 0x80e40004, 0xa000000e, 0x04000004, 0x800f0004, 0x80e40002, 0x80e40004,
+ 0xa055000e, 0x04000004, 0x800f0000, 0x80e40002, 0x80e40004, 0x80e40000, 0x03000002, 0x800f0003,
+ 0x80e40000, 0xa0aa000e, 0x0400005a, 0x80010000, 0x80e40003, 0xa0e40000, 0x80000001, 0x0400005a,
+ 0x80020000, 0x80e40003, 0xa0e40001, 0x80000001, 0x0400005a, 0x80040000, 0x80e40003, 0xa0e40002,
+ 0x80000001, 0x03000002, 0x80070000, 0x80e40000, 0x80e40003, 0x03000005, 0x800e0001, 0x80550000,
+ 0xa090000b, 0x04000004, 0x800e0001, 0x80000000, 0xa090000a, 0x80e40001, 0x03000002, 0x80070003,
+ 0x80e40000, 0x80f90001, 0x03000008, 0x80010000, 0x80e40003, 0xa0e4000c, 0x03000008, 0x80020000,
+ 0x80e40003, 0xa0e4000d, 0x03000002, 0x80030000, 0x80e40000, 0x80e40003, 0x03000005, 0x800c0000,
+ 0x80550000, 0xa0440004, 0x04000004, 0x800c0000, 0x80000000, 0xa0440003, 0x80e40000, 0x04000004,
+ 0x800c0000, 0x80aa0003, 0xa0440005, 0x80e40000, 0x03000002, 0x80030003, 0x80ee0000, 0x80e40000,
+ 0x0000002a, 0x02000001, 0x80080003, 0x90ff0001, 0x0000002b, 0x01000028, 0xe0e40805, 0x04000004,
+ 0x800f0000, 0x80e40003, 0xa0550010, 0xa0aa0010, 0x02000013, 0x800f0000, 0x80e40000, 0x04000004,
+ 0x800f0000, 0x80e40000, 0xa000000f, 0xa055000f, 0x03000005, 0x800f0000, 0x80e40000, 0x80e40000,
+ 0x04000004, 0x800f0002, 0x80e40000, 0xa0aa000f, 0xa0ff000f, 0x04000004, 0x800f0002, 0x80e40000,
+ 0x80e40002, 0xa0ff0010, 0x04000004, 0x800f0002, 0x80e40000, 0x80e40002, 0xa000000e, 0x04000004,
+ 0x800f0002, 0x80e40000, 0x80e40002, 0xa055000e, 0x04000004, 0x800f0000, 0x80e40000, 0x80e40002,
+ 0x80e40003, 0x03000002, 0x800f0000, 0x80e40000, 0xa0aa000e, 0x04000004, 0x800f0002, 0x80e40000,
+ 0xa1ff000e, 0xa155000e, 0x02000013, 0x800f0002, 0x80e40002, 0x04000004, 0x800f0002, 0x80e40002,
+ 0xa000000f, 0xa055000f, 0x03000005, 0x800f0002, 0x80e40002, 0x80e40002, 0x04000004, 0x800f0004,
+ 0x80e40002, 0xa0aa000f, 0xa0ff000f, 0x04000004, 0x800f0004, 0x80e40002, 0x80e40004, 0xa0ff0010,
+ 0x04000004, 0x800f0004, 0x80e40002, 0x80e40004, 0xa000000e, 0x04000004, 0x800f0004, 0x80e40002,
+ 0x80e40004, 0xa055000e, 0x04000004, 0x800f0000, 0x80e40002, 0x80e40004, 0x80e40000, 0x03000002,
+ 0x800f0003, 0x80e40000, 0xa0aa000e, 0x0400005a, 0x80010000, 0x80e40003, 0xa0e40000, 0x80000001,
+ 0x0400005a, 0x80020000, 0x80e40003, 0xa0e40001, 0x80000001, 0x0400005a, 0x80040000, 0x80e40003,
+ 0xa0e40002, 0x80000001, 0x03000002, 0x80070000, 0x80e40000, 0x80e40003, 0x03000005, 0x80070001,
+ 0x80550000, 0xa0e4000b, 0x04000004, 0x80070001, 0x80000000, 0xa0e4000a, 0x80e40001, 0x03000002,
+ 0x80070003, 0x80e40000, 0x80e40001, 0x03000008, 0x80010000, 0x80e40003, 0xa0e4000c, 0x03000008,
+ 0x80020000, 0x80e40003, 0xa0e4000d, 0x03000002, 0x80030000, 0x80e40000, 0x80e40003, 0x03000005,
+ 0x800c0000, 0x80550000, 0xa0440004, 0x04000004, 0x800c0000, 0x80000000, 0xa0440003, 0x80e40000,
+ 0x04000004, 0x800c0000, 0x80aa0003, 0xa0440005, 0x80e40000, 0x03000002, 0x80030003, 0x80ee0000,
+ 0x80e40000, 0x0000002b, 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
+ 0x80e40000, 0x80e40003, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801, 0x03000002, 0x800f0800,
+ 0x80e40000, 0x80e40001, 0x0000ffff, 0x00000007, 0x00000b6c, 0xfffe0300, 0x013cfffe, 0x42415443,
+ 0x0000001c, 0x000004bb, 0xfffe0300, 0x0000000c, 0x0000001c, 0x00000000, 0x000004b4, 0x0000010c,
+ 0x00200002, 0x00000001, 0x00000114, 0x00000124, 0x00000134, 0x001d0002, 0x00000002, 0x0000013c,
+ 0x0000014c, 0x0000016c, 0x001f0002, 0x00000001, 0x00000174, 0x00000184, 0x00000194, 0x00100002,
+ 0x00000004, 0x000001a0, 0x000001b0, 0x000001f0, 0x00140002, 0x00000003, 0x000001f8, 0x00000208,
+ 0x00000238, 0x00170002, 0x00000003, 0x00000244, 0x00000254, 0x00000284, 0x000c0002, 0x00000004,
+ 0x0000028c, 0x0000029c, 0x000002dc, 0x00020003, 0x00000001, 0x000002e8, 0x00000000, 0x000002f8,
+ 0x00000003, 0x00000002, 0x00000308, 0x00000000, 0x00000318, 0x001a0002, 0x00000003, 0x00000370,
+ 0x00000380, 0x000003b0, 0x00000002, 0x00000006, 0x000003b4, 0x000003c4, 0x00000424, 0x00060002,
+ 0x00000006, 0x00000444, 0x00000454, 0x31727261, 0xababab00, 0x00030000, 0x00010001, 0x00000001,
+ 0x00000000, 0x42b60000, 0x00000000, 0x00000000, 0x00000000, 0x32727261, 0xababab00, 0x00030000,
+ 0x00010001, 0x00000002, 0x00000000, 0x42b80000, 0x00000000, 0x00000000, 0x00000000, 0x42ba0000,
+ 0x00000000, 0x00000000, 0x00000000, 0x6f505f67, 0xab003173, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3478336d, 0x756c6f63, 0xab006e6d,
+ 0x00030003, 0x00040003, 0x00000001, 0x00000000, 0x41300000, 0x41a80000, 0x41f80000, 0x00000000,
+ 0x41400000, 0x41b00000, 0x42000000, 0x00000000, 0x41500000, 0x41b80000, 0x42040000, 0x00000000,
+ 0x41600000, 0x41c00000, 0x42080000, 0x00000000, 0x3478336d, 0x00776f72, 0x00030002, 0x00040003,
+ 0x00000001, 0x00000000, 0x41300000, 0x41400000, 0x41500000, 0x41600000, 0x41a80000, 0x41b00000,
+ 0x41b80000, 0x41c00000, 0x41f80000, 0x42000000, 0x42040000, 0x42080000, 0x3378346d, 0x756c6f63,
+ 0xab006e6d, 0x00030003, 0x00030004, 0x00000001, 0x00000000, 0x41300000, 0x41a80000, 0x41f80000,
+ 0x42240000, 0x41400000, 0x41b00000, 0x42000000, 0x42280000, 0x41500000, 0x41b80000, 0x42040000,
+ 0x422c0000, 0x3378346d, 0x00776f72, 0x00030002, 0x00030004, 0x00000001, 0x00000000, 0x41300000,
+ 0x41400000, 0x41500000, 0x00000000, 0x41a80000, 0x41b00000, 0x41b80000, 0x00000000, 0x41f80000,
+ 0x42000000, 0x42040000, 0x00000000, 0x42240000, 0x42280000, 0x422c0000, 0x00000000, 0x706d6173,
+ 0x3172656c, 0xababab00, 0x000c0004, 0x00010001, 0x00000001, 0x00000000, 0x706d6173, 0x7372656c,
+ 0x7272615f, 0xab007961, 0x000c0004, 0x00010001, 0x00000002, 0x00000000, 0x00317374, 0xab003176,
+ 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0xab007666, 0x00030000, 0x00010001, 0x00000001,
+ 0x00000000, 0xab003276, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x0000031c, 0x00000320,
+ 0x00000330, 0x00000334, 0x00000344, 0x00000348, 0x00000005, 0x00080001, 0x00030001, 0x00000358,
+ 0x41100000, 0x41200000, 0x41300000, 0x00000000, 0x41400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x41500000, 0x41600000, 0x41700000, 0x41800000, 0x00327374, 0x00000005, 0x00080001, 0x00030002,
+ 0x00000358, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x40000000, 0x40400000,
+ 0x00000000, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000,
+ 0x41000000, 0x00337374, 0xab007374, 0x00000005, 0x00080001, 0x00030002, 0x00000358, 0x00000428,
+ 0x0000042c, 0x00000005, 0x00100001, 0x00010001, 0x0000043c, 0x3f800000, 0x40000000, 0x40400000,
+ 0x00000000, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000,
+ 0x41000000, 0x41100000, 0x41200000, 0x41300000, 0x00000000, 0x41400000, 0x00000000, 0x00000000,
+ 0x00000000, 0x41500000, 0x41600000, 0x41700000, 0x41800000, 0x335f7376, 0x4d00305f, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x00f0fffe, 0x53455250, 0x46580201, 0x0047fffe, 0x42415443,
+ 0x0000001c, 0x000000e7, 0x46580201, 0x00000003, 0x0000001c, 0x00000100, 0x000000e4, 0x00000058,
+ 0x00020002, 0x00000001, 0x00000060, 0x00000070, 0x00000080, 0x00030002, 0x00000001, 0x00000088,
+ 0x00000070, 0x00000098, 0x00000002, 0x00000002, 0x000000a4, 0x000000b4, 0x6f505f67, 0xab003173,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x6f505f67, 0xab003273, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x65535f67, 0x7463656c,
+ 0xab00726f, 0x00030001, 0x00040001, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x41200000, 0x41200000, 0x41200000, 0x41200000, 0x459c4800, 0x459c5000, 0x459c5800,
+ 0x459c6000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+ 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x000cfffe, 0x49535250,
+ 0x00000021, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000021,
+ 0x00000001, 0x00000000, 0x00000000, 0x0032fffe, 0x54494c43, 0x00000018, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3fe00000,
+ 0x00000000, 0xc0000000, 0x00000000, 0xc0080000, 0x00000000, 0x00000000, 0x00000000, 0x40100000,
+ 0x00000000, 0x40140000, 0x00000000, 0x40180000, 0x00000000, 0x401c0000, 0x0064fffe, 0x434c5846,
+ 0x00000009, 0xa0500004, 0x00000002, 0x00000000, 0x00000001, 0x00000011, 0x00000000, 0x00000002,
+ 0x00000008, 0x00000000, 0x00000007, 0x00000000, 0x20400004, 0x00000002, 0x00000000, 0x00000007,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000014, 0x00000000, 0x00000007, 0x00000004, 0xa0500004,
+ 0x00000002, 0x00000000, 0x00000001, 0x00000012, 0x00000000, 0x00000002, 0x0000000c, 0x00000000,
+ 0x00000007, 0x00000000, 0x20400004, 0x00000002, 0x00000000, 0x00000007, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000014, 0x00000000, 0x00000007, 0x00000008, 0x10100004, 0x00000001, 0x00000000,
+ 0x00000007, 0x00000008, 0x00000000, 0x00000007, 0x00000000, 0x20400004, 0x00000002, 0x00000000,
+ 0x00000007, 0x00000000, 0x00000000, 0x00000007, 0x00000004, 0x00000000, 0x00000007, 0x0000000c,
+ 0xa0200001, 0x00000002, 0x00000000, 0x00000001, 0x00000010, 0x00000000, 0x00000002, 0x00000005,
+ 0x00000000, 0x00000007, 0x00000000, 0xa0500004, 0x00000002, 0x00000000, 0x00000007, 0x00000000,
+ 0x00000000, 0x00000007, 0x0000000c, 0x00000000, 0x00000007, 0x00000004, 0x20400004, 0x00000002,
+ 0x00000000, 0x00000007, 0x00000004, 0x00000000, 0x00000007, 0x00000008, 0x00000000, 0x00000004,
+ 0x00000084, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x05000051, 0xa00f0022, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000, 0xa00f0801,
+ 0x0200001f, 0x90000000, 0xa00f0802, 0x0200001f, 0x80000000, 0xe00f0000, 0x0200001f, 0x80000005,
+ 0xe0030001, 0x0200001f, 0x8000000a, 0xe00f0002, 0x03000009, 0x80010000, 0x90e40000, 0xa0e40017,
+ 0x03000009, 0x80020000, 0x90e40000, 0xa0e40018, 0x03000009, 0x80040000, 0x90e40000, 0xa0e40019,
+ 0x03000008, 0x80010001, 0x90e40000, 0xa0e40010, 0x03000008, 0x80020001, 0x90e40000, 0xa0e40011,
+ 0x03000008, 0x80040001, 0x90e40000, 0xa0e40012, 0x03000008, 0x80080001, 0x90e40000, 0xa0e40013,
+ 0x02000001, 0x80080000, 0xa0000022, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000005,
+ 0x800f0001, 0xa0e40015, 0x90550000, 0x04000004, 0x800f0001, 0x90000000, 0xa0e40014, 0x80e40001,
+ 0x04000004, 0x800f0001, 0x90aa0000, 0xa0e40016, 0x80e40001, 0x03000002, 0x800f0000, 0x80e40000,
+ 0x80e40001, 0x03000005, 0x80070001, 0xa0e4000d, 0x90550000, 0x04000004, 0x80070001, 0x90000000,
+ 0xa0e4000c, 0x80e40001, 0x04000004, 0x80070001, 0x90aa0000, 0xa0e4000e, 0x80e40001, 0x04000004,
+ 0x80070001, 0x90ff0000, 0xa0e4000f, 0x80e40001, 0x03000002, 0x80070000, 0x80e40000, 0x80e40001,
+ 0x04000004, 0x800f0000, 0x90e40000, 0xa000001b, 0x80e40000, 0x03000009, 0x80010001, 0x90e40000,
+ 0xa0e4001c, 0x03000002, 0x800f0000, 0x80e40000, 0x80000001, 0x04000004, 0x800f0000, 0x90e40000,
+ 0xa0000004, 0x80e40000, 0x03000009, 0x80010001, 0x90e40000, 0xa0e40005, 0x03000002, 0x800f0000,
+ 0x80e40000, 0x80000001, 0x04000004, 0x800f0000, 0x90e40000, 0xa0000020, 0x80e40000, 0x04000004,
+ 0x800f0000, 0x90e40000, 0xa000001e, 0x80e40000, 0x04000004, 0x800f0000, 0x90e40000, 0xa000000a,
+ 0x80e40000, 0x03000009, 0x80010001, 0x90e40000, 0xa0e4000b, 0x03000002, 0x800f0000, 0x80e40000,
+ 0x80000001, 0x0300005f, 0x800f0001, 0xa0e4001f, 0xa0e40802, 0x03000002, 0x800f0000, 0x80e40000,
+ 0x80e40001, 0x0300005f, 0x800f0001, 0xa0e4001f, 0xa0e40801, 0x03000002, 0xe00f0002, 0x80e40000,
+ 0x80e40001, 0x02000001, 0xe00f0000, 0xa0e40021, 0x02000001, 0xe0030001, 0xa0000022, 0x0000ffff,
+ 0x00000008, 0x000001dc, 0xfffe0300, 0x0016fffe, 0x42415443, 0x0000001c, 0x00000023, 0xfffe0300,
+ 0x00000000, 0x00000000, 0x00000000, 0x0000001c, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x0045fffe, 0x53455250, 0x46580201, 0x0024fffe, 0x42415443, 0x0000001c,
+ 0x0000005b, 0x46580201, 0x00000001, 0x0000001c, 0x00000100, 0x00000058, 0x00000030, 0x00000002,
+ 0x00000001, 0x00000038, 0x00000048, 0x6f505f67, 0xab003173, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x000cfffe, 0x49535250, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10000004, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+ 0xe00f0000, 0x0200001f, 0x80000005, 0xe0030001, 0x0200001f, 0x8000000a, 0xe00f0002, 0x02000001,
+ 0xe00f0000, 0xa0e40000, 0x02000001, 0xe0030001, 0xa0000001, 0x02000001, 0xe00f0002, 0xa0000001,
+ 0x0000ffff, 0x00000005, 0x00000000, 0x00000004, 0x00000000, 0x00000001, 0x0000002c, 0xfffe0101,
+ 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000001, 0xc00f0000,
+ 0xa0e40000, 0x0000ffff, 0x00000002, 0x0000002c, 0xfffe0101, 0x00000051, 0xa00f0000, 0x40000000,
+ 0x40000000, 0x40000000, 0x40000000, 0x00000001, 0xc00f0000, 0xa0e40000, 0x0000ffff, 0x00000003,
+ 0x0000002c, 0xfffe0200, 0x05000051, 0xa00f0000, 0x40400000, 0x40400000, 0x40400000, 0x40400000,
+ 0x02000001, 0xc00f0000, 0xa0e40000, 0x0000ffff, 0x00000000, 0x00000001, 0xffffffff, 0x00000000,
+ 0x00000002, 0x000000e8, 0x00000008, 0x615f7376, 0x00007272, 0x46580200, 0x0024fffe, 0x42415443,
+ 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x00000100, 0x00000058, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x56695f67, 0x00746365, 0x00020001, 0x00040001,
+ 0x00000001, 0x00000000, 0x40800000, 0x40400000, 0x40000000, 0x3f800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846,
+ 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000029,
+ 0x00000000, 0x00000198, 0x46580200, 0x0053fffe, 0x42415443, 0x0000001c, 0x00000117, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000114, 0x00000030, 0x00000002, 0x00000005, 0x000000a4,
+ 0x000000b4, 0x00337374, 0x76007374, 0xabab0031, 0x00030001, 0x00030001, 0x00000001, 0x00000000,
+ 0xab007666, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0xab003276, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000037, 0x0000003c, 0x0000004c, 0x00000050, 0x00000060, 0x00000064,
+ 0x00000005, 0x00080001, 0x00030002, 0x00000074, 0x00000034, 0x0000008c, 0x00000005, 0x00100001,
+ 0x00010001, 0x0000009c, 0x3f800000, 0x40000000, 0x40400000, 0x00000000, 0x40800000, 0x00000000,
+ 0x00000000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000, 0x41000000, 0x41100000, 0x41200000,
+ 0x41300000, 0x00000000, 0x41400000, 0x00000000, 0x00000000, 0x00000000, 0x41500000, 0x41600000,
+ 0x41700000, 0x41800000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000010, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000028, 0x00000000, 0x00000198, 0x46580200, 0x0053fffe,
+ 0x42415443, 0x0000001c, 0x00000117, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000114,
+ 0x00000030, 0x00000002, 0x00000002, 0x000000a4, 0x000000b4, 0x00337374, 0x76007374, 0xabab0031,
+ 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0xab007666, 0x00030000, 0x00010001, 0x00000001,
+ 0x00000000, 0xab003276, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000037, 0x0000003c,
+ 0x0000004c, 0x00000050, 0x00000060, 0x00000064, 0x00000005, 0x00080001, 0x00030002, 0x00000074,
+ 0x00000034, 0x0000008c, 0x00000005, 0x00100001, 0x00010001, 0x0000009c, 0x3f800000, 0x40000000,
+ 0x40400000, 0x00000000, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000,
+ 0x40e00000, 0x41000000, 0x41100000, 0x41200000, 0x41300000, 0x00000000, 0x41400000, 0x00000000,
+ 0x00000000, 0x00000000, 0x41500000, 0x41600000, 0x41700000, 0x41800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846,
+ 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000027,
+ 0x00000000, 0x0000017c, 0x46580200, 0x004cfffe, 0x42415443, 0x0000001c, 0x000000fb, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x000000f8, 0x00000030, 0x00000002, 0x00000005, 0x00000088,
+ 0x00000098, 0x00327374, 0xab003176, 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0xab007666,
+ 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0xab003276, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000034, 0x00000038, 0x00000048, 0x0000004c, 0x0000005c, 0x00000060, 0x00000005,
+ 0x00080001, 0x00030002, 0x00000070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
+ 0x40000000, 0x40400000, 0x00000000, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000,
+ 0x40c00000, 0x40e00000, 0x41000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000010, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000026, 0x00000000, 0x0000017c, 0x46580200,
+ 0x004cfffe, 0x42415443, 0x0000001c, 0x000000fb, 0x46580200, 0x00000001, 0x0000001c, 0x20000100,
+ 0x000000f8, 0x00000030, 0x00000002, 0x00000002, 0x00000088, 0x00000098, 0x00327374, 0xab003176,
+ 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0xab007666, 0x00030000, 0x00010001, 0x00000001,
+ 0x00000000, 0xab003276, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000034, 0x00000038,
+ 0x00000048, 0x0000004c, 0x0000005c, 0x00000060, 0x00000005, 0x00080001, 0x00030002, 0x00000070,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x00000000,
+ 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000, 0x41000000,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000004,
+ 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0x00000024, 0x00000000, 0x00000770, 0x46580200, 0x008cfffe, 0x42415443, 0x0000001c,
+ 0x000001fb, 0x46580200, 0x00000004, 0x0000001c, 0x20000100, 0x000001f8, 0x0000006c, 0x000b0002,
+ 0x00000001, 0x00000074, 0x00000084, 0x00000094, 0x00060002, 0x00000004, 0x0000009c, 0x000000ac,
+ 0x000000ec, 0x00000002, 0x00000006, 0x00000160, 0x00000170, 0x000001d0, 0x000a0002, 0x00000001,
+ 0x000001d8, 0x000001e8, 0x56695f67, 0x00746365, 0x00020001, 0x00040001, 0x00000001, 0x00000000,
+ 0x40800000, 0x40400000, 0x40000000, 0x3f800000, 0x3478346d, 0xababab00, 0x00030003, 0x00040004,
+ 0x00000001, 0x00000000, 0x41300000, 0x41a80000, 0x41f80000, 0x42240000, 0x41400000, 0x41b00000,
+ 0x42000000, 0x42280000, 0x41500000, 0x41b80000, 0x42040000, 0x422c0000, 0x41600000, 0x41c00000,
+ 0x42080000, 0x42300000, 0x00337374, 0x76007374, 0xabab0031, 0x00030001, 0x00030001, 0x00000001,
+ 0x00000000, 0xab007666, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0xab003276, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x000000f3, 0x000000f8, 0x00000108, 0x0000010c, 0x0000011c,
+ 0x00000120, 0x00000005, 0x00080001, 0x00030002, 0x00000130, 0x000000f0, 0x00000148, 0x00000005,
+ 0x00100001, 0x00010001, 0x00000158, 0x3f800000, 0x40000000, 0x40400000, 0x00000000, 0x40800000,
+ 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000, 0x41000000, 0x41100000,
+ 0x41200000, 0x41300000, 0x00000000, 0x41400000, 0x00000000, 0x00000000, 0x00000000, 0x41500000,
+ 0x41600000, 0x41700000, 0x41800000, 0x33636576, 0xababab00, 0x00030001, 0x00030001, 0x00000001,
+ 0x00000000, 0x447a4000, 0x447a8000, 0x447ac000, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x008afffe, 0x54494c43, 0x00000044, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3ff00000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3ff00000, 0x00000000, 0x40080000, 0x00000000,
+ 0x3ff00000, 0x00000000, 0x40000000, 0x00000000, 0x00000000, 0x00c1fffe, 0x434c5846, 0x0000000e,
+ 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000018, 0x00000001, 0x00000002, 0x0000002e,
+ 0x00000001, 0x0000003c, 0x00000000, 0x00000007, 0x00000000, 0x50000004, 0x00000002, 0x00000000,
+ 0x00000002, 0x0000001c, 0x00000001, 0x00000002, 0x0000002e, 0x00000001, 0x0000003c, 0x00000000,
+ 0x00000007, 0x00000001, 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000020, 0x00000001,
+ 0x00000002, 0x0000002e, 0x00000001, 0x0000003c, 0x00000000, 0x00000007, 0x00000002, 0x50000004,
+ 0x00000002, 0x00000000, 0x00000002, 0x00000024, 0x00000001, 0x00000002, 0x0000002e, 0x00000001,
+ 0x0000003c, 0x00000000, 0x00000007, 0x00000003, 0xa0400001, 0x00000002, 0x00000000, 0x00000002,
+ 0x0000002f, 0x00000000, 0x00000002, 0x0000002f, 0x00000000, 0x00000007, 0x00000004, 0x50000004,
+ 0x00000002, 0x00000000, 0x00000002, 0x00000018, 0x00000001, 0x00000007, 0x00000004, 0x00000001,
+ 0x00000030, 0x00000000, 0x00000007, 0x00000008, 0x50000004, 0x00000002, 0x00000000, 0x00000002,
+ 0x0000001c, 0x00000001, 0x00000007, 0x00000004, 0x00000001, 0x00000030, 0x00000000, 0x00000007,
+ 0x00000009, 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000020, 0x00000001, 0x00000007,
+ 0x00000004, 0x00000001, 0x00000030, 0x00000000, 0x00000007, 0x0000000a, 0x50000004, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000024, 0x00000001, 0x00000007, 0x00000004, 0x00000001, 0x00000030,
+ 0x00000000, 0x00000007, 0x0000000b, 0x50000004, 0x00000002, 0x00000000, 0x00000007, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000008, 0x00000000, 0x00000004, 0x00000000, 0x50000003, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000028, 0x00000001, 0x00000002, 0x0000002e, 0x00000001, 0x00000030,
+ 0x00000000, 0x00000004, 0x00000002, 0x70e00001, 0x00000006, 0x00000000, 0x00000001, 0x00000041,
+ 0x00000000, 0x00000001, 0x00000042, 0x00000000, 0x00000001, 0x00000040, 0x00000001, 0x00000002,
+ 0x0000002f, 0x00000001, 0x00000030, 0x00000001, 0x00000002, 0x0000002f, 0x00000001, 0x00000031,
+ 0x00000001, 0x00000002, 0x0000002f, 0x00000001, 0x00000032, 0x00000000, 0x00000004, 0x00000003,
+ 0xa0500001, 0x00000002, 0x00000000, 0x00000002, 0x0000002c, 0x00000000, 0x00000001, 0x00000040,
+ 0x00000000, 0x00000007, 0x00000000, 0x10000001, 0x00000001, 0x00000001, 0x00000007, 0x00000000,
+ 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000001, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000023, 0x00000000, 0x000004ec, 0x46580200, 0x005afffe,
+ 0x42415443, 0x0000001c, 0x00000133, 0x46580200, 0x00000004, 0x0000001c, 0x20000100, 0x00000130,
+ 0x0000006c, 0x00000002, 0x00000003, 0x00000078, 0x00000088, 0x000000b8, 0x000a0002, 0x00000001,
+ 0x000000c0, 0x000000d0, 0x000000e0, 0x00080002, 0x00000001, 0x000000e8, 0x000000f8, 0x00000108,
+ 0x00090002, 0x00000001, 0x00000110, 0x00000120, 0x65535f67, 0x7463656c, 0xab00726f, 0x00030001,
+ 0x00040001, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x41200000,
+ 0x41200000, 0x41200000, 0x41200000, 0x459c4800, 0x459c5000, 0x459c5800, 0x459c6000, 0x56695f67,
+ 0x00746365, 0x00020001, 0x00040001, 0x00000001, 0x00000000, 0x40800000, 0x40400000, 0x40000000,
+ 0x3f800000, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x4d007874, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x007afffe, 0x54494c43, 0x0000003c, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3ff00000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3ff00000, 0x0062fffe, 0x434c5846, 0x00000008,
+ 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000020, 0x00000001, 0x00000002, 0x0000002a,
+ 0x00000001, 0x0000002c, 0x00000000, 0x00000004, 0x00000000, 0x10400001, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000025, 0x00000000, 0x00000007, 0x00000000, 0x10100001, 0x00000001, 0x00000000,
+ 0x00000007, 0x00000000, 0x00000000, 0x00000007, 0x00000004, 0xa0400001, 0x00000002, 0x00000000,
+ 0x00000002, 0x00000025, 0x00000000, 0x00000001, 0x0000002c, 0x00000000, 0x00000007, 0x00000000,
+ 0xa0400001, 0x00000002, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000007, 0x00000004,
+ 0x00000000, 0x00000007, 0x00000008, 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000028,
+ 0x00000001, 0x00000007, 0x00000008, 0x00000001, 0x0000002c, 0x00000000, 0x00000004, 0x00000001,
+ 0xa0400001, 0x00000002, 0x00000001, 0x00000002, 0x0000002b, 0x00000002, 0x00000010, 0x00000001,
+ 0x00000002, 0x0000002b, 0x00000002, 0x0000001d, 0x00000000, 0x00000004, 0x00000002, 0xa0400001,
+ 0x00000002, 0x00000001, 0x00000002, 0x00000028, 0x00000002, 0x00000001, 0x00000001, 0x00000002,
+ 0x0000002b, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000022, 0x00000000, 0x000002cc, 0x46580200,
+ 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002, 0x0000001c, 0x20000100,
+ 0x00000094, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002,
+ 0x00000001, 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x001afffe, 0x54494c43, 0x0000000c, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0061fffe,
+ 0x434c5846, 0x00000006, 0xa0500001, 0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000002, 0x00000004, 0x00000000, 0x00000007, 0x00000000, 0xa0500001, 0x00000002, 0x00000000,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000005, 0x00000000, 0x00000007, 0x00000001,
+ 0xa0400001, 0x00000002, 0x00000000, 0x00000007, 0x00000001, 0x00000000, 0x00000007, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000000, 0x70e00001, 0x00000006, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000004, 0x00000000, 0x00000002, 0x00000005, 0x00000000, 0x00000002, 0x00000006, 0x00000000,
+ 0x00000004, 0x00000001, 0x70e00001, 0x00000008, 0x00000000, 0x00000002, 0x00000002, 0x00000000,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000002,
+ 0x00000005, 0x00000000, 0x00000002, 0x00000005, 0x00000000, 0x00000004, 0x00000002, 0x10000001,
+ 0x00000001, 0x00000000, 0x00000001, 0x00000008, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0,
+ 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000021, 0x00000000, 0x00000248,
+ 0x46580200, 0x003efffe, 0x42415443, 0x0000001c, 0x000000c3, 0x46580200, 0x00000003, 0x0000001c,
+ 0x20000100, 0x000000c0, 0x00000058, 0x00000002, 0x00000001, 0x00000060, 0x00000070, 0x00000080,
+ 0x00010002, 0x00000001, 0x00000088, 0x00000098, 0x000000a8, 0x00020002, 0x00000001, 0x000000b0,
+ 0x00000070, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x6576706f, 0x00337463, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0022fffe, 0x54494c43, 0x00000010, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x812dea11, 0x3d719799, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x002dfffe, 0x434c5846, 0x00000004, 0xa0500004, 0x00000002,
+ 0x00000000, 0x00000001, 0x0000000c, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000007,
+ 0x00000000, 0x20400004, 0x00000002, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000007, 0x00000004, 0x10100004, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000008, 0x00000000, 0x00000007, 0x00000000, 0x20400004, 0x00000002, 0x00000000, 0x00000007,
+ 0x00000000, 0x00000000, 0x00000007, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0,
+ 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000020, 0x00000000, 0x000001f0,
+ 0x46580200, 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002, 0x0000001c,
+ 0x20000100, 0x00000094, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c,
+ 0x00010002, 0x00000001, 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x001afffe, 0x54494c43, 0x0000000c,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x002afffe, 0x434c5846, 0x00000004, 0x50000004, 0x00000002, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000001, 0x50000004, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000002, 0x10000001, 0x00000001, 0x00000000, 0x00000001, 0x00000008, 0x00000000, 0x00000004,
+ 0x00000000, 0x10000001, 0x00000001, 0x00000000, 0x00000001, 0x00000008, 0x00000000, 0x00000004,
+ 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000001f,
+ 0x00000000, 0x000001a8, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0012fffe, 0x54494c43, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x47ae147b, 0x3f847ae1, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x002ffffe, 0x434c5846, 0x00000005, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000007, 0x00000001, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000007, 0x00000002, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000007, 0x00000003, 0xa0500004, 0x00000002,
+ 0x00000000, 0x00000001, 0x00000004, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000001e,
+ 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10900004, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000001d, 0x00000000, 0x000000dc, 0x46580200,
+ 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100,
+ 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x000cfffe, 0x434c5846, 0x00000001, 0x10800004, 0x00000001, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0x0000001c, 0x00000000, 0x00000124, 0x46580200, 0x0033fffe, 0x42415443, 0x0000001c,
+ 0x00000097, 0x46580200, 0x00000002, 0x0000001c, 0x20000100, 0x00000094, 0x00000044, 0x00000002,
+ 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002, 0x00000001, 0x00000074, 0x00000084,
+ 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x80000000,
+ 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820,
+ 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235,
+ 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe, 0x434c5846, 0x00000001, 0x20100004,
+ 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x00000000,
+ 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff,
+ 0x0000001b, 0x00000000, 0x00000124, 0x46580200, 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097,
+ 0x46580200, 0x00000002, 0x0000001c, 0x20000100, 0x00000094, 0x00000044, 0x00000002, 0x00000001,
+ 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002, 0x00000001, 0x00000074, 0x00000084, 0x6576706f,
+ 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd,
+ 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x3f800000,
+ 0x40000000, 0xc0400000, 0x40800000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe, 0x434c5846, 0x00000001, 0x20000004, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x0000001a,
+ 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10400004, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000019, 0x00000000, 0x0000013c, 0x46580200,
+ 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100,
+ 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x0024fffe, 0x434c5846, 0x00000004, 0x10300001, 0x00000001, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000000, 0x10300001, 0x00000001, 0x00000000, 0x00000002, 0x00000001,
+ 0x00000000, 0x00000004, 0x00000001, 0x10300001, 0x00000001, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000004, 0x00000002, 0x10300001, 0x00000001, 0x00000000, 0x00000002, 0x00000003,
+ 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0x00000018, 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c,
+ 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002,
+ 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369, 0x74666f73,
+ 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001,
+ 0x10100004, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000,
+ 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000017, 0x00000000,
+ 0x00000124, 0x46580200, 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002,
+ 0x0000001c, 0x20000100, 0x00000094, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c,
+ 0x0000006c, 0x00010002, 0x00000001, 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f,
+ 0x00327463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000,
+ 0x40800000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+ 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43,
+ 0x00000000, 0x000ffffe, 0x434c5846, 0x00000001, 0x20300004, 0x00000002, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0,
+ 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000016, 0x00000000, 0x00000124,
+ 0x46580200, 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002, 0x0000001c,
+ 0x20000100, 0x00000094, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c,
+ 0x00010002, 0x00000001, 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x000ffffe, 0x434c5846, 0x00000001, 0x20200004, 0x00000002, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000015, 0x00000000, 0x00000124, 0x46580200,
+ 0x0033fffe, 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002, 0x0000001c, 0x20000100,
+ 0x00000094, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002,
+ 0x00000001, 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001,
+ 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe,
+ 0x434c5846, 0x00000001, 0x20400004, 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000014, 0x00000000, 0x00000124, 0x46580200, 0x0033fffe,
+ 0x42415443, 0x0000001c, 0x00000097, 0x46580200, 0x00000002, 0x0000001c, 0x20000100, 0x00000094,
+ 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002, 0x00000001,
+ 0x00000074, 0x00000084, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x6576706f, 0x00327463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0xc0400000, 0x40800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe, 0x434c5846,
+ 0x00000001, 0x20500004, 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000013, 0x00000000, 0x0000013c, 0x46580200, 0x0024fffe, 0x42415443,
+ 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000000, 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x0024fffe, 0x434c5846,
+ 0x00000004, 0x10700001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000000, 0x10700001, 0x00000001, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000004,
+ 0x00000001, 0x10700001, 0x00000001, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000004,
+ 0x00000002, 0x10700001, 0x00000001, 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000004,
+ 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000012,
+ 0x00000000, 0x0000013c, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000,
+ 0x80000000, 0xc00ccccd, 0x7f7fffff, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0002fffe, 0x54494c43, 0x00000000, 0x0024fffe, 0x434c5846, 0x00000004, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000004, 0x00000001, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000004, 0x00000002, 0x10300001, 0x00000001,
+ 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f,
+ 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000001, 0x00000002, 0x00000134, 0x00000008,
+ 0x615f7370, 0x00007272, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200,
+ 0x00000001, 0x0000001c, 0x00000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x56695f67, 0x00746365, 0x00020001, 0x00040001, 0x00000001, 0x00000000, 0x40800000,
+ 0x40400000, 0x40000000, 0x3f800000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+ 0x0012fffe, 0x54494c43, 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbff00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x000ffffe, 0x434c5846, 0x00000001, 0xa0400001, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000001, 0x00000004, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000,
+ 0x00000002, 0x00000134, 0x00000008, 0x615f7376, 0x00327272, 0x46580200, 0x0024fffe, 0x42415443,
+ 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x00000100, 0x00000058, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x56695f67, 0x00746365, 0x00020001, 0x00040001,
+ 0x00000001, 0x00000000, 0x40800000, 0x40400000, 0x40000000, 0x3f800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0012fffe, 0x54494c43, 0x00000008, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbff00000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000ffffe, 0x434c5846,
+ 0x00000001, 0xa0400001, 0x00000002, 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000001,
+ 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0xffffffff,
+ 0x0000001f, 0x00000001, 0x00000001, 0x00000000, 0x000000e4, 0x46580200, 0x0026fffe, 0x42415443,
+ 0x0000001c, 0x00000063, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000060, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000040, 0x00000050, 0x74636576, 0x6d61735f, 0x72656c70, 0xababab00,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000001,
+ 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0xffffffff, 0x0000001f,
+ 0x00000000, 0x00000001, 0x00000000, 0x000000e4, 0x46580200, 0x0026fffe, 0x42415443, 0x0000001c,
+ 0x00000063, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000060, 0x00000030, 0x00000002,
+ 0x00000001, 0x00000040, 0x00000050, 0x74636576, 0x6d61735f, 0x72656c70, 0xababab00, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe,
+ 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0xffffffff, 0x0000001e, 0x00000000,
+ 0x00000002, 0x00000000, 0x000000f0, 0x46580200, 0x0026fffe, 0x42415443, 0x0000001c, 0x00000063,
+ 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000060, 0x00000030, 0x00000002, 0x00000001,
+ 0x00000040, 0x00000050, 0x74636576, 0x6d61735f, 0x72656c70, 0xababab00, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe, 0x434c5846,
+ 0x00000001, 0xa0400001, 0x00000002, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0xffffffff,
+ 0x0000001e, 0x00000000, 0x00000001, 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443,
+ 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x56695f67, 0x00746365, 0x00020001, 0x00040001,
+ 0x00000001, 0x00000000, 0x40800000, 0x40400000, 0x40000000, 0x3f800000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846,
+ 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0xffffffff, 0x0000001e, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000005, 0x31786574, 0x00000000,
+};
+#define TEST_EFFECT_PRESHADER_VSHADER_POS 2991
+#define TEST_EFFECT_PRESHADER_VSHADER_LEN 13
+
+#define test_effect_preshader_compare_shader_bytecode(a, b, c, d) \
+ test_effect_preshader_compare_shader_bytecode_(__LINE__, a, b, c, d)
+static void test_effect_preshader_compare_shader_bytecode_(unsigned int line,
+ const DWORD *bytecode, unsigned int bytecode_size, int expected_shader_index, BOOL todo)
+{
+ unsigned int i = 0;
+
+ todo_wine_if(todo)
+ ok_(__FILE__, line)(!!bytecode, "NULL shader bytecode.\n");
+
+ if (!bytecode)
+ return;
+
+ while (bytecode[i++] != 0x0000ffff)
+ ;
+
+ if (!bytecode_size)
+ bytecode_size = i * sizeof(*bytecode);
+ else
+ ok(i * sizeof(*bytecode) == bytecode_size, "Unexpected byte code size %u.\n", bytecode_size);
+
+ todo_wine_if(todo)
+ ok_(__FILE__, line)(!memcmp(bytecode, &test_effect_preshader_effect_blob[TEST_EFFECT_PRESHADER_VSHADER_POS
+ + expected_shader_index * TEST_EFFECT_PRESHADER_VSHADER_LEN], bytecode_size),
+ "Incorrect shader selected.\n");
+}
+
+#define test_effect_preshader_compare_shader(a, b, c) \
+ test_effect_preshader_compare_shader_(__LINE__, a, b, c)
+static void test_effect_preshader_compare_shader_(unsigned int line, IDirect3DDevice9 *device,
+ int expected_shader_index, BOOL todo)
+{
+ IDirect3DVertexShader9 *vshader;
+ void *byte_code;
+ unsigned int byte_code_size;
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok_(__FILE__, line)(hr == D3D_OK, "IDirect3DDevice9_GetVertexShader result %#x.\n", hr);
+
+ todo_wine_if(todo)
+ ok_(__FILE__, line)(!!vshader, "Got NULL vshader.\n");
+ if (!vshader)
+ return;
+
+ hr = IDirect3DVertexShader9_GetFunction(vshader, NULL, &byte_code_size);
+ ok_(__FILE__, line)(hr == D3D_OK, "IDirect3DVertexShader9_GetFunction %#x.\n", hr);
+ ok_(__FILE__, line)(byte_code_size > 1, "Got unexpected byte code size %u.\n", byte_code_size);
+
+ byte_code = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, byte_code_size);
+ hr = IDirect3DVertexShader9_GetFunction(vshader, byte_code, &byte_code_size);
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader_bytecode_(line, byte_code,
+ byte_code_size, expected_shader_index, todo);
+
+ HeapFree(GetProcessHeap(), 0, byte_code);
+ IDirect3DVertexShader9_Release(vshader);
+ }
+
+static const struct
+{
+ const char *comment;
+ BOOL todo[4];
+ unsigned int result[4];
+ unsigned int ulps;
+}
+test_effect_preshader_op_expected[] =
+{
+ {"1 / op", {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
+ {"rsq", {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0x7f800000, 0x3f2c985c, 0x1f800001}, 1},
+ {"mul", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0x40d33334, 0x7f800000}},
+ {"add", {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x40000000, 0xc0a66666, 0x7f7fffff}},
+ {"lt", {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x3f800000, 0x00000000, 0x00000000}},
+ {"ge", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {"neg", {FALSE, FALSE, FALSE, FALSE}, {0x80000000, 0x00000000, 0x400ccccd, 0xff7fffff}},
+ {"rcp", {FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbee8ba2e, 0x00200000}},
+
+ {"frac", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x00000000, 0x3f4ccccc, 0x00000000}},
+ {"min", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0xc0400000, 0x40800000}},
+ {"max", {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x40000000, 0xc00ccccd, 0x7f7fffff}},
+#if __x86_64__
+ {"sin", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0xbf0599b3}},
+ {"cos", {FALSE, FALSE, FALSE, FALSE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0x3f5a5f96}},
+#else
+ {"sin", {FALSE, FALSE, FALSE, TRUE}, {0x00000000, 0x80000000, 0xbf4ef99e, 0x3f792dc4}},
+ {"cos", {FALSE, FALSE, FALSE, TRUE}, {0x3f800000, 0x3f800000, 0xbf16a803, 0xbe6acefc}},
+#endif
+ {"den mul",{FALSE, FALSE, FALSE, FALSE}, {0x7f800000, 0xff800000, 0xbb94f209, 0x000051ec}},
+ {"dot", {FALSE, FALSE, FALSE, FALSE}, {0x00000000, 0x7f800000, 0x41f00000, 0x00000000}},
+ {"prec", {FALSE, FALSE, TRUE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0xac531800, 0x00000000}},
+
+ {"dotswiz", {FALSE, FALSE, FALSE, FALSE}, {0xc00ccccd, 0xc0d33334, 0xc10ccccd, 0}},
+ {"reladdr", {FALSE, FALSE, FALSE, FALSE}, {0xc00ccccd, 0x3f800000, 0, 0x41200000}},
+ {"reladdr2", {FALSE, FALSE, FALSE, FALSE}, {0, 0, 0x447ac000, 0x40000000}},
+};
+
+enum expected_state_update
+{
+ EXPECTED_STATE_ZERO,
+ EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_ANYTHING
+};
+
+#define test_effect_preshader_op_results(a, b, c) test_effect_preshader_op_results_(__LINE__, a, b, c)
+static void test_effect_preshader_op_results_(unsigned int line, IDirect3DDevice9 *device,
+ const enum expected_state_update *expected_state, const char *updated_param)
+{
+ static const D3DCOLORVALUE black = {0.0f};
+ unsigned int i, j;
+ D3DLIGHT9 light;
+ const float *v;
+ HRESULT hr;
+
+ for (i = 0; i < ARRAY_SIZE(test_effect_preshader_op_expected); ++i)
+ {
+ hr = IDirect3DDevice9_GetLight(device, i % 8, &light);
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ v = i < 8 ? &light.Diffuse.r : (i < 16 ? &light.Ambient.r : &light.Specular.r);
+ if (!expected_state || expected_state[i] == EXPECTED_STATE_UPDATED)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ todo_wine_if(test_effect_preshader_op_expected[i].todo[j])
+ ok_(__FILE__, line)(compare_float(v[j],
+ ((const float *)test_effect_preshader_op_expected[i].result)[j],
+ test_effect_preshader_op_expected[i].ulps),
+ "Operation %s, component %u, expected %#x, got %#x (%g).\n",
+ test_effect_preshader_op_expected[i].comment, j,
+ test_effect_preshader_op_expected[i].result[j],
+ ((const unsigned int *)v)[j], v[j]);
+ }
+ }
+ else if (expected_state[i] == EXPECTED_STATE_ZERO)
+ {
+ ok_(__FILE__, line)(!memcmp(v, &black, sizeof(black)),
+ "Parameter %s, test %d, operation %s, state updated unexpectedly.\n",
+ updated_param, i, test_effect_preshader_op_expected[i].comment);
+ }
+ }
+}
+
+static const D3DXVECTOR4 fvect_filler = {-9999.0f, -9999.0f, -9999.0f, -9999.0f};
+
+static void test_effect_preshader_clear_vconsts(IDirect3DDevice9 *device)
+{
+ unsigned int i;
+ HRESULT hr;
+
+ for (i = 0; i < 256; ++i)
+ {
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, i, &fvect_filler.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+}
+
+static const D3DXVECTOR4 test_effect_preshader_fvect_v[] =
+{
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {1.0f, 2.0f, 3.0f, 0.0f},
+ {4.0f, 0.0f, 0.0f, 0.0f},
+ {5.0f, 6.0f, 7.0f, 8.0f},
+ {1.0f, 2.0f, 3.0f, 0.0f},
+ {4.0f, 0.0f, 0.0f, 0.0f},
+ {5.0f, 6.0f, 7.0f, 8.0f},
+ {9.0f, 10.0f, 11.0f, 0.0f},
+ {12.0f, 0.0f, 0.0f, 0.0f},
+ {13.0f, 14.0f, 15.0f, 16.0f},
+ {11.0f, 12.0f, 13.0f, 0.0f},
+ {21.0f, 22.0f, 23.0f, 0.0f},
+ {31.0f, 32.0f, 33.0f, 0.0f},
+ {41.0f, 42.0f, 43.0f, 0.0f},
+ {11.0f, 21.0f, 31.0f, 0.0f},
+ {12.0f, 22.0f, 32.0f, 0.0f},
+ {13.0f, 23.0f, 33.0f, 0.0f},
+ {14.0f, 24.0f, 34.0f, 0.0f},
+ {11.0f, 12.0f, 13.0f, 14.0f},
+ {21.0f, 22.0f, 23.0f, 24.0f},
+ {31.0f, 32.0f, 33.0f, 34.0f},
+ {11.0f, 21.0f, 31.0f, 41.0f},
+ {12.0f, 22.0f, 32.0f, 42.0f},
+ {13.0f, 23.0f, 33.0f, 43.0f},
+ {9.0f, 10.0f, 11.0f, 0.0f},
+ {12.0f, 0.0f, 0.0f, 0.0f},
+ {13.0f, 14.0f, 15.0f, 16.0f},
+ {92.0f, 0.0f, 0.0f, 0.0f},
+ {93.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {91.0f, 0.0f, 0.0f, 0.0f},
+ {4.0f, 5.0f, 6.0f, 7.0f},
+};
+#define TEST_EFFECT_BITMASK_BLOCK_SIZE (sizeof(unsigned int) * 8)
+
+#define test_effect_preshader_compare_vconsts(a, b, c) \
+ test_effect_preshader_compare_vconsts_(__LINE__, a, b, c)
+static void test_effect_preshader_compare_vconsts_(unsigned int line, IDirect3DDevice9 *device,
+ const unsigned int *const_updated_mask, const char *updated_param)
+{
+ HRESULT hr;
+ unsigned int i;
+ D3DXVECTOR4 fdata[ARRAY_SIZE(test_effect_preshader_fvect_v)];
+
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, &fdata[0].x,
+ ARRAY_SIZE(test_effect_preshader_fvect_v));
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ if (!const_updated_mask)
+ {
+ ok_(__FILE__, line)(!memcmp(fdata, test_effect_preshader_fvect_v, sizeof(test_effect_preshader_fvect_v)),
+ "Vertex shader float constants do not match.\n");
+ }
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE(test_effect_preshader_fvect_v); ++i)
+ {
+ if (const_updated_mask[i / TEST_EFFECT_BITMASK_BLOCK_SIZE]
+ & (1u << (i % TEST_EFFECT_BITMASK_BLOCK_SIZE)))
+ {
+ ok_(__FILE__, line)(!memcmp(&fdata[i], &test_effect_preshader_fvect_v[i], sizeof(fdata[i])),
+ "Vertex shader float constants do not match, expected (%g, %g, %g, %g), "
+ "got (%g, %g, %g, %g), parameter %s.\n",
+ test_effect_preshader_fvect_v[i].x, test_effect_preshader_fvect_v[i].y,
+ test_effect_preshader_fvect_v[i].z, test_effect_preshader_fvect_v[i].w,
+ fdata[i].x, fdata[i].y, fdata[i].z, fdata[i].w, updated_param);
+ }
+ else
+ {
+ ok_(__FILE__, line)(!memcmp(&fdata[i], &fvect_filler, sizeof(fdata[i])),
+ "Vertex shader float constants updated unexpectedly, parameter %s.\n", updated_param);
+ }
+ }
+ }
+
+ for (i = ARRAY_SIZE(test_effect_preshader_fvect_v); i < 256; ++i)
+ {
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, i, &fdata[0].x, 1);
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok_(__FILE__, line)(!memcmp(fdata, &fvect_filler, sizeof(fvect_filler)),
+ "Vertex shader float constants do not match.\n");
+ }
+}
+
+static const BOOL test_effect_preshader_bconsts[] =
+{
+ TRUE, FALSE, TRUE, FALSE, TRUE, TRUE
+};
+
+static void test_effect_preshader_clear_pbool_consts(IDirect3DDevice9 *device)
+{
+ BOOL bval;
+ unsigned int i;
+ HRESULT hr;
+
+ for (i = 0; i < 16; ++i)
+ {
+ bval = i < ARRAY_SIZE(test_effect_preshader_bconsts) ? !test_effect_preshader_bconsts[i] : FALSE;
+ hr = IDirect3DDevice9_SetPixelShaderConstantB(device, i, &bval, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+}
+
+#define test_effect_preshader_compare_pbool_consts(a, b, c) \
+ test_effect_preshader_compare_pbool_consts_(__LINE__, a, b, c)
+static void test_effect_preshader_compare_pbool_consts_(unsigned int line, IDirect3DDevice9 *device,
+ const unsigned int *const_updated_mask, const char *updated_param)
+{
+ unsigned int i;
+ BOOL bdata[16];
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_GetPixelShaderConstantB(device, 0, bdata, ARRAY_SIZE(bdata));
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ if (!const_updated_mask)
+ {
+ for (i = 0; i < ARRAY_SIZE(test_effect_preshader_bconsts); ++i)
+ {
+ /* The negation on both sides is actually needed, sometimes you
+ * get 0xffffffff instead of 1 on native. */
+ ok_(__FILE__, line)(!bdata[i] == !test_effect_preshader_bconsts[i],
+ "Pixel shader boolean constants do not match, expected %#x, got %#x, i %u.\n",
+ test_effect_preshader_bconsts[i], bdata[i], i);
+ }
+ }
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE(test_effect_preshader_bconsts); ++i)
+ {
+ if (const_updated_mask[i / TEST_EFFECT_BITMASK_BLOCK_SIZE]
+ & (1u << (i % TEST_EFFECT_BITMASK_BLOCK_SIZE)))
+ {
+ /* The negation on both sides is actually needed, sometimes
+ * you get 0xffffffff instead of 1 on native. */
+ ok_(__FILE__, line)(!bdata[i] == !test_effect_preshader_bconsts[i],
+ "Pixel shader boolean constants do not match, expected %#x, got %#x, i %u, parameter %s.\n",
+ test_effect_preshader_bconsts[i], bdata[i], i, updated_param);
+ }
+ else
+ {
+ ok_(__FILE__, line)(bdata[i] == !test_effect_preshader_bconsts[i],
+ "Pixel shader boolean constants updated unexpectedly, parameter %s.\n", updated_param);
+ }
+ }
+ }
+
+ for (; i < 16; ++i)
+ {
+ ok_(__FILE__, line)(!bdata[i], "Got result %#x, boolean register value %u.\n", hr, bdata[i]);
+ }
+}
+
+static void test_effect_preshader(IDirect3DDevice9 *device)
+{
+ static const D3DXVECTOR4 test_effect_preshader_fvect_p[] =
+ {
+ {11.0f, 21.0f, 0.0f, 0.0f},
+ {12.0f, 22.0f, 0.0f, 0.0f},
+ {13.0f, 23.0f, 0.0f, 0.0f},
+ {11.0f, 12.0f, 0.0f, 0.0f},
+ {21.0f, 22.0f, 0.0f, 0.0f},
+ {31.0f, 32.0f, 0.0f, 0.0f},
+ {11.0f, 12.0f, 0.0f, 0.0f},
+ {21.0f, 22.0f, 0.0f, 0.0f},
+ {11.0f, 21.0f, 0.0f, 0.0f},
+ {12.0f, 22.0f, 0.0f, 0.0f},
+ {11.0f, 12.0f, 13.0f, 0.0f},
+ {21.0f, 22.0f, 23.0f, 0.0f},
+ {11.0f, 21.0f, 31.0f, 0.0f},
+ {12.0f, 22.0f, 32.0f, 0.0f}
+ };
+ static const int test_effect_preshader_iconsts[][4] =
+ {
+ {4, 3, 2, 1}
+ };
+ static const D3DXVECTOR4 fvect1 = {28.0f, 29.0f, 30.0f, 31.0f};
+ static const D3DXVECTOR4 fvect2 = {0.0f, 0.0f, 1.0f, 0.0f};
+ static const int ivect_empty[4] = {-1, -1, -1, -1};
+ HRESULT hr;
+ ID3DXEffect *effect;
+ D3DXHANDLE par;
+ unsigned int npasses;
+ DWORD value;
+ D3DXVECTOR4 fdata[ARRAY_SIZE(test_effect_preshader_fvect_p)];
+ int idata[ARRAY_SIZE(test_effect_preshader_iconsts)][4];
+ IDirect3DVertexShader9 *vshader;
+ unsigned int i;
+ D3DCAPS9 caps;
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
+ || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ {
+ skip("Test requires VS >= 3 and PS >= 3, skipping.\n");
+ return;
+ }
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_clear_vconsts(device);
+
+ for (i = 0; i < 224; ++i)
+ {
+ hr = IDirect3DDevice9_SetPixelShaderConstantF(device, i, &fvect_filler.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+
+ test_effect_preshader_clear_pbool_consts(device);
+
+ for (i = 0; i < 16; ++i)
+ {
+ hr = IDirect3DDevice9_SetPixelShaderConstantI(device, i, ivect_empty, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+
+ hr = effect->lpVtbl->Begin(effect, &npasses, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ par = effect->lpVtbl->GetParameterByName(effect, NULL, "g_Pos2");
+ ok(par != NULL, "GetParameterByName failed.\n");
+
+ hr = effect->lpVtbl->SetVector(effect, par, &fvect1);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_vconsts(device, NULL, NULL);
+
+ hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, &fdata[0].x,
+ ARRAY_SIZE(test_effect_preshader_fvect_p));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!memcmp(fdata, test_effect_preshader_fvect_p, sizeof(test_effect_preshader_fvect_p)),
+ "Pixel shader float constants do not match.\n");
+ for (i = ARRAY_SIZE(test_effect_preshader_fvect_p); i < 224; ++i)
+ {
+ hr = IDirect3DDevice9_GetPixelShaderConstantF(device, i, &fdata[0].x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!memcmp(fdata, &fvect_filler, sizeof(fvect_filler)),
+ "Pixel shader float constants do not match.\n");
+ }
+ hr = IDirect3DDevice9_GetPixelShaderConstantI(device, 0, idata[0],
+ ARRAY_SIZE(test_effect_preshader_iconsts));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!memcmp(idata, test_effect_preshader_iconsts, sizeof(test_effect_preshader_iconsts)),
+ "Pixel shader integer constants do not match.\n");
+ for (i = ARRAY_SIZE(test_effect_preshader_iconsts); i < 16; ++i)
+ {
+ hr = IDirect3DDevice9_GetPixelShaderConstantI(device, i, idata[0], 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!memcmp(idata[0], ivect_empty, sizeof(ivect_empty)),
+ "Pixel shader integer constants do not match.\n");
+ }
+
+ test_effect_preshader_compare_pbool_consts(device, NULL, NULL);
+
+ test_effect_preshader_op_results(device, NULL, NULL);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 3, "Unexpected sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine ok(value == 3, "Unexpected sampler 0 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, 1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected sampler 1 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 1, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 1, "Unexpected sampler 1 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected vertex sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 1, "Unexpected vertex sampler 0 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 0, "Unexpected vertex sampler 1 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 0, "Unexpected vertex sampler 1 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 3, "Unexpected vertex sampler 2 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine ok(value == 3, "Unexpected vertex sampler 2 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGDENSITY, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected fog density %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGSTART, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 4.0f, "Unexpected fog start %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_A, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 4.0f, "Unexpected point scale A %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_B, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 12.0f, "Unexpected point scale B %g.\n", *(float *)&value);
+
+ hr = effect->lpVtbl->EndPass(effect);
+
+ par = effect->lpVtbl->GetParameterByName(effect, NULL, "g_iVect");
+ ok(par != NULL, "GetParameterByName failed.\n");
+ hr = effect->lpVtbl->SetVector(effect, par, &fvect2);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->SetVector(effect, par, &fvect1);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Incorrect shader selected.\n");
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &npasses, D3DXFX_DONOTSAVESTATE);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 3, "Unexpected sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine ok(value == 3, "Unexpected sampler 0 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, 1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected sampler 1 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 1, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 1, "Unexpected sampler 1 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected vertex sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 1, "Unexpected vertex sampler 0 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 2, "Unexpected vertex sampler 1 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 2, "Unexpected vertex sampler 1 magfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 3, "Unexpected vertex sampler 2 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 3, "Unexpected vertex sampler 2 magfilter %u.\n", value);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect->lpVtbl->Release(effect);
+}
+
+/*
+ * fxc.exe /Tfx_2_0
+ */
+#if 0
+float4 opvect1;
+float4 opvect2;
+float4 opvect3;
+
+technique tech0
+{
+ pass p0
+ {
+ LightEnable[0] = TRUE;
+ LightEnable[1] = TRUE;
+ LightEnable[2] = TRUE;
+ LightEnable[3] = TRUE;
+ LightEnable[4] = TRUE;
+ LightEnable[5] = TRUE;
+ LightEnable[6] = TRUE;
+ LightEnable[7] = TRUE;
+ LightType[0] = POINT;
+ LightType[1] = POINT;
+ LightType[2] = POINT;
+ LightType[3] = POINT;
+ LightType[4] = POINT;
+ LightType[5] = POINT;
+ LightType[6] = POINT;
+ LightType[7] = POINT;
+
+ LightDiffuse[0] = exp(opvect1);
+ LightDiffuse[1] = log(opvect1);
+ LightDiffuse[2] = asin(opvect1);
+ LightDiffuse[3] = acos(opvect1);
+ LightDiffuse[4] = atan(opvect1);
+ LightDiffuse[5] = atan2(opvect1, opvect2);
+ LightDiffuse[6] = opvect1 * opvect2;
+
+ /* Placeholder for 'div' instruction manually edited in binary blob. */
+ LightDiffuse[7] = opvect1 * opvect2;
+
+ /* Placeholder for 'cmp' instruction manually edited in binary blob. */
+ LightAmbient[0] = opvect1 + opvect2 + opvect3;
+ }
+}
+#endif
+static const DWORD test_effect_preshader_ops_blob[] =
+{
+ 0xfeff0901, 0x0000044c, 0x00000000, 0x00000003, 0x00000001, 0x00000030, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x6576706f,
+ 0x00317463, 0x00000003, 0x00000001, 0x00000068, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x6576706f, 0x00327463, 0x00000003,
+ 0x00000001, 0x000000a0, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000008, 0x6576706f, 0x00337463, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000002, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000001,
+ 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000030, 0x00000003, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000004, 0x00000020, 0x00000000, 0x00000000, 0x0000003c, 0x00000058, 0x00000000,
+ 0x00000000, 0x00000074, 0x00000090, 0x00000000, 0x00000000, 0x00000440, 0x00000000, 0x00000001,
+ 0x00000438, 0x00000000, 0x00000019, 0x00000091, 0x00000000, 0x000000b0, 0x000000ac, 0x00000091,
+ 0x00000001, 0x000000d0, 0x000000cc, 0x00000091, 0x00000002, 0x000000f0, 0x000000ec, 0x00000091,
+ 0x00000003, 0x00000110, 0x0000010c, 0x00000091, 0x00000004, 0x00000130, 0x0000012c, 0x00000091,
+ 0x00000005, 0x00000150, 0x0000014c, 0x00000091, 0x00000006, 0x00000170, 0x0000016c, 0x00000091,
+ 0x00000007, 0x00000190, 0x0000018c, 0x00000084, 0x00000000, 0x000001b0, 0x000001ac, 0x00000084,
+ 0x00000001, 0x000001d0, 0x000001cc, 0x00000084, 0x00000002, 0x000001f0, 0x000001ec, 0x00000084,
+ 0x00000003, 0x00000210, 0x0000020c, 0x00000084, 0x00000004, 0x00000230, 0x0000022c, 0x00000084,
+ 0x00000005, 0x00000250, 0x0000024c, 0x00000084, 0x00000006, 0x00000270, 0x0000026c, 0x00000084,
+ 0x00000007, 0x00000290, 0x0000028c, 0x00000085, 0x00000000, 0x000002bc, 0x000002ac, 0x00000085,
+ 0x00000001, 0x000002e8, 0x000002d8, 0x00000085, 0x00000002, 0x00000314, 0x00000304, 0x00000085,
+ 0x00000003, 0x00000340, 0x00000330, 0x00000085, 0x00000004, 0x0000036c, 0x0000035c, 0x00000085,
+ 0x00000005, 0x00000398, 0x00000388, 0x00000085, 0x00000006, 0x000003c4, 0x000003b4, 0x00000085,
+ 0x00000007, 0x000003f0, 0x000003e0, 0x00000087, 0x00000000, 0x0000041c, 0x0000040c, 0x00000000,
+ 0x00000009, 0x00000000, 0x00000000, 0xffffffff, 0x00000018, 0x00000000, 0x0000016c, 0x46580200,
+ 0x003afffe, 0x42415443, 0x0000001c, 0x000000b3, 0x46580200, 0x00000003, 0x0000001c, 0x20000100,
+ 0x000000b0, 0x00000058, 0x00000002, 0x00000001, 0x00000060, 0x00000070, 0x00000080, 0x00010002,
+ 0x00000001, 0x00000088, 0x00000070, 0x00000098, 0x00020002, 0x00000001, 0x000000a0, 0x00000070,
+ 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x6576706f, 0x00337463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ /* FXLC for LightAmbient[0] start. */
+ 0x001afffe, 0x434c5846,
+ 0x00000001, /* Instruction count, set to 1. */
+ 0x30000004, /* Operation code (bits 20-30) set to 'cmp' opcode 0x300. */
+ 0x00000003, /* Input arguments count set to 3. */
+ /* Argument 1. */
+ 0x00000000, /* Relative addressing flag. */
+ 0x00000002, /* Register table ("c", float constants). */
+ 0x00000000, /* Register offset. */
+ /* Argument 2. */
+ 0x00000000, 0x00000002, 0x00000004,
+ /* Argument 3. */
+ 0x00000000, 0x00000002, 0x00000008,
+ /* Output register. */
+ 0x00000000, 0x00000004, 0x00000000,
+ /* End mark. */
+ 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ /* Padding to match placeholder length. */
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ /* FXLC for LightAmbient[0] end. */
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000017, 0x00000000, 0x00000114,
+ 0x46580200, 0x002ffffe, 0x42415443, 0x0000001c, 0x00000087, 0x46580200, 0x00000002, 0x0000001c,
+ 0x20000100, 0x00000084, 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c,
+ 0x00010002, 0x00000001, 0x00000074, 0x0000005c, 0x6576706f, 0x00317463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6576706f, 0x00327463,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820,
+ 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235,
+ 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ /* FXLC for LightDiffuse[7] start. */
+ 0x000ffffe, 0x434c5846,
+ 0x00000001, /* Instruction count. */
+ 0x20800004, /* Operation code (bits 20-30) set to 'div' opcode 0x208. */
+ 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x00000000,
+ 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ /* FXLC for LightDiffuse[7] end. */
+ 0x00000000, 0x00000000, 0xffffffff,
+ 0x00000016, 0x00000000, 0x00000114, 0x46580200, 0x002ffffe, 0x42415443, 0x0000001c, 0x00000087,
+ 0x46580200, 0x00000002, 0x0000001c, 0x20000100, 0x00000084, 0x00000044, 0x00000002, 0x00000001,
+ 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002, 0x00000001, 0x00000074, 0x0000005c, 0x6576706f,
+ 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x6576706f, 0x00327463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000ffffe,
+ 0x434c5846, 0x00000001, 0x20500004, 0x00000002, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000015, 0x00000000, 0x00000114, 0x46580200, 0x002ffffe,
+ 0x42415443, 0x0000001c, 0x00000087, 0x46580200, 0x00000002, 0x0000001c, 0x20000100, 0x00000084,
+ 0x00000044, 0x00000002, 0x00000001, 0x0000004c, 0x0000005c, 0x0000006c, 0x00010002, 0x00000001,
+ 0x00000074, 0x0000005c, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6576706f, 0x00327463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000ffffe, 0x434c5846, 0x00000001, 0x20600004, 0x00000002, 0x00000000,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000,
+ 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000014, 0x00000000,
+ 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001,
+ 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048,
+ 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10c00004, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000013, 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe,
+ 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058,
+ 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463, 0x00030001,
+ 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe,
+ 0x434c5846, 0x00000001, 0x10b00004, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff,
+ 0x00000012, 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b,
+ 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001,
+ 0x00000038, 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820,
+ 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235,
+ 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10a00004,
+ 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0,
+ 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000011, 0x00000000, 0x0000013c,
+ 0x46580200, 0x0024fffe, 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c,
+ 0x20000100, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f,
+ 0x00317463, 0x00030001, 0x00040001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+ 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43,
+ 0x00000000, 0x0024fffe, 0x434c5846, 0x00000004, 0x10600001, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x10600001, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000001, 0x00000000, 0x00000004, 0x00000001, 0x10600001, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000002, 0x00000000, 0x00000004, 0x00000002, 0x10600001, 0x00000001, 0x00000000, 0x00000002,
+ 0x00000003, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000010, 0x00000000, 0x0000013c, 0x46580200, 0x0024fffe, 0x42415443,
+ 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058, 0x00000030,
+ 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x6576706f, 0x00317463, 0x00030001, 0x00040001,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x0024fffe, 0x434c5846,
+ 0x00000004, 0x10500001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000000, 0x10500001, 0x00000001, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000004,
+ 0x00000001, 0x10500001, 0x00000001, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000004,
+ 0x00000002, 0x10500001, 0x00000001, 0x00000000, 0x00000002, 0x00000003, 0x00000000, 0x00000004,
+ 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+};
+
+static void test_effect_preshader_ops(IDirect3DDevice9 *device)
+{
+ static D3DLIGHT9 light;
+ const struct
+ {
+ const char *mnem;
+ unsigned int expected_result[4];
+ unsigned int result_index;
+ float *result;
+ D3DXVECTOR4 opvect1, opvect2, opvect3;
+ unsigned int ulps;
+ BOOL todo[4];
+ }
+ op_tests[] =
+ {
+ {"exp", {0x3f800000, 0x3f800000, 0x3e5edc66, 0x7f800000}, 0, &light.Diffuse.r,
+ {0.0f, -0.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}},
+ {"log", {0, 0x40000000, 0x3f9199b7, 0x43000000}, 1, &light.Diffuse.r,
+ {0.0f, 4.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}},
+ {"asin", {0xbe9c00ad, 0xffc00000, 0xffc00000, 0xffc00000}, 2, &light.Diffuse.r,
+ {-0.3f, 4.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}},
+ {"acos", {0x3ff01006, 0xffc00000, 0xffc00000, 0xffc00000}, 3, &light.Diffuse.r,
+ {-0.3f, 4.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}},
+ {"atan", {0xbe9539d4, 0x3fa9b465, 0xbf927420, 0x3fc90fdb}, 4, &light.Diffuse.r,
+ {-0.3f, 4.0f, -2.2f, 3.402823466e+38f}, {1.0f, 2.0f, -3.0f, 4.0f}},
+ {"atan2 test #1", {0xbfc90fdb, 0x40490fdb, 0x80000000, 0x7fc00000}, 5, &light.Diffuse.r,
+ {-0.3f, 0.0f, -0.0f, NAN}, {0.0f, -0.0f, 0.0f, 1.0f}},
+ {"atan2 test #2", {0xbfc90fdb, 0, 0xc0490fdb, 0}, 5, &light.Diffuse.r,
+ {-0.3f, 0.0f, -0.0f, -0.0f}, {-0.0f, 0.0f, -0.0f, 1.0f}},
+ {"div", {0, 0, 0, 0}, 7, &light.Diffuse.r,
+ {-0.3f, 0.0f, -2.2f, NAN}, {0.0f, -0.0f, -3.0f, 1.0f}},
+ {"cmp", {0x40a00000, 0x40000000, 0x40400000, 0x41000000}, 0, &light.Ambient.r,
+ {-0.3f, 0.0f, 2.2f, NAN}, {1.0f, 2.0f, 3.0f, 4.0f}, {5.0f, 6.0f, 7.0f, 8.0f}},
+ {"0 * INF", {0xffc00000, 0xffc00000, 0xc0d33334, 0x7f800000}, 6, &light.Diffuse.r,
+ {0.0f, -0.0f, -2.2f, 3.402823466e+38f}, {INFINITY, INFINITY, 3.0f, 4.0f}},
+ };
+ unsigned int i, j, passes_count;
+ ID3DXEffect *effect;
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_ops_blob, sizeof(test_effect_preshader_ops_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(op_tests); ++i)
+ {
+ const float *result = op_tests[i].result;
+ const float *expected_float = (float *)op_tests[i].expected_result;
+
+ hr = effect->lpVtbl->SetVector(effect, "opvect1", &op_tests[i].opvect1);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->SetVector(effect, "opvect2", &op_tests[i].opvect2);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->SetVector(effect, "opvect3", &op_tests[i].opvect3);
+ ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetLight(device, op_tests[i].result_index, &light);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ for (j = 0; j < 4; ++j)
+ {
+ todo_wine_if(op_tests[i].todo[j])
+ ok(compare_float(result[j], expected_float[j], op_tests[i].ulps),
+ "Operation %s, component %u, expected %#x (%.8e), got %#x (%.8e).\n", op_tests[i].mnem,
+ j, op_tests[i].expected_result[j], expected_float[j],
+ ((unsigned int *)result)[j], result[j]);
+ }
+ }
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect->lpVtbl->Release(effect);
+}
+
+static void test_isparameterused_children(unsigned int line, ID3DXEffect *effect,
+ D3DXHANDLE tech, D3DXHANDLE param)
+{
+ D3DXPARAMETER_DESC desc;
+ D3DXHANDLE param_child;
+ unsigned int i, child_count;
+ HRESULT hr;
+
+ hr = effect->lpVtbl->GetParameterDesc(effect, param, &desc);
+ ok_(__FILE__, line)(hr == D3D_OK, "GetParameterDesc failed, result %#x.\n", hr);
+ child_count = desc.Elements ? desc.Elements : desc.StructMembers;
+ for (i = 0; i < child_count; ++i)
+ {
+ param_child = desc.Elements ? effect->lpVtbl->GetParameterElement(effect, param, i)
+ : effect->lpVtbl->GetParameter(effect, param, i);
+ ok_(__FILE__, line)(!!param_child, "Failed getting child parameter %s[%u].\n", desc.Name, i);
+ ok_(__FILE__, line)(!effect->lpVtbl->IsParameterUsed(effect, param_child, tech),
+ "Unexpected IsParameterUsed() result for %s[%u].\n", desc.Name, i);
+ test_isparameterused_children(line, effect, tech, param_child);
+ }
+}
+
+#ifdef __REACTOS__
+#define test_isparameterused_param_with_children(...) \
+ test_isparameterused_param_with_children_(__LINE__, __VA_ARGS__)
+#else
+#define test_isparameterused_param_with_children(args...) \
+ test_isparameterused_param_with_children_(__LINE__, args)
+#endif
+static void test_isparameterused_param_with_children_(unsigned int line, ID3DXEffect *effect,
+ ID3DXEffect *effect2, D3DXHANDLE tech, const char *name, BOOL expected_result)
+{
+ D3DXHANDLE param;
+
+ ok_(__FILE__, line)(effect->lpVtbl->IsParameterUsed(effect, (D3DXHANDLE)name, tech)
+ == expected_result, "Unexpected IsParameterUsed() result for %s (referenced by name).\n", name);
+
+ if (effect2)
+ param = effect2->lpVtbl->GetParameterByName(effect2, NULL, name);
+ else
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, name);
+ ok_(__FILE__, line)(!!param, "GetParameterByName failed for %s.\n", name);
+
+ ok_(__FILE__, line)(effect->lpVtbl->IsParameterUsed(effect, param, tech) == expected_result,
+ "Unexpected IsParameterUsed() result for %s (referenced by handle).\n", name);
+
+ test_isparameterused_children(line, effect, tech, param);
+}
+
+static void test_effect_isparameterused(IDirect3DDevice9 *device)
+{
+ static const struct
+ {
+ const char *name;
+ BOOL expected_result;
+ }
+ check_parameters[] =
+ {
+ {"g_Pos1", TRUE},
+ {"g_Pos2", TRUE},
+ {"g_Selector", TRUE},
+ {"opvect1", TRUE},
+ {"opvect2", TRUE},
+ {"opvect3", TRUE},
+ {"arr2", TRUE},
+ {"vs_arr", TRUE},
+ {"g_iVect", TRUE},
+ {"vect_sampler", TRUE},
+ {"tex1", TRUE},
+ {"tex2", FALSE},
+ {"sampler1", TRUE},
+ {"ts1", TRUE},
+ {"ts2", TRUE},
+ {"ts3", TRUE},
+ };
+ ID3DXEffect *effect, *effect2;
+ HRESULT hr;
+ D3DXHANDLE tech;
+ unsigned int i;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ tech = effect->lpVtbl->GetTechniqueByName(effect, "tech0");
+ ok(!!tech, "GetTechniqueByName failed.\n");
+
+ for (i = 0; i < ARRAY_SIZE(check_parameters); ++i)
+ test_isparameterused_param_with_children(effect, NULL, tech, check_parameters[i].name,
+ check_parameters[i].expected_result);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect2, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(check_parameters); ++i)
+ test_isparameterused_param_with_children(effect, effect2, tech, check_parameters[i].name,
+ check_parameters[i].expected_result);
+
+ effect2->lpVtbl->Release(effect2);
+
+ hr = D3DXCreateEffect(device, test_effect_states_effect_blob, sizeof(test_effect_states_effect_blob),
+ NULL, NULL, 0, NULL, &effect2, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_isparameterused_param_with_children(effect, effect2, tech, "sampler1", TRUE);
+ effect2->lpVtbl->Release(effect2);
+
+ effect->lpVtbl->Release(effect);
+}
+
+static void test_effect_out_of_bounds_selector(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect;
+ HRESULT hr;
+ D3DXHANDLE param;
+ int ivect[4];
+ unsigned int passes_count;
+ IDirect3DVertexShader9 *vshader;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ivect[0] = ivect[1] = ivect[3] = 1;
+
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_iVect");
+ ok(!!param, "GetParameterByName failed.\n");
+ ivect[2] = 3;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+
+ /* Second try reports success and selects array element used previously.
+ * Probably array index is not recomputed and previous index value is used. */
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader(device, 2, FALSE);
+
+ /* Confirm that array element selected is the previous good one and does not depend
+ * on computed (out of bound) index value. */
+ ivect[2] = 1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ivect[2] = 3;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+
+ /* End and begin effect again to ensure it will not trigger array
+ * index recompute and error return from BeginPass. */
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ivect[2] = -2;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ivect[2] = -1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader(device, 0, FALSE);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ivect[2] = 3;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+
+ ivect[2] = -1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+
+ ivect[2] = 1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader(device, 1, FALSE);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+}
+
+static void test_effect_commitchanges(IDirect3DDevice9 *device)
+{
+ static const struct
+ {
+ const char *param_name;
+ enum expected_state_update state_updated[ARRAY_SIZE(test_effect_preshader_op_expected)];
+ }
+ check_op_parameters[] =
+ {
+ {"opvect1", {EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_ANYTHING,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED}},
+ {"opvect2", {EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_ANYTHING,
+ EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED, EXPECTED_STATE_UPDATED}},
+ {"opvect3", {EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO,
+ EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_UPDATED,
+ EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO,
+ EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ANYTHING,
+ EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO, EXPECTED_STATE_ZERO}},
+ };
+ static const struct
+ {
+ const char *param_name;
+ const unsigned int const_updated_mask[(ARRAY_SIZE(test_effect_preshader_fvect_v)
+ + TEST_EFFECT_BITMASK_BLOCK_SIZE - 1) / TEST_EFFECT_BITMASK_BLOCK_SIZE];
+ }
+ check_vconsts_parameters[] =
+ {
+ {"g_Selector", {0x00000000, 0x00000002}},
+ {"g_Pos1", {0x80000000, 0x00000002}},
+ {"g_Pos2", {0x00000000, 0x00000002}},
+ {"m4x3column", {0x03800000, 0x00000000}},
+ {"m3x4column", {0x000f0000, 0x00000000}},
+ {"m4x3row", {0x0000f000, 0x00000000}},
+ {"m3x4row", {0x00700000, 0x00000000}},
+ {"ts1", {0x1c000000, 0x00000000}},
+ {"ts2", {0x0000003f, 0x00000000}},
+ {"arr1", {0x00000000, 0x00000001}},
+ {"arr2", {0x60000000, 0x00000000}},
+ {"ts3", {0x00000fc0, 0x00000000}},
+ };
+ static const struct
+ {
+ const char *param_name;
+ const unsigned int const_updated_mask[(ARRAY_SIZE(test_effect_preshader_bconsts)
+ + TEST_EFFECT_BITMASK_BLOCK_SIZE - 1) / TEST_EFFECT_BITMASK_BLOCK_SIZE];
+ }
+ check_bconsts_parameters[] =
+ {
+ {"mb2x3row", {0x0000001f}},
+ {"mb2x3column", {0x00000060}},
+ };
+ static const unsigned int const_no_update_mask[(ARRAY_SIZE(test_effect_preshader_fvect_v)
+ + TEST_EFFECT_BITMASK_BLOCK_SIZE - 1) / TEST_EFFECT_BITMASK_BLOCK_SIZE];
+ static const D3DLIGHT9 light_filler = {D3DLIGHT_POINT};
+
+ ID3DXEffect *effect;
+ HRESULT hr;
+ D3DXHANDLE param;
+ unsigned int i, passes_count, value;
+ int ivect[4];
+ D3DXVECTOR4 fvect;
+ IDirect3DVertexShader9 *vshader;
+ unsigned char buffer[256];
+
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_iVect");
+ ok(!!param, "GetParameterByName failed.\n");
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(check_op_parameters); ++i)
+ {
+ unsigned int j;
+
+ for (j = 0; j < 8; ++j)
+ {
+ hr = IDirect3DDevice9_SetLight(device, j, &light_filler);
+ ok(hr == D3D_OK, "Got result %#x, i %u, j %u.\n", hr, i, j);
+ }
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, check_op_parameters[i].param_name);
+ ok(!!param, "Failed to get parameter (test %u).\n", i);
+ hr = effect->lpVtbl->GetValue(effect, param, &fvect, sizeof(fvect));
+ ok(hr == D3D_OK, "Failed to get parameter value, hr %#x (test %u).\n", hr, i);
+ hr = effect->lpVtbl->SetValue(effect, param, &fvect, sizeof(fvect));
+ ok(hr == D3D_OK, "Failed to set parameter value, hr %#x (test %u).\n", hr, i);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Failed to commit changes, hr %#x (test %u).\n", hr, i);
+
+ test_effect_preshader_op_results(device, check_op_parameters[i].state_updated,
+ check_op_parameters[i].param_name);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(check_vconsts_parameters); ++i)
+ {
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, check_vconsts_parameters[i].param_name);
+ ok(!!param, "GetParameterByName failed.\n");
+ hr = effect->lpVtbl->GetValue(effect, param, buffer, sizeof(buffer));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, param, buffer, sizeof(buffer));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[i].const_updated_mask,
+ check_vconsts_parameters[i].param_name);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(check_bconsts_parameters); ++i)
+ {
+ test_effect_preshader_clear_pbool_consts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, check_bconsts_parameters[i].param_name);
+ ok(!!param, "GetParameterByName failed.\n");
+ hr = effect->lpVtbl->GetValue(effect, param, buffer, sizeof(buffer));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, param, buffer, sizeof(buffer));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_pbool_consts(device, check_bconsts_parameters[i].const_updated_mask,
+ check_bconsts_parameters[i].param_name);
+ }
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_Selector");
+ ok(!!param, "GetParameterByName failed.\n");
+ fvect.x = fvect.y = fvect.z = fvect.w = 0.0f;
+ hr = effect->lpVtbl->SetVectorArray(effect, param, &fvect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[0].const_updated_mask,
+ check_vconsts_parameters[0].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 0);
+ ok(!!param, "GetParameterElement failed.\n");
+ hr = effect->lpVtbl->SetFloat(effect, param, 92.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, const_no_update_mask,
+ check_vconsts_parameters[10].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 1);
+ ok(!!param, "GetParameterElement failed.\n");
+ fvect.x = 93.0f;
+ hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(fvect.x));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[10].const_updated_mask,
+ check_vconsts_parameters[10].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ fvect.x = 92.0f;
+ hr = effect->lpVtbl->SetFloatArray(effect, param, &fvect.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[10].const_updated_mask,
+ check_vconsts_parameters[10].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 1);
+ ok(!!param, "GetParameterElement failed.\n");
+ hr = effect->lpVtbl->SetInt(effect, param, 93);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, const_no_update_mask,
+ check_vconsts_parameters[10].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_Pos1");
+ ok(!!param, "GetParameterByName failed.\n");
+ fvect.x = fvect.y = fvect.z = fvect.w = 0.0f;
+ hr = effect->lpVtbl->SetVector(effect, param, &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[1].const_updated_mask,
+ check_vconsts_parameters[1].param_name);
+
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "ts1");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 0);
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterByName(effect, param, "fv");
+ ok(!!param, "GetParameterByName failed.\n");
+ fvect.x = 12;
+ hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(float));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[7].const_updated_mask,
+ check_vconsts_parameters[7].param_name);
+
+ *(float *)&value = 9999.0f;
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "ts2");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 0);
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterByName(effect, param, "v1");
+ ok(!!param, "GetParameterByName failed.\n");
+ hr = effect->lpVtbl->GetValue(effect, param, &fvect, sizeof(float) * 3);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, param, &fvect, sizeof(float) * 3);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGDENSITY, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected fog density %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGSTART, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 4.0f, "Unexpected fog start %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_A, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 9999.0f, "Unexpected point scale A %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_B, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 9999.0f, "Unexpected point scale B %g.\n", *(float *)&value);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[8].const_updated_mask,
+ check_vconsts_parameters[8].param_name);
+
+ *(float *)&value = 9999.0f;
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_clear_vconsts(device);
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "ts3");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterByName(effect, param, "ts");
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterElement(effect, param, 1);
+ ok(!!param, "GetParameterByName failed.\n");
+ param = effect->lpVtbl->GetParameterByName(effect, param, "fv");
+ ok(!!param, "GetParameterByName failed.\n");
+ hr = effect->lpVtbl->GetValue(effect, param, &fvect.x, sizeof(float));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(float));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGDENSITY, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 9999.0f, "Unexpected fog density %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGSTART, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 9999.0f, "Unexpected fog start %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_A, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 4.0f, "Unexpected point scale A %g.\n", *(float *)&value);
+ hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSCALE_B, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(*(float *)&value == 12.0f, "Unexpected point scale B %g.\n", *(float *)&value);
+ test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[11].const_updated_mask,
+ check_vconsts_parameters[11].param_name);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(value == 0, "Unexpected sampler 1 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 3, "Unexpected sampler 2 minfilter %u.\n", value);
+
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_iVect");
+ ok(!!param, "GetParameterByName failed.\n");
+ ivect[0] = ivect[1] = ivect[2] = ivect[3] = 1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ for (i = 0; i < 3; ++i)
+ {
+ hr = IDirect3DDevice9_SetSamplerState(device, D3DVERTEXTEXTURESAMPLER0 + i, D3DSAMP_MINFILTER, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, D3DVERTEXTEXTURESAMPLER0 + i, D3DSAMP_MAGFILTER, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetVertexShader(device, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_clear_vconsts(device);
+
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+ test_effect_preshader_compare_vconsts(device, const_no_update_mask,
+ "selector g_iVect");
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER1, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected sampler 1 minfilter %u.\n", value);
+
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected sampler 2 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, D3DVERTEXTEXTURESAMPLER2, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected sampler 2 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MINFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 1, "Unexpected sampler 0 minfilter %u.\n", value);
+ hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_MAGFILTER, &value);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(value == 0, "Unexpected sampler 0 minfilter %u.\n", value);
+
+ ivect[3] = 2;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ivect[3] = 1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+ test_effect_preshader_compare_vconsts(device, const_no_update_mask,
+ "selector g_iVect");
+ ivect[3] = 2;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!!vshader, "Got NULL vshader.\n");
+ IDirect3DVertexShader9_Release(vshader);
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, &fvect.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(fvect.x == 0.0f && fvect.y == 0.0f && fvect.z == 0.0f && fvect.w == 0.0f,
+ "Vertex shader float constants do not match.\n");
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &fvect_filler.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, const_no_update_mask,
+ "selector g_iVect");
+ ivect[3] = 1;
+ hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_vconsts(device, NULL, NULL);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+}
+
+static void test_effect_preshader_relative_addressing(IDirect3DDevice9 *device)
+{
+ static const struct
+ {
+ D3DXVECTOR4 opvect2;
+ D3DXVECTOR4 g_ivect;
+ unsigned int expected[4];
+ }
+ test_out_of_bounds_index[] =
+ {
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {101.0f, 101.0f, 101.0f, 101.0f}, {0, 0x42ca0000, 0x3f800000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {3333.0f, 1094.0f, 2222.0f, 3333.0f},
+ {0x447ac000, 0x45505000, 0x3f800000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {3333.0f, 1094.0f, 2222.0f, 1.0f},
+ {0x447ac000, 0x3f800000, 0x447a8000, 0x453b9000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {1.0f, 1094.0f, 2222.0f, 3333.0f},
+ {0x447ac000, 0x45505000, 0x3f800000, 0x453ba000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {1111.0f, 1094.0f, 2222.0f, 1111.0f},
+ {0x447ac000, 0x448ae000, 0, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {1111.0f, 1094.0f, 2222.0f, 3333.0f},
+ {0x447ac000, 0x45505000, 0x3f800000, 0}},
+ {{-1111.0f, 1094.0f, -2222.0f, -3333.0f}, {4.0f, 3.0f, 2.0f, 1.0f},
+ {0x447ac000, 0x40800000, 0x447a8000, 0x453b9000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-1.0f, -1.0f, -1.0f, -1.0f}, {0, 0xbf800000, 0, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-2.0f, -2.0f, -2.0f, -2.0f}, {0, 0xc0000000, 0x459c4800, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-3.0f, -3.0f, -3.0f, -3.0f}, {0, 0xc0400000, 0x453b9000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-4.0f, -4.0f, -4.0f, -4.0f}, {0, 0xc0800000, 0x44fa2000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-5.0f, -5.0f, -5.0f, -5.0f}, {0, 0xc0a00000, 0x459c5000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-6.0f, -6.0f, -6.0f, -6.0f}, {0, 0xc0c00000, 0x453ba000, 0xc1400000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-7.0f, -7.0f, -7.0f, -7.0f}, {0, 0xc0e00000, 0x44fa4000, 0x40400000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-8.0f, -8.0f, -8.0f, -8.0f}, {0, 0xc1000000, 0, 0x44fa6000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-9.0f, -9.0f, -9.0f, -9.0f}, {0, 0xc1100000, 0, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-10.0f, -10.0f, -10.0f, -10.0f}, {0, 0xc1200000, 0xc1200000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-11.0f, -11.0f, -11.0f, -11.0f}, {0, 0xc1300000, 0x3f800000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-12.0f, -12.0f, -12.0f, -12.0f}, {0, 0xc1400000, 0x447a4000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {5.0f, 5.0f, 5.0f, 5.0f}, {0, 0x40a00000, 0x3f800000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-1111.0f, 1094.0f, -2222.0f, -3333.0f},
+ {0x447ac000, 0xc5505000, 0x459c5000, 0x40000000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-3333.0f, 1094.0f, -2222.0f, -1111.0f},
+ {0x447ac000, 0xc48ae000, 0x44fa4000, 0x3f800000}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-3333.0f, 1094.0f, -2222.0f, -3333.0f},
+ {0x447ac000, 0xc5505000, 0x459c5000, 0}},
+ {{1.0f, 2.0f, 3.0f, 4.0f}, {-1111.0f, 1094.0f, -2222.0f, -1111.0f},
+ {0x447ac000, 0xc48ae000, 0x44fa4000, 0x40400000}},
+ };
+ static const struct
+ {
+ unsigned int zw[2];
+ }
+ expected_light_specular[] =
+ {
+ {{0, 0x44fa2000}},
+ {{0x447a8000, 0x453b9000}},
+ {{0x40000000, 0x459c4800}},
+ {{0xbf800000, 0}},
+ {{0x447a4000, 0}},
+ {{0x3f800000, 0}},
+ {{0xbf800000, 0}},
+ {{0, 0}},
+ {{0, 0x447a4000}},
+ {{0x44fa4000, 0x3f800000}},
+ {{0x453ba000, 0xbf800000}},
+ {{0x459c5000, 0}},
+ {{0x44fa2000, 0}},
+ {{0x453b9000, 0}},
+ {{0x459c4800, 0}},
+ {{0, 0}},
+ };
+ static const struct
+ {
+ int index_value;
+ unsigned int expected[4];
+ }
+ test_index_to_immediate_table[] =
+ {
+ {-1000000, {0, 0x40800000, 0x45bbd800, 0x41300000}},
+ {-1001, {0x448d4000, 0x41300000, 0, 0}},
+ {-32, {0x448d4000, 0x40800000, 0, 0}},
+ {-31, {0x45843000, 0x41400000, 0, 0}},
+ {-30, {0x46a64000, 0x41400000, 0x447a4000, 0x3f800000}},
+ {-29, {0, 0x447a4000, 0x447a8000, 0x40000000}},
+ {-28, {0, 0, 0x447ac000, 0x40400000}},
+ {-27, {0, 0x3f800000, 0, 0}},
+ {-26, {0, 0x41100000, 0x45bbd800, 0x41300000}},
+ {-25, {0, 0x41300000, 0, 0}},
+ {-24, {0, 0x41600000, 0, 0}},
+ {-23, {0, 0, 0, 0}},
+ {-22, {0, 0, 0, 0}},
+ {-21, {0, 0x40a00000, 0, 0}},
+ {-20, {0, 0x41500000, 0, 0}},
+ {-19, {0, 0x41500000, 0, 0}},
+ {-18, {0, 0xc1900000, 0, 0}},
+ {-17, {0, 0, 0, 0}},
+ {-16, {0, 0x40800000, 0, 0}},
+ {-15, {0, 0x41400000, 0, 0}},
+ {-14, {0, 0x41400000, 0, 0}},
+ {-13, {0, 0x447a4000, 0x447a4000, 0x3f800000}},
+ {-12, {0, 0, 0, 0}},
+ {-11, {0, 0x3f800000, 0, 0}},
+ {-10, {0, 0x41100000, 0, 0}},
+ {-9, {0, 0x41300000, 0, 0}},
+ {-8, {0, 0x41600000, 0, 0}},
+ {-7, {0, 0, 0, 0}},
+ {-6, {0, 0, 0, 0}},
+ {-5, {0, 0x40a00000, 0, 0}},
+ {-4, {0, 0x41500000, 0, 0}},
+ {-3, {0, 0x41500000, 0, 0}},
+ {-2, {0, 0xc0000000, 0, 0}},
+ {-1, {0, 0, 0, 0}},
+ {0, {0x45052000, 0x40800000, 0x447a4000, 0x3f800000}},
+ {1, {0x467e6000, 0x41400000, 0x447a8000, 0x40000000}},
+ {2, {0, 0x41400000, 0x447ac000, 0x40400000}},
+ {3, {0, 0x447a4000, 0, 0}},
+ {4, {0, 0, 0x45bbd800, 0x41300000}},
+ {5, {0, 0x3f800000, 0, 0}},
+ {6, {0, 0x41100000, 0, 0}},
+ {7, {0, 0x41300000, 0, 0}},
+ {8, {0, 0x41600000, 0, 0}},
+ {9, {0, 0, 0, 0}},
+ {10, {0, 0, 0, 0}},
+ {11, {0, 0x40a00000, 0, 0}},
+ {12, {0, 0x41500000, 0, 0}},
+ {13, {0, 0x41500000, 0, 0}},
+ {14, {0, 0x41600000, 0, 0}},
+ {15, {0, 0, 0, 0}},
+ {16, {0, 0x40800000, 0, 0}},
+ {17, {0x45052000, 0x41400000, 0x447a4000, 0x3f800000}},
+ {18, {0x467e6000, 0x41400000, 0x447a8000, 0x40000000}},
+ {19, {0, 0x447a4000, 0x447ac000, 0x40400000}},
+ {20, {0, 0, 0, 0}},
+ {21, {0, 0x3f800000, 0x45bbd800, 0x41300000}},
+ {22, {0, 0x41100000, 0, 0}},
+ {23, {0, 0x41300000, 0, 0}},
+ {24, {0, 0x41600000, 0, 0}},
+ {25, {0, 0, 0, 0}},
+ {26, {0, 0, 0, 0}},
+ {27, {0, 0x40a00000, 0, 0}},
+ {28, {0, 0x41500000, 0, 0}},
+ {29, {0, 0x41500000, 0, 0}},
+ {30, {0, 0x41f00000, 0, 0}},
+ {31, {0, 0, 0, 0}},
+ {1001, {0, 0, 0, 0}},
+ {1000000, {0, 0x40800000, 0, 0}},
+ };
+ static const D3DLIGHT9 light_filler = {D3DLIGHT_POINT, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f},
+ {1.0f, 1.0f, 1.0f, 1.0f}};
+ unsigned int j, passes_count;
+ const unsigned int *expected;
+ const float *expected_float;
+ ID3DXEffect *effect;
+ D3DXVECTOR4 fvect;
+ D3DLIGHT9 light;
+ const float *v;
+ HRESULT hr;
+ int i;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 1001.0f; fvect.y = 1002.0f; fvect.z = 1003.0f; fvect.w = 1004.0f;
+ hr = effect->lpVtbl->SetVector(effect, "opvect1", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 2001.0f; fvect.y = 2002.0f; fvect.z = 2003.0f; fvect.w = 2004.0f;
+ hr = effect->lpVtbl->SetVector(effect, "g_Selector[0]", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 3001.0f; fvect.y = 3002.0f; fvect.z = 3003.0f; fvect.w = 3004.0f;
+ hr = effect->lpVtbl->SetVector(effect, "g_Selector[1]", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ v = &light.Specular.r;
+ for (i = 0; i < ARRAY_SIZE(test_out_of_bounds_index); ++i)
+ {
+ hr = effect->lpVtbl->SetVector(effect, "opvect2", &test_out_of_bounds_index[i].opvect2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &test_out_of_bounds_index[i].g_ivect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetLight(device, 1, &light_filler);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetLight(device, 1, &light);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ expected = test_out_of_bounds_index[i].expected;
+ expected_float = (const float *)expected;
+
+ for (j = 0; j < 4; ++j)
+ {
+ ok(compare_float(v[j], expected_float[j], 0),
+ "Test %d, component %u, expected %#x (%g), got %#x (%g).\n",
+ i, j, expected[j], expected_float[j], ((const unsigned int *)v)[j], v[j]);
+ }
+ }
+
+ hr = effect->lpVtbl->SetVector(effect, "opvect2", &test_out_of_bounds_index[7].opvect2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &test_out_of_bounds_index[7].g_ivect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_SetLight(device, 1, &light_filler);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect = test_out_of_bounds_index[7].g_ivect;
+ v = &light.Specular.b;
+ for (i = -100; i < 100; ++i)
+ {
+ fvect.w = i;
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetLight(device, 1, &light);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ expected = expected_light_specular[(unsigned int)i % ARRAY_SIZE(expected_light_specular)].zw;
+ expected_float = (const float *)expected;
+
+ for (j = 0; j < 2; ++j)
+ {
+ ok(compare_float(v[j], expected_float[j], 0),
+ "i %d, component %u, expected %#x (%g), got %#x (%g).\n",
+ i, j + 2, expected[j], expected_float[j], ((const unsigned int *)v)[j], v[j]);
+ }
+ }
+
+ v = &light.Specular.r;
+ for (i = 0; i < ARRAY_SIZE(test_index_to_immediate_table); ++i)
+ {
+ fvect.x = fvect.y = fvect.z = fvect.w = test_index_to_immediate_table[i].index_value;
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetLight(device, 2, &light);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ expected = test_index_to_immediate_table[i].expected;
+ expected_float = (const float *)expected;
+
+ for (j = 0; j < 4; ++j)
+ {
+ ok(compare_float(v[j], expected_float[j], 0),
+ "Test %d, component %u, expected %#x (%g), got %#x (%g).\n",
+ i, j, expected[j], expected_float[j], ((const unsigned int *)v)[j], v[j]);
+ }
+ }
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+}
+
+struct test_state_manager_update
+{
+ unsigned int state_op;
+ DWORD param1;
+ DWORD param2;
+};
+
+struct test_manager
+{
+ ID3DXEffectStateManager ID3DXEffectStateManager_iface;
+ LONG ref;
+
+ IDirect3DDevice9 *device;
+ struct test_state_manager_update *update_record;
+ unsigned int update_record_count;
+ unsigned int update_record_size;
+};
+
+#define INITIAL_UPDATE_RECORD_SIZE 64
+
+static struct test_manager *impl_from_ID3DXEffectStateManager(ID3DXEffectStateManager *iface)
+{
+ return CONTAINING_RECORD(iface, struct test_manager, ID3DXEffectStateManager_iface);
+}
+
+static void free_test_effect_state_manager(struct test_manager *state_manager)
+{
+ HeapFree(GetProcessHeap(), 0, state_manager->update_record);
+ state_manager->update_record = NULL;
+
+ IDirect3DDevice9_Release(state_manager->device);
+}
+
+static ULONG WINAPI test_manager_AddRef(ID3DXEffectStateManager *iface)
+{
+ struct test_manager *state_manager = impl_from_ID3DXEffectStateManager(iface);
+
+ return InterlockedIncrement(&state_manager->ref);
+}
+
+static ULONG WINAPI test_manager_Release(ID3DXEffectStateManager *iface)
+{
+ struct test_manager *state_manager = impl_from_ID3DXEffectStateManager(iface);
+ ULONG ref = InterlockedDecrement(&state_manager->ref);
+
+ if (!ref)
+ {
+ free_test_effect_state_manager(state_manager);
+ HeapFree(GetProcessHeap(), 0, state_manager);
+ }
+ return ref;
+}
+
+static HRESULT test_process_set_state(ID3DXEffectStateManager *iface,
+ unsigned int state_op, DWORD param1, DWORD param2)
+{
+ struct test_manager *state_manager = impl_from_ID3DXEffectStateManager(iface);
+
+ if (state_manager->update_record_count == state_manager->update_record_size)
+ {
+ if (!state_manager->update_record_size)
+ {
+ state_manager->update_record_size = INITIAL_UPDATE_RECORD_SIZE;
+ state_manager->update_record = HeapAlloc(GetProcessHeap(), 0,
+ sizeof(*state_manager->update_record) * state_manager->update_record_size);
+ }
+ else
+ {
+ state_manager->update_record_size *= 2;
+ state_manager->update_record = HeapReAlloc(GetProcessHeap(), 0, state_manager->update_record,
+ sizeof(*state_manager->update_record) * state_manager->update_record_size);
+ }
+ }
+ state_manager->update_record[state_manager->update_record_count].state_op = state_op;
+ state_manager->update_record[state_manager->update_record_count].param1 = param1;
+ state_manager->update_record[state_manager->update_record_count].param2 = param2;
+ ++state_manager->update_record_count;
+ return D3D_OK;
+}
+
+static HRESULT WINAPI test_manager_SetTransform(ID3DXEffectStateManager *iface,
+ D3DTRANSFORMSTATETYPE state, const D3DMATRIX *matrix)
+{
+ return test_process_set_state(iface, 0, state, 0);
+}
+
+static HRESULT WINAPI test_manager_SetMaterial(ID3DXEffectStateManager *iface,
+ const D3DMATERIAL9 *material)
+{
+ return test_process_set_state(iface, 1, 0, 0);
+}
+
+static HRESULT WINAPI test_manager_SetLight(ID3DXEffectStateManager *iface,
+ DWORD index, const D3DLIGHT9 *light)
+{
+ struct test_manager *state_manager = impl_from_ID3DXEffectStateManager(iface);
+
+ IDirect3DDevice9_SetLight(state_manager->device, index, light);
+ return test_process_set_state(iface, 2, index, 0);
+}
+
+static HRESULT WINAPI test_manager_LightEnable(ID3DXEffectStateManager *iface,
+ DWORD index, BOOL enable)
+{
+ struct test_manager *state_manager = impl_from_ID3DXEffectStateManager(iface);
+
+ IDirect3DDevice9_LightEnable(state_manager->device, index, enable);
+ return test_process_set_state(iface, 3, index, 0);
+}
+
+static HRESULT WINAPI test_manager_SetRenderState(ID3DXEffectStateManager *iface,
+ D3DRENDERSTATETYPE state, DWORD value)
+{
+ return test_process_set_state(iface, 4, state, 0);
+}
+
+static HRESULT WINAPI test_manager_SetTexture(ID3DXEffectStateManager *iface,
+ DWORD stage, struct IDirect3DBaseTexture9 *texture)
+{
+ return test_process_set_state(iface, 5, stage, 0);
+}
+
+static HRESULT WINAPI test_manager_SetTextureStageState(ID3DXEffectStateManager *iface,
+ DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value)
+{
+ return test_process_set_state(iface, 6, stage, type);
+}
+
+static HRESULT WINAPI test_manager_SetSamplerState(ID3DXEffectStateManager *iface,
+ DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value)
+{
+ return test_process_set_state(iface, 7, sampler, type);
+}
+
+static HRESULT WINAPI test_manager_SetNPatchMode(ID3DXEffectStateManager *iface,
+ FLOAT num_segments)
+{
+ return test_process_set_state(iface, 8, 0, 0);
+}
+
+static HRESULT WINAPI test_manager_SetFVF(ID3DXEffectStateManager *iface,
+ DWORD format)
+{
+ return test_process_set_state(iface, 9, 0, 0);
+}
+
+static HRESULT WINAPI test_manager_SetVertexShader(ID3DXEffectStateManager *iface,
+ struct IDirect3DVertexShader9 *shader)
+{
+ return test_process_set_state(iface, 10, 0, 0);
+}
+
+static HRESULT WINAPI test_manager_SetVertexShaderConstantF(ID3DXEffectStateManager *iface,
+ UINT register_index, const FLOAT *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 11, register_index, register_count);
+}
+
+static HRESULT WINAPI test_manager_SetVertexShaderConstantI(ID3DXEffectStateManager *iface,
+ UINT register_index, const INT *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 12, register_index, register_count);
+}
+
+static HRESULT WINAPI test_manager_SetVertexShaderConstantB(ID3DXEffectStateManager *iface,
+ UINT register_index, const BOOL *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 13, register_index, register_count);
+}
+
+static HRESULT WINAPI test_manager_SetPixelShader(ID3DXEffectStateManager *iface,
+ struct IDirect3DPixelShader9 *shader)
+{
+ return test_process_set_state(iface, 14, 0, 0);
+}
+
+static HRESULT WINAPI test_manager_SetPixelShaderConstantF(ID3DXEffectStateManager *iface,
+ UINT register_index, const FLOAT *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 15, register_index, register_count);
+}
+
+static HRESULT WINAPI test_manager_SetPixelShaderConstantI(ID3DXEffectStateManager *iface,
+ UINT register_index, const INT *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 16, register_index, register_count);
+}
+
+static HRESULT WINAPI test_manager_SetPixelShaderConstantB(ID3DXEffectStateManager *iface,
+ UINT register_index, const BOOL *constant_data, UINT register_count)
+{
+ return test_process_set_state(iface, 17, register_index, register_count);
+}
+
+static void test_effect_state_manager_init(struct test_manager *state_manager,
+ IDirect3DDevice9 *device)
+{
+ static const struct ID3DXEffectStateManagerVtbl test_ID3DXEffectStateManager_Vtbl =
+ {
+ /*** IUnknown methods ***/
+ NULL,
+ test_manager_AddRef,
+ test_manager_Release,
+ /*** ID3DXEffectStateManager methods ***/
+ test_manager_SetTransform,
+ test_manager_SetMaterial,
+ test_manager_SetLight,
+ test_manager_LightEnable,
+ test_manager_SetRenderState,
+ test_manager_SetTexture,
+ test_manager_SetTextureStageState,
+ test_manager_SetSamplerState,
+ test_manager_SetNPatchMode,
+ test_manager_SetFVF,
+ test_manager_SetVertexShader,
+ test_manager_SetVertexShaderConstantF,
+ test_manager_SetVertexShaderConstantI,
+ test_manager_SetVertexShaderConstantB,
+ test_manager_SetPixelShader,
+ test_manager_SetPixelShaderConstantF,
+ test_manager_SetPixelShaderConstantI,
+ test_manager_SetPixelShaderConstantB,
+ };
+
+ state_manager->ID3DXEffectStateManager_iface.lpVtbl = &test_ID3DXEffectStateManager_Vtbl;
+ state_manager->ref = 1;
+
+ IDirect3DDevice9_AddRef(device);
+ state_manager->device = device;
+}
+
+static const char *test_effect_state_manager_state_names[] =
+{
+ "SetTransform",
+ "SetMaterial",
+ "SetLight",
+ "LightEnable",
+ "SetRenderState",
+ "SetTexture",
+ "SetTextureStageState",
+ "SetSamplerState",
+ "SetNPatchMode",
+ "SetFVF",
+ "SetVertexShader",
+ "SetVertexShaderConstantF",
+ "SetVertexShaderConstantI",
+ "SetVertexShaderConstantB",
+ "SetPixelShader",
+ "SetPixelShaderConstantF",
+ "SetPixelShaderConstantI",
+ "SetPixelShaderConstantB",
+};
+
+static int compare_update_record(const void *a, const void *b)
+{
+ const struct test_state_manager_update *r1 = (const struct test_state_manager_update *)a;
+ const struct test_state_manager_update *r2 = (const struct test_state_manager_update *)b;
+
+ if (r1->state_op != r2->state_op)
+ return r1->state_op - r2->state_op;
+ if (r1->param1 != r2->param1)
+ return r1->param1 - r2->param1;
+ return r1->param2 - r2->param2;
+}
+
+static void test_effect_state_manager(IDirect3DDevice9 *device)
+{
+ static const struct test_state_manager_update expected_updates[] =
+ {
+ {2, 0, 0},
+ {2, 1, 0},
+ {2, 2, 0},
+ {2, 3, 0},
+ {2, 4, 0},
+ {2, 5, 0},
+ {2, 6, 0},
+ {2, 7, 0},
+ {3, 0, 0},
+ {3, 1, 0},
+ {3, 2, 0},
+ {3, 3, 0},
+ {3, 4, 0},
+ {3, 5, 0},
+ {3, 6, 0},
+ {3, 7, 0},
+ {4, 28, 0},
+ {4, 36, 0},
+ {4, 38, 0},
+ {4, 158, 0},
+ {4, 159, 0},
+ {5, 0, 0},
+ {5, 259, 0},
+ {7, 0, 5},
+ {7, 0, 6},
+ {7, 1, 5},
+ {7, 1, 6},
+ {7, 257, 5},
+ {7, 257, 6},
+ {7, 258, 5},
+ {7, 258, 6},
+ {7, 259, 5},
+ {7, 259, 6},
+ {10, 0, 0},
+ {11, 0, 34},
+ {14, 0, 0},
+ {15, 0, 14},
+ {16, 0, 1},
+ {17, 0, 6},
+ };
+ static D3DLIGHT9 light_filler =
+ {D3DLIGHT_DIRECTIONAL, {0.5f, 0.5f, 0.5f, 0.5f}, {0.5f, 0.5f, 0.5f, 0.5f}, {0.5f, 0.5f, 0.5f, 0.5f}};
+ struct test_manager *state_manager;
+ unsigned int passes_count, i, n;
+ ID3DXEffect *effect;
+ ULONG refcount;
+ HRESULT hr;
+
+ state_manager = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*state_manager));
+ test_effect_state_manager_init(state_manager, device);
+
+ for (i = 0; i < 8; ++i)
+ {
+ hr = IDirect3DDevice9_SetLight(device, i, &light_filler);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->SetStateManager(effect, &state_manager->ID3DXEffectStateManager_iface);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+
+ qsort(state_manager->update_record, state_manager->update_record_count,
+ sizeof(*state_manager->update_record), compare_update_record);
+
+ ok(ARRAY_SIZE(expected_updates) == state_manager->update_record_count,
+ "Got %u update records.\n", state_manager->update_record_count);
+ n = min(ARRAY_SIZE(expected_updates), state_manager->update_record_count);
+ for (i = 0; i < n; ++i)
+ {
+ ok(!memcmp(&expected_updates[i], &state_manager->update_record[i],
+ sizeof(expected_updates[i])),
+ "Update record mismatch, expected %s, %u, %u, got %s, %u, %u.\n",
+ test_effect_state_manager_state_names[expected_updates[i].state_op],
+ expected_updates[i].param1, expected_updates[i].param2,
+ test_effect_state_manager_state_names[state_manager->update_record[i].state_op],
+ state_manager->update_record[i].param1, state_manager->update_record[i].param2);
+ }
+
+ for (i = 0; i < 8; ++i)
+ {
+ D3DLIGHT9 light;
+
+ hr = IDirect3DDevice9_GetLight(device, i, &light);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!memcmp(&light, &light_filler, sizeof(light)), "Light %u mismatch.\n", i);
+ }
+
+ refcount = state_manager->ID3DXEffectStateManager_iface.lpVtbl->Release(
+ &state_manager->ID3DXEffectStateManager_iface);
+ ok(!refcount, "State manager was not properly freed, refcount %u.\n", refcount);
+}
+
+static void test_cross_effect_handle(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect1, *effect2;
+ D3DXHANDLE param1, param2;
+ static int expected_ivect[4] = {28, 29, 30, 31};
+ int ivect[4];
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect1, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect2, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(effect1 != effect2, "Got same effect unexpectedly.\n");
+
+ param1 = effect1->lpVtbl->GetParameterByName(effect1, NULL, "g_iVect");
+ ok(!!param1, "GetParameterByName failed.\n");
+
+ param2 = effect2->lpVtbl->GetParameterByName(effect2, NULL, "g_iVect");
+ ok(!!param2, "GetParameterByName failed.\n");
+
+ ok(param1 != param2, "Got same parameter handle unexpectedly.\n");
+
+ hr = effect2->lpVtbl->SetValue(effect2, param1, expected_ivect, sizeof(expected_ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect1->lpVtbl->GetValue(effect1, param1, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(!memcmp(ivect, expected_ivect, sizeof(expected_ivect)), "Vector value mismatch.\n");
+
+ effect2->lpVtbl->Release(effect2);
+ effect1->lpVtbl->Release(effect1);
+}
+
+#if 0
+struct test_struct
+{
+ float3 v1_2;
+ float fv_2;
+ float4 v2_2;
+};
+
+shared float arr2[1];
+shared test_struct ts2[2] = {{{0, 0, 0}, 0, {0, 0, 0, 0}}, {{1, 2, 3}, 4, {5, 6, 7, 8}}};
+
+struct VS_OUTPUT
+{
+ float4 Position : POSITION;
+};
+
+VS_OUTPUT RenderSceneVS(float4 vPos : POSITION)
+{
+ VS_OUTPUT Output;
+
+ Output.Position = arr2[0] * vPos;
+ return Output;
+}
+
+shared vertexshader vs_arr2[2] = {compile vs_3_0 RenderSceneVS(), NULL};
+
+technique tech0
+{
+ pass p0
+ {
+ FogEnable = TRUE;
+ FogDensity = arr2[0];
+ PointScale_A = ts2[0].fv_2;
+ VertexShader = vs_arr2[0];
+ }
+
+ pass p1
+ {
+ VertexShader = vs_arr2[1];
+ }
+}
+#endif
+static const DWORD test_effect_shared_parameters_blob[] =
+{
+ 0xfeff0901, 0x000001dc, 0x00000000, 0x00000003, 0x00000000, 0x00000024, 0x00000000, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000005, 0x32727261, 0x00000000, 0x00000000, 0x00000005,
+ 0x000000dc, 0x00000000, 0x00000002, 0x00000003, 0x00000003, 0x00000001, 0x000000e4, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000001, 0x00000003, 0x00000000, 0x000000f0, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000003, 0x00000001, 0x000000fc, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000,
+ 0x41000000, 0x00000004, 0x00327374, 0x00000005, 0x325f3176, 0x00000000, 0x00000005, 0x325f7666,
+ 0x00000000, 0x00000005, 0x325f3276, 0x00000000, 0x00000010, 0x00000004, 0x00000124, 0x00000000,
+ 0x00000002, 0x00000001, 0x00000002, 0x00000008, 0x615f7376, 0x00327272, 0x00000001, 0x00000002,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003,
+ 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00000010,
+ 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003070, 0x00000004, 0x00000010,
+ 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003170, 0x00000006, 0x68636574,
+ 0x00000030, 0x00000003, 0x00000001, 0x00000006, 0x00000005, 0x00000004, 0x00000020, 0x00000001,
+ 0x00000000, 0x00000030, 0x0000009c, 0x00000001, 0x00000000, 0x00000108, 0x0000011c, 0x00000001,
+ 0x00000000, 0x000001d0, 0x00000000, 0x00000002, 0x000001a8, 0x00000000, 0x00000004, 0x0000000e,
+ 0x00000000, 0x00000134, 0x00000130, 0x00000014, 0x00000000, 0x00000154, 0x00000150, 0x00000041,
+ 0x00000000, 0x00000174, 0x00000170, 0x00000092, 0x00000000, 0x00000194, 0x00000190, 0x000001c8,
+ 0x00000000, 0x00000001, 0x00000092, 0x00000000, 0x000001b4, 0x000001b0, 0x00000002, 0x00000004,
+ 0x00000001, 0x000000c8, 0xfffe0300, 0x0025fffe, 0x42415443, 0x0000001c, 0x0000005f, 0xfffe0300,
+ 0x00000001, 0x0000001c, 0x00000000, 0x00000058, 0x00000030, 0x00000002, 0x00000001, 0x00000038,
+ 0x00000048, 0x32727261, 0xababab00, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820,
+ 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235,
+ 0x00313131, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x03000005,
+ 0xe00f0000, 0xa0000000, 0x90e40000, 0x0000ffff, 0x00000002, 0x00000000, 0x00000000, 0x00000001,
+ 0xffffffff, 0x00000000, 0x00000001, 0x0000000b, 0x615f7376, 0x5b327272, 0x00005d31, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000003, 0x00000001, 0x0000000b, 0x615f7376, 0x5b327272, 0x00005d30,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000002, 0x00000000, 0x00000188, 0x46580200, 0x004ffffe,
+ 0x42415443, 0x0000001c, 0x00000107, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000104,
+ 0x00000030, 0x00000002, 0x00000002, 0x00000094, 0x000000a4, 0x00327374, 0x325f3176, 0xababab00,
+ 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0x325f7666, 0xababab00, 0x00030000, 0x00010001,
+ 0x00000001, 0x00000000, 0x325f3276, 0xababab00, 0x00030001, 0x00040001, 0x00000001, 0x00000000,
+ 0x00000034, 0x0000003c, 0x0000004c, 0x00000054, 0x00000064, 0x0000006c, 0x00000005, 0x00080001,
+ 0x00030002, 0x0000007c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x40000000,
+ 0x40400000, 0x00000000, 0x40800000, 0x00000000, 0x00000000, 0x00000000, 0x40a00000, 0x40c00000,
+ 0x40e00000, 0x41000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000004, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0x00000001, 0x00000000, 0x000000dc, 0x46580200, 0x0024fffe,
+ 0x42415443, 0x0000001c, 0x0000005b, 0x46580200, 0x00000001, 0x0000001c, 0x20000100, 0x00000058,
+ 0x00000030, 0x00000002, 0x00000001, 0x00000038, 0x00000048, 0x32727261, 0xababab00, 0x00030000,
+ 0x00010001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+ 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe,
+ 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+};
+
+#ifdef __REACTOS__
+#define test_effect_shared_vs_arr_compare_helper(...) \
+ test_effect_shared_vs_arr_compare_helper_(__LINE__, __VA_ARGS__)
+#else
+#define test_effect_shared_vs_arr_compare_helper(args...) \
+ test_effect_shared_vs_arr_compare_helper_(__LINE__, args)
+#endif
+static void test_effect_shared_vs_arr_compare_helper_(unsigned int line, ID3DXEffect *effect,
+ D3DXHANDLE param_child, struct IDirect3DVertexShader9 *vshader1, unsigned int element,
+ BOOL todo)
+{
+ struct IDirect3DVertexShader9 *vshader2;
+ D3DXHANDLE param_child2;
+ HRESULT hr;
+
+ param_child2 = effect->lpVtbl->GetParameterElement(effect, "vs_arr2", element);
+ ok_(__FILE__, line)(!!param_child2, "GetParameterElement failed.\n");
+ ok_(__FILE__, line)(param_child != param_child2, "Got same parameter handle unexpectedly.\n");
+ hr = effect->lpVtbl->GetVertexShader(effect, param_child2, &vshader2);
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine_if(todo)
+ ok_(__FILE__, line)(vshader1 == vshader2, "Shared shader interface pointers differ.\n");
+ if (vshader2)
+ IDirect3DVertexShader9_Release(vshader2);
+}
+
+#ifdef __REACTOS__
+#define test_effect_shared_parameters_compare_vconst(...) \
+ test_effect_shared_parameters_compare_vconst_(__LINE__, __VA_ARGS__)
+#else
+#define test_effect_shared_parameters_compare_vconst(args...) \
+ test_effect_shared_parameters_compare_vconst_(__LINE__, args)
+#endif
+static void test_effect_shared_parameters_compare_vconst_(unsigned int line, IDirect3DDevice9 *device,
+ unsigned int index, const D3DXVECTOR4 *expected_fvect, BOOL todo)
+{
+ D3DXVECTOR4 fvect;
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, index, &fvect.x, 1);
+ ok_(__FILE__, line)(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine_if(todo)
+ ok_(__FILE__, line)(!memcmp(&fvect, expected_fvect, sizeof(fvect)),
+ "Unexpected constant value %g, %g, %g, %g.\n", fvect.x, fvect.y, fvect.z, fvect.w);
+}
+
+static void test_effect_shared_parameters(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect1, *effect2, *effect3, *effect4;
+ ID3DXEffectPool *pool;
+ HRESULT hr;
+ D3DXHANDLE param, param_child, param2, param_child2;
+ unsigned int i, passes_count;
+ ULONG refcount;
+ D3DXVECTOR4 fvect;
+ float fval[2];
+
+ hr = D3DXCreateEffectPool(&pool);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, pool, &effect2, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect2->lpVtbl->SetFloat(effect2, "arr2[0]", 28.0f);
+ effect2->lpVtbl->Release(effect2);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, pool, &effect2, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect2->lpVtbl->GetFloat(effect2, "arr2[0]", &fvect.x);
+ ok(fvect.x == 92.0f, "Unexpected parameter value %g.\n", fvect.x);
+ effect2->lpVtbl->SetFloat(effect2, "arr2[0]", 28.0f);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, pool, &effect1, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect1->lpVtbl->GetFloat(effect1, "arr2[0]", &fvect.x);
+ ok(fvect.x == 28.0f, "Unexpected parameter value %g.\n", fvect.x);
+
+ hr = D3DXCreateEffect(device, test_effect_shared_parameters_blob, sizeof(test_effect_shared_parameters_blob),
+ NULL, NULL, 0, pool, &effect3, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = D3DXCreateEffect(device, test_effect_shared_parameters_blob, sizeof(test_effect_shared_parameters_blob),
+ NULL, NULL, 0, pool, &effect4, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect2->lpVtbl->SetFloat(effect2, "arr2[0]", 3.0f);
+ effect2->lpVtbl->SetFloat(effect2, "ts2[0].fv", 3.0f);
+
+ effect3->lpVtbl->GetFloat(effect3, "arr2[0]", &fvect.x);
+ ok(fvect.x == 0.0f, "Unexpected parameter value %g.\n", fvect.x);
+ effect4->lpVtbl->SetFloat(effect4, "arr2[0]", 28.0f);
+ effect3->lpVtbl->GetFloat(effect3, "arr2[0]", &fvect.x);
+ ok(fvect.x == 28.0f, "Unexpected parameter value %g.\n", fvect.x);
+ effect1->lpVtbl->GetFloat(effect1, "arr2[0]", &fvect.x);
+ ok(fvect.x == 3.0f, "Unexpected parameter value %g.\n", fvect.x);
+
+ param = effect3->lpVtbl->GetParameterByName(effect3, NULL, "ts2[0].fv_2");
+ ok(!!param, "GetParameterByName failed.\n");
+ effect3->lpVtbl->GetFloat(effect3, param, &fvect.x);
+ ok(fvect.x == 0.0f, "Unexpected parameter value %g.\n", fvect.x);
+
+ param = effect1->lpVtbl->GetParameterByName(effect1, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ ok(!effect3->lpVtbl->IsParameterUsed(effect3, param, "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ param = effect3->lpVtbl->GetParameterByName(effect3, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ ok(effect3->lpVtbl->IsParameterUsed(effect3, param, "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ param = effect1->lpVtbl->GetParameterByName(effect1, NULL, "vs_arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ todo_wine
+ ok(!effect3->lpVtbl->IsParameterUsed(effect3, param, "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ ok(effect3->lpVtbl->IsParameterUsed(effect3, "vs_arr2", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(!effect3->lpVtbl->IsParameterUsed(effect3, "vs_arr2[0]", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(!effect3->lpVtbl->IsParameterUsed(effect3, "vs_arr2[1]", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ ok(effect1->lpVtbl->IsParameterUsed(effect1, param, "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ hr = effect3->lpVtbl->Begin(effect3, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ if (0)
+ {
+ /* Native d3dx crashes in BeginPass(). This is the case of shader array declared shared
+ * but initialized with different shaders using different parameters. */
+ hr = effect3->lpVtbl->BeginPass(effect3, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect3->lpVtbl->EndPass(effect3);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ }
+
+ test_effect_preshader_clear_vconsts(device);
+ fvect.x = fvect.y = fvect.z = fvect.w = 28.0f;
+ hr = effect2->lpVtbl->SetVector(effect2, "g_Pos1", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect1->lpVtbl->SetVector(effect1, "g_Pos1", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect3->lpVtbl->BeginPass(effect3, 1);
+ todo_wine
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, &fvect.x, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ todo_wine
+ ok(fvect.x == 0.0f && fvect.y == 0.0f && fvect.z == 0.0f && fvect.w == 0.0f,
+ "Unexpected vector %g, %g, %g, %g.\n", fvect.x, fvect.y, fvect.z, fvect.w);
+
+ hr = effect3->lpVtbl->EndPass(effect3);
+ todo_wine
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect3->lpVtbl->End(effect3);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ for (i = 0; i < 2; ++i)
+ {
+ struct IDirect3DVertexShader9 *vshader1;
+
+ param_child = effect1->lpVtbl->GetParameterElement(effect1, "vs_arr2", i);
+ ok(!!param_child, "GetParameterElement failed.\n");
+ hr = effect1->lpVtbl->GetVertexShader(effect1, param_child, &vshader1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_shared_vs_arr_compare_helper(effect2, param_child, vshader1, i, FALSE);
+ test_effect_shared_vs_arr_compare_helper(effect3, param_child, vshader1, i, FALSE);
+ test_effect_shared_vs_arr_compare_helper(effect4, param_child, vshader1, i, FALSE);
+ IDirect3DVertexShader9_Release(vshader1);
+ }
+
+ effect3->lpVtbl->Release(effect3);
+ effect4->lpVtbl->Release(effect4);
+
+ fval[0] = 1.0f;
+ hr = effect1->lpVtbl->SetFloatArray(effect1, "arr1", fval, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ fval[0] = 0.0f;
+ hr = effect2->lpVtbl->GetFloatArray(effect2, "arr1", fval, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(fval[0] == 91.0f, "Unexpected value %g.\n", fval[0]);
+
+ param = effect1->lpVtbl->GetParameterByName(effect1, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ param2 = effect2->lpVtbl->GetParameterByName(effect2, NULL, "arr2");
+ ok(!!param, "GetParameterByName failed.\n");
+ ok(param != param2, "Got same parameter handle unexpectedly.\n");
+ param_child = effect1->lpVtbl->GetParameterElement(effect1, param, 0);
+ ok(!!param_child, "GetParameterElement failed.\n");
+ param_child2 = effect1->lpVtbl->GetParameterElement(effect2, param2, 0);
+ ok(!!param_child2, "GetParameterElement failed.\n");
+ ok(param_child != param_child2, "Got same parameter handle unexpectedly.\n");
+
+ fval[0] = 33.0f;
+ hr = effect1->lpVtbl->SetFloatArray(effect1, "arr2", fval, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ fval[0] = 0.0f;
+ hr = effect1->lpVtbl->GetFloatArray(effect1, "arr2", fval, 2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(fval[0] == 33.0f && fval[1] == 93.0f, "Unexpected values %g, %g.\n", fval[0], fval[1]);
+ fval[0] = 0.0f;
+ hr = effect2->lpVtbl->GetFloatArray(effect2, "arr2", fval, 2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(fval[0] == 33.0f && fval[1] == 93.0f, "Unexpected values %g, %g.\n", fval[0], fval[1]);
+
+ hr = effect1->lpVtbl->Begin(effect1, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect2->lpVtbl->Begin(effect2, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect1->lpVtbl->BeginPass(effect1, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 1.0f;
+ fvect.y = fvect.z = fvect.w = 0.0f;
+ test_effect_shared_parameters_compare_vconst(device, 32, &fvect, FALSE);
+
+ hr = effect1->lpVtbl->BeginPass(effect2, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 91.0f;
+ test_effect_shared_parameters_compare_vconst(device, 32, &fvect, FALSE);
+ fvect.x = 33.0f;
+ test_effect_shared_parameters_compare_vconst(device, 29, &fvect, FALSE);
+
+ fval[0] = 28.0f;
+ fval[1] = -1.0f;
+ hr = effect1->lpVtbl->SetFloatArray(effect1, "arr2", fval, 2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_clear_vconsts(device);
+
+ hr = effect1->lpVtbl->CommitChanges(effect1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 28.0f;
+ test_effect_shared_parameters_compare_vconst(device, 29, &fvect, FALSE);
+ fvect.x = -1.0f;
+ test_effect_shared_parameters_compare_vconst(device, 30, &fvect, FALSE);
+
+ test_effect_preshader_clear_vconsts(device);
+
+ hr = effect1->lpVtbl->CommitChanges(effect1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_shared_parameters_compare_vconst(device, 29, &fvect_filler, FALSE);
+ test_effect_shared_parameters_compare_vconst(device, 30, &fvect_filler, FALSE);
+
+ hr = effect2->lpVtbl->CommitChanges(effect2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = 28.0f;
+ test_effect_shared_parameters_compare_vconst(device, 29, &fvect, FALSE);
+ fvect.x = -1.0f;
+ test_effect_shared_parameters_compare_vconst(device, 30, &fvect, FALSE);
+
+ fval[0] = -2.0f;
+ hr = effect2->lpVtbl->SetFloat(effect2, "arr2[0]", fval[0]);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect1->lpVtbl->CommitChanges(effect1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.x = -2.0f;
+ test_effect_shared_parameters_compare_vconst(device, 29, &fvect, FALSE);
+ fvect.x = -1.0f;
+ test_effect_shared_parameters_compare_vconst(device, 30, &fvect, FALSE);
+
+ fvect.x = fvect.y = fvect.z = fvect.w = 1111.0f;
+ hr = effect2->lpVtbl->SetVector(effect2, "g_Pos1", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect1->lpVtbl->CommitChanges(effect1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_shared_parameters_compare_vconst(device, 31, &fvect_filler, FALSE);
+
+ hr = effect1->lpVtbl->CommitChanges(effect2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_shared_parameters_compare_vconst(device, 31, &fvect, FALSE);
+
+ hr = effect1->lpVtbl->End(effect1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect2->lpVtbl->End(effect2);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ if (0)
+ {
+ refcount = pool->lpVtbl->Release(pool);
+ ok(refcount == 2, "Unexpected refcount %u.\n", refcount);
+
+ refcount = pool->lpVtbl->Release(pool);
+ ok(refcount == 1, "Unexpected refcount %u.\n", refcount);
+
+ refcount = pool->lpVtbl->Release(pool);
+ ok(!refcount, "Unexpected refcount %u.\n", refcount);
+
+ /* Native d3dx crashes in GetFloat(). */
+ effect2->lpVtbl->GetFloat(effect2, "arr2[0]", &fvect.x);
+ }
+
+ effect1->lpVtbl->Release(effect1);
+ effect2->lpVtbl->Release(effect2);
+
+ refcount = pool->lpVtbl->Release(pool);
+ ok(!refcount, "Effect pool was not properly freed, refcount %u.\n", refcount);
+}
+
+static void test_effect_large_address_aware_flag(IDirect3DDevice9 *device)
+{
+ ID3DXEffect *effect;
+ D3DXHANDLE param;
+ static int expected_ivect[4] = {28, 29, 30, 31};
+ int ivect[4];
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, D3DXFX_LARGEADDRESSAWARE, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ param = effect->lpVtbl->GetParameterByName(effect, NULL, "g_iVect");
+ ok(!!param, "GetParameterByName failed.\n");
+
+ hr = effect->lpVtbl->SetValue(effect, param, expected_ivect, sizeof(expected_ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->GetValue(effect, param, ivect, sizeof(ivect));
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(!memcmp(ivect, expected_ivect, sizeof(expected_ivect)), "Vector value mismatch.\n");
+
+ if (0)
+ {
+ /* Native d3dx crashes in GetValue(). */
+ hr = effect->lpVtbl->GetValue(effect, "g_iVect", ivect, sizeof(ivect));
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ }
+
+ effect->lpVtbl->Release(effect);
+}
+
+static void test_effect_get_pass_desc(IDirect3DDevice9 *device)
+{
+ unsigned int passes_count;
+ ID3DXEffect *effect;
+ D3DXPASS_DESC desc;
+ D3DXVECTOR4 fvect;
+ D3DXHANDLE pass;
+ HRESULT hr;
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ pass = effect->lpVtbl->GetPass(effect, "tech0", 1);
+ ok(!!pass, "GetPass() failed.\n");
+
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE);
+
+ fvect.x = fvect.y = fvect.w = 0.0f;
+ fvect.z = 0.0f;
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!desc.pPixelShaderFunction, "Unexpected non null desc.pPixelShaderFunction.\n");
+
+ test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, FALSE);
+
+ fvect.z = 3.0f;
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
+
+ /* Repeating call to confirm GetPassDesc() returns same error on the second call,
+ * as it is not the case sometimes for BeginPass() with out of bound access. */
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 0, FALSE);
+
+ fvect.z = 2.0f;
+ hr = effect->lpVtbl->SetVector(effect, "g_iVect", &fvect);
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ test_effect_preshader_compare_shader_bytecode(desc.pVertexShaderFunction, 0, 2, FALSE);
+
+ effect->lpVtbl->Release(effect);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ pass = effect->lpVtbl->GetPass(effect, "tech0", 1);
+ ok(!!pass, "GetPass() failed.\n");
+
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(!desc.pVertexShaderFunction, "Unexpected non null desc.pVertexShaderFunction.\n");
+ ok(!desc.pPixelShaderFunction, "Unexpected non null desc.pPixelShaderFunction.\n");
+
+ effect->lpVtbl->Release(effect);
+}
+
+#if 0
+float v1 : register(c2);
+float v2 : register(c3);
+float v3;
+float v4 : register(c4);
+float v5;
+float v6[2] : register(c5) = {11, 22};
+
+struct VS_OUTPUT
+{
+ float4 Position : POSITION;
+};
+
+VS_OUTPUT RenderSceneVS(float4 vPos : POSITION)
+{
+ VS_OUTPUT Output;
+
+ Output.Position = v1 * v2 * vPos + v2 + v3 + v4;
+ Output.Position += v6[0] + v6[1];
+ return Output;
+}
+
+technique tech0
+{
+ pass p0
+ {
+ PointScale_A = v4;
+ VertexShader = compile vs_3_0 RenderSceneVS();
+ }
+}
+#endif
+static const DWORD test_effect_skip_constants_blob[] =
+{
+ 0xfeff0901, 0x00000144, 0x00000000, 0x00000003, 0x00000000, 0x00000024, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00003176, 0x00000003, 0x00000000, 0x0000004c,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00003276, 0x00000003,
+ 0x00000000, 0x00000074, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000003,
+ 0x00003376, 0x00000003, 0x00000000, 0x0000009c, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000000, 0x00000003, 0x00003476, 0x00000003, 0x00000000, 0x000000c4, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000003, 0x00003576, 0x00000003, 0x00000000, 0x000000f0,
+ 0x00000000, 0x00000002, 0x00000001, 0x00000001, 0x41300000, 0x41b00000, 0x00000003, 0x00003676,
+ 0x00000000, 0x00000003, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003070,
+ 0x00000006, 0x68636574, 0x00000030, 0x00000006, 0x00000001, 0x00000002, 0x00000002, 0x00000004,
+ 0x00000020, 0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000, 0x00000000, 0x00000054,
+ 0x00000070, 0x00000000, 0x00000000, 0x0000007c, 0x00000098, 0x00000000, 0x00000000, 0x000000a4,
+ 0x000000c0, 0x00000000, 0x00000000, 0x000000cc, 0x000000e8, 0x00000000, 0x00000000, 0x00000138,
+ 0x00000000, 0x00000001, 0x00000130, 0x00000000, 0x00000002, 0x00000041, 0x00000000, 0x000000fc,
+ 0x000000f8, 0x00000092, 0x00000000, 0x0000011c, 0x00000118, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000001, 0x00000000, 0x000001bc, 0xfffe0300, 0x0047fffe, 0x42415443,
+ 0x0000001c, 0x000000e7, 0xfffe0300, 0x00000005, 0x0000001c, 0x20000000, 0x000000e0, 0x00000080,
+ 0x00020002, 0x000a0001, 0x00000084, 0x00000094, 0x000000a4, 0x00030002, 0x000e0001, 0x00000084,
+ 0x00000094, 0x000000a7, 0x00000002, 0x00000001, 0x00000084, 0x00000094, 0x000000aa, 0x00040002,
+ 0x00120001, 0x00000084, 0x00000094, 0x000000ad, 0x00050002, 0x00160002, 0x000000b0, 0x000000c0,
+ 0xab003176, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x76003276, 0x34760033, 0x00367600, 0x00030000, 0x00010001, 0x00000002, 0x00000000,
+ 0x41300000, 0x00000000, 0x00000000, 0x00000000, 0x41b00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+ 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0200001f, 0x80000000,
+ 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x02000001, 0x80010000, 0xa0000003, 0x03000005,
+ 0x80010000, 0x80000000, 0xa0000002, 0x04000004, 0x800f0000, 0x80000000, 0x90e40000, 0xa0000003,
+ 0x03000002, 0x800f0000, 0x80e40000, 0xa0000000, 0x03000002, 0x800f0000, 0x80e40000, 0xa0000004,
+ 0x02000001, 0x80010001, 0xa0000005, 0x03000002, 0x80010001, 0x80000001, 0xa0000006, 0x03000002,
+ 0xe00f0000, 0x80e40000, 0x80000001, 0x0000ffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000,
+ 0x00000000, 0x000000d8, 0x46580200, 0x0023fffe, 0x42415443, 0x0000001c, 0x00000057, 0x46580200,
+ 0x00000001, 0x0000001c, 0x20000100, 0x00000054, 0x00000030, 0x00040002, 0x00120001, 0x00000034,
+ 0x00000044, 0xab003476, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe,
+ 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000,
+ 0x00000002, 0x00000010, 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+};
+
+static void test_effect_skip_constants(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ ID3DXEffect *effect;
+ unsigned int passes_count;
+ D3DXVECTOR4 fvect;
+ unsigned int i;
+
+ hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
+ NULL, NULL, "v3", 0, NULL, &effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
+ NULL, NULL, "v4", 0, NULL, &effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
+ NULL, NULL, "v1;v5;v4", 0, NULL, &effect, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ hr = D3DXCreateEffectEx(device, test_effect_skip_constants_blob, sizeof(test_effect_skip_constants_blob),
+ NULL, NULL, " v1#,.+-= &\t\nv2*/!\"'v5 v6[1]", 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ ok(!effect->lpVtbl->IsParameterUsed(effect, "v1", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(!effect->lpVtbl->IsParameterUsed(effect, "v2", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(effect->lpVtbl->IsParameterUsed(effect, "v3", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(effect->lpVtbl->IsParameterUsed(effect, "v4", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(!effect->lpVtbl->IsParameterUsed(effect, "v5", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+ ok(!effect->lpVtbl->IsParameterUsed(effect, "v6", "tech0"),
+ "Unexpected IsParameterUsed result.\n");
+
+ hr = effect->lpVtbl->SetFloat(effect, "v1", 28.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetFloat(effect, "v2", 29.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetFloat(effect, "v3", 30.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetFloat(effect, "v4", 31.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->SetFloat(effect, "v5", 32.0f);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ test_effect_preshader_clear_vconsts(device);
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ fvect.y = fvect.z = fvect.w = 0.0f;
+ fvect.x = 30.0f;
+ test_effect_shared_parameters_compare_vconst(device, 0, &fvect, FALSE);
+ for (i = 1; i < 4; ++i)
+ test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, FALSE);
+ fvect.x = 31.0f;
+ test_effect_shared_parameters_compare_vconst(device, 4, &fvect, FALSE);
+ for (i = 5; i < 256; ++i)
+ test_effect_shared_parameters_compare_vconst(device, i, &fvect_filler, FALSE);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+}
+
+#if 0
+vertexshader vs_arr[2] =
+{
+ asm
+ {
+ vs_3_0
+ def c0, 1, 1, 1, 1
+ dcl_position o0
+ mov o0, c0
+ },
+
+ asm
+ {
+ vs_3_sw
+ def c256, 1, 1, 1, 1
+ dcl_position o0
+ mov o0, c256
+ },
+};
+
+int i;
+
+technique tech0
+{
+ pass p0
+ {
+ VertexShader = vs_arr[1];
+ }
+}
+technique tech1
+{
+ pass p0
+ {
+ VertexShader = vs_arr[i];
+ }
+}
+#endif
+static const DWORD test_effect_unsupported_shader_blob[] =
+{
+ 0xfeff0901, 0x000000ac, 0x00000000, 0x00000010, 0x00000004, 0x00000020, 0x00000000, 0x00000002,
+ 0x00000001, 0x00000002, 0x00000007, 0x615f7376, 0x00007272, 0x00000002, 0x00000000, 0x0000004c,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000069, 0x00000003,
+ 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00003070, 0x00000006,
+ 0x68636574, 0x00000030, 0x00000004, 0x00000010, 0x00000004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000031, 0x00000002, 0x00000002, 0x00000006,
+ 0x00000005, 0x00000004, 0x00000018, 0x00000000, 0x00000000, 0x0000002c, 0x00000048, 0x00000000,
+ 0x00000000, 0x00000074, 0x00000000, 0x00000001, 0x0000006c, 0x00000000, 0x00000001, 0x00000092,
+ 0x00000000, 0x00000058, 0x00000054, 0x000000a0, 0x00000000, 0x00000001, 0x00000098, 0x00000000,
+ 0x00000001, 0x00000092, 0x00000000, 0x00000084, 0x00000080, 0x00000002, 0x00000002, 0x00000001,
+ 0x00000038, 0xfffe0300, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0x0200001f, 0x80000000, 0xe00f0000, 0x02000001, 0xe00f0000, 0xa0e40000, 0x0000ffff, 0x00000002,
+ 0x00000038, 0xfffe03ff, 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
+ 0x0200001f, 0x80000000, 0xe00f0000, 0x02000001, 0xe00f0000, 0xa0e40100, 0x0000ffff, 0x00000001,
+ 0x00000000, 0xffffffff, 0x00000000, 0x00000002, 0x000000e4, 0x00000008, 0x615f7376, 0x00007272,
+ 0x46580200, 0x0023fffe, 0x42415443, 0x0000001c, 0x00000057, 0x46580200, 0x00000001, 0x0000001c,
+ 0x00000100, 0x00000054, 0x00000030, 0x00000002, 0x00000001, 0x00000034, 0x00000044, 0xabab0069,
+ 0x00020000, 0x00010001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+ 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000,
+ 0x000cfffe, 0x434c5846, 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000000,
+ 0x00000000, 0x00000004, 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0x00000000, 0x00000001, 0x0000000a, 0x615f7376, 0x315b7272, 0x0000005d,
+};
+
+#define TEST_EFFECT_UNSUPPORTED_SHADER_BYTECODE_VS_3_0_POS 81
+#define TEST_EFFECT_UNSUPPORTED_SHADER_BYTECODE_VS_3_0_LEN 14
+
+static void test_effect_unsupported_shader(void)
+{
+ IDirect3DVertexShader9 *vshader;
+ unsigned int passes_count;
+ IDirect3DDevice9 *device;
+ UINT byte_code_size;
+ ID3DXEffect *effect;
+ void *byte_code;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(device = create_device(&window)))
+ return;
+
+ hr = D3DXCreateEffectEx(device, test_effect_unsupported_shader_blob, sizeof(test_effect_unsupported_shader_blob),
+ NULL, NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->ValidateTechnique(effect, "missing_technique");
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech0");
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect->lpVtbl->SetInt(effect, "i", 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ effect->lpVtbl->SetInt(effect, "i", 0);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->SetTechnique(effect, "tech0");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->SetTechnique(effect, "tech1");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->Begin(effect, &passes_count, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!!vshader, "Got NULL vshader.\n");
+ hr = IDirect3DVertexShader9_GetFunction(vshader, NULL, &byte_code_size);
+ ok(hr == D3D_OK, "Got result %x.\n", hr);
+ byte_code = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, byte_code_size);
+ hr = IDirect3DVertexShader9_GetFunction(vshader, byte_code, &byte_code_size);
+ ok(hr == D3D_OK, "Got result %x.\n", hr);
+ ok(byte_code_size == TEST_EFFECT_UNSUPPORTED_SHADER_BYTECODE_VS_3_0_LEN * sizeof(DWORD),
+ "Got unexpected byte code size %u.\n", byte_code_size);
+ ok(!memcmp(byte_code,
+ &test_effect_unsupported_shader_blob[TEST_EFFECT_UNSUPPORTED_SHADER_BYTECODE_VS_3_0_POS],
+ byte_code_size), "Incorrect shader selected.\n");
+ HeapFree(GetProcessHeap(), 0, byte_code);
+ IDirect3DVertexShader9_Release(vshader);
+
+ effect->lpVtbl->SetInt(effect, "i", 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->CommitChanges(effect);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
+ ok(hr == D3D_OK, "Got result %x.\n", hr);
+ ok(!vshader, "Got non NULL vshader.\n");
+
+ effect->lpVtbl->Release(effect);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
+#if 0
+vertexshader vs_arr[2];
+
+int i;
+
+technique tech0
+{
+ pass p0
+ {
+ VertexShader = null;
+ }
+}
+technique tech1
+{
+ pass p0
+ {
+ VertexShader = vs_arr[i];
+ }
+}
+#endif
+static const DWORD test_effect_null_shader_blob[] =
+{
+ 0xfeff0901, 0x000000b4, 0x00000000, 0x00000010, 0x00000004, 0x00000020, 0x00000000, 0x00000002,
+ 0x00000001, 0x00000002, 0x00000007, 0x615f7376, 0x00007272, 0x00000002, 0x00000000, 0x0000004c,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000069, 0x00000000,
+ 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000003,
+ 0x00003070, 0x00000006, 0x68636574, 0x00000030, 0x00000003, 0x00000010, 0x00000004, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000031, 0x00000002,
+ 0x00000002, 0x00000005, 0x00000004, 0x00000004, 0x00000018, 0x00000000, 0x00000000, 0x0000002c,
+ 0x00000048, 0x00000000, 0x00000000, 0x0000007c, 0x00000000, 0x00000001, 0x00000074, 0x00000000,
+ 0x00000001, 0x00000092, 0x00000000, 0x00000058, 0x00000054, 0x000000a8, 0x00000000, 0x00000001,
+ 0x000000a0, 0x00000000, 0x00000001, 0x00000092, 0x00000000, 0x0000008c, 0x00000088, 0x00000002,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000002, 0x000000e4, 0x00000008, 0x615f7376, 0x00007272, 0x46580200, 0x0023fffe,
+ 0x42415443, 0x0000001c, 0x00000057, 0x46580200, 0x00000001, 0x0000001c, 0x00000100, 0x00000054,
+ 0x00000030, 0x00000002, 0x00000001, 0x00000034, 0x00000044, 0xabab0069, 0x00020000, 0x00010001,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x4d007874, 0x6f726369,
+ 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+ 0x392e3932, 0x332e3235, 0x00313131, 0x0002fffe, 0x54494c43, 0x00000000, 0x000cfffe, 0x434c5846,
+ 0x00000001, 0x10000001, 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000000, 0x00000004,
+ 0x00000000, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+};
+
+static void test_effect_null_shader(void)
+{
+ IDirect3DDevice9 *device;
+ ID3DXEffect *effect;
+ D3DXPASS_DESC desc;
+ D3DXHANDLE pass;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ /* Creating a fresh device because the existing device can have invalid
+ * render states from previous tests. If IDirect3DDevice9_ValidateDevice()
+ * returns certain error codes, native ValidateTechnique() fails. */
+ if (!(device = create_device(&window)))
+ return;
+
+ hr = D3DXCreateEffectEx(device, test_effect_null_shader_blob,
+ sizeof(test_effect_null_shader_blob), NULL, NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Failed to create effect, hr %#x.\n", hr);
+
+ pass = effect->lpVtbl->GetPass(effect, "tech0", 0);
+ ok(!!pass, "GetPass() failed.\n");
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!desc.pVertexShaderFunction, "Got non NULL vertex function.\n");
+
+ pass = effect->lpVtbl->GetPass(effect, "tech1", 0);
+ ok(!!pass, "GetPass() failed.\n");
+ hr = effect->lpVtbl->GetPassDesc(effect, pass, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!desc.pVertexShaderFunction, "Got non NULL vertex function.\n");
+
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech0");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect->lpVtbl->SetInt(effect, "i", 0);
+ ok(hr == D3D_OK, "Failed to set parameter, hr %#x.\n", hr);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ effect->lpVtbl->SetInt(effect, "i", 1);
+ ok(hr == D3D_OK, "Failed to set parameter, hr %#x.\n", hr);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->SetInt(effect, "i", 2);
+ ok(hr == D3D_OK, "Failed to set parameter, hr %#x.\n", hr);
+ hr = effect->lpVtbl->ValidateTechnique(effect, "tech1");
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
+static void test_effect_clone(void)
+{
+ IDirect3DDevice9 *device, *device2, *device3;
+ ID3DXEffect *effect, *cloned;
+ HWND window, window2;
+ ULONG refcount;
+ HRESULT hr;
+
+ if (!(device = create_device(&window)))
+ return;
+
+ /* D3DXFX_NOT_CLONEABLE */
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ cloned = (void *)0xdeadbeef;
+ hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+ hr = effect->lpVtbl->CloneEffect(effect, device, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ cloned = (void *)0xdeadbeef;
+ hr = effect->lpVtbl->CloneEffect(effect, device, &cloned);
+ ok(hr == E_FAIL, "Got result %#x.\n", hr);
+ ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+ effect->lpVtbl->Release(effect);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+ NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ cloned = (void *)0xdeadbeef;
+ hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+ ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+ hr = effect->lpVtbl->CloneEffect(effect, device, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->CloneEffect(effect, device, &cloned);
+todo_wine
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+if (hr == D3D_OK)
+{
+ ok(cloned != effect, "Expected new effect instance.\n");
+ cloned->lpVtbl->Release(cloned);
+}
+ /* Try with different device. */
+ device2 = create_device(&window2);
+ hr = effect->lpVtbl->CloneEffect(effect, device2, &cloned);
+todo_wine
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+if (hr == D3D_OK)
+{
+ ok(cloned != effect, "Expected new effect instance.\n");
+
+ hr = cloned->lpVtbl->GetDevice(cloned, &device3);
+ ok(hr == S_OK, "Failed to get effect device.\n");
+ ok(device3 == device2, "Unexpected device instance.\n");
+ IDirect3DDevice9_Release(device3);
+
+ cloned->lpVtbl->Release(cloned);
+}
+ IDirect3DDevice9_Release(device2);
+ DestroyWindow(window2);
+ effect->lpVtbl->Release(effect);
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
+static unsigned int get_texture_refcount(IDirect3DTexture9 *iface)
+{
+ IDirect3DTexture9_AddRef(iface);
+ return IDirect3DTexture9_Release(iface);
+}
+
+static void test_refcount(void)
+{
+ IDirect3DTexture9 *texture, *cur_texture, *managed_texture, *sysmem_texture;
+ unsigned int passes_count;
+ IDirect3DDevice9 *device;
+ ID3DXEffect *effect;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(device = create_device(&window)))
+ return;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+
+ hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob,
+ sizeof(test_effect_preshader_effect_blob), NULL, NULL,
+ D3DXFX_DONOTSAVESTATE, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Failed to create effect, hr %#x.\n", hr);
+
+ hr = effect->lpVtbl->SetTexture(effect, "tex1", (IDirect3DBaseTexture9 *)texture);
+ ok(hr == D3D_OK, "Failed to set texture parameter, hr %#x.\n", hr);
+
+ hr = effect->lpVtbl->Begin(effect, &passes_count, D3DXFX_DONOTSAVESTATE);
+ ok(hr == D3D_OK, "Begin() failed, hr %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "BeginPass() failed, hr %#x.\n", hr);
+
+ IDirect3DDevice9_GetTexture(device, 0, (IDirect3DBaseTexture9 **)&cur_texture);
+ ok(cur_texture == texture, "Unexpected current texture %p.\n", cur_texture);
+ IDirect3DTexture9_Release(cur_texture);
+
+ IDirect3DDevice9_SetTexture(device, 0, NULL);
+ effect->lpVtbl->CommitChanges(effect);
+
+ IDirect3DDevice9_GetTexture(device, 0, (IDirect3DBaseTexture9 **)&cur_texture);
+ ok(cur_texture == NULL, "Unexpected current texture %p.\n", cur_texture);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "EndPass() failed, hr %#x.\n", hr);
+
+ hr = effect->lpVtbl->BeginPass(effect, 0);
+ ok(hr == D3D_OK, "BeginPass() failed, hr %#x.\n", hr);
+
+ IDirect3DDevice9_GetTexture(device, 0, (IDirect3DBaseTexture9 **)&cur_texture);
+ ok(cur_texture == texture, "Unexpected current texture %p.\n", cur_texture);
+ IDirect3DTexture9_Release(cur_texture);
+
+ hr = effect->lpVtbl->EndPass(effect);
+ ok(hr == D3D_OK, "EndPass() failed, hr %#x.\n", hr);
+ hr = effect->lpVtbl->End(effect);
+ ok(hr == D3D_OK, "End() failed, hr %#x.\n", hr);
+
+ IDirect3DDevice9_GetTexture(device, 0, (IDirect3DBaseTexture9 **)&cur_texture);
+ ok(cur_texture == texture, "Unexpected current texture %p.\n", cur_texture);
+ IDirect3DTexture9_Release(cur_texture);
+ refcount = get_texture_refcount(texture);
+ ok(refcount == 2, "Unexpected texture refcount %u.\n", refcount);
+
+ hr = effect->lpVtbl->OnLostDevice(effect);
+ ok(hr == D3D_OK, "OnLostDevice() failed, hr %#x.\n", hr);
+ refcount = get_texture_refcount(texture);
+ ok(refcount == 1, "Unexpected texture refcount %u.\n", refcount);
+
+ hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED,
+ &managed_texture, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ effect->lpVtbl->SetTexture(effect, "tex1", (IDirect3DBaseTexture9 *)managed_texture);
+
+ refcount = get_texture_refcount(managed_texture);
+ ok(refcount == 2, "Unexpected texture refcount %u.\n", refcount);
+ hr = effect->lpVtbl->OnLostDevice(effect);
+ ok(hr == D3D_OK, "OnLostDevice() failed, hr %#x.\n", hr);
+ refcount = get_texture_refcount(managed_texture);
+ ok(refcount == 2, "Unexpected texture refcount %u.\n", refcount);
+
+ hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
+ &sysmem_texture, NULL);
+ ok(hr == D3D_OK, "Failed to create texture, hr %#x.\n", hr);
+ effect->lpVtbl->SetTexture(effect, "tex1", (IDirect3DBaseTexture9 *)sysmem_texture);
+
+ refcount = get_texture_refcount(managed_texture);
+ ok(refcount == 1, "Unexpected texture refcount %u.\n", refcount);
+ IDirect3DTexture9_Release(managed_texture);
+ refcount = get_texture_refcount(sysmem_texture);
+ ok(refcount == 2, "Unexpected texture refcount %u.\n", refcount);
+ hr = effect->lpVtbl->OnLostDevice(effect);
+ ok(hr == D3D_OK, "OnLostDevice() failed, hr %#x.\n", hr);
+ refcount = get_texture_refcount(sysmem_texture);
+ ok(refcount == 2, "Unexpected texture refcount %u.\n", refcount);
+
+ effect->lpVtbl->Release(effect);
+
+ refcount = get_texture_refcount(sysmem_texture);
+ ok(refcount == 1, "Unexpected texture refcount %u.\n", refcount);
+ IDirect3DTexture9_Release(sysmem_texture);
+
+ IDirect3DDevice9_GetTexture(device, 0, (IDirect3DBaseTexture9 **)&cur_texture);
+ ok(cur_texture == texture, "Unexpected current texture %p.\n", cur_texture);
+ IDirect3DTexture9_Release(cur_texture);
+ refcount = get_texture_refcount(texture);
+ ok(refcount == 1, "Unexpected texture refcount %u.\n", refcount);
+ IDirect3DTexture9_Release(texture);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ DestroyWindow(window);
+}
+
+static HRESULT WINAPI d3dxinclude_open(ID3DXInclude *iface, D3DXINCLUDE_TYPE include_type,
+ const char *filename, const void *parent_data, const void **data, UINT *bytes)
+{
+ static const char include1[] =
+ "float4 light;\n"
+ "float4x4 mat;\n"
+ "float4 color;\n"
+ "\n"
+ "struct vs_input\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float3 normal : NORMAL;\n"
+ "};\n"
+ "\n"
+ "struct vs_output\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float4 diffuse : COLOR;\n"
+ "};\n";
+ static const char include2[] =
+ "#include \"include1.h\"\n"
+ "\n"
+ "vs_output vs_main(const vs_input v)\n"
+ "{\n"
+ " vs_output o;\n"
+ " const float4 scaled_color = 0.5 * color;\n"
+ "\n"
+ " o.position = mul(v.position, mat);\n"
+ " o.diffuse = dot((float3)light, v.normal) * scaled_color;\n"
+ "\n"
+ " return o;\n"
+ "}\n";
+ static const char effect2[] =
+ "#include \"include\\include2.h\"\n"
+ "\n"
+ "technique t\n"
+ "{\n"
+ " pass p\n"
+ " {\n"
+ " VertexShader = compile vs_2_0 vs_main();\n"
+ " }\n"
+ "}\n";
+ char *buffer;
+
+ trace("filename %s.\n", filename);
+ trace("parent_data %p: %s.\n", parent_data, parent_data ? (char *)parent_data : "(null)");
+
+ if (!strcmp(filename, "effect2.fx"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(effect2));
+ memcpy(buffer, effect2, sizeof(effect2));
+ *bytes = sizeof(effect2);
+ ok(!parent_data, "Unexpected parent_data value.\n");
+ }
+ else if (!strcmp(filename, "include1.h"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include1));
+ memcpy(buffer, include1, sizeof(include1));
+ *bytes = sizeof(include1);
+ ok(!strncmp(parent_data, include2, strlen(include2)), "Unexpected parent_data value.\n");
+ }
+ else if (!strcmp(filename, "include\\include2.h"))
+ {
+ buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(include2));
+ memcpy(buffer, include2, sizeof(include2));
+ *bytes = sizeof(include2);
+ todo_wine ok(parent_data && !strncmp(parent_data, effect2, strlen(effect2)),
+ "unexpected parent_data value.\n");
+ }
+ else
+ {
+ ok(0, "Unexpected #include for file %s.\n", filename);
+ return D3DERR_INVALIDCALL;
+ }
+ *data = buffer;
+ return S_OK;
+}
+
+static HRESULT WINAPI d3dxinclude_close(ID3DXInclude *iface, const void *data)
+{
+ HeapFree(GetProcessHeap(), 0, (void *)data);
+ return S_OK;
+}
+
+static const struct ID3DXIncludeVtbl d3dxinclude_vtbl =
+{
+ d3dxinclude_open,
+ d3dxinclude_close
+};
+
+struct d3dxinclude
+{
+ ID3DXInclude ID3DXInclude_iface;
+};
+
+static void test_create_effect_from_file(void)
+{
+ static const char effect1[] =
+ "float4 light;\n"
+ "float4x4 mat;\n"
+ "float4 color;\n"
+ "\n"
+ "struct vs_input\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float3 normal : NORMAL;\n"
+ "};\n"
+ "\n"
+ "struct vs_output\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float4 diffuse : COLOR;\n"
+ "};\n"
+ "\n"
+ "vs_output vs_main(const vs_input v)\n"
+ "{\n"
+ " vs_output o;\n"
+ " const float4 scaled_color = 0.5 * color;\n"
+ "\n"
+ " o.position = mul(v.position, mat);\n"
+ " o.diffuse = dot((float3)light, v.normal) * scaled_color;\n"
+ "\n"
+ " return o;\n"
+ "}\n"
+ "\n"
+ "technique t\n"
+ "{\n"
+ " pass p\n"
+ " {\n"
+ " VertexShader = compile vs_2_0 vs_main();\n"
+ " }\n"
+ "}\n";
+ static const char include1[] =
+ "float4 light;\n"
+ "float4x4 mat;\n"
+ "float4 color;\n"
+ "\n"
+ "struct vs_input\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float3 normal : NORMAL;\n"
+ "};\n"
+ "\n"
+ "struct vs_output\n"
+ "{\n"
+ " float4 position : POSITION;\n"
+ " float4 diffuse : COLOR;\n"
+ "};\n";
+ static const char include1_wrong[] =
+ "#error \"wrong include\"\n";
+ static const char include2[] =
+ "#include \"include1.h\"\n"
+ "\n"
+ "vs_output vs_main(const vs_input v)\n"
+ "{\n"
+ " vs_output o;\n"
+ " const float4 scaled_color = 0.5 * color;\n"
+ "\n"
+ " o.position = mul(v.position, mat);\n"
+ " o.diffuse = dot((float3)light, v.normal) * scaled_color;\n"
+ "\n"
+ " return o;\n"
+ "}\n";
+ static const char effect2[] =
+ "#include \"include\\include2.h\"\n"
+ "\n"
+ "technique t\n"
+ "{\n"
+ " pass p\n"
+ " {\n"
+ " VertexShader = compile vs_2_0 vs_main();\n"
+ " }\n"
+ "}\n";
+ static const WCHAR effect1_filename_w[] = {'e','f','f','e','c','t','1','.','f','x',0};
+ static const WCHAR effect2_filename_w[] = {'e','f','f','e','c','t','2','.','f','x',0};
+ WCHAR effect_path_w[MAX_PATH], filename_w[MAX_PATH];
+ char effect_path[MAX_PATH], filename[MAX_PATH];
+ D3DPRESENT_PARAMETERS present_parameters = {0};
+ unsigned int filename_size;
+ struct d3dxinclude include;
+ IDirect3DDevice9 *device;
+ ID3DXBuffer *messages;
+ ID3DXEffect *effect;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Failed to create window.\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Failed to create IDirect3D9 object.\n");
+ DestroyWindow(window);
+ return;
+ }
+ present_parameters.Windowed = TRUE;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+ return;
+ }
+
+ if (!create_file("effect1.fx", effect1, sizeof(effect1) - 1, filename))
+ {
+ skip("Couldn't create temporary file, skipping test.\n");
+ return;
+ }
+
+ filename_size = strlen(filename);
+ filename_size -= sizeof("effect1.fx") - 1;
+ memcpy(effect_path, filename, filename_size);
+ effect_path[filename_size] = 0;
+ MultiByteToWideChar(CP_ACP, 0, effect_path, -1, effect_path_w, ARRAY_SIZE(effect_path_w));
+
+ create_directory("include");
+ create_file("effect2.fx", effect2, sizeof(effect2) - 1, NULL);
+ create_file("include\\include1.h", include1, sizeof(include1) - 1, NULL);
+ create_file("include\\include2.h", include2, sizeof(include2) - 1, NULL);
+ create_file("include1.h", include1_wrong, sizeof(include1_wrong) - 1, NULL);
+
+ lstrcpyW(filename_w, effect_path_w);
+ lstrcatW(filename_w, effect1_filename_w);
+ effect = NULL;
+ messages = NULL;
+ hr = D3DXCreateEffectFromFileExW(device, filename_w, NULL, NULL, NULL,
+ 0, NULL, &effect, &messages);
+ todo_wine ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ if (messages)
+ {
+ trace("D3DXCreateEffectFromFileExW messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (effect)
+ effect->lpVtbl->Release(effect);
+
+ lstrcpyW(filename_w, effect_path_w);
+ lstrcatW(filename_w, effect2_filename_w);
+ effect = NULL;
+ messages = NULL;
+ /* This is apparently broken on native, it ends up using the wrong include. */
+ hr = D3DXCreateEffectFromFileExW(device, filename_w, NULL, NULL, NULL,
+ 0, NULL, &effect, &messages);
+ todo_wine ok(hr == E_FAIL, "Unexpected error, hr %#x.\n", hr);
+ if (messages)
+ {
+ trace("D3DXCreateEffectFromFileExW messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+ if (effect)
+ effect->lpVtbl->Release(effect);
+
+ delete_file("effect1.fx");
+ delete_file("effect2.fx");
+ delete_file("include\\include1.h");
+ delete_file("include\\include2.h");
+ delete_file("include2.h");
+ delete_directory("include");
+
+ lstrcpyW(filename_w, effect2_filename_w);
+ effect = NULL;
+ messages = NULL;
+ include.ID3DXInclude_iface.lpVtbl = &d3dxinclude_vtbl;
+ /* This is actually broken in native d3dx9 (manually tried multiple
+ * versions, all are affected). For reference, the message printed below
+ * is "ID3DXEffectCompiler: There were no techniques" */
+ hr = D3DXCreateEffectFromFileExW(device, filename_w, NULL, &include.ID3DXInclude_iface, NULL,
+ 0, NULL, &effect, &messages);
+ todo_wine ok(hr == E_FAIL, "D3DXInclude test failed with error %#x.\n", hr);
+ if (messages)
+ {
+ trace("D3DXCreateEffectFromFileExW messages:\n%s", (char *)ID3DXBuffer_GetBufferPointer(messages));
+ ID3DXBuffer_Release(messages);
+ }
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
+#if 0
+technique tech0
+{
+ pass p0
+ {
+ LightEnable[0] = FALSE;
+ FogEnable = FALSE;
+ }
+}
+technique tech1
+{
+ pass p0
+ {
+ LightEnable[0] = TRUE;
+ FogEnable = TRUE;
+ }
+}
+#endif
+static const DWORD test_two_techniques_blob[] =
+{
+ 0xfeff0901, 0x000000ac, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000002, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000030,
+ 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000002, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000001,
+ 0x00000003, 0x00003070, 0x00000006, 0x68636574, 0x00000031, 0x00000000, 0x00000002, 0x00000002,
+ 0x00000001, 0x0000004c, 0x00000000, 0x00000001, 0x00000044, 0x00000000, 0x00000002, 0x00000091,
+ 0x00000000, 0x00000008, 0x00000004, 0x0000000e, 0x00000000, 0x00000028, 0x00000024, 0x000000a0,
+ 0x00000000, 0x00000001, 0x00000098, 0x00000000, 0x00000002, 0x00000091, 0x00000000, 0x0000005c,
+ 0x00000058, 0x0000000e, 0x00000000, 0x0000007c, 0x00000078, 0x00000000, 0x00000000,
+};
+
+static void test_effect_find_next_valid_technique(void)
+{
+ D3DPRESENT_PARAMETERS present_parameters = {0};
+ IDirect3DDevice9 *device;
+ D3DXTECHNIQUE_DESC desc;
+ ID3DXEffect *effect;
+ IDirect3D9 *d3d;
+ D3DXHANDLE tech;
+ ULONG refcount;
+ HWND window;
+ HRESULT hr;
+
+ if (!(window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Failed to create window.\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Failed to create IDirect3D9 object.\n");
+ DestroyWindow(window);
+ return;
+ }
+ present_parameters.Windowed = TRUE;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+ return;
+ }
+
+ hr = D3DXCreateEffectEx(device, test_two_techniques_blob, sizeof(test_two_techniques_blob),
+ NULL, NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, &tech);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech1"), "Got unexpected technique %s.\n", desc.Name);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == S_FALSE, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name);
+
+ effect->lpVtbl->Release(effect);
+
+ hr = D3DXCreateEffectEx(device, test_effect_unsupported_shader_blob, sizeof(test_effect_unsupported_shader_blob),
+ NULL, NULL, NULL, 0, NULL, &effect, NULL);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, &tech);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech1"), "Got unexpected technique %s.\n", desc.Name);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == S_FALSE, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name);
+
+ effect->lpVtbl->SetInt(effect, "i", 1);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+ tech = (D3DXHANDLE)0xdeadbeef;
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, NULL, &tech);
+ ok(hr == S_FALSE, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech0"), "Got unexpected technique %s.\n", desc.Name);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == S_FALSE, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->SetInt(effect, "i", 0);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ hr = effect->lpVtbl->GetTechniqueDesc(effect, tech, &desc);
+ ok(hr == D3D_OK, "Got result %#x.\n", hr);
+ ok(!strcmp(desc.Name, "tech1"), "Got unexpected technique %s.\n", desc.Name);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, tech, &tech);
+ ok(hr == S_FALSE, "Got result %#x.\n", hr);
+
+ hr = effect->lpVtbl->FindNextValidTechnique(effect, "nope", &tech);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+ effect->lpVtbl->Release(effect);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
+START_TEST(effect)
+{
+ IDirect3DDevice9 *device;
+ ULONG refcount;
+ HWND wnd;
+
+ if (!(device = create_device(&wnd)))
+ return;
+
+ test_create_effect_and_pool(device);
+ test_create_effect_compiler();
+ test_effect_parameter_value(device);
+ test_effect_setvalue_object(device);
+ test_effect_variable_names(device);
+ test_effect_compilation_errors(device);
+ test_effect_states(device);
+ test_effect_preshader(device);
+ test_effect_preshader_ops(device);
+ test_effect_isparameterused(device);
+ test_effect_out_of_bounds_selector(device);
+ test_effect_commitchanges(device);
+ test_effect_preshader_relative_addressing(device);
+ test_effect_state_manager(device);
+ test_cross_effect_handle(device);
+ test_effect_shared_parameters(device);
+ test_effect_large_address_aware_flag(device);
+ test_effect_get_pass_desc(device);
+ test_effect_skip_constants(device);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+ DestroyWindow(wnd);
+
+ test_effect_unsupported_shader();
+ test_effect_null_shader();
+ test_effect_clone();
+ test_refcount();
+ test_create_effect_from_file();
+ test_effect_find_next_valid_technique();
+}
--- /dev/null
+/*
+ * Copyright 2010 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+#include "d3dx9.h"
+
+#define admitted_error 0.0001f
+
+#define relative_error(exp, out) ((exp == 0.0f) ? fabs(exp - out) : (fabs(1.0f - out/ exp) ))
+
+static inline BOOL compare_matrix(const D3DXMATRIX *m1, const D3DXMATRIX *m2)
+{
+ int i, j;
+
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ if (relative_error(U(*m1).m[i][j], U(*m2).m[i][j]) > admitted_error)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+#define expect_mat(expectedmat, gotmat) \
+do { \
+ const D3DXMATRIX *__m1 = (expectedmat); \
+ const D3DXMATRIX *__m2 = (gotmat); \
+ ok(compare_matrix(__m1, __m2), "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n" \
+ "Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n", \
+ U(*__m1).m[0][0], U(*__m1).m[0][1], U(*__m1).m[0][2], U(*__m1).m[0][3], \
+ U(*__m1).m[1][0], U(*__m1).m[1][1], U(*__m1).m[1][2], U(*__m1).m[1][3], \
+ U(*__m1).m[2][0], U(*__m1).m[2][1], U(*__m1).m[2][2], U(*__m1).m[2][3], \
+ U(*__m1).m[3][0], U(*__m1).m[3][1], U(*__m1).m[3][2], U(*__m1).m[3][3], \
+ U(*__m2).m[0][0], U(*__m2).m[0][1], U(*__m2).m[0][2], U(*__m2).m[0][3], \
+ U(*__m2).m[1][0], U(*__m2).m[1][1], U(*__m2).m[1][2], U(*__m2).m[1][3], \
+ U(*__m2).m[2][0], U(*__m2).m[2][1], U(*__m2).m[2][2], U(*__m2).m[2][3], \
+ U(*__m2).m[3][0], U(*__m2).m[3][1], U(*__m2).m[3][2], U(*__m2).m[3][3]); \
+} while(0)
+
+static void test_create_line(IDirect3DDevice9* device)
+{
+ HRESULT hr;
+ ID3DXLine *line = NULL;
+ struct IDirect3DDevice9 *return_device;
+ D3DXMATRIX world, identity, result;
+ FLOAT r11, r12, r13, r14;
+ ULONG ref;
+
+ /* Arbitrary values for matrix tests. */
+ r11 = 0.1421; r12 = 0.2114; r13 = 0.8027; r14 = 0.4587;
+
+ hr = D3DXCreateLine(NULL, &line);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateLine(device, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateLine(device, &line);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (FAILED(hr))
+ {
+ return;
+ }
+
+ hr = ID3DXLine_GetDevice(line, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3D_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXLine_GetDevice(line, &return_device);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(return_device == device, "Expected line device %p, got %p\n", device, return_device);
+
+ D3DXMatrixIdentity(&world);
+ D3DXMatrixIdentity(&identity);
+ S(U(world))._11 = r11; S(U(world))._12 = r12; S(U(world))._13 = r13; S(U(world))._14 = r14;
+
+ hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &world);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = ID3DXLine_Begin(line);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &result);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ expect_mat(&identity, &result);
+
+ hr = ID3DXLine_End(line);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &result);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ expect_mat(&world, &result);
+
+ IDirect3DDevice9_Release(return_device);
+
+ ref = ID3DXLine_Release(line);
+ ok(ref == 0, "Got %x references to line %p, expected 0\n", ref, line);
+}
+
+START_TEST(line)
+{
+ HWND wnd;
+ IDirect3D9* d3d;
+ IDirect3DDevice9* device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr)) {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ test_create_line(device);
+
+ IDirect3DDevice9_Release(device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+}
--- /dev/null
+/*
+ * Copyright 2008 David Adam
+ * Copyright 2008 Luis Busquets
+ * Copyright 2008 Philip Nilsson
+ * Copyright 2008 Henri Verbeet
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+#include "d3dx9.h"
+#include <math.h>
+
+static BOOL compare_float(float f, float g, unsigned int ulps)
+{
+ int x = *(int *)&f;
+ int y = *(int *)&g;
+
+ if (x < 0)
+ x = INT_MIN - x;
+ if (y < 0)
+ y = INT_MIN - y;
+
+ if (abs(x - y) > ulps)
+ return FALSE;
+
+ return TRUE;
+}
+
+static BOOL compare_vec2(const D3DXVECTOR2 *v1, const D3DXVECTOR2 *v2, unsigned int ulps)
+{
+ return compare_float(v1->x, v2->x, ulps) && compare_float(v1->y, v2->y, ulps);
+}
+
+static BOOL compare_vec3(const D3DXVECTOR3 *v1, const D3DXVECTOR3 *v2, unsigned int ulps)
+{
+ return compare_float(v1->x, v2->x, ulps)
+ && compare_float(v1->y, v2->y, ulps)
+ && compare_float(v1->z, v2->z, ulps);
+}
+
+static BOOL compare_vec4(const D3DXVECTOR4 *v1, const D3DXVECTOR4 *v2, unsigned int ulps)
+{
+ return compare_float(v1->x, v2->x, ulps)
+ && compare_float(v1->y, v2->y, ulps)
+ && compare_float(v1->z, v2->z, ulps)
+ && compare_float(v1->w, v2->w, ulps);
+}
+
+static BOOL compare_color(const D3DXCOLOR *c1, const D3DXCOLOR *c2, unsigned int ulps)
+{
+ return compare_float(c1->r, c2->r, ulps)
+ && compare_float(c1->g, c2->g, ulps)
+ && compare_float(c1->b, c2->b, ulps)
+ && compare_float(c1->a, c2->a, ulps);
+}
+
+static BOOL compare_plane(const D3DXPLANE *p1, const D3DXPLANE *p2, unsigned int ulps)
+{
+ return compare_float(p1->a, p2->a, ulps)
+ && compare_float(p1->b, p2->b, ulps)
+ && compare_float(p1->c, p2->c, ulps)
+ && compare_float(p1->d, p2->d, ulps);
+}
+
+static BOOL compare_quaternion(const D3DXQUATERNION *q1, const D3DXQUATERNION *q2, unsigned int ulps)
+{
+ return compare_float(q1->x, q2->x, ulps)
+ && compare_float(q1->y, q2->y, ulps)
+ && compare_float(q1->z, q2->z, ulps)
+ && compare_float(q1->w, q2->w, ulps);
+}
+
+static BOOL compare_matrix(const D3DXMATRIX *m1, const D3DXMATRIX *m2, unsigned int ulps)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ if (!compare_float(U(*m1).m[i][j], U(*m2).m[i][j], ulps))
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+#define expect_vec2(expected, vector, ulps) expect_vec2_(__LINE__, expected, vector, ulps)
+static void expect_vec2_(unsigned int line, const D3DXVECTOR2 *expected, const D3DXVECTOR2 *vector, unsigned int ulps)
+{
+ BOOL equal = compare_vec2(expected, vector, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected vector {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
+ vector->x, vector->y, expected->x, expected->y);
+}
+
+#define expect_vec3(expected, vector, ulps) expect_vec3_(__LINE__, expected, vector, ulps)
+static void expect_vec3_(unsigned int line, const D3DXVECTOR3 *expected, const D3DXVECTOR3 *vector, unsigned int ulps)
+{
+ BOOL equal = compare_vec3(expected, vector, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected vector {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
+ vector->x, vector->y, vector->z, expected->x, expected->y, expected->z);
+}
+
+#define expect_vec4(expected, vector, ulps) expect_vec4_(__LINE__, expected, vector, ulps)
+static void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, const D3DXVECTOR4 *vector, unsigned int ulps)
+{
+ BOOL equal = compare_vec4(expected, vector, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected vector {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ vector->x, vector->y, vector->z, vector->w, expected->x, expected->y, expected->z, expected->w);
+}
+
+#define expect_color(expected, color, ulps) expect_color_(__LINE__, expected, color, ulps)
+static void expect_color_(unsigned int line, const D3DXCOLOR *expected, const D3DXCOLOR *color, unsigned int ulps)
+{
+ BOOL equal = compare_color(expected, color, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected color {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ color->r, color->g, color->b, color->a, expected->r, expected->g, expected->b, expected->a);
+}
+
+#define expect_plane(expected, plane, ulps) expect_plane_(__LINE__, expected, plane, ulps)
+static void expect_plane_(unsigned int line, const D3DXPLANE *expected, const D3DXPLANE *plane, unsigned int ulps)
+{
+ BOOL equal = compare_plane(expected, plane, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected plane {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ plane->a, plane->b, plane->c, plane->d, expected->a, expected->b, expected->c, expected->d);
+}
+
+#define expect_quaternion(expected, quaternion, ulps) expect_quaternion_(__LINE__, expected, quaternion, ulps)
+static void expect_quaternion_(unsigned int line, const D3DXQUATERNION *expected,
+ const D3DXQUATERNION *quaternion, unsigned int ulps)
+{
+ BOOL equal = compare_quaternion(expected, quaternion, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected quaternion {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ quaternion->x, quaternion->y, quaternion->z, quaternion->w,
+ expected->x, expected->y, expected->z, expected->w);
+}
+
+#define expect_matrix(expected, matrix, ulps) expect_matrix_(__LINE__, expected, matrix, ulps)
+static void expect_matrix_(unsigned int line, const D3DXMATRIX *expected, const D3DXMATRIX *matrix, unsigned int ulps)
+{
+ BOOL equal = compare_matrix(expected, matrix, ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, "
+ "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
+ "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, "
+ "%.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
+ U(*matrix).m[0][0], U(*matrix).m[0][1], U(*matrix).m[0][2], U(*matrix).m[0][3],
+ U(*matrix).m[1][0], U(*matrix).m[1][1], U(*matrix).m[1][2], U(*matrix).m[1][3],
+ U(*matrix).m[2][0], U(*matrix).m[2][1], U(*matrix).m[2][2], U(*matrix).m[2][3],
+ U(*matrix).m[3][0], U(*matrix).m[3][1], U(*matrix).m[3][2], U(*matrix).m[3][3],
+ U(*expected).m[0][0], U(*expected).m[0][1], U(*expected).m[0][2], U(*expected).m[0][3],
+ U(*expected).m[1][0], U(*expected).m[1][1], U(*expected).m[1][2], U(*expected).m[1][3],
+ U(*expected).m[2][0], U(*expected).m[2][1], U(*expected).m[2][2], U(*expected).m[2][3],
+ U(*expected).m[3][0], U(*expected).m[3][1], U(*expected).m[3][2], U(*expected).m[3][3]);
+}
+
+#define expect_vec4_array(count, expected, vector, ulps) expect_vec4_array_(__LINE__, count, expected, vector, ulps)
+static void expect_vec4_array_(unsigned int line, unsigned int count, const D3DXVECTOR4 *expected,
+ const D3DXVECTOR4 *vector, unsigned int ulps)
+{
+ BOOL equal;
+ unsigned int i;
+
+ for (i = 0; i < count; ++i)
+ {
+ equal = compare_vec4(&expected[i], &vector[i], ulps);
+ ok_(__FILE__, line)(equal,
+ "Got unexpected vector {%.8e, %.8e, %.8e, %.8e} at index %u, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ vector[i].x, vector[i].y, vector[i].z, vector[i].w, i,
+ expected[i].x, expected[i].y, expected[i].z, expected[i].w);
+ if (!equal)
+ break;
+ }
+}
+
+static void set_matrix(D3DXMATRIX* mat,
+ float m00, float m01, float m02, float m03,
+ float m10, float m11, float m12, float m13,
+ float m20, float m21, float m22, float m23,
+ float m30, float m31, float m32, float m33)
+{
+ U(mat)->m[0][0] = m00; U(mat)->m[0][1] = m01; U(mat)->m[0][2] = m02; U(mat)->m[0][3] = m03;
+ U(mat)->m[1][0] = m10; U(mat)->m[1][1] = m11; U(mat)->m[1][2] = m12; U(mat)->m[1][3] = m13;
+ U(mat)->m[2][0] = m20; U(mat)->m[2][1] = m21; U(mat)->m[2][2] = m22; U(mat)->m[2][3] = m23;
+ U(mat)->m[3][0] = m30; U(mat)->m[3][1] = m31; U(mat)->m[3][2] = m32; U(mat)->m[3][3] = m33;
+}
+
+static void D3DXColorTest(void)
+{
+ D3DXCOLOR color, color1, color2, expected, got;
+ LPD3DXCOLOR funcpointer;
+ FLOAT scale;
+
+ color.r = 0.2f; color.g = 0.75f; color.b = 0.41f; color.a = 0.93f;
+ color1.r = 0.6f; color1.g = 0.55f; color1.b = 0.23f; color1.a = 0.82f;
+ color2.r = 0.3f; color2.g = 0.5f; color2.b = 0.76f; color2.a = 0.11f;
+
+ scale = 0.3f;
+
+/*_______________D3DXColorAdd________________*/
+ expected.r = 0.9f; expected.g = 1.05f; expected.b = 0.99f, expected.a = 0.93f;
+ D3DXColorAdd(&got,&color1,&color2);
+ expect_color(&expected, &got, 1);
+ /* Test the NULL case */
+ funcpointer = D3DXColorAdd(&got,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorAdd(NULL,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorAdd(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXColorAdjustContrast______*/
+ expected.r = 0.41f; expected.g = 0.575f; expected.b = 0.473f, expected.a = 0.93f;
+ D3DXColorAdjustContrast(&got,&color,scale);
+ expect_color(&expected, &got, 0);
+
+/*_______________D3DXColorAdjustSaturation______*/
+ expected.r = 0.486028f; expected.g = 0.651028f; expected.b = 0.549028f, expected.a = 0.93f;
+ D3DXColorAdjustSaturation(&got,&color,scale);
+ expect_color(&expected, &got, 16);
+
+/*_______________D3DXColorLerp________________*/
+ expected.r = 0.32f; expected.g = 0.69f; expected.b = 0.356f; expected.a = 0.897f;
+ D3DXColorLerp(&got,&color,&color1,scale);
+ expect_color(&expected, &got, 0);
+ /* Test the NULL case */
+ funcpointer = D3DXColorLerp(&got,NULL,&color1,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorLerp(NULL,NULL,&color1,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorLerp(NULL,NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXColorModulate________________*/
+ expected.r = 0.18f; expected.g = 0.275f; expected.b = 0.1748f; expected.a = 0.0902f;
+ D3DXColorModulate(&got,&color1,&color2);
+ expect_color(&expected, &got, 0);
+ /* Test the NULL case */
+ funcpointer = D3DXColorModulate(&got,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorModulate(NULL,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorModulate(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXColorNegative________________*/
+ expected.r = 0.8f; expected.g = 0.25f; expected.b = 0.59f; expected.a = 0.93f;
+ D3DXColorNegative(&got,&color);
+ expect_color(&expected, &got, 1);
+ /* Test the greater than 1 case */
+ color1.r = 0.2f; color1.g = 1.75f; color1.b = 0.41f; color1.a = 0.93f;
+ expected.r = 0.8f; expected.g = -0.75f; expected.b = 0.59f; expected.a = 0.93f;
+ D3DXColorNegative(&got,&color1);
+ expect_color(&expected, &got, 1);
+ /* Test the negative case */
+ color1.r = 0.2f; color1.g = -0.75f; color1.b = 0.41f; color1.a = 0.93f;
+ expected.r = 0.8f; expected.g = 1.75f; expected.b = 0.59f; expected.a = 0.93f;
+ D3DXColorNegative(&got,&color1);
+ expect_color(&expected, &got, 1);
+ /* Test the NULL case */
+ funcpointer = D3DXColorNegative(&got,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorNegative(NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXColorScale________________*/
+ expected.r = 0.06f; expected.g = 0.225f; expected.b = 0.123f; expected.a = 0.279f;
+ D3DXColorScale(&got,&color,scale);
+ expect_color(&expected, &got, 1);
+ /* Test the NULL case */
+ funcpointer = D3DXColorScale(&got,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorScale(NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXColorSubtract_______________*/
+ expected.r = -0.1f; expected.g = 0.25f; expected.b = -0.35f, expected.a = 0.82f;
+ D3DXColorSubtract(&got,&color,&color2);
+ expect_color(&expected, &got, 1);
+ /* Test the NULL case */
+ funcpointer = D3DXColorSubtract(&got,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorSubtract(NULL,NULL,&color2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXColorSubtract(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+}
+
+static void D3DXFresnelTest(void)
+{
+ float fresnel;
+ BOOL equal;
+
+ fresnel = D3DXFresnelTerm(0.5f, 1.5f);
+ equal = compare_float(fresnel, 8.91867128e-02f, 1);
+ ok(equal, "Got unexpected Fresnel term %.8e.\n", fresnel);
+}
+
+static void D3DXMatrixTest(void)
+{
+ D3DXMATRIX expectedmat, gotmat, mat, mat2, mat3;
+ BOOL expected, got, equal;
+ float angle, determinant;
+ D3DXMATRIX *funcpointer;
+ D3DXPLANE plane;
+ D3DXQUATERNION q, r;
+ D3DXVECTOR3 at, axis, eye, last;
+ D3DXVECTOR4 light;
+
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = 10.0f; U(mat).m[1][1] = 20.0f; U(mat).m[2][2] = 30.0f;
+ U(mat).m[3][3] = -40.0f;
+
+ U(mat2).m[0][0] = 1.0f; U(mat2).m[1][0] = 2.0f; U(mat2).m[2][0] = 3.0f;
+ U(mat2).m[3][0] = 4.0f; U(mat2).m[0][1] = 5.0f; U(mat2).m[1][1] = 6.0f;
+ U(mat2).m[2][1] = 7.0f; U(mat2).m[3][1] = 8.0f; U(mat2).m[0][2] = -8.0f;
+ U(mat2).m[1][2] = -7.0f; U(mat2).m[2][2] = -6.0f; U(mat2).m[3][2] = -5.0f;
+ U(mat2).m[0][3] = -4.0f; U(mat2).m[1][3] = -3.0f; U(mat2).m[2][3] = -2.0f;
+ U(mat2).m[3][3] = -1.0f;
+
+ plane.a = -3.0f; plane.b = -1.0f; plane.c = 4.0f; plane.d = 7.0f;
+
+ q.x = 1.0f; q.y = -4.0f; q.z =7.0f; q.w = -11.0f;
+ r.x = 0.87f; r.y = 0.65f; r.z =0.43f; r.w= 0.21f;
+
+ at.x = -2.0f; at.y = 13.0f; at.z = -9.0f;
+ axis.x = 1.0f; axis.y = -3.0f; axis.z = 7.0f;
+ eye.x = 8.0f; eye.y = -5.0f; eye.z = 5.75f;
+ last.x = 9.7f; last.y = -8.6; last.z = 1.3f;
+
+ light.x = 9.6f; light.y = 8.5f; light.z = 7.4; light.w = 6.3;
+
+ angle = D3DX_PI/3.0f;
+
+/*____________D3DXMatrixAffineTransformation______*/
+ set_matrix(&expectedmat,
+ -459.239990f, -576.719971f, -263.440002f, 0.0f,
+ 519.760010f, -352.440002f, -277.679993f, 0.0f,
+ 363.119995f, -121.040001f, -117.479996f, 0.0f,
+ -1239.0f, 667.0f, 567.0f, 1.0f);
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, &at, &q, &axis);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ /* Test the NULL case */
+ U(expectedmat).m[3][0] = 1.0f; U(expectedmat).m[3][1] = -3.0f; U(expectedmat).m[3][2] = 7.0f; U(expectedmat).m[3][3] = 1.0f;
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, NULL, &q, &axis);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ U(expectedmat).m[3][0] = -1240.0f; U(expectedmat).m[3][1] = 670.0f; U(expectedmat).m[3][2] = 560.0f; U(expectedmat).m[3][3] = 1.0f;
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, &at, &q, NULL);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ U(expectedmat).m[3][0] = 0.0f; U(expectedmat).m[3][1] = 0.0f; U(expectedmat).m[3][2] = 0.0f; U(expectedmat).m[3][3] = 1.0f;
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, NULL, &q, NULL);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ set_matrix(&expectedmat,
+ 3.56f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 3.56f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 3.56f, 0.0f,
+ 1.0f, -3.0f, 7.0f, 1.0f);
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, NULL, NULL, &axis);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, &at, NULL, &axis);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ U(expectedmat).m[3][0] = 0.0f; U(expectedmat).m[3][1] = 0.0f; U(expectedmat).m[3][2] = 0.0f; U(expectedmat).m[3][3] = 1.0f;
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, &at, NULL, NULL);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+ D3DXMatrixAffineTransformation(&gotmat, 3.56f, NULL, NULL, NULL);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixfDeterminant_____________*/
+ determinant = D3DXMatrixDeterminant(&mat);
+ equal = compare_float(determinant, -147888.0f, 0);
+ ok(equal, "Got unexpected determinant %.8e.\n", determinant);
+
+/*____________D3DXMatrixInverse______________*/
+ set_matrix(&expectedmat,
+ 16067.0f/73944.0f, -10165.0f/147888.0f, -2729.0f/147888.0f, -1631.0f/49296.0f,
+ -565.0f/36972.0f, 2723.0f/73944.0f, -1073.0f/73944.0f, 289.0f/24648.0f,
+ -389.0f/2054.0f, 337.0f/4108.0f, 181.0f/4108.0f, 317.0f/4108.0f,
+ 163.0f/5688.0f, -101.0f/11376.0f, -73.0f/11376.0f, -127.0f/3792.0f);
+ D3DXMatrixInverse(&gotmat, &determinant, &mat);
+ expect_matrix(&expectedmat, &gotmat, 1);
+ equal = compare_float(determinant, -147888.0f, 0);
+ ok(equal, "Got unexpected determinant %.8e.\n", determinant);
+ funcpointer = D3DXMatrixInverse(&gotmat,NULL,&mat2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*____________D3DXMatrixIsIdentity______________*/
+ expected = FALSE;
+ memset(&mat3, 0, sizeof(mat3));
+ got = D3DXMatrixIsIdentity(&mat3);
+ ok(expected == got, "Expected : %d, Got : %d\n", expected, got);
+ D3DXMatrixIdentity(&mat3);
+ expected = TRUE;
+ got = D3DXMatrixIsIdentity(&mat3);
+ ok(expected == got, "Expected : %d, Got : %d\n", expected, got);
+ U(mat3).m[0][0] = 0.000009f;
+ expected = FALSE;
+ got = D3DXMatrixIsIdentity(&mat3);
+ ok(expected == got, "Expected : %d, Got : %d\n", expected, got);
+ /* Test the NULL case */
+ expected = FALSE;
+ got = D3DXMatrixIsIdentity(NULL);
+ ok(expected == got, "Expected : %d, Got : %d\n", expected, got);
+
+/*____________D3DXMatrixLookAtLH_______________*/
+ set_matrix(&expectedmat,
+ -0.82246518f, -0.40948939f, -0.39480308f, 0.0f,
+ -0.55585691f, 0.43128574f, 0.71064550f, 0.0f,
+ -0.12072885f, 0.80393475f, -0.58233452f, 0.0f,
+ 4.4946337f, 0.80971903f, 10.060076f, 1.0f);
+ D3DXMatrixLookAtLH(&gotmat, &eye, &at, &axis);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixLookAtRH_______________*/
+ set_matrix(&expectedmat,
+ 0.82246518f, -0.40948939f, 0.39480308f, 0.0f,
+ 0.55585691f, 0.43128574f, -0.71064550f, 0.0f,
+ 0.12072885f, 0.80393475f, 0.58233452f, 0.0f,
+ -4.4946337f, 0.80971903f, -10.060076f, 1.0f);
+ D3DXMatrixLookAtRH(&gotmat, &eye, &at, &axis);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixMultiply______________*/
+ set_matrix(&expectedmat,
+ 73.0f, 193.0f, -197.0f, -77.0f,
+ 231.0f, 551.0f, -489.0f, -169.0f,
+ 239.0f, 523.0f, -400.0f, -116.0f,
+ -164.0f, -320.0f, 187.0f, 31.0f);
+ D3DXMatrixMultiply(&gotmat, &mat, &mat2);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixMultiplyTranspose____*/
+ set_matrix(&expectedmat,
+ 73.0f, 231.0f, 239.0f, -164.0f,
+ 193.0f, 551.0f, 523.0f, -320.0f,
+ -197.0f, -489.0f, -400.0f, 187.0f,
+ -77.0f, -169.0f, -116.0f, 31.0f);
+ D3DXMatrixMultiplyTranspose(&gotmat, &mat, &mat2);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixOrthoLH_______________*/
+ set_matrix(&expectedmat,
+ 0.8f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.27027027f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -0.15151515f, 0.0f,
+ 0.0f, 0.0f, -0.48484848f, 1.0f);
+ D3DXMatrixOrthoLH(&gotmat, 2.5f, 7.4f, -3.2f, -9.8f);
+ expect_matrix(&expectedmat, &gotmat, 16);
+
+/*____________D3DXMatrixOrthoOffCenterLH_______________*/
+ set_matrix(&expectedmat,
+ 3.6363636f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.18018018f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -0.045662100f, 0.0f,
+ -1.7272727f, -0.56756757f, 0.42465753f, 1.0f);
+ D3DXMatrixOrthoOffCenterLH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f, 9.3, -12.6);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixOrthoOffCenterRH_______________*/
+ set_matrix(&expectedmat,
+ 3.6363636f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.18018018f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.045662100f, 0.0f,
+ -1.7272727f, -0.56756757f, 0.42465753f, 1.0f);
+ D3DXMatrixOrthoOffCenterRH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f, 9.3, -12.6);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixOrthoRH_______________*/
+ set_matrix(&expectedmat,
+ 0.8f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.27027027f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.15151515f, 0.0f,
+ 0.0f, 0.0f, -0.48484848f, 1.0f);
+ D3DXMatrixOrthoRH(&gotmat, 2.5f, 7.4f, -3.2f, -9.8f);
+ expect_matrix(&expectedmat, &gotmat, 16);
+
+/*____________D3DXMatrixPerspectiveFovLH_______________*/
+ set_matrix(&expectedmat,
+ 13.288858f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 9.9666444f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.78378378f, 1.0f,
+ 0.0f, 0.0f, 1.8810811f, 0.0f);
+ D3DXMatrixPerspectiveFovLH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f);
+ expect_matrix(&expectedmat, &gotmat, 4);
+
+/*____________D3DXMatrixPerspectiveFovRH_______________*/
+ set_matrix(&expectedmat,
+ 13.288858f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 9.9666444f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -0.78378378f, -1.0f,
+ 0.0f, 0.0f, 1.8810811f, 0.0f);
+ D3DXMatrixPerspectiveFovRH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f);
+ expect_matrix(&expectedmat, &gotmat, 4);
+
+/*____________D3DXMatrixPerspectiveLH_______________*/
+ set_matrix(&expectedmat,
+ -24.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -6.4f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.78378378f, 1.0f,
+ 0.0f, 0.0f, 1.8810811f, 0.0f);
+ D3DXMatrixPerspectiveLH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f);
+ expect_matrix(&expectedmat, &gotmat, 4);
+
+/*____________D3DXMatrixPerspectiveOffCenterLH_______________*/
+ set_matrix(&expectedmat,
+ 11.636364f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.57657658f, 0.0f, 0.0f,
+ -1.7272727f, -0.56756757f, 0.84079602f, 1.0f,
+ 0.0f, 0.0f, -2.6905473f, 0.0f);
+ D3DXMatrixPerspectiveOffCenterLH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f, 3.2f, -16.9f);
+ expect_matrix(&expectedmat, &gotmat, 8);
+
+/*____________D3DXMatrixPerspectiveOffCenterRH_______________*/
+ set_matrix(&expectedmat,
+ 11.636364f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.57657658f, 0.0f, 0.0f,
+ 1.7272727f, 0.56756757f, -0.84079602f, -1.0f,
+ 0.0f, 0.0f, -2.6905473f, 0.0f);
+ D3DXMatrixPerspectiveOffCenterRH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f, 3.2f, -16.9f);
+ expect_matrix(&expectedmat, &gotmat, 8);
+
+/*____________D3DXMatrixPerspectiveRH_______________*/
+ set_matrix(&expectedmat,
+ -24.0f, -0.0f, 0.0f, 0.0f,
+ 0.0f, -6.4f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -0.78378378f, -1.0f,
+ 0.0f, 0.0f, 1.8810811f, 0.0f);
+ D3DXMatrixPerspectiveRH(&gotmat, 0.2f, 0.75f, -2.4f, 8.7f);
+ expect_matrix(&expectedmat, &gotmat, 4);
+
+/*____________D3DXMatrixReflect______________*/
+ set_matrix(&expectedmat,
+ 0.30769235f, -0.23076922f, 0.92307687f, 0.0f,
+ -0.23076922, 0.92307693f, 0.30769232f, 0.0f,
+ 0.92307687f, 0.30769232f, -0.23076922f, 0.0f,
+ 1.6153846f, 0.53846157f, -2.1538463f, 1.0f);
+ D3DXMatrixReflect(&gotmat, &plane);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixRotationAxis_____*/
+ set_matrix(&expectedmat,
+ 0.50847453f, 0.76380461f, 0.39756277f, 0.0f,
+ -0.81465209f, 0.57627118f, -0.065219201f, 0.0f,
+ -0.27891868f, -0.29071301f, 0.91525424f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationAxis(&gotmat, &axis, angle);
+ expect_matrix(&expectedmat, &gotmat, 32);
+
+/*____________D3DXMatrixRotationQuaternion______________*/
+ set_matrix(&expectedmat,
+ -129.0f, -162.0f, -74.0f, 0.0f,
+ 146.0f, -99.0f, -78.0f, 0.0f,
+ 102.0f, -34.0f, -33.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationQuaternion(&gotmat, &q);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixRotationX______________*/
+ set_matrix(&expectedmat,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.5f, sqrt(3.0f)/2.0f, 0.0f,
+ 0.0f, -sqrt(3.0f)/2.0f, 0.5f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationX(&gotmat, angle);
+ expect_matrix(&expectedmat, &gotmat, 1);
+
+/*____________D3DXMatrixRotationY______________*/
+ set_matrix(&expectedmat,
+ 0.5f, 0.0f, -sqrt(3.0f)/2.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ sqrt(3.0f)/2.0f, 0.0f, 0.5f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationY(&gotmat, angle);
+ expect_matrix(&expectedmat, &gotmat, 1);
+
+/*____________D3DXMatrixRotationYawPitchRoll____*/
+ set_matrix(&expectedmat,
+ 0.88877726f, 0.091874748f, -0.44903678f, 0.0f,
+ 0.35171318f, 0.49148652f, 0.79670501f, 0.0f,
+ 0.29389259f, -0.86602545f, 0.40450847f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationYawPitchRoll(&gotmat, 3.0f * angle / 5.0f, angle, 3.0f * angle / 17.0f);
+ expect_matrix(&expectedmat, &gotmat, 64);
+
+/*____________D3DXMatrixRotationZ______________*/
+ set_matrix(&expectedmat,
+ 0.5f, sqrt(3.0f)/2.0f, 0.0f, 0.0f,
+ -sqrt(3.0f)/2.0f, 0.5f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixRotationZ(&gotmat, angle);
+ expect_matrix(&expectedmat, &gotmat, 1);
+
+/*____________D3DXMatrixScaling______________*/
+ set_matrix(&expectedmat,
+ 0.69f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.53f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 4.11f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f);
+ D3DXMatrixScaling(&gotmat, 0.69f, 0.53f, 4.11f);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixShadow______________*/
+ set_matrix(&expectedmat,
+ 12.786773f, 5.0009613f, 4.3537784f, 3.7065949f,
+ 1.8827150f, 8.8056154f, 1.4512594f, 1.2355317f,
+ -7.5308599f, -6.6679487f, 1.3335901f, -4.9421268f,
+ -13.179006f, -11.668910f, -10.158816f, -1.5100943f);
+ D3DXMatrixShadow(&gotmat, &light, &plane);
+ expect_matrix(&expectedmat, &gotmat, 8);
+
+/*____________D3DXMatrixTransformation______________*/
+ set_matrix(&expectedmat,
+ -0.21480007f, 1.3116000f, 0.47520003f, 0.0f,
+ 0.95040143f, -0.88360137f, 0.92439979f, 0.0f,
+ 1.0212044f, 0.19359307f, -1.3588026f, 0.0f,
+ 18.298532f, -29.624001f, 15.683499f, 1.0f);
+ D3DXMatrixTransformation(&gotmat, &at, &q, NULL, &eye, &r, &last);
+ expect_matrix(&expectedmat, &gotmat, 512);
+
+/*____________D3DXMatrixTranslation______________*/
+ set_matrix(&expectedmat,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.69f, 0.53f, 4.11f, 1.0f);
+ D3DXMatrixTranslation(&gotmat, 0.69f, 0.53f, 4.11f);
+ expect_matrix(&expectedmat, &gotmat, 0);
+
+/*____________D3DXMatrixTranspose______________*/
+ set_matrix(&expectedmat,
+ 10.0f, 11.0f, 19.0f, 2.0f,
+ 5.0f, 20.0f, -21.0f, 3.0f,
+ 7.0f, 16.0f, 30.f, -4.0f,
+ 8.0f, 33.0f, 43.0f, -40.0f);
+ D3DXMatrixTranspose(&gotmat, &mat);
+ expect_matrix(&expectedmat, &gotmat, 0);
+}
+
+static void D3DXPlaneTest(void)
+{
+ D3DXMATRIX mat;
+ D3DXPLANE expectedplane, gotplane, nulplane, plane;
+ D3DXVECTOR3 expectedvec, gotvec, vec1, vec2, vec3;
+ LPD3DXVECTOR3 funcpointer;
+ D3DXVECTOR4 vec;
+ FLOAT expected, got;
+
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = 10.0f; U(mat).m[1][1] = 20.0f; U(mat).m[2][2] = 30.0f;
+ U(mat).m[3][3] = -40.0f;
+
+ plane.a = -3.0f; plane.b = -1.0f; plane.c = 4.0f; plane.d = 7.0f;
+
+ vec.x = 2.0f; vec.y = 5.0f; vec.z = -6.0f; vec.w = 11.0f;
+
+/*_______________D3DXPlaneDot________________*/
+ expected = 42.0f;
+ got = D3DXPlaneDot(&plane,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDot(NULL,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDot(NULL,NULL),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+
+/*_______________D3DXPlaneDotCoord________________*/
+ expected = -28.0f;
+ got = D3DXPlaneDotCoord(&plane,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDotCoord(NULL,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDotCoord(NULL,NULL),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+
+/*_______________D3DXPlaneDotNormal______________*/
+ expected = -35.0f;
+ got = D3DXPlaneDotNormal(&plane,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDotNormal(NULL,&vec),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+ expected = 0.0f;
+ got = D3DXPlaneDotNormal(NULL,NULL),
+ ok( expected == got, "Expected : %f, Got : %f\n",expected, got);
+
+/*_______________D3DXPlaneFromPointNormal_______*/
+ vec1.x = 11.0f; vec1.y = 13.0f; vec1.z = 15.0f;
+ vec2.x = 17.0f; vec2.y = 31.0f; vec2.z = 24.0f;
+ expectedplane.a = 17.0f; expectedplane.b = 31.0f; expectedplane.c = 24.0f; expectedplane.d = -950.0f;
+ D3DXPlaneFromPointNormal(&gotplane, &vec1, &vec2);
+ expect_plane(&expectedplane, &gotplane, 0);
+ gotplane.a = vec2.x; gotplane.b = vec2.y; gotplane.c = vec2.z;
+ D3DXPlaneFromPointNormal(&gotplane, &vec1, (D3DXVECTOR3 *)&gotplane);
+ expect_plane(&expectedplane, &gotplane, 0);
+ gotplane.a = vec1.x; gotplane.b = vec1.y; gotplane.c = vec1.z;
+ expectedplane.d = -1826.0f;
+ D3DXPlaneFromPointNormal(&gotplane, (D3DXVECTOR3 *)&gotplane, &vec2);
+ expect_plane(&expectedplane, &gotplane, 0);
+
+/*_______________D3DXPlaneFromPoints_______*/
+ vec1.x = 1.0f; vec1.y = 2.0f; vec1.z = 3.0f;
+ vec2.x = 1.0f; vec2.y = -6.0f; vec2.z = -5.0f;
+ vec3.x = 83.0f; vec3.y = 74.0f; vec3.z = 65.0f;
+ expectedplane.a = 0.085914f; expectedplane.b = -0.704492f; expectedplane.c = 0.704492f; expectedplane.d = -0.790406f;
+ D3DXPlaneFromPoints(&gotplane,&vec1,&vec2,&vec3);
+ expect_plane(&expectedplane, &gotplane, 64);
+
+/*_______________D3DXPlaneIntersectLine___________*/
+ vec1.x = 9.0f; vec1.y = 6.0f; vec1.z = 3.0f;
+ vec2.x = 2.0f; vec2.y = 5.0f; vec2.z = 8.0f;
+ expectedvec.x = 20.0f/3.0f; expectedvec.y = 17.0f/3.0f; expectedvec.z = 14.0f/3.0f;
+ D3DXPlaneIntersectLine(&gotvec,&plane,&vec1,&vec2);
+ expect_vec3(&expectedvec, &gotvec, 1);
+ /* Test a parallel line */
+ vec1.x = 11.0f; vec1.y = 13.0f; vec1.z = 15.0f;
+ vec2.x = 17.0f; vec2.y = 31.0f; vec2.z = 24.0f;
+ expectedvec.x = 20.0f/3.0f; expectedvec.y = 17.0f/3.0f; expectedvec.z = 14.0f/3.0f;
+ funcpointer = D3DXPlaneIntersectLine(&gotvec,&plane,&vec1,&vec2);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXPlaneNormalize______________*/
+ expectedplane.a = -3.0f/sqrt(26.0f); expectedplane.b = -1.0f/sqrt(26.0f); expectedplane.c = 4.0f/sqrt(26.0f); expectedplane.d = 7.0/sqrt(26.0f);
+ D3DXPlaneNormalize(&gotplane, &plane);
+ expect_plane(&expectedplane, &gotplane, 2);
+ nulplane.a = 0.0; nulplane.b = 0.0f, nulplane.c = 0.0f; nulplane.d = 0.0f;
+ expectedplane.a = 0.0f; expectedplane.b = 0.0f; expectedplane.c = 0.0f; expectedplane.d = 0.0f;
+ D3DXPlaneNormalize(&gotplane, &nulplane);
+ expect_plane(&expectedplane, &gotplane, 0);
+
+/*_______________D3DXPlaneTransform____________*/
+ expectedplane.a = 49.0f; expectedplane.b = -98.0f; expectedplane.c = 55.0f; expectedplane.d = -165.0f;
+ D3DXPlaneTransform(&gotplane,&plane,&mat);
+ expect_plane(&expectedplane, &gotplane, 0);
+}
+
+static void D3DXQuaternionTest(void)
+{
+ D3DXMATRIX mat;
+ D3DXQUATERNION expectedquat, gotquat, Nq, Nq1, nul, smallq, smallr, q, r, s, t, u;
+ BOOL expectedbool, gotbool, equal;
+ float angle, got, scale, scale2;
+ LPD3DXQUATERNION funcpointer;
+ D3DXVECTOR3 axis, expectedvec;
+
+ nul.x = 0.0f; nul.y = 0.0f; nul.z = 0.0f; nul.w = 0.0f;
+ q.x = 1.0f, q.y = 2.0f; q.z = 4.0f; q.w = 10.0f;
+ r.x = -3.0f; r.y = 4.0f; r.z = -5.0f; r.w = 7.0;
+ t.x = -1111.0f, t.y = 111.0f; t.z = -11.0f; t.w = 1.0f;
+ u.x = 91.0f; u.y = - 82.0f; u.z = 7.3f; u.w = -6.4f;
+ smallq.x = 0.1f; smallq.y = 0.2f; smallq.z= 0.3f; smallq.w = 0.4f;
+ smallr.x = 0.5f; smallr.y = 0.6f; smallr.z= 0.7f; smallr.w = 0.8f;
+
+ scale = 0.3f;
+ scale2 = 0.78f;
+
+/*_______________D3DXQuaternionBaryCentric________________________*/
+ expectedquat.x = -867.444458; expectedquat.y = 87.851111f; expectedquat.z = -9.937778f; expectedquat.w = 3.235555f;
+ D3DXQuaternionBaryCentric(&gotquat,&q,&r,&t,scale,scale2);
+ expect_quaternion(&expectedquat, &gotquat, 1);
+
+/*_______________D3DXQuaternionConjugate________________*/
+ expectedquat.x = -1.0f; expectedquat.y = -2.0f; expectedquat.z = -4.0f; expectedquat.w = 10.0f;
+ D3DXQuaternionConjugate(&gotquat,&q);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ /* Test the NULL case */
+ funcpointer = D3DXQuaternionConjugate(&gotquat,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXQuaternionConjugate(NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXQuaternionDot______________________*/
+ got = D3DXQuaternionDot(&q,&r);
+ equal = compare_float(got, 55.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ /* Tests the case NULL */
+ got = D3DXQuaternionDot(NULL,&r);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ got = D3DXQuaternionDot(NULL,NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+
+/*_______________D3DXQuaternionExp______________________________*/
+ expectedquat.x = -0.216382f; expectedquat.y = -0.432764f; expectedquat.z = -0.8655270f; expectedquat.w = -0.129449f;
+ D3DXQuaternionExp(&gotquat,&q);
+ expect_quaternion(&expectedquat, &gotquat, 16);
+ /* Test the null quaternion */
+ expectedquat.x = 0.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 1.0f;
+ D3DXQuaternionExp(&gotquat,&nul);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ /* Test the case where the norm of the quaternion is <1 */
+ Nq1.x = 0.2f; Nq1.y = 0.1f; Nq1.z = 0.3; Nq1.w= 0.9f;
+ expectedquat.x = 0.195366; expectedquat.y = 0.097683f; expectedquat.z = 0.293049f; expectedquat.w = 0.930813f;
+ D3DXQuaternionExp(&gotquat,&Nq1);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+
+/*_______________D3DXQuaternionIdentity________________*/
+ expectedquat.x = 0.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 1.0f;
+ D3DXQuaternionIdentity(&gotquat);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ /* Test the NULL case */
+ funcpointer = D3DXQuaternionIdentity(NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXQuaternionInverse________________________*/
+ expectedquat.x = -1.0f/121.0f; expectedquat.y = -2.0f/121.0f; expectedquat.z = -4.0f/121.0f; expectedquat.w = 10.0f/121.0f;
+ D3DXQuaternionInverse(&gotquat,&q);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+
+ expectedquat.x = 1.0f; expectedquat.y = 2.0f; expectedquat.z = 4.0f; expectedquat.w = 10.0f;
+ D3DXQuaternionInverse(&gotquat,&gotquat);
+ expect_quaternion(&expectedquat, &gotquat, 1);
+
+
+/*_______________D3DXQuaternionIsIdentity________________*/
+ s.x = 0.0f; s.y = 0.0f; s.z = 0.0f; s.w = 1.0f;
+ expectedbool = TRUE;
+ gotbool = D3DXQuaternionIsIdentity(&s);
+ ok( expectedbool == gotbool, "Expected boolean : %d, Got bool : %d\n", expectedbool, gotbool);
+ s.x = 2.3f; s.y = -4.2f; s.z = 1.2f; s.w=0.2f;
+ expectedbool = FALSE;
+ gotbool = D3DXQuaternionIsIdentity(&q);
+ ok( expectedbool == gotbool, "Expected boolean : %d, Got bool : %d\n", expectedbool, gotbool);
+ /* Test the NULL case */
+ gotbool = D3DXQuaternionIsIdentity(NULL);
+ ok(gotbool == FALSE, "Expected boolean: %d, Got boolean: %d\n", FALSE, gotbool);
+
+/*_______________D3DXQuaternionLength__________________________*/
+ got = D3DXQuaternionLength(&q);
+ equal = compare_float(got, 11.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXQuaternionLength(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXQuaternionLengthSq________________________*/
+ got = D3DXQuaternionLengthSq(&q);
+ equal = compare_float(got, 121.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL */
+ got = D3DXQuaternionLengthSq(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXQuaternionLn______________________________*/
+ expectedquat.x = 1.0f; expectedquat.y = 2.0f; expectedquat.z = 4.0f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&q);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ expectedquat.x = -3.0f; expectedquat.y = 4.0f; expectedquat.z = -5.0f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&r);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ Nq.x = 1.0f/11.0f; Nq.y = 2.0f/11.0f; Nq.z = 4.0f/11.0f; Nq.w=10.0f/11.0f;
+ expectedquat.x = 0.093768f; expectedquat.y = 0.187536f; expectedquat.z = 0.375073f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&Nq);
+ expect_quaternion(&expectedquat, &gotquat, 32);
+ Nq.x = 0.0f; Nq.y = 0.0f; Nq.z = 0.0f; Nq.w = 1.0f;
+ expectedquat.x = 0.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&Nq);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ Nq.x = 5.4f; Nq.y = 1.2f; Nq.z = -0.3f; Nq.w = -0.3f;
+ expectedquat.x = 10.616652f; expectedquat.y = 2.359256f; expectedquat.z = -0.589814f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&Nq);
+ expect_quaternion(&expectedquat, &gotquat, 1);
+ /* Test the case where the norm of the quaternion is <1 */
+ Nq1.x = 0.2f; Nq1.y = 0.1f; Nq1.z = 0.3; Nq1.w = 0.9f;
+ expectedquat.x = 0.206945f; expectedquat.y = 0.103473f; expectedquat.z = 0.310418f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&Nq1);
+ expect_quaternion(&expectedquat, &gotquat, 64);
+ /* Test the case where the real part of the quaternion is -1.0f */
+ Nq1.x = 0.2f; Nq1.y = 0.1f; Nq1.z = 0.3; Nq1.w = -1.0f;
+ expectedquat.x = 0.2f; expectedquat.y = 0.1f; expectedquat.z = 0.3f; expectedquat.w = 0.0f;
+ D3DXQuaternionLn(&gotquat,&Nq1);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+
+/*_______________D3DXQuaternionMultiply________________________*/
+ expectedquat.x = 3.0f; expectedquat.y = 61.0f; expectedquat.z = -32.0f; expectedquat.w = 85.0f;
+ D3DXQuaternionMultiply(&gotquat,&q,&r);
+ expect_quaternion(&expectedquat, &gotquat, 0);
+
+/*_______________D3DXQuaternionNormalize________________________*/
+ expectedquat.x = 1.0f/11.0f; expectedquat.y = 2.0f/11.0f; expectedquat.z = 4.0f/11.0f; expectedquat.w = 10.0f/11.0f;
+ D3DXQuaternionNormalize(&gotquat,&q);
+ expect_quaternion(&expectedquat, &gotquat, 1);
+
+/*_______________D3DXQuaternionRotationAxis___________________*/
+ axis.x = 2.0f; axis.y = 7.0; axis.z = 13.0f;
+ angle = D3DX_PI/3.0f;
+ expectedquat.x = 0.067116; expectedquat.y = 0.234905f; expectedquat.z = 0.436251f; expectedquat.w = 0.866025f;
+ D3DXQuaternionRotationAxis(&gotquat,&axis,angle);
+ expect_quaternion(&expectedquat, &gotquat, 64);
+ /* Test the nul quaternion */
+ axis.x = 0.0f; axis.y = 0.0; axis.z = 0.0f;
+ expectedquat.x = 0.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 0.866025f;
+ D3DXQuaternionRotationAxis(&gotquat,&axis,angle);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+
+/*_______________D3DXQuaternionRotationMatrix___________________*/
+ /* test when the trace is >0 */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = 10.0f; U(mat).m[1][1] = 20.0f; U(mat).m[2][2] = 30.0f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 2.368682f; expectedquat.y = 0.768221f; expectedquat.z = -0.384111f; expectedquat.w = 3.905125f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 16);
+ /* test the case when the greater element is (2,2) */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = -60.0f; U(mat).m[2][2] = 40.0f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.233905f; expectedquat.y = -0.237290f; expectedquat.z = 5.267827f; expectedquat.w = -0.284747f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 64);
+ /* test the case when the greater element is (1,1) */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 60.0f; U(mat).m[2][2] = -80.0f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 0.651031f; expectedquat.y = 6.144103f; expectedquat.z = -0.203447f; expectedquat.w = 0.488273f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is near 0 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = -0.9f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.709495f; expectedquat.y = 2.339872f; expectedquat.z = -0.534217f; expectedquat.w = 1.282122f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is 0.49 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = -0.51f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.724923f; expectedquat.y = 2.318944f; expectedquat.z = -0.539039f; expectedquat.w = 1.293692f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is 0.51 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = -0.49f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.725726f; expectedquat.y = 2.317865f; expectedquat.z = -0.539289f; expectedquat.w = 1.294294f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is 0.99 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = -0.01f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.745328f; expectedquat.y = 2.291833f; expectedquat.z = -0.545415f; expectedquat.w = 1.308996f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 4);
+ /* test the case when the trace is 1.0 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 0.0f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 1.745743f; expectedquat.y = 2.291288f; expectedquat.z = -0.545545f; expectedquat.w = 1.309307f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is 1.01 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 0.01f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 18.408188f; expectedquat.y = 5.970223f; expectedquat.z = -2.985111f; expectedquat.w = 0.502494f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 4);
+ /* test the case when the trace is 1.5 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 0.5f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 15.105186f; expectedquat.y = 4.898980f; expectedquat.z = -2.449490f; expectedquat.w = 0.612372f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+ /* test the case when the trace is 1.7 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 0.70f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 14.188852f; expectedquat.y = 4.601790f; expectedquat.z = -2.300895f; expectedquat.w = 0.651920f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 4);
+ /* test the case when the trace is 1.99 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 0.99f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 13.114303f; expectedquat.y = 4.253287f; expectedquat.z = -2.126644f; expectedquat.w = 0.705337f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 4);
+ /* test the case when the trace is 2.0 in a matrix which is not a rotation */
+ U(mat).m[0][1] = 5.0f; U(mat).m[0][2] = 7.0f; U(mat).m[0][3] = 8.0f;
+ U(mat).m[1][0] = 11.0f; U(mat).m[1][2] = 16.0f; U(mat).m[1][3] = 33.0f;
+ U(mat).m[2][0] = 19.0f; U(mat).m[2][1] = -21.0f; U(mat).m[2][3] = 43.0f;
+ U(mat).m[3][0] = 2.0f; U(mat).m[3][1] = 3.0f; U(mat).m[3][2] = -4.0f;
+ U(mat).m[0][0] = -10.0f; U(mat).m[1][1] = 10.0f; U(mat).m[2][2] = 2.0f;
+ U(mat).m[3][3] = 48.0f;
+ expectedquat.x = 10.680980f; expectedquat.y = 3.464102f; expectedquat.z = -1.732051f; expectedquat.w = 0.866025f;
+ D3DXQuaternionRotationMatrix(&gotquat,&mat);
+ expect_quaternion(&expectedquat, &gotquat, 8);
+
+/*_______________D3DXQuaternionRotationYawPitchRoll__________*/
+ expectedquat.x = 0.303261f; expectedquat.y = 0.262299f; expectedquat.z = 0.410073f; expectedquat.w = 0.819190f;
+ D3DXQuaternionRotationYawPitchRoll(&gotquat,D3DX_PI/4.0f,D3DX_PI/11.0f,D3DX_PI/3.0f);
+ expect_quaternion(&expectedquat, &gotquat, 16);
+
+/*_______________D3DXQuaternionSlerp________________________*/
+ expectedquat.x = -0.2f; expectedquat.y = 2.6f; expectedquat.z = 1.3f; expectedquat.w = 9.1f;
+ D3DXQuaternionSlerp(&gotquat,&q,&r,scale);
+ expect_quaternion(&expectedquat, &gotquat, 4);
+ expectedquat.x = 334.0f; expectedquat.y = -31.9f; expectedquat.z = 6.1f; expectedquat.w = 6.7f;
+ D3DXQuaternionSlerp(&gotquat,&q,&t,scale);
+ expect_quaternion(&expectedquat, &gotquat, 2);
+ expectedquat.x = 0.239485f; expectedquat.y = 0.346580f; expectedquat.z = 0.453676f; expectedquat.w = 0.560772f;
+ D3DXQuaternionSlerp(&gotquat,&smallq,&smallr,scale);
+ expect_quaternion(&expectedquat, &gotquat, 32);
+
+/*_______________D3DXQuaternionSquad________________________*/
+ expectedquat.x = -156.296f; expectedquat.y = 30.242f; expectedquat.z = -2.5022f; expectedquat.w = 7.3576f;
+ D3DXQuaternionSquad(&gotquat,&q,&r,&t,&u,scale);
+ expect_quaternion(&expectedquat, &gotquat, 2);
+
+/*_______________D3DXQuaternionSquadSetup___________________*/
+ r.x = 1.0f, r.y = 2.0f; r.z = 4.0f; r.w = 10.0f;
+ s.x = -3.0f; s.y = 4.0f; s.z = -5.0f; s.w = 7.0;
+ t.x = -1111.0f, t.y = 111.0f; t.z = -11.0f; t.w = 1.0f;
+ u.x = 91.0f; u.y = - 82.0f; u.z = 7.3f; u.w = -6.4f;
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &s, &t, &u);
+ expectedquat.x = 7.121285f; expectedquat.y = 2.159964f; expectedquat.z = -3.855094f; expectedquat.w = 5.362844f;
+ expect_quaternion(&expectedquat, &gotquat, 2);
+ expectedquat.x = -1113.492920f; expectedquat.y = 82.679260f; expectedquat.z = -6.696645f; expectedquat.w = -4.090050f;
+ expect_quaternion(&expectedquat, &Nq, 2);
+ expectedquat.x = -1111.0f; expectedquat.y = 111.0f; expectedquat.z = -11.0f; expectedquat.w = 1.0f;
+ expect_quaternion(&expectedquat, &Nq1, 0);
+ gotquat = s;
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &gotquat, &t, &u);
+ expectedquat.x = -1113.492920f; expectedquat.y = 82.679260f; expectedquat.z = -6.696645f; expectedquat.w = -4.090050f;
+ expect_quaternion(&expectedquat, &Nq, 2);
+ Nq1 = u;
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &s, &t, &Nq1);
+ expect_quaternion(&expectedquat, &Nq, 2);
+ r.x = 0.2f; r.y = 0.3f; r.z = 1.3f; r.w = -0.6f;
+ s.x = -3.0f; s.y =-2.0f; s.z = 4.0f; s.w = 0.2f;
+ t.x = 0.4f; t.y = 8.3f; t.z = -3.1f; t.w = -2.7f;
+ u.x = 1.1f; u.y = -0.7f; u.z = 9.2f; u.w = 0.0f;
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &s, &u, &t);
+ expectedquat.x = -4.139569f; expectedquat.y = -2.469115f; expectedquat.z = 2.364477f; expectedquat.w = 0.465494f;
+ expect_quaternion(&expectedquat, &gotquat, 16);
+ expectedquat.x = 2.342533f; expectedquat.y = 2.365127f; expectedquat.z = 8.628538f; expectedquat.w = -0.898356f;
+ expect_quaternion(&expectedquat, &Nq, 16);
+ expectedquat.x = 1.1f; expectedquat.y = -0.7f; expectedquat.z = 9.2f; expectedquat.w = 0.0f;
+ expect_quaternion(&expectedquat, &Nq1, 0);
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &s, &t, &u);
+ expectedquat.x = -3.754567f; expectedquat.y = -0.586085f; expectedquat.z = 3.815818f; expectedquat.w = -0.198150f;
+ expect_quaternion(&expectedquat, &gotquat, 32);
+ expectedquat.x = 0.140773f; expectedquat.y = -8.737090f; expectedquat.z = -0.516593f; expectedquat.w = 3.053942f;
+ expect_quaternion(&expectedquat, &Nq, 16);
+ expectedquat.x = -0.4f; expectedquat.y = -8.3f; expectedquat.z = 3.1f; expectedquat.w = 2.7f;
+ expect_quaternion(&expectedquat, &Nq1, 0);
+ r.x = -1.0f; r.y = 0.0f; r.z = 0.0f; r.w = 0.0f;
+ s.x = 1.0f; s.y =0.0f; s.z = 0.0f; s.w = 0.0f;
+ t.x = 1.0f; t.y = 0.0f; t.z = 0.0f; t.w = 0.0f;
+ u.x = -1.0f; u.y = 0.0f; u.z = 0.0f; u.w = 0.0f;
+ D3DXQuaternionSquadSetup(&gotquat, &Nq, &Nq1, &r, &s, &t, &u);
+ expectedquat.x = 1.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 0.0f;
+ expect_quaternion(&expectedquat, &gotquat, 0);
+ expectedquat.x = 1.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 0.0f;
+ expect_quaternion(&expectedquat, &Nq, 0);
+ expectedquat.x = 1.0f; expectedquat.y = 0.0f; expectedquat.z = 0.0f; expectedquat.w = 0.0f;
+ expect_quaternion(&expectedquat, &Nq1, 0);
+
+/*_______________D3DXQuaternionToAxisAngle__________________*/
+ Nq.x = 1.0f/22.0f; Nq.y = 2.0f/22.0f; Nq.z = 4.0f/22.0f; Nq.w = 10.0f/22.0f;
+ expectedvec.x = 1.0f/22.0f; expectedvec.y = 2.0f/22.0f; expectedvec.z = 4.0f/22.0f;
+ D3DXQuaternionToAxisAngle(&Nq,&axis,&angle);
+ expect_vec3(&expectedvec, &axis, 0);
+ equal = compare_float(angle, 2.197869f, 1);
+ ok(equal, "Got unexpected angle %.8e.\n", angle);
+ /* Test if |w|>1.0f */
+ expectedvec.x = 1.0f; expectedvec.y = 2.0f; expectedvec.z = 4.0f;
+ D3DXQuaternionToAxisAngle(&q,&axis,&angle);
+ expect_vec3(&expectedvec, &axis, 0);
+ /* Test the null quaternion */
+ expectedvec.x = 0.0f; expectedvec.y = 0.0f; expectedvec.z = 0.0f;
+ D3DXQuaternionToAxisAngle(&nul, &axis, &angle);
+ expect_vec3(&expectedvec, &axis, 0);
+ equal = compare_float(angle, 3.14159274e+00f, 0);
+ ok(equal, "Got unexpected angle %.8e.\n", angle);
+
+ D3DXQuaternionToAxisAngle(&nul, &axis, NULL);
+ D3DXQuaternionToAxisAngle(&nul, NULL, &angle);
+ expect_vec3(&expectedvec, &axis, 0);
+ equal = compare_float(angle, 3.14159274e+00f, 0);
+ ok(equal, "Got unexpected angle %.8e.\n", angle);
+}
+
+static void D3DXVector2Test(void)
+{
+ D3DXVECTOR2 expectedvec, gotvec, nul, u, v, w, x;
+ LPD3DXVECTOR2 funcpointer;
+ D3DXVECTOR4 expectedtrans, gottrans;
+ float coeff1, coeff2, got, scale;
+ D3DXMATRIX mat;
+ BOOL equal;
+
+ nul.x = 0.0f; nul.y = 0.0f;
+ u.x = 3.0f; u.y = 4.0f;
+ v.x = -7.0f; v.y = 9.0f;
+ w.x = 4.0f; w.y = -3.0f;
+ x.x = 2.0f; x.y = -11.0f;
+
+ set_matrix(&mat,
+ 1.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 6.0f, 7.0f, 8.0f,
+ 9.0f, 10.0f, 11.0f, 12.0f,
+ 13.0f, 14.0f, 15.0f, 16.0f);
+
+ coeff1 = 2.0f; coeff2 = 5.0f;
+ scale = -6.5f;
+
+/*_______________D3DXVec2Add__________________________*/
+ expectedvec.x = -4.0f; expectedvec.y = 13.0f;
+ D3DXVec2Add(&gotvec,&u,&v);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec2Add(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Add(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2BaryCentric___________________*/
+ expectedvec.x = -12.0f; expectedvec.y = -21.0f;
+ D3DXVec2BaryCentric(&gotvec,&u,&v,&w,coeff1,coeff2);
+ expect_vec2(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec2CatmullRom____________________*/
+ expectedvec.x = 5820.25f; expectedvec.y = -3654.5625f;
+ D3DXVec2CatmullRom(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec2(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec2CCW__________________________*/
+ got = D3DXVec2CCW(&u, &v);
+ equal = compare_float(got, 55.0f, 0);
+ ok(equal, "Got unexpected ccw %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec2CCW(NULL, &v);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected ccw %.8e.\n", got);
+ got = D3DXVec2CCW(NULL, NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected ccw %.8e.\n", got);
+
+/*_______________D3DXVec2Dot__________________________*/
+ got = D3DXVec2Dot(&u, &v);
+ equal = compare_float(got, 15.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ /* Tests the case NULL */
+ got = D3DXVec2Dot(NULL, &v);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ got = D3DXVec2Dot(NULL, NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+
+/*_______________D3DXVec2Hermite__________________________*/
+ expectedvec.x = 2604.625f; expectedvec.y = -4533.0f;
+ D3DXVec2Hermite(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec2(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec2Length__________________________*/
+ got = D3DXVec2Length(&u);
+ equal = compare_float(got, 5.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec2Length(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec2LengthSq________________________*/
+ got = D3DXVec2LengthSq(&u);
+ equal = compare_float(got, 25.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec2LengthSq(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec2Lerp__________________________*/
+ expectedvec.x = 68.0f; expectedvec.y = -28.5f;
+ D3DXVec2Lerp(&gotvec, &u, &v, scale);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL. */
+ funcpointer = D3DXVec2Lerp(&gotvec,NULL,&v,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Lerp(NULL,NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2Maximize__________________________*/
+ expectedvec.x = 3.0f; expectedvec.y = 9.0f;
+ D3DXVec2Maximize(&gotvec, &u, &v);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL. */
+ funcpointer = D3DXVec2Maximize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Maximize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2Minimize__________________________*/
+ expectedvec.x = -7.0f; expectedvec.y = 4.0f;
+ D3DXVec2Minimize(&gotvec,&u,&v);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec2Minimize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Minimize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2Normalize_________________________*/
+ expectedvec.x = 0.6f; expectedvec.y = 0.8f;
+ D3DXVec2Normalize(&gotvec,&u);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Test the nul vector */
+ expectedvec.x = 0.0f; expectedvec.y = 0.0f;
+ D3DXVec2Normalize(&gotvec,&nul);
+ expect_vec2(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec2Scale____________________________*/
+ expectedvec.x = -19.5f; expectedvec.y = -26.0f;
+ D3DXVec2Scale(&gotvec,&u,scale);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec2Scale(&gotvec,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Scale(NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2Subtract__________________________*/
+ expectedvec.x = 10.0f; expectedvec.y = -5.0f;
+ D3DXVec2Subtract(&gotvec, &u, &v);
+ expect_vec2(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL. */
+ funcpointer = D3DXVec2Subtract(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec2Subtract(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec2Transform_______________________*/
+ expectedtrans.x = 36.0f; expectedtrans.y = 44.0f; expectedtrans.z = 52.0f; expectedtrans.w = 60.0f;
+ D3DXVec2Transform(&gottrans, &u, &mat);
+ expect_vec4(&expectedtrans, &gottrans, 0);
+ gottrans.x = u.x; gottrans.y = u.y;
+ D3DXVec2Transform(&gottrans, (D3DXVECTOR2 *)&gottrans, &mat);
+ expect_vec4(&expectedtrans, &gottrans, 0);
+
+/*_______________D3DXVec2TransformCoord_______________________*/
+ expectedvec.x = 0.6f; expectedvec.y = 11.0f/15.0f;
+ D3DXVec2TransformCoord(&gotvec, &u, &mat);
+ expect_vec2(&expectedvec, &gotvec, 1);
+ gotvec.x = u.x; gotvec.y = u.y;
+ D3DXVec2TransformCoord(&gotvec, (D3DXVECTOR2 *)&gotvec, &mat);
+ expect_vec2(&expectedvec, &gotvec, 1);
+
+ /*_______________D3DXVec2TransformNormal______________________*/
+ expectedvec.x = 23.0f; expectedvec.y = 30.0f;
+ D3DXVec2TransformNormal(&gotvec,&u,&mat);
+ expect_vec2(&expectedvec, &gotvec, 0);
+}
+
+static void D3DXVector3Test(void)
+{
+ D3DVIEWPORT9 viewport;
+ D3DXVECTOR3 expectedvec, gotvec, nul, u, v, w, x;
+ LPD3DXVECTOR3 funcpointer;
+ D3DXVECTOR4 expectedtrans, gottrans;
+ D3DXMATRIX mat, projection, view, world;
+ float coeff1, coeff2, got, scale;
+ BOOL equal;
+
+ nul.x = 0.0f; nul.y = 0.0f; nul.z = 0.0f;
+ u.x = 9.0f; u.y = 6.0f; u.z = 2.0f;
+ v.x = 2.0f; v.y = -3.0f; v.z = -4.0;
+ w.x = 3.0f; w.y = -5.0f; w.z = 7.0f;
+ x.x = 4.0f; x.y = 1.0f; x.z = 11.0f;
+
+ viewport.Width = 800; viewport.MinZ = 0.2f; viewport.X = 10;
+ viewport.Height = 680; viewport.MaxZ = 0.9f; viewport.Y = 5;
+
+ set_matrix(&mat,
+ 1.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 6.0f, 7.0f, 8.0f,
+ 9.0f, 10.0f, 11.0f, 12.0f,
+ 13.0f, 14.0f, 15.0f, 16.0f);
+
+ U(view).m[0][1] = 5.0f; U(view).m[0][2] = 7.0f; U(view).m[0][3] = 8.0f;
+ U(view).m[1][0] = 11.0f; U(view).m[1][2] = 16.0f; U(view).m[1][3] = 33.0f;
+ U(view).m[2][0] = 19.0f; U(view).m[2][1] = -21.0f; U(view).m[2][3] = 43.0f;
+ U(view).m[3][0] = 2.0f; U(view).m[3][1] = 3.0f; U(view).m[3][2] = -4.0f;
+ U(view).m[0][0] = 10.0f; U(view).m[1][1] = 20.0f; U(view).m[2][2] = 30.0f;
+ U(view).m[3][3] = -40.0f;
+
+ set_matrix(&world,
+ 21.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 23.0f, 7.0f, 8.0f,
+ -8.0f, -7.0f, 25.0f, -5.0f,
+ -4.0f, -3.0f, -2.0f, 27.0f);
+
+ coeff1 = 2.0f; coeff2 = 5.0f;
+ scale = -6.5f;
+
+/*_______________D3DXVec3Add__________________________*/
+ expectedvec.x = 11.0f; expectedvec.y = 3.0f; expectedvec.z = -2.0f;
+ D3DXVec3Add(&gotvec,&u,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Add(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Add(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3BaryCentric___________________*/
+ expectedvec.x = -35.0f; expectedvec.y = -67.0; expectedvec.z = 15.0f;
+ D3DXVec3BaryCentric(&gotvec,&u,&v,&w,coeff1,coeff2);
+ expect_vec3(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec3CatmullRom____________________*/
+ expectedvec.x = 1458.0f; expectedvec.y = 22.1875f; expectedvec.z = 4141.375f;
+ D3DXVec3CatmullRom(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec3(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec3Cross________________________*/
+ expectedvec.x = -18.0f; expectedvec.y = 40.0f; expectedvec.z = -39.0f;
+ D3DXVec3Cross(&gotvec,&u,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ expectedvec.x = -277.0f; expectedvec.y = -150.0f; expectedvec.z = -26.0f;
+ D3DXVec3Cross(&gotvec,&gotvec,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Cross(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Cross(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Dot__________________________*/
+ got = D3DXVec3Dot(&u, &v);
+ equal = compare_float(got, -8.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ /* Tests the case NULL */
+ got = D3DXVec3Dot(NULL, &v);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ got = D3DXVec3Dot(NULL, NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+
+/*_______________D3DXVec3Hermite__________________________*/
+ expectedvec.x = -6045.75f; expectedvec.y = -6650.0f; expectedvec.z = 1358.875f;
+ D3DXVec3Hermite(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec3(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec3Length__________________________*/
+ got = D3DXVec3Length(&u);
+ equal = compare_float(got, 11.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec3Length(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec3LengthSq________________________*/
+ got = D3DXVec3LengthSq(&u);
+ equal = compare_float(got, 121.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec3LengthSq(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec3Lerp__________________________*/
+ expectedvec.x = 54.5f; expectedvec.y = 64.5f, expectedvec.z = 41.0f ;
+ D3DXVec3Lerp(&gotvec,&u,&v,scale);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Lerp(&gotvec,NULL,&v,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Lerp(NULL,NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Maximize__________________________*/
+ expectedvec.x = 9.0f; expectedvec.y = 6.0f; expectedvec.z = 2.0f;
+ D3DXVec3Maximize(&gotvec,&u,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Maximize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Maximize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Minimize__________________________*/
+ expectedvec.x = 2.0f; expectedvec.y = -3.0f; expectedvec.z = -4.0f;
+ D3DXVec3Minimize(&gotvec,&u,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Minimize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Minimize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Normalize_________________________*/
+ expectedvec.x = 9.0f/11.0f; expectedvec.y = 6.0f/11.0f; expectedvec.z = 2.0f/11.0f;
+ D3DXVec3Normalize(&gotvec,&u);
+ expect_vec3(&expectedvec, &gotvec, 1);
+ /* Test the nul vector */
+ expectedvec.x = 0.0f; expectedvec.y = 0.0f; expectedvec.z = 0.0f;
+ D3DXVec3Normalize(&gotvec,&nul);
+ expect_vec3(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec3Scale____________________________*/
+ expectedvec.x = -58.5f; expectedvec.y = -39.0f; expectedvec.z = -13.0f;
+ D3DXVec3Scale(&gotvec,&u,scale);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Scale(&gotvec,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Scale(NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Subtract_______________________*/
+ expectedvec.x = 7.0f; expectedvec.y = 9.0f; expectedvec.z = 6.0f;
+ D3DXVec3Subtract(&gotvec,&u,&v);
+ expect_vec3(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec3Subtract(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec3Subtract(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec3Transform_______________________*/
+ expectedtrans.x = 70.0f; expectedtrans.y = 88.0f; expectedtrans.z = 106.0f; expectedtrans.w = 124.0f;
+ D3DXVec3Transform(&gottrans, &u, &mat);
+ expect_vec4(&expectedtrans, &gottrans, 0);
+
+ gottrans.x = u.x; gottrans.y = u.y; gottrans.z = u.z;
+ D3DXVec3Transform(&gottrans, (D3DXVECTOR3 *)&gottrans, &mat);
+ expect_vec4(&expectedtrans, &gottrans, 0);
+
+/*_______________D3DXVec3TransformCoord_______________________*/
+ expectedvec.x = 70.0f/124.0f; expectedvec.y = 88.0f/124.0f; expectedvec.z = 106.0f/124.0f;
+ D3DXVec3TransformCoord(&gotvec,&u,&mat);
+ expect_vec3(&expectedvec, &gotvec, 1);
+
+/*_______________D3DXVec3TransformNormal______________________*/
+ expectedvec.x = 57.0f; expectedvec.y = 74.0f; expectedvec.z = 91.0f;
+ D3DXVec3TransformNormal(&gotvec,&u,&mat);
+ expect_vec3(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec3Project_________________________*/
+ expectedvec.x = 1135.721924f; expectedvec.y = 147.086914f; expectedvec.z = 0.153412f;
+ D3DXMatrixPerspectiveFovLH(&projection,D3DX_PI/4.0f,20.0f/17.0f,1.0f,1000.0f);
+ D3DXVec3Project(&gotvec,&u,&viewport,&projection,&view,&world);
+ expect_vec3(&expectedvec, &gotvec, 32);
+ /* World matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&world,&view);
+ D3DXVec3Project(&gotvec,&u,&viewport,&projection,&mat,NULL);
+ expect_vec3(&expectedvec, &gotvec, 32);
+ /* Projection matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&view,&projection);
+ D3DXVec3Project(&gotvec,&u,&viewport,NULL,&mat,&world);
+ expect_vec3(&expectedvec, &gotvec, 32);
+ /* View matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&world,&view);
+ D3DXVec3Project(&gotvec,&u,&viewport,&projection,NULL,&mat);
+ expect_vec3(&expectedvec, &gotvec, 32);
+ /* All matrices can be omitted */
+ expectedvec.x = 4010.000000f; expectedvec.y = -1695.000000f; expectedvec.z = 1.600000f;
+ D3DXVec3Project(&gotvec,&u,&viewport,NULL,NULL,NULL);
+ expect_vec3(&expectedvec, &gotvec, 2);
+ /* Viewport can be omitted */
+ expectedvec.x = 1.814305f; expectedvec.y = 0.582097f; expectedvec.z = -0.066555f;
+ D3DXVec3Project(&gotvec,&u,NULL,&projection,&view,&world);
+ expect_vec3(&expectedvec, &gotvec, 64);
+
+/*_______________D3DXVec3Unproject_________________________*/
+ expectedvec.x = -2.913411f; expectedvec.y = 1.593215f; expectedvec.z = 0.380724f;
+ D3DXMatrixPerspectiveFovLH(&projection,D3DX_PI/4.0f,20.0f/17.0f,1.0f,1000.0f);
+ D3DXVec3Unproject(&gotvec,&u,&viewport,&projection,&view,&world);
+ expect_vec3(&expectedvec, &gotvec, 16);
+ /* World matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&world,&view);
+ D3DXVec3Unproject(&gotvec,&u,&viewport,&projection,&mat,NULL);
+ expect_vec3(&expectedvec, &gotvec, 16);
+ /* Projection matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&view,&projection);
+ D3DXVec3Unproject(&gotvec,&u,&viewport,NULL,&mat,&world);
+ expect_vec3(&expectedvec, &gotvec, 32);
+ /* View matrix can be omitted */
+ D3DXMatrixMultiply(&mat,&world,&view);
+ D3DXVec3Unproject(&gotvec,&u,&viewport,&projection,NULL,&mat);
+ expect_vec3(&expectedvec, &gotvec, 16);
+ /* All matrices can be omitted */
+ expectedvec.x = -1.002500f; expectedvec.y = 0.997059f; expectedvec.z = 2.571429f;
+ D3DXVec3Unproject(&gotvec,&u,&viewport,NULL,NULL,NULL);
+ expect_vec3(&expectedvec, &gotvec, 4);
+ /* Viewport can be omitted */
+ expectedvec.x = -11.018396f; expectedvec.y = 3.218991f; expectedvec.z = 1.380329f;
+ D3DXVec3Unproject(&gotvec,&u,NULL,&projection,&view,&world);
+ expect_vec3(&expectedvec, &gotvec, 8);
+}
+
+static void D3DXVector4Test(void)
+{
+ D3DXVECTOR4 expectedvec, gotvec, u, v, w, x;
+ LPD3DXVECTOR4 funcpointer;
+ D3DXVECTOR4 expectedtrans, gottrans;
+ float coeff1, coeff2, got, scale;
+ D3DXMATRIX mat;
+ BOOL equal;
+
+ u.x = 1.0f; u.y = 2.0f; u.z = 4.0f; u.w = 10.0;
+ v.x = -3.0f; v.y = 4.0f; v.z = -5.0f; v.w = 7.0;
+ w.x = 4.0f; w.y =6.0f; w.z = -2.0f; w.w = 1.0f;
+ x.x = 6.0f; x.y = -7.0f; x.z =8.0f; x.w = -9.0f;
+
+ set_matrix(&mat,
+ 1.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 6.0f, 7.0f, 8.0f,
+ 9.0f, 10.0f, 11.0f, 12.0f,
+ 13.0f, 14.0f, 15.0f, 16.0f);
+
+ coeff1 = 2.0f; coeff2 = 5.0;
+ scale = -6.5f;
+
+/*_______________D3DXVec4Add__________________________*/
+ expectedvec.x = -2.0f; expectedvec.y = 6.0f; expectedvec.z = -1.0f; expectedvec.w = 17.0f;
+ D3DXVec4Add(&gotvec,&u,&v);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Add(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Add(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4BaryCentric____________________*/
+ expectedvec.x = 8.0f; expectedvec.y = 26.0; expectedvec.z = -44.0f; expectedvec.w = -41.0f;
+ D3DXVec4BaryCentric(&gotvec,&u,&v,&w,coeff1,coeff2);
+ expect_vec4(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec4CatmullRom____________________*/
+ expectedvec.x = 2754.625f; expectedvec.y = 2367.5625f; expectedvec.z = 1060.1875f; expectedvec.w = 131.3125f;
+ D3DXVec4CatmullRom(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec4(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec4Cross_________________________*/
+ expectedvec.x = 390.0f; expectedvec.y = -393.0f; expectedvec.z = -316.0f; expectedvec.w = 166.0f;
+ D3DXVec4Cross(&gotvec,&u,&v,&w);
+ expect_vec4(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec4Dot__________________________*/
+ got = D3DXVec4Dot(&u, &v);
+ equal = compare_float(got, 55.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec4Dot(NULL, &v);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+ got = D3DXVec4Dot(NULL, NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected dot %.8e.\n", got);
+
+/*_______________D3DXVec4Hermite_________________________*/
+ expectedvec.x = 1224.625f; expectedvec.y = 3461.625f; expectedvec.z = -4758.875f; expectedvec.w = -5781.5f;
+ D3DXVec4Hermite(&gotvec,&u,&v,&w,&x,scale);
+ expect_vec4(&expectedvec, &gotvec, 0);
+
+/*_______________D3DXVec4Length__________________________*/
+ got = D3DXVec4Length(&u);
+ equal = compare_float(got, 11.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec4Length(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec4LengthSq________________________*/
+ got = D3DXVec4LengthSq(&u);
+ equal = compare_float(got, 121.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+ /* Tests the case NULL. */
+ got = D3DXVec4LengthSq(NULL);
+ equal = compare_float(got, 0.0f, 0);
+ ok(equal, "Got unexpected length %.8e.\n", got);
+
+/*_______________D3DXVec4Lerp__________________________*/
+ expectedvec.x = 27.0f; expectedvec.y = -11.0f; expectedvec.z = 62.5; expectedvec.w = 29.5;
+ D3DXVec4Lerp(&gotvec,&u,&v,scale);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Lerp(&gotvec,NULL,&v,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Lerp(NULL,NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4Maximize__________________________*/
+ expectedvec.x = 1.0f; expectedvec.y = 4.0f; expectedvec.z = 4.0f; expectedvec.w = 10.0;
+ D3DXVec4Maximize(&gotvec,&u,&v);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Maximize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Maximize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4Minimize__________________________*/
+ expectedvec.x = -3.0f; expectedvec.y = 2.0f; expectedvec.z = -5.0f; expectedvec.w = 7.0;
+ D3DXVec4Minimize(&gotvec,&u,&v);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Minimize(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Minimize(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4Normalize_________________________*/
+ expectedvec.x = 1.0f/11.0f; expectedvec.y = 2.0f/11.0f; expectedvec.z = 4.0f/11.0f; expectedvec.w = 10.0f/11.0f;
+ D3DXVec4Normalize(&gotvec,&u);
+ expect_vec4(&expectedvec, &gotvec, 1);
+
+/*_______________D3DXVec4Scale____________________________*/
+ expectedvec.x = -6.5f; expectedvec.y = -13.0f; expectedvec.z = -26.0f; expectedvec.w = -65.0f;
+ D3DXVec4Scale(&gotvec,&u,scale);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Scale(&gotvec,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Scale(NULL,NULL,scale);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4Subtract__________________________*/
+ expectedvec.x = 4.0f; expectedvec.y = -2.0f; expectedvec.z = 9.0f; expectedvec.w = 3.0f;
+ D3DXVec4Subtract(&gotvec,&u,&v);
+ expect_vec4(&expectedvec, &gotvec, 0);
+ /* Tests the case NULL */
+ funcpointer = D3DXVec4Subtract(&gotvec,NULL,&v);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+ funcpointer = D3DXVec4Subtract(NULL,NULL,NULL);
+ ok(funcpointer == NULL, "Expected: %p, Got: %p\n", NULL, funcpointer);
+
+/*_______________D3DXVec4Transform_______________________*/
+ expectedtrans.x = 177.0f; expectedtrans.y = 194.0f; expectedtrans.z = 211.0f; expectedtrans.w = 228.0f;
+ D3DXVec4Transform(&gottrans,&u,&mat);
+ expect_vec4(&expectedtrans, &gottrans, 0);
+}
+
+static void test_matrix_stack(void)
+{
+ ID3DXMatrixStack *stack;
+ ULONG refcount;
+ HRESULT hr;
+
+ const D3DXMATRIX mat1 = {{{
+ 1.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 6.0f, 7.0f, 8.0f,
+ 9.0f, 10.0f, 11.0f, 12.0f,
+ 13.0f, 14.0f, 15.0f, 16.0f
+ }}};
+
+ const D3DXMATRIX mat2 = {{{
+ 17.0f, 18.0f, 19.0f, 20.0f,
+ 21.0f, 22.0f, 23.0f, 24.0f,
+ 25.0f, 26.0f, 27.0f, 28.0f,
+ 29.0f, 30.0f, 31.0f, 32.0f
+ }}};
+
+ hr = D3DXCreateMatrixStack(0, &stack);
+ ok(SUCCEEDED(hr), "Failed to create a matrix stack, hr %#x\n", hr);
+ if (FAILED(hr)) return;
+
+ ok(D3DXMatrixIsIdentity(ID3DXMatrixStack_GetTop(stack)),
+ "The top of an empty matrix stack should be an identity matrix\n");
+
+ hr = ID3DXMatrixStack_Pop(stack);
+ ok(SUCCEEDED(hr), "Pop failed, hr %#x\n", hr);
+
+ hr = ID3DXMatrixStack_Push(stack);
+ ok(SUCCEEDED(hr), "Push failed, hr %#x\n", hr);
+ ok(D3DXMatrixIsIdentity(ID3DXMatrixStack_GetTop(stack)), "The top should be an identity matrix\n");
+
+ hr = ID3DXMatrixStack_Push(stack);
+ ok(SUCCEEDED(hr), "Push failed, hr %#x\n", hr);
+
+ hr = ID3DXMatrixStack_LoadMatrix(stack, &mat1);
+ ok(SUCCEEDED(hr), "LoadMatrix failed, hr %#x\n", hr);
+ expect_matrix(&mat1, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_Push(stack);
+ ok(SUCCEEDED(hr), "Push failed, hr %#x\n", hr);
+ expect_matrix(&mat1, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_LoadMatrix(stack, &mat2);
+ ok(SUCCEEDED(hr), "LoadMatrix failed, hr %#x\n", hr);
+ expect_matrix(&mat2, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_Push(stack);
+ ok(SUCCEEDED(hr), "Push failed, hr %#x\n", hr);
+ expect_matrix(&mat2, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_LoadIdentity(stack);
+ ok(SUCCEEDED(hr), "LoadIdentity failed, hr %#x\n", hr);
+ ok(D3DXMatrixIsIdentity(ID3DXMatrixStack_GetTop(stack)), "The top should be an identity matrix\n");
+
+ hr = ID3DXMatrixStack_Pop(stack);
+ ok(SUCCEEDED(hr), "Pop failed, hr %#x\n", hr);
+ expect_matrix(&mat2, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_Pop(stack);
+ ok(SUCCEEDED(hr), "Pop failed, hr %#x\n", hr);
+ expect_matrix(&mat1, ID3DXMatrixStack_GetTop(stack), 0);
+
+ hr = ID3DXMatrixStack_Pop(stack);
+ ok(SUCCEEDED(hr), "Pop failed, hr %#x\n", hr);
+ ok(D3DXMatrixIsIdentity(ID3DXMatrixStack_GetTop(stack)), "The top should be an identity matrix\n");
+
+ hr = ID3DXMatrixStack_Pop(stack);
+ ok(SUCCEEDED(hr), "Pop failed, hr %#x\n", hr);
+ ok(D3DXMatrixIsIdentity(ID3DXMatrixStack_GetTop(stack)), "The top should be an identity matrix\n");
+
+ refcount = ID3DXMatrixStack_Release(stack);
+ ok(!refcount, "Matrix stack has %u references left.\n", refcount);
+}
+
+static void test_Matrix_AffineTransformation2D(void)
+{
+ D3DXMATRIX exp_mat, got_mat;
+ D3DXVECTOR2 center, position;
+ FLOAT angle, scale;
+
+ center.x = 3.0f;
+ center.y = 4.0f;
+
+ position.x = -6.0f;
+ position.y = 7.0f;
+
+ angle = D3DX_PI/3.0f;
+
+ scale = 20.0f;
+
+ U(exp_mat).m[0][0] = 10.0f;
+ U(exp_mat).m[1][0] = -17.320507f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = -1.035898f;
+ U(exp_mat).m[0][1] = 17.320507f;
+ U(exp_mat).m[1][1] = 10.0f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = 6.401924f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixAffineTransformation2D(&got_mat, scale, ¢er, angle, &position);
+ expect_matrix(&exp_mat, &got_mat, 2);
+
+/*______________*/
+
+ center.x = 3.0f;
+ center.y = 4.0f;
+
+ angle = D3DX_PI/3.0f;
+
+ scale = 20.0f;
+
+ U(exp_mat).m[0][0] = 10.0f;
+ U(exp_mat).m[1][0] = -17.320507f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = 4.964102f;
+ U(exp_mat).m[0][1] = 17.320507f;
+ U(exp_mat).m[1][1] = 10.0f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = -0.598076f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixAffineTransformation2D(&got_mat, scale, ¢er, angle, NULL);
+ expect_matrix(&exp_mat, &got_mat, 8);
+
+/*______________*/
+
+ position.x = -6.0f;
+ position.y = 7.0f;
+
+ angle = D3DX_PI/3.0f;
+
+ scale = 20.0f;
+
+ U(exp_mat).m[0][0] = 10.0f;
+ U(exp_mat).m[1][0] = -17.320507f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = -6.0f;
+ U(exp_mat).m[0][1] = 17.320507f;
+ U(exp_mat).m[1][1] = 10.0f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = 7.0f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixAffineTransformation2D(&got_mat, scale, NULL, angle, &position);
+ expect_matrix(&exp_mat, &got_mat, 1);
+
+/*______________*/
+
+ angle = 5.0f * D3DX_PI/4.0f;
+
+ scale = -20.0f;
+
+ U(exp_mat).m[0][0] = 14.142133f;
+ U(exp_mat).m[1][0] = -14.142133f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = 0.0f;
+ U(exp_mat).m[0][1] = 14.142133;
+ U(exp_mat).m[1][1] = 14.142133f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = 0.0f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixAffineTransformation2D(&got_mat, scale, NULL, angle, NULL);
+ expect_matrix(&exp_mat, &got_mat, 8);
+}
+
+static void test_Matrix_Decompose(void)
+{
+ D3DXMATRIX pm;
+ D3DXQUATERNION exp_rotation, got_rotation;
+ D3DXVECTOR3 exp_scale, got_scale, exp_translation, got_translation;
+ HRESULT hr;
+ BOOL equal;
+
+/*___________*/
+
+ U(pm).m[0][0] = -9.23879206e-01f;
+ U(pm).m[1][0] = -2.70598412e-01f;
+ U(pm).m[2][0] = 2.70598441e-01f;
+ U(pm).m[3][0] = -5.00000000e+00f;
+ U(pm).m[0][1] = 2.70598471e-01f;
+ U(pm).m[1][1] = 3.80604863e-02f;
+ U(pm).m[2][1] = 9.61939573e-01f;
+ U(pm).m[3][1] = 0.00000000e+00f;
+ U(pm).m[0][2] = -2.70598441e-01f;
+ U(pm).m[1][2] = 9.61939573e-01f;
+ U(pm).m[2][2] = 3.80603075e-02f;
+ U(pm).m[3][2] = 1.00000000e+01f;
+ U(pm).m[0][3] = 0.00000000e+00f;
+ U(pm).m[1][3] = 0.00000000e+00f;
+ U(pm).m[2][3] = 0.00000000e+00f;
+ U(pm).m[3][3] = 1.00000000e+00f;
+
+ exp_scale.x = 9.99999881e-01f;
+ exp_scale.y = 9.99999881e-01f;
+ exp_scale.z = 9.99999881e-01f;
+
+ exp_rotation.x = 2.14862776e-08f;
+ exp_rotation.y = 6.93519890e-01f;
+ exp_rotation.z = 6.93519890e-01f;
+ exp_rotation.w = 1.95090637e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 10.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 1);
+ expect_quaternion(&exp_rotation, &got_rotation, 1);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*_________*/
+
+ U(pm).m[0][0] = -2.255813f;
+ U(pm).m[1][0] = 1.302324f;
+ U(pm).m[2][0] = 1.488373f;
+ U(pm).m[3][0] = 1.0f;
+ U(pm).m[0][1] = 1.302327f;
+ U(pm).m[1][1] = -0.7209296f;
+ U(pm).m[2][1] = 2.60465f;
+ U(pm).m[3][1] = 2.0f;
+ U(pm).m[0][2] = 1.488371f;
+ U(pm).m[1][2] = 2.604651f;
+ U(pm).m[2][2] = -0.02325551f;
+ U(pm).m[3][2] = 3.0f;
+ U(pm).m[0][3] = 0.0f;
+ U(pm).m[1][3] = 0.0f;
+ U(pm).m[2][3] = 0.0f;
+ U(pm).m[3][3] = 1.0f;
+
+ exp_scale.x = 2.99999928e+00f;
+ exp_scale.y = 2.99999905e+00f;
+ exp_scale.z = 2.99999952e+00f;
+
+ exp_rotation.x = 3.52180451e-01f;
+ exp_rotation.y = 6.16315663e-01f;
+ exp_rotation.z = 7.04360664e-01f;
+ exp_rotation.w = 3.38489343e-07f;
+
+ exp_translation.x = 1.0f;
+ exp_translation.y = 2.0f;
+ exp_translation.z = 3.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 0);
+ expect_quaternion(&exp_rotation, &got_rotation, 2);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*_____________*/
+
+ U(pm).m[0][0] = 2.427051f;
+ U(pm).m[1][0] = 0.0f;
+ U(pm).m[2][0] = 1.763355f;
+ U(pm).m[3][0] = 5.0f;
+ U(pm).m[0][1] = 0.0f;
+ U(pm).m[1][1] = 3.0f;
+ U(pm).m[2][1] = 0.0f;
+ U(pm).m[3][1] = 5.0f;
+ U(pm).m[0][2] = -1.763355f;
+ U(pm).m[1][2] = 0.0f;
+ U(pm).m[2][2] = 2.427051f;
+ U(pm).m[3][2] = 5.0f;
+ U(pm).m[0][3] = 0.0f;
+ U(pm).m[1][3] = 0.0f;
+ U(pm).m[2][3] = 0.0f;
+ U(pm).m[3][3] = 1.0f;
+
+ exp_scale.x = 2.99999976e+00f;
+ exp_scale.y = 3.00000000e+00f;
+ exp_scale.z = 2.99999976e+00f;
+
+ exp_rotation.x = 0.00000000e+00f;
+ exp_rotation.y = 3.09016883e-01f;
+ exp_rotation.z = 0.00000000e+00f;
+ exp_rotation.w = 9.51056540e-01f;
+
+ exp_translation.x = 5.0f;
+ exp_translation.y = 5.0f;
+ exp_translation.z = 5.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 1);
+ expect_quaternion(&exp_rotation, &got_rotation, 1);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*_____________*/
+
+ U(pm).m[0][0] = -9.23879206e-01f;
+ U(pm).m[1][0] = -2.70598412e-01f;
+ U(pm).m[2][0] = 2.70598441e-01f;
+ U(pm).m[3][0] = -5.00000000e+00f;
+ U(pm).m[0][1] = 2.70598471e-01f;
+ U(pm).m[1][1] = 3.80604863e-02f;
+ U(pm).m[2][1] = 9.61939573e-01f;
+ U(pm).m[3][1] = 0.00000000e+00f;
+ U(pm).m[0][2] = -2.70598441e-01f;
+ U(pm).m[1][2] = 9.61939573e-01f;
+ U(pm).m[2][2] = 3.80603075e-02f;
+ U(pm).m[3][2] = 1.00000000e+01f;
+ U(pm).m[0][3] = 0.00000000e+00f;
+ U(pm).m[1][3] = 0.00000000e+00f;
+ U(pm).m[2][3] = 0.00000000e+00f;
+ U(pm).m[3][3] = 1.00000000e+00f;
+
+ exp_scale.x = 9.99999881e-01f;
+ exp_scale.y = 9.99999881e-01f;
+ exp_scale.z = 9.99999881e-01f;
+
+ exp_rotation.x = 2.14862776e-08f;
+ exp_rotation.y = 6.93519890e-01f;
+ exp_rotation.z = 6.93519890e-01f;
+ exp_rotation.w = 1.95090637e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 10.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 1);
+ expect_quaternion(&exp_rotation, &got_rotation, 1);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*__________*/
+
+ U(pm).m[0][0] = -9.23878908e-01f;
+ U(pm).m[1][0] = -5.41196704e-01f;
+ U(pm).m[2][0] = 8.11795175e-01f;
+ U(pm).m[3][0] = -5.00000000e+00f;
+ U(pm).m[0][1] = 2.70598322e-01f;
+ U(pm).m[1][1] = 7.61209577e-02f;
+ U(pm).m[2][1] = 2.88581824e+00f;
+ U(pm).m[3][1] = 0.00000000e+00f;
+ U(pm).m[0][2] = -2.70598352e-01f;
+ U(pm).m[1][2] = 1.92387879e+00f;
+ U(pm).m[2][2] = 1.14180908e-01f;
+ U(pm).m[3][2] = 1.00000000e+01f;
+ U(pm).m[0][3] = 0.00000000e+00f;
+ U(pm).m[1][3] = 0.00000000e+00f;
+ U(pm).m[2][3] = 0.00000000e+00f;
+ U(pm).m[3][3] = 1.00000000e+00f;
+
+ exp_scale.x = 9.99999583e-01f;
+ exp_scale.y = 1.99999940e+00f;
+ exp_scale.z = 2.99999928e+00f;
+
+ exp_rotation.x = 1.07431388e-08f;
+ exp_rotation.y = 6.93519890e-01f;
+ exp_rotation.z = 6.93519831e-01f;
+ exp_rotation.w = 1.95090622e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 10.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 1);
+ equal = compare_quaternion(&exp_rotation, &got_rotation, 1);
+ exp_rotation.x = 0.0f;
+ equal |= compare_quaternion(&exp_rotation, &got_rotation, 2);
+ ok(equal, "Got unexpected quaternion {%.8e, %.8e, %.8e, %.8e}.\n",
+ got_rotation.x, got_rotation.y, got_rotation.z, got_rotation.w);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*__________*/
+
+ U(pm).m[0][0] = 0.7156004f;
+ U(pm).m[1][0] = -0.5098283f;
+ U(pm).m[2][0] = -0.4774843f;
+ U(pm).m[3][0] = -5.0f;
+ U(pm).m[0][1] = -0.6612288f;
+ U(pm).m[1][1] = -0.7147621f;
+ U(pm).m[2][1] = -0.2277977f;
+ U(pm).m[3][1] = 0.0f;
+ U(pm).m[0][2] = -0.2251499f;
+ U(pm).m[1][2] = 0.4787385f;
+ U(pm).m[2][2] = -0.8485972f;
+ U(pm).m[3][2] = 10.0f;
+ U(pm).m[0][3] = 0.0f;
+ U(pm).m[1][3] = 0.0f;
+ U(pm).m[2][3] = 0.0f;
+ U(pm).m[3][3] = 1.0f;
+
+ exp_scale.x = 9.99999940e-01f;
+ exp_scale.y = 1.00000012e+00f;
+ exp_scale.z = 1.00000012e+00f;
+
+ exp_rotation.x = 9.05394852e-01f;
+ exp_rotation.y = -3.23355347e-01f;
+ exp_rotation.z = -1.94013178e-01f;
+ exp_rotation.w = 1.95090592e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 10.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 0);
+ expect_quaternion(&exp_rotation, &got_rotation, 1);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*_____________*/
+
+ U(pm).m[0][0] = 0.06554436f;
+ U(pm).m[1][0] = -0.6873012f;
+ U(pm).m[2][0] = 0.7234092f;
+ U(pm).m[3][0] = -5.0f;
+ U(pm).m[0][1] = -0.9617381f;
+ U(pm).m[1][1] = -0.2367795f;
+ U(pm).m[2][1] = -0.1378230f;
+ U(pm).m[3][1] = 0.0f;
+ U(pm).m[0][2] = 0.2660144f;
+ U(pm).m[1][2] = -0.6866967f;
+ U(pm).m[2][2] = -0.6765233f;
+ U(pm).m[3][2] = 10.0f;
+ U(pm).m[0][3] = 0.0f;
+ U(pm).m[1][3] = 0.0f;
+ U(pm).m[2][3] = 0.0f;
+ U(pm).m[3][3] = 1.0f;
+
+ exp_scale.x = 9.99999940e-01f;
+ exp_scale.y = 9.99999940e-01f;
+ exp_scale.z = 9.99999881e-01f;
+
+ exp_rotation.x = 7.03357518e-01f;
+ exp_rotation.y = -5.86131275e-01f;
+ exp_rotation.z = 3.51678789e-01f;
+ exp_rotation.w = -1.95090577e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 10.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 1);
+ expect_quaternion(&exp_rotation, &got_rotation, 2);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*_________*/
+
+ U(pm).m[0][0] = 7.12104797e+00f;
+ U(pm).m[1][0] = -5.88348627e+00f;
+ U(pm).m[2][0] = 1.18184204e+01f;
+ U(pm).m[3][0] = -5.00000000e+00f;
+ U(pm).m[0][1] = 5.88348627e+00f;
+ U(pm).m[1][1] = -1.06065865e+01f;
+ U(pm).m[2][1] = -8.82523251e+00f;
+ U(pm).m[3][1] = 0.00000000e+00f;
+ U(pm).m[0][2] = 1.18184204e+01f;
+ U(pm).m[1][2] = 8.82523155e+00f;
+ U(pm).m[2][2] = -2.72764111e+00f;
+ U(pm).m[3][2] = 2.00000000e+00f;
+ U(pm).m[0][3] = 0.00000000e+00f;
+ U(pm).m[1][3] = 0.00000000e+00f;
+ U(pm).m[2][3] = 0.00000000e+00f;
+ U(pm).m[3][3] = 1.00000000e+00f;
+
+ exp_scale.x = 1.49999933e+01f;
+ exp_scale.y = 1.49999933e+01f;
+ exp_scale.z = 1.49999943e+01f;
+
+ exp_rotation.x = 7.68714130e-01f;
+ exp_rotation.y = 0.00000000e+00f;
+ exp_rotation.z = 5.12475967e-01f;
+ exp_rotation.w = 3.82683903e-01f;
+
+ exp_translation.x = -5.0f;
+ exp_translation.y = 0.0f;
+ exp_translation.z = 2.0f;
+
+ D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ expect_vec3(&exp_scale, &got_scale, 0);
+ expect_quaternion(&exp_rotation, &got_rotation, 1);
+ expect_vec3(&exp_translation, &got_translation, 0);
+
+/*__________*/
+
+ U(pm).m[0][0] = 0.0f;
+ U(pm).m[1][0] = 4.0f;
+ U(pm).m[2][0] = 5.0f;
+ U(pm).m[3][0] = -5.0f;
+ U(pm).m[0][1] = 0.0f;
+ U(pm).m[1][1] = -10.60660f;
+ U(pm).m[2][1] = -8.825232f;
+ U(pm).m[3][1] = 6.0f;
+ U(pm).m[0][2] = 0.0f;
+ U(pm).m[1][2] = 8.8252320f;
+ U(pm).m[2][2] = 2.727645;
+ U(pm).m[3][2] = 3.0f;
+ U(pm).m[0][3] = 0.0f;
+ U(pm).m[1][3] = 0.0f;
+ U(pm).m[2][3] = 0.0f;
+ U(pm).m[3][3] = 1.0f;
+
+ hr = D3DXMatrixDecompose(&got_scale, &got_rotation, &got_translation, &pm);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %x\n", hr);
+}
+
+static void test_Matrix_Transformation2D(void)
+{
+ D3DXMATRIX exp_mat, got_mat;
+ D3DXVECTOR2 rot_center, sca, sca_center, trans;
+ FLOAT rot, sca_rot;
+
+ rot_center.x = 3.0f;
+ rot_center.y = 4.0f;
+
+ sca.x = 12.0f;
+ sca.y = -3.0f;
+
+ sca_center.x = 9.0f;
+ sca_center.y = -5.0f;
+
+ trans.x = -6.0f;
+ trans.y = 7.0f;
+
+ rot = D3DX_PI/3.0f;
+
+ sca_rot = 5.0f*D3DX_PI/4.0f;
+
+ U(exp_mat).m[0][0] = -4.245192f;
+ U(exp_mat).m[1][0] = -0.147116f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = 45.265373f;
+ U(exp_mat).m[0][1] = 7.647113f;
+ U(exp_mat).m[1][1] = 8.745192f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = -13.401899f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixTransformation2D(&got_mat, &sca_center, sca_rot, &sca, &rot_center, rot, &trans);
+ expect_matrix(&exp_mat, &got_mat, 64);
+
+/*_________*/
+
+ sca_center.x = 9.0f;
+ sca_center.y = -5.0f;
+
+ trans.x = -6.0f;
+ trans.y = 7.0f;
+
+ rot = D3DX_PI/3.0f;
+
+ sca_rot = 5.0f*D3DX_PI/4.0f;
+
+ U(exp_mat).m[0][0] = 0.50f;
+ U(exp_mat).m[1][0] = -0.866025f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = -6.0f;
+ U(exp_mat).m[0][1] = 0.866025f;
+ U(exp_mat).m[1][1] = 0.50f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = 7.0f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixTransformation2D(&got_mat, &sca_center, sca_rot, NULL, NULL, rot, &trans);
+ expect_matrix(&exp_mat, &got_mat, 8);
+
+/*_________*/
+
+ U(exp_mat).m[0][0] = 0.50f;
+ U(exp_mat).m[1][0] = -0.866025f;
+ U(exp_mat).m[2][0] = 0.0f;
+ U(exp_mat).m[3][0] = 0.0f;
+ U(exp_mat).m[0][1] = 0.866025f;
+ U(exp_mat).m[1][1] = 0.50f;
+ U(exp_mat).m[2][1] = 0.0f;
+ U(exp_mat).m[3][1] = 0.0f;
+ U(exp_mat).m[0][2] = 0.0f;
+ U(exp_mat).m[1][2] = 0.0f;
+ U(exp_mat).m[2][2] = 1.0f;
+ U(exp_mat).m[3][2] = 0.0f;
+ U(exp_mat).m[0][3] = 0.0f;
+ U(exp_mat).m[1][3] = 0.0f;
+ U(exp_mat).m[2][3] = 0.0f;
+ U(exp_mat).m[3][3] = 1.0f;
+
+ D3DXMatrixTransformation2D(&got_mat, NULL, sca_rot, NULL, NULL, rot, NULL);
+ expect_matrix(&exp_mat, &got_mat, 8);
+}
+
+static void test_D3DXVec_Array(void)
+{
+ D3DXPLANE inp_plane[5], out_plane[7], exp_plane[7];
+ D3DXVECTOR4 inp_vec[5], out_vec[7], exp_vec[7];
+ D3DXMATRIX mat, projection, view, world;
+ D3DVIEWPORT9 viewport;
+ unsigned int i;
+
+ viewport.Width = 800; viewport.MinZ = 0.2f; viewport.X = 10;
+ viewport.Height = 680; viewport.MaxZ = 0.9f; viewport.Y = 5;
+
+ memset(out_vec, 0, sizeof(out_vec));
+ memset(exp_vec, 0, sizeof(exp_vec));
+ memset(out_plane, 0, sizeof(out_plane));
+ memset(exp_plane, 0, sizeof(exp_plane));
+
+ for (i = 0; i < ARRAY_SIZE(inp_vec); ++i)
+ {
+ inp_plane[i].a = inp_plane[i].c = inp_vec[i].x = inp_vec[i].z = i;
+ inp_plane[i].b = inp_plane[i].d = inp_vec[i].y = inp_vec[i].w = ARRAY_SIZE(inp_vec) - i;
+ }
+
+ set_matrix(&mat,
+ 1.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 6.0f, 7.0f, 8.0f,
+ 9.0f, 10.0f, 11.0f, 12.0f,
+ 13.0f, 14.0f, 15.0f, 16.0f);
+
+ D3DXMatrixPerspectiveFovLH(&projection, D3DX_PI / 4.0f, 20.0f / 17.0f, 1.0f, 1000.0f);
+
+ U(view).m[0][1] = 5.0f; U(view).m[0][2] = 7.0f; U(view).m[0][3] = 8.0f;
+ U(view).m[1][0] = 11.0f; U(view).m[1][2] = 16.0f; U(view).m[1][3] = 33.0f;
+ U(view).m[2][0] = 19.0f; U(view).m[2][1] = -21.0f; U(view).m[2][3] = 43.0f;
+ U(view).m[3][0] = 2.0f; U(view).m[3][1] = 3.0f; U(view).m[3][2] = -4.0f;
+ U(view).m[0][0] = 10.0f; U(view).m[1][1] = 20.0f; U(view).m[2][2] = 30.0f;
+ U(view).m[3][3] = -40.0f;
+
+ set_matrix(&world,
+ 21.0f, 2.0f, 3.0f, 4.0f,
+ 5.0f, 23.0f, 7.0f, 8.0f,
+ -8.0f, -7.0f, 25.0f, -5.0f,
+ -4.0f, -3.0f, -2.0f, 27.0f);
+
+ /* D3DXVec2TransformCoordArray */
+ exp_vec[1].x = 6.78571403e-01f; exp_vec[1].y = 7.85714269e-01f;
+ exp_vec[2].x = 6.53846204e-01f; exp_vec[2].y = 7.69230783e-01f;
+ exp_vec[3].x = 6.25000000e-01f; exp_vec[3].y = 7.50000000e-01f;
+ exp_vec[4].x = 5.90909123e-01f; exp_vec[4].y = 7.27272749e-01f;
+ exp_vec[5].x = 5.49999952e-01f; exp_vec[5].y = 6.99999928e-01f;
+ D3DXVec2TransformCoordArray((D3DXVECTOR2 *)&out_vec[1], sizeof(*out_vec),
+ (D3DXVECTOR2 *)inp_vec, sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 1);
+
+ /* D3DXVec2TransformNormalArray */
+ exp_vec[1].x = 25.0f; exp_vec[1].y = 30.0f;
+ exp_vec[2].x = 21.0f; exp_vec[2].y = 26.0f;
+ exp_vec[3].x = 17.0f; exp_vec[3].y = 22.0f;
+ exp_vec[4].x = 13.0f; exp_vec[4].y = 18.0f;
+ exp_vec[5].x = 9.0f; exp_vec[5].y = 14.0f;
+ D3DXVec2TransformNormalArray((D3DXVECTOR2 *)&out_vec[1], sizeof(*out_vec),
+ (D3DXVECTOR2 *)inp_vec, sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 0);
+
+ /* D3DXVec3TransformCoordArray */
+ exp_vec[1].x = 6.78571403e-01f; exp_vec[1].y = 7.85714269e-01f; exp_vec[1].z = 8.92857075e-01f;
+ exp_vec[2].x = 6.71874940e-01f; exp_vec[2].y = 7.81249940e-01f; exp_vec[2].z = 8.90624940e-01f;
+ exp_vec[3].x = 6.66666627e-01f; exp_vec[3].y = 7.77777731e-01f; exp_vec[3].z = 8.88888836e-01f;
+ exp_vec[4].x = 6.62499964e-01f; exp_vec[4].y = 7.74999976e-01f; exp_vec[4].z = 8.87499928e-01f;
+ exp_vec[5].x = 6.59090877e-01f; exp_vec[5].y = 7.72727251e-01f; exp_vec[5].z = 8.86363566e-01f;
+ D3DXVec3TransformCoordArray((D3DXVECTOR3 *)&out_vec[1], sizeof(*out_vec),
+ (D3DXVECTOR3 *)inp_vec, sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 1);
+
+ /* D3DXVec3TransformNormalArray */
+ exp_vec[1].x = 25.0f; exp_vec[1].y = 30.0f; exp_vec[1].z = 35.0f;
+ exp_vec[2].x = 30.0f; exp_vec[2].y = 36.0f; exp_vec[2].z = 42.0f;
+ exp_vec[3].x = 35.0f; exp_vec[3].y = 42.0f; exp_vec[3].z = 49.0f;
+ exp_vec[4].x = 40.0f; exp_vec[4].y = 48.0f; exp_vec[4].z = 56.0f;
+ exp_vec[5].x = 45.0f; exp_vec[5].y = 54.0f; exp_vec[5].z = 63.0f;
+ D3DXVec3TransformNormalArray((D3DXVECTOR3 *)&out_vec[1], sizeof(*out_vec),
+ (D3DXVECTOR3 *)inp_vec, sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 0);
+
+ /* D3DXVec3ProjectArray */
+ exp_vec[1].x = 1.08955420e+03f; exp_vec[1].y = -2.26590622e+02f; exp_vec[1].z = 2.15272754e-01f;
+ exp_vec[2].x = 1.06890344e+03f; exp_vec[2].y = 1.03085144e+02f; exp_vec[2].z = 1.83049560e-01f;
+ exp_vec[3].x = 1.05177905e+03f; exp_vec[3].y = 3.76462280e+02f; exp_vec[3].z = 1.56329080e-01f;
+ exp_vec[4].x = 1.03734888e+03f; exp_vec[4].y = 6.06827393e+02f; exp_vec[4].z = 1.33812696e-01f;
+ exp_vec[5].x = 1.02502356e+03f; exp_vec[5].y = 8.03591248e+02f; exp_vec[5].z = 1.14580572e-01f;
+ D3DXVec3ProjectArray((D3DXVECTOR3 *)&out_vec[1], sizeof(*out_vec), (D3DXVECTOR3 *)inp_vec,
+ sizeof(*inp_vec), &viewport, &projection, &view, &world, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 8);
+
+ /* D3DXVec3UnprojectArray */
+ exp_vec[1].x = -6.12403107e+00f; exp_vec[1].y = 3.22536016e+00f; exp_vec[1].z = 6.20571136e-01f;
+ exp_vec[2].x = -3.80710936e+00f; exp_vec[2].y = 2.04657936e+00f; exp_vec[2].z = 4.46894377e-01f;
+ exp_vec[3].x = -2.92283988e+00f; exp_vec[3].y = 1.59668946e+00f; exp_vec[3].z = 3.80609393e-01f;
+ exp_vec[4].x = -2.45622563e+00f; exp_vec[4].y = 1.35928988e+00f; exp_vec[4].z = 3.45631927e-01f;
+ exp_vec[5].x = -2.16789746e+00f; exp_vec[5].y = 1.21259713e+00f; exp_vec[5].z = 3.24018806e-01f;
+ D3DXVec3UnprojectArray((D3DXVECTOR3 *)&out_vec[1], sizeof(*out_vec), (D3DXVECTOR3 *)inp_vec,
+ sizeof(*inp_vec), &viewport, &projection, &view, &world, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 4);
+
+ /* D3DXVec2TransformArray */
+ exp_vec[1].x = 38.0f; exp_vec[1].y = 44.0f; exp_vec[1].z = 50.0f; exp_vec[1].w = 56.0f;
+ exp_vec[2].x = 34.0f; exp_vec[2].y = 40.0f; exp_vec[2].z = 46.0f; exp_vec[2].w = 52.0f;
+ exp_vec[3].x = 30.0f; exp_vec[3].y = 36.0f; exp_vec[3].z = 42.0f; exp_vec[3].w = 48.0f;
+ exp_vec[4].x = 26.0f; exp_vec[4].y = 32.0f; exp_vec[4].z = 38.0f; exp_vec[4].w = 44.0f;
+ exp_vec[5].x = 22.0f; exp_vec[5].y = 28.0f; exp_vec[5].z = 34.0f; exp_vec[5].w = 40.0f;
+ D3DXVec2TransformArray(&out_vec[1], sizeof(*out_vec), (D3DXVECTOR2 *)inp_vec,
+ sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 0);
+
+ /* D3DXVec3TransformArray */
+ exp_vec[1].x = 38.0f; exp_vec[1].y = 44.0f; exp_vec[1].z = 50.0f; exp_vec[1].w = 56.0f;
+ exp_vec[2].x = 43.0f; exp_vec[2].y = 50.0f; exp_vec[2].z = 57.0f; exp_vec[2].w = 64.0f;
+ exp_vec[3].x = 48.0f; exp_vec[3].y = 56.0f; exp_vec[3].z = 64.0f; exp_vec[3].w = 72.0f;
+ exp_vec[4].x = 53.0f; exp_vec[4].y = 62.0f; exp_vec[4].z = 71.0f; exp_vec[4].w = 80.0f;
+ exp_vec[5].x = 58.0f; exp_vec[5].y = 68.0f; exp_vec[5].z = 78.0f; exp_vec[5].w = 88.0f;
+ D3DXVec3TransformArray(&out_vec[1], sizeof(*out_vec), (D3DXVECTOR3 *)inp_vec,
+ sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 0);
+
+ /* D3DXVec4TransformArray */
+ exp_vec[1].x = 90.0f; exp_vec[1].y = 100.0f; exp_vec[1].z = 110.0f; exp_vec[1].w = 120.0f;
+ exp_vec[2].x = 82.0f; exp_vec[2].y = 92.0f; exp_vec[2].z = 102.0f; exp_vec[2].w = 112.0f;
+ exp_vec[3].x = 74.0f; exp_vec[3].y = 84.0f; exp_vec[3].z = 94.0f; exp_vec[3].w = 104.0f;
+ exp_vec[4].x = 66.0f; exp_vec[4].y = 76.0f; exp_vec[4].z = 86.0f; exp_vec[4].w = 96.0f;
+ exp_vec[5].x = 58.0f; exp_vec[5].y = 68.0f; exp_vec[5].z = 78.0f; exp_vec[5].w = 88.0f;
+ D3DXVec4TransformArray(&out_vec[1], sizeof(*out_vec), inp_vec, sizeof(*inp_vec), &mat, ARRAY_SIZE(inp_vec));
+ expect_vec4_array(ARRAY_SIZE(exp_vec), exp_vec, out_vec, 0);
+
+ /* D3DXPlaneTransformArray */
+ exp_plane[1].a = 90.0f; exp_plane[1].b = 100.0f; exp_plane[1].c = 110.0f; exp_plane[1].d = 120.0f;
+ exp_plane[2].a = 82.0f; exp_plane[2].b = 92.0f; exp_plane[2].c = 102.0f; exp_plane[2].d = 112.0f;
+ exp_plane[3].a = 74.0f; exp_plane[3].b = 84.0f; exp_plane[3].c = 94.0f; exp_plane[3].d = 104.0f;
+ exp_plane[4].a = 66.0f; exp_plane[4].b = 76.0f; exp_plane[4].c = 86.0f; exp_plane[4].d = 96.0f;
+ exp_plane[5].a = 58.0f; exp_plane[5].b = 68.0f; exp_plane[5].c = 78.0f; exp_plane[5].d = 88.0f;
+ D3DXPlaneTransformArray(&out_plane[1], sizeof(*out_plane), inp_plane,
+ sizeof(*inp_plane), &mat, ARRAY_SIZE(inp_plane));
+ for (i = 0; i < ARRAY_SIZE(exp_plane); ++i)
+ {
+ BOOL equal = compare_plane(&exp_plane[i], &out_plane[i], 0);
+ ok(equal, "Got unexpected plane {%.8e, %.8e, %.8e, %.8e} at index %u, expected {%.8e, %.8e, %.8e, %.8e}.\n",
+ out_plane[i].a, out_plane[i].b, out_plane[i].c, out_plane[i].d, i,
+ exp_plane[i].a, exp_plane[i].b, exp_plane[i].c, exp_plane[i].d);
+ if (!equal)
+ break;
+ }
+}
+
+static void test_D3DXFloat_Array(void)
+{
+ unsigned int i;
+ void *out = NULL;
+ D3DXFLOAT16 half;
+ BOOL equal;
+
+ /* Input floats through bit patterns because compilers do not generate reliable INF and NaN values. */
+ union convert
+ {
+ DWORD d;
+ float f;
+ } single;
+
+ struct
+ {
+ union convert single_in;
+
+ /* half_ver2 occurs on WXPPROSP3 (32 bit math), WVISTAADM (32/64 bit math), W7PRO (32 bit math) */
+ WORD half_ver1, half_ver2;
+
+ /* single_out_ver2 confirms that half -> single conversion is consistent across platforms */
+ union convert single_out_ver1, single_out_ver2;
+ }
+ testdata[] =
+ {
+ { { 0x479c4000 }, 0x7c00, 0x7ce2, { 0x47800000 }, { 0x479c4000 } }, /* 80000.0f */
+ { { 0x477fdf00 }, 0x7bff, 0x7bff, { 0x477fe000 }, { 0x477fe000 } }, /* 65503.0f */
+ { { 0x477fe000 }, 0x7bff, 0x7bff, { 0x477fe000 }, { 0x477fe000 } }, /* 65504.0f */
+ { { 0x477ff000 }, 0x7bff, 0x7c00, { 0x477fe000 }, { 0x47800000 } }, /* 65520.0f */
+ { { 0x477ff100 }, 0x7c00, 0x7c00, { 0x47800000 }, { 0x47800000 } }, /* 65521.0f */
+
+ { { 0x477ffe00 }, 0x7c00, 0x7c00, { 0x47800000 }, { 0x47800000 } }, /* 65534.0f */
+ { { 0x477fff00 }, 0x7c00, 0x7c00, { 0x47800000 }, { 0x47800000 } }, /* 65535.0f */
+ { { 0x47800000 }, 0x7c00, 0x7c00, { 0x47800000 }, { 0x47800000 } }, /* 65536.0f */
+ { { 0xc79c4000 }, 0xfc00, 0xfce2, { 0xc7800000 }, { 0xc79c4000 } }, /* -80000.0f */
+ { { 0xc77fdf00 }, 0xfbff, 0xfbff, { 0xc77fe000 }, { 0xc77fe000 } }, /* -65503.0f */
+
+ { { 0xc77fe000 }, 0xfbff, 0xfbff, { 0xc77fe000 }, { 0xc77fe000 } }, /* -65504.0f */
+ { { 0xc77ff000 }, 0xfbff, 0xfc00, { 0xc77fe000 }, { 0xc7800000 } }, /* -65520.0f */
+ { { 0xc77ff100 }, 0xfc00, 0xfc00, { 0xc7800000 }, { 0xc7800000 } }, /* -65521.0f */
+ { { 0xc77ffe00 }, 0xfc00, 0xfc00, { 0xc7800000 }, { 0xc7800000 } }, /* -65534.0f */
+ { { 0xc77fff00 }, 0xfc00, 0xfc00, { 0xc7800000 }, { 0xc7800000 } }, /* -65535.0f */
+
+ { { 0xc7800000 }, 0xfc00, 0xfc00, { 0xc7800000 }, { 0xc7800000 } }, /* -65536.0f */
+ { { 0x7f800000 }, 0x7c00, 0x7fff, { 0x47800000 }, { 0x47ffe000 } }, /* INF */
+ { { 0xff800000 }, 0xffff, 0xffff, { 0xc7ffe000 }, { 0xc7ffe000 } }, /* -INF */
+ { { 0x7fc00000 }, 0x7fff, 0xffff, { 0x47ffe000 }, { 0xc7ffe000 } }, /* NaN */
+ { { 0xffc00000 }, 0xffff, 0xffff, { 0xc7ffe000 }, { 0xc7ffe000 } }, /* -NaN */
+
+ { { 0x00000000 }, 0x0000, 0x0000, { 0x00000000 }, { 0x00000000 } }, /* 0.0f */
+ { { 0x80000000 }, 0x8000, 0x8000, { 0x80000000 }, { 0x80000000 } }, /* -0.0f */
+ { { 0x330007ff }, 0x0000, 0x0000, { 0x00000000 }, { 0x00000000 } }, /* 2.9809595e-08f */
+ { { 0xb30007ff }, 0x8000, 0x8000, { 0x80000000 }, { 0x80000000 } }, /* -2.9809595e-08f */
+ { { 0x33000800 }, 0x0001, 0x0000, { 0x33800000 }, { 0x00000000 } }, /* 2.9809598e-08f */
+
+ { { 0xb3000800 }, 0x8001, 0x8000, { 0xb3800000 }, { 0x80000000 } }, /* -2.9809598e-08f */
+ { { 0x33c00000 }, 0x0002, 0x0001, { 0x34000000 }, { 0x33800000 } }, /* 8.9406967e-08f */
+ };
+
+ /* exception on NULL out or in parameter */
+ out = D3DXFloat32To16Array(&half, &single.f, 0);
+ ok(out == &half, "Got %p, expected %p.\n", out, &half);
+
+ out = D3DXFloat16To32Array(&single.f, &half, 0);
+ ok(out == &single.f, "Got %p, expected %p.\n", out, &single.f);
+
+ for (i = 0; i < ARRAY_SIZE(testdata); ++i)
+ {
+ out = D3DXFloat32To16Array(&half, &testdata[i].single_in.f, 1);
+ ok(out == &half, "Got %p, expected %p.\n", out, &half);
+ ok(half.value == testdata[i].half_ver1 || half.value == testdata[i].half_ver2,
+ "Got %x, expected %x or %x for index %d.\n", half.value, testdata[i].half_ver1,
+ testdata[i].half_ver2, i);
+
+ out = D3DXFloat16To32Array(&single.f, (D3DXFLOAT16 *)&testdata[i].half_ver1, 1);
+ ok(out == &single.f, "Got %p, expected %p.\n", out, &single.f);
+ equal = compare_float(single.f, testdata[i].single_out_ver1.f, 0);
+ ok(equal, "Got %#x, expected %#x at index %u.\n", single.d, testdata[i].single_out_ver1.d, i);
+
+ out = D3DXFloat16To32Array(&single.f, (D3DXFLOAT16 *)&testdata[i].half_ver2, 1);
+ ok(out == &single.f, "Got %p, expected %p.\n", out, &single.f);
+ equal = compare_float(single.f, testdata[i].single_out_ver2.f, 0);
+ ok(equal, "Got %#x, expected %#x at index %u.\n", single.d, testdata[i].single_out_ver2.d, i);
+ }
+}
+
+static void test_D3DXSHAdd(void)
+{
+ float out[50] = {0.0f};
+ unsigned int i, k;
+ float *ret;
+ BOOL equal;
+
+ static const float in1[50] =
+ {
+ 1.11f, 1.12f, 1.13f, 1.14f, 1.15f, 1.16f, 1.17f, 1.18f,
+ 1.19f, 1.20f, 1.21f, 1.22f, 1.23f, 1.24f, 1.25f, 1.26f,
+ 1.27f, 1.28f, 1.29f, 1.30f, 1.31f, 1.32f, 1.33f, 1.34f,
+ 1.35f, 1.36f, 1.37f, 1.38f, 1.39f, 1.40f, 1.41f, 1.42f,
+ 1.43f, 1.44f, 1.45f, 1.46f, 1.47f, 1.48f, 1.49f, 1.50f,
+ 1.51f, 1.52f, 1.53f, 1.54f, 1.55f, 1.56f, 1.57f, 1.58f,
+ 1.59f, 1.60f,
+ };
+ static const float in2[50] =
+ {
+ 2.11f, 2.12f, 2.13f, 2.14f, 2.15f, 2.16f, 2.17f, 2.18f,
+ 2.19f, 2.20f, 2.21f, 2.22f, 2.23f, 2.24f, 2.25f, 2.26f,
+ 2.27f, 2.28f, 2.29f, 2.30f, 2.31f, 2.32f, 2.33f, 2.34f,
+ 2.35f, 2.36f, 2.37f, 2.38f, 2.39f, 2.40f, 2.41f, 2.42f,
+ 2.43f, 2.44f, 2.45f, 2.46f, 2.47f, 2.48f, 2.49f, 2.50f,
+ 2.51f, 2.52f, 2.53f, 2.54f, 2.55f, 2.56f, 2.57f, 2.58f,
+ 2.59f, 2.60f,
+ };
+
+ /*
+ * Order is not limited by D3DXSH_MINORDER and D3DXSH_MAXORDER!
+ * All values will work, test from 0-7 [D3DXSH_MINORDER = 2, D3DXSH_MAXORDER = 6]
+ * Exceptions will show up when out, in1 or in2 is NULL
+ */
+ for (k = 0; k <= D3DXSH_MAXORDER + 1; k++)
+ {
+ UINT count = k * k;
+
+ ret = D3DXSHAdd(&out[0], k, &in1[0], &in2[0]);
+ ok(ret == out, "%u: D3DXSHAdd() failed, got %p, expected %p\n", k, out, ret);
+
+ for (i = 0; i < count; ++i)
+ {
+ equal = compare_float(in1[i] + in2[i], out[i], 0);
+ ok(equal, "%u-%u: Got %.8e, expected %.8e.\n", k, i, out[i], in1[i] + in2[i]);
+ }
+ equal = compare_float(out[count], 0.0f, 0);
+ ok(equal, "%u-%u: Got %.8e, expected 0.0.\n", k, k * k, out[count]);
+ }
+}
+
+static void test_D3DXSHDot(void)
+{
+ float a[49], b[49], got;
+ unsigned int i;
+ BOOL equal;
+
+ static const float expected[] = {0.5f, 0.5f, 25.0f, 262.5f, 1428.0f, 5362.5f, 15873.0f, 39812.5f};
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ a[i] = i + 1.0f;
+ b[i] = i + 0.5f;
+ }
+
+ /* D3DXSHDot computes by using order * order elements */
+ for (i = 0; i <= D3DXSH_MAXORDER + 1; i++)
+ {
+ got = D3DXSHDot(i, a, b);
+ equal = compare_float(got, expected[i], 0);
+ ok(equal, "order %u: Got %.8e, expected %.8e.\n", i, got, expected[i]);
+ }
+}
+
+static void test_D3DXSHEvalConeLight(void)
+{
+ float bout[49], expected, gout[49], rout[49];
+ unsigned int j, l, order;
+ D3DXVECTOR3 dir;
+ HRESULT hr;
+ BOOL equal;
+
+ static const float table[] =
+ {
+ /* Red colour */
+ 1.604815f, -3.131381f, 7.202175f, -2.870432f, 6.759296f, -16.959688f,
+ 32.303082f, -15.546381f, -0.588878f, -5.902123f, 40.084042f, -77.423569f,
+ 137.556320f, -70.971603f, -3.492171f, 7.683092f, -2.129311f, -35.971344f,
+ 183.086548f, -312.414948f, 535.091064f, -286.380371f, -15.950727f, 46.825714f,
+ -12.127637f, 11.289261f, -12.417809f, -155.039566f, 681.182556f, -1079.733643f,
+ 1807.650513f, -989.755798f, -59.345467f, 201.822815f, -70.726486f, 7.206529f,
+
+ 3.101155f, -3.128710f, 7.196033f, -2.867984f, -0.224708f, 0.563814f,
+ -1.073895f, 0.516829f, 0.019577f, 2.059788f, -13.988971f, 27.020128f,
+ -48.005917f, 24.768450f, 1.218736f, -2.681329f, -0.088639f, -1.497410f,
+ 7.621501f, -13.005165f, 22.274696f, -11.921401f, -0.663995f, 1.949254f,
+ -0.504848f, 4.168484f, -4.585193f, -57.247314f, 251.522095f, -398.684387f,
+ 667.462891f, -365.460693f, -21.912912f, 74.521721f, -26.115280f, 2.660963f,
+ /* Green colour */
+ 2.454422f, -4.789170f, 11.015091f, -4.390072f, 10.337747f, -25.938347f,
+ 49.404713f, -23.776817f, -0.900637f, -9.026776f, 61.305000f, -118.412514f,
+ 210.380249f, -108.544792f, -5.340967f, 11.750610f, -3.256593f, -55.014996f,
+ 280.014709f, -477.811066f, 818.374512f, -437.993469f, -24.395227f, 71.615799f,
+ -18.548151f, 17.265928f, -18.991943f, -237.119324f, 1041.808594f, -1651.357300f,
+ 2764.642090f, -1513.744141f, -90.763657f, 308.670197f, -108.169922f, 11.021750f,
+
+ 4.742942f, -4.785086f, 11.005697f, -4.386329f, -0.343672f, 0.862303f,
+ -1.642427f, 0.790444f, 0.029941f, 3.150264f, -21.394896f, 41.324898f,
+ -73.420807f, 37.881153f, 1.863950f, -4.100857f, -0.135565f, -2.290156f,
+ 11.656413f, -19.890251f, 34.067181f, -18.232729f, -1.015521f, 2.981212f,
+ -0.772120f, 6.375328f, -7.012648f, -87.554710f, 384.680817f, -609.752563f,
+ 1020.825500f, -558.939819f, -33.513863f, 113.974388f, -39.941013f, 4.069707f,
+ /* Blue colour */
+ 3.304030f, -6.446959f, 14.828006f, -5.909713f, 13.916198f, -34.917004f,
+ 66.506340f, -32.007256f, -1.212396f, -12.151429f, 82.525963f, -159.401459f,
+ 283.204193f, -146.117996f, -7.189764f, 15.818130f, -4.383876f, -74.058655f,
+ 376.942871f, -643.207214f, 1101.658081f, -589.606628f, -32.839729f, 96.405884f,
+ -24.968664f, 23.242596f, -25.566080f, -319.199097f, 1402.434692f, -2222.980957f,
+ 3721.633545f, -2037.732544f, -122.181847f, 415.517578f, -145.613358f, 14.836972f,
+
+ 6.384730f, -6.441462f, 14.815362f, -5.904673f, -0.462635f, 1.160793f,
+ -2.210959f, 1.064060f, 0.040305f, 4.240739f, -28.800821f, 55.629673f,
+ -98.835709f, 50.993862f, 2.509163f, -5.520384f, -0.182491f, -3.082903f,
+ 15.691326f, -26.775339f, 45.859665f, -24.544060f, -1.367048f, 4.013170f,
+ -1.039392f, 8.582172f, -9.440103f, -117.862114f, 517.839600f, -820.820740f,
+ 1374.188232f, -752.419067f, -45.114819f, 153.427063f, -53.766754f, 5.478452f, };
+ const struct
+ {
+ float *red_received, *green_received, *blue_received;
+ const float *red_expected, *green_expected, *blue_expected;
+ float radius, roffset, goffset, boffset;
+ }
+ test[] =
+ {
+ { rout, gout, bout, table, &table[72], &table[144], 0.5f, 1.01f, 1.02f, 1.03f, },
+ { rout, gout, bout, &table[36], &table[108], &table[180], 1.6f, 1.01f, 1.02f, 1.03f, },
+ { rout, rout, rout, &table[144], &table[144], &table[144], 0.5f, 1.03f, 1.03f, 1.03f, },
+ { rout, rout, bout, &table[72], &table[72], &table[144], 0.5, 1.02f, 1.02f, 1.03f, },
+ { rout, gout, gout, table, &table[144], &table[144], 0.5f, 1.01f, 1.03f, 1.03f, },
+ { rout, gout, rout, &table[144], &table[72], &table[144], 0.5f, 1.03f, 1.02f, 1.03f, },
+ /* D3DXSHEvalConeLight accepts NULL green or blue colour. */
+ { rout, NULL, bout, table, NULL, &table[144], 0.5f, 1.01f, 0.0f, 1.03f, },
+ { rout, gout, NULL, table, &table[72], NULL, 0.5f, 1.01f, 1.02f, 0.0f, },
+ { rout, NULL, NULL, table, NULL, NULL, 0.5f, 1.01f, 0.0f, 0.0f, },
+ };
+
+ dir.x = 1.1f; dir.y = 1.2f; dir.z = 2.76f;
+
+ for (l = 0; l < ARRAY_SIZE(test); ++l)
+ {
+ for (order = D3DXSH_MINORDER; order <= D3DXSH_MAXORDER; order++)
+ {
+ for (j = 0; j < 49; j++)
+ {
+ test[l].red_received[j] = 1.01f + j;
+ if (test[l].green_received)
+ test[l].green_received[j] = 1.02f + j;
+ if (test[l].blue_received)
+ test[l].blue_received[j] = 1.03f + j;
+ }
+
+ hr = D3DXSHEvalConeLight(order, &dir, test[l].radius, 1.7f, 2.6f, 3.5f, test[l].red_received, test[l].green_received, test[l].blue_received);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+
+ for (j = 0; j < 49; j++)
+ {
+ if (j >= order * order)
+ expected = j + test[l].roffset;
+ else
+ expected = test[l].red_expected[j];
+ equal = compare_float(test[l].red_received[j], expected, 128);
+ ok(equal, "Red: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].red_received[j]);
+
+ if (test[l].green_received)
+ {
+ if (j >= order * order)
+ expected = j + test[l].goffset;
+ else
+ expected = test[l].green_expected[j];
+ equal = compare_float(test[l].green_received[j], expected, 64);
+ ok(equal, "Green: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].green_received[j]);
+ }
+
+ if (test[l].blue_received)
+ {
+ if (j >= order * order)
+ expected = j + test[l].boffset;
+ else
+ expected = test[l].blue_expected[j];
+ equal = compare_float(test[l].blue_received[j], expected, 128);
+ ok(equal, "Blue: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].blue_received[j]);
+ }
+ }
+ }
+ }
+
+ /* Cone light with radius <= 0.0f behaves as a directional light */
+ for (order = D3DXSH_MINORDER; order <= D3DXSH_MAXORDER; order++)
+ {
+ FLOAT blue[49], green[49], red[49];
+
+ for (j = 0; j < 49; j++)
+ {
+ rout[j] = 1.01f + j;
+ gout[j] = 1.02f + j;
+ bout[j] = 1.03f + j;
+ red[j] = 1.01f + j;
+ green[j] = 1.02f + j;
+ blue[j] = 1.03f + j;
+ }
+
+ hr = D3DXSHEvalConeLight(order, &dir, -0.1f, 1.7f, 2.6f, 3.5f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ D3DXSHEvalDirectionalLight(order, &dir, 1.7f, 2.6f, 3.5f, red, green, blue);
+
+ for (j = 0; j < 49; j++)
+ {
+ equal = compare_float(red[j], rout[j], 0);
+ ok(equal, "Red: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, red[j], rout[j]);
+
+ equal = compare_float(green[j], gout[j], 0);
+ ok(equal, "Green: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, green[j], gout[j]);
+
+ equal = compare_float(blue[j], bout[j], 0);
+ ok(equal, "Blue: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, blue[j], bout[j]);
+ }
+ }
+
+ /* D3DXSHEvalConeLight accepts order < D3DXSH_MINORDER or order > D3DXSH_MAXORDER. But tests in native windows show that the colour outputs are not set */
+ hr = D3DXSHEvalConeLight(7, &dir, 0.5f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalConeLight(0, &dir, 0.5f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalConeLight(1, &dir, 0.5f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+}
+
+static void test_D3DXSHEvalDirection(void)
+{
+ float a[49], expected, *received_ptr;
+ unsigned int i, order;
+ D3DXVECTOR3 d;
+ BOOL equal;
+
+ static const float table[36] =
+ {
+ 2.82094806e-01f, -9.77205038e-01f, 1.46580756e+00f, -4.88602519e-01f, 2.18509698e+00f, -6.55529118e+00f,
+ 8.20018101e+00f, -3.27764559e-00f, -1.63882279e+00f, 1.18008721e+00f, 1.73436680e+01f, -4.02200317e+01f,
+ 4.70202179e+01f, -2.01100159e+01f, -1.30077515e+01f, 6.49047947e+00f, -1.50200577e+01f, 1.06207848e+01f,
+ 1.17325661e+02f, -2.40856750e+02f, 2.71657288e+02f, -1.20428375e+02f, -8.79942474e+01f, 5.84143143e+01f,
+ -4.38084984e+00f, 2.49425201e+01f, -1.49447693e+02f, 7.82781296e+01f, 7.47791748e+02f, -1.42768787e+03f,
+ 1.57461914e+03f, -7.13843933e+02f, -5.60843811e+02f, 4.30529724e+02f, -4.35889091e+01f, -2.69116650e+01f,
+ };
+
+ d.x = 1.0; d.y = 2.0f; d.z = 3.0f;
+
+ for (order = 0; order <= D3DXSH_MAXORDER + 1; order++)
+ {
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ a[i] = 1.5f + i;
+
+ received_ptr = D3DXSHEvalDirection(a, order, &d);
+ ok(received_ptr == a, "Expected %p, received %p\n", a, received_ptr);
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ /* if the order is < D3DXSH_MINORDER or order > D3DXSH_MAXORDER or
+ * the index of the element is greater than order * order - 1,
+ * D3DXSHEvalDirection() does not modify the output. */
+ if ((order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) || (i >= order * order))
+ expected = 1.5f + i;
+ else
+ expected = table[i];
+
+ equal = compare_float(a[i], expected, 2);
+ ok(equal, "order %u, index %u: Got unexpected result %.8e, expected %.8e.\n",
+ order, i, a[i], expected);
+ }
+ }
+}
+
+static void test_D3DXSHEvalDirectionalLight(void)
+{
+ float *blue_out, bout[49], expected, gout[49], *green_out, *red_out, rout[49];
+ unsigned int j, l, order, startindex;
+ D3DXVECTOR3 dir;
+ HRESULT hr;
+ BOOL equal;
+
+ static const float table[] =
+ {
+ /* Red colour */
+ 2.008781f, -4.175174f, 9.602900f, -3.827243f, 1.417963f, -2.947181f,
+ 6.778517f, -2.701583f, 7.249108f, -18.188671f, 34.643921f, -16.672949f,
+ -0.631551f, 1.417963f, -2.947181f, 6.778517f, -2.701583f, 7.249108f,
+ -18.188671f, 34.643921f, -16.672949f, -0.631551f, -7.794341f, 52.934967f,
+ -102.245529f, 181.656815f, -93.725060f, -4.611760f, 10.146287f, 1.555186f,
+ -3.232392f, 7.434503f, -2.963026f, 7.950634f, -19.948866f, 37.996559f,
+ -18.286459f, -0.692669f, -8.548632f, 58.057705f, -112.140251f, 199.236496f,
+ -102.795227f, -5.058059f, 11.128186f, -4.189955f, -70.782669f, 360.268829f,
+ -614.755005f, 1052.926270f, -563.525391f, -31.387066f, 92.141365f, -23.864176f,
+ 1.555186f, -3.232392f, 7.434503f, -2.963026f, 7.950634f, -19.948866f,
+ 37.996559f, -18.286459f, -0.692669f, -8.548632f, 58.057705f, -112.140251f,
+ 199.236496f, -102.795227f, -5.058059f, 11.128186f, -4.189955f, -70.782669f,
+ 360.268829f, -614.755005f, 1052.926270f, -563.525391f, -31.387066f, 92.141365f,
+ -23.864176f, 34.868664f, -38.354366f, -478.864166f, 2103.939941f, -3334.927734f,
+ 5583.213867f, -3057.017090f, -183.297836f, 623.361633f, -218.449921f, 22.258503f,
+ /* Green colour */
+ 3.072254f, -6.385560f, 14.686787f, -5.853429f, 2.168650f, -4.507453f,
+ 10.367143f, -4.131832f, 11.086870f, -27.817965f, 52.984818f, -25.499800f,
+ -0.965902f, 2.168650f, -4.507453f, 10.367143f, -4.131832f, 11.086870f,
+ -27.817965f, 52.984818f, -25.499800f, -0.965902f, -11.920755f, 80.959351f,
+ -156.375488f, 277.828033f, -143.344193f, -7.053278f, 15.517849f, 2.378519f,
+ -4.943659f, 11.370415f, -4.531687f, 12.159794f, -30.510029f, 58.112385f,
+ -27.967525f, -1.059376f, -13.074378f, 88.794136f, -171.508621f, 304.714630f,
+ -157.216217f, -7.735855f, 17.019577f, -6.408166f, -108.255844f, 550.999390f,
+ -940.213501f, 1610.357788f, -861.862305f, -48.003746f, 140.922089f, -36.498150f,
+ 2.378519f, -4.943659f, 11.370415f, -4.531687f, 12.159794f, -30.510029f,
+ 58.112385f, -27.967525f, -1.059376f, -13.074378f, 88.794136f, -171.508621f,
+ 304.714630f, -157.216217f, -7.735855f, 17.019577f, -6.408166f, -108.255844f,
+ 550.999390f, -940.213501f, 1610.357788f, -861.862305f, -48.003746f, 140.922089f,
+ -36.498150f, 53.328545f, -58.659618f, -732.380493f, 3217.790283f, -5100.477539f,
+ 8539.033203f, -4675.437500f, -280.337860f, 953.376587f, -334.099884f, 34.042416f,
+ /* Blue colour */
+ 4.135726f, -8.595945f, 19.770674f, -7.879617f, 2.919336f, -6.067726f,
+ 13.955770f, -5.562082f, 14.924634f, -37.447262f, 71.325722f, -34.326656f,
+ -1.300252f, 2.919336f, -6.067726f, 13.955770f, -5.562082f, 14.924634f,
+ -37.447262f, 71.325722f, -34.326656f, -1.300252f, -16.047173f, 108.983749f,
+ -210.505493f, 373.999298f, -192.963348f, -9.494799f, 20.889414f, 3.201853f,
+ -6.654925f, 15.306328f, -6.100348f, 16.368954f, -41.071194f, 78.228210f,
+ -37.648590f, -1.426083f, -17.600124f, 119.530563f, -230.876984f, 410.192780f,
+ -211.637222f, -10.413651f, 22.910971f, -8.626378f, -145.729019f, 741.729919f,
+ -1265.671997f, 2167.789307f, -1160.199219f, -64.620430f, 189.702820f, -49.132126f,
+ 3.201853f, -6.654925f, 15.306328f, -6.100348f, 16.368954f, -41.071194f,
+ 78.228210f, -37.648590f, -1.426083f, -17.600124f, 119.530563f, -230.876984f,
+ 410.192780f, -211.637222f, -10.413651f, 22.910971f, -8.626378f, -145.729019f,
+ 741.729919f, -1265.671997f, 2167.789307f, -1160.199219f, -64.620430f, 189.702820f,
+ -49.132126f, 71.788422f, -78.964867f, -985.896790f, 4331.640625f, -6866.027344f,
+ 11494.852539f, -6293.858398f, -377.377899f, 1283.391479f, -449.749817f, 45.826328f, };
+ const struct
+ {
+ float *red_in, *green_in, *blue_in;
+ const float *red_out, *green_out, *blue_out;
+ float roffset, goffset, boffset;
+ }
+ test[] =
+ {
+ { rout, gout, bout, table, &table[90], &table[180], 1.01f, 1.02f, 1.03f, },
+ { rout, rout, rout, &table[180], &table[180], &table[180], 1.03f, 1.03f, 1.03f, },
+ { rout, rout, bout, &table[90], &table[90], &table[180], 1.02f, 1.02f, 1.03f, },
+ { rout, gout, gout, table, &table[180], &table[180], 1.01f, 1.03f, 1.03f, },
+ { rout, gout, rout, &table[180], &table[90], &table[180], 1.03f, 1.02f, 1.03f, },
+ /* D3DXSHEvalDirectionaLight accepts NULL green or blue colour. */
+ { rout, NULL, bout, table, NULL, &table[180], 1.01f, 0.0f, 1.03f, },
+ { rout, gout, NULL, table, &table[90], NULL, 1.01f, 1.02f, 0.0f, },
+ { rout, NULL, NULL, table, NULL, NULL, 1.01f, 0.0f, 0.0f, },
+ };
+
+ dir.x = 1.1f; dir.y= 1.2f; dir.z = 2.76f;
+
+ for (l = 0; l < ARRAY_SIZE(test); ++l)
+ {
+ startindex = 0;
+
+ for (order = D3DXSH_MINORDER; order <= D3DXSH_MAXORDER; order++)
+ {
+ red_out = test[l].red_in;
+ green_out = test[l].green_in;
+ blue_out = test[l].blue_in;
+
+ for (j = 0; j < ARRAY_SIZE(rout); ++j)
+ {
+ red_out[j] = 1.01f + j;
+ if ( green_out )
+ green_out[j] = 1.02f + j;
+ if ( blue_out )
+ blue_out[j] = 1.03f + j;
+ }
+
+ hr = D3DXSHEvalDirectionalLight(order, &dir, 1.7f, 2.6f, 3.5f, red_out, green_out, blue_out);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+
+ for (j = 0; j < ARRAY_SIZE(rout); ++j)
+ {
+ if ( j >= order * order )
+ expected = j + test[l].roffset;
+ else
+ expected = test[l].red_out[startindex + j];
+ equal = compare_float(expected, red_out[j], 8);
+ ok(equal, "Red: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, red_out[j]);
+
+ if ( green_out )
+ {
+ if ( j >= order * order )
+ expected = j + test[l].goffset;
+ else
+ expected = test[l].green_out[startindex + j];
+ equal = compare_float(expected, green_out[j], 8);
+ ok(equal, "Green: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, green_out[j]);
+ }
+
+ if ( blue_out )
+ {
+ if ( j >= order * order )
+ expected = j + test[l].boffset;
+ else
+ expected = test[l].blue_out[startindex + j];
+ equal = compare_float(expected, blue_out[j], 4);
+ ok(equal, "Blue: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, blue_out[j]);
+ }
+ }
+
+ startindex += order * order;
+ }
+ }
+
+ /* D3DXSHEvalDirectionalLight accepts order < D3DXSH_MINORDER or order > D3DXSH_MAXORDER. But tests in native windows show that the colour outputs are not set*/
+ hr = D3DXSHEvalDirectionalLight(7, &dir, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalDirectionalLight(0, &dir, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalDirectionalLight(1, &dir, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+}
+
+static void test_D3DXSHEvalHemisphereLight(void)
+{
+ float bout[49], expected, gout[49], rout[49];
+ unsigned int j, l, order;
+ D3DXCOLOR bottom, top;
+ D3DXVECTOR3 dir;
+ HRESULT hr;
+ BOOL equal;
+
+ static const float table[] =
+ {
+ /* Red colour. */
+ 23.422981f, 15.859521f, -36.476898f, 14.537894f,
+ /* Green colour. */
+ 19.966694f, 6.096982f, -14.023058f, 5.588900f,
+ /* Blue colour. */
+ 24.566214f, 8.546826f, -19.657701f, 7.834591f,
+ };
+ const struct
+ {
+ float *red_received, *green_received, *blue_received;
+ const float *red_expected, *green_expected, *blue_expected;
+ const float roffset, goffset, boffset;
+ }
+ test[] =
+ {
+ { rout, gout, bout, table, &table[4], &table[8], 1.01f, 1.02f, 1.03f, },
+ { rout, rout, rout, &table[8], &table[8], &table[8], 1.03f, 1.03f, 1.03f, },
+ { rout, rout, bout, &table[4], &table[4], &table[8], 1.02f, 1.02f, 1.03f, },
+ { rout, gout, gout, table, &table[8], &table[8], 1.01f, 1.03f, 1.03f, },
+ { rout, gout, rout, &table[8], &table[4], &table[8], 1.03f, 1.02f, 1.03f, },
+ /* D3DXSHEvalHemisphereLight accepts NULL green or blue colour. */
+ { rout, NULL, bout, table, NULL, &table[8], 1.01f, 1.02f, 1.03f, },
+ { rout, gout, NULL, table, &table[4], NULL, 1.01f, 1.02f, 1.03f, },
+ { rout, NULL, NULL, table, NULL, NULL, 1.01f, 1.02f, 1.03f, },
+ };
+
+ dir.x = 1.1f; dir.y = 1.2f; dir.z = 2.76f;
+ top.r = 0.1f; top.g = 2.1f; top.b = 2.3f; top.a = 4.3f;
+ bottom.r = 8.71f; bottom.g = 5.41f; bottom.b = 6.94f; bottom.a = 8.43f;
+
+ for (l = 0; l < ARRAY_SIZE(test); ++l)
+ for (order = D3DXSH_MINORDER; order <= D3DXSH_MAXORDER + 1; order++)
+ {
+ for (j = 0; j < 49; j++)
+ {
+ test[l].red_received[j] = 1.01f + j;
+ if (test[l].green_received)
+ test[l].green_received[j] = 1.02f + j;
+ if (test[l].blue_received)
+ test[l].blue_received[j] = 1.03f + j;
+ }
+
+ hr = D3DXSHEvalHemisphereLight(order, &dir, top, bottom, test[l].red_received, test[l].green_received, test[l].blue_received);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+
+ for (j = 0; j < 49; j++)
+ {
+ if (j < 4)
+ expected = test[l].red_expected[j];
+ else if (j < order * order)
+ expected = 0.0f;
+ else
+ expected = test[l].roffset + j;
+ equal = compare_float(test[l].red_received[j], expected, 4);
+ ok(equal, "Red: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].red_received[j]);
+
+ if (test[l].green_received)
+ {
+ if (j < 4)
+ expected = test[l].green_expected[j];
+ else if (j < order * order)
+ expected = 0.0f;
+ else
+ expected = test[l].goffset + j;
+ equal = compare_float(expected, test[l].green_received[j], 4);
+ ok(equal, "Green: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].green_received[j]);
+ }
+
+ if (test[l].blue_received)
+ {
+ if (j < 4)
+ expected = test[l].blue_expected[j];
+ else if (j < order * order)
+ expected = 0.0f;
+ else
+ expected = test[l].boffset + j;
+ equal = compare_float(expected, test[l].blue_received[j], 4);
+ ok(equal, "Blue: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].blue_received[j]);
+ }
+ }
+ }
+}
+
+static void test_D3DXSHEvalSphericalLight(void)
+{
+ float bout[49], expected, gout[49], rout[49];
+ unsigned int j, l, order;
+ D3DXVECTOR3 dir;
+ HRESULT hr;
+ BOOL equal;
+
+ static const float table[] =
+ {
+ /* Red colour. */
+ 3.01317163e+00f, -9.77240128e-01f, 2.24765220e+00f, -8.95803434e-01f, 3.25255224e-35f, -8.16094904e-35f,
+ 8.95199460e-35f, -7.48086982e-35f, -2.83366352e-36f, 6.29281376e-02f, -4.27374053e-01f, 6.19212543e-01f,
+ -3.04508915e-01f, 5.67611487e-01f, 3.72333533e-02f, -8.19167317e-02f, 1.25205729e-36f, 2.11515287e-35f,
+ -8.85884025e-35f, 8.22100105e-35f, -1.41290744e-37f, 7.53591749e-35f, 7.71793061e-36f, -2.75340121e-35f,
+ 7.13117824e-36f, 1.24992691e-02f, -1.37487792e-02f, -1.48109290e-01f, 4.34345843e-01f, -2.45986100e-01f,
+ -1.51757946e-01f, -2.25487254e-01f, -3.78407442e-02f, 1.92801335e-01f, -7.83071154e-02f, 7.97894137e-03f,
+
+ 4.02519645e-01f, -2.43653315e-01f, 5.60402600e-01f, -2.23348868e-01f, 1.62046875e-01f, -4.06590330e-01f,
+ 4.46001368e-01f, -3.72707796e-01f, -1.41177231e-02f, -4.31995198e-02f, 2.93387896e-01f, -4.25083048e-01f,
+ 2.09042241e-01f, -3.89659453e-01f, -2.55603144e-02f, 5.62349945e-02f, -4.68822967e-03f, -7.92002290e-02f,
+ 3.31712278e-01f, -3.07828893e-01f, 5.29052032e-04f, -2.82176480e-01f, -2.88991817e-02f, 1.03098934e-01f,
+ -2.67021338e-02f, 7.24339502e-03f, -7.96749298e-03f, -8.58301461e-02f, 2.51705799e-01f, -1.42550295e-01f,
+ -8.79445626e-02f, -1.30671101e-01f, -2.19289189e-02f, 1.11729432e-01f, -4.53794030e-02f, 4.62384030e-03f,
+
+ 1.95445306e+00f, -8.56593659e-01f, 1.97016533e+00f, -7.85210840e-01f, 2.31033385e-01f, -5.79683751e-01f,
+ 6.35872835e-01f, -5.31376762e-01f, -2.01279127e-02f, 2.11104646e-02f, -1.43370917e-01f, 2.07726860e-01f,
+ -1.02153423e-01f, 1.90416285e-01f, 1.24906507e-02f, -2.74805568e-02f, 6.33162467e-03f, 1.06962790e-01f,
+ -4.47989495e-01f, 4.15734115e-01f, -7.14504011e-04f, 3.81089599e-01f, 3.90293960e-02f, -1.39238860e-01f,
+ 3.60622028e-02f, -4.47359268e-03f, 4.92080277e-03f, 5.30095505e-02f, -1.55456001e-01f, 8.80404774e-02f,
+ 5.43154350e-02f, 8.07037695e-02f, 1.35435180e-02f, -6.90052063e-02f, 2.80267699e-02f, -2.85572968e-03f,
+ /* Green colour. */
+ 4.60837984e+00f, -1.49460245e+00f, 3.43758549e+00f, -1.37005222e+00f, 4.97449134e-35f, -1.24814507e-34f,
+ 1.36912850e-34f, -1.14413296e-34f, -4.33383805e-36f, 9.62430278e-02f, -6.53630863e-01f, 9.47030887e-01f,
+ -4.65719486e-01f, 8.68111630e-01f, 5.69451249e-02f, -1.25284405e-01f, 1.91491103e-36f, 3.23493947e-35f,
+ -1.35488136e-34f, 1.25732949e-34f, -2.16091711e-37f, 1.15255201e-34f, 1.18038931e-35f, -4.21108392e-35f,
+ 1.09065072e-35f, 1.91165280e-02f, -2.10275433e-02f, -2.26520076e-01f, 6.64293599e-01f, -3.76214011e-01f,
+ -2.32100374e-01f, -3.44862837e-01f, -5.78740756e-02f, 2.94872611e-01f, -1.19763816e-01f, 1.22030860e-02f,
+
+ 6.15618240e-01f, -3.72646222e-01f, 8.57086273e-01f, -3.41592364e-01f, 2.47836381e-01f, -6.21843994e-01f,
+ 6.82119695e-01f, -5.70023651e-01f, -2.15918104e-02f, -6.60698496e-02f, 4.48710870e-01f, -6.50126972e-01f,
+ 3.19711642e-01f, -5.95949713e-01f, -3.90922430e-02f, 8.60064566e-02f, -7.17023314e-03f, -1.21129754e-01f,
+ 5.07324627e-01f, -4.70797100e-01f, 8.09138350e-04f, -4.31564000e-01f, -4.41987457e-02f, 1.57680712e-01f,
+ -4.08385549e-02f, 1.10781328e-02f, -1.21855767e-02f, -1.31269627e-01f, 3.84961785e-01f, -2.18018084e-01f,
+ -1.34503440e-01f, -1.99849906e-01f, -3.35383443e-02f, 1.70880296e-01f, -6.94037884e-02f, 7.07175529e-03f,
+
+ 2.98916331e+00f, -1.31008433e+00f, 3.01319384e+00f, -1.20091062e+00f, 3.53345154e-01f, -8.86575090e-01f,
+ 9.72511332e-01f, -8.12693818e-01f, -3.07838645e-02f, 3.22865908e-02f, -2.19273153e-01f, 3.17699883e-01f,
+ -1.56234637e-01f, 2.91224888e-01f, 1.91033469e-02f, -4.20290842e-02f, 9.68366064e-03f, 1.63590138e-01f,
+ -6.85160360e-01f, 6.35828606e-01f, -1.09277077e-03f, 5.82842878e-01f, 5.96920135e-02f, -2.12953537e-01f,
+ 5.51539537e-02f, -6.84196484e-03f, 7.52593316e-03f, 8.10734249e-02f, -2.37756221e-01f, 1.34650133e-01f,
+ 8.30706600e-02f, 1.23429287e-01f, 2.07136145e-02f, -1.05537368e-01f, 4.28644688e-02f, -4.36758628e-03f,
+ /* Blue colour. */
+ 6.20358848e+00f, -2.01196491e+00f, 4.62751910e+00f, -1.84430114e+00f, 6.69643089e-35f, -1.68019534e-34f,
+ 1.84305766e-34f, -1.54017904e-34f, -5.83401297e-36f, 1.29557927e-01f, -8.79887732e-01f, 1.27484932e+00f,
+ -6.26930101e-01f, 1.16861185e+00f, 7.66569017e-02f, -1.68652090e-01f, 2.57776494e-36f, 4.35472637e-35f,
+ -1.82387882e-34f, 1.69255899e-34f, -2.90892699e-37f, 1.55151238e-34f, 1.58898567e-35f, -5.66876703e-35f,
+ 1.46818371e-35f, 2.57337886e-02f, -2.83063093e-02f, -3.04930882e-01f, 8.94241416e-01f, -5.06441957e-01f,
+ -3.12442822e-01f, -4.64238452e-01f, -7.79074123e-02f, 3.96943914e-01f, -1.61220527e-01f, 1.64272318e-02f,
+
+ 8.28716892e-01f, -5.01639163e-01f, 1.15377003e+00f, -4.59835891e-01f, 3.33625909e-01f, -8.37097715e-01f,
+ 9.18238085e-01f, -7.67339558e-01f, -2.90658997e-02f, -8.89401854e-02f, 6.04033886e-01f, -8.75170956e-01f,
+ 4.30381072e-01f, -8.02240028e-01f, -5.26241753e-02f, 1.15777927e-01f, -9.65223728e-03f, -1.63059290e-01f,
+ 6.82937023e-01f, -6.33765350e-01f, 1.08922474e-03f, -5.80951560e-01f, -5.94983136e-02f, 2.12262505e-01f,
+ -5.49749798e-02f, 1.49128717e-02f, -1.64036616e-02f, -1.76709119e-01f, 5.18217807e-01f, -2.93485893e-01f,
+ -1.81062330e-01f, -2.69028730e-01f, -4.51477729e-02f, 2.30031176e-01f, -9.34281801e-02f, 9.51967094e-03f,
+
+ 4.02387383e+00f, -1.76357513e+00f, 4.05622263e+00f, -1.61661051e+00f, 4.75656955e-01f, -1.19346651e+00f,
+ 1.30914992e+00f, -1.09401095e+00f, -4.14398191e-02f, 4.34627200e-02f, -2.95175409e-01f, 4.27672935e-01f,
+ -2.10315865e-01f, 3.92033517e-01f, 2.57160448e-02f, -5.65776154e-02f, 1.30356975e-02f, 2.20217502e-01f,
+ -9.22331288e-01f, 8.55923154e-01f, -1.47103763e-03f, 7.84596211e-01f, 8.03546365e-02f, -2.86668233e-01f,
+ 7.42457096e-02f, -9.21033762e-03f, 1.01310642e-02f, 1.09137307e-01f, -3.20056463e-01f, 1.81259801e-01f,
+ 1.11825893e-01f, 1.66154815e-01f, 2.78837128e-02f, -1.42069538e-01f, 5.77021717e-02f, -5.87944329e-03f,
+ };
+ const struct
+ {
+ float *red_received, *green_received, *blue_received;
+ const float *red_expected, *green_expected, *blue_expected;
+ float radius, roffset, goffset, boffset;
+ }
+ test[] =
+ {
+ { rout, gout, bout, table, &table[108], &table[216], 17.4f, 1.01f, 1.02f, 1.03f, },
+ { rout, gout, bout, &table[36], &table[144], &table[252], 1.6f, 1.01f, 1.02f, 1.03f, },
+ { rout, gout, bout, &table[72], &table[180], &table[288], -3.0f, 1.01f, 1.02f, 1.03f, },
+ { rout, rout, rout, &table[216], &table[216], &table[216], 17.4f, 1.03f, 1.03f, 1.03f, },
+ { rout, rout, bout, &table[108], &table[108], &table[216], 17.4, 1.02f, 1.02f, 1.03f, },
+ { rout, gout, gout, table, &table[216], &table[216], 17.4f, 1.01f, 1.03f, 1.03f, },
+ { rout, gout, rout, &table[216], &table[108], &table[216], 17.4f, 1.03f, 1.02f, 1.03f, },
+ /* D3DXSHEvalSphericalLight accepts NULL green or blue colour. */
+ { rout, NULL, bout, table, NULL, &table[216], 17.4f, 1.01f, 0.0f, 1.03f, },
+ { rout, gout, NULL, table, &table[108], NULL, 17.4f, 1.01f, 1.02f, 0.0f, },
+ { rout, NULL, NULL, table, NULL, NULL, 17.4f, 1.01f, 0.0f, 0.0f, },
+ };
+
+ dir.x = 1.1f; dir.y = 1.2f; dir.z = 2.76f;
+
+ for (l = 0; l < ARRAY_SIZE(test); ++l)
+ {
+ for (order = D3DXSH_MINORDER; order <= D3DXSH_MAXORDER; order++)
+ {
+ for (j = 0; j < 49; j++)
+ {
+ test[l].red_received[j] = 1.01f + j;
+ if (test[l].green_received)
+ test[l].green_received[j] = 1.02f + j;
+ if (test[l].blue_received)
+ test[l].blue_received[j] = 1.03f + j;
+ }
+
+ hr = D3DXSHEvalSphericalLight(order, &dir, test[l].radius, 1.7f, 2.6f, 3.5f, test[l].red_received, test[l].green_received, test[l].blue_received);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+
+ for (j = 0; j < 49; j++)
+ {
+ if (j >= order * order)
+ expected = j + test[l].roffset;
+ else
+ expected = test[l].red_expected[j];
+ equal = compare_float(expected, test[l].red_received[j], 4096);
+ ok(equal || (fabs(expected) < 1.0e-6f && fabs(test[l].red_received[j]) < 1.0e-6f),
+ "Red: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].red_received[j]);
+
+ if (test[l].green_received)
+ {
+ if (j >= order * order)
+ expected = j + test[l].goffset;
+ else
+ expected = test[l].green_expected[j];
+ equal = compare_float(expected, test[l].green_received[j], 4096);
+ ok(equal || (fabs(expected) < 1.0e-6f && fabs(test[l].green_received[j]) < 1.0e-6f),
+ "Green: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].green_received[j]);
+ }
+
+ if (test[l].blue_received)
+ {
+ if (j >= order * order)
+ expected = j + test[l].boffset;
+ else
+ expected = test[l].blue_expected[j];
+ equal = compare_float(expected, test[l].blue_received[j], 4096);
+ ok(equal || (fabs(expected) < 1.0e-6f && fabs(test[l].blue_received[j]) < 1.0e-6f),
+ "Blue: case %u, order %u: expected[%u] = %.8e, received %.8e.\n",
+ l, order, j, expected, test[l].blue_received[j]);
+ }
+ }
+ }
+ }
+
+ /* D3DXSHEvalSphericalLight accepts order < D3DXSH_MINORDER or order > D3DXSH_MAXORDER. But tests in native windows show that the colour outputs are not set */
+ hr = D3DXSHEvalSphericalLight(7, &dir, 17.4f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalSphericalLight(0, &dir, 17.4f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+ hr = D3DXSHEvalSphericalLight(1, &dir, 17.4f, 1.0f, 2.0f, 3.0f, rout, gout, bout);
+ ok(hr == D3D_OK, "Expected %#x, got %#x\n", D3D_OK, hr);
+}
+
+static void test_D3DXSHMultiply2(void)
+{
+ float a[20], b[20], c[20];
+ unsigned int i;
+ BOOL equal;
+
+ /* D3DXSHMultiply2() only modifies the first 4 elements of the array. */
+ static const float expected[20] =
+ {
+ 3.41859412f, 1.69821072f, 1.70385253f, 1.70949447f, 4.0f, 5.0f, 6.0f,
+ 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f,
+ 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ a[i] = 1.0f + i / 100.0f;
+ b[i] = 3.0f - i / 100.0f;
+ c[i] = i;
+ }
+
+ D3DXSHMultiply2(c, a, b);
+ for (i = 0; i < ARRAY_SIZE(expected); ++i)
+ {
+ equal = compare_float(c[i], expected[i], 2);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected[i], c[i]);
+ }
+}
+
+static void test_D3DXSHMultiply3(void)
+{
+ float a[20], b[20], c[20];
+ unsigned int i;
+ BOOL equal;
+
+ /* D3DXSHMultiply3() only modifies the first 9 elements of the array. */
+ static const float expected[20] =
+ {
+ 7.81391382e+00f, 2.25605774e+00f, 5.94839954e+00f, 4.97089481e+00f, 2.89985824e+00f, 3.59894633e+00f,
+ 1.72657156e+00f, 5.57353783e+00f, 6.22063160e-01f, 9.00000000e+00f, 1.00000000e+01f, 1.10000000e+01f,
+ 1.20000000e+01f, 1.30000000e+01f, 1.40000000e+01f, 1.50000000e+01f, 1.60000000e+01f, 1.70000000e+01f,
+ 1.80000000e+01f, 1.90000000e+01f,
+ };
+ static const float expected_aliased[20] =
+ {
+ 4.54092499e+02f, 2.12640405e+00f, 5.57040071e+00f, 1.53303785e+01f, 2.27960873e+01f, 4.36041260e+01f,
+ 4.27384138e+00f, 1.75772034e+02f, 2.37672729e+02f, 1.09000003e+00f, 1.10000002e+00f, 1.11000001e+00f,
+ 1.12000000e+00f, 1.13000000e+00f, 1.13999999e+00f, 1.14999998e+00f, 1.15999997e+00f, 1.16999996e+00f,
+ 1.17999995e+00f, 1.19000006e+00f,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ a[i] = 1.0f + i / 100.0f;
+ b[i] = 3.0f - i / 100.0f;
+ c[i] = i;
+ }
+
+ D3DXSHMultiply3(c, a, b);
+ for (i = 0; i < ARRAY_SIZE(expected); ++i)
+ {
+ equal = compare_float(c[i], expected[i], 4);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected[i], c[i]);
+ }
+
+ memcpy(c, a, sizeof(c));
+ D3DXSHMultiply3(c, c, b);
+ for (i = 0; i < ARRAY_SIZE(expected_aliased); ++i)
+ {
+ equal = compare_float(c[i], expected_aliased[i], 32);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected_aliased[i], c[i]);
+ }
+}
+
+static void test_D3DXSHMultiply4(void)
+{
+ float a[20], b[20], c[20];
+ unsigned int i;
+ BOOL equal;
+
+ /* D3DXSHMultiply4() only modifies the first 16 elements of the array. */
+ static const float expected[] =
+ {
+ /* c, a, b */
+ 1.41825991e+01f, 2.61570334e+00f, 1.28286009e+01f, 9.82059574e+00f, 3.03969646e+00f, 4.53044176e+00f,
+ 5.82058382e+00f, 1.22498465e+01f, 2.19434643e+00f, 3.90015244e+00f, 5.41660881e+00f, 5.60181284e+00f,
+ 9.59981740e-01f, 7.03754997e+00f, 3.62523031e+00f, 4.63601470e-01f, 1.60000000e+01f, 1.70000000e+01f,
+ 1.80000000e+01f, 1.90000000e+01f,
+ /* c, c, b */
+ -2.11441266e+05f, -2.52915771e+03f, -1.00233936e+04f, -4.41277191e+02f, -1.63994385e+02f, -5.26305115e+02f,
+ 2.96361875e+04f, -3.93183081e+03f, -1.35771113e+04f, -3.97897388e+03f, -1.03303418e+04f, -1.37797871e+04f,
+ -1.66851094e+04f, -4.49813750e+04f, -7.32697422e+04f, -9.52373359e+04f, 1.60000000e+01f, 1.70000000e+01f,
+ 1.80000000e+01f, 1.90000000e+01f,
+ /* c, c, c */
+ 2.36682415e-01f, -7.17648506e-01f, -1.80499524e-01f, -7.71235973e-02f, 1.44830629e-01f, 5.73285699e-01f,
+ -3.37959230e-01f, 5.56938872e-02f, -4.42100227e-01f, 1.47701755e-01f, -5.51566519e-02f, 8.43374059e-02f,
+ 1.79876596e-01f, 9.09878965e-03f, 2.32199892e-01f, 7.41420984e-02f, 1.60000002e+00f, 1.70000005e+00f,
+ 1.80000007e+00f, 1.89999998e+00f,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ a[i] = 1.0f + i / 100.0f;
+ b[i] = 3.0f - i / 100.0f;
+ c[i] = i;
+ }
+
+ D3DXSHMultiply4(c, a, b);
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
+ {
+ equal = compare_float(c[i], expected[i], 16);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected[i], c[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(b); ++i)
+ {
+ b[i] = 3.0f - i / 100.0f;
+ c[i] = i;
+ }
+
+ D3DXSHMultiply4(c, c, b);
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
+ {
+ equal = compare_float(c[i], expected[20 + i], 32);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected[20 + i], c[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
+ c[i] = 0.1f * i;
+
+ D3DXSHMultiply4(c, c, c);
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
+ {
+ equal = compare_float(c[i], expected[40 + i], 8);
+ ok(equal, "Expected[%u] = %.8e, received = %.8e.\n", i, expected[40 + i], c[i]);
+ }
+}
+
+static void test_D3DXSHRotate(void)
+{
+ float expected, in[49], out[49], *out_temp, *received_ptr;
+ unsigned int i, j, l, order;
+ D3DXMATRIX m[4];
+ BOOL equal;
+
+ static const float table[]=
+ {
+ /* Rotation around the x-axis, π/2. */
+ 1.00999999e+00f, -3.00999999e+00f, 2.00999975e+00f, 4.01000023e+00f, -8.01000023e+00f, -6.00999928e+00f,
+ -1.13078899e+01f, 5.00999975e+00f, -1.56583869e+00f, 1.09359801e+00f, -1.10099983e+01f, 1.98334141e+01f,
+ -1.52681913e+01f, -1.90041180e+01f, -3.36488891e+00f, -9.56262684e+00f, 1.20996542e+01f, -2.72131383e-01f,
+ 3.02410126e+01f, 2.69199905e+01f, 3.92368774e+01f, -2.26324463e+01f, 6.70738792e+00f, -1.17682819e+01f,
+ 3.44367194e+00f, -6.07445812e+00f, 1.16183939e+01f, 1.52756083e+00f, 3.78963356e+01f, -5.69012184e+01f,
+ 4.74228935e+01f, 5.03915329e+01f, 1.06181908e+01f, 2.55010109e+01f, 4.92456071e-02f, 1.69833069e+01f,
+
+ 1.00999999e+00f, -3.00999999e+00f, -3.01000023e+00f, 4.01000023e+00f, -8.01000023e+00f, -6.00999928e+00f,
+ -1.13078890e+01f, -8.01000023e+00f, 1.42979193e+01f,
+ /* Rotation around the x-axis, -Ï€/2. */
+ 1.00999999e+00f, 3.00999999e+00f, -2.01000023e+00f, 4.01000023e+00f, 8.01000023e+00f, -6.01000118e+00f,
+ -1.13078880e+01f, -5.01000071e+00f, -1.56583774e+00f, -1.09359753e+00f, -1.10100021e+01f, -1.98334103e+01f,
+ 1.52681961e+01f, -1.90041142e+01f, 3.36489248e+00f, -9.56262398e+00f, -1.20996523e+01f, -2.72129118e-01f,
+ -3.02410049e+01f, 2.69200020e+01f, 3.92368736e+01f, 2.26324520e+01f, 6.70738268e+00f, 1.17682877e+01f,
+ 3.44367099e+00f, 6.07445717e+00f, 1.16183996e+01f, -1.52756333e+00f, 3.78963509e+01f, 5.69011993e+01f,
+ -4.74229126e+01f, 5.03915253e+01f, -1.06182041e+01f, 2.55009995e+01f, -4.92481887e-02f, 1.69833050e+01f,
+
+ 1.00999999e+00f, 3.00999999e+00f, -3.01000023e+00f, 4.01000023e+00f, 8.01000023e+00f, -6.01000118e+00f,
+ -1.13078899e+01f, -8.01000023e+00f, 1.42979193e+01f,
+ /* Yaw π/3, pitch π/4, roll π/5. */
+ 1.00999999e+00f, 4.94489908e+00f, 1.44230127e+00f, 1.62728095e+00f, 2.19220325e-01f, 1.05408239e+01f,
+ -9.13690281e+00f, 2.76374960e+00f, -7.30904531e+00f, -5.87572050e+00f, 5.30312395e+00f, -8.68215370e+00f,
+ -2.56833839e+01f, 1.68027866e+00f, -1.88083878e+01f, 7.65365601e+00f, 1.69391327e+01f, -1.73280182e+01f,
+ 1.46297951e+01f, -5.44671021e+01f, -1.22310352e+01f, -4.08985710e+00f, -9.44422245e+00f, 3.05603528e+00f,
+ 1.79257303e-01f, -1.00418749e+01f, 2.30900917e+01f, -2.31887093e+01f, 1.17270985e+01f, -6.51830902e+01f,
+ 4.86715775e+01f, -1.50732088e+01f, 3.87931709e+01f, -2.60395355e+01f, 6.19276857e+00f, -1.76722469e+01f,
+
+ 1.00999999e+00f, 4.94489908e+00f, -8.91142070e-01f, 4.60769463e+00f, 2.19218358e-01f, 1.07733250e+01f,
+ -8.20476913e+00f, 1.35638294e+01f, -1.20077667e+01f,
+ /* Rotation around the z-axis, π/6. */
+ 1.00999999e+00f, 3.74571109e+00f, 3.00999999e+00f, 2.46776199e+00f, 1.03078890e+01f, 9.20981312e+00f,
+ 7.01000023e+00f, 3.93186355e+00f, 1.66212186e-01f, 1.60099983e+01f, 1.85040417e+01f, 1.74059658e+01f,
+ 1.30100002e+01f, 6.12801647e+00f, -2.02994061e+00f, -1.00100012e+01f, 1.31542921e+01f, 2.40099964e+01f,
+ 2.94322453e+01f, 2.83341675e+01f, 2.10100021e+01f, 9.05622101e+00f, -4.95814323e+00f, -1.80100002e+01f,
+ -2.72360935e+01f, -4.52033186e+00f, 1.68145428e+01f, 3.40099945e+01f, 4.30924950e+01f, 4.19944229e+01f,
+ 3.10100002e+01f, 1.27164707e+01f, -8.61839962e+00f, -2.80100021e+01f, -4.08963470e+01f, -4.41905708e+01f,
+
+ 1.00999999e+00f, 3.74571109e+00f, 3.00999999e+00f, 1.59990644e+00f, 1.03078890e+01f, 9.20981312e+00f,
+ 7.01000023e+00f, 2.33195710e+00f, -4.42189360e+00f,
+ };
+
+ D3DXMatrixRotationX(&m[0], -D3DX_PI / 2.0f);
+ D3DXMatrixRotationX(&m[1], D3DX_PI / 2.0f);
+ D3DXMatrixRotationYawPitchRoll(&m[2], D3DX_PI / 3.0f, D3DX_PI / 4.0f, D3DX_PI / 5.0f);
+ D3DXMatrixRotationZ(&m[3], D3DX_PI / 6.0f);
+
+ for (l = 0; l < 2; l++)
+ {
+ if (l == 0)
+ out_temp = out;
+ else
+ out_temp = in;
+
+ for (j = 0; j < ARRAY_SIZE(m); ++j)
+ {
+ for (order = 0; order <= D3DXSH_MAXORDER; order++)
+ {
+ for (i = 0; i < ARRAY_SIZE(out); ++i)
+ {
+ out[i] = ( i + 1.0f ) * ( i + 1.0f );
+ in[i] = i + 1.01f;
+ }
+
+ received_ptr = D3DXSHRotate(out_temp, order, &m[j], in);
+ ok(received_ptr == out_temp, "Order %u, expected %p, received %p.\n",
+ order, out, received_ptr);
+
+ for (i = 0; i < ARRAY_SIZE(out); ++i)
+ {
+ if ((i > 0) && ((i >= order * order) || (order > D3DXSH_MAXORDER)))
+ {
+ if (l == 0)
+ expected = ( i + 1.0f ) * ( i + 1.0f );
+ else
+ expected = i + 1.01f;
+ }
+ else if ((l == 0) || (order > 3))
+ expected = table[45 * j + i];
+ else
+ expected = table[45 * j + 36 +i];
+ equal = compare_float(out_temp[i], expected, 4096);
+ ok(equal, "Order %u index %u, expected %.8e, received %.8e.\n",
+ order, i, expected, out_temp[i]);
+ }
+ }
+ }
+ }
+}
+
+static void test_D3DXSHRotateZ(void)
+{
+ float expected, in[49], out[49], *out_temp, *received_ptr;
+ unsigned int end, i, j, l, order, square;
+ BOOL equal;
+
+ static const float angle[] = {D3DX_PI / 3.0f, -D3DX_PI / 3.0f, 4.0f * D3DX_PI / 3.0f};
+ static const float table[] =
+ {
+ /* Angle π/3. */
+ 1.00999999e+00f, 4.47776222e+00f, 3.00999999e+00f, 2.64288902e-01f, 5.29788828e+00f, 9.94186401e+00f,
+ 7.01000023e+00f, -1.19981313e+00f, -8.84378910e+00f, -1.00100021e+01f, 7.49403954e+00f, 1.81380157e+01f,
+ 1.30100002e+01f, -3.39596605e+00f, -1.70399418e+01f, -1.60099983e+01f, -3.01642971e+01f, -1.80100040e+01f,
+ 1.04222422e+01f, 2.90662193e+01f, 2.10100002e+01f, -6.32417059e+00f, -2.79681454e+01f, -2.40099983e+01f,
+ 2.22609901e+00f, -1.81805649e+01f, -4.38245506e+01f, -2.80100040e+01f, 1.40824928e+01f, 4.27264709e+01f,
+ 3.10100002e+01f, -9.98442554e+00f, -4.16283989e+01f, -3.40099945e+01f, 5.88635778e+00f, 4.05303307e+01f,
+
+ 1.00999999e+00f, 4.47776222e+00f, 0.00000000e+00f, -5.81678391e+00f, 5.29788828e+00f, 6.93686390e+00f,
+ 0.00000000e+00f, -9.01125050e+00f, -2.29405236e+00f, -1.00100021e+01f, 1.29990416e+01f, 1.21330166e+01f,
+ 0.00000000e+00f, -1.57612505e+01f, -5.62874842e+00f, 0.00000000e+00f, -3.01642971e+01f, -3.29017075e-06f,
+ 1.99272442e+01f, 1.90612202e+01f, 0.00000000e+00f, -2.47612514e+01f, -8.62874794e+00f, 0.00000000e+00f,
+ -1.30615301e+01f, -1.81805649e+01f, -3.03195534e+01f, -4.66050415e-06f, 2.85874958e+01f, 2.77214737e+01f,
+ 0.00000000e+00f, -3.60112534e+01f, -1.23787460e+01f, 0.00000000e+00f, -1.31287584e+01f, -2.36172504e+01f,
+
+ 1.00999999e+00f, 3.97776222e+00f, 3.97776222e+00f, 1.11419535e+00f, 7.24579096e+00f, 1.05597591e+01f,
+ 1.05597591e+01f, -9.95159924e-01f, -4.67341393e-01f, 4.67339337e-01f, 1.27653713e+01f, 1.85157013e+01f,
+ 1.85157013e+01f, -1.79728663e+00f, 4.93915796e-01f, -4.93915856e-01f, -2.14123421e+01f, 2.14123383e+01f,
+ 9.22107220e+00f, 2.36717567e+01f, 2.36717567e+01f, 3.85019469e+00f, -2.04687271e+01f, 2.04687233e+01f,
+ -1.06621027e+01f, -3.65166283e+01f, -1.20612450e+01f, 1.20612402e+01f, 2.25568752e+01f, 3.89999084e+01f,
+ 3.89999084e+01f, -3.48751247e-02f, -1.04279022e+01f, 1.04279003e+01f, -3.68382835e+01f, -2.76528034e+01f,
+ /* Angle -Ï€/3. */
+ 1.00999999e+00f, -2.46776247e+00f, 3.00999999e+00f, 3.74571109e+00f, -1.03078899e+01f, -3.93186426e+00f,
+ 7.01000023e+00f, 9.20981312e+00f, -1.66213632e-01f, -1.00099983e+01f, -1.85040436e+01f, -6.12801695e+00f,
+ 1.30100002e+01f, 1.74059658e+01f, 2.02993774e+00f, -1.60100021e+01f, 1.31543026e+01f, -1.80099964e+01f,
+ -2.94322472e+01f, -9.05622101e+00f, 2.10100002e+01f, 2.83341694e+01f, 4.95813942e+00f, -2.40100021e+01f,
+ -2.72360916e+01f, 4.41905823e+01f, 1.68145580e+01f, -2.80099964e+01f, -4.30924988e+01f, -1.27164736e+01f,
+ 3.10100002e+01f, 4.19944229e+01f, 8.61839294e+00f, -3.40100021e+01f, -4.08963470e+01f, -4.52030993e+00f,
+
+ 1.00999999e+00f, -2.46776247e+00f, 0.00000000e+00f, -3.20571756e+00f, -1.03078899e+01f, -6.93686390e+00f,
+ 0.00000000e+00f, -9.01125050e+00f, -4.46344614e+00f, -1.00099983e+01f, -1.29990416e+01f, -1.21330166e+01f,
+ 0.00000000e+00f, -1.57612505e+01f, -5.62874842e+00f, 0.00000000e+00f, 1.31543026e+01f, 3.29017075e-06f,
+ -1.99272442e+01f, -1.90612202e+01f, 0.00000000e+00f, -2.47612514e+01f, -8.62874794e+00f, 0.00000000e+00f,
+ -5.69598293e+00f, 4.41905823e+01f, 3.03195534e+01f, 4.66050415e-06f, -2.85874958e+01f, -2.77214737e+01f,
+ 0.00000000e+00f, -3.60112534e+01f, -1.23787460e+01f, 0.00000000e+00f, -1.31287584e+01f, -5.74052582e+01f,
+
+ 1.00999999e+00f, -2.96776223e+00f, -2.96776223e+00f, -6.09195352e-01f, -7.49829102e+00f, -1.06860094e+01f,
+ -1.06860094e+01f, -1.18367157e+01f, 5.39078045e+00f, -5.39077854e+00f, -1.03036509e+01f, -1.72848415e+01f,
+ -1.72848415e+01f, -1.75656433e+01f, 4.11427259e+00f, -4.11427307e+00f, 2.37164364e+01f, -2.37164326e+01f,
+ -8.06902504e+00f, -2.30957317e+01f, -2.30957317e+01f, -1.85358467e+01f, -1.12711067e+01f, 1.12711039e+01f,
+ -2.07248449e+00f, 3.01493301e+01f, 1.52448931e+01f, -1.52448883e+01f, -2.09650497e+01f, -3.82039986e+01f,
+ -3.82039986e+01f, -3.72582664e+01f, 5.42667723e+00f, -5.42667913e+00f, -2.33967514e+01f, -9.90355873e+00f,
+ /* Angle 4Ï€/3. */
+ 1.00999999e+00f, -4.47776222e+00f, 3.00999999e+00f, -2.64288664e-01f, 5.29788685e+00f, -9.94186401e+00f,
+ 7.01000023e+00f, 1.19981360e+00f, -8.84378815e+00f, 1.00100040e+01f, 7.49403811e+00f, -1.81380157e+01f,
+ 1.30100002e+01f, 3.39596677e+00f, -1.70399399e+01f, 1.60099964e+01f, -3.01642933e+01f, 1.80100060e+01f,
+ 1.04222393e+01f, -2.90662193e+01f, 2.10100002e+01f, 6.32417202e+00f, -2.79681435e+01f, 2.40099926e+01f,
+ 2.22610497e+00f, 1.81805515e+01f, -4.38245430e+01f, 2.80100079e+01f, 1.40824890e+01f, -4.27264709e+01f,
+ 3.10100002e+01f, 9.98442745e+00f, -4.16283989e+01f, 3.40099869e+01f, 5.88636589e+00f, -4.05303268e+01f,
+
+ 1.00999999e+00f, -4.47776222e+00f, 0.00000000e+00f, -1.93892837e+00f, 5.29788685e+00f, -6.93686390e+00f,
+ 0.00000000e+00f, -3.00375080e+00f, -2.29405141e+00f, 1.00100040e+01f, 1.29990396e+01f, -1.21330166e+01f,
+ 0.00000000e+00f, -5.25375128e+00f, -5.62874699e+00f, -5.68378528e-06f, -3.01642933e+01f, 7.00829787e-06f,
+ 1.99272423e+01f, -1.90612202e+01f, 0.00000000e+00f, -8.25375271e+00f, -8.62874603e+00f, -4.09131496e-12f,
+ -1.30615349e+01f, 1.81805515e+01f, -3.03195534e+01f, 9.92720470e-06f, 2.85874920e+01f, -2.77214737e+01f,
+ 0.00000000e+00f, -1.20037527e+01f, -1.23787422e+01f, -5.79531909e-12f, -1.31287651e+01f, -7.87240028e+00f,
+
+ 1.00999999e+00f, -3.97776222e+00f, -3.97776222e+00f, 2.86356640e+00f, 6.37110424e+00f, -1.01224155e+01f,
+ -1.01224155e+01f, 1.05787458e+01f, -7.76929522e+00f, -7.76928997e+00f, 1.68836861e+01f, -2.05748577e+01f,
+ -2.05748577e+01f, 2.49091301e+01f, -5.72616625e+00f, -5.72616386e+00f, -1.87962208e+01f, -1.87962112e+01f,
+ 2.93253498e+01f, -3.37238922e+01f, -3.37238922e+01f, 4.22584419e+01f, -4.85123205e+00f, -4.85122633e+00f,
+ -2.53339314e+00f, 3.24522591e+01f, -4.65456696e+01f, -4.65456543e+01f, 5.18603249e+01f, -5.36516304e+01f,
+ -5.36516304e+01f, 7.17381744e+01f, 4.44061565e+00f, 4.44062901e+00f, 2.58841743e+01f, -1.07481155e+01f,
+ };
+
+ for (l = 0; l < 3; l++)
+ {
+ if (l == 0)
+ out_temp = out;
+ else
+ out_temp = &in[l - 1];
+
+ if (l < 2)
+ end = 49;
+ else
+ end = 48;
+
+ for (j = 0; j < ARRAY_SIZE(angle); ++j)
+ {
+ for (order = 0; order <= D3DXSH_MAXORDER + 1; order++)
+ {
+ for (i = 0; i < ARRAY_SIZE(out); ++i)
+ {
+ out[i] = ( i + 1.0f ) * ( i + 1.0f );
+ in[i] = i + 1.01f;
+ }
+
+ received_ptr = D3DXSHRotateZ(out_temp, order, angle[j], in);
+ ok(received_ptr == out_temp, "angle %f, order %u, expected %p, received %p\n", angle[j], order, out_temp, received_ptr);
+
+ for (i = 0; i < end; i++)
+ {
+ /* order = 0 or order = 1 behaves like order = D3DXSH_MINORDER */
+ square = (order <= D3DXSH_MINORDER) ? D3DXSH_MINORDER * D3DXSH_MINORDER : order * order;
+ if (i >= square || ((order >= D3DXSH_MAXORDER) && (i >= D3DXSH_MAXORDER * D3DXSH_MAXORDER)))
+ if (l > 0)
+ expected = i + l + 0.01f;
+ else
+ expected = ( i + 1.0f ) * ( i + 1.0f );
+ else
+ expected = table[36 * (l + 3 * j) + i];
+ equal = compare_float(expected, out_temp[i], 256);
+ ok(equal || (fabs(expected) < 2.0e-5f && fabs(out_temp[i]) < 2.0e-5f),
+ "angle %.8e, order %u index %u, expected %.8e, received %.8e.\n",
+ angle[j], order, i, expected, out_temp[i]);
+ }
+ }
+ }
+ }
+}
+
+static void test_D3DXSHScale(void)
+{
+ float a[49], b[49], expected, *received_array;
+ unsigned int i, order;
+ BOOL equal;
+
+ for (i = 0; i < ARRAY_SIZE(a); ++i)
+ {
+ a[i] = i;
+ b[i] = i;
+ }
+
+ for (order = 0; order <= D3DXSH_MAXORDER + 1; order++)
+ {
+ received_array = D3DXSHScale(b, order, a, 5.0f);
+ ok(received_array == b, "Expected %p, received %p\n", b, received_array);
+
+ for (i = 0; i < ARRAY_SIZE(b); ++i)
+ {
+ if (i < order * order)
+ expected = 5.0f * a[i];
+ /* D3DXSHScale does not modify the elements of the array after the order * order-th element */
+ else
+ expected = a[i];
+ equal = compare_float(b[i], expected, 0);
+ ok(equal, "order %u, element %u, expected %.8e, received %.8e.\n", order, i, expected, b[i]);
+ }
+ }
+}
+
+START_TEST(math)
+{
+ D3DXColorTest();
+ D3DXFresnelTest();
+ D3DXMatrixTest();
+ D3DXPlaneTest();
+ D3DXQuaternionTest();
+ D3DXVector2Test();
+ D3DXVector3Test();
+ D3DXVector4Test();
+ test_matrix_stack();
+ test_Matrix_AffineTransformation2D();
+ test_Matrix_Decompose();
+ test_Matrix_Transformation2D();
+ test_D3DXVec_Array();
+ test_D3DXFloat_Array();
+ test_D3DXSHAdd();
+ test_D3DXSHDot();
+ test_D3DXSHEvalConeLight();
+ test_D3DXSHEvalDirection();
+ test_D3DXSHEvalDirectionalLight();
+ test_D3DXSHEvalHemisphereLight();
+ test_D3DXSHEvalSphericalLight();
+ test_D3DXSHMultiply2();
+ test_D3DXSHMultiply3();
+ test_D3DXSHMultiply4();
+ test_D3DXSHRotate();
+ test_D3DXSHRotateZ();
+ test_D3DXSHScale();
+}
--- /dev/null
+/*
+ * Copyright 2008 David Adam
+ * Copyright 2008 Luis Busquets
+ * Copyright 2009 Henri Verbeet for CodeWeavers
+ * Copyright 2011 Michael Mc Donnell
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include <stdio.h>
+#include <float.h>
+#include <limits.h>
+#include "wine/test.h"
+#include "d3dx9.h"
+
+#ifndef NAN
+/* From wine/port.h */
+static inline float __port_nan(void)
+{
+ static const unsigned __nan_bytes = 0x7fc00000;
+ return *(const float *)&__nan_bytes;
+}
+#define NAN __port_nan()
+#endif
+
+/* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose
+ * function call traces of ID3DXAllocateHierarchy callbacks. */
+#define TRACECALLBACK if(winetest_debug > 1) trace
+
+#define admitted_error 0.0001f
+
+#define compare_vertex_sizes(type, exp) \
+ got=D3DXGetFVFVertexSize(type); \
+ ok(got==exp, "Expected: %d, Got: %d\n", exp, got);
+
+#define compare_float(got, exp) \
+ do { \
+ float _got = (got); \
+ float _exp = (exp); \
+ ok(_got == _exp, "Expected: %g, Got: %g\n", _exp, _got); \
+ } while (0)
+
+static BOOL compare(FLOAT u, FLOAT v)
+{
+ return (fabs(u-v) < admitted_error);
+}
+
+static BOOL compare_vec3(D3DXVECTOR3 u, D3DXVECTOR3 v)
+{
+ return ( compare(u.x, v.x) && compare(u.y, v.y) && compare(u.z, v.z) );
+}
+
+static BOOL compare_vec4(D3DXVECTOR4 u, D3DXVECTOR4 v)
+{
+ return compare(u.x, v.x) && compare(u.y, v.y) && compare(u.z, v.z) && compare(u.w, v.w);
+}
+
+#define check_floats(got, exp, dim) check_floats_(__LINE__, "", got, exp, dim)
+static void check_floats_(int line, const char *prefix, const float *got, const float *exp, int dim)
+{
+ int i;
+ char exp_buffer[256] = "";
+ char got_buffer[256] = "";
+ char *exp_buffer_ptr = exp_buffer;
+ char *got_buffer_ptr = got_buffer;
+ BOOL equal = TRUE;
+
+ for (i = 0; i < dim; i++) {
+ if (i) {
+ exp_buffer_ptr += sprintf(exp_buffer_ptr, ", ");
+ got_buffer_ptr += sprintf(got_buffer_ptr, ", ");
+ }
+ equal = equal && compare(*exp, *got);
+ exp_buffer_ptr += sprintf(exp_buffer_ptr, "%g", *exp);
+ got_buffer_ptr += sprintf(got_buffer_ptr, "%g", *got);
+ exp++, got++;
+ }
+ ok_(__FILE__,line)(equal, "%sExpected (%s), got (%s)", prefix, exp_buffer, got_buffer);
+}
+
+struct vertex
+{
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+};
+
+typedef WORD face[3];
+
+static BOOL compare_face(face a, face b)
+{
+ return (a[0]==b[0] && a[1] == b[1] && a[2] == b[2]);
+}
+
+struct test_context
+{
+ HWND hwnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+};
+
+/* Initializes a test context struct. Use it to initialize DirectX.
+ *
+ * Returns NULL if an error occurred.
+ */
+static struct test_context *new_test_context(void)
+{
+ HRESULT hr;
+ HWND hwnd = NULL;
+ IDirect3D9 *d3d = NULL;
+ IDirect3DDevice9 *device = NULL;
+ D3DPRESENT_PARAMETERS d3dpp = {0};
+ struct test_context *test_context;
+
+ if (!(hwnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ goto error;
+ }
+
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d)
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ goto error;
+ }
+
+ memset(&d3dpp, 0, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr))
+ {
+ skip("Couldn't create IDirect3DDevice9 object %#x\n", hr);
+ goto error;
+ }
+
+ test_context = HeapAlloc(GetProcessHeap(), 0, sizeof(*test_context));
+ if (!test_context)
+ {
+ skip("Couldn't allocate memory for test_context\n");
+ goto error;
+ }
+ test_context->hwnd = hwnd;
+ test_context->d3d = d3d;
+ test_context->device = device;
+
+ return test_context;
+
+error:
+ if (device)
+ IDirect3DDevice9_Release(device);
+
+ if (d3d)
+ IDirect3D9_Release(d3d);
+
+ if (hwnd)
+ DestroyWindow(hwnd);
+
+ return NULL;
+}
+
+static void free_test_context(struct test_context *test_context)
+{
+ if (!test_context)
+ return;
+
+ if (test_context->device)
+ IDirect3DDevice9_Release(test_context->device);
+
+ if (test_context->d3d)
+ IDirect3D9_Release(test_context->d3d);
+
+ if (test_context->hwnd)
+ DestroyWindow(test_context->hwnd);
+
+ HeapFree(GetProcessHeap(), 0, test_context);
+}
+
+struct mesh
+{
+ DWORD number_of_vertices;
+ struct vertex *vertices;
+
+ DWORD number_of_faces;
+ face *faces;
+
+ DWORD fvf;
+ UINT vertex_size;
+};
+
+static void free_mesh(struct mesh *mesh)
+{
+ HeapFree(GetProcessHeap(), 0, mesh->faces);
+ HeapFree(GetProcessHeap(), 0, mesh->vertices);
+}
+
+static BOOL new_mesh(struct mesh *mesh, DWORD number_of_vertices, DWORD number_of_faces)
+{
+ mesh->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, number_of_vertices * sizeof(*mesh->vertices));
+ if (!mesh->vertices)
+ {
+ return FALSE;
+ }
+ mesh->number_of_vertices = number_of_vertices;
+
+ mesh->faces = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, number_of_faces * sizeof(*mesh->faces));
+ if (!mesh->faces)
+ {
+ HeapFree(GetProcessHeap(), 0, mesh->vertices);
+ return FALSE;
+ }
+ mesh->number_of_faces = number_of_faces;
+
+ return TRUE;
+}
+
+static void compare_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mesh)
+{
+ HRESULT hr;
+ DWORD number_of_vertices, number_of_faces;
+ IDirect3DVertexBuffer9 *vertex_buffer;
+ IDirect3DIndexBuffer9 *index_buffer;
+ D3DVERTEXBUFFER_DESC vertex_buffer_description;
+ D3DINDEXBUFFER_DESC index_buffer_description;
+ struct vertex *vertices;
+ face *faces;
+ int expected, i;
+
+ number_of_vertices = d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh);
+ ok(number_of_vertices == mesh->number_of_vertices, "Test %s, result %u, expected %d\n",
+ name, number_of_vertices, mesh->number_of_vertices);
+
+ number_of_faces = d3dxmesh->lpVtbl->GetNumFaces(d3dxmesh);
+ ok(number_of_faces == mesh->number_of_faces, "Test %s, result %u, expected %d\n",
+ name, number_of_faces, mesh->number_of_faces);
+
+ /* vertex buffer */
+ hr = d3dxmesh->lpVtbl->GetVertexBuffer(d3dxmesh, &vertex_buffer);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't get vertex buffer\n");
+ }
+ else
+ {
+ hr = IDirect3DVertexBuffer9_GetDesc(vertex_buffer, &vertex_buffer_description);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't get vertex buffer description\n");
+ }
+ else
+ {
+ ok(vertex_buffer_description.Format == D3DFMT_VERTEXDATA, "Test %s, result %x, expected %x (D3DFMT_VERTEXDATA)\n",
+ name, vertex_buffer_description.Format, D3DFMT_VERTEXDATA);
+ ok(vertex_buffer_description.Type == D3DRTYPE_VERTEXBUFFER, "Test %s, result %x, expected %x (D3DRTYPE_VERTEXBUFFER)\n",
+ name, vertex_buffer_description.Type, D3DRTYPE_VERTEXBUFFER);
+ ok(vertex_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, vertex_buffer_description.Usage, 0);
+ ok(vertex_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
+ name, vertex_buffer_description.Pool, D3DPOOL_MANAGED);
+ ok(vertex_buffer_description.FVF == mesh->fvf, "Test %s, result %x, expected %x\n",
+ name, vertex_buffer_description.FVF, mesh->fvf);
+ if (mesh->fvf == 0)
+ {
+ expected = number_of_vertices * mesh->vertex_size;
+ }
+ else
+ {
+ expected = number_of_vertices * D3DXGetFVFVertexSize(mesh->fvf);
+ }
+ ok(vertex_buffer_description.Size == expected, "Test %s, result %x, expected %x\n",
+ name, vertex_buffer_description.Size, expected);
+ }
+
+ /* specify offset and size to avoid potential overruns */
+ hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, number_of_vertices * sizeof(D3DXVECTOR3) * 2,
+ (void **)&vertices, D3DLOCK_DISCARD);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't lock vertex buffer\n");
+ }
+ else
+ {
+ for (i = 0; i < number_of_vertices; i++)
+ {
+ ok(compare_vec3(vertices[i].position, mesh->vertices[i].position),
+ "Test %s, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i,
+ vertices[i].position.x, vertices[i].position.y, vertices[i].position.z,
+ mesh->vertices[i].position.x, mesh->vertices[i].position.y, mesh->vertices[i].position.z);
+ ok(compare_vec3(vertices[i].normal, mesh->vertices[i].normal),
+ "Test %s, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i,
+ vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z,
+ mesh->vertices[i].normal.x, mesh->vertices[i].normal.y, mesh->vertices[i].normal.z);
+ }
+
+ IDirect3DVertexBuffer9_Unlock(vertex_buffer);
+ }
+
+ IDirect3DVertexBuffer9_Release(vertex_buffer);
+ }
+
+ /* index buffer */
+ hr = d3dxmesh->lpVtbl->GetIndexBuffer(d3dxmesh, &index_buffer);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (!index_buffer)
+ {
+ skip("Couldn't get index buffer\n");
+ }
+ else
+ {
+ hr = IDirect3DIndexBuffer9_GetDesc(index_buffer, &index_buffer_description);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't get index buffer description\n");
+ }
+ else
+ {
+ ok(index_buffer_description.Format == D3DFMT_INDEX16, "Test %s, result %x, expected %x (D3DFMT_INDEX16)\n",
+ name, index_buffer_description.Format, D3DFMT_INDEX16);
+ ok(index_buffer_description.Type == D3DRTYPE_INDEXBUFFER, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
+ name, index_buffer_description.Type, D3DRTYPE_INDEXBUFFER);
+ ok(index_buffer_description.Usage == 0, "Test %s, result %#x, expected %#x.\n",
+ name, index_buffer_description.Usage, 0);
+ ok(index_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, result %x, expected %x (D3DPOOL_MANAGED)\n",
+ name, index_buffer_description.Pool, D3DPOOL_MANAGED);
+ expected = number_of_faces * sizeof(WORD) * 3;
+ ok(index_buffer_description.Size == expected, "Test %s, result %x, expected %x\n",
+ name, index_buffer_description.Size, expected);
+ }
+
+ /* specify offset and size to avoid potential overruns */
+ hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, number_of_faces * sizeof(WORD) * 3,
+ (void **)&faces, D3DLOCK_DISCARD);
+ ok(hr == D3D_OK, "Test %s, result %x, expected 0 (D3D_OK)\n", name, hr);
+
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't lock index buffer\n");
+ }
+ else
+ {
+ for (i = 0; i < number_of_faces; i++)
+ {
+ ok(compare_face(faces[i], mesh->faces[i]),
+ "Test %s, face %d, result (%u, %u, %u), expected (%u, %u, %u)\n", name, i,
+ faces[i][0], faces[i][1], faces[i][2],
+ mesh->faces[i][0], mesh->faces[i][1], mesh->faces[i][2]);
+ }
+
+ IDirect3DIndexBuffer9_Unlock(index_buffer);
+ }
+
+ IDirect3DIndexBuffer9_Release(index_buffer);
+ }
+}
+
+static void D3DXBoundProbeTest(void)
+{
+ BOOL result;
+ D3DXVECTOR3 bottom_point, center, top_point, raydirection, rayposition;
+ FLOAT radius;
+
+/*____________Test the Box case___________________________*/
+ bottom_point.x = -3.0f; bottom_point.y = -2.0f; bottom_point.z = -1.0f;
+ top_point.x = 7.0f; top_point.y = 8.0f; top_point.z = 9.0f;
+
+ raydirection.x = -4.0f; raydirection.y = -5.0f; raydirection.z = -6.0f;
+ rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 11.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == TRUE, "expected TRUE, received FALSE\n");
+
+ raydirection.x = 4.0f; raydirection.y = 5.0f; raydirection.z = 6.0f;
+ rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 11.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == FALSE, "expected FALSE, received TRUE\n");
+
+ rayposition.x = -4.0f; rayposition.y = 1.0f; rayposition.z = -2.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == TRUE, "expected TRUE, received FALSE\n");
+
+ bottom_point.x = 1.0f; bottom_point.y = 0.0f; bottom_point.z = 0.0f;
+ top_point.x = 1.0f; top_point.y = 0.0f; top_point.z = 0.0f;
+ rayposition.x = 0.0f; rayposition.y = 1.0f; rayposition.z = 0.0f;
+ raydirection.x = 0.0f; raydirection.y = 3.0f; raydirection.z = 0.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == FALSE, "expected FALSE, received TRUE\n");
+
+ bottom_point.x = 1.0f; bottom_point.y = 2.0f; bottom_point.z = 3.0f;
+ top_point.x = 10.0f; top_point.y = 15.0f; top_point.z = 20.0f;
+
+ raydirection.x = 7.0f; raydirection.y = 8.0f; raydirection.z = 9.0f;
+ rayposition.x = 3.0f; rayposition.y = 7.0f; rayposition.z = -6.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == TRUE, "expected TRUE, received FALSE\n");
+
+ bottom_point.x = 0.0f; bottom_point.y = 0.0f; bottom_point.z = 0.0f;
+ top_point.x = 1.0f; top_point.y = 1.0f; top_point.z = 1.0f;
+
+ raydirection.x = 0.0f; raydirection.y = 1.0f; raydirection.z = .0f;
+ rayposition.x = -3.0f; rayposition.y = 0.0f; rayposition.z = 0.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == FALSE, "expected FALSE, received TRUE\n");
+
+ raydirection.x = 1.0f; raydirection.y = 0.0f; raydirection.z = .0f;
+ rayposition.x = -3.0f; rayposition.y = 0.0f; rayposition.z = 0.0f;
+ result = D3DXBoxBoundProbe(&bottom_point, &top_point, &rayposition, &raydirection);
+ ok(result == TRUE, "expected TRUE, received FALSE\n");
+
+/*____________Test the Sphere case________________________*/
+ radius = sqrt(77.0f);
+ center.x = 1.0f; center.y = 2.0f; center.z = 3.0f;
+ raydirection.x = 2.0f; raydirection.y = -4.0f; raydirection.z = 2.0f;
+
+ rayposition.x = 5.0f; rayposition.y = 5.0f; rayposition.z = 9.0f;
+ result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection);
+ ok(result == TRUE, "expected TRUE, received FALSE\n");
+
+ rayposition.x = 45.0f; rayposition.y = -75.0f; rayposition.z = 49.0f;
+ result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection);
+ ok(result == FALSE, "expected FALSE, received TRUE\n");
+
+ rayposition.x = 5.0f; rayposition.y = 11.0f; rayposition.z = 9.0f;
+ result = D3DXSphereBoundProbe(¢er, radius, &rayposition, &raydirection);
+ ok(result == FALSE, "expected FALSE, received TRUE\n");
+}
+
+static void D3DXComputeBoundingBoxTest(void)
+{
+ D3DXVECTOR3 exp_max, exp_min, got_max, got_min, vertex[5];
+ HRESULT hr;
+
+ vertex[0].x = 1.0f; vertex[0].y = 1.0f; vertex[0].z = 1.0f;
+ vertex[1].x = 1.0f; vertex[1].y = 1.0f; vertex[1].z = 1.0f;
+ vertex[2].x = 1.0f; vertex[2].y = 1.0f; vertex[2].z = 1.0f;
+ vertex[3].x = 1.0f; vertex[3].y = 1.0f; vertex[3].z = 1.0f;
+ vertex[4].x = 9.0f; vertex[4].y = 9.0f; vertex[4].z = 9.0f;
+
+ exp_min.x = 1.0f; exp_min.y = 1.0f; exp_min.z = 1.0f;
+ exp_max.x = 9.0f; exp_max.y = 9.0f; exp_max.z = 9.0f;
+
+ hr = D3DXComputeBoundingBox(&vertex[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_min,&got_max);
+
+ ok( hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok( compare_vec3(exp_min,got_min), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min.x,exp_min.y,exp_min.z,got_min.x,got_min.y,got_min.z);
+ ok( compare_vec3(exp_max,got_max), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max.x,exp_max.y,exp_max.z,got_max.x,got_max.y,got_max.z);
+
+/*________________________*/
+
+ vertex[0].x = 2.0f; vertex[0].y = 5.9f; vertex[0].z = -1.2f;
+ vertex[1].x = -1.87f; vertex[1].y = 7.9f; vertex[1].z = 7.4f;
+ vertex[2].x = 7.43f; vertex[2].y = -0.9f; vertex[2].z = 11.9f;
+ vertex[3].x = -6.92f; vertex[3].y = 6.3f; vertex[3].z = -3.8f;
+ vertex[4].x = 11.4f; vertex[4].y = -8.1f; vertex[4].z = 4.5f;
+
+ exp_min.x = -6.92f; exp_min.y = -8.1f; exp_min.z = -3.80f;
+ exp_max.x = 11.4f; exp_max.y = 7.90f; exp_max.z = 11.9f;
+
+ hr = D3DXComputeBoundingBox(&vertex[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_min,&got_max);
+
+ ok( hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok( compare_vec3(exp_min,got_min), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min.x,exp_min.y,exp_min.z,got_min.x,got_min.y,got_min.z);
+ ok( compare_vec3(exp_max,got_max), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max.x,exp_max.y,exp_max.z,got_max.x,got_max.y,got_max.z);
+
+/*________________________*/
+
+ vertex[0].x = 2.0f; vertex[0].y = 5.9f; vertex[0].z = -1.2f;
+ vertex[1].x = -1.87f; vertex[1].y = 7.9f; vertex[1].z = 7.4f;
+ vertex[2].x = 7.43f; vertex[2].y = -0.9f; vertex[2].z = 11.9f;
+ vertex[3].x = -6.92f; vertex[3].y = 6.3f; vertex[3].z = -3.8f;
+ vertex[4].x = 11.4f; vertex[4].y = -8.1f; vertex[4].z = 4.5f;
+
+ exp_min.x = -6.92f; exp_min.y = -0.9f; exp_min.z = -3.8f;
+ exp_max.x = 7.43f; exp_max.y = 7.90f; exp_max.z = 11.9f;
+
+ hr = D3DXComputeBoundingBox(&vertex[0],4,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_min,&got_max);
+
+ ok( hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok( compare_vec3(exp_min,got_min), "Expected min: (%f, %f, %f), got: (%f, %f, %f)\n", exp_min.x,exp_min.y,exp_min.z,got_min.x,got_min.y,got_min.z);
+ ok( compare_vec3(exp_max,got_max), "Expected max: (%f, %f, %f), got: (%f, %f, %f)\n", exp_max.x,exp_max.y,exp_max.z,got_max.x,got_max.y,got_max.z);
+
+/*________________________*/
+ hr = D3DXComputeBoundingBox(NULL,5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_min,&got_max);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+/*________________________*/
+ hr = D3DXComputeBoundingBox(&vertex[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),NULL,&got_max);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+/*________________________*/
+ hr = D3DXComputeBoundingBox(&vertex[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_min,NULL);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+}
+
+static void D3DXComputeBoundingSphereTest(void)
+{
+ D3DXVECTOR3 exp_cen, got_cen, vertex[5];
+ FLOAT exp_rad, got_rad;
+ HRESULT hr;
+
+ vertex[0].x = 1.0f; vertex[0].y = 1.0f; vertex[0].z = 1.0f;
+ vertex[1].x = 1.0f; vertex[1].y = 1.0f; vertex[1].z = 1.0f;
+ vertex[2].x = 1.0f; vertex[2].y = 1.0f; vertex[2].z = 1.0f;
+ vertex[3].x = 1.0f; vertex[3].y = 1.0f; vertex[3].z = 1.0f;
+ vertex[4].x = 9.0f; vertex[4].y = 9.0f; vertex[4].z = 9.0f;
+
+ exp_rad = 6.928203f;
+ exp_cen.x = 5.0; exp_cen.y = 5.0; exp_cen.z = 5.0;
+
+ hr = D3DXComputeBoundingSphere(&vertex[3],2,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_cen,&got_rad);
+
+ ok( hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok( compare(exp_rad, got_rad), "Expected radius: %f, got radius: %f\n", exp_rad, got_rad);
+ ok( compare_vec3(exp_cen,got_cen), "Expected center: (%f, %f, %f), got center: (%f, %f, %f)\n", exp_cen.x,exp_cen.y,exp_cen.z,got_cen.x,got_cen.y,got_cen.z);
+
+/*________________________*/
+
+ vertex[0].x = 2.0f; vertex[0].y = 5.9f; vertex[0].z = -1.2f;
+ vertex[1].x = -1.87f; vertex[1].y = 7.9f; vertex[1].z = 7.4f;
+ vertex[2].x = 7.43f; vertex[2].y = -0.9f; vertex[2].z = 11.9f;
+ vertex[3].x = -6.92f; vertex[3].y = 6.3f; vertex[3].z = -3.8f;
+ vertex[4].x = 11.4f; vertex[4].y = -8.1f; vertex[4].z = 4.5f;
+
+ exp_rad = 13.707883f;
+ exp_cen.x = 2.408f; exp_cen.y = 2.22f; exp_cen.z = 3.76f;
+
+ hr = D3DXComputeBoundingSphere(&vertex[0],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_cen,&got_rad);
+
+ ok( hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok( compare(exp_rad, got_rad), "Expected radius: %f, got radius: %f\n", exp_rad, got_rad);
+ ok( compare_vec3(exp_cen,got_cen), "Expected center: (%f, %f, %f), got center: (%f, %f, %f)\n", exp_cen.x,exp_cen.y,exp_cen.z,got_cen.x,got_cen.y,got_cen.z);
+
+/*________________________*/
+ hr = D3DXComputeBoundingSphere(NULL,5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_cen,&got_rad);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+/*________________________*/
+ hr = D3DXComputeBoundingSphere(&vertex[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),NULL,&got_rad);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+/*________________________*/
+ hr = D3DXComputeBoundingSphere(&vertex[3],5,D3DXGetFVFVertexSize(D3DFVF_XYZ),&got_cen,NULL);
+ ok( hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+}
+
+static void print_elements(const D3DVERTEXELEMENT9 *elements)
+{
+ D3DVERTEXELEMENT9 last = D3DDECL_END();
+ const D3DVERTEXELEMENT9 *ptr = elements;
+ int count = 0;
+
+ while (memcmp(ptr, &last, sizeof(D3DVERTEXELEMENT9)))
+ {
+ trace(
+ "[Element %d] Stream = %d, Offset = %d, Type = %d, Method = %d, Usage = %d, UsageIndex = %d\n",
+ count, ptr->Stream, ptr->Offset, ptr->Type, ptr->Method, ptr->Usage, ptr->UsageIndex);
+ ptr++;
+ count++;
+ }
+}
+
+static void compare_elements(const D3DVERTEXELEMENT9 *elements, const D3DVERTEXELEMENT9 *expected_elements,
+ unsigned int line, unsigned int test_id)
+{
+ D3DVERTEXELEMENT9 last = D3DDECL_END();
+ unsigned int i;
+
+ for (i = 0; i < MAX_FVF_DECL_SIZE; i++)
+ {
+ int end1 = memcmp(&elements[i], &last, sizeof(last));
+ int end2 = memcmp(&expected_elements[i], &last, sizeof(last));
+ int status;
+
+ if (!end1 && !end2) break;
+
+ status = !end1 ^ !end2;
+ ok(!status, "Line %u, test %u: Mismatch in size, test declaration is %s than expected.\n",
+ line, test_id, end1 ? "shorter" : "longer");
+ if (status)
+ {
+ print_elements(elements);
+ break;
+ }
+
+ status = memcmp(&elements[i], &expected_elements[i], sizeof(D3DVERTEXELEMENT9));
+ ok(!status, "Line %u, test %u: Mismatch in element %u.\n", line, test_id, i);
+ if (status)
+ {
+ print_elements(elements);
+ break;
+ }
+ }
+}
+
+static void test_fvf_to_decl(DWORD test_fvf, const D3DVERTEXELEMENT9 expected_elements[],
+ HRESULT expected_hr, unsigned int line, unsigned int test_id)
+{
+ HRESULT hr;
+ D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
+
+ hr = D3DXDeclaratorFromFVF(test_fvf, decl);
+ ok(hr == expected_hr,
+ "Line %u, test %u: D3DXDeclaratorFromFVF returned %#x, expected %#x.\n",
+ line, test_id, hr, expected_hr);
+ if (SUCCEEDED(hr)) compare_elements(decl, expected_elements, line, test_id);
+}
+
+static void test_decl_to_fvf(const D3DVERTEXELEMENT9 *decl, DWORD expected_fvf,
+ HRESULT expected_hr, unsigned int line, unsigned int test_id)
+{
+ HRESULT hr;
+ DWORD result_fvf = 0xdeadbeef;
+
+ hr = D3DXFVFFromDeclarator(decl, &result_fvf);
+ ok(hr == expected_hr,
+ "Line %u, test %u: D3DXFVFFromDeclarator returned %#x, expected %#x.\n",
+ line, test_id, hr, expected_hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(expected_fvf == result_fvf, "Line %u, test %u: Got FVF %#x, expected %#x.\n",
+ line, test_id, result_fvf, expected_fvf);
+ }
+}
+
+static void test_fvf_decl_conversion(void)
+{
+ static const struct
+ {
+ D3DVERTEXELEMENT9 decl[MAXD3DDECLLENGTH + 1];
+ DWORD fvf;
+ }
+ test_data[] =
+ {
+ {{
+ D3DDECL_END(),
+ }, 0},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZ},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZRHW},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZRHW},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB1},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB2},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB3},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ }, D3DFVF_NORMAL},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END(),
+ }, D3DFVF_NORMAL | D3DFVF_DIFFUSE},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
+ D3DDECL_END(),
+ }, D3DFVF_PSIZE},
+ {{
+ {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END(),
+ }, D3DFVF_DIFFUSE},
+ {{
+ {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
+ D3DDECL_END(),
+ }, D3DFVF_SPECULAR},
+ /* Make sure textures of different sizes work. */
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END(),
+ }, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END(),
+ }, D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END(),
+ }, D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END(),
+ }, D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1},
+ /* Make sure the TEXCOORD index works correctly - try several textures. */
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
+ {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2},
+ {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
+ D3DDECL_END(),
+ }, D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1)
+ | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE4(3)},
+ /* Now try some combination tests. */
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ {0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
+ {0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1},
+ D3DDECL_END(),
+ }, D3DFVF_XYZB4 | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX2
+ | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1)},
+ {{
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
+ {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
+ {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, 36, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
+ D3DDECL_END(),
+ }, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_PSIZE | D3DFVF_SPECULAR | D3DFVF_TEX2
+ | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE4(1)},
+ };
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(test_data); ++i)
+ {
+ test_decl_to_fvf(test_data[i].decl, test_data[i].fvf, D3D_OK, __LINE__, i);
+ test_fvf_to_decl(test_data[i].fvf, test_data[i].decl, D3D_OK, __LINE__, i);
+ }
+
+ /* Usage indices for position and normal are apparently ignored. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, D3DFVF_XYZ, D3D_OK, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, D3DFVF_NORMAL, D3D_OK, __LINE__, 0);
+ }
+ /* D3DFVF_LASTBETA_UBYTE4 and D3DFVF_LASTBETA_D3DCOLOR are ignored if
+ * there are no blend matrices. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_fvf_to_decl(D3DFVF_XYZ | D3DFVF_LASTBETA_UBYTE4, decl, D3D_OK, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_fvf_to_decl(D3DFVF_XYZ | D3DFVF_LASTBETA_D3DCOLOR, decl, D3D_OK, __LINE__, 0);
+ }
+ /* D3DFVF_LASTBETA_UBYTE4 takes precedence over D3DFVF_LASTBETA_D3DCOLOR. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ };
+ test_fvf_to_decl(D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR | D3DFVF_LASTBETA_UBYTE4,
+ decl, D3D_OK, __LINE__, 0);
+ }
+ /* These are supposed to fail, both ways. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, D3DFVF_XYZW, D3DERR_INVALIDCALL, __LINE__, 0);
+ test_fvf_to_decl(D3DFVF_XYZW, decl, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 16, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, D3DFVF_XYZW | D3DFVF_NORMAL, D3DERR_INVALIDCALL, __LINE__, 0);
+ test_fvf_to_decl(D3DFVF_XYZW | D3DFVF_NORMAL, decl, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ {0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, D3DFVF_XYZB5, D3DERR_INVALIDCALL, __LINE__, 0);
+ test_fvf_to_decl(D3DFVF_XYZB5, decl, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Test a declaration that can't be converted to an FVF. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0},
+ {0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1},
+ {0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ /* 8 bytes padding */
+ {0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Elements must be ordered by offset. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Basic tests for element order. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ {0, 16, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Textures must be ordered by texcoords. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 2},
+ {0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 1},
+ {0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Duplicate elements are not allowed. */
+ {
+ const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ {0, 16, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END(),
+ };
+ test_decl_to_fvf(decl, 0, D3DERR_INVALIDCALL, __LINE__, 0);
+ }
+ /* Invalid FVFs cannot be converted to a declarator. */
+ test_fvf_to_decl(0xdeadbeef, NULL, D3DERR_INVALIDCALL, __LINE__, 0);
+}
+
+static void D3DXGetFVFVertexSizeTest(void)
+{
+ UINT got;
+
+ compare_vertex_sizes (D3DFVF_XYZ, 12);
+
+ compare_vertex_sizes (D3DFVF_XYZB3, 24);
+
+ compare_vertex_sizes (D3DFVF_XYZB5, 32);
+
+ compare_vertex_sizes (D3DFVF_XYZ | D3DFVF_NORMAL, 24);
+
+ compare_vertex_sizes (D3DFVF_XYZ | D3DFVF_DIFFUSE, 16);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX1 |
+ D3DFVF_TEXCOORDSIZE1(0), 16);
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX2 |
+ D3DFVF_TEXCOORDSIZE1(0) |
+ D3DFVF_TEXCOORDSIZE1(1), 20);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX1 |
+ D3DFVF_TEXCOORDSIZE2(0), 20);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX2 |
+ D3DFVF_TEXCOORDSIZE2(0) |
+ D3DFVF_TEXCOORDSIZE2(1), 28);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX6 |
+ D3DFVF_TEXCOORDSIZE2(0) |
+ D3DFVF_TEXCOORDSIZE2(1) |
+ D3DFVF_TEXCOORDSIZE2(2) |
+ D3DFVF_TEXCOORDSIZE2(3) |
+ D3DFVF_TEXCOORDSIZE2(4) |
+ D3DFVF_TEXCOORDSIZE2(5), 60);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX8 |
+ D3DFVF_TEXCOORDSIZE2(0) |
+ D3DFVF_TEXCOORDSIZE2(1) |
+ D3DFVF_TEXCOORDSIZE2(2) |
+ D3DFVF_TEXCOORDSIZE2(3) |
+ D3DFVF_TEXCOORDSIZE2(4) |
+ D3DFVF_TEXCOORDSIZE2(5) |
+ D3DFVF_TEXCOORDSIZE2(6) |
+ D3DFVF_TEXCOORDSIZE2(7), 76);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX1 |
+ D3DFVF_TEXCOORDSIZE3(0), 24);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX4 |
+ D3DFVF_TEXCOORDSIZE3(0) |
+ D3DFVF_TEXCOORDSIZE3(1) |
+ D3DFVF_TEXCOORDSIZE3(2) |
+ D3DFVF_TEXCOORDSIZE3(3), 60);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX1 |
+ D3DFVF_TEXCOORDSIZE4(0), 28);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX2 |
+ D3DFVF_TEXCOORDSIZE4(0) |
+ D3DFVF_TEXCOORDSIZE4(1), 44);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZ |
+ D3DFVF_TEX3 |
+ D3DFVF_TEXCOORDSIZE4(0) |
+ D3DFVF_TEXCOORDSIZE4(1) |
+ D3DFVF_TEXCOORDSIZE4(2), 60);
+
+ compare_vertex_sizes (
+ D3DFVF_XYZB5 |
+ D3DFVF_NORMAL |
+ D3DFVF_DIFFUSE |
+ D3DFVF_SPECULAR |
+ D3DFVF_TEX8 |
+ D3DFVF_TEXCOORDSIZE4(0) |
+ D3DFVF_TEXCOORDSIZE4(1) |
+ D3DFVF_TEXCOORDSIZE4(2) |
+ D3DFVF_TEXCOORDSIZE4(3) |
+ D3DFVF_TEXCOORDSIZE4(4) |
+ D3DFVF_TEXCOORDSIZE4(5) |
+ D3DFVF_TEXCOORDSIZE4(6) |
+ D3DFVF_TEXCOORDSIZE4(7), 180);
+}
+
+static void D3DXIntersectTriTest(void)
+{
+ BOOL exp_res, got_res;
+ D3DXVECTOR3 position, ray, vertex[3];
+ FLOAT exp_dist, got_dist, exp_u, got_u, exp_v, got_v;
+
+ vertex[0].x = 1.0f; vertex[0].y = 0.0f; vertex[0].z = 0.0f;
+ vertex[1].x = 2.0f; vertex[1].y = 0.0f; vertex[1].z = 0.0f;
+ vertex[2].x = 1.0f; vertex[2].y = 1.0f; vertex[2].z = 0.0f;
+
+ position.x = -14.5f; position.y = -23.75f; position.z = -32.0f;
+
+ ray.x = 2.0f; ray.y = 3.0f; ray.z = 4.0f;
+
+ exp_res = TRUE; exp_u = 0.5f; exp_v = 0.25f; exp_dist = 8.0f;
+
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, &got_u, &got_v, &got_dist);
+ ok(got_res == exp_res, "Expected result %d, got %d.\n", exp_res, got_res);
+ ok(compare(exp_u, got_u), "Expected u %f, got %f.\n", exp_u, got_u);
+ ok(compare(exp_v, got_v), "Expected v %f, got %f.\n", exp_v, got_v);
+ ok(compare(exp_dist, got_dist), "Expected distance %f, got %f.\n", exp_dist, got_dist);
+
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, NULL, NULL, NULL);
+ ok(got_res == exp_res, "Expected result %d, got %d.\n", exp_res, got_res);
+
+ vertex[2].x = 1.0f; vertex[2].y = 0.0f; vertex[2].z = 0.0f;
+ vertex[1].x = 2.0f; vertex[1].y = 0.0f; vertex[1].z = 0.0f;
+ vertex[0].x = 1.0f; vertex[0].y = 1.0f; vertex[0].z = 0.0f;
+
+ got_u = got_v = got_dist = 0.0f;
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, &got_u, &got_v, &got_dist);
+ ok(got_res == exp_res, "Expected result %d, got %d.\n", exp_res, got_res);
+ ok(compare(exp_u, got_u), "Expected u %f, got %f.\n", exp_u, got_u);
+ ok(compare(exp_v, got_v), "Expected v %f, got %f.\n", exp_v, got_v);
+ ok(compare(exp_dist, got_dist), "Expected distance %f, got %f.\n", exp_dist, got_dist);
+
+ vertex[2].x = 1.0f; vertex[2].y = 0.0f; vertex[2].z = 0.0f;
+ vertex[1].x = 2.0f; vertex[1].y = 0.0f; vertex[1].z = -0.5f;
+ vertex[0].x = 1.0f; vertex[0].y = 1.0f; vertex[0].z = -1.0f;
+ exp_u = 0.375f;
+ exp_v = 0.5625f;
+ exp_dist = 7.9375f;
+ got_u = got_v = got_dist = 0.0f;
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, &got_u, &got_v, &got_dist);
+ ok(got_res == exp_res, "Expected result %d, got %d.\n", exp_res, got_res);
+ ok(compare(exp_u, got_u), "Expected u %f, got %f.\n", exp_u, got_u);
+ ok(compare(exp_v, got_v), "Expected v %f, got %f.\n", exp_v, got_v);
+ ok(compare(exp_dist, got_dist), "Expected distance %f, got %f.\n", exp_dist, got_dist);
+
+
+/*Only positive ray is taken in account*/
+
+ vertex[0].x = 1.0f; vertex[0].y = 0.0f; vertex[0].z = 0.0f;
+ vertex[1].x = 2.0f; vertex[1].y = 0.0f; vertex[1].z = 0.0f;
+ vertex[2].x = 1.0f; vertex[2].y = 1.0f; vertex[2].z = 0.0f;
+
+ position.x = 17.5f; position.y = 24.25f; position.z = 32.0f;
+
+ ray.x = 2.0f; ray.y = 3.0f; ray.z = 4.0f;
+
+ exp_res = FALSE;
+
+ got_res = D3DXIntersectTri(&vertex[0],&vertex[1],&vertex[2],&position,&ray,&got_u,&got_v,&got_dist);
+ ok( got_res == exp_res, "Expected result = %d, got %d\n",exp_res,got_res);
+
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, NULL, NULL, NULL);
+ ok(got_res == exp_res, "Expected result = %d, got %d\n", exp_res, got_res);
+
+/*Intersection between ray and triangle in a same plane is considered as empty*/
+
+ vertex[0].x = 4.0f; vertex[0].y = 0.0f; vertex[0].z = 0.0f;
+ vertex[1].x = 6.0f; vertex[1].y = 0.0f; vertex[1].z = 0.0f;
+ vertex[2].x = 4.0f; vertex[2].y = 2.0f; vertex[2].z = 0.0f;
+
+ position.x = 1.0f; position.y = 1.0f; position.z = 0.0f;
+
+ ray.x = 1.0f; ray.y = 0.0f; ray.z = 0.0f;
+
+ exp_res = FALSE;
+
+ got_res = D3DXIntersectTri(&vertex[0],&vertex[1],&vertex[2],&position,&ray,&got_u,&got_v,&got_dist);
+ ok( got_res == exp_res, "Expected result = %d, got %d\n",exp_res,got_res);
+
+ got_res = D3DXIntersectTri(&vertex[0], &vertex[1], &vertex[2], &position, &ray, NULL, NULL, NULL);
+ ok(got_res == exp_res, "Expected result = %d, got %d\n", exp_res, got_res);
+}
+
+static void D3DXCreateMeshTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9 *device, *test_device;
+ ID3DXMesh *d3dxmesh;
+ int i, size;
+ D3DVERTEXELEMENT9 test_decl[MAX_FVF_DECL_SIZE];
+ DWORD options;
+ struct mesh mesh;
+ struct test_context *test_context;
+
+ static const D3DVERTEXELEMENT9 decl1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ };
+
+ static const D3DVERTEXELEMENT9 decl2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0},
+ {0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
+ {0, 32, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ /* 8 bytes padding */
+ {0, 44, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
+ D3DDECL_END(),
+ };
+
+ static const D3DVERTEXELEMENT9 decl3[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ };
+
+ hr = D3DXCreateMesh(0, 0, 0, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, NULL, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateMesh(0, 3, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMesh(1, 0, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMesh(1, 3, 0, decl1, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ if (hr == D3D_OK)
+ {
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ }
+
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, 0, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, device, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ /* device */
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, &test_device);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(test_device == device, "Got result %p, expected %p\n", test_device, device);
+
+ if (hr == D3D_OK)
+ {
+ IDirect3DDevice9_Release(device);
+ }
+
+ /* declaration */
+ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, test_decl);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ size = ARRAY_SIZE(decl1);
+ for (i = 0; i < size - 1; i++)
+ {
+ ok(test_decl[i].Stream == decl1[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl1[i].Stream);
+ ok(test_decl[i].Type == decl1[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl1[i].Type);
+ ok(test_decl[i].Method == decl1[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl1[i].Method);
+ ok(test_decl[i].Usage == decl1[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl1[i].Usage);
+ ok(test_decl[i].UsageIndex == decl1[i].UsageIndex, "Returned usage index %d, expected %d\n", test_decl[i].UsageIndex, decl1[i].UsageIndex);
+ ok(test_decl[i].Offset == decl1[i].Offset, "Returned offset %d, expected %d\n", test_decl[i].Offset, decl1[i].Offset);
+ }
+ ok(decl1[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
+ }
+
+ /* options */
+ options = d3dxmesh->lpVtbl->GetOptions(d3dxmesh);
+ ok(options == D3DXMESH_MANAGED, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options, D3DXMESH_MANAGED);
+
+ /* rest */
+ if (!new_mesh(&mesh, 3, 1))
+ {
+ skip("Couldn't create mesh\n");
+ }
+ else
+ {
+ memset(mesh.vertices, 0, mesh.number_of_vertices * sizeof(*mesh.vertices));
+ memset(mesh.faces, 0, mesh.number_of_faces * sizeof(*mesh.faces));
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ compare_mesh("createmesh1", d3dxmesh, &mesh);
+
+ free_mesh(&mesh);
+ }
+
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ }
+
+ /* Test a declaration that can't be converted to an FVF. */
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl2, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ /* device */
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, &test_device);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(test_device == device, "Got result %p, expected %p\n", test_device, device);
+
+ if (hr == D3D_OK)
+ {
+ IDirect3DDevice9_Release(device);
+ }
+
+ /* declaration */
+ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, test_decl);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ size = ARRAY_SIZE(decl2);
+ for (i = 0; i < size - 1; i++)
+ {
+ ok(test_decl[i].Stream == decl2[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl2[i].Stream);
+ ok(test_decl[i].Type == decl2[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl2[i].Type);
+ ok(test_decl[i].Method == decl2[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl2[i].Method);
+ ok(test_decl[i].Usage == decl2[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl2[i].Usage);
+ ok(test_decl[i].UsageIndex == decl2[i].UsageIndex, "Returned usage index %d, expected %d\n", test_decl[i].UsageIndex, decl2[i].UsageIndex);
+ ok(test_decl[i].Offset == decl2[i].Offset, "Returned offset %d, expected %d\n", test_decl[i].Offset, decl2[i].Offset);
+ }
+ ok(decl2[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
+ }
+
+ /* options */
+ options = d3dxmesh->lpVtbl->GetOptions(d3dxmesh);
+ ok(options == D3DXMESH_MANAGED, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options, D3DXMESH_MANAGED);
+
+ /* rest */
+ if (!new_mesh(&mesh, 3, 1))
+ {
+ skip("Couldn't create mesh\n");
+ }
+ else
+ {
+ memset(mesh.vertices, 0, mesh.number_of_vertices * sizeof(*mesh.vertices));
+ memset(mesh.faces, 0, mesh.number_of_faces * sizeof(*mesh.faces));
+ mesh.fvf = 0;
+ mesh.vertex_size = 60;
+
+ compare_mesh("createmesh2", d3dxmesh, &mesh);
+
+ free_mesh(&mesh);
+ }
+
+ mesh.vertex_size = d3dxmesh->lpVtbl->GetNumBytesPerVertex(d3dxmesh);
+ ok(mesh.vertex_size == 60, "Got vertex size %u, expected %u\n", mesh.vertex_size, 60);
+
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ }
+
+ /* Test a declaration with multiple streams. */
+ hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl3, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ free_test_context(test_context);
+}
+
+static void D3DXCreateMeshFVFTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9 *device, *test_device;
+ ID3DXMesh *d3dxmesh;
+ int i, size;
+ D3DVERTEXELEMENT9 test_decl[MAX_FVF_DECL_SIZE];
+ DWORD options;
+ struct mesh mesh;
+ struct test_context *test_context;
+
+ static const D3DVERTEXELEMENT9 decl[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END(),
+ };
+
+ hr = D3DXCreateMeshFVF(0, 0, 0, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, NULL, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateMeshFVF(0, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMeshFVF(1, 0, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMeshFVF(1, 3, 0, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ if (hr == D3D_OK)
+ {
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ }
+
+ hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, 0xdeadbeef, device, &d3dxmesh);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateMeshFVF(1, 3, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ /* device */
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, &test_device);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(test_device == device, "Got result %p, expected %p\n", test_device, device);
+
+ if (hr == D3D_OK)
+ {
+ IDirect3DDevice9_Release(device);
+ }
+
+ /* declaration */
+ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, test_decl);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ if (hr == D3D_OK)
+ {
+ size = ARRAY_SIZE(decl);
+ for (i = 0; i < size - 1; i++)
+ {
+ ok(test_decl[i].Stream == decl[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl[i].Stream);
+ ok(test_decl[i].Type == decl[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl[i].Type);
+ ok(test_decl[i].Method == decl[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl[i].Method);
+ ok(test_decl[i].Usage == decl[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl[i].Usage);
+ ok(test_decl[i].UsageIndex == decl[i].UsageIndex, "Returned usage index %d, expected %d\n",
+ test_decl[i].UsageIndex, decl[i].UsageIndex);
+ ok(test_decl[i].Offset == decl[i].Offset, "Returned offset %d, expected %d\n", test_decl[i].Offset, decl[i].Offset);
+ }
+ ok(decl[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
+ }
+
+ /* options */
+ options = d3dxmesh->lpVtbl->GetOptions(d3dxmesh);
+ ok(options == D3DXMESH_MANAGED, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options, D3DXMESH_MANAGED);
+
+ /* rest */
+ if (!new_mesh(&mesh, 3, 1))
+ {
+ skip("Couldn't create mesh\n");
+ }
+ else
+ {
+ memset(mesh.vertices, 0, mesh.number_of_vertices * sizeof(*mesh.vertices));
+ memset(mesh.faces, 0, mesh.number_of_faces * sizeof(*mesh.faces));
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ compare_mesh("createmeshfvf", d3dxmesh, &mesh);
+
+ free_mesh(&mesh);
+ }
+
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ }
+
+ free_test_context(test_context);
+}
+
+#define check_vertex_buffer(mesh, vertices, num_vertices, fvf) \
+ check_vertex_buffer_(__LINE__, mesh, vertices, num_vertices, fvf)
+static void check_vertex_buffer_(int line, ID3DXMesh *mesh, const void *vertices, DWORD num_vertices, DWORD fvf)
+{
+ DWORD mesh_num_vertices = mesh->lpVtbl->GetNumVertices(mesh);
+ DWORD mesh_fvf = mesh->lpVtbl->GetFVF(mesh);
+ const void *mesh_vertices;
+ HRESULT hr;
+
+ ok_(__FILE__,line)(fvf == mesh_fvf, "expected FVF %x, got %x\n", fvf, mesh_fvf);
+ ok_(__FILE__,line)(num_vertices == mesh_num_vertices,
+ "Expected %u vertices, got %u\n", num_vertices, mesh_num_vertices);
+
+ hr = mesh->lpVtbl->LockVertexBuffer(mesh, D3DLOCK_READONLY, (void**)&mesh_vertices);
+ ok_(__FILE__,line)(hr == D3D_OK, "LockVertexBuffer returned %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (FAILED(hr))
+ return;
+
+ if (mesh_fvf == fvf) {
+ DWORD vertex_size = D3DXGetFVFVertexSize(fvf), i;
+
+ for (i = 0; i < min(num_vertices, mesh_num_vertices); i++)
+ {
+ const FLOAT *exp_float = vertices;
+ const FLOAT *got_float = mesh_vertices;
+ DWORD texcount;
+ DWORD pos_dim = 0;
+ int j;
+ BOOL last_beta_dword = FALSE;
+ char prefix[128];
+
+ switch (fvf & D3DFVF_POSITION_MASK) {
+ case D3DFVF_XYZ: pos_dim = 3; break;
+ case D3DFVF_XYZRHW: pos_dim = 4; break;
+ case D3DFVF_XYZB1:
+ case D3DFVF_XYZB2:
+ case D3DFVF_XYZB3:
+ case D3DFVF_XYZB4:
+ case D3DFVF_XYZB5:
+ pos_dim = (fvf & D3DFVF_POSITION_MASK) - D3DFVF_XYZB1 + 1;
+ if (fvf & (D3DFVF_LASTBETA_UBYTE4 | D3DFVF_LASTBETA_D3DCOLOR))
+ {
+ pos_dim--;
+ last_beta_dword = TRUE;
+ }
+ break;
+ case D3DFVF_XYZW: pos_dim = 4; break;
+ }
+ sprintf(prefix, "vertex[%u] position, ", i);
+ check_floats_(line, prefix, got_float, exp_float, pos_dim);
+ exp_float += pos_dim;
+ got_float += pos_dim;
+
+ if (last_beta_dword) {
+ ok_(__FILE__,line)(*(DWORD*)exp_float == *(DWORD*)got_float,
+ "Vertex[%u]: Expected last beta %08x, got %08x\n", i, *(DWORD*)exp_float, *(DWORD*)got_float);
+ exp_float++;
+ got_float++;
+ }
+
+ if (fvf & D3DFVF_NORMAL) {
+ sprintf(prefix, "vertex[%u] normal, ", i);
+ check_floats_(line, prefix, got_float, exp_float, 3);
+ exp_float += 3;
+ got_float += 3;
+ }
+ if (fvf & D3DFVF_PSIZE) {
+ ok_(__FILE__,line)(compare(*exp_float, *got_float),
+ "Vertex[%u]: Expected psize %g, got %g\n", i, *exp_float, *got_float);
+ exp_float++;
+ got_float++;
+ }
+ if (fvf & D3DFVF_DIFFUSE) {
+ ok_(__FILE__,line)(*(DWORD*)exp_float == *(DWORD*)got_float,
+ "Vertex[%u]: Expected diffuse %08x, got %08x\n", i, *(DWORD*)exp_float, *(DWORD*)got_float);
+ exp_float++;
+ got_float++;
+ }
+ if (fvf & D3DFVF_SPECULAR) {
+ ok_(__FILE__,line)(*(DWORD*)exp_float == *(DWORD*)got_float,
+ "Vertex[%u]: Expected specular %08x, got %08x\n", i, *(DWORD*)exp_float, *(DWORD*)got_float);
+ exp_float++;
+ got_float++;
+ }
+
+ texcount = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
+ for (j = 0; j < texcount; j++) {
+ DWORD dim = (((fvf >> (16 + 2 * j)) + 1) & 0x03) + 1;
+ sprintf(prefix, "vertex[%u] texture, ", i);
+ check_floats_(line, prefix, got_float, exp_float, dim);
+ exp_float += dim;
+ got_float += dim;
+ }
+
+ vertices = (BYTE*)vertices + vertex_size;
+ mesh_vertices = (BYTE*)mesh_vertices + vertex_size;
+ }
+ }
+
+ mesh->lpVtbl->UnlockVertexBuffer(mesh);
+}
+
+#define check_index_buffer(mesh, indices, num_indices, index_size) \
+ check_index_buffer_(__LINE__, mesh, indices, num_indices, index_size)
+static void check_index_buffer_(int line, ID3DXMesh *mesh, const void *indices, DWORD num_indices, DWORD index_size)
+{
+ DWORD mesh_index_size = (mesh->lpVtbl->GetOptions(mesh) & D3DXMESH_32BIT) ? 4 : 2;
+ DWORD mesh_num_indices = mesh->lpVtbl->GetNumFaces(mesh) * 3;
+ const void *mesh_indices;
+ HRESULT hr;
+ DWORD i;
+
+ ok_(__FILE__,line)(index_size == mesh_index_size,
+ "Expected index size %u, got %u\n", index_size, mesh_index_size);
+ ok_(__FILE__,line)(num_indices == mesh_num_indices,
+ "Expected %u indices, got %u\n", num_indices, mesh_num_indices);
+
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, D3DLOCK_READONLY, (void**)&mesh_indices);
+ ok_(__FILE__,line)(hr == D3D_OK, "LockIndexBuffer returned %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (FAILED(hr))
+ return;
+
+ if (mesh_index_size == index_size) {
+ for (i = 0; i < min(num_indices, mesh_num_indices); i++)
+ {
+ if (index_size == 4)
+ ok_(__FILE__,line)(*(DWORD*)indices == *(DWORD*)mesh_indices,
+ "Index[%u]: expected %u, got %u\n", i, *(DWORD*)indices, *(DWORD*)mesh_indices);
+ else
+ ok_(__FILE__,line)(*(WORD*)indices == *(WORD*)mesh_indices,
+ "Index[%u]: expected %u, got %u\n", i, *(WORD*)indices, *(WORD*)mesh_indices);
+ indices = (BYTE*)indices + index_size;
+ mesh_indices = (BYTE*)mesh_indices + index_size;
+ }
+ }
+ mesh->lpVtbl->UnlockIndexBuffer(mesh);
+}
+
+#define check_matrix(got, expected) check_matrix_(__LINE__, got, expected)
+static void check_matrix_(int line, const D3DXMATRIX *got, const D3DXMATRIX *expected)
+{
+ int i, j;
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ ok_(__FILE__,line)(compare(U(*expected).m[i][j], U(*got).m[i][j]),
+ "matrix[%u][%u]: expected %g, got %g\n",
+ i, j, U(*expected).m[i][j], U(*got).m[i][j]);
+ }
+ }
+}
+
+static void check_colorvalue_(int line, const char *prefix, const D3DCOLORVALUE got, const D3DCOLORVALUE expected)
+{
+ ok_(__FILE__,line)(expected.r == got.r && expected.g == got.g && expected.b == got.b && expected.a == got.a,
+ "%sExpected (%g, %g, %g, %g), got (%g, %g, %g, %g)\n", prefix,
+ expected.r, expected.g, expected.b, expected.a, got.r, got.g, got.b, got.a);
+}
+
+#define check_materials(got, got_count, expected, expected_count) \
+ check_materials_(__LINE__, got, got_count, expected, expected_count)
+static void check_materials_(int line, const D3DXMATERIAL *got, DWORD got_count, const D3DXMATERIAL *expected, DWORD expected_count)
+{
+ int i;
+ ok_(__FILE__,line)(expected_count == got_count, "Expected %u materials, got %u\n", expected_count, got_count);
+ if (!expected) {
+ ok_(__FILE__,line)(got == NULL, "Expected NULL material ptr, got %p\n", got);
+ return;
+ }
+ for (i = 0; i < min(expected_count, got_count); i++)
+ {
+ if (!expected[i].pTextureFilename)
+ ok_(__FILE__,line)(got[i].pTextureFilename == NULL,
+ "Expected NULL pTextureFilename, got %p\n", got[i].pTextureFilename);
+ else
+ ok_(__FILE__,line)(!strcmp(expected[i].pTextureFilename, got[i].pTextureFilename),
+ "Expected '%s' for pTextureFilename, got '%s'\n", expected[i].pTextureFilename, got[i].pTextureFilename);
+ check_colorvalue_(line, "Diffuse: ", got[i].MatD3D.Diffuse, expected[i].MatD3D.Diffuse);
+ check_colorvalue_(line, "Ambient: ", got[i].MatD3D.Ambient, expected[i].MatD3D.Ambient);
+ check_colorvalue_(line, "Specular: ", got[i].MatD3D.Specular, expected[i].MatD3D.Specular);
+ check_colorvalue_(line, "Emissive: ", got[i].MatD3D.Emissive, expected[i].MatD3D.Emissive);
+ ok_(__FILE__,line)(expected[i].MatD3D.Power == got[i].MatD3D.Power,
+ "Power: Expected %g, got %g\n", expected[i].MatD3D.Power, got[i].MatD3D.Power);
+ }
+}
+
+#define check_generated_adjacency(mesh, got, epsilon) check_generated_adjacency_(__LINE__, mesh, got, epsilon)
+static void check_generated_adjacency_(int line, ID3DXMesh *mesh, const DWORD *got, FLOAT epsilon)
+{
+ DWORD *expected;
+ DWORD num_faces = mesh->lpVtbl->GetNumFaces(mesh);
+ HRESULT hr;
+
+ expected = HeapAlloc(GetProcessHeap(), 0, num_faces * sizeof(DWORD) * 3);
+ if (!expected) {
+ skip_(__FILE__, line)("Out of memory\n");
+ return;
+ }
+ hr = mesh->lpVtbl->GenerateAdjacency(mesh, epsilon, expected);
+ ok_(__FILE__, line)(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ int i;
+ for (i = 0; i < num_faces; i++)
+ {
+ ok_(__FILE__, line)(expected[i * 3] == got[i * 3] &&
+ expected[i * 3 + 1] == got[i * 3 + 1] &&
+ expected[i * 3 + 2] == got[i * 3 + 2],
+ "Face %u adjacencies: Expected (%u, %u, %u), got (%u, %u, %u)\n", i,
+ expected[i * 3], expected[i * 3 + 1], expected[i * 3 + 2],
+ got[i * 3], got[i * 3 + 1], got[i * 3 + 2]);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, expected);
+}
+
+#define check_generated_effects(materials, num_materials, effects) \
+ check_generated_effects_(__LINE__, materials, num_materials, effects)
+static void check_generated_effects_(int line, const D3DXMATERIAL *materials, DWORD num_materials, const D3DXEFFECTINSTANCE *effects)
+{
+ int i;
+ static const struct {
+ const char *name;
+ DWORD name_size;
+ DWORD num_bytes;
+ DWORD value_offset;
+ } params[] = {
+#define EFFECT_TABLE_ENTRY(str, field) \
+ {str, sizeof(str), sizeof(materials->MatD3D.field), offsetof(D3DXMATERIAL, MatD3D.field)}
+ EFFECT_TABLE_ENTRY("Diffuse", Diffuse),
+ EFFECT_TABLE_ENTRY("Power", Power),
+ EFFECT_TABLE_ENTRY("Specular", Specular),
+ EFFECT_TABLE_ENTRY("Emissive", Emissive),
+ EFFECT_TABLE_ENTRY("Ambient", Ambient),
+#undef EFFECT_TABLE_ENTRY
+ };
+
+ if (!num_materials) {
+ ok_(__FILE__, line)(effects == NULL, "Expected NULL effects, got %p\n", effects);
+ return;
+ }
+ for (i = 0; i < num_materials; i++)
+ {
+ int j;
+ DWORD expected_num_defaults = ARRAY_SIZE(params) + (materials[i].pTextureFilename ? 1 : 0);
+
+ ok_(__FILE__,line)(expected_num_defaults == effects[i].NumDefaults,
+ "effect[%u] NumDefaults: Expected %u, got %u\n", i,
+ expected_num_defaults, effects[i].NumDefaults);
+ for (j = 0; j < min(ARRAY_SIZE(params), effects[i].NumDefaults); j++)
+ {
+ int k;
+ D3DXEFFECTDEFAULT *got_param = &effects[i].pDefaults[j];
+ ok_(__FILE__,line)(!strcmp(params[j].name, got_param->pParamName),
+ "effect[%u].pDefaults[%u].pParamName: Expected '%s', got '%s'\n", i, j,
+ params[j].name, got_param->pParamName);
+ ok_(__FILE__,line)(D3DXEDT_FLOATS == got_param->Type,
+ "effect[%u].pDefaults[%u].Type: Expected %u, got %u\n", i, j,
+ D3DXEDT_FLOATS, got_param->Type);
+ ok_(__FILE__,line)(params[j].num_bytes == got_param->NumBytes,
+ "effect[%u].pDefaults[%u].NumBytes: Expected %u, got %u\n", i, j,
+ params[j].num_bytes, got_param->NumBytes);
+ for (k = 0; k < min(params[j].num_bytes, got_param->NumBytes) / 4; k++)
+ {
+ FLOAT expected = ((FLOAT*)((BYTE*)&materials[i] + params[j].value_offset))[k];
+ FLOAT got = ((FLOAT*)got_param->pValue)[k];
+ ok_(__FILE__,line)(compare(expected, got),
+ "effect[%u].pDefaults[%u] float value %u: Expected %g, got %g\n", i, j, k, expected, got);
+ }
+ }
+ if (effects[i].NumDefaults > ARRAY_SIZE(params)) {
+ D3DXEFFECTDEFAULT *got_param = &effects[i].pDefaults[j];
+ static const char *expected_name = "Texture0@Name";
+
+ ok_(__FILE__,line)(!strcmp(expected_name, got_param->pParamName),
+ "effect[%u].pDefaults[%u].pParamName: Expected '%s', got '%s'\n", i, j,
+ expected_name, got_param->pParamName);
+ ok_(__FILE__,line)(D3DXEDT_STRING == got_param->Type,
+ "effect[%u].pDefaults[%u].Type: Expected %u, got %u\n", i, j,
+ D3DXEDT_STRING, got_param->Type);
+ if (materials[i].pTextureFilename) {
+ ok_(__FILE__,line)(strlen(materials[i].pTextureFilename) + 1 == got_param->NumBytes,
+ "effect[%u] texture filename length: Expected %u, got %u\n", i,
+ (DWORD)strlen(materials[i].pTextureFilename) + 1, got_param->NumBytes);
+ ok_(__FILE__,line)(!strcmp(materials[i].pTextureFilename, got_param->pValue),
+ "effect[%u] texture filename: Expected '%s', got '%s'\n", i,
+ materials[i].pTextureFilename, (char*)got_param->pValue);
+ }
+ }
+ }
+}
+
+static char *strdupA(const char *p)
+{
+ char *ret;
+ if (!p) return NULL;
+ ret = HeapAlloc(GetProcessHeap(), 0, strlen(p) + 1);
+ if (ret) strcpy(ret, p);
+ return ret;
+}
+
+static HRESULT CALLBACK ID3DXAllocateHierarchyImpl_DestroyFrame(ID3DXAllocateHierarchy *iface, LPD3DXFRAME frame)
+{
+ TRACECALLBACK("ID3DXAllocateHierarchyImpl_DestroyFrame(%p, %p)\n", iface, frame);
+ if (frame) {
+ HeapFree(GetProcessHeap(), 0, frame->Name);
+ HeapFree(GetProcessHeap(), 0, frame);
+ }
+ return D3D_OK;
+}
+
+static HRESULT CALLBACK ID3DXAllocateHierarchyImpl_CreateFrame(ID3DXAllocateHierarchy *iface,
+ const char *name, D3DXFRAME **new_frame)
+{
+ D3DXFRAME *frame;
+
+ TRACECALLBACK("ID3DXAllocateHierarchyImpl_CreateFrame(%p, '%s', %p)\n", iface, name, new_frame);
+ frame = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*frame));
+ if (!frame)
+ return E_OUTOFMEMORY;
+ if (name) {
+ frame->Name = strdupA(name);
+ if (!frame->Name) {
+ HeapFree(GetProcessHeap(), 0, frame);
+ return E_OUTOFMEMORY;
+ }
+ }
+ *new_frame = frame;
+ return D3D_OK;
+}
+
+static HRESULT destroy_mesh_container(LPD3DXMESHCONTAINER mesh_container)
+{
+ int i;
+
+ if (!mesh_container)
+ return D3D_OK;
+ HeapFree(GetProcessHeap(), 0, mesh_container->Name);
+ if (U(mesh_container->MeshData).pMesh)
+ IUnknown_Release(U(mesh_container->MeshData).pMesh);
+ if (mesh_container->pMaterials) {
+ for (i = 0; i < mesh_container->NumMaterials; i++)
+ HeapFree(GetProcessHeap(), 0, mesh_container->pMaterials[i].pTextureFilename);
+ HeapFree(GetProcessHeap(), 0, mesh_container->pMaterials);
+ }
+ if (mesh_container->pEffects) {
+ for (i = 0; i < mesh_container->NumMaterials; i++) {
+ HeapFree(GetProcessHeap(), 0, mesh_container->pEffects[i].pEffectFilename);
+ if (mesh_container->pEffects[i].pDefaults) {
+ int j;
+ for (j = 0; j < mesh_container->pEffects[i].NumDefaults; j++) {
+ HeapFree(GetProcessHeap(), 0, mesh_container->pEffects[i].pDefaults[j].pParamName);
+ HeapFree(GetProcessHeap(), 0, mesh_container->pEffects[i].pDefaults[j].pValue);
+ }
+ HeapFree(GetProcessHeap(), 0, mesh_container->pEffects[i].pDefaults);
+ }
+ }
+ HeapFree(GetProcessHeap(), 0, mesh_container->pEffects);
+ }
+ HeapFree(GetProcessHeap(), 0, mesh_container->pAdjacency);
+ if (mesh_container->pSkinInfo)
+ IUnknown_Release(mesh_container->pSkinInfo);
+ HeapFree(GetProcessHeap(), 0, mesh_container);
+ return D3D_OK;
+}
+
+static HRESULT CALLBACK ID3DXAllocateHierarchyImpl_DestroyMeshContainer(ID3DXAllocateHierarchy *iface, LPD3DXMESHCONTAINER mesh_container)
+{
+ TRACECALLBACK("ID3DXAllocateHierarchyImpl_DestroyMeshContainer(%p, %p)\n", iface, mesh_container);
+ return destroy_mesh_container(mesh_container);
+}
+
+static HRESULT CALLBACK ID3DXAllocateHierarchyImpl_CreateMeshContainer(ID3DXAllocateHierarchy *iface,
+ const char *name, const D3DXMESHDATA *mesh_data, const D3DXMATERIAL *materials,
+ const D3DXEFFECTINSTANCE *effects, DWORD num_materials, const DWORD *adjacency,
+ ID3DXSkinInfo *skin_info, D3DXMESHCONTAINER **new_mesh_container)
+{
+ LPD3DXMESHCONTAINER mesh_container = NULL;
+ int i;
+
+ TRACECALLBACK("ID3DXAllocateHierarchyImpl_CreateMeshContainer(%p, '%s', %u, %p, %p, %p, %d, %p, %p, %p)\n",
+ iface, name, mesh_data->Type, U(*mesh_data).pMesh, materials, effects,
+ num_materials, adjacency, skin_info, *new_mesh_container);
+
+ mesh_container = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*mesh_container));
+ if (!mesh_container)
+ return E_OUTOFMEMORY;
+
+ if (name) {
+ mesh_container->Name = strdupA(name);
+ if (!mesh_container->Name)
+ goto error;
+ }
+
+ mesh_container->NumMaterials = num_materials;
+ if (num_materials) {
+ mesh_container->pMaterials = HeapAlloc(GetProcessHeap(), 0, num_materials * sizeof(*materials));
+ if (!mesh_container->pMaterials)
+ goto error;
+
+ memcpy(mesh_container->pMaterials, materials, num_materials * sizeof(*materials));
+ for (i = 0; i < num_materials; i++)
+ mesh_container->pMaterials[i].pTextureFilename = NULL;
+ for (i = 0; i < num_materials; i++) {
+ if (materials[i].pTextureFilename) {
+ mesh_container->pMaterials[i].pTextureFilename = strdupA(materials[i].pTextureFilename);
+ if (!mesh_container->pMaterials[i].pTextureFilename)
+ goto error;
+ }
+ }
+
+ mesh_container->pEffects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, num_materials * sizeof(*effects));
+ if (!mesh_container->pEffects)
+ goto error;
+ for (i = 0; i < num_materials; i++) {
+ int j;
+ const D3DXEFFECTINSTANCE *effect_src = &effects[i];
+ D3DXEFFECTINSTANCE *effect_dest = &mesh_container->pEffects[i];
+
+ if (effect_src->pEffectFilename) {
+ effect_dest->pEffectFilename = strdupA(effect_src->pEffectFilename);
+ if (!effect_dest->pEffectFilename)
+ goto error;
+ }
+ effect_dest->pDefaults = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ effect_src->NumDefaults * sizeof(*effect_src->pDefaults));
+ if (!effect_dest->pDefaults)
+ goto error;
+ effect_dest->NumDefaults = effect_src->NumDefaults;
+ for (j = 0; j < effect_src->NumDefaults; j++) {
+ const D3DXEFFECTDEFAULT *default_src = &effect_src->pDefaults[j];
+ D3DXEFFECTDEFAULT *default_dest = &effect_dest->pDefaults[j];
+
+ if (default_src->pParamName) {
+ default_dest->pParamName = strdupA(default_src->pParamName);
+ if (!default_dest->pParamName)
+ goto error;
+ }
+ default_dest->NumBytes = default_src->NumBytes;
+ default_dest->Type = default_src->Type;
+ default_dest->pValue = HeapAlloc(GetProcessHeap(), 0, default_src->NumBytes);
+ memcpy(default_dest->pValue, default_src->pValue, default_src->NumBytes);
+ }
+ }
+ }
+
+ ok(adjacency != NULL, "Expected non-NULL adjacency, got NULL\n");
+ if (adjacency) {
+ if (mesh_data->Type == D3DXMESHTYPE_MESH || mesh_data->Type == D3DXMESHTYPE_PMESH) {
+ ID3DXBaseMesh *basemesh = (ID3DXBaseMesh*)U(*mesh_data).pMesh;
+ DWORD num_faces = basemesh->lpVtbl->GetNumFaces(basemesh);
+ size_t size = num_faces * sizeof(DWORD) * 3;
+ mesh_container->pAdjacency = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!mesh_container->pAdjacency)
+ goto error;
+ memcpy(mesh_container->pAdjacency, adjacency, size);
+ } else {
+ ok(mesh_data->Type == D3DXMESHTYPE_PATCHMESH, "Unknown mesh type %u\n", mesh_data->Type);
+ if (mesh_data->Type == D3DXMESHTYPE_PATCHMESH)
+ trace("FIXME: copying adjacency data for patch mesh not implemented\n");
+ }
+ }
+
+ memcpy(&mesh_container->MeshData, mesh_data, sizeof(*mesh_data));
+ if (U(*mesh_data).pMesh)
+ IUnknown_AddRef(U(*mesh_data).pMesh);
+ if (skin_info) {
+ mesh_container->pSkinInfo = skin_info;
+ skin_info->lpVtbl->AddRef(skin_info);
+ }
+ *new_mesh_container = mesh_container;
+
+ return S_OK;
+error:
+ destroy_mesh_container(mesh_container);
+ return E_OUTOFMEMORY;
+}
+
+static ID3DXAllocateHierarchyVtbl ID3DXAllocateHierarchyImpl_Vtbl = {
+ ID3DXAllocateHierarchyImpl_CreateFrame,
+ ID3DXAllocateHierarchyImpl_CreateMeshContainer,
+ ID3DXAllocateHierarchyImpl_DestroyFrame,
+ ID3DXAllocateHierarchyImpl_DestroyMeshContainer,
+};
+static ID3DXAllocateHierarchy alloc_hier = { &ID3DXAllocateHierarchyImpl_Vtbl };
+
+#define test_LoadMeshFromX(device, xfile_str, vertex_array, fvf, index_array, materials_array, check_adjacency) \
+ test_LoadMeshFromX_(__LINE__, device, xfile_str, sizeof(xfile_str) - 1, vertex_array, ARRAY_SIZE(vertex_array), fvf, \
+ index_array, ARRAY_SIZE(index_array), sizeof(*index_array), materials_array, ARRAY_SIZE(materials_array), \
+ check_adjacency);
+static void test_LoadMeshFromX_(int line, IDirect3DDevice9 *device, const char *xfile_str, size_t xfile_strlen,
+ const void *vertices, DWORD num_vertices, DWORD fvf, const void *indices, DWORD num_indices, size_t index_size,
+ const D3DXMATERIAL *expected_materials, DWORD expected_num_materials, BOOL check_adjacency)
+{
+ HRESULT hr;
+ ID3DXBuffer *materials = NULL;
+ ID3DXBuffer *effects = NULL;
+ ID3DXBuffer *adjacency = NULL;
+ ID3DXMesh *mesh = NULL;
+ DWORD num_materials = 0;
+
+ /* Adjacency is not checked when the X file contains multiple meshes,
+ * since calling GenerateAdjacency on the merged mesh is not equivalent
+ * to calling GenerateAdjacency on the individual meshes and then merging
+ * the adjacency data. */
+ hr = D3DXLoadMeshFromXInMemory(xfile_str, xfile_strlen, D3DXMESH_MANAGED, device,
+ check_adjacency ? &adjacency : NULL, &materials, &effects, &num_materials, &mesh);
+ ok_(__FILE__,line)(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr)) {
+ D3DXMATERIAL *materials_ptr = materials ? ID3DXBuffer_GetBufferPointer(materials) : NULL;
+ D3DXEFFECTINSTANCE *effects_ptr = effects ? ID3DXBuffer_GetBufferPointer(effects) : NULL;
+ DWORD *adjacency_ptr = check_adjacency ? ID3DXBuffer_GetBufferPointer(adjacency) : NULL;
+
+ check_vertex_buffer_(line, mesh, vertices, num_vertices, fvf);
+ check_index_buffer_(line, mesh, indices, num_indices, index_size);
+ check_materials_(line, materials_ptr, num_materials, expected_materials, expected_num_materials);
+ check_generated_effects_(line, materials_ptr, num_materials, effects_ptr);
+ if (check_adjacency)
+ check_generated_adjacency_(line, mesh, adjacency_ptr, 0.0f);
+
+ if (materials) ID3DXBuffer_Release(materials);
+ if (effects) ID3DXBuffer_Release(effects);
+ if (adjacency) ID3DXBuffer_Release(adjacency);
+ IUnknown_Release(mesh);
+ }
+}
+
+static void D3DXLoadMeshTest(void)
+{
+ static const char empty_xfile[] = "xof 0303txt 0032";
+ /*________________________*/
+ static const char simple_xfile[] =
+ "xof 0303txt 0032"
+ "Mesh {"
+ "3;"
+ "0.0; 0.0; 0.0;,"
+ "0.0; 1.0; 0.0;,"
+ "1.0; 1.0; 0.0;;"
+ "1;"
+ "3; 0, 1, 2;;"
+ "}";
+ static const WORD simple_index_buffer[] = {0, 1, 2};
+ static const D3DXVECTOR3 simple_vertex_buffer[] = {
+ {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}
+ };
+ const DWORD simple_fvf = D3DFVF_XYZ;
+ static const char framed_xfile[] =
+ "xof 0303txt 0032"
+ "Frame {"
+ "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 1.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
+ "FrameTransformMatrix {" /* translation (0.0, 0.0, 2.0) */
+ "1.0, 0.0, 0.0, 0.0,"
+ "0.0, 1.0, 0.0, 0.0,"
+ "0.0, 0.0, 1.0, 0.0,"
+ "0.0, 0.0, 2.0, 1.0;;"
+ "}"
+ "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 2.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
+ "FrameTransformMatrix {" /* translation (0.0, 0.0, 3.0) */
+ "1.0, 0.0, 0.0, 0.0,"
+ "0.0, 1.0, 0.0, 0.0,"
+ "0.0, 0.0, 1.0, 0.0,"
+ "0.0, 0.0, 3.0, 1.0;;"
+ "}"
+ "Mesh { 3; 0.0; 0.0; 0.0;, 0.0; 1.0; 0.0;, 3.0; 1.0; 0.0;; 1; 3; 0, 1, 2;; }"
+ "}";
+ static const WORD framed_index_buffer[] = { 0, 1, 2 };
+ static const D3DXVECTOR3 framed_vertex_buffers[3][3] = {
+ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0}},
+ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {2.0, 1.0, 0.0}},
+ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {3.0, 1.0, 0.0}},
+ };
+ static const WORD merged_index_buffer[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
+ /* frame transforms accumulates for D3DXLoadMeshFromX */
+ static const D3DXVECTOR3 merged_vertex_buffer[] = {
+ {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 1.0, 0.0},
+ {0.0, 0.0, 2.0}, {0.0, 1.0, 2.0}, {2.0, 1.0, 2.0},
+ {0.0, 0.0, 5.0}, {0.0, 1.0, 5.0}, {3.0, 1.0, 5.0},
+ };
+ const DWORD framed_fvf = D3DFVF_XYZ;
+ /*________________________*/
+ static const char box_xfile[] =
+ "xof 0303txt 0032"
+ "Mesh {"
+ "8;" /* DWORD nVertices; */
+ /* array Vector vertices[nVertices]; */
+ "0.0; 0.0; 0.0;,"
+ "0.0; 0.0; 1.0;,"
+ "0.0; 1.0; 0.0;,"
+ "0.0; 1.0; 1.0;,"
+ "1.0; 0.0; 0.0;,"
+ "1.0; 0.0; 1.0;,"
+ "1.0; 1.0; 0.0;,"
+ "1.0; 1.0; 1.0;;"
+ "6;" /* DWORD nFaces; */
+ /* array MeshFace faces[nFaces]; */
+ "4; 0, 1, 3, 2;," /* (left side) */
+ "4; 2, 3, 7, 6;," /* (top side) */
+ "4; 6, 7, 5, 4;," /* (right side) */
+ "4; 1, 0, 4, 5;," /* (bottom side) */
+ "4; 1, 5, 7, 3;," /* (back side) */
+ "4; 0, 2, 6, 4;;" /* (front side) */
+ "MeshNormals {"
+ "6;" /* DWORD nNormals; */
+ /* array Vector normals[nNormals]; */
+ "-1.0; 0.0; 0.0;,"
+ "0.0; 1.0; 0.0;,"
+ "1.0; 0.0; 0.0;,"
+ "0.0; -1.0; 0.0;,"
+ "0.0; 0.0; 1.0;,"
+ "0.0; 0.0; -1.0;;"
+ "6;" /* DWORD nFaceNormals; */
+ /* array MeshFace faceNormals[nFaceNormals]; */
+ "4; 0, 0, 0, 0;,"
+ "4; 1, 1, 1, 1;,"
+ "4; 2, 2, 2, 2;,"
+ "4; 3, 3, 3, 3;,"
+ "4; 4, 4, 4, 4;,"
+ "4; 5, 5, 5, 5;;"
+ "}"
+ "MeshMaterialList materials {"
+ "2;" /* DWORD nMaterials; */
+ "6;" /* DWORD nFaceIndexes; */
+ /* array DWORD faceIndexes[nFaceIndexes]; */
+ "0, 0, 0, 1, 1, 1;;"
+ "Material {"
+ /* ColorRGBA faceColor; */
+ "0.0; 0.0; 1.0; 1.0;;"
+ /* FLOAT power; */
+ "0.5;"
+ /* ColorRGB specularColor; */
+ "1.0; 1.0; 1.0;;"
+ /* ColorRGB emissiveColor; */
+ "0.0; 0.0; 0.0;;"
+ "}"
+ "Material {"
+ /* ColorRGBA faceColor; */
+ "1.0; 1.0; 1.0; 1.0;;"
+ /* FLOAT power; */
+ "1.0;"
+ /* ColorRGB specularColor; */
+ "1.0; 1.0; 1.0;;"
+ /* ColorRGB emissiveColor; */
+ "0.0; 0.0; 0.0;;"
+ "TextureFilename { \"texture.jpg\"; }"
+ "}"
+ "}"
+ "MeshVertexColors {"
+ "8;" /* DWORD nVertexColors; */
+ /* array IndexedColor vertexColors[nVertexColors]; */
+ "0; 0.0; 0.0; 0.0; 0.0;;"
+ "1; 0.0; 0.0; 1.0; 0.1;;"
+ "2; 0.0; 1.0; 0.0; 0.2;;"
+ "3; 0.0; 1.0; 1.0; 0.3;;"
+ "4; 1.0; 0.0; 0.0; 0.4;;"
+ "5; 1.0; 0.0; 1.0; 0.5;;"
+ "6; 1.0; 1.0; 0.0; 0.6;;"
+ "7; 1.0; 1.0; 1.0; 0.7;;"
+ "}"
+ "MeshTextureCoords {"
+ "8;" /* DWORD nTextureCoords; */
+ /* array Coords2d textureCoords[nTextureCoords]; */
+ "0.0; 1.0;,"
+ "1.0; 1.0;,"
+ "0.0; 0.0;,"
+ "1.0; 0.0;,"
+ "1.0; 1.0;,"
+ "0.0; 1.0;,"
+ "1.0; 0.0;,"
+ "0.0; 0.0;;"
+ "}"
+ "}";
+ static const WORD box_index_buffer[] = {
+ 0, 1, 3,
+ 0, 3, 2,
+ 8, 9, 7,
+ 8, 7, 6,
+ 10, 11, 5,
+ 10, 5, 4,
+ 12, 13, 14,
+ 12, 14, 15,
+ 16, 17, 18,
+ 16, 18, 19,
+ 20, 21, 22,
+ 20, 22, 23,
+ };
+ static const struct {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ D3DCOLOR diffuse;
+ D3DXVECTOR2 tex_coords;
+ } box_vertex_buffer[] = {
+ {{0.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, 0x00000000, {0.0, 1.0}},
+ {{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, 0x1a0000ff, {1.0, 1.0}},
+ {{0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, 0x3300ff00, {0.0, 0.0}},
+ {{0.0, 1.0, 1.0}, {-1.0, 0.0, 0.0}, 0x4d00ffff, {1.0, 0.0}},
+ {{1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, 0x66ff0000, {1.0, 1.0}},
+ {{1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, 0x80ff00ff, {0.0, 1.0}},
+ {{1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, 0x99ffff00, {1.0, 0.0}},
+ {{1.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, 0xb3ffffff, {0.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, 0x3300ff00, {0.0, 0.0}},
+ {{0.0, 1.0, 1.0}, {0.0, 1.0, 0.0}, 0x4d00ffff, {1.0, 0.0}},
+ {{1.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, 0x99ffff00, {1.0, 0.0}},
+ {{1.0, 1.0, 1.0}, {1.0, 0.0, 0.0}, 0xb3ffffff, {0.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, 0x1a0000ff, {1.0, 1.0}},
+ {{0.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, 0x00000000, {0.0, 1.0}},
+ {{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, 0x66ff0000, {1.0, 1.0}},
+ {{1.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, 0x80ff00ff, {0.0, 1.0}},
+ {{0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, 0x1a0000ff, {1.0, 1.0}},
+ {{1.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, 0x80ff00ff, {0.0, 1.0}},
+ {{1.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, 0xb3ffffff, {0.0, 0.0}},
+ {{0.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, 0x4d00ffff, {1.0, 0.0}},
+ {{0.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, 0x00000000, {0.0, 1.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, 0x3300ff00, {0.0, 0.0}},
+ {{1.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, 0x99ffff00, {1.0, 0.0}},
+ {{1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, 0x66ff0000, {1.0, 1.0}},
+ };
+ static const D3DXMATERIAL box_materials[] = {
+ {
+ {
+ {0.0, 0.0, 1.0, 1.0}, /* Diffuse */
+ {0.0, 0.0, 0.0, 1.0}, /* Ambient */
+ {1.0, 1.0, 1.0, 1.0}, /* Specular */
+ {0.0, 0.0, 0.0, 1.0}, /* Emissive */
+ 0.5, /* Power */
+ },
+ NULL, /* pTextureFilename */
+ },
+ {
+ {
+ {1.0, 1.0, 1.0, 1.0}, /* Diffuse */
+ {0.0, 0.0, 0.0, 1.0}, /* Ambient */
+ {1.0, 1.0, 1.0, 1.0}, /* Specular */
+ {0.0, 0.0, 0.0, 1.0}, /* Emissive */
+ 1.0, /* Power */
+ },
+ (char *)"texture.jpg", /* pTextureFilename */
+ },
+ };
+ static const char box_anim_xfile[] =
+ "xof 0303txt 0032"
+ "Mesh CubeMesh {"
+ "8;" /* DWORD nVertices; */
+ /* array Vector vertices[nVertices]; */
+ "0.0; 0.0; 0.0;,"
+ "0.0; 0.0; 1.0;,"
+ "0.0; 1.0; 0.0;,"
+ "0.0; 1.0; 1.0;,"
+ "1.0; 0.0; 0.0;,"
+ "1.0; 0.0; 1.0;,"
+ "1.0; 1.0; 0.0;,"
+ "1.0; 1.0; 1.0;;"
+ "6;" /* DWORD nFaces; */
+ /* array MeshFace faces[nFaces]; */
+ "4; 0, 1, 3, 2;," /* left side */
+ "4; 2, 3, 7, 6;," /* top side */
+ "4; 6, 7, 5, 4;," /* right side */
+ "4; 1, 0, 4, 5;," /* bottom side */
+ "4; 1, 5, 7, 3;," /* back side */
+ "4; 0, 2, 6, 4;;" /* front side */
+ "MeshNormals {"
+ "6;" /* DWORD nNormals; */
+ /* array Vector normals[nNormals]; */
+ "-1.0; 0.0; 0.0;,"
+ "0.0; 1.0; 0.0;,"
+ "1.0; 0.0; 0.0;,"
+ "0.0; -1.0; 0.0;,"
+ "0.0; 0.0; 1.0;,"
+ "0.0; 0.0; -1.0;;"
+ "6;" /* DWORD nFaceNormals; */
+ /* array MeshFace faceNormals[nFaceNormals]; */
+ "4; 0, 0, 0, 0;,"
+ "4; 1, 1, 1, 1;,"
+ "4; 2, 2, 2, 2;,"
+ "4; 3, 3, 3, 3;,"
+ "4; 4, 4, 4, 4;,"
+ "4; 5, 5, 5, 5;;"
+ "}"
+ "MeshMaterialList materials {"
+ "2;" /* DWORD nMaterials; */
+ "6;" /* DWORD nFaceIndexes; */
+ /* array DWORD faceIndexes[nFaceIndexes]; */
+ "0, 0, 0, 1, 1, 1;;"
+ "Material {"
+ /* ColorRGBA faceColor; */
+ "0.0; 0.0; 1.0; 1.0;;"
+ /* FLOAT power; */
+ "0.5;"
+ /* ColorRGB specularColor; */
+ "1.0; 1.0; 1.0;;"
+ /* ColorRGB emissiveColor; */
+ "0.0; 0.0; 0.0;;"
+ "}"
+ "Material {"
+ /* ColorRGBA faceColor; */
+ "1.0; 1.0; 1.0; 1.0;;"
+ /* FLOAT power; */
+ "1.0;"
+ /* ColorRGB specularColor; */
+ "1.0; 1.0; 1.0;;"
+ /* ColorRGB emissiveColor; */
+ "0.0; 0.0; 0.0;;"
+ "TextureFilename { \"texture.jpg\"; }"
+ "}"
+ "}"
+ "MeshVertexColors {"
+ "8;" /* DWORD nVertexColors; */
+ /* array IndexedColor vertexColors[nVertexColors]; */
+ "0; 0.0; 0.0; 0.0; 0.0;;"
+ "1; 0.0; 0.0; 1.0; 0.1;;"
+ "2; 0.0; 1.0; 0.0; 0.2;;"
+ "3; 0.0; 1.0; 1.0; 0.3;;"
+ "4; 1.0; 0.0; 0.0; 0.4;;"
+ "5; 1.0; 0.0; 1.0; 0.5;;"
+ "6; 1.0; 1.0; 0.0; 0.6;;"
+ "7; 1.0; 1.0; 1.0; 0.7;;"
+ "}"
+ "MeshTextureCoords {"
+ "8;" /* DWORD nTextureCoords; */
+ /* array Coords2d textureCoords[nTextureCoords]; */
+ "0.0; 1.0;,"
+ "1.0; 1.0;,"
+ "0.0; 0.0;,"
+ "1.0; 0.0;,"
+ "1.0; 1.0;,"
+ "0.0; 1.0;,"
+ "1.0; 0.0;,"
+ "0.0; 0.0;;"
+ "}"
+ "}"
+ "Frame CubeFrame {"
+ "FrameTransformMatrix {"
+ /* Matrix4x4 frameMatrix; */
+ "1.0, 0.0, 0.0, 0.0,"
+ "0.0, 1.0, 0.0, 0.0,"
+ "0.0, 0.0, 1.0, 0.0,"
+ "0.0, 0.0, 0.0, 1.0;;"
+ "}"
+ "{CubeMesh}"
+ "}"
+ "AnimationSet AnimationSet0 {"
+ "Animation Animation0 {"
+ "{CubeFrame}"
+ "AnimationKey {"
+ "2;" /* DWORD keyType; */
+ "9;" /* DWORD nKeys; */
+ /* array TimedFloatKeys keys[nKeys]; */
+ "10; 3; -100.0, 0.0, 0.0;;,"
+ "20; 3; -75.0, 0.0, 0.0;;,"
+ "30; 3; -50.0, 0.0, 0.0;;,"
+ "40; 3; -25.5, 0.0, 0.0;;,"
+ "50; 3; 0.0, 0.0, 0.0;;,"
+ "60; 3; 25.5, 0.0, 0.0;;,"
+ "70; 3; 50.0, 0.0, 0.0;;,"
+ "80; 3; 75.5, 0.0, 0.0;;,"
+ "90; 3; 100.0, 0.0, 0.0;;;"
+ "}"
+ "}"
+ "}";
+
+ const DWORD box_fvf = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1;
+ /*________________________*/
+ static const D3DXMATERIAL default_materials[] = {
+ {
+ {
+ {0.5, 0.5, 0.5, 0.0}, /* Diffuse */
+ {0.0, 0.0, 0.0, 0.0}, /* Ambient */
+ {0.5, 0.5, 0.5, 0.0}, /* Specular */
+ {0.0, 0.0, 0.0, 0.0}, /* Emissive */
+ 0.0, /* Power */
+ },
+ NULL, /* pTextureFilename */
+ }
+ };
+ HRESULT hr;
+ IDirect3DDevice9 *device = NULL;
+ ID3DXMesh *mesh = NULL;
+ D3DXFRAME *frame_hier = NULL;
+ D3DXMATRIX transform;
+ struct test_context *test_context;
+ ID3DXAnimationController *controller;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(NULL, sizeof(simple_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, 0,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1,
+ D3DXMESH_MANAGED, NULL, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1,
+ D3DXMESH_MANAGED, device, NULL, NULL, &frame_hier, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(empty_xfile, sizeof(empty_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == E_FAIL, "Expected E_FAIL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr)) {
+ D3DXMESHCONTAINER *container = frame_hier->pMeshContainer;
+
+ ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name);
+ D3DXMatrixIdentity(&transform);
+ check_matrix(&frame_hier->TransformationMatrix, &transform);
+
+ ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name);
+ ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n",
+ D3DXMESHTYPE_MESH, container->MeshData.Type);
+ mesh = U(container->MeshData).pMesh;
+ check_vertex_buffer(mesh, simple_vertex_buffer, ARRAY_SIZE(simple_vertex_buffer), simple_fvf);
+ check_index_buffer(mesh, simple_index_buffer, ARRAY_SIZE(simple_index_buffer), sizeof(*simple_index_buffer));
+ check_materials(container->pMaterials, container->NumMaterials, NULL, 0);
+ check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects);
+ check_generated_adjacency(mesh, container->pAdjacency, 0.0f);
+ hr = D3DXFrameDestroy(frame_hier, &alloc_hier);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ frame_hier = NULL;
+ }
+
+ controller = (ID3DXAnimationController *)0xdeadbeef;
+ hr = D3DXLoadMeshHierarchyFromXInMemory(box_anim_xfile, sizeof(box_anim_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, &controller);
+ todo_wine ok(hr == D3D_OK, "Expected D3D_OK, got %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(controller != NULL, "Animation Controller NULL.\n");
+
+ hr = D3DXFrameDestroy(frame_hier, &alloc_hier);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x.\n", hr);
+ if (controller)
+ controller->lpVtbl->Release(controller);
+
+ frame_hier = NULL;
+ }
+
+ controller = (ID3DXAnimationController *)0xdeadbeef;
+ hr = D3DXLoadMeshHierarchyFromXInMemory(box_xfile, sizeof(box_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, &controller);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ D3DXMESHCONTAINER *container = frame_hier->pMeshContainer;
+
+ ok(!controller, "Animation Controller returned.\n");
+ ok(frame_hier->Name == NULL, "Expected NULL, got '%s'\n", frame_hier->Name);
+ D3DXMatrixIdentity(&transform);
+ check_matrix(&frame_hier->TransformationMatrix, &transform);
+
+ ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name);
+ ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n",
+ D3DXMESHTYPE_MESH, container->MeshData.Type);
+ mesh = U(container->MeshData).pMesh;
+ check_vertex_buffer(mesh, box_vertex_buffer, ARRAY_SIZE(box_vertex_buffer), box_fvf);
+ check_index_buffer(mesh, box_index_buffer, ARRAY_SIZE(box_index_buffer), sizeof(*box_index_buffer));
+ check_materials(container->pMaterials, container->NumMaterials, box_materials, ARRAY_SIZE(box_materials));
+ check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects);
+ check_generated_adjacency(mesh, container->pAdjacency, 0.0f);
+ hr = D3DXFrameDestroy(frame_hier, &alloc_hier);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ frame_hier = NULL;
+ }
+
+ hr = D3DXLoadMeshHierarchyFromXInMemory(framed_xfile, sizeof(framed_xfile) - 1,
+ D3DXMESH_MANAGED, device, &alloc_hier, NULL, &frame_hier, NULL);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr)) {
+ D3DXMESHCONTAINER *container = frame_hier->pMeshContainer;
+ int i;
+
+ ok(!strcmp(frame_hier->Name, ""), "Expected '', got '%s'\n", frame_hier->Name);
+ /* last frame transform replaces the first */
+ D3DXMatrixIdentity(&transform);
+ U(transform).m[3][2] = 3.0;
+ check_matrix(&frame_hier->TransformationMatrix, &transform);
+
+ for (i = 0; i < 3; i++) {
+ ok(!strcmp(container->Name, ""), "Expected '', got '%s'\n", container->Name);
+ ok(container->MeshData.Type == D3DXMESHTYPE_MESH, "Expected %d, got %d\n",
+ D3DXMESHTYPE_MESH, container->MeshData.Type);
+ mesh = U(container->MeshData).pMesh;
+ check_vertex_buffer(mesh, framed_vertex_buffers[i], ARRAY_SIZE(framed_vertex_buffers[0]), framed_fvf);
+ check_index_buffer(mesh, framed_index_buffer, ARRAY_SIZE(framed_index_buffer), sizeof(*framed_index_buffer));
+ check_materials(container->pMaterials, container->NumMaterials, NULL, 0);
+ check_generated_effects(container->pMaterials, container->NumMaterials, container->pEffects);
+ check_generated_adjacency(mesh, container->pAdjacency, 0.0f);
+ container = container->pNextMeshContainer;
+ }
+ ok(container == NULL, "Expected NULL, got %p\n", container);
+ hr = D3DXFrameDestroy(frame_hier, &alloc_hier);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ frame_hier = NULL;
+ }
+
+
+ hr = D3DXLoadMeshFromXInMemory(NULL, 0, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(NULL, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(simple_xfile, 0, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED,
+ NULL, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(empty_xfile, sizeof(empty_xfile) - 1, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == E_FAIL, "Expected E_FAIL, got %#x\n", hr);
+
+ hr = D3DXLoadMeshFromXInMemory(simple_xfile, sizeof(simple_xfile) - 1, D3DXMESH_MANAGED,
+ device, NULL, NULL, NULL, NULL, &mesh);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr))
+ IUnknown_Release(mesh);
+
+ test_LoadMeshFromX(device, simple_xfile, simple_vertex_buffer, simple_fvf, simple_index_buffer, default_materials, TRUE);
+ test_LoadMeshFromX(device, box_xfile, box_vertex_buffer, box_fvf, box_index_buffer, box_materials, TRUE);
+ test_LoadMeshFromX(device, framed_xfile, merged_vertex_buffer, framed_fvf, merged_index_buffer, default_materials, FALSE);
+
+ free_test_context(test_context);
+}
+
+static BOOL compute_box(struct mesh *mesh, float width, float height, float depth)
+{
+ unsigned int i, face;
+ static const D3DXVECTOR3 unit_box[] =
+ {
+ {-1.0f, -1.0f, -1.0f}, {-1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, -1.0f},
+ {-1.0f, 1.0f, -1.0f}, {-1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, -1.0f},
+ { 1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, -1.0f},
+ {-1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}, { 1.0f, -1.0f, 1.0f},
+ {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f},
+ {-1.0f, -1.0f, -1.0f}, {-1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f, -1.0f}, { 1.0f, -1.0f, -1.0f}
+ };
+ static const D3DXVECTOR3 normals[] =
+ {
+ {-1.0f, 0.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f},
+ { 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, -1.0f}
+ };
+
+ if (!new_mesh(mesh, 24, 12))
+ {
+ return FALSE;
+ }
+
+ width /= 2.0f;
+ height /= 2.0f;
+ depth /= 2.0f;
+
+ for (i = 0; i < 24; i++)
+ {
+ mesh->vertices[i].position.x = width * unit_box[i].x;
+ mesh->vertices[i].position.y = height * unit_box[i].y;
+ mesh->vertices[i].position.z = depth * unit_box[i].z;
+ mesh->vertices[i].normal.x = normals[i / 4].x;
+ mesh->vertices[i].normal.y = normals[i / 4].y;
+ mesh->vertices[i].normal.z = normals[i / 4].z;
+ }
+
+ face = 0;
+ for (i = 0; i < 12; i++)
+ {
+ mesh->faces[i][0] = face++;
+ mesh->faces[i][1] = face++;
+ mesh->faces[i][2] = (i % 2) ? face - 4 : face;
+ }
+
+ return TRUE;
+}
+
+static void test_box(IDirect3DDevice9 *device, float width, float height, float depth)
+{
+ HRESULT hr;
+ ID3DXMesh *box;
+ struct mesh mesh;
+ char name[256];
+
+ hr = D3DXCreateBox(device, width, height, depth, &box, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't create box\n");
+ return;
+ }
+
+ if (!compute_box(&mesh, width, height, depth))
+ {
+ skip("Couldn't create mesh\n");
+ box->lpVtbl->Release(box);
+ return;
+ }
+
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ sprintf(name, "box (%g, %g, %g)", width, height, depth);
+ compare_mesh(name, box, &mesh);
+
+ free_mesh(&mesh);
+
+ box->lpVtbl->Release(box);
+}
+static void D3DXCreateBoxTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9* device;
+ ID3DXMesh* box;
+ ID3DXBuffer* ppBuffer;
+ DWORD *buffer;
+ static const DWORD adjacency[36]=
+ {6, 9, 1, 2, 10, 0,
+ 1, 9, 3, 4, 10, 2,
+ 3, 8, 5, 7, 11, 4,
+ 0, 11, 7, 5, 8, 6,
+ 7, 4, 9, 2, 0, 8,
+ 1, 3, 11, 5, 6, 10};
+ unsigned int i;
+ struct test_context *test_context;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateBox(device,2.0f,20.0f,4.9f,NULL, &ppBuffer);
+ ok(hr==D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreateBox(NULL,22.0f,20.0f,4.9f,&box, &ppBuffer);
+ ok(hr==D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreateBox(device,-2.0f,20.0f,4.9f,&box, &ppBuffer);
+ ok(hr==D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreateBox(device,22.0f,-20.0f,4.9f,&box, &ppBuffer);
+ ok(hr==D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreateBox(device,22.0f,20.0f,-4.9f,&box, &ppBuffer);
+ ok(hr==D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ ppBuffer = NULL;
+ hr = D3DXCreateBox(device,10.9f,20.0f,4.9f,&box, &ppBuffer);
+ ok(hr==D3D_OK, "Expected D3D_OK, received %#x\n", hr);
+
+ buffer = ID3DXBuffer_GetBufferPointer(ppBuffer);
+ for(i=0; i<36; i++)
+ ok(adjacency[i]==buffer[i], "expected adjacency %d: %#x, received %#x\n",i,adjacency[i], buffer[i]);
+
+ box->lpVtbl->Release(box);
+ ID3DXBuffer_Release(ppBuffer);
+
+ test_box(device, 10.9f, 20.0f, 4.9f);
+
+ free_test_context(test_context);
+}
+
+static BOOL compute_polygon(struct mesh *mesh, float length, unsigned int sides)
+{
+ unsigned int i;
+ float angle, scale;
+
+ if (!new_mesh(mesh, sides + 1, sides))
+ return FALSE;
+
+ angle = D3DX_PI / sides;
+ scale = 0.5f * length / sinf(angle);
+ angle *= 2.0f;
+
+ mesh->vertices[0].position.x = 0.0f;
+ mesh->vertices[0].position.y = 0.0f;
+ mesh->vertices[0].position.z = 0.0f;
+ mesh->vertices[0].normal.x = 0.0f;
+ mesh->vertices[0].normal.y = 0.0f;
+ mesh->vertices[0].normal.z = 1.0f;
+
+ for (i = 0; i < sides; ++i)
+ {
+ mesh->vertices[i + 1].position.x = cosf(angle * i) * scale;
+ mesh->vertices[i + 1].position.y = sinf(angle * i) * scale;
+ mesh->vertices[i + 1].position.z = 0.0f;
+ mesh->vertices[i + 1].normal.x = 0.0f;
+ mesh->vertices[i + 1].normal.y = 0.0f;
+ mesh->vertices[i + 1].normal.z = 1.0f;
+
+ mesh->faces[i][0] = 0;
+ mesh->faces[i][1] = i + 1;
+ mesh->faces[i][2] = i + 2;
+ }
+
+ mesh->faces[sides - 1][2] = 1;
+
+ return TRUE;
+}
+
+static void test_polygon(IDirect3DDevice9 *device, float length, unsigned int sides)
+{
+ HRESULT hr;
+ ID3DXMesh *polygon;
+ struct mesh mesh;
+ char name[64];
+
+ hr = D3DXCreatePolygon(device, length, sides, &polygon, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't create polygon\n");
+ return;
+ }
+
+ if (!compute_polygon(&mesh, length, sides))
+ {
+ skip("Couldn't create mesh\n");
+ polygon->lpVtbl->Release(polygon);
+ return;
+ }
+
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ sprintf(name, "polygon (%g, %u)", length, sides);
+ compare_mesh(name, polygon, &mesh);
+
+ free_mesh(&mesh);
+
+ polygon->lpVtbl->Release(polygon);
+}
+
+static void D3DXCreatePolygonTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9 *device;
+ ID3DXMesh *polygon;
+ ID3DXBuffer *adjacency;
+ DWORD (*buffer)[3], buffer_size;
+ unsigned int i;
+ struct test_context *test_context;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreatePolygon(device, 2.0f, 11, NULL, &adjacency);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreatePolygon(NULL, 2.0f, 11, &polygon, &adjacency);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ hr = D3DXCreatePolygon(device, -2.0f, 11, &polygon, &adjacency);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ polygon = (void *)0xdeadbeef;
+ adjacency = (void *)0xdeadbeef;
+ hr = D3DXCreatePolygon(device, 2.0f, 0, &polygon, &adjacency);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+ ok(polygon == (void *)0xdeadbeef, "Polygon was changed to %p\n", polygon);
+ ok(adjacency == (void *)0xdeadbeef, "Adjacency was changed to %p\n", adjacency);
+
+ hr = D3DXCreatePolygon(device, 2.0f, 2, &polygon, &adjacency);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr);
+
+ adjacency = NULL;
+ hr = D3DXCreatePolygon(device, 3.0f, 11, &polygon, &adjacency);
+ ok(hr == D3D_OK, "Expected D3D_OK, received %#x\n", hr);
+
+ buffer_size = ID3DXBuffer_GetBufferSize(adjacency);
+ ok(buffer_size == 33 * sizeof(DWORD), "Wrong adjacency buffer size %u\n", buffer_size);
+
+ buffer = ID3DXBuffer_GetBufferPointer(adjacency);
+ for (i = 0; i < 11; ++i)
+ {
+ ok(buffer[i][0] == (i + 10) % 11, "Wrong adjacency[%d][0] = %u\n", i, buffer[i][0]);
+ ok(buffer[i][1] == ~0U, "Wrong adjacency[%d][1] = %u\n", i, buffer[i][1]);
+ ok(buffer[i][2] == (i + 1) % 11, "Wrong adjacency[%d][2] = %u\n", i, buffer[i][2]);
+ }
+
+ polygon->lpVtbl->Release(polygon);
+ ID3DXBuffer_Release(adjacency);
+
+ test_polygon(device, 2.0f, 3);
+ test_polygon(device, 10.0f, 3);
+ test_polygon(device, 10.0f, 5);
+ test_polygon(device, 10.0f, 10);
+ test_polygon(device, 20.0f, 10);
+ test_polygon(device, 20.0f, 32000);
+
+ free_test_context(test_context);
+}
+
+struct sincos_table
+{
+ float *sin;
+ float *cos;
+};
+
+static void free_sincos_table(struct sincos_table *sincos_table)
+{
+ HeapFree(GetProcessHeap(), 0, sincos_table->cos);
+ HeapFree(GetProcessHeap(), 0, sincos_table->sin);
+}
+
+/* pre compute sine and cosine tables; caller must free */
+static BOOL compute_sincos_table(struct sincos_table *sincos_table, float angle_start, float angle_step, int n)
+{
+ float angle;
+ int i;
+
+ sincos_table->sin = HeapAlloc(GetProcessHeap(), 0, n * sizeof(*sincos_table->sin));
+ if (!sincos_table->sin)
+ {
+ return FALSE;
+ }
+ sincos_table->cos = HeapAlloc(GetProcessHeap(), 0, n * sizeof(*sincos_table->cos));
+ if (!sincos_table->cos)
+ {
+ HeapFree(GetProcessHeap(), 0, sincos_table->sin);
+ return FALSE;
+ }
+
+ angle = angle_start;
+ for (i = 0; i < n; i++)
+ {
+ sincos_table->sin[i] = sin(angle);
+ sincos_table->cos[i] = cos(angle);
+ angle += angle_step;
+ }
+
+ return TRUE;
+}
+
+static WORD vertex_index(UINT slices, int slice, int stack)
+{
+ return stack*slices+slice+1;
+}
+
+/* slices = subdivisions along xy plane, stacks = subdivisions along z axis */
+static BOOL compute_sphere(struct mesh *mesh, FLOAT radius, UINT slices, UINT stacks)
+{
+ float theta_step, theta_start;
+ struct sincos_table theta;
+ float phi_step, phi_start;
+ struct sincos_table phi;
+ DWORD number_of_vertices, number_of_faces;
+ DWORD vertex, face;
+ int slice, stack;
+
+ /* theta = angle on xy plane wrt x axis */
+ theta_step = D3DX_PI / stacks;
+ theta_start = theta_step;
+
+ /* phi = angle on xz plane wrt z axis */
+ phi_step = -2 * D3DX_PI / slices;
+ phi_start = D3DX_PI / 2;
+
+ if (!compute_sincos_table(&theta, theta_start, theta_step, stacks))
+ {
+ return FALSE;
+ }
+ if (!compute_sincos_table(&phi, phi_start, phi_step, slices))
+ {
+ free_sincos_table(&theta);
+ return FALSE;
+ }
+
+ number_of_vertices = 2 + slices * (stacks-1);
+ number_of_faces = 2 * slices + (stacks - 2) * (2 * slices);
+
+ if (!new_mesh(mesh, number_of_vertices, number_of_faces))
+ {
+ free_sincos_table(&phi);
+ free_sincos_table(&theta);
+ return FALSE;
+ }
+
+ vertex = 0;
+ face = 0;
+
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = 1.0f;
+ mesh->vertices[vertex].position.x = 0.0f;
+ mesh->vertices[vertex].position.y = 0.0f;
+ mesh->vertices[vertex].position.z = radius;
+ vertex++;
+
+ for (stack = 0; stack < stacks - 1; stack++)
+ {
+ for (slice = 0; slice < slices; slice++)
+ {
+ mesh->vertices[vertex].normal.x = theta.sin[stack] * phi.cos[slice];
+ mesh->vertices[vertex].normal.y = theta.sin[stack] * phi.sin[slice];
+ mesh->vertices[vertex].normal.z = theta.cos[stack];
+ mesh->vertices[vertex].position.x = radius * theta.sin[stack] * phi.cos[slice];
+ mesh->vertices[vertex].position.y = radius * theta.sin[stack] * phi.sin[slice];
+ mesh->vertices[vertex].position.z = radius * theta.cos[stack];
+ vertex++;
+
+ if (slice > 0)
+ {
+ if (stack == 0)
+ {
+ /* top stack is triangle fan */
+ mesh->faces[face][0] = 0;
+ mesh->faces[face][1] = slice + 1;
+ mesh->faces[face][2] = slice;
+ face++;
+ }
+ else
+ {
+ /* stacks in between top and bottom are quad strips */
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice, stack-1);
+ mesh->faces[face][2] = vertex_index(slices, slice-1, stack);
+ face++;
+
+ mesh->faces[face][0] = vertex_index(slices, slice, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice, stack);
+ mesh->faces[face][2] = vertex_index(slices, slice-1, stack);
+ face++;
+ }
+ }
+ }
+
+ if (stack == 0)
+ {
+ mesh->faces[face][0] = 0;
+ mesh->faces[face][1] = 1;
+ mesh->faces[face][2] = slice;
+ face++;
+ }
+ else
+ {
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, 0, stack-1);
+ mesh->faces[face][2] = vertex_index(slices, slice-1, stack);
+ face++;
+
+ mesh->faces[face][0] = vertex_index(slices, 0, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, 0, stack);
+ mesh->faces[face][2] = vertex_index(slices, slice-1, stack);
+ face++;
+ }
+ }
+
+ mesh->vertices[vertex].position.x = 0.0f;
+ mesh->vertices[vertex].position.y = 0.0f;
+ mesh->vertices[vertex].position.z = -radius;
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = -1.0f;
+
+ /* bottom stack is triangle fan */
+ for (slice = 1; slice < slices; slice++)
+ {
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice, stack-1);
+ mesh->faces[face][2] = vertex;
+ face++;
+ }
+
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, 0, stack-1);
+ mesh->faces[face][2] = vertex;
+
+ free_sincos_table(&phi);
+ free_sincos_table(&theta);
+
+ return TRUE;
+}
+
+static void test_sphere(IDirect3DDevice9 *device, FLOAT radius, UINT slices, UINT stacks)
+{
+ HRESULT hr;
+ ID3DXMesh *sphere;
+ struct mesh mesh;
+ char name[256];
+
+ hr = D3DXCreateSphere(device, radius, slices, stacks, &sphere, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't create sphere\n");
+ return;
+ }
+
+ if (!compute_sphere(&mesh, radius, slices, stacks))
+ {
+ skip("Couldn't create mesh\n");
+ sphere->lpVtbl->Release(sphere);
+ return;
+ }
+
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ sprintf(name, "sphere (%g, %u, %u)", radius, slices, stacks);
+ compare_mesh(name, sphere, &mesh);
+
+ free_mesh(&mesh);
+
+ sphere->lpVtbl->Release(sphere);
+}
+
+static void D3DXCreateSphereTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9* device;
+ ID3DXMesh* sphere = NULL;
+ struct test_context *test_context;
+
+ hr = D3DXCreateSphere(NULL, 0.0f, 0, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(NULL, 0.1f, 0, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(NULL, 0.0f, 1, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(NULL, 0.0f, 0, 1, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateSphere(device, 1.0f, 1, 1, &sphere, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(device, 1.0f, 2, 1, &sphere, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(device, 1.0f, 1, 2, &sphere, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateSphere(device, -0.1f, 1, 2, &sphere, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ test_sphere(device, 0.0f, 2, 2);
+ test_sphere(device, 1.0f, 2, 2);
+ test_sphere(device, 1.0f, 3, 2);
+ test_sphere(device, 1.0f, 4, 4);
+ test_sphere(device, 1.0f, 3, 4);
+ test_sphere(device, 5.0f, 6, 7);
+ test_sphere(device, 10.0f, 11, 12);
+
+ free_test_context(test_context);
+}
+
+static BOOL compute_cylinder(struct mesh *mesh, FLOAT radius1, FLOAT radius2, FLOAT length, UINT slices, UINT stacks)
+{
+ float theta_step, theta_start;
+ struct sincos_table theta;
+ FLOAT delta_radius, radius, radius_step;
+ FLOAT z, z_step, z_normal;
+ DWORD number_of_vertices, number_of_faces;
+ DWORD vertex, face;
+ int slice, stack;
+
+ /* theta = angle on xy plane wrt x axis */
+ theta_step = -2 * D3DX_PI / slices;
+ theta_start = D3DX_PI / 2;
+
+ if (!compute_sincos_table(&theta, theta_start, theta_step, slices))
+ {
+ return FALSE;
+ }
+
+ number_of_vertices = 2 + (slices * (3 + stacks));
+ number_of_faces = 2 * slices + stacks * (2 * slices);
+
+ if (!new_mesh(mesh, number_of_vertices, number_of_faces))
+ {
+ free_sincos_table(&theta);
+ return FALSE;
+ }
+
+ vertex = 0;
+ face = 0;
+
+ delta_radius = radius1 - radius2;
+ radius = radius1;
+ radius_step = delta_radius / stacks;
+
+ z = -length / 2;
+ z_step = length / stacks;
+ z_normal = delta_radius / length;
+ if (isnan(z_normal))
+ {
+ z_normal = 0.0f;
+ }
+
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = -1.0f;
+ mesh->vertices[vertex].position.x = 0.0f;
+ mesh->vertices[vertex].position.y = 0.0f;
+ mesh->vertices[vertex++].position.z = z;
+
+ for (slice = 0; slice < slices; slice++, vertex++)
+ {
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = -1.0f;
+ mesh->vertices[vertex].position.x = radius * theta.cos[slice];
+ mesh->vertices[vertex].position.y = radius * theta.sin[slice];
+ mesh->vertices[vertex].position.z = z;
+
+ if (slice > 0)
+ {
+ mesh->faces[face][0] = 0;
+ mesh->faces[face][1] = slice;
+ mesh->faces[face++][2] = slice + 1;
+ }
+ }
+
+ mesh->faces[face][0] = 0;
+ mesh->faces[face][1] = slice;
+ mesh->faces[face++][2] = 1;
+
+ for (stack = 1; stack <= stacks+1; stack++)
+ {
+ for (slice = 0; slice < slices; slice++, vertex++)
+ {
+ mesh->vertices[vertex].normal.x = theta.cos[slice];
+ mesh->vertices[vertex].normal.y = theta.sin[slice];
+ mesh->vertices[vertex].normal.z = z_normal;
+ D3DXVec3Normalize(&mesh->vertices[vertex].normal, &mesh->vertices[vertex].normal);
+ mesh->vertices[vertex].position.x = radius * theta.cos[slice];
+ mesh->vertices[vertex].position.y = radius * theta.sin[slice];
+ mesh->vertices[vertex].position.z = z;
+
+ if (stack > 1 && slice > 0)
+ {
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face++][2] = vertex_index(slices, slice, stack-1);
+
+ mesh->faces[face][0] = vertex_index(slices, slice, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face++][2] = vertex_index(slices, slice, stack);
+ }
+ }
+
+ if (stack > 1)
+ {
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face++][2] = vertex_index(slices, 0, stack-1);
+
+ mesh->faces[face][0] = vertex_index(slices, 0, stack-1);
+ mesh->faces[face][1] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face++][2] = vertex_index(slices, 0, stack);
+ }
+
+ if (stack < stacks + 1)
+ {
+ z += z_step;
+ radius -= radius_step;
+ }
+ }
+
+ for (slice = 0; slice < slices; slice++, vertex++)
+ {
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = 1.0f;
+ mesh->vertices[vertex].position.x = radius * theta.cos[slice];
+ mesh->vertices[vertex].position.y = radius * theta.sin[slice];
+ mesh->vertices[vertex].position.z = z;
+
+ if (slice > 0)
+ {
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face][1] = number_of_vertices - 1;
+ mesh->faces[face++][2] = vertex_index(slices, slice, stack);
+ }
+ }
+
+ mesh->vertices[vertex].position.x = 0.0f;
+ mesh->vertices[vertex].position.y = 0.0f;
+ mesh->vertices[vertex].position.z = z;
+ mesh->vertices[vertex].normal.x = 0.0f;
+ mesh->vertices[vertex].normal.y = 0.0f;
+ mesh->vertices[vertex].normal.z = 1.0f;
+
+ mesh->faces[face][0] = vertex_index(slices, slice-1, stack);
+ mesh->faces[face][1] = number_of_vertices - 1;
+ mesh->faces[face][2] = vertex_index(slices, 0, stack);
+
+ free_sincos_table(&theta);
+
+ return TRUE;
+}
+
+static void test_cylinder(IDirect3DDevice9 *device, FLOAT radius1, FLOAT radius2, FLOAT length, UINT slices, UINT stacks)
+{
+ HRESULT hr;
+ ID3DXMesh *cylinder;
+ struct mesh mesh;
+ char name[256];
+
+ hr = D3DXCreateCylinder(device, radius1, radius2, length, slices, stacks, &cylinder, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't create cylinder\n");
+ return;
+ }
+
+ if (!compute_cylinder(&mesh, radius1, radius2, length, slices, stacks))
+ {
+ skip("Couldn't create mesh\n");
+ cylinder->lpVtbl->Release(cylinder);
+ return;
+ }
+
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ sprintf(name, "cylinder (%g, %g, %g, %u, %u)", radius1, radius2, length, slices, stacks);
+ compare_mesh(name, cylinder, &mesh);
+
+ free_mesh(&mesh);
+
+ cylinder->lpVtbl->Release(cylinder);
+}
+
+static void D3DXCreateCylinderTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9* device;
+ ID3DXMesh* cylinder = NULL;
+ struct test_context *test_context;
+
+ hr = D3DXCreateCylinder(NULL, 0.0f, 0.0f, 0.0f, 0, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCylinder(NULL, 1.0f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateCylinder(device, -0.1f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCylinder(device, 0.0f, 1.0f, 1.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
+
+ if (SUCCEEDED(hr) && cylinder)
+ {
+ cylinder->lpVtbl->Release(cylinder);
+ }
+
+ hr = D3DXCreateCylinder(device, 1.0f, -0.1f, 1.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCylinder(device, 1.0f, 0.0f, 1.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
+
+ if (SUCCEEDED(hr) && cylinder)
+ {
+ cylinder->lpVtbl->Release(cylinder);
+ }
+
+ hr = D3DXCreateCylinder(device, 1.0f, 1.0f, -0.1f, 2, 1, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ /* Test with length == 0.0f succeeds */
+ hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 0.0f, 2, 1, &cylinder, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n",hr);
+
+ if (SUCCEEDED(hr) && cylinder)
+ {
+ cylinder->lpVtbl->Release(cylinder);
+ }
+
+ hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 1, 1, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 2, 0, &cylinder, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCylinder(device, 1.0f, 1.0f, 1.0f, 2, 1, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n",hr,D3DERR_INVALIDCALL);
+
+ test_cylinder(device, 0.0f, 0.0f, 0.0f, 2, 1);
+ test_cylinder(device, 1.0f, 1.0f, 1.0f, 2, 1);
+ test_cylinder(device, 1.0f, 1.0f, 2.0f, 3, 4);
+ test_cylinder(device, 3.0f, 2.0f, 4.0f, 3, 4);
+ test_cylinder(device, 2.0f, 3.0f, 4.0f, 3, 4);
+ test_cylinder(device, 3.0f, 4.0f, 5.0f, 11, 20);
+
+ free_test_context(test_context);
+}
+
+static BOOL compute_torus(struct mesh *mesh, float innerradius, float outerradius, UINT sides, UINT rings)
+{
+ float phi, phi_step, sin_phi, cos_phi;
+ float theta, theta_step, sin_theta, cos_theta;
+ unsigned int numvert, numfaces, i, j;
+
+ numvert = sides * rings;
+ numfaces = numvert * 2;
+
+ if (!new_mesh(mesh, numvert, numfaces))
+ return FALSE;
+
+ phi_step = D3DX_PI / sides * 2.0f;
+ theta_step = D3DX_PI / rings * -2.0f;
+
+ theta = 0.0f;
+
+ for (i = 0; i < rings; ++i)
+ {
+ phi = 0.0f;
+
+ cos_theta = cosf(theta);
+ sin_theta = sinf(theta);
+
+ for (j = 0; j < sides; ++j)
+ {
+ sin_phi = sinf(phi);
+ cos_phi = cosf(phi);
+
+ mesh->vertices[i * sides + j].position.x = (innerradius * cos_phi + outerradius) * cos_theta;
+ mesh->vertices[i * sides + j].position.y = (innerradius * cos_phi + outerradius) * sin_theta;
+ mesh->vertices[i * sides + j].position.z = innerradius * sin_phi;
+ mesh->vertices[i * sides + j].normal.x = cos_phi * cos_theta;
+ mesh->vertices[i * sides + j].normal.y = cos_phi * sin_theta;
+ mesh->vertices[i * sides + j].normal.z = sin_phi;
+
+ phi += phi_step;
+ }
+
+ theta += theta_step;
+ }
+
+ for (i = 0; i < numfaces - sides * 2; ++i)
+ {
+ mesh->faces[i][0] = i % 2 ? i / 2 + sides : i / 2;
+ mesh->faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
+ mesh->faces[i][2] = (i + 1) % (sides * 2) ? (i + 1) / 2 + sides : (i + 1) / 2;
+ }
+
+ for (j = 0; i < numfaces; ++i, ++j)
+ {
+ mesh->faces[i][0] = i % 2 ? j / 2 : i / 2;
+ mesh->faces[i][1] = (i / 2 + 1) % sides ? i / 2 + 1 : i / 2 + 1 - sides;
+ mesh->faces[i][2] = i == numfaces - 1 ? 0 : (j + 1) / 2;
+ }
+
+ return TRUE;
+}
+
+static void test_torus(IDirect3DDevice9 *device, float innerradius, float outerradius, UINT sides, UINT rings)
+{
+ HRESULT hr;
+ ID3DXMesh *torus;
+ struct mesh mesh;
+ char name[256];
+
+ hr = D3DXCreateTorus(device, innerradius, outerradius, sides, rings, &torus, NULL);
+ ok(hr == D3D_OK, "Got result %#x, expected 0 (D3D_OK)\n", hr);
+ if (hr != D3D_OK)
+ {
+ skip("Couldn't create torus\n");
+ return;
+ }
+
+ if (!compute_torus(&mesh, innerradius, outerradius, sides, rings))
+ {
+ skip("Couldn't create mesh\n");
+ torus->lpVtbl->Release(torus);
+ return;
+ }
+
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ sprintf(name, "torus (%g, %g, %u, %u)", innerradius, outerradius, sides, rings);
+ compare_mesh(name, torus, &mesh);
+
+ free_mesh(&mesh);
+
+ torus->lpVtbl->Release(torus);
+}
+
+static void D3DXCreateTorusTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9* device;
+ ID3DXMesh* torus = NULL;
+ struct test_context *test_context;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateTorus(NULL, 0.0f, 0.0f, 3, 3, &torus, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTorus(device, -1.0f, 0.0f, 3, 3, &torus, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTorus(device, 0.0f, -1.0f, 3, 3, &torus, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTorus(device, 0.0f, 0.0f, 2, 3, &torus, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTorus(device, 0.0f, 0.0f, 3, 2, &torus, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTorus(device, 0.0f, 0.0f, 3, 3, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %#x, expected %#x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ test_torus(device, 0.0f, 0.0f, 3, 3);
+ test_torus(device, 1.0f, 1.0f, 3, 3);
+ test_torus(device, 1.0f, 1.0f, 32, 64);
+ test_torus(device, 0.0f, 1.0f, 5, 5);
+ test_torus(device, 1.0f, 0.0f, 5, 5);
+ test_torus(device, 5.0f, 0.2f, 8, 8);
+ test_torus(device, 0.2f, 1.0f, 60, 3);
+ test_torus(device, 0.2f, 1.0f, 8, 70);
+
+ free_test_context(test_context);
+}
+
+struct dynamic_array
+{
+ int count, capacity;
+ void *items;
+};
+
+enum pointtype {
+ POINTTYPE_CURVE = 0,
+ POINTTYPE_CORNER,
+ POINTTYPE_CURVE_START,
+ POINTTYPE_CURVE_END,
+ POINTTYPE_CURVE_MIDDLE,
+};
+
+struct point2d
+{
+ D3DXVECTOR2 pos;
+ enum pointtype corner;
+};
+
+/* is a dynamic_array */
+struct outline
+{
+ int count, capacity;
+ struct point2d *items;
+};
+
+/* is a dynamic_array */
+struct outline_array
+{
+ int count, capacity;
+ struct outline *items;
+};
+
+struct glyphinfo
+{
+ struct outline_array outlines;
+ float offset_x;
+};
+
+static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
+{
+ if (count > array->capacity) {
+ void *new_buffer;
+ int new_capacity;
+ if (array->items && array->capacity) {
+ new_capacity = max(array->capacity * 2, count);
+ new_buffer = HeapReAlloc(GetProcessHeap(), 0, array->items, new_capacity * itemsize);
+ } else {
+ new_capacity = max(16, count);
+ new_buffer = HeapAlloc(GetProcessHeap(), 0, new_capacity * itemsize);
+ }
+ if (!new_buffer)
+ return FALSE;
+ array->items = new_buffer;
+ array->capacity = new_capacity;
+ }
+ return TRUE;
+}
+
+static struct point2d *add_point(struct outline *array)
+{
+ struct point2d *item;
+
+ if (!reserve((struct dynamic_array *)array, array->count + 1, sizeof(array->items[0])))
+ return NULL;
+
+ item = &array->items[array->count++];
+ ZeroMemory(item, sizeof(*item));
+ return item;
+}
+
+static struct outline *add_outline(struct outline_array *array)
+{
+ struct outline *item;
+
+ if (!reserve((struct dynamic_array *)array, array->count + 1, sizeof(array->items[0])))
+ return NULL;
+
+ item = &array->items[array->count++];
+ ZeroMemory(item, sizeof(*item));
+ return item;
+}
+
+static inline D3DXVECTOR2 *convert_fixed_to_float(POINTFX *pt, int count, float emsquare)
+{
+ D3DXVECTOR2 *ret = (D3DXVECTOR2*)pt;
+ while (count--) {
+ D3DXVECTOR2 *pt_flt = (D3DXVECTOR2*)pt;
+ pt_flt->x = (pt->x.value + pt->x.fract / (float)0x10000) / emsquare;
+ pt_flt->y = (pt->y.value + pt->y.fract / (float)0x10000) / emsquare;
+ pt++;
+ }
+ return ret;
+}
+
+static HRESULT add_bezier_points(struct outline *outline, const D3DXVECTOR2 *p1,
+ const D3DXVECTOR2 *p2, const D3DXVECTOR2 *p3,
+ float max_deviation)
+{
+ D3DXVECTOR2 split1 = {0, 0}, split2 = {0, 0}, middle, vec;
+ float deviation;
+
+ D3DXVec2Scale(&split1, D3DXVec2Add(&split1, p1, p2), 0.5f);
+ D3DXVec2Scale(&split2, D3DXVec2Add(&split2, p2, p3), 0.5f);
+ D3DXVec2Scale(&middle, D3DXVec2Add(&middle, &split1, &split2), 0.5f);
+
+ deviation = D3DXVec2Length(D3DXVec2Subtract(&vec, &middle, p2));
+ if (deviation < max_deviation) {
+ struct point2d *pt = add_point(outline);
+ if (!pt) return E_OUTOFMEMORY;
+ pt->pos = *p2;
+ pt->corner = POINTTYPE_CURVE;
+ /* the end point is omitted because the end line merges into the next segment of
+ * the split bezier curve, and the end of the split bezier curve is added outside
+ * this recursive function. */
+ } else {
+ HRESULT hr = add_bezier_points(outline, p1, &split1, &middle, max_deviation);
+ if (hr != S_OK) return hr;
+ hr = add_bezier_points(outline, &middle, &split2, p3, max_deviation);
+ if (hr != S_OK) return hr;
+ }
+
+ return S_OK;
+}
+
+static inline BOOL is_direction_similar(D3DXVECTOR2 *dir1, D3DXVECTOR2 *dir2, float cos_theta)
+{
+ /* dot product = cos(theta) */
+ return D3DXVec2Dot(dir1, dir2) > cos_theta;
+}
+
+static inline D3DXVECTOR2 *unit_vec2(D3DXVECTOR2 *dir, const D3DXVECTOR2 *pt1, const D3DXVECTOR2 *pt2)
+{
+ return D3DXVec2Normalize(D3DXVec2Subtract(dir, pt2, pt1), dir);
+}
+
+static BOOL attempt_line_merge(struct outline *outline,
+ int pt_index,
+ const D3DXVECTOR2 *nextpt,
+ BOOL to_curve)
+{
+ D3DXVECTOR2 curdir, lastdir;
+ struct point2d *prevpt, *pt;
+ BOOL ret = FALSE;
+ const float cos_half = cos(D3DXToRadian(0.5f));
+
+ pt = &outline->items[pt_index];
+ pt_index = (pt_index - 1 + outline->count) % outline->count;
+ prevpt = &outline->items[pt_index];
+
+ if (to_curve)
+ pt->corner = pt->corner != POINTTYPE_CORNER ? POINTTYPE_CURVE_MIDDLE : POINTTYPE_CURVE_START;
+
+ if (outline->count < 2)
+ return FALSE;
+
+ /* remove last point if the next line continues the last line */
+ unit_vec2(&lastdir, &prevpt->pos, &pt->pos);
+ unit_vec2(&curdir, &pt->pos, nextpt);
+ if (is_direction_similar(&lastdir, &curdir, cos_half))
+ {
+ outline->count--;
+ if (pt->corner == POINTTYPE_CURVE_END)
+ prevpt->corner = pt->corner;
+ if (prevpt->corner == POINTTYPE_CURVE_END && to_curve)
+ prevpt->corner = POINTTYPE_CURVE_MIDDLE;
+ pt = prevpt;
+
+ ret = TRUE;
+ if (outline->count < 2)
+ return ret;
+
+ pt_index = (pt_index - 1 + outline->count) % outline->count;
+ prevpt = &outline->items[pt_index];
+ unit_vec2(&lastdir, &prevpt->pos, &pt->pos);
+ unit_vec2(&curdir, &pt->pos, nextpt);
+ }
+ return ret;
+}
+
+static HRESULT create_outline(struct glyphinfo *glyph, void *raw_outline, int datasize,
+ float max_deviation, float emsquare)
+{
+ const float cos_45 = cos(D3DXToRadian(45.0f));
+ const float cos_90 = cos(D3DXToRadian(90.0f));
+ TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)raw_outline;
+
+ while ((char *)header < (char *)raw_outline + datasize)
+ {
+ TTPOLYCURVE *curve = (TTPOLYCURVE *)(header + 1);
+ struct point2d *lastpt, *pt;
+ D3DXVECTOR2 lastdir;
+ D3DXVECTOR2 *pt_flt;
+ int j;
+ struct outline *outline = add_outline(&glyph->outlines);
+
+ if (!outline)
+ return E_OUTOFMEMORY;
+
+ pt = add_point(outline);
+ if (!pt)
+ return E_OUTOFMEMORY;
+ pt_flt = convert_fixed_to_float(&header->pfxStart, 1, emsquare);
+ pt->pos = *pt_flt;
+ pt->corner = POINTTYPE_CORNER;
+
+ if (header->dwType != TT_POLYGON_TYPE)
+ trace("Unknown header type %d\n", header->dwType);
+
+ while ((char *)curve < (char *)header + header->cb)
+ {
+ D3DXVECTOR2 bezier_start = outline->items[outline->count - 1].pos;
+ BOOL to_curve = curve->wType != TT_PRIM_LINE && curve->cpfx > 1;
+
+ if (!curve->cpfx) {
+ curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
+ continue;
+ }
+
+ pt_flt = convert_fixed_to_float(curve->apfx, curve->cpfx, emsquare);
+
+ attempt_line_merge(outline, outline->count - 1, &pt_flt[0], to_curve);
+
+ if (to_curve)
+ {
+ HRESULT hr;
+ int count = curve->cpfx;
+ j = 0;
+
+ while (count > 2)
+ {
+ D3DXVECTOR2 bezier_end;
+
+ D3DXVec2Scale(&bezier_end, D3DXVec2Add(&bezier_end, &pt_flt[j], &pt_flt[j+1]), 0.5f);
+ hr = add_bezier_points(outline, &bezier_start, &pt_flt[j], &bezier_end, max_deviation);
+ if (hr != S_OK)
+ return hr;
+ bezier_start = bezier_end;
+ count--;
+ j++;
+ }
+ hr = add_bezier_points(outline, &bezier_start, &pt_flt[j], &pt_flt[j+1], max_deviation);
+ if (hr != S_OK)
+ return hr;
+
+ pt = add_point(outline);
+ if (!pt)
+ return E_OUTOFMEMORY;
+ j++;
+ pt->pos = pt_flt[j];
+ pt->corner = POINTTYPE_CURVE_END;
+ } else {
+ for (j = 0; j < curve->cpfx; j++)
+ {
+ pt = add_point(outline);
+ if (!pt)
+ return E_OUTOFMEMORY;
+ pt->pos = pt_flt[j];
+ pt->corner = POINTTYPE_CORNER;
+ }
+ }
+
+ curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx];
+ }
+
+ /* remove last point if the next line continues the last line */
+ if (outline->count >= 3) {
+ BOOL to_curve;
+
+ lastpt = &outline->items[outline->count - 1];
+ pt = &outline->items[0];
+ if (pt->pos.x == lastpt->pos.x && pt->pos.y == lastpt->pos.y) {
+ if (lastpt->corner == POINTTYPE_CURVE_END)
+ {
+ if (pt->corner == POINTTYPE_CURVE_START)
+ pt->corner = POINTTYPE_CURVE_MIDDLE;
+ else
+ pt->corner = POINTTYPE_CURVE_END;
+ }
+ outline->count--;
+ } else {
+ /* outline closed with a line from end to start point */
+ attempt_line_merge(outline, outline->count - 1, &pt->pos, FALSE);
+ }
+ lastpt = &outline->items[0];
+ to_curve = lastpt->corner != POINTTYPE_CORNER && lastpt->corner != POINTTYPE_CURVE_END;
+ if (lastpt->corner == POINTTYPE_CURVE_START)
+ lastpt->corner = POINTTYPE_CORNER;
+ pt = &outline->items[1];
+ if (attempt_line_merge(outline, 0, &pt->pos, to_curve))
+ *lastpt = outline->items[outline->count];
+ }
+
+ lastpt = &outline->items[outline->count - 1];
+ pt = &outline->items[0];
+ unit_vec2(&lastdir, &lastpt->pos, &pt->pos);
+ for (j = 0; j < outline->count; j++)
+ {
+ D3DXVECTOR2 curdir;
+
+ lastpt = pt;
+ pt = &outline->items[(j + 1) % outline->count];
+ unit_vec2(&curdir, &lastpt->pos, &pt->pos);
+
+ switch (lastpt->corner)
+ {
+ case POINTTYPE_CURVE_START:
+ case POINTTYPE_CURVE_END:
+ if (!is_direction_similar(&lastdir, &curdir, cos_45))
+ lastpt->corner = POINTTYPE_CORNER;
+ break;
+ case POINTTYPE_CURVE_MIDDLE:
+ if (!is_direction_similar(&lastdir, &curdir, cos_90))
+ lastpt->corner = POINTTYPE_CORNER;
+ else
+ lastpt->corner = POINTTYPE_CURVE;
+ break;
+ default:
+ break;
+ }
+ lastdir = curdir;
+ }
+
+ header = (TTPOLYGONHEADER *)((char *)header + header->cb);
+ }
+ return S_OK;
+}
+
+static void free_outline(struct outline *outline)
+{
+ HeapFree(GetProcessHeap(), 0, outline->items);
+}
+
+static void free_glyphinfo(struct glyphinfo *glyph)
+{
+ unsigned int i;
+
+ for (i = 0; i < glyph->outlines.count; ++i)
+ free_outline(&glyph->outlines.items[i]);
+ HeapFree(GetProcessHeap(), 0, glyph->outlines.items);
+}
+
+static void compute_text_mesh(struct mesh *mesh, const char *text,
+ float deviation, float extrusion, float otmEMSquare, const struct glyphinfo *glyphs)
+{
+ DWORD nb_vertices, nb_faces;
+ DWORD nb_corners, nb_outline_points;
+ int textlen = 0;
+ int i;
+ struct vertex *vertex_ptr;
+ face *face_ptr;
+
+ textlen = strlen(text);
+
+ /* corner points need an extra vertex for the different side faces normals */
+ nb_corners = 0;
+ nb_outline_points = 0;
+ for (i = 0; i < textlen; i++)
+ {
+ int j;
+ for (j = 0; j < glyphs[i].outlines.count; j++)
+ {
+ int k;
+ struct outline *outline = &glyphs[i].outlines.items[j];
+ nb_outline_points += outline->count;
+ nb_corners++; /* first outline point always repeated as a corner */
+ for (k = 1; k < outline->count; k++)
+ if (outline->items[k].corner)
+ nb_corners++;
+ }
+ }
+
+ nb_vertices = (nb_outline_points + nb_corners) * 2 + textlen;
+ nb_faces = nb_outline_points * 2;
+
+ ok(new_mesh(mesh, nb_vertices, nb_faces), "Failed to create reference text mesh.\n");
+
+ /* convert 2D vertices and faces into 3D mesh */
+ vertex_ptr = mesh->vertices;
+ face_ptr = mesh->faces;
+ for (i = 0; i < textlen; i++)
+ {
+ int j;
+
+ /* side vertices and faces */
+ for (j = 0; j < glyphs[i].outlines.count; j++)
+ {
+ struct vertex *outline_vertices = vertex_ptr;
+ struct outline *outline = &glyphs[i].outlines.items[j];
+ int k;
+ struct point2d *prevpt = &outline->items[outline->count - 1];
+ struct point2d *pt = &outline->items[0];
+
+ for (k = 1; k <= outline->count; k++)
+ {
+ struct vertex vtx;
+ struct point2d *nextpt = &outline->items[k % outline->count];
+ WORD vtx_idx = vertex_ptr - mesh->vertices;
+ D3DXVECTOR2 vec;
+
+ if (pt->corner == POINTTYPE_CURVE_START)
+ D3DXVec2Subtract(&vec, &pt->pos, &prevpt->pos);
+ else if (pt->corner)
+ D3DXVec2Subtract(&vec, &nextpt->pos, &pt->pos);
+ else
+ D3DXVec2Subtract(&vec, &nextpt->pos, &prevpt->pos);
+ D3DXVec2Normalize(&vec, &vec);
+ vtx.normal.x = -vec.y;
+ vtx.normal.y = vec.x;
+ vtx.normal.z = 0;
+
+ vtx.position.x = pt->pos.x + glyphs[i].offset_x;
+ vtx.position.y = pt->pos.y;
+ vtx.position.z = 0;
+ *vertex_ptr++ = vtx;
+
+ vtx.position.z = -extrusion;
+ *vertex_ptr++ = vtx;
+
+ vtx.position.x = nextpt->pos.x + glyphs[i].offset_x;
+ vtx.position.y = nextpt->pos.y;
+ if (pt->corner && nextpt->corner && nextpt->corner != POINTTYPE_CURVE_END) {
+ vtx.position.z = -extrusion;
+ *vertex_ptr++ = vtx;
+ vtx.position.z = 0;
+ *vertex_ptr++ = vtx;
+
+ (*face_ptr)[0] = vtx_idx;
+ (*face_ptr)[1] = vtx_idx + 2;
+ (*face_ptr)[2] = vtx_idx + 1;
+ face_ptr++;
+
+ (*face_ptr)[0] = vtx_idx;
+ (*face_ptr)[1] = vtx_idx + 3;
+ (*face_ptr)[2] = vtx_idx + 2;
+ face_ptr++;
+ } else {
+ if (nextpt->corner) {
+ if (nextpt->corner == POINTTYPE_CURVE_END) {
+ struct point2d *nextpt2 = &outline->items[(k + 1) % outline->count];
+ D3DXVec2Subtract(&vec, &nextpt2->pos, &nextpt->pos);
+ } else {
+ D3DXVec2Subtract(&vec, &nextpt->pos, &pt->pos);
+ }
+ D3DXVec2Normalize(&vec, &vec);
+ vtx.normal.x = -vec.y;
+ vtx.normal.y = vec.x;
+
+ vtx.position.z = 0;
+ *vertex_ptr++ = vtx;
+ vtx.position.z = -extrusion;
+ *vertex_ptr++ = vtx;
+ }
+
+ (*face_ptr)[0] = vtx_idx;
+ (*face_ptr)[1] = vtx_idx + 3;
+ (*face_ptr)[2] = vtx_idx + 1;
+ face_ptr++;
+
+ (*face_ptr)[0] = vtx_idx;
+ (*face_ptr)[1] = vtx_idx + 2;
+ (*face_ptr)[2] = vtx_idx + 3;
+ face_ptr++;
+ }
+
+ prevpt = pt;
+ pt = nextpt;
+ }
+ if (!pt->corner) {
+ *vertex_ptr++ = *outline_vertices++;
+ *vertex_ptr++ = *outline_vertices++;
+ }
+ }
+
+ /* FIXME: compute expected faces */
+ /* Add placeholder to separate glyph outlines */
+ vertex_ptr->position.x = 0;
+ vertex_ptr->position.y = 0;
+ vertex_ptr->position.z = 0;
+ vertex_ptr->normal.x = 0;
+ vertex_ptr->normal.y = 0;
+ vertex_ptr->normal.z = 1;
+ vertex_ptr++;
+ }
+}
+
+static void compare_text_outline_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mesh,
+ size_t textlen, float extrusion, const struct glyphinfo *glyphs)
+{
+ HRESULT hr;
+ DWORD number_of_vertices, number_of_faces;
+ IDirect3DVertexBuffer9 *vertex_buffer = NULL;
+ IDirect3DIndexBuffer9 *index_buffer = NULL;
+ D3DVERTEXBUFFER_DESC vertex_buffer_description;
+ D3DINDEXBUFFER_DESC index_buffer_description;
+ struct vertex *vertices = NULL;
+ face *faces = NULL;
+ int expected, i;
+ int vtx_idx1, face_idx1, vtx_idx2, face_idx2;
+
+ number_of_vertices = d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh);
+ number_of_faces = d3dxmesh->lpVtbl->GetNumFaces(d3dxmesh);
+
+ hr = d3dxmesh->lpVtbl->GetVertexBuffer(d3dxmesh, &vertex_buffer);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ hr = IDirect3DVertexBuffer9_GetDesc(vertex_buffer, &vertex_buffer_description);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ ok(vertex_buffer_description.Format == D3DFMT_VERTEXDATA, "Test %s, unexpected format %u.\n",
+ name, vertex_buffer_description.Format);
+ ok(vertex_buffer_description.Type == D3DRTYPE_VERTEXBUFFER, "Test %s, unexpected resource type %u.\n",
+ name, vertex_buffer_description.Type);
+ ok(!vertex_buffer_description.Usage, "Test %s, unexpected usage %#x.\n", name, vertex_buffer_description.Usage);
+ ok(vertex_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, unexpected pool %u.\n",
+ name, vertex_buffer_description.Pool);
+ ok(vertex_buffer_description.FVF == mesh->fvf, "Test %s, unexpected FVF %#x (expected %#x).\n",
+ name, vertex_buffer_description.FVF, mesh->fvf);
+ if (!mesh->fvf)
+ expected = number_of_vertices * mesh->vertex_size;
+ else
+ expected = number_of_vertices * D3DXGetFVFVertexSize(mesh->fvf);
+ ok(vertex_buffer_description.Size == expected, "Test %s, unexpected size %u (expected %u).\n",
+ name, vertex_buffer_description.Size, expected);
+
+ hr = d3dxmesh->lpVtbl->GetIndexBuffer(d3dxmesh, &index_buffer);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ hr = IDirect3DIndexBuffer9_GetDesc(index_buffer, &index_buffer_description);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ ok(index_buffer_description.Format == D3DFMT_INDEX16, "Test %s, unexpected format %u.\n",
+ name, index_buffer_description.Format);
+ ok(index_buffer_description.Type == D3DRTYPE_INDEXBUFFER, "Test %s, unexpected resource type %u.\n",
+ name, index_buffer_description.Type);
+ ok(!index_buffer_description.Usage, "Test %s, unexpected usage %#x.\n",
+ name, index_buffer_description.Usage);
+ ok(index_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, unexpected pool %u.\n",
+ name, index_buffer_description.Pool);
+ expected = number_of_faces * sizeof(WORD) * 3;
+ ok(index_buffer_description.Size == expected, "Test %s, unexpected size %u.\n",
+ name, index_buffer_description.Size);
+
+ hr = IDirect3DVertexBuffer9_Lock(vertex_buffer, 0, number_of_vertices * sizeof(D3DXVECTOR3) * 2,
+ (void **)&vertices, D3DLOCK_DISCARD);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ hr = IDirect3DIndexBuffer9_Lock(index_buffer, 0, number_of_faces * sizeof(WORD) * 3,
+ (void **)&faces, D3DLOCK_DISCARD);
+ ok(hr == D3D_OK, "Test %s, unexpected hr %#x.\n", name, hr);
+ face_idx1 = 0;
+ vtx_idx2 = 0;
+ face_idx2 = 0;
+ vtx_idx1 = 0;
+ for (i = 0; i < textlen; i++)
+ {
+ int nb_outline_vertices1, nb_outline_faces1;
+ int nb_outline_vertices2, nb_outline_faces2;
+ int nb_back_vertices, nb_back_faces;
+ int first_vtx1, first_vtx2;
+ int first_face1, first_face2;
+ int j;
+
+ first_vtx1 = vtx_idx1;
+ first_vtx2 = vtx_idx2;
+ /* Glyphs without outlines do not generate any vertices. */
+ if (glyphs[i].outlines.count > 0)
+ {
+ for (; vtx_idx1 < number_of_vertices; vtx_idx1++)
+ {
+ if (vertices[vtx_idx1].normal.z != 0)
+ break;
+ }
+
+ for (; vtx_idx2 < mesh->number_of_vertices; vtx_idx2++)
+ {
+ if (mesh->vertices[vtx_idx2].normal.z != 0)
+ break;
+ }
+ }
+ nb_outline_vertices1 = vtx_idx1 - first_vtx1;
+ nb_outline_vertices2 = vtx_idx2 - first_vtx2;
+ ok(nb_outline_vertices1 == nb_outline_vertices2,
+ "Test %s, glyph %d, outline vertex count result %d, expected %d\n", name, i,
+ nb_outline_vertices1, nb_outline_vertices2);
+
+ for (j = 0; j < min(nb_outline_vertices1, nb_outline_vertices2); j++)
+ {
+ vtx_idx1 = first_vtx1 + j;
+ vtx_idx2 = first_vtx2 + j;
+ ok(compare_vec3(vertices[vtx_idx1].position, mesh->vertices[vtx_idx2].position),
+ "Test %s, glyph %d, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].position.x, vertices[vtx_idx1].position.y, vertices[vtx_idx1].position.z,
+ mesh->vertices[vtx_idx2].position.x, mesh->vertices[vtx_idx2].position.y, mesh->vertices[vtx_idx2].position.z);
+ ok(compare_vec3(vertices[vtx_idx1].normal, mesh->vertices[first_vtx2 + j].normal),
+ "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].normal.x, vertices[vtx_idx1].normal.y, vertices[vtx_idx1].normal.z,
+ mesh->vertices[vtx_idx2].normal.x, mesh->vertices[vtx_idx2].normal.y, mesh->vertices[vtx_idx2].normal.z);
+ }
+ vtx_idx1 = first_vtx1 + nb_outline_vertices1;
+ vtx_idx2 = first_vtx2 + nb_outline_vertices2;
+
+ first_face1 = face_idx1;
+ first_face2 = face_idx2;
+ for (; face_idx1 < number_of_faces; face_idx1++)
+ {
+ if (faces[face_idx1][0] >= vtx_idx1 ||
+ faces[face_idx1][1] >= vtx_idx1 ||
+ faces[face_idx1][2] >= vtx_idx1)
+ break;
+ }
+ for (; face_idx2 < mesh->number_of_faces; face_idx2++)
+ {
+ if (mesh->faces[face_idx2][0] >= vtx_idx2 ||
+ mesh->faces[face_idx2][1] >= vtx_idx2 ||
+ mesh->faces[face_idx2][2] >= vtx_idx2)
+ break;
+ }
+ nb_outline_faces1 = face_idx1 - first_face1;
+ nb_outline_faces2 = face_idx2 - first_face2;
+ ok(nb_outline_faces1 == nb_outline_faces2,
+ "Test %s, glyph %d, outline face count result %d, expected %d\n", name, i,
+ nb_outline_faces1, nb_outline_faces2);
+
+ for (j = 0; j < min(nb_outline_faces1, nb_outline_faces2); j++)
+ {
+ face_idx1 = first_face1 + j;
+ face_idx2 = first_face2 + j;
+ ok(faces[face_idx1][0] - first_vtx1 == mesh->faces[face_idx2][0] - first_vtx2 &&
+ faces[face_idx1][1] - first_vtx1 == mesh->faces[face_idx2][1] - first_vtx2 &&
+ faces[face_idx1][2] - first_vtx1 == mesh->faces[face_idx2][2] - first_vtx2,
+ "Test %s, glyph %d, face %d, result (%d, %d, %d), expected (%d, %d, %d)\n", name, i, face_idx1,
+ faces[face_idx1][0], faces[face_idx1][1], faces[face_idx1][2],
+ mesh->faces[face_idx2][0] - first_vtx2 + first_vtx1,
+ mesh->faces[face_idx2][1] - first_vtx2 + first_vtx1,
+ mesh->faces[face_idx2][2] - first_vtx2 + first_vtx1);
+ }
+ face_idx1 = first_face1 + nb_outline_faces1;
+ face_idx2 = first_face2 + nb_outline_faces2;
+
+ /* partial test on back vertices and faces */
+ first_vtx1 = vtx_idx1;
+ for (; vtx_idx1 < number_of_vertices; vtx_idx1++) {
+ struct vertex vtx;
+
+ if (vertices[vtx_idx1].normal.z != 1.0f)
+ break;
+
+ vtx.position.z = 0.0f;
+ vtx.normal.x = 0.0f;
+ vtx.normal.y = 0.0f;
+ vtx.normal.z = 1.0f;
+ ok(compare(vertices[vtx_idx1].position.z, vtx.position.z),
+ "Test %s, glyph %d, vertex position.z %d, result %g, expected %g\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].position.z, vtx.position.z);
+ ok(compare_vec3(vertices[vtx_idx1].normal, vtx.normal),
+ "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].normal.x, vertices[vtx_idx1].normal.y, vertices[vtx_idx1].normal.z,
+ vtx.normal.x, vtx.normal.y, vtx.normal.z);
+ }
+ nb_back_vertices = vtx_idx1 - first_vtx1;
+ first_face1 = face_idx1;
+ for (; face_idx1 < number_of_faces; face_idx1++)
+ {
+ const D3DXVECTOR3 *vtx1, *vtx2, *vtx3;
+ D3DXVECTOR3 normal;
+ D3DXVECTOR3 v1 = {0, 0, 0};
+ D3DXVECTOR3 v2 = {0, 0, 0};
+ D3DXVECTOR3 forward = {0.0f, 0.0f, 1.0f};
+
+ if (faces[face_idx1][0] >= vtx_idx1 ||
+ faces[face_idx1][1] >= vtx_idx1 ||
+ faces[face_idx1][2] >= vtx_idx1)
+ break;
+
+ vtx1 = &vertices[faces[face_idx1][0]].position;
+ vtx2 = &vertices[faces[face_idx1][1]].position;
+ vtx3 = &vertices[faces[face_idx1][2]].position;
+
+ D3DXVec3Subtract(&v1, vtx2, vtx1);
+ D3DXVec3Subtract(&v2, vtx3, vtx2);
+ D3DXVec3Cross(&normal, &v1, &v2);
+ D3DXVec3Normalize(&normal, &normal);
+ ok(!D3DXVec3Length(&normal) || compare_vec3(normal, forward),
+ "Test %s, glyph %d, face %d normal, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, face_idx1,
+ normal.x, normal.y, normal.z, forward.x, forward.y, forward.z);
+ }
+ nb_back_faces = face_idx1 - first_face1;
+
+ /* compare front and back faces & vertices */
+ if (extrusion == 0.0f) {
+ /* Oddly there are only back faces in this case */
+ nb_back_vertices /= 2;
+ nb_back_faces /= 2;
+ face_idx1 -= nb_back_faces;
+ vtx_idx1 -= nb_back_vertices;
+ }
+ for (j = 0; j < nb_back_vertices; j++)
+ {
+ struct vertex vtx = vertices[first_vtx1];
+ vtx.position.z = -extrusion;
+ vtx.normal.x = 0.0f;
+ vtx.normal.y = 0.0f;
+ vtx.normal.z = extrusion == 0.0f ? 1.0f : -1.0f;
+ ok(compare_vec3(vertices[vtx_idx1].position, vtx.position),
+ "Test %s, glyph %d, vertex position %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].position.x, vertices[vtx_idx1].position.y, vertices[vtx_idx1].position.z,
+ vtx.position.x, vtx.position.y, vtx.position.z);
+ ok(compare_vec3(vertices[vtx_idx1].normal, vtx.normal),
+ "Test %s, glyph %d, vertex normal %d, result (%g, %g, %g), expected (%g, %g, %g)\n", name, i, vtx_idx1,
+ vertices[vtx_idx1].normal.x, vertices[vtx_idx1].normal.y, vertices[vtx_idx1].normal.z,
+ vtx.normal.x, vtx.normal.y, vtx.normal.z);
+ vtx_idx1++;
+ first_vtx1++;
+ }
+ for (j = 0; j < nb_back_faces; j++)
+ {
+ int f1, f2;
+ if (extrusion == 0.0f) {
+ f1 = 1;
+ f2 = 2;
+ } else {
+ f1 = 2;
+ f2 = 1;
+ }
+ ok(faces[face_idx1][0] == faces[first_face1][0] + nb_back_vertices &&
+ faces[face_idx1][1] == faces[first_face1][f1] + nb_back_vertices &&
+ faces[face_idx1][2] == faces[first_face1][f2] + nb_back_vertices,
+ "Test %s, glyph %d, face %d, result (%d, %d, %d), expected (%d, %d, %d)\n", name, i, face_idx1,
+ faces[face_idx1][0], faces[face_idx1][1], faces[face_idx1][2],
+ faces[first_face1][0] - nb_back_faces,
+ faces[first_face1][f1] - nb_back_faces,
+ faces[first_face1][f2] - nb_back_faces);
+ first_face1++;
+ face_idx1++;
+ }
+
+ /* skip to the outline for the next glyph */
+ for (; vtx_idx2 < mesh->number_of_vertices; vtx_idx2++) {
+ if (mesh->vertices[vtx_idx2].normal.z == 0)
+ break;
+ }
+ for (; face_idx2 < mesh->number_of_faces; face_idx2++)
+ {
+ if (mesh->faces[face_idx2][0] >= vtx_idx2 ||
+ mesh->faces[face_idx2][1] >= vtx_idx2 ||
+ mesh->faces[face_idx2][2] >= vtx_idx2) break;
+ }
+ }
+
+ IDirect3DIndexBuffer9_Unlock(index_buffer);
+ IDirect3DVertexBuffer9_Unlock(vertex_buffer);
+ IDirect3DIndexBuffer9_Release(index_buffer);
+ IDirect3DVertexBuffer9_Release(vertex_buffer);
+}
+
+static void test_createtext(IDirect3DDevice9 *device, HDC hdc, const char *text, float deviation, float extrusion)
+{
+ static const MAT2 identity = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
+ HRESULT hr;
+ ID3DXMesh *d3dxmesh = NULL;
+ struct mesh mesh = {0};
+ char name[256];
+ OUTLINETEXTMETRICA otm;
+ GLYPHMETRICS gm;
+ struct glyphinfo *glyphs;
+ GLYPHMETRICSFLOAT *glyphmetrics_float = HeapAlloc(GetProcessHeap(), 0, sizeof(GLYPHMETRICSFLOAT) * strlen(text));
+ int i;
+ LOGFONTA lf;
+ float offset_x;
+ size_t textlen;
+ HFONT font = NULL, oldfont = NULL;
+ char *raw_outline;
+
+ sprintf(name, "text ('%s', %f, %f)", text, deviation, extrusion);
+
+ hr = D3DXCreateTextA(device, hdc, text, deviation, extrusion, &d3dxmesh, NULL, glyphmetrics_float);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+
+ /* must select a modified font having lfHeight = otm.otmEMSquare before
+ * calling GetGlyphOutline to get the expected values */
+ ok(GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf), "Failed to get current DC font.\n");
+ ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "Failed to get DC font outline.\n");
+ lf.lfHeight = otm.otmEMSquare;
+ lf.lfWidth = 0;
+ ok(!!(font = CreateFontIndirectA(&lf)), "Failed to create font.\n");
+
+ textlen = strlen(text);
+ glyphs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, textlen * sizeof(*glyphs));
+ oldfont = SelectObject(hdc, font);
+
+ for (i = 0; i < textlen; i++)
+ {
+ GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, 0, NULL, &identity);
+ compare_float(glyphmetrics_float[i].gmfBlackBoxX, gm.gmBlackBoxX / (float)otm.otmEMSquare);
+ compare_float(glyphmetrics_float[i].gmfBlackBoxY, gm.gmBlackBoxY / (float)otm.otmEMSquare);
+ compare_float(glyphmetrics_float[i].gmfptGlyphOrigin.x, gm.gmptGlyphOrigin.x / (float)otm.otmEMSquare);
+ compare_float(glyphmetrics_float[i].gmfptGlyphOrigin.y, gm.gmptGlyphOrigin.y / (float)otm.otmEMSquare);
+ compare_float(glyphmetrics_float[i].gmfCellIncX, gm.gmCellIncX / (float)otm.otmEMSquare);
+ compare_float(glyphmetrics_float[i].gmfCellIncY, gm.gmCellIncY / (float)otm.otmEMSquare);
+ }
+
+ if (deviation == 0.0f)
+ deviation = 1.0f / otm.otmEMSquare;
+
+ offset_x = 0.0f;
+ for (i = 0; i < textlen; i++)
+ {
+ DWORD datasize;
+
+ glyphs[i].offset_x = offset_x;
+
+ datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, 0, NULL, &identity);
+ ok(datasize != GDI_ERROR, "Failed to retrieve GDI glyph outline size.\n");
+ raw_outline = HeapAlloc(GetProcessHeap(), 0, datasize);
+ datasize = GetGlyphOutlineA(hdc, text[i], GGO_NATIVE, &gm, datasize, raw_outline, &identity);
+ ok(datasize != GDI_ERROR, "Failed to retrieve GDI glyph outline.\n");
+ create_outline(&glyphs[i], raw_outline, datasize, deviation, otm.otmEMSquare);
+ HeapFree(GetProcessHeap(), 0, raw_outline);
+
+ offset_x += gm.gmCellIncX / (float)otm.otmEMSquare;
+ }
+
+ SelectObject(hdc, oldfont);
+
+ compute_text_mesh(&mesh, text, deviation, extrusion, otm.otmEMSquare, glyphs);
+ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
+
+ compare_text_outline_mesh(name, d3dxmesh, &mesh, textlen, extrusion, glyphs);
+
+ free_mesh(&mesh);
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+ DeleteObject(font);
+ HeapFree(GetProcessHeap(), 0, glyphmetrics_float);
+
+ for (i = 0; i < textlen; i++)
+ free_glyphinfo(&glyphs[i]);
+ HeapFree(GetProcessHeap(), 0, glyphs);
+}
+
+static void D3DXCreateTextTest(void)
+{
+ HRESULT hr;
+ HDC hdc;
+ IDirect3DDevice9* device;
+ ID3DXMesh* d3dxmesh = NULL;
+ HFONT hFont;
+ OUTLINETEXTMETRICA otm;
+ int number_of_vertices;
+ int number_of_faces;
+ struct test_context *test_context;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hdc = CreateCompatibleDC(NULL);
+
+ hFont = CreateFontA(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
+ SelectObject(hdc, hFont);
+ GetOutlineTextMetricsA(hdc, sizeof(otm), &otm);
+
+ hr = D3DXCreateTextA(device, hdc, "wine", 0.001f, 0.4f, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ /* D3DXCreateTextA page faults from passing NULL text */
+
+ hr = D3DXCreateTextW(device, hdc, NULL, 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(device, hdc, "", 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(device, hdc, " ", 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(NULL, hdc, "wine", 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(device, NULL, "wine", 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(device, hdc, "wine", -FLT_MIN, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextA(device, hdc, "wine", 0.001f, -FLT_MIN, &d3dxmesh, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ /* deviation = 0.0f treated as if deviation = 1.0f / otm.otmEMSquare */
+ hr = D3DXCreateTextA(device, hdc, "wine", 1.0f / otm.otmEMSquare, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ number_of_vertices = d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh);
+ number_of_faces = d3dxmesh->lpVtbl->GetNumFaces(d3dxmesh);
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+
+ hr = D3DXCreateTextA(device, hdc, "wine", 0.0f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(number_of_vertices == d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh),
+ "Got %d vertices, expected %d\n",
+ d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh), number_of_vertices);
+ ok(number_of_faces == d3dxmesh->lpVtbl->GetNumFaces(d3dxmesh),
+ "Got %d faces, expected %d\n",
+ d3dxmesh->lpVtbl->GetNumVertices(d3dxmesh), number_of_faces);
+ d3dxmesh->lpVtbl->Release(d3dxmesh);
+
+if (0)
+{
+ /* too much detail requested, so will appear to hang */
+ trace("Waiting for D3DXCreateText to finish with deviation = FLT_MIN ...\n");
+ hr = D3DXCreateTextA(device, hdc, "wine", FLT_MIN, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (SUCCEEDED(hr) && d3dxmesh) d3dxmesh->lpVtbl->Release(d3dxmesh);
+ trace("D3DXCreateText finish with deviation = FLT_MIN\n");
+}
+
+ hr = D3DXCreateTextA(device, hdc, "wine", 0.001f, 0.4f, &d3dxmesh, NULL, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (SUCCEEDED(hr) && d3dxmesh) d3dxmesh->lpVtbl->Release(d3dxmesh);
+
+ test_createtext(device, hdc, "wine", FLT_MAX, 0.4f);
+ test_createtext(device, hdc, "wine", 0.001f, FLT_MIN);
+ test_createtext(device, hdc, "wine", 0.001f, 0.0f);
+ test_createtext(device, hdc, "wine", 0.001f, FLT_MAX);
+ test_createtext(device, hdc, "wine", 0.0f, 1.0f);
+ test_createtext(device, hdc, " wine", 1.0f, 0.0f);
+ test_createtext(device, hdc, "wine ", 1.0f, 0.0f);
+ test_createtext(device, hdc, "wi ne", 1.0f, 0.0f);
+
+ DeleteDC(hdc);
+ DeleteObject(hFont);
+
+ free_test_context(test_context);
+}
+
+static void test_get_decl_length(void)
+{
+ static const D3DVERTEXELEMENT9 declaration1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 0, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 0, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {8, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {9, 0, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {10, 0, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {11, 0, D3DDECLTYPE_UDEC3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {12, 0, D3DDECLTYPE_DEC3N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {13, 0, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {14, 0, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ static const D3DVERTEXELEMENT9 declaration2[] =
+ {
+ {0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 8, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 8, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 8, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 8, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 8, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 8, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 8, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 8, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 8, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 8, D3DDECLTYPE_UDEC3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 8, D3DDECLTYPE_DEC3N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 8, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 8, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ UINT size;
+
+ size = D3DXGetDeclLength(declaration1);
+ ok(size == 15, "Got size %u, expected 15.\n", size);
+
+ size = D3DXGetDeclLength(declaration2);
+ ok(size == 16, "Got size %u, expected 16.\n", size);
+}
+
+static void test_get_decl_vertex_size(void)
+{
+ static const D3DVERTEXELEMENT9 declaration1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 0, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 0, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {8, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {9, 0, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {10, 0, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {11, 0, D3DDECLTYPE_UDEC3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {12, 0, D3DDECLTYPE_DEC3N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {13, 0, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {14, 0, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ static const D3DVERTEXELEMENT9 declaration2[] =
+ {
+ {0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 8, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 8, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 8, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 8, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 8, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 8, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 8, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 8, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {2, 8, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {3, 8, D3DDECLTYPE_UDEC3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {4, 8, D3DDECLTYPE_DEC3N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {5, 8, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {6, 8, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {7, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END(),
+ };
+ static const UINT sizes1[] =
+ {
+ 4, 8, 12, 16,
+ 4, 4, 4, 8,
+ 4, 4, 8, 4,
+ 4, 4, 8, 0,
+ };
+ static const UINT sizes2[] =
+ {
+ 12, 16, 20, 24,
+ 12, 12, 16, 16,
+ };
+ unsigned int i;
+ UINT size;
+
+ size = D3DXGetDeclVertexSize(NULL, 0);
+ ok(size == 0, "Got size %#x, expected 0.\n", size);
+
+ for (i = 0; i < 16; ++i)
+ {
+ size = D3DXGetDeclVertexSize(declaration1, i);
+ ok(size == sizes1[i], "Got size %u for stream %u, expected %u.\n", size, i, sizes1[i]);
+ }
+
+ for (i = 0; i < 8; ++i)
+ {
+ size = D3DXGetDeclVertexSize(declaration2, i);
+ ok(size == sizes2[i], "Got size %u for stream %u, expected %u.\n", size, i, sizes2[i]);
+ }
+}
+
+static void D3DXGenerateAdjacencyTest(void)
+{
+ HRESULT hr;
+ IDirect3DDevice9 *device;
+ ID3DXMesh *d3dxmesh = NULL;
+ D3DXVECTOR3 *vertices = NULL;
+ WORD *indices = NULL;
+ int i;
+ struct {
+ DWORD num_vertices;
+ D3DXVECTOR3 vertices[6];
+ DWORD num_faces;
+ WORD indices[3 * 3];
+ FLOAT epsilon;
+ DWORD adjacency[3 * 3];
+ } test_data[] = {
+ { /* for epsilon < 0, indices must match for faces to be adjacent */
+ 4, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
+ 2, {0, 1, 2, 0, 2, 3},
+ -1.0,
+ {-1, -1, 1, 0, -1, -1},
+ },
+ {
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
+ 2, {0, 1, 2, 3, 4, 5},
+ -1.0,
+ {-1, -1, -1, -1, -1, -1},
+ },
+ { /* for epsilon == 0, indices or vertices must match for faces to be adjacent */
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
+ 2, {0, 1, 2, 3, 4, 5},
+ 0.0,
+ {-1, -1, 1, 0, -1, -1},
+ },
+ { /* for epsilon > 0, vertices must be less than (but NOT equal to) epsilon distance away */
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.25}, {1.0, 1.0, 0.25}, {0.0, 1.0, 0.25}},
+ 2, {0, 1, 2, 3, 4, 5},
+ 0.25,
+ {-1, -1, -1, -1, -1, -1},
+ },
+ { /* for epsilon > 0, vertices must be less than (but NOT equal to) epsilon distance away */
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.0, 0.25}, {1.0, 1.0, 0.25}, {0.0, 1.0, 0.25}},
+ 2, {0, 1, 2, 3, 4, 5},
+ 0.250001,
+ {-1, -1, 1, 0, -1, -1},
+ },
+ { /* length between vertices are compared to epsilon, not the individual dimension deltas */
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.25, 0.25}, {1.0, 1.25, 0.25}, {0.0, 1.25, 0.25}},
+ 2, {0, 1, 2, 3, 4, 5},
+ 0.353, /* < sqrt(0.25*0.25 + 0.25*0.25) */
+ {-1, -1, -1, -1, -1, -1},
+ },
+ {
+ 6, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 0.25, 0.25}, {1.0, 1.25, 0.25}, {0.0, 1.25, 0.25}},
+ 2, {0, 1, 2, 3, 4, 5},
+ 0.354, /* > sqrt(0.25*0.25 + 0.25*0.25) */
+ {-1, -1, 1, 0, -1, -1},
+ },
+ { /* adjacent faces must have opposite winding orders at the shared edge */
+ 4, {{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}},
+ 2, {0, 1, 2, 0, 3, 2},
+ 0.0,
+ {-1, -1, -1, -1, -1, -1},
+ },
+ };
+ struct test_context *test_context;
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ for (i = 0; i < ARRAY_SIZE(test_data); i++)
+ {
+ DWORD adjacency[ARRAY_SIZE(test_data[0].adjacency)];
+ int j;
+
+ if (d3dxmesh) d3dxmesh->lpVtbl->Release(d3dxmesh);
+ d3dxmesh = NULL;
+
+ hr = D3DXCreateMeshFVF(test_data[i].num_faces, test_data[i].num_vertices, 0, D3DFVF_XYZ, device, &d3dxmesh);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+
+ hr = d3dxmesh->lpVtbl->LockVertexBuffer(d3dxmesh, D3DLOCK_DISCARD, (void**)&vertices);
+ ok(hr == D3D_OK, "test %d: Got result %x, expected %x (D3D_OK)\n", i, hr, D3D_OK);
+ if (FAILED(hr)) continue;
+ CopyMemory(vertices, test_data[i].vertices, test_data[i].num_vertices * sizeof(test_data[0].vertices[0]));
+ d3dxmesh->lpVtbl->UnlockVertexBuffer(d3dxmesh);
+
+ hr = d3dxmesh->lpVtbl->LockIndexBuffer(d3dxmesh, D3DLOCK_DISCARD, (void**)&indices);
+ ok(hr == D3D_OK, "test %d: Got result %x, expected %x (D3D_OK)\n", i, hr, D3D_OK);
+ if (FAILED(hr)) continue;
+ CopyMemory(indices, test_data[i].indices, test_data[i].num_faces * 3 * sizeof(test_data[0].indices[0]));
+ d3dxmesh->lpVtbl->UnlockIndexBuffer(d3dxmesh);
+
+ if (i == 0) {
+ hr = d3dxmesh->lpVtbl->GenerateAdjacency(d3dxmesh, 0.0f, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ }
+
+ hr = d3dxmesh->lpVtbl->GenerateAdjacency(d3dxmesh, test_data[i].epsilon, adjacency);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ if (FAILED(hr)) continue;
+
+ for (j = 0; j < test_data[i].num_faces * 3; j++)
+ ok(adjacency[j] == test_data[i].adjacency[j],
+ "Test %d adjacency %d: Got result %u, expected %u\n", i, j,
+ adjacency[j], test_data[i].adjacency[j]);
+ }
+ if (d3dxmesh) d3dxmesh->lpVtbl->Release(d3dxmesh);
+
+ free_test_context(test_context);
+}
+
+static void test_update_semantics(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ ID3DXMesh *mesh = NULL;
+ D3DVERTEXELEMENT9 declaration0[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_pos_type_color[] =
+ {
+ {0, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_smaller[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_larger[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ {0, 40, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_multiple_streams[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_double_usage[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_undefined_type[] =
+ {
+ {0, 0, D3DDECLTYPE_UNUSED+1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_not_4_byte_aligned_offset[] =
+ {
+ {0, 3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ static const struct
+ {
+ D3DXVECTOR3 position0;
+ D3DXVECTOR3 position1;
+ D3DXVECTOR3 normal;
+ DWORD color;
+ }
+ vertices[] =
+ {
+ { { 0.0f, 1.0f, 0.f}, { 1.0f, 0.0f, 0.f}, {0.0f, 0.0f, 1.0f}, 0xffff0000 },
+ { { 1.0f, -1.0f, 0.f}, {-1.0f, -1.0f, 0.f}, {0.0f, 0.0f, 1.0f}, 0xff00ff00 },
+ { {-1.0f, -1.0f, 0.f}, {-1.0f, 1.0f, 0.f}, {0.0f, 0.0f, 1.0f}, 0xff0000ff },
+ };
+ unsigned int faces[] = {0, 1, 2};
+ unsigned int attributes[] = {0};
+ unsigned int num_faces = ARRAY_SIZE(faces) / 3;
+ unsigned int num_vertices = ARRAY_SIZE(vertices);
+ int offset = sizeof(D3DXVECTOR3);
+ DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ void *vertex_buffer;
+ void *index_buffer;
+ DWORD *attributes_buffer;
+ D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE];
+ D3DVERTEXELEMENT9 *decl_ptr;
+ DWORD exp_vertex_size = sizeof(*vertices);
+ DWORD vertex_size = 0;
+ int equal;
+ int i = 0;
+ int *decl_mem;
+ int filler_a = 0xaaaaaaaa;
+ int filler_b = 0xbbbbbbbb;
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create a test_context\n");
+ goto cleanup;
+ }
+
+ hr = D3DXCreateMesh(num_faces, num_vertices, options, declaration0,
+ test_context->device, &mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't create test mesh %#x\n", hr);
+ goto cleanup;
+ }
+
+ mesh->lpVtbl->LockVertexBuffer(mesh, 0, &vertex_buffer);
+ memcpy(vertex_buffer, vertices, sizeof(vertices));
+ mesh->lpVtbl->UnlockVertexBuffer(mesh);
+
+ mesh->lpVtbl->LockIndexBuffer(mesh, 0, &index_buffer);
+ memcpy(index_buffer, faces, sizeof(faces));
+ mesh->lpVtbl->UnlockIndexBuffer(mesh);
+
+ mesh->lpVtbl->LockAttributeBuffer(mesh, 0, &attributes_buffer);
+ memcpy(attributes_buffer, attributes, sizeof(attributes));
+ mesh->lpVtbl->UnlockAttributeBuffer(mesh);
+
+ /* Get the declaration and try to change it */
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ if (FAILED(hr))
+ {
+ skip("Couldn't get vertex declaration %#x\n", hr);
+ goto cleanup;
+ }
+ equal = memcmp(declaration, declaration0, sizeof(declaration0));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ for (decl_ptr = declaration; decl_ptr->Stream != 0xFF; decl_ptr++)
+ {
+ if (decl_ptr->Usage == D3DDECLUSAGE_POSITION)
+ {
+ /* Use second vertex position instead of first */
+ decl_ptr->Offset = offset;
+ }
+ }
+
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration);
+ ok(hr == D3D_OK, "Test UpdateSemantics, got %#x expected %#x\n", hr, D3D_OK);
+
+ /* Check that declaration was written by getting it again */
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ if (FAILED(hr))
+ {
+ skip("Couldn't get vertex declaration %#x\n", hr);
+ goto cleanup;
+ }
+
+ for (decl_ptr = declaration; decl_ptr->Stream != 0xFF; decl_ptr++)
+ {
+ if (decl_ptr->Usage == D3DDECLUSAGE_POSITION)
+ {
+ ok(decl_ptr->Offset == offset, "Test UpdateSemantics, got offset %d expected %d\n",
+ decl_ptr->Offset, offset);
+ }
+ }
+
+ /* Check that GetDeclaration only writes up to the D3DDECL_END() marker and
+ * not the full MAX_FVF_DECL_SIZE elements.
+ */
+ memset(declaration, filler_a, sizeof(declaration));
+ memcpy(declaration, declaration0, sizeof(declaration0));
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration);
+ ok(hr == D3D_OK, "Test UpdateSemantics, "
+ "got %#x expected D3D_OK\n", hr);
+ memset(declaration, filler_b, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ decl_mem = (int*)declaration;
+ for (i = sizeof(declaration0)/sizeof(*decl_mem); i < sizeof(declaration)/sizeof(*decl_mem); i++)
+ {
+ equal = memcmp(&decl_mem[i], &filler_b, sizeof(filler_b));
+ ok(equal == 0,
+ "GetDeclaration wrote past the D3DDECL_END() marker. "
+ "Got %#x, expected %#x\n", decl_mem[i], filler_b);
+ if (equal != 0) break;
+ }
+
+ /* UpdateSemantics does not check for overlapping fields */
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ if (FAILED(hr))
+ {
+ skip("Couldn't get vertex declaration %#x\n", hr);
+ goto cleanup;
+ }
+
+ for (decl_ptr = declaration; decl_ptr->Stream != 0xFF; decl_ptr++)
+ {
+ if (decl_ptr->Type == D3DDECLTYPE_FLOAT3)
+ {
+ decl_ptr->Type = D3DDECLTYPE_FLOAT4;
+ }
+ }
+
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration);
+ ok(hr == D3D_OK, "Test UpdateSemantics for overlapping fields, "
+ "got %#x expected D3D_OK\n", hr);
+
+ /* Set the position type to color instead of float3 */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_pos_type_color);
+ ok(hr == D3D_OK, "Test UpdateSemantics position type color, "
+ "got %#x expected D3D_OK\n", hr);
+
+ /* The following test cases show that NULL, smaller or larger declarations,
+ * and declarations with non-zero Stream values are not accepted.
+ * UpdateSemantics returns D3DERR_INVALIDCALL and the previously set
+ * declaration will be used by DrawSubset, GetNumBytesPerVertex, and
+ * GetDeclaration.
+ */
+
+ /* Null declaration (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Test UpdateSemantics null pointer declaration, "
+ "got %#x expected D3DERR_INVALIDCALL\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration0, sizeof(declaration0));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* Smaller vertex declaration (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_smaller);
+ ok(hr == D3DERR_INVALIDCALL, "Test UpdateSemantics for smaller vertex declaration, "
+ "got %#x expected D3DERR_INVALIDCALL\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration0, sizeof(declaration0));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* Larger vertex declaration (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_larger);
+ ok(hr == D3DERR_INVALIDCALL, "Test UpdateSemantics for larger vertex declaration, "
+ "got %#x expected D3DERR_INVALIDCALL\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration0, sizeof(declaration0));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* Use multiple streams and keep the same vertex size (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_multiple_streams);
+ ok(hr == D3DERR_INVALIDCALL, "Test UpdateSemantics using multiple streams, "
+ "got %#x expected D3DERR_INVALIDCALL\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration0, sizeof(declaration0));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* The next following test cases show that some invalid declarations are
+ * accepted with a D3D_OK. An access violation is thrown on Windows if
+ * DrawSubset is called. The methods GetNumBytesPerVertex and GetDeclaration
+ * are not affected, which indicates that the declaration is cached.
+ */
+
+ /* Double usage (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_double_usage);
+ ok(hr == D3D_OK, "Test UpdateSemantics double usage, "
+ "got %#x expected D3D_OK\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration_double_usage, sizeof(declaration_double_usage));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* Set the position to an undefined type (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_undefined_type);
+ ok(hr == D3D_OK, "Test UpdateSemantics undefined type, "
+ "got %#x expected D3D_OK\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration_undefined_type, sizeof(declaration_undefined_type));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+ /* Use a not 4 byte aligned offset (invalid declaration) */
+ mesh->lpVtbl->UpdateSemantics(mesh, declaration0); /* Set a valid declaration */
+ hr = mesh->lpVtbl->UpdateSemantics(mesh, declaration_not_4_byte_aligned_offset);
+ ok(hr == D3D_OK, "Test UpdateSemantics not 4 byte aligned offset, "
+ "got %#x expected D3D_OK\n", hr);
+ vertex_size = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+ ok(vertex_size == exp_vertex_size, "Got vertex declaration size %u, expected %u\n",
+ vertex_size, exp_vertex_size);
+ memset(declaration, 0, sizeof(declaration));
+ hr = mesh->lpVtbl->GetDeclaration(mesh, declaration);
+ ok(hr == D3D_OK, "Couldn't get vertex declaration. Got %#x, expected D3D_OK\n", hr);
+ equal = memcmp(declaration, declaration_not_4_byte_aligned_offset,
+ sizeof(declaration_not_4_byte_aligned_offset));
+ ok(equal == 0, "Vertex declarations were not equal\n");
+
+cleanup:
+ if (mesh)
+ mesh->lpVtbl->Release(mesh);
+
+ free_test_context(test_context);
+}
+
+static void test_create_skin_info(void)
+{
+ HRESULT hr;
+ ID3DXSkinInfo *skininfo = NULL;
+ D3DVERTEXELEMENT9 empty_declaration[] = { D3DDECL_END() };
+ D3DVERTEXELEMENT9 declaration_out[MAX_FVF_DECL_SIZE];
+ const D3DVERTEXELEMENT9 declaration_with_nonzero_stream[] = {
+ {1, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END()
+ };
+
+ hr = D3DXCreateSkinInfo(0, empty_declaration, 0, &skininfo);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (skininfo) IUnknown_Release(skininfo);
+ skininfo = NULL;
+
+ hr = D3DXCreateSkinInfo(1, NULL, 1, &skininfo);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXCreateSkinInfo(1, declaration_with_nonzero_stream, 1, &skininfo);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXCreateSkinInfoFVF(1, 0, 1, &skininfo);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (skininfo)
+ {
+ DWORD dword_result;
+ float flt_result;
+ const char *string_result;
+ D3DXMATRIX *transform;
+ D3DXMATRIX identity_matrix;
+
+ /* test initial values */
+ hr = skininfo->lpVtbl->GetDeclaration(skininfo, declaration_out);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ if (SUCCEEDED(hr))
+ compare_elements(declaration_out, empty_declaration, __LINE__, 0);
+
+ dword_result = skininfo->lpVtbl->GetNumBones(skininfo);
+ ok(dword_result == 1, "Expected 1, got %u\n", dword_result);
+
+ flt_result = skininfo->lpVtbl->GetMinBoneInfluence(skininfo);
+ ok(flt_result == 0.0f, "Expected 0.0, got %g\n", flt_result);
+
+ string_result = skininfo->lpVtbl->GetBoneName(skininfo, 0);
+ ok(string_result == NULL, "Expected NULL, got %p\n", string_result);
+
+ dword_result = skininfo->lpVtbl->GetFVF(skininfo);
+ ok(dword_result == 0, "Expected 0, got %u\n", dword_result);
+
+ dword_result = skininfo->lpVtbl->GetNumBoneInfluences(skininfo, 0);
+ ok(dword_result == 0, "Expected 0, got %u\n", dword_result);
+
+ dword_result = skininfo->lpVtbl->GetNumBoneInfluences(skininfo, 1);
+ ok(dword_result == 0, "Expected 0, got %u\n", dword_result);
+
+ transform = skininfo->lpVtbl->GetBoneOffsetMatrix(skininfo, -1);
+ ok(transform == NULL, "Expected NULL, got %p\n", transform);
+
+ {
+ /* test [GS]etBoneOffsetMatrix */
+ hr = skininfo->lpVtbl->SetBoneOffsetMatrix(skininfo, 1, &identity_matrix);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneOffsetMatrix(skininfo, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ D3DXMatrixIdentity(&identity_matrix);
+ hr = skininfo->lpVtbl->SetBoneOffsetMatrix(skininfo, 0, &identity_matrix);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ transform = skininfo->lpVtbl->GetBoneOffsetMatrix(skininfo, 0);
+ check_matrix(transform, &identity_matrix);
+ }
+
+ {
+ /* test [GS]etBoneName */
+ const char *name_in = "testBoneName";
+ const char *string_result2;
+
+ hr = skininfo->lpVtbl->SetBoneName(skininfo, 1, name_in);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneName(skininfo, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneName(skininfo, 0, name_in);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ string_result = skininfo->lpVtbl->GetBoneName(skininfo, 0);
+ ok(string_result != NULL, "Expected non-NULL string, got %p\n", string_result);
+ ok(!strcmp(string_result, name_in), "Expected '%s', got '%s'\n", name_in, string_result);
+
+ string_result2 = skininfo->lpVtbl->GetBoneName(skininfo, 0);
+ ok(string_result == string_result2, "Expected %p, got %p\n", string_result, string_result2);
+
+ string_result = skininfo->lpVtbl->GetBoneName(skininfo, 1);
+ ok(string_result == NULL, "Expected NULL, got %p\n", string_result);
+ }
+
+ {
+ /* test [GS]etBoneInfluence */
+ DWORD vertices[2];
+ FLOAT weights[2];
+ int i;
+ DWORD num_influences;
+ DWORD exp_vertices[2];
+ FLOAT exp_weights[2];
+
+ /* vertex and weight arrays untouched when num_influences is 0 */
+ vertices[0] = 0xdeadbeef;
+ weights[0] = FLT_MAX;
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, vertices, weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok(vertices[0] == 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", vertices[0]);
+ ok(weights[0] == FLT_MAX, "expected %g, got %g\n", FLT_MAX, weights[0]);
+
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 1, vertices, weights);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, vertices, NULL);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, NULL, weights);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+
+ /* no vertex or weight value checking */
+ exp_vertices[0] = 0;
+ exp_vertices[1] = 0x87654321;
+ exp_weights[0] = 0.5;
+ exp_weights[1] = NAN;
+ num_influences = 2;
+
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 1, num_influences, vertices, weights);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, num_influences, NULL, weights);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, num_influences, vertices, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, num_influences, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, num_influences, exp_vertices, exp_weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ memset(vertices, 0, sizeof(vertices));
+ memset(weights, 0, sizeof(weights));
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, vertices, weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ for (i = 0; i < num_influences; i++) {
+ ok(exp_vertices[i] == vertices[i],
+ "influence[%d]: expected vertex %u, got %u\n", i, exp_vertices[i], vertices[i]);
+ ok((isnan(exp_weights[i]) && isnan(weights[i])) || exp_weights[i] == weights[i],
+ "influence[%d]: expected weights %g, got %g\n", i, exp_weights[i], weights[i]);
+ }
+
+ /* vertices and weights aren't returned after setting num_influences to 0 */
+ memset(vertices, 0, sizeof(vertices));
+ memset(weights, 0, sizeof(weights));
+ hr = skininfo->lpVtbl->SetBoneInfluence(skininfo, 0, 0, vertices, weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ vertices[0] = 0xdeadbeef;
+ weights[0] = FLT_MAX;
+ hr = skininfo->lpVtbl->GetBoneInfluence(skininfo, 0, vertices, weights);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ ok(vertices[0] == 0xdeadbeef, "expected vertex 0xdeadbeef, got %u\n", vertices[0]);
+ ok(weights[0] == FLT_MAX, "expected weight %g, got %g\n", FLT_MAX, weights[0]);
+ }
+
+ {
+ /* test [GS]etFVF and [GS]etDeclaration */
+ D3DVERTEXELEMENT9 declaration_in[MAX_FVF_DECL_SIZE];
+ DWORD fvf = D3DFVF_XYZ;
+ DWORD got_fvf;
+
+ hr = skininfo->lpVtbl->SetDeclaration(skininfo, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetDeclaration(skininfo, declaration_with_nonzero_stream);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = skininfo->lpVtbl->SetFVF(skininfo, 0);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+
+ hr = D3DXDeclaratorFromFVF(fvf, declaration_in);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ hr = skininfo->lpVtbl->SetDeclaration(skininfo, declaration_in);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ got_fvf = skininfo->lpVtbl->GetFVF(skininfo);
+ ok(fvf == got_fvf, "Expected %#x, got %#x\n", fvf, got_fvf);
+ hr = skininfo->lpVtbl->GetDeclaration(skininfo, declaration_out);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ compare_elements(declaration_out, declaration_in, __LINE__, 0);
+
+ hr = skininfo->lpVtbl->SetDeclaration(skininfo, empty_declaration);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ got_fvf = skininfo->lpVtbl->GetFVF(skininfo);
+ ok(got_fvf == 0, "Expected 0, got %#x\n", got_fvf);
+ hr = skininfo->lpVtbl->GetDeclaration(skininfo, declaration_out);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ compare_elements(declaration_out, empty_declaration, __LINE__, 0);
+
+ hr = skininfo->lpVtbl->SetFVF(skininfo, fvf);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ got_fvf = skininfo->lpVtbl->GetFVF(skininfo);
+ ok(fvf == got_fvf, "Expected %#x, got %#x\n", fvf, got_fvf);
+ hr = skininfo->lpVtbl->GetDeclaration(skininfo, declaration_out);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ compare_elements(declaration_out, declaration_in, __LINE__, 0);
+ }
+ }
+ if (skininfo) IUnknown_Release(skininfo);
+ skininfo = NULL;
+
+ hr = D3DXCreateSkinInfoFVF(1, D3DFVF_XYZ, 1, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+
+ hr = D3DXCreateSkinInfo(1, NULL, 1, &skininfo);
+ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, got %#x\n", hr);
+}
+
+static void test_convert_adjacency_to_point_reps(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ const DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ const DWORD options_16bit = D3DXMESH_SYSTEMMEM;
+ const D3DVERTEXELEMENT9 declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ const unsigned int VERTS_PER_FACE = 3;
+ void *vertex_buffer;
+ void *index_buffer;
+ DWORD *attributes_buffer;
+ int i, j;
+ enum color { RED = 0xffff0000, GREEN = 0xff00ff00, BLUE = 0xff0000ff};
+ struct vertex_pnc
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ enum color color; /* In case of manual visual inspection */
+ };
+#ifndef __REACTOS__
+ D3DXVECTOR3 up = {0.0f, 0.0f, 1.0f};
+#else
+#define up {0.0f, 0.0f, 1.0f}
+#endif
+ /* mesh0 (one face)
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ const struct vertex_pnc vertices0[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices0[] = {0, 1, 2};
+ const unsigned int num_vertices0 = ARRAY_SIZE(vertices0);
+ const unsigned int num_faces0 = ARRAY_SIZE(indices0) / VERTS_PER_FACE;
+ const DWORD adjacency0[] = {-1, -1, -1};
+ const DWORD exp_point_rep0[] = {0, 1, 2};
+ /* mesh1 (right)
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_pnc vertices1[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices1[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices1 = ARRAY_SIZE(vertices1);
+ const unsigned int num_faces1 = ARRAY_SIZE(indices1) / VERTS_PER_FACE;
+ const DWORD adjacency1[] = {-1, 1, -1, -1, -1, 0};
+ const DWORD exp_point_rep1[] = {0, 1, 2, 1, 4, 2};
+ /* mesh2 (left)
+ *
+ * 3 0--1
+ * /| | /
+ * / | |/
+ * 5--4 2
+ */
+ const struct vertex_pnc vertices2[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{-1.0f, 3.0f, 0.f}, up, RED},
+ {{-1.0f, 0.0f, 0.f}, up, GREEN},
+ {{-3.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices2[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices2 = ARRAY_SIZE(vertices2);
+ const unsigned int num_faces2 = ARRAY_SIZE(indices2) / VERTS_PER_FACE;
+ const DWORD adjacency2[] = {-1, -1, 1, 0, -1, -1};
+ const DWORD exp_point_rep2[] = {0, 1, 2, 0, 2, 5};
+ /* mesh3 (above)
+ *
+ * 3
+ * /|
+ * / |
+ * 5--4
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ struct vertex_pnc vertices3[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 2.0f, 7.0f, 0.f}, up, BLUE},
+ {{ 2.0f, 4.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 4.0f, 0.f}, up, RED},
+ };
+ const DWORD indices3[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices3 = ARRAY_SIZE(vertices3);
+ const unsigned int num_faces3 = ARRAY_SIZE(indices3) / VERTS_PER_FACE;
+ const DWORD adjacency3[] = {1, -1, -1, -1, 0, -1};
+ const DWORD exp_point_rep3[] = {0, 1, 2, 3, 1, 0};
+ /* mesh4 (below, tip against tip)
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ * 3
+ * |\
+ * | \
+ * 5--4
+ */
+ struct vertex_pnc vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 0.0f, -4.0f, 0.f}, up, BLUE},
+ {{ 2.0f, -7.0f, 0.f}, up, GREEN},
+ {{ 0.0f, -7.0f, 0.f}, up, RED},
+ };
+ const DWORD indices4[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices4 = ARRAY_SIZE(vertices4);
+ const unsigned int num_faces4 = ARRAY_SIZE(indices4) / VERTS_PER_FACE;
+ const DWORD adjacency4[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD exp_point_rep4[] = {0, 1, 2, 3, 4, 5};
+ /* mesh5 (gap in mesh)
+ *
+ * 0 3-----4 15
+ * / \ \ / / \
+ * / \ \ / / \
+ * 2-----1 5 17-----16
+ * 6-----7 9 12-----13
+ * \ / / \ \ /
+ * \ / / \ \ /
+ * 8 10-----11 14
+ *
+ */
+ const struct vertex_pnc vertices5[] =
+ {
+ {{ 0.0f, 1.0f, 0.f}, up, RED},
+ {{ 1.0f, -1.0f, 0.f}, up, GREEN},
+ {{-1.0f, -1.0f, 0.f}, up, BLUE},
+
+ {{ 0.1f, 1.0f, 0.f}, up, RED},
+ {{ 2.1f, 1.0f, 0.f}, up, BLUE},
+ {{ 1.1f, -1.0f, 0.f}, up, GREEN},
+
+ {{-1.0f, -1.1f, 0.f}, up, BLUE},
+ {{ 1.0f, -1.1f, 0.f}, up, GREEN},
+ {{ 0.0f, -3.1f, 0.f}, up, RED},
+
+ {{ 1.1f, -1.1f, 0.f}, up, GREEN},
+ {{ 2.1f, -3.1f, 0.f}, up, BLUE},
+ {{ 0.1f, -3.1f, 0.f}, up, RED},
+
+ {{ 1.2f, -1.1f, 0.f}, up, GREEN},
+ {{ 3.2f, -1.1f, 0.f}, up, RED},
+ {{ 2.2f, -3.1f, 0.f}, up, BLUE},
+
+ {{ 2.2f, 1.0f, 0.f}, up, BLUE},
+ {{ 3.2f, -1.0f, 0.f}, up, RED},
+ {{ 1.2f, -1.0f, 0.f}, up, GREEN},
+ };
+ const DWORD indices5[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+ const unsigned int num_vertices5 = ARRAY_SIZE(vertices5);
+ const unsigned int num_faces5 = ARRAY_SIZE(indices5) / VERTS_PER_FACE;
+ const DWORD adjacency5[] = {-1, 2, -1, -1, 5, -1, 0, -1, -1, 4, -1, -1, 5, -1, 3, -1, 4, 1};
+ const DWORD exp_point_rep5[] = {0, 1, 2, 3, 4, 5, 2, 1, 8, 5, 10, 11, 5, 13, 10, 4, 13, 5};
+ const WORD indices5_16bit[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+ /* mesh6 (indices re-ordering)
+ *
+ * 0--1 6 3
+ * | / /| |\
+ * |/ / | | \
+ * 2 8--7 5--4
+ */
+ const struct vertex_pnc vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 4.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 6.0f, 0.0f, 0.f}, up, BLUE},
+ {{ 4.0f, 0.0f, 0.f}, up, RED},
+ };
+ const DWORD indices6[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
+ const unsigned int num_vertices6 = ARRAY_SIZE(vertices6);
+ const unsigned int num_faces6 = ARRAY_SIZE(indices6) / VERTS_PER_FACE;
+ const DWORD adjacency6[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
+ const DWORD exp_point_rep6[] = {0, 1, 2, 1, 4, 5, 1, 5, 2};
+ /* mesh7 (expands collapsed triangle)
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_pnc vertices7[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices7[] = {0, 1, 2, 3, 3, 3}; /* Face 1 is collapsed*/
+ const unsigned int num_vertices7 = ARRAY_SIZE(vertices7);
+ const unsigned int num_faces7 = ARRAY_SIZE(indices7) / VERTS_PER_FACE;
+ const DWORD adjacency7[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD exp_point_rep7[] = {0, 1, 2, 3, 4, 5};
+ /* mesh8 (indices re-ordering and double replacement)
+ *
+ * 0--1 9 6
+ * | / /| |\
+ * |/ / | | \
+ * 2 11-10 8--7
+ * 3--4
+ * | /
+ * |/
+ * 5
+ */
+ const struct vertex_pnc vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 4.0, -4.0, 0.f}, up, RED},
+ {{ 6.0, -4.0, 0.f}, up, BLUE},
+ {{ 4.0, -7.0, 0.f}, up, GREEN},
+
+ {{ 4.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 6.0f, 0.0f, 0.f}, up, BLUE},
+ {{ 4.0f, 0.0f, 0.f}, up, RED},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices8[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
+ const unsigned int num_vertices8 = ARRAY_SIZE(vertices8);
+ const unsigned int num_faces8 = ARRAY_SIZE(indices8) / VERTS_PER_FACE;
+ const DWORD adjacency8[] = {-1, 1, -1, 2, -1, 0, -1, 3, 1, 2, -1, -1};
+ const DWORD exp_point_rep8[] = {0, 1, 2, 3, 4, 5, 1, 4, 3, 1, 3, 2};
+ /* mesh9 (right, shared vertices)
+ *
+ * 0--1
+ * | /|
+ * |/ |
+ * 2--3
+ */
+ const struct vertex_pnc vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 2.0f, 0.0f, 0.f}, up, RED},
+ };
+ const DWORD indices9[] = {0, 1, 2, 1, 3, 2};
+ const unsigned int num_vertices9 = ARRAY_SIZE(vertices9);
+ const unsigned int num_faces9 = ARRAY_SIZE(indices9) / VERTS_PER_FACE;
+ const DWORD adjacency9[] = {-1, 1, -1, -1, -1, 0};
+ const DWORD exp_point_rep9[] = {0, 1, 2, 3};
+ /* All mesh data */
+ ID3DXMesh *mesh = NULL;
+ ID3DXMesh *mesh_null_check = NULL;
+ unsigned int attributes[] = {0};
+ struct
+ {
+ const struct vertex_pnc *vertices;
+ const DWORD *indices;
+ const DWORD num_vertices;
+ const DWORD num_faces;
+ const DWORD *adjacency;
+ const DWORD *exp_point_reps;
+ const DWORD options;
+ }
+ tc[] =
+ {
+ {
+ vertices0,
+ indices0,
+ num_vertices0,
+ num_faces0,
+ adjacency0,
+ exp_point_rep0,
+ options
+ },
+ {
+ vertices1,
+ indices1,
+ num_vertices1,
+ num_faces1,
+ adjacency1,
+ exp_point_rep1,
+ options
+ },
+ {
+ vertices2,
+ indices2,
+ num_vertices2,
+ num_faces2,
+ adjacency2,
+ exp_point_rep2,
+ options
+ },
+ {
+ vertices3,
+ indices3,
+ num_vertices3,
+ num_faces3,
+ adjacency3,
+ exp_point_rep3,
+ options
+ },
+ {
+ vertices4,
+ indices4,
+ num_vertices4,
+ num_faces4,
+ adjacency4,
+ exp_point_rep4,
+ options
+ },
+ {
+ vertices5,
+ indices5,
+ num_vertices5,
+ num_faces5,
+ adjacency5,
+ exp_point_rep5,
+ options
+ },
+ {
+ vertices6,
+ indices6,
+ num_vertices6,
+ num_faces6,
+ adjacency6,
+ exp_point_rep6,
+ options
+ },
+ {
+ vertices7,
+ indices7,
+ num_vertices7,
+ num_faces7,
+ adjacency7,
+ exp_point_rep7,
+ options
+ },
+ {
+ vertices8,
+ indices8,
+ num_vertices8,
+ num_faces8,
+ adjacency8,
+ exp_point_rep8,
+ options
+ },
+ {
+ vertices9,
+ indices9,
+ num_vertices9,
+ num_faces9,
+ adjacency9,
+ exp_point_rep9,
+ options
+ },
+ {
+ vertices5,
+ (DWORD*)indices5_16bit,
+ num_vertices5,
+ num_faces5,
+ adjacency5,
+ exp_point_rep5,
+ options_16bit
+ },
+ };
+ DWORD *point_reps = NULL;
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ hr = D3DXCreateMesh(tc[i].num_faces, tc[i].num_vertices, tc[i].options, declaration,
+ test_context->device, &mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't create mesh %d. Got %x expected D3D_OK\n", i, hr);
+ goto cleanup;
+ }
+
+ if (i == 0) /* Save first mesh for later NULL checks */
+ mesh_null_check = mesh;
+
+ point_reps = HeapAlloc(GetProcessHeap(), 0, tc[i].num_vertices * sizeof(*point_reps));
+ if (!point_reps)
+ {
+ skip("Couldn't allocate point reps array.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, &vertex_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock vertex buffer.\n");
+ goto cleanup;
+ }
+ memcpy(vertex_buffer, tc[i].vertices, tc[i].num_vertices * sizeof(*tc[i].vertices));
+ hr = mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock vertex buffer.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, &index_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock index buffer.\n");
+ goto cleanup;
+ }
+ if (tc[i].options & D3DXMESH_32BIT)
+ {
+ memcpy(index_buffer, tc[i].indices, VERTS_PER_FACE * tc[i].num_faces * sizeof(DWORD));
+ }
+ else
+ {
+ memcpy(index_buffer, tc[i].indices, VERTS_PER_FACE * tc[i].num_faces * sizeof(WORD));
+ }
+ hr = mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ if (FAILED(hr)) {
+ skip("Couldn't unlock index buffer.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockAttributeBuffer(mesh, 0, &attributes_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock attributes buffer.\n");
+ goto cleanup;
+ }
+ memcpy(attributes_buffer, attributes, sizeof(attributes));
+ hr = mesh->lpVtbl->UnlockAttributeBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock attributes buffer.\n");
+ goto cleanup;
+ }
+
+ /* Convert adjacency to point representation */
+ for (j = 0; j < tc[i].num_vertices; j++) point_reps[j] = -1;
+ hr = mesh->lpVtbl->ConvertAdjacencyToPointReps(mesh, tc[i].adjacency, point_reps);
+ ok(hr == D3D_OK, "ConvertAdjacencyToPointReps failed case %d. "
+ "Got %x expected D3D_OK\n", i, hr);
+
+ /* Check point representation */
+ for (j = 0; j < tc[i].num_vertices; j++)
+ {
+ ok(point_reps[j] == tc[i].exp_point_reps[j],
+ "Unexpected point representation at (%d, %d)."
+ " Got %d expected %d\n",
+ i, j, point_reps[j], tc[i].exp_point_reps[j]);
+ }
+
+ HeapFree(GetProcessHeap(), 0, point_reps);
+ point_reps = NULL;
+
+ if (i != 0) /* First mesh will be freed during cleanup */
+ mesh->lpVtbl->Release(mesh);
+ }
+
+ /* NULL checks */
+ hr = mesh_null_check->lpVtbl->ConvertAdjacencyToPointReps(mesh_null_check, tc[0].adjacency, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ConvertAdjacencyToPointReps point_reps NULL. "
+ "Got %x expected D3DERR_INVALIDCALL\n", hr);
+ hr = mesh_null_check->lpVtbl->ConvertAdjacencyToPointReps(mesh_null_check, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ConvertAdjacencyToPointReps adjacency and point_reps NULL. "
+ "Got %x expected D3DERR_INVALIDCALL\n", hr);
+
+cleanup:
+ if (mesh_null_check)
+ mesh_null_check->lpVtbl->Release(mesh_null_check);
+ HeapFree(GetProcessHeap(), 0, point_reps);
+ free_test_context(test_context);
+#ifdef __REACTOS__
+#undef up
+#endif
+}
+
+static void test_convert_point_reps_to_adjacency(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ const DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ const DWORD options_16bit = D3DXMESH_SYSTEMMEM;
+ const D3DVERTEXELEMENT9 declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ const unsigned int VERTS_PER_FACE = 3;
+ void *vertex_buffer;
+ void *index_buffer;
+ DWORD *attributes_buffer;
+ int i, j;
+ enum color { RED = 0xffff0000, GREEN = 0xff00ff00, BLUE = 0xff0000ff};
+ struct vertex_pnc
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ enum color color; /* In case of manual visual inspection */
+ };
+#ifndef __REACTOS__
+ D3DXVECTOR3 up = {0.0f, 0.0f, 1.0f};
+#else
+#define up {0.0f, 0.0f, 1.0f}
+#endif
+
+ /* mesh0 (one face)
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ const struct vertex_pnc vertices0[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices0[] = {0, 1, 2};
+ const unsigned int num_vertices0 = ARRAY_SIZE(vertices0);
+ const unsigned int num_faces0 = num_vertices0 / VERTS_PER_FACE;
+ const DWORD exp_adjacency0[] = {-1, -1, -1};
+ const DWORD exp_id_adjacency0[] = {-1, -1, -1};
+ const DWORD point_rep0[] = {0, 1, 2};
+ /* mesh1 (right)
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_pnc vertices1[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices1[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices1 = ARRAY_SIZE(vertices1);
+ const unsigned int num_faces1 = num_vertices1 / VERTS_PER_FACE;
+ const DWORD exp_adjacency1[] = {-1, 1, -1, -1, -1, 0};
+ const DWORD exp_id_adjacency1[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD point_rep1[] = {0, 1, 2, 1, 4, 2};
+ /* mesh2 (left)
+ *
+ * 3 0--1
+ * /| | /
+ * / | |/
+ * 5--4 2
+ */
+ const struct vertex_pnc vertices2[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{-1.0f, 3.0f, 0.f}, up, RED},
+ {{-1.0f, 0.0f, 0.f}, up, GREEN},
+ {{-3.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices2[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices2 = ARRAY_SIZE(vertices2);
+ const unsigned int num_faces2 = num_vertices2 / VERTS_PER_FACE;
+ const DWORD exp_adjacency2[] = {-1, -1, 1, 0, -1, -1};
+ const DWORD exp_id_adjacency2[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD point_rep2[] = {0, 1, 2, 0, 2, 5};
+ /* mesh3 (above)
+ *
+ * 3
+ * /|
+ * / |
+ * 5--4
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ struct vertex_pnc vertices3[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 2.0f, 7.0f, 0.f}, up, BLUE},
+ {{ 2.0f, 4.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 4.0f, 0.f}, up, RED},
+ };
+ const DWORD indices3[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices3 = ARRAY_SIZE(vertices3);
+ const unsigned int num_faces3 = num_vertices3 / VERTS_PER_FACE;
+ const DWORD exp_adjacency3[] = {1, -1, -1, -1, 0, -1};
+ const DWORD exp_id_adjacency3[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD point_rep3[] = {0, 1, 2, 3, 1, 0};
+ /* mesh4 (below, tip against tip)
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ * 3
+ * |\
+ * | \
+ * 5--4
+ */
+ struct vertex_pnc vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 0.0f, -4.0f, 0.f}, up, BLUE},
+ {{ 2.0f, -7.0f, 0.f}, up, GREEN},
+ {{ 0.0f, -7.0f, 0.f}, up, RED},
+ };
+ const DWORD indices4[] = {0, 1, 2, 3, 4, 5};
+ const unsigned int num_vertices4 = ARRAY_SIZE(vertices4);
+ const unsigned int num_faces4 = num_vertices4 / VERTS_PER_FACE;
+ const DWORD exp_adjacency4[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD exp_id_adjacency4[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD point_rep4[] = {0, 1, 2, 3, 4, 5};
+ /* mesh5 (gap in mesh)
+ *
+ * 0 3-----4 15
+ * / \ \ / / \
+ * / \ \ / / \
+ * 2-----1 5 17-----16
+ * 6-----7 9 12-----13
+ * \ / / \ \ /
+ * \ / / \ \ /
+ * 8 10-----11 14
+ *
+ */
+ const struct vertex_pnc vertices5[] =
+ {
+ {{ 0.0f, 1.0f, 0.f}, up, RED},
+ {{ 1.0f, -1.0f, 0.f}, up, GREEN},
+ {{-1.0f, -1.0f, 0.f}, up, BLUE},
+
+ {{ 0.1f, 1.0f, 0.f}, up, RED},
+ {{ 2.1f, 1.0f, 0.f}, up, BLUE},
+ {{ 1.1f, -1.0f, 0.f}, up, GREEN},
+
+ {{-1.0f, -1.1f, 0.f}, up, BLUE},
+ {{ 1.0f, -1.1f, 0.f}, up, GREEN},
+ {{ 0.0f, -3.1f, 0.f}, up, RED},
+
+ {{ 1.1f, -1.1f, 0.f}, up, GREEN},
+ {{ 2.1f, -3.1f, 0.f}, up, BLUE},
+ {{ 0.1f, -3.1f, 0.f}, up, RED},
+
+ {{ 1.2f, -1.1f, 0.f}, up, GREEN},
+ {{ 3.2f, -1.1f, 0.f}, up, RED},
+ {{ 2.2f, -3.1f, 0.f}, up, BLUE},
+
+ {{ 2.2f, 1.0f, 0.f}, up, BLUE},
+ {{ 3.2f, -1.0f, 0.f}, up, RED},
+ {{ 1.2f, -1.0f, 0.f}, up, GREEN},
+ };
+ const DWORD indices5[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
+ const unsigned int num_vertices5 = ARRAY_SIZE(vertices5);
+ const unsigned int num_faces5 = num_vertices5 / VERTS_PER_FACE;
+ const DWORD exp_adjacency5[] = {-1, 2, -1, -1, 5, -1, 0, -1, -1, 4, -1, -1, 5, -1, 3, -1, 4, 1};
+ const DWORD exp_id_adjacency5[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ const DWORD point_rep5[] = {0, 1, 2, 3, 4, 5, 2, 1, 8, 5, 10, 11, 5, 13, 10, 4, 13, 5};
+ /* mesh6 (indices re-ordering)
+ *
+ * 0--1 6 3
+ * | / /| |\
+ * |/ / | | \
+ * 2 8--7 5--4
+ */
+ const struct vertex_pnc vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 4.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 6.0f, 0.0f, 0.f}, up, BLUE},
+ {{ 4.0f, 0.0f, 0.f}, up, RED},
+ };
+ const DWORD indices6[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
+ const unsigned int num_vertices6 = ARRAY_SIZE(vertices6);
+ const unsigned int num_faces6 = num_vertices6 / VERTS_PER_FACE;
+ const DWORD exp_adjacency6[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
+ const DWORD exp_id_adjacency6[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1};
+ const DWORD point_rep6[] = {0, 1, 2, 1, 4, 5, 1, 5, 2};
+ /* mesh7 (expands collapsed triangle)
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_pnc vertices7[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices7[] = {0, 1, 2, 3, 3, 3}; /* Face 1 is collapsed*/
+ const unsigned int num_vertices7 = ARRAY_SIZE(vertices7);
+ const unsigned int num_faces7 = num_vertices7 / VERTS_PER_FACE;
+ const DWORD exp_adjacency7[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD exp_id_adjacency7[] = {-1, -1, -1, -1, -1, -1};
+ const DWORD point_rep7[] = {0, 1, 2, 3, 4, 5};
+ /* mesh8 (indices re-ordering and double replacement)
+ *
+ * 0--1 9 6
+ * | / /| |\
+ * |/ / | | \
+ * 2 11-10 8--7
+ * 3--4
+ * | /
+ * |/
+ * 5
+ */
+ const struct vertex_pnc vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 4.0, -4.0, 0.f}, up, RED},
+ {{ 6.0, -4.0, 0.f}, up, BLUE},
+ {{ 4.0, -7.0, 0.f}, up, GREEN},
+
+ {{ 4.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 6.0f, 0.0f, 0.f}, up, BLUE},
+ {{ 4.0f, 0.0f, 0.f}, up, RED},
+
+ {{ 3.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 3.0f, 0.0f, 0.f}, up, RED},
+ {{ 1.0f, 0.0f, 0.f}, up, BLUE},
+ };
+ const DWORD indices8[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
+ const WORD indices8_16bit[] = {0, 1, 2, 9, 10, 11, 6, 7, 8, 3, 4, 5};
+ const unsigned int num_vertices8 = ARRAY_SIZE(vertices8);
+ const unsigned int num_faces8 = num_vertices8 / VERTS_PER_FACE;
+ const DWORD exp_adjacency8[] = {-1, 1, -1, 2, -1, 0, -1, 3, 1, 2, -1, -1};
+ const DWORD exp_id_adjacency8[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+ const DWORD point_rep8[] = {0, 1, 2, 3, 4, 5, 1, 4, 3, 1, 3, 2};
+ /* mesh9 (right, shared vertices)
+ *
+ * 0--1
+ * | /|
+ * |/ |
+ * 2--3
+ */
+ const struct vertex_pnc vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, RED},
+ {{ 2.0f, 3.0f, 0.f}, up, GREEN},
+ {{ 0.0f, 0.0f, 0.f}, up, BLUE},
+
+ {{ 2.0f, 0.0f, 0.f}, up, RED},
+ };
+ const DWORD indices9[] = {0, 1, 2, 1, 3, 2};
+ const unsigned int num_vertices9 = ARRAY_SIZE(vertices9);
+ const unsigned int num_faces9 = 2;
+ const DWORD exp_adjacency9[] = {-1, 1, -1, -1, -1, 0};
+ const DWORD exp_id_adjacency9[] = {-1, 1, -1, -1, -1, 0};
+ const DWORD point_rep9[] = {0, 1, 2, 3};
+ /* All mesh data */
+ ID3DXMesh *mesh = NULL;
+ ID3DXMesh *mesh_null_check = NULL;
+ unsigned int attributes[] = {0};
+ struct
+ {
+ const struct vertex_pnc *vertices;
+ const DWORD *indices;
+ const DWORD num_vertices;
+ const DWORD num_faces;
+ const DWORD *point_reps;
+ const DWORD *exp_adjacency;
+ const DWORD *exp_id_adjacency;
+ const DWORD options;
+ }
+ tc[] =
+ {
+ {
+ vertices0,
+ indices0,
+ num_vertices0,
+ num_faces0,
+ point_rep0,
+ exp_adjacency0,
+ exp_id_adjacency0,
+ options
+ },
+ {
+ vertices1,
+ indices1,
+ num_vertices1,
+ num_faces1,
+ point_rep1,
+ exp_adjacency1,
+ exp_id_adjacency1,
+ options
+ },
+ {
+ vertices2,
+ indices2,
+ num_vertices2,
+ num_faces2,
+ point_rep2,
+ exp_adjacency2,
+ exp_id_adjacency2,
+ options
+ },
+ {
+ vertices3,
+ indices3,
+ num_vertices3,
+ num_faces3,
+ point_rep3,
+ exp_adjacency3,
+ exp_id_adjacency3,
+ options
+ },
+ {
+ vertices4,
+ indices4,
+ num_vertices4,
+ num_faces4,
+ point_rep4,
+ exp_adjacency4,
+ exp_id_adjacency4,
+ options
+ },
+ {
+ vertices5,
+ indices5,
+ num_vertices5,
+ num_faces5,
+ point_rep5,
+ exp_adjacency5,
+ exp_id_adjacency5,
+ options
+ },
+ {
+ vertices6,
+ indices6,
+ num_vertices6,
+ num_faces6,
+ point_rep6,
+ exp_adjacency6,
+ exp_id_adjacency6,
+ options
+ },
+ {
+ vertices7,
+ indices7,
+ num_vertices7,
+ num_faces7,
+ point_rep7,
+ exp_adjacency7,
+ exp_id_adjacency7,
+ options
+ },
+ {
+ vertices8,
+ indices8,
+ num_vertices8,
+ num_faces8,
+ point_rep8,
+ exp_adjacency8,
+ exp_id_adjacency8,
+ options
+ },
+ {
+ vertices9,
+ indices9,
+ num_vertices9,
+ num_faces9,
+ point_rep9,
+ exp_adjacency9,
+ exp_id_adjacency9,
+ options
+ },
+ {
+ vertices8,
+ (DWORD*)indices8_16bit,
+ num_vertices8,
+ num_faces8,
+ point_rep8,
+ exp_adjacency8,
+ exp_id_adjacency8,
+ options_16bit
+ },
+ };
+ DWORD *adjacency = NULL;
+#ifdef __REACTOS__
+#undef up
+#endif
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ hr = D3DXCreateMesh(tc[i].num_faces, tc[i].num_vertices, tc[i].options,
+ declaration, test_context->device, &mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't create mesh %d. Got %x expected D3D_OK\n", i, hr);
+ goto cleanup;
+ }
+
+ if (i == 0) /* Save first mesh for later NULL checks */
+ mesh_null_check = mesh;
+
+ adjacency = HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE * tc[i].num_faces * sizeof(*adjacency));
+ if (!adjacency)
+ {
+ skip("Couldn't allocate adjacency array.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, &vertex_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock vertex buffer.\n");
+ goto cleanup;
+ }
+ memcpy(vertex_buffer, tc[i].vertices, tc[i].num_vertices * sizeof(*tc[i].vertices));
+ hr = mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock vertex buffer.\n");
+ goto cleanup;
+ }
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, &index_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock index buffer.\n");
+ goto cleanup;
+ }
+ if (tc[i].options & D3DXMESH_32BIT)
+ {
+ memcpy(index_buffer, tc[i].indices, VERTS_PER_FACE * tc[i].num_faces * sizeof(DWORD));
+ }
+ else
+ {
+ memcpy(index_buffer, tc[i].indices, VERTS_PER_FACE * tc[i].num_faces * sizeof(WORD));
+ }
+ hr = mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ if (FAILED(hr)) {
+ skip("Couldn't unlock index buffer.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockAttributeBuffer(mesh, 0, &attributes_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock attributes buffer.\n");
+ goto cleanup;
+ }
+ memcpy(attributes_buffer, attributes, sizeof(attributes));
+ hr = mesh->lpVtbl->UnlockAttributeBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock attributes buffer.\n");
+ goto cleanup;
+ }
+
+ /* Convert point representation to adjacency*/
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++) adjacency[j] = -2;
+
+ hr = mesh->lpVtbl->ConvertPointRepsToAdjacency(mesh, tc[i].point_reps, adjacency);
+ ok(hr == D3D_OK, "ConvertPointRepsToAdjacency failed case %d. "
+ "Got %x expected D3D_OK\n", i, hr);
+ /* Check adjacency */
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(adjacency[j] == tc[i].exp_adjacency[j],
+ "Unexpected adjacency information at (%d, %d)."
+ " Got %d expected %d\n",
+ i, j, adjacency[j], tc[i].exp_adjacency[j]);
+ }
+
+ /* NULL point representation is considered identity. */
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++) adjacency[j] = -2;
+ hr = mesh_null_check->lpVtbl->ConvertPointRepsToAdjacency(mesh, NULL, adjacency);
+ ok(hr == D3D_OK, "ConvertPointRepsToAdjacency NULL point_reps. "
+ "Got %x expected D3D_OK\n", hr);
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(adjacency[j] == tc[i].exp_id_adjacency[j],
+ "Unexpected adjacency information (id) at (%d, %d)."
+ " Got %d expected %d\n",
+ i, j, adjacency[j], tc[i].exp_id_adjacency[j]);
+ }
+
+ HeapFree(GetProcessHeap(), 0, adjacency);
+ adjacency = NULL;
+ if (i != 0) /* First mesh will be freed during cleanup */
+ mesh->lpVtbl->Release(mesh);
+ }
+
+ /* NULL checks */
+ hr = mesh_null_check->lpVtbl->ConvertPointRepsToAdjacency(mesh_null_check, tc[0].point_reps, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ConvertPointRepsToAdjacency NULL adjacency. "
+ "Got %x expected D3DERR_INVALIDCALL\n", hr);
+ hr = mesh_null_check->lpVtbl->ConvertPointRepsToAdjacency(mesh_null_check, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "ConvertPointRepsToAdjacency NULL point_reps and adjacency. "
+ "Got %x expected D3DERR_INVALIDCALL\n", hr);
+
+cleanup:
+ if (mesh_null_check)
+ mesh_null_check->lpVtbl->Release(mesh_null_check);
+ HeapFree(GetProcessHeap(), 0, adjacency);
+ free_test_context(test_context);
+}
+
+static HRESULT init_test_mesh(const DWORD num_faces, const DWORD num_vertices,
+ const DWORD options,
+ const D3DVERTEXELEMENT9 *declaration,
+ IDirect3DDevice9 *device, ID3DXMesh **mesh_ptr,
+ const void *vertices, const DWORD vertex_size,
+ const DWORD *indices, const DWORD *attributes)
+{
+ HRESULT hr;
+ void *vertex_buffer;
+ void *index_buffer;
+ DWORD *attributes_buffer;
+ ID3DXMesh *mesh = NULL;
+
+ hr = D3DXCreateMesh(num_faces, num_vertices, options, declaration, device, mesh_ptr);
+ if (FAILED(hr))
+ {
+ skip("Couldn't create mesh. Got %x expected D3D_OK\n", hr);
+ goto cleanup;
+ }
+ mesh = *mesh_ptr;
+
+ hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, &vertex_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock vertex buffer.\n");
+ goto cleanup;
+ }
+ memcpy(vertex_buffer, vertices, num_vertices * vertex_size);
+ hr = mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock vertex buffer.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, &index_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock index buffer.\n");
+ goto cleanup;
+ }
+ if (options & D3DXMESH_32BIT)
+ {
+ if (indices)
+ memcpy(index_buffer, indices, 3 * num_faces * sizeof(DWORD));
+ else
+ {
+ /* Fill index buffer with 0, 1, 2, ...*/
+ DWORD *indices_32bit = (DWORD*)index_buffer;
+ UINT i;
+ for (i = 0; i < 3 * num_faces; i++)
+ indices_32bit[i] = i;
+ }
+ }
+ else
+ {
+ if (indices)
+ memcpy(index_buffer, indices, 3 * num_faces * sizeof(WORD));
+ else
+ {
+ /* Fill index buffer with 0, 1, 2, ...*/
+ WORD *indices_16bit = (WORD*)index_buffer;
+ UINT i;
+ for (i = 0; i < 3 * num_faces; i++)
+ indices_16bit[i] = i;
+ }
+ }
+ hr = mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ if (FAILED(hr)) {
+ skip("Couldn't unlock index buffer.\n");
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->LockAttributeBuffer(mesh, 0, &attributes_buffer);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock attributes buffer.\n");
+ goto cleanup;
+ }
+
+ if (attributes)
+ memcpy(attributes_buffer, attributes, num_faces * sizeof(*attributes));
+ else
+ memset(attributes_buffer, 0, num_faces * sizeof(*attributes));
+
+ hr = mesh->lpVtbl->UnlockAttributeBuffer(mesh);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock attributes buffer.\n");
+ goto cleanup;
+ }
+
+ hr = D3D_OK;
+cleanup:
+ return hr;
+}
+
+/* Using structs instead of bit-fields in order to avoid compiler issues. */
+struct udec3
+{
+ UINT x;
+ UINT y;
+ UINT z;
+ UINT w;
+};
+
+struct dec3n
+{
+ INT x;
+ INT y;
+ INT z;
+ INT w;
+};
+
+static DWORD init_udec3_dword(UINT x, UINT y, UINT z, UINT w)
+{
+ DWORD d = 0;
+
+ d |= x & 0x3ff;
+ d |= (y << 10) & 0xffc00;
+ d |= (z << 20) & 0x3ff00000;
+ d |= (w << 30) & 0xc0000000;
+
+ return d;
+}
+
+static DWORD init_dec3n_dword(INT x, INT y, INT z, INT w)
+{
+ DWORD d = 0;
+
+ d |= x & 0x3ff;
+ d |= (y << 10) & 0xffc00;
+ d |= (z << 20) & 0x3ff00000;
+ d |= (w << 30) & 0xc0000000;
+
+ return d;
+}
+
+static struct udec3 dword_to_udec3(DWORD d)
+{
+ struct udec3 v;
+
+ v.x = d & 0x3ff;
+ v.y = (d & 0xffc00) >> 10;
+ v.z = (d & 0x3ff00000) >> 20;
+ v.w = (d & 0xc0000000) >> 30;
+
+ return v;
+}
+
+static struct dec3n dword_to_dec3n(DWORD d)
+{
+ struct dec3n v;
+
+ v.x = d & 0x3ff;
+ v.y = (d & 0xffc00) >> 10;
+ v.z = (d & 0x3ff00000) >> 20;
+ v.w = (d & 0xc0000000) >> 30;
+
+ return v;
+}
+
+static void check_vertex_components(int line, int mesh_number, int vertex_number, BYTE *got_ptr, const BYTE *exp_ptr, D3DVERTEXELEMENT9 *declaration)
+{
+ const char *usage_strings[] =
+ {
+ "position",
+ "blend weight",
+ "blend indices",
+ "normal",
+ "point size",
+ "texture coordinates",
+ "tangent",
+ "binormal",
+ "tessellation factor",
+ "position transformed",
+ "color",
+ "fog",
+ "depth",
+ "sample"
+ };
+ D3DVERTEXELEMENT9 *decl_ptr;
+ const float PRECISION = 1e-5f;
+
+ for (decl_ptr = declaration; decl_ptr->Stream != 0xFF; decl_ptr++)
+ {
+ switch (decl_ptr->Type)
+ {
+ case D3DDECLTYPE_FLOAT1:
+ {
+ FLOAT *got = (FLOAT*)(got_ptr + decl_ptr->Offset);
+ FLOAT *exp = (FLOAT*)(exp_ptr + decl_ptr->Offset);
+ FLOAT diff = fabsf(*got - *exp);
+ ok_(__FILE__,line)(diff <= PRECISION, "Mesh %d: Got %f for vertex %d %s, expected %f.\n",
+ mesh_number, *got, vertex_number, usage_strings[decl_ptr->Usage], *exp);
+ break;
+ }
+ case D3DDECLTYPE_FLOAT2:
+ {
+ D3DXVECTOR2 *got = (D3DXVECTOR2*)(got_ptr + decl_ptr->Offset);
+ D3DXVECTOR2 *exp = (D3DXVECTOR2*)(exp_ptr + decl_ptr->Offset);
+ FLOAT diff = max(fabsf(got->x - exp->x), fabsf(got->y - exp->y));
+ ok_(__FILE__,line)(diff <= PRECISION, "Mesh %d: Got (%f, %f) for vertex %d %s, expected (%f, %f).\n",
+ mesh_number, got->x, got->y, vertex_number, usage_strings[decl_ptr->Usage], exp->x, exp->y);
+ break;
+ }
+ case D3DDECLTYPE_FLOAT3:
+ {
+ D3DXVECTOR3 *got = (D3DXVECTOR3*)(got_ptr + decl_ptr->Offset);
+ D3DXVECTOR3 *exp = (D3DXVECTOR3*)(exp_ptr + decl_ptr->Offset);
+ FLOAT diff = max(fabsf(got->x - exp->x), fabsf(got->y - exp->y));
+ diff = max(diff, fabsf(got->z - exp->z));
+ ok_(__FILE__,line)(diff <= PRECISION, "Mesh %d: Got (%f, %f, %f) for vertex %d %s, expected (%f, %f, %f).\n",
+ mesh_number, got->x, got->y, got->z, vertex_number, usage_strings[decl_ptr->Usage], exp->x, exp->y, exp->z);
+ break;
+ }
+ case D3DDECLTYPE_FLOAT4:
+ {
+ D3DXVECTOR4 *got = (D3DXVECTOR4*)(got_ptr + decl_ptr->Offset);
+ D3DXVECTOR4 *exp = (D3DXVECTOR4*)(exp_ptr + decl_ptr->Offset);
+ FLOAT diff = max(fabsf(got->x - exp->x), fabsf(got->y - exp->y));
+ diff = max(diff, fabsf(got->z - exp->z));
+ diff = max(diff, fabsf(got->w - exp->w));
+ ok_(__FILE__,line)(diff <= PRECISION, "Mesh %d: Got (%f, %f, %f, %f) for vertex %d %s, expected (%f, %f, %f, %f).\n",
+ mesh_number, got->x, got->y, got->z, got->w, vertex_number, usage_strings[decl_ptr->Usage], exp->x, exp->y, exp->z, got->w);
+ break;
+ }
+ case D3DDECLTYPE_D3DCOLOR:
+ {
+ BYTE *got = got_ptr + decl_ptr->Offset;
+ const BYTE *exp = exp_ptr + decl_ptr->Offset;
+ BOOL same_color = got[0] == exp[0] && got[1] == exp[1]
+ && got[2] == exp[2] && got[3] == exp[3];
+ const char *color_types[] = {"diffuse", "specular", "undefined color"};
+ BYTE usage_index = decl_ptr->UsageIndex;
+ if (usage_index > 1) usage_index = 2;
+ ok_(__FILE__,line)(same_color, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
+ mesh_number, got[0], got[1], got[2], got[3], vertex_number, color_types[usage_index], exp[0], exp[1], exp[2], exp[3]);
+ break;
+ }
+ case D3DDECLTYPE_UBYTE4:
+ case D3DDECLTYPE_UBYTE4N:
+ {
+ BYTE *got = got_ptr + decl_ptr->Offset;
+ const BYTE *exp = exp_ptr + decl_ptr->Offset;
+ BOOL same = got[0] == exp[0] && got[1] == exp[1]
+ && got[2] == exp[2] && got[3] == exp[3];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
+ mesh_number, got[0], got[1], got[2], got[3], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1], exp[2], exp[3]);
+ break;
+ }
+ case D3DDECLTYPE_SHORT2:
+ case D3DDECLTYPE_SHORT2N:
+ {
+ SHORT *got = (SHORT*)(got_ptr + decl_ptr->Offset);
+ SHORT *exp = (SHORT*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hd, %hd) for vertex %d %s, expected (%hd, %hd).\n",
+ mesh_number, got[0], got[1], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1]);
+ break;
+ }
+ case D3DDECLTYPE_SHORT4:
+ case D3DDECLTYPE_SHORT4N:
+ {
+ SHORT *got = (SHORT*)(got_ptr + decl_ptr->Offset);
+ SHORT *exp = (SHORT*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1]
+ && got[2] == exp[2] && got[3] == exp[3];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hd, %hd, %hd, %hd) for vertex %d %s, expected (%hd, %hd, %hd, %hd).\n",
+ mesh_number, got[0], got[1], got[2], got[3], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1], exp[2], exp[3]);
+ break;
+ }
+ case D3DDECLTYPE_USHORT2N:
+ {
+ USHORT *got = (USHORT*)(got_ptr + decl_ptr->Offset);
+ USHORT *exp = (USHORT*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hu, %hu) for vertex %d %s, expected (%hu, %hu).\n",
+ mesh_number, got[0], got[1], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1]);
+ break;
+ }
+ case D3DDECLTYPE_USHORT4N:
+ {
+ USHORT *got = (USHORT*)(got_ptr + decl_ptr->Offset);
+ USHORT *exp = (USHORT*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1]
+ && got[2] == exp[2] && got[3] == exp[3];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hu, %hu, %hu, %hu) for vertex %d %s, expected (%hu, %hu, %hu, %hu).\n",
+ mesh_number, got[0], got[1], got[2], got[3], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1], exp[2], exp[3]);
+ break;
+ }
+ case D3DDECLTYPE_UDEC3:
+ {
+ DWORD *got = (DWORD*)(got_ptr + decl_ptr->Offset);
+ DWORD *exp = (DWORD*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = memcmp(got, exp, sizeof(*got)) == 0;
+ struct udec3 got_udec3 = dword_to_udec3(*got);
+ struct udec3 exp_udec3 = dword_to_udec3(*exp);
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%u, %u, %u, %u) for vertex %d %s, expected (%u, %u, %u, %u).\n",
+ mesh_number, got_udec3.x, got_udec3.y, got_udec3.z, got_udec3.w, vertex_number, usage_strings[decl_ptr->Usage], exp_udec3.x, exp_udec3.y, exp_udec3.z, exp_udec3.w);
+
+ break;
+ }
+ case D3DDECLTYPE_DEC3N:
+ {
+ DWORD *got = (DWORD*)(got_ptr + decl_ptr->Offset);
+ DWORD *exp = (DWORD*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = memcmp(got, exp, sizeof(*got)) == 0;
+ struct dec3n got_dec3n = dword_to_dec3n(*got);
+ struct dec3n exp_dec3n = dword_to_dec3n(*exp);
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%d, %d, %d, %d) for vertex %d %s, expected (%d, %d, %d, %d).\n",
+ mesh_number, got_dec3n.x, got_dec3n.y, got_dec3n.z, got_dec3n.w, vertex_number, usage_strings[decl_ptr->Usage], exp_dec3n.x, exp_dec3n.y, exp_dec3n.z, exp_dec3n.w);
+ break;
+ }
+ case D3DDECLTYPE_FLOAT16_2:
+ {
+ WORD *got = (WORD*)(got_ptr + decl_ptr->Offset);
+ WORD *exp = (WORD*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hx, %hx) for vertex %d %s, expected (%hx, %hx).\n",
+ mesh_number, got[0], got[1], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1]);
+ break;
+ }
+ case D3DDECLTYPE_FLOAT16_4:
+ {
+ WORD *got = (WORD*)(got_ptr + decl_ptr->Offset);
+ WORD *exp = (WORD*)(exp_ptr + decl_ptr->Offset);
+ BOOL same = got[0] == exp[0] && got[1] == exp[1]
+ && got[2] == exp[2] && got[3] == exp[3];
+ ok_(__FILE__,line)(same, "Mesh %d: Got (%hx, %hx, %hx, %hx) for vertex %d %s, expected (%hx, %hx, %hx, %hx).\n",
+ mesh_number, got[0], got[1], got[2], got[3], vertex_number, usage_strings[decl_ptr->Usage], exp[0], exp[1], exp[3], exp[4]);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+static void test_weld_vertices(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ DWORD i;
+ const DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ const DWORD options_16bit = D3DXMESH_SYSTEMMEM;
+ BYTE *vertices = NULL;
+ DWORD *indices = NULL;
+ WORD *indices_16bit = NULL;
+ const UINT VERTS_PER_FACE = 3;
+#ifndef __REACTOS__
+ const D3DXVECTOR3 up = {0.0f, 0.0f, 1.0f};
+#else
+#define up {0.0f, 0.0f, 1.0f}
+#endif
+ struct vertex_normal
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ };
+ struct vertex_blendweight
+ {
+ D3DXVECTOR3 position;
+ FLOAT blendweight;
+ };
+ struct vertex_texcoord
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR2 texcoord;
+ };
+ struct vertex_color
+ {
+ D3DXVECTOR3 position;
+ DWORD color;
+ };
+ struct vertex_color_ubyte4
+ {
+ D3DXVECTOR3 position;
+ BYTE color[4];
+ };
+ struct vertex_texcoord_short2
+ {
+ D3DXVECTOR3 position;
+ SHORT texcoord[2];
+ };
+ struct vertex_texcoord_ushort2n
+ {
+ D3DXVECTOR3 position;
+ USHORT texcoord[2];
+ };
+ struct vertex_normal_short4
+ {
+ D3DXVECTOR3 position;
+ SHORT normal[4];
+ };
+ struct vertex_texcoord_float16_2
+ {
+ D3DXVECTOR3 position;
+ WORD texcoord[2];
+ };
+ struct vertex_texcoord_float16_4
+ {
+ D3DXVECTOR3 position;
+ WORD texcoord[4];
+ };
+ struct vertex_normal_udec3
+ {
+ D3DXVECTOR3 position;
+ DWORD normal;
+ };
+ struct vertex_normal_dec3n
+ {
+ D3DXVECTOR3 position;
+ DWORD normal;
+ };
+ UINT vertex_size_normal = sizeof(struct vertex_normal);
+ UINT vertex_size_blendweight = sizeof(struct vertex_blendweight);
+ UINT vertex_size_texcoord = sizeof(struct vertex_texcoord);
+ UINT vertex_size_color = sizeof(struct vertex_color);
+ UINT vertex_size_color_ubyte4 = sizeof(struct vertex_color_ubyte4);
+ UINT vertex_size_texcoord_short2 = sizeof(struct vertex_texcoord_short2);
+ UINT vertex_size_normal_short4 = sizeof(struct vertex_normal_short4);
+ UINT vertex_size_texcoord_float16_2 = sizeof(struct vertex_texcoord_float16_2);
+ UINT vertex_size_texcoord_float16_4 = sizeof(struct vertex_texcoord_float16_4);
+ UINT vertex_size_normal_udec3 = sizeof(struct vertex_normal_udec3);
+ UINT vertex_size_normal_dec3n = sizeof(struct vertex_normal_dec3n);
+ D3DVERTEXELEMENT9 declaration_normal[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal3[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 3},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_blendweight[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_color[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_color_ubyte4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_color_ubyte4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord_short2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord_short2n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord_ushort2n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_USHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal_short4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal_short4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal_ushort4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord10[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 10},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_color2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 2},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_color1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord_float16_2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_texcoord_float16_4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal_udec3[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UDEC3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_normal_dec3n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_DEC3N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ /* Test 0. One face and no welding.
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ const struct vertex vertices0[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD indices0[] = {0, 1, 2};
+ const DWORD attributes0[] = {0};
+ const DWORD exp_indices0[] = {0, 1, 2};
+ const UINT num_vertices0 = ARRAY_SIZE(vertices0);
+ const UINT num_faces0 = ARRAY_SIZE(indices0) / VERTS_PER_FACE;
+ const DWORD flags0 = D3DXWELDEPSILONS_WELDALL;
+ /* epsilons0 is NULL */
+ const DWORD adjacency0[] = {-1, -1, -1};
+ const struct vertex exp_vertices0[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD exp_face_remap0[] = {0};
+ const DWORD exp_vertex_remap0[] = {0, 1, 2};
+ const DWORD exp_new_num_vertices0 = ARRAY_SIZE(exp_vertices0);
+ /* Test 1. Two vertices should be removed without regard to epsilon.
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_normal vertices1[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, up},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD indices1[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes1[] = {0, 0};
+ const UINT num_vertices1 = ARRAY_SIZE(vertices1);
+ const UINT num_faces1 = ARRAY_SIZE(indices1) / VERTS_PER_FACE;
+ const DWORD flags1 = D3DXWELDEPSILONS_WELDALL;
+ /* epsilons1 is NULL */
+ const DWORD adjacency1[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices1[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up}
+ };
+ const DWORD exp_indices1[] = {0, 1, 2, 1, 3, 2};
+ const DWORD exp_face_remap1[] = {0, 1};
+ const DWORD exp_vertex_remap1[] = {0, 1, 2, 4, -1, -1};
+ const DWORD exp_new_num_vertices1 = ARRAY_SIZE(exp_vertices1);
+ /* Test 2. Two faces. No vertices should be removed because of normal
+ * epsilon, but the positions should be replaced. */
+ const struct vertex_normal vertices2[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices2[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes2[] = {0, 0};
+ const UINT num_vertices2 = ARRAY_SIZE(vertices2);
+ const UINT num_faces2 = ARRAY_SIZE(indices2) / VERTS_PER_FACE;
+ DWORD flags2 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons2 = {1.0f, 0.0f, 0.499999f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency2[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices2[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD exp_indices2[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_face_remap2[] = {0, 1};
+ const DWORD exp_vertex_remap2[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_new_num_vertices2 = ARRAY_SIZE(exp_vertices2);
+ /* Test 3. Two faces. One vertex should be removed because of normal epsilon. */
+ const struct vertex_normal vertices3[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices3[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes3[] = {0, 0};
+ const UINT num_vertices3 = ARRAY_SIZE(vertices3);
+ const UINT num_faces3 = ARRAY_SIZE(indices3) / VERTS_PER_FACE;
+ DWORD flags3 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons3 = {1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency3[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices3[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD exp_indices3[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap3[] = {0, 1};
+ const DWORD exp_vertex_remap3[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices3 = ARRAY_SIZE(exp_vertices3);
+ /* Test 4 Two faces. Two vertices should be removed. */
+ const struct vertex_normal vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices4[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes4[] = {0, 0};
+ const UINT num_vertices4 = ARRAY_SIZE(vertices4);
+ const UINT num_faces4 = ARRAY_SIZE(indices4) / VERTS_PER_FACE;
+ DWORD flags4 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons4 = {1.0f, 0.0f, 0.6f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency4[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD exp_indices4[] = {0, 1, 2, 1, 3, 2};
+ const DWORD exp_face_remap4[] = {0, 1};
+ const DWORD exp_vertex_remap4[] = {0, 1, 2, 4, -1, -1};
+ const DWORD exp_new_num_vertices4 = ARRAY_SIZE(exp_vertices4);
+ /* Test 5. Odd face ordering.
+ *
+ * 0--1 6 3
+ * | / /| |\
+ * |/ / | | \
+ * 2 8--7 5--4
+ */
+ const struct vertex_normal vertices5[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, up},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, up},
+
+ {{ 4.0f, 3.0f, 0.f}, up},
+ {{ 6.0f, 0.0f, 0.f}, up},
+ {{ 4.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD indices5[] = {0, 1, 2, 6, 7, 8, 3, 4, 5};
+ const DWORD exp_indices5[] = {0, 1, 2, 1, 4, 2, 1, 3, 4};
+ const DWORD attributes5[] = {0, 0, 0};
+ const UINT num_vertices5 = ARRAY_SIZE(vertices5);
+ const UINT num_faces5 = ARRAY_SIZE(indices5) / VERTS_PER_FACE;
+ DWORD flags5 = D3DXWELDEPSILONS_WELDALL;
+ const DWORD adjacency5[] = {-1, 1, -1, 2, -1, 0, -1, -1, 1};
+ const struct vertex_normal exp_vertices5[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD exp_face_remap5[] = {0, 1, 2};
+ const DWORD exp_vertex_remap5[] = {0, 1, 2, 4, 5, -1, -1, -1, -1};
+ const DWORD exp_new_num_vertices5 = ARRAY_SIZE(exp_vertices5);
+ /* Test 6. Two faces. Do not remove flag is used, so no vertices should be
+ * removed. */
+ const struct vertex_normal vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices6[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes6[] = {0, 0};
+ const UINT num_vertices6 = ARRAY_SIZE(vertices6);
+ const UINT num_faces6 = ARRAY_SIZE(indices6) / VERTS_PER_FACE;
+ DWORD flags6 = D3DXWELDEPSILONS_WELDPARTIALMATCHES | D3DXWELDEPSILONS_DONOTREMOVEVERTICES;
+ const D3DXWELDEPSILONS epsilons6 = {1.0f, 0.0f, 0.6f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency6[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ };
+ const DWORD exp_indices6[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_face_remap6[] = {0, 1};
+ const DWORD exp_vertex_remap6[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_new_num_vertices6 = ARRAY_SIZE(exp_vertices6);
+ /* Test 7. Same as test 6 but with 16 bit indices. */
+ const WORD indices6_16bit[] = {0, 1, 2, 3, 4, 5};
+ /* Test 8. No flags. Same result as D3DXWELDEPSILONS_WELDPARTIALMATCHES. */
+ const struct vertex_normal vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices8[] = {0, 1, 2, 1, 3, 4};
+ const DWORD attributes8[] = {0, 0};
+ const UINT num_vertices8 = ARRAY_SIZE(vertices8);
+ const UINT num_faces8 = ARRAY_SIZE(indices8) / VERTS_PER_FACE;
+ DWORD flags8 = 0;
+ const D3DXWELDEPSILONS epsilons8 = {1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency8[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD exp_indices8[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap8[] = {0, 1};
+ const DWORD exp_vertex_remap8[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices8 = ARRAY_SIZE(exp_vertices8);
+ /* Test 9. Vertices are removed even though they belong to separate
+ * attribute groups if D3DXWELDEPSILONS_DONOTSPLIT is set. */
+ const struct vertex_normal vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices9[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes9[] = {0, 1};
+ const UINT num_vertices9 = ARRAY_SIZE(vertices9);
+ const UINT num_faces9 = ARRAY_SIZE(indices9) / VERTS_PER_FACE;
+ DWORD flags9 = D3DXWELDEPSILONS_WELDPARTIALMATCHES | D3DXWELDEPSILONS_DONOTSPLIT;
+ const D3DXWELDEPSILONS epsilons9 = {1.0f, 0.0f, 0.6f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency9[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up},
+ };
+ const DWORD exp_indices9[] = {0, 1, 2, 1, 3, 2};
+ const DWORD exp_face_remap9[] = {0, 1};
+ const DWORD exp_vertex_remap9[] = {0, 1, 2, 4, -1, -1};
+ const DWORD exp_new_num_vertices9 = ARRAY_SIZE(exp_vertices9);
+ /* Test 10. Weld blendweight (FLOAT1). */
+ const struct vertex_blendweight vertices10[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 1.0f},
+ {{ 0.0f, 0.0f, 0.f}, 1.0f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.9},
+ {{ 3.0f, 0.0f, 0.f}, 1.0},
+ {{ 1.0f, 0.0f, 0.f}, 0.4},
+ };
+ const DWORD indices10[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes10[] = {0, 0};
+ const UINT num_vertices10 = ARRAY_SIZE(vertices10);
+ const UINT num_faces10 = ARRAY_SIZE(indices10) / VERTS_PER_FACE;
+ DWORD flags10 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons10 = {1.0f, 0.1f + FLT_EPSILON, 0.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency10[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_blendweight exp_vertices10[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 1.0f},
+ {{ 0.0f, 0.0f, 0.f}, 1.0f},
+
+ {{ 3.0f, 0.0f, 0.f}, 1.0},
+ {{ 0.0f, 0.0f, 0.f}, 0.4},
+ };
+ const DWORD exp_indices10[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap10[] = {0, 1};
+ const DWORD exp_vertex_remap10[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices10 = ARRAY_SIZE(exp_vertices10);
+ /* Test 11. Weld texture coordinates. */
+ const struct vertex_texcoord vertices11[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.1f, 0.2f}}
+ };
+ const DWORD indices11[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes11[] = {0, 0};
+ const UINT num_vertices11 = ARRAY_SIZE(vertices11);
+ const UINT num_faces11 = ARRAY_SIZE(indices11) / VERTS_PER_FACE;
+ DWORD flags11 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons11 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {0.4f + FLT_EPSILON, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency11[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord exp_vertices11[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 0.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.1f, 0.2f}},
+ };
+ const DWORD exp_indices11[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap11[] = {0, 1};
+ const DWORD exp_vertex_remap11[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices11 = ARRAY_SIZE(exp_vertices11);
+ /* Test 12. Weld with color. */
+ const struct vertex_color vertices12[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 3.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ {{ 1.0f, 0.0f, 0.f}, 0x88888888},
+ };
+ const DWORD indices12[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes12[] = {0, 0};
+ const UINT num_vertices12 = ARRAY_SIZE(vertices12);
+ const UINT num_faces12 = ARRAY_SIZE(indices12) / VERTS_PER_FACE;
+ DWORD flags12 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons12 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency12[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color exp_vertices12[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 2.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ };
+ const DWORD exp_indices12[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap12[] = {0, 1};
+ const DWORD exp_vertex_remap12[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices12 = ARRAY_SIZE(exp_vertices12);
+ /* Test 13. Two faces. One vertex should be removed because of normal epsilon.
+ * This is similar to test 3, but the declaration has been changed to NORMAL3.
+ */
+ const struct vertex_normal vertices13[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 0.5f, 0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD indices13[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes13[] = {0, 0};
+ const UINT num_vertices13 = ARRAY_SIZE(vertices3);
+ const UINT num_faces13 = ARRAY_SIZE(indices3) / VERTS_PER_FACE;
+ DWORD flags13 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons13 = {1.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency13[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal exp_vertices13[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, {0.2f, 0.4f, 0.4f}},
+ };
+ const DWORD exp_indices13[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap13[] = {0, 1};
+ const DWORD exp_vertex_remap13[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices13 = ARRAY_SIZE(exp_vertices13);
+ /* Test 14. Another test for welding with color. */
+ const struct vertex_color vertices14[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 3.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ {{ 1.0f, 0.0f, 0.f}, 0x01010101},
+ };
+ const DWORD indices14[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes14[] = {0, 0};
+ const UINT num_vertices14 = ARRAY_SIZE(vertices14);
+ const UINT num_faces14 = ARRAY_SIZE(indices14) / VERTS_PER_FACE;
+ DWORD flags14 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons14 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 254.0f/255.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency14[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color exp_vertices14[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 2.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ };
+ const DWORD exp_indices14[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap14[] = {0, 1};
+ const DWORD exp_vertex_remap14[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices14 = ARRAY_SIZE(exp_vertices14);
+ /* Test 15. Weld with color, but as UBYTE4N instead of D3DCOLOR. It shows
+ * that UBYTE4N and D3DCOLOR are compared the same way.
+ */
+ const struct vertex_color_ubyte4 vertices15[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0, 0, 0, 0}},
+ {{ 3.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 1.0f, 0.0f, 0.f}, { 1, 1, 1, 1}},
+ };
+ const DWORD indices15[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes15[] = {0, 0};
+ const UINT num_vertices15 = ARRAY_SIZE(vertices15);
+ const UINT num_faces15 = ARRAY_SIZE(indices15) / VERTS_PER_FACE;
+ DWORD flags15 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons15 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 254.0f/255.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency15[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color_ubyte4 exp_vertices15[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0, 0, 0}},
+ {{ 3.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+ };
+ const DWORD exp_indices15[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap15[] = {0, 1};
+ const DWORD exp_vertex_remap15[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices15 = ARRAY_SIZE(exp_vertices15);
+ /* Test 16. Weld with color, but as UBYTE4 instead of D3DCOLOR. It shows
+ * that UBYTE4 is not normalized and that epsilon is truncated and compared
+ * directly to each of the four bytes.
+ */
+ const struct vertex_color_ubyte4 vertices16[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0, 0, 0, 0}},
+ {{ 3.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 1.0f, 0.0f, 0.f}, { 1, 1, 1, 1}},
+ };
+ const DWORD indices16[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes16[] = {0, 0};
+ const UINT num_vertices16 = ARRAY_SIZE(vertices16);
+ const UINT num_faces16 = ARRAY_SIZE(indices16) / VERTS_PER_FACE;
+ DWORD flags16 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons16 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 254.9f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency16[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color_ubyte4 exp_vertices16[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {255, 255, 255, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0, 0, 0}},
+ {{ 3.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+ };
+ const DWORD exp_indices16[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap16[] = {0, 1};
+ const DWORD exp_vertex_remap16[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices16 = ARRAY_SIZE(exp_vertices16);
+ /* Test 17. Weld texture coordinates but as SHORT2 instead of D3DXVECTOR2.*/
+ const struct vertex_texcoord_short2 vertices17[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {32766, 32766}},
+ };
+ const DWORD indices17[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes17[] = {0, 0};
+ const UINT num_vertices17 = ARRAY_SIZE(vertices17);
+ const UINT num_faces17 = ARRAY_SIZE(indices17) / VERTS_PER_FACE;
+ DWORD flags17 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons17 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {32766.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency17[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord_short2 exp_vertices17[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ };
+ const DWORD exp_indices17[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap17[] = {0, 1};
+ const DWORD exp_vertex_remap17[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices17 = ARRAY_SIZE(exp_vertices17);
+ /* Test 18. Weld texture coordinates but as SHORT2N instead of D3DXVECTOR2. */
+ const struct vertex_texcoord_short2 vertices18[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {32766, 32766}},
+ };
+ const DWORD indices18[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes18[] = {0, 0};
+ const UINT num_vertices18 = ARRAY_SIZE(vertices18);
+ const UINT num_faces18 = ARRAY_SIZE(indices18) / VERTS_PER_FACE;
+ DWORD flags18 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons18 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {32766.0f/32767.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency18[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord_short2 exp_vertices18[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ };
+ const DWORD exp_indices18[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap18[] = {0, 1};
+ const DWORD exp_vertex_remap18[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices18 = ARRAY_SIZE(exp_vertices18);
+ /* Test 19. Weld texture coordinates but as USHORT2N instead of D3DXVECTOR2. */
+ const struct vertex_texcoord_ushort2n vertices19[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {65535, 65535}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {65534, 65534}},
+ };
+ const DWORD indices19[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes19[] = {0, 0};
+ const UINT num_vertices19 = ARRAY_SIZE(vertices19);
+ const UINT num_faces19 = ARRAY_SIZE(indices19) / VERTS_PER_FACE;
+ DWORD flags19 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons19 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {65534.0f/65535.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency19[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord_ushort2n exp_vertices19[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, { 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, { 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {65535, 65535}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0}},
+ };
+ const DWORD exp_indices19[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap19[] = {0, 1};
+ const DWORD exp_vertex_remap19[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices19 = ARRAY_SIZE(exp_vertices19);
+ /* Test 20. Weld normal as SHORT4 instead of D3DXVECTOR3. */
+ const struct vertex_normal_short4 vertices20[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {32767, 32767, 32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {32766, 32766, 32766, 32766}},
+ };
+ const DWORD indices20[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes20[] = {0, 0};
+ const UINT num_vertices20 = ARRAY_SIZE(vertices20);
+ const UINT num_faces20 = ARRAY_SIZE(indices20) / VERTS_PER_FACE;
+ DWORD flags20 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons20 = {1.0f, 0.0f, 32766.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency20[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal_short4 exp_vertices20[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {32767, 32767, 32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ };
+ const DWORD exp_indices20[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap20[] = {0, 1};
+ const DWORD exp_vertex_remap20[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices20 = ARRAY_SIZE(exp_vertices20);
+ /* Test 21. Weld normal as SHORT4N instead of D3DXVECTOR3. */
+ const struct vertex_normal_short4 vertices21[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {32767, 32767, 32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {32766, 32766, 32766, 32766}},
+ };
+ const DWORD indices21[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes21[] = {0, 0};
+ const UINT num_vertices21 = ARRAY_SIZE(vertices21);
+ const UINT num_faces21 = ARRAY_SIZE(indices21) / VERTS_PER_FACE;
+ DWORD flags21 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons21 = {1.0f, 0.0f, 32766.0f/32767.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency21[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal_short4 exp_vertices21[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {32767, 32767, 32767, 32767}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ };
+ const DWORD exp_indices21[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap21[] = {0, 1};
+ const DWORD exp_vertex_remap21[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices21 = ARRAY_SIZE(exp_vertices21);
+ /* Test 22. Weld normal as USHORT4N instead of D3DXVECTOR3. */
+ const struct vertex_normal_short4 vertices22[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {65535, 65535, 65535, 65535}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {65534, 65534, 65534, 65534}},
+ };
+ const DWORD indices22[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes22[] = {0, 0};
+ const UINT num_vertices22 = ARRAY_SIZE(vertices22);
+ const UINT num_faces22 = ARRAY_SIZE(indices22) / VERTS_PER_FACE;
+ DWORD flags22 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons22 = {1.0f, 0.0f, 65534.0f/65535.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency22[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal_short4 exp_vertices22[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+
+ {{ 2.0f, 3.0f, 0.f}, {65535, 65535, 65535, 65535}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 0}},
+ };
+ const DWORD exp_indices22[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap22[] = {0, 1};
+ const DWORD exp_vertex_remap22[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices22 = ARRAY_SIZE(exp_vertices22);
+ /* Test 23. Weld texture coordinates as FLOAT16_2. Similar to test 11, but
+ * with texture coordinates converted to float16 in hex. */
+ const struct vertex_texcoord_float16_2 vertices23[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
+ };
+ const DWORD indices23[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes23[] = {0, 0};
+ const UINT num_vertices23 = ARRAY_SIZE(vertices23);
+ const UINT num_faces23 = ARRAY_SIZE(indices23) / VERTS_PER_FACE;
+ DWORD flags23 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons23 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {0.41f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency23[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord_float16_2 exp_vertices23[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
+
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 0.0f, 0.0f, 0.f}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
+ };
+ const DWORD exp_indices23[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap23[] = {0, 1};
+ const DWORD exp_vertex_remap23[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices23 = ARRAY_SIZE(exp_vertices23);
+ /* Test 24. Weld texture coordinates as FLOAT16_4. Similar to test 24. */
+ const struct vertex_texcoord_float16_4 vertices24[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a, 0x3800, 0x399a}},
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd, 0xb266, 0xb4cd}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd, 0x3266, 0x34cd}},
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
+ };
+ const DWORD indices24[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes24[] = {0, 0};
+ const UINT num_vertices24 = ARRAY_SIZE(vertices24);
+ const UINT num_faces24 = ARRAY_SIZE(indices24) / VERTS_PER_FACE;
+ DWORD flags24 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons24 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {0.41f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency24[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord_float16_4 exp_vertices24[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a, 0x3800, 0x399a}},
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd, 0xb266, 0xb4cd}},
+
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
+ {{ 0.0f, 0.0f, 0.f}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
+ };
+ const DWORD exp_indices24[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap24[] = {0, 1};
+ const DWORD exp_vertex_remap24[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices24 = ARRAY_SIZE(exp_vertices24);
+ /* Test 25. Weld texture coordinates with usage index 10 (TEXCOORD10). The
+ * usage index is capped at 7, so the epsilon for TEXCOORD7 is used instead.
+ */
+ const struct vertex_texcoord vertices25[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.1f, 0.2f}}
+ };
+ const DWORD indices25[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes25[] = {0, 0};
+ const UINT num_vertices25 = ARRAY_SIZE(vertices25);
+ const UINT num_faces25 = ARRAY_SIZE(indices25) / VERTS_PER_FACE;
+ DWORD flags25 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons25 = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.4f + FLT_EPSILON}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency25[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_texcoord exp_vertices25[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 0.0f, 0.f}, {1.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.1f, 0.2f}},
+ };
+ const DWORD exp_indices25[] = {0, 1, 2, 1, 3, 4};
+ const DWORD exp_face_remap25[] = {0, 1};
+ const DWORD exp_vertex_remap25[] = {0, 1, 2, 4, 5, -1};
+ const DWORD exp_new_num_vertices25 = ARRAY_SIZE(exp_vertices25);
+ /* Test 26. Weld color with usage index larger than 1. Shows that none of
+ * the epsilon values are used. */
+ const struct vertex_color vertices26[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 3.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ {{ 1.0f, 0.0f, 0.f}, 0x01010101},
+ };
+ const DWORD indices26[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes26[] = {0, 0};
+ const UINT num_vertices26 = ARRAY_SIZE(vertices26);
+ const UINT num_faces26 = ARRAY_SIZE(indices26) / VERTS_PER_FACE;
+ DWORD flags26 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons26 = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}, 1.0f, 1.0f, 1.0f};
+ const DWORD adjacency26[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color exp_vertices26[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 2.0f, 3.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+
+ {{ 2.0f, 3.0f, 0.f}, 0x00000000},
+ {{ 3.0f, 0.0f, 0.f}, 0xFFFFFFFF},
+ {{ 0.0f, 0.0f, 0.f}, 0x01010101},
+ };
+ const DWORD exp_indices26[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_face_remap26[] = {0, 1};
+ const DWORD exp_vertex_remap26[] = {0, 1, 2, 3, 4, 5};
+ const DWORD exp_new_num_vertices26 = ARRAY_SIZE(exp_vertices26);
+ /* Test 27. Weld color with usage index 1 (specular). */
+ /* Previously this test used float color values and index > 1 but that case
+ * appears to be effectively unhandled in native so the test gave
+ * inconsistent results. */
+ const struct vertex_color vertices27[] =
+ {
+ {{ 0.0f, 3.0f, 0.0f}, 0x00000000},
+ {{ 2.0f, 3.0f, 0.0f}, 0x10203040},
+ {{ 0.0f, 0.0f, 0.0f}, 0x50607080},
+
+ {{ 3.0f, 3.0f, 0.0f}, 0x11213141},
+ {{ 3.0f, 0.0f, 0.0f}, 0xffffffff},
+ {{ 1.0f, 0.0f, 0.0f}, 0x51617181},
+ };
+ const DWORD indices27[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes27[] = {0, 0};
+ const UINT num_vertices27 = ARRAY_SIZE(vertices27);
+ const UINT num_faces27 = ARRAY_SIZE(indices27) / VERTS_PER_FACE;
+ DWORD flags27 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons27 =
+ {
+ 1.1f, 0.0f, 0.0f, 0.0f, 2.0f / 255.0f, 0.0f,
+ {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f
+ };
+ const DWORD adjacency27[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_color exp_vertices27[] =
+ {
+ {{ 0.0f, 3.0f, 0.0f}, 0x00000000},
+ {{ 2.0f, 3.0f, 0.0f}, 0x10203040},
+ {{ 0.0f, 0.0f, 0.0f}, 0x50607080},
+
+ {{ 3.0f, 0.0f, 0.0f}, 0xffffffff},
+ };
+ const DWORD exp_indices27[] = {0, 1, 2, 1, 3, 2};
+ const DWORD exp_face_remap27[] = {0, 1};
+ const DWORD exp_vertex_remap27[] = {0, 1, 2, 4, -1, -1};
+ const DWORD exp_new_num_vertices27 = ARRAY_SIZE(exp_vertices27);
+ /* Test 28. Weld one normal with UDEC3. */
+ const DWORD dword_udec3_zero = init_udec3_dword(0, 0, 0, 1);
+ const DWORD dword_udec3_1023 = init_udec3_dword(1023, 1023, 1023, 1);
+ const DWORD dword_udec3_1022 = init_udec3_dword(1022, 1022, 1022, 1);
+ const struct vertex_normal_udec3 vertices28[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, dword_udec3_zero},
+ {{ 2.0f, 3.0f, 0.f}, dword_udec3_zero},
+ {{ 0.0f, 0.0f, 0.f}, dword_udec3_zero},
+
+ {{ 3.0f, 3.0f, 0.f}, dword_udec3_1023},
+ {{ 3.0f, 0.0f, 0.f}, dword_udec3_zero},
+ {{ 1.0f, 0.0f, 0.f}, dword_udec3_1022},
+ };
+ const DWORD indices28[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes28[] = {0, 0};
+ const UINT num_vertices28 = ARRAY_SIZE(vertices28);
+ const UINT num_faces28 = ARRAY_SIZE(indices28) / VERTS_PER_FACE;
+ DWORD flags28 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons28 = {1.0f, 0.0f, 1022.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency28[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal_udec3 exp_vertices28[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, dword_udec3_zero},
+ {{ 2.0f, 3.0f, 0.f}, dword_udec3_zero},
+ {{ 0.0f, 0.0f, 0.f}, dword_udec3_zero},
+
+ {{ 2.0f, 3.0f, 0.f}, dword_udec3_1023},
+ {{ 3.0f, 0.0f, 0.f}, dword_udec3_zero},
+ };
+ const DWORD exp_indices28[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap28[] = {0, 1};
+ const DWORD exp_vertex_remap28[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices28 = ARRAY_SIZE(exp_vertices28);
+ /* Test 29. Weld one normal with DEC3N. */
+ const DWORD dword_dec3n_zero = init_dec3n_dword(0, 0, 0, 1);
+ const DWORD dword_dec3n_511 = init_dec3n_dword(511, 511, 511, 1);
+ const DWORD dword_dec3n_510 = init_dec3n_dword(510, 510, 510, 1);
+ const struct vertex_normal_dec3n vertices29[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, dword_dec3n_zero},
+ {{ 2.0f, 3.0f, 0.f}, dword_dec3n_zero},
+ {{ 0.0f, 0.0f, 0.f}, dword_dec3n_zero},
+
+ {{ 3.0f, 3.0f, 0.f}, dword_dec3n_511},
+ {{ 3.0f, 0.0f, 0.f}, dword_dec3n_zero},
+ {{ 1.0f, 0.0f, 0.f}, dword_dec3n_510},
+ };
+ const DWORD indices29[] = {0, 1, 2, 3, 4, 5};
+ const DWORD attributes29[] = {0, 0};
+ const UINT num_vertices29 = ARRAY_SIZE(vertices29);
+ const UINT num_faces29 = ARRAY_SIZE(indices29) / VERTS_PER_FACE;
+ DWORD flags29 = D3DXWELDEPSILONS_WELDPARTIALMATCHES;
+ const D3DXWELDEPSILONS epsilons29 = {1.0f, 0.0f, 510.0f/511.0f, 0.0f, 0.0f, 0.0f, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, .0f}, 0.0f, 0.0f, 0.0f};
+ const DWORD adjacency29[] = {-1, 1, -1, -1, -1, 0};
+ const struct vertex_normal_dec3n exp_vertices29[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, dword_dec3n_zero},
+ {{ 2.0f, 3.0f, 0.f}, dword_dec3n_zero},
+ {{ 0.0f, 0.0f, 0.f}, dword_dec3n_zero},
+
+ {{ 2.0f, 3.0f, 0.f}, dword_dec3n_511},
+ {{ 3.0f, 0.0f, 0.f}, dword_dec3n_zero},
+ };
+ const DWORD exp_indices29[] = {0, 1, 2, 3, 4, 2};
+ const DWORD exp_face_remap29[] = {0, 1};
+ const DWORD exp_vertex_remap29[] = {0, 1, 2, 3, 4, -1};
+ const DWORD exp_new_num_vertices29 = ARRAY_SIZE(exp_vertices29);
+ /* All mesh data */
+ DWORD *adjacency_out = NULL;
+ DWORD *face_remap = NULL;
+ ID3DXMesh *mesh = NULL;
+ ID3DXBuffer *vertex_remap = NULL;
+ struct
+ {
+ const BYTE *vertices;
+ const DWORD *indices;
+ const DWORD *attributes;
+ const DWORD num_vertices;
+ const DWORD num_faces;
+ const DWORD options;
+ D3DVERTEXELEMENT9 *declaration;
+ const UINT vertex_size;
+ const DWORD flags;
+ const D3DXWELDEPSILONS *epsilons;
+ const DWORD *adjacency;
+ const BYTE *exp_vertices;
+ const DWORD *exp_indices;
+ const DWORD *exp_face_remap;
+ const DWORD *exp_vertex_remap;
+ const DWORD exp_new_num_vertices;
+ }
+ tc[] =
+ {
+ {
+ (BYTE*)vertices0,
+ indices0,
+ attributes0,
+ num_vertices0,
+ num_faces0,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags0,
+ NULL,
+ adjacency0,
+ (BYTE*)exp_vertices0,
+ exp_indices0,
+ exp_face_remap0,
+ exp_vertex_remap0,
+ exp_new_num_vertices0
+ },
+ {
+ (BYTE*)vertices1,
+ indices1,
+ attributes1,
+ num_vertices1,
+ num_faces1,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags1,
+ NULL,
+ adjacency1,
+ (BYTE*)exp_vertices1,
+ exp_indices1,
+ exp_face_remap1,
+ exp_vertex_remap1,
+ exp_new_num_vertices1
+ },
+ {
+ (BYTE*)vertices2,
+ indices2,
+ attributes2,
+ num_vertices2,
+ num_faces2,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags2,
+ &epsilons2,
+ adjacency2,
+ (BYTE*)exp_vertices2,
+ exp_indices2,
+ exp_face_remap2,
+ exp_vertex_remap2,
+ exp_new_num_vertices2
+ },
+ {
+ (BYTE*)vertices3,
+ indices3,
+ attributes3,
+ num_vertices3,
+ num_faces3,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags3,
+ &epsilons3,
+ adjacency3,
+ (BYTE*)exp_vertices3,
+ exp_indices3,
+ exp_face_remap3,
+ exp_vertex_remap3,
+ exp_new_num_vertices3
+ },
+ {
+ (BYTE*)vertices4,
+ indices4,
+ attributes4,
+ num_vertices4,
+ num_faces4,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags4,
+ &epsilons4,
+ adjacency4,
+ (BYTE*)exp_vertices4,
+ exp_indices4,
+ exp_face_remap4,
+ exp_vertex_remap4,
+ exp_new_num_vertices4
+ },
+ /* Unusual ordering. */
+ {
+ (BYTE*)vertices5,
+ indices5,
+ attributes5,
+ num_vertices5,
+ num_faces5,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags5,
+ NULL,
+ adjacency5,
+ (BYTE*)exp_vertices5,
+ exp_indices5,
+ exp_face_remap5,
+ exp_vertex_remap5,
+ exp_new_num_vertices5
+ },
+ {
+ (BYTE*)vertices6,
+ indices6,
+ attributes6,
+ num_vertices6,
+ num_faces6,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags6,
+ &epsilons6,
+ adjacency6,
+ (BYTE*)exp_vertices6,
+ exp_indices6,
+ exp_face_remap6,
+ exp_vertex_remap6,
+ exp_new_num_vertices6
+ },
+ {
+ (BYTE*)vertices6,
+ (DWORD*)indices6_16bit,
+ attributes6,
+ num_vertices6,
+ num_faces6,
+ options_16bit,
+ declaration_normal,
+ vertex_size_normal,
+ flags6,
+ &epsilons6,
+ adjacency6,
+ (BYTE*)exp_vertices6,
+ exp_indices6,
+ exp_face_remap6,
+ exp_vertex_remap6,
+ exp_new_num_vertices6
+ },
+ {
+ (BYTE*)vertices8,
+ indices8,
+ attributes8,
+ num_vertices8,
+ num_faces8,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags8,
+ &epsilons8,
+ adjacency8,
+ (BYTE*)exp_vertices8,
+ exp_indices8,
+ exp_face_remap8,
+ exp_vertex_remap8,
+ exp_new_num_vertices8
+ },
+ {
+ (BYTE*)vertices9,
+ indices9,
+ attributes9,
+ num_vertices9,
+ num_faces9,
+ options,
+ declaration_normal,
+ vertex_size_normal,
+ flags9,
+ &epsilons9,
+ adjacency9,
+ (BYTE*)exp_vertices9,
+ exp_indices9,
+ exp_face_remap9,
+ exp_vertex_remap9,
+ exp_new_num_vertices9
+ },
+ {
+ (BYTE*)vertices10,
+ indices10,
+ attributes10,
+ num_vertices10,
+ num_faces10,
+ options,
+ declaration_blendweight,
+ vertex_size_blendweight,
+ flags10,
+ &epsilons10,
+ adjacency10,
+ (BYTE*)exp_vertices10,
+ exp_indices10,
+ exp_face_remap10,
+ exp_vertex_remap10,
+ exp_new_num_vertices10
+ },
+ {
+ (BYTE*)vertices11,
+ indices11,
+ attributes11,
+ num_vertices11,
+ num_faces11,
+ options,
+ declaration_texcoord,
+ vertex_size_texcoord,
+ flags11,
+ &epsilons11,
+ adjacency11,
+ (BYTE*)exp_vertices11,
+ exp_indices11,
+ exp_face_remap11,
+ exp_vertex_remap11,
+ exp_new_num_vertices11
+ },
+ {
+ (BYTE*)vertices12,
+ indices12,
+ attributes12,
+ num_vertices12,
+ num_faces12,
+ options,
+ declaration_color,
+ vertex_size_color,
+ flags12,
+ &epsilons12,
+ adjacency12,
+ (BYTE*)exp_vertices12,
+ exp_indices12,
+ exp_face_remap12,
+ exp_vertex_remap12,
+ exp_new_num_vertices12
+ },
+ {
+ (BYTE*)vertices13,
+ indices13,
+ attributes13,
+ num_vertices13,
+ num_faces13,
+ options,
+ declaration_normal3,
+ vertex_size_normal,
+ flags13,
+ &epsilons13,
+ adjacency13,
+ (BYTE*)exp_vertices13,
+ exp_indices13,
+ exp_face_remap13,
+ exp_vertex_remap13,
+ exp_new_num_vertices13
+ },
+ {
+ (BYTE*)vertices14,
+ indices14,
+ attributes14,
+ num_vertices14,
+ num_faces14,
+ options,
+ declaration_color,
+ vertex_size_color,
+ flags14,
+ &epsilons14,
+ adjacency14,
+ (BYTE*)exp_vertices14,
+ exp_indices14,
+ exp_face_remap14,
+ exp_vertex_remap14,
+ exp_new_num_vertices14
+ },
+ {
+ (BYTE*)vertices15,
+ indices15,
+ attributes15,
+ num_vertices15,
+ num_faces15,
+ options,
+ declaration_color_ubyte4n,
+ vertex_size_color_ubyte4, /* UBYTE4 same size as UBYTE4N */
+ flags15,
+ &epsilons15,
+ adjacency15,
+ (BYTE*)exp_vertices15,
+ exp_indices15,
+ exp_face_remap15,
+ exp_vertex_remap15,
+ exp_new_num_vertices15
+ },
+ {
+ (BYTE*)vertices16,
+ indices16,
+ attributes16,
+ num_vertices16,
+ num_faces16,
+ options,
+ declaration_color_ubyte4,
+ vertex_size_color_ubyte4,
+ flags16,
+ &epsilons16,
+ adjacency16,
+ (BYTE*)exp_vertices16,
+ exp_indices16,
+ exp_face_remap16,
+ exp_vertex_remap16,
+ exp_new_num_vertices16
+ },
+ {
+ (BYTE*)vertices17,
+ indices17,
+ attributes17,
+ num_vertices17,
+ num_faces17,
+ options,
+ declaration_texcoord_short2,
+ vertex_size_texcoord_short2,
+ flags17,
+ &epsilons17,
+ adjacency17,
+ (BYTE*)exp_vertices17,
+ exp_indices17,
+ exp_face_remap17,
+ exp_vertex_remap17,
+ exp_new_num_vertices17
+ },
+ {
+ (BYTE*)vertices18,
+ indices18,
+ attributes18,
+ num_vertices18,
+ num_faces18,
+ options,
+ declaration_texcoord_short2n,
+ vertex_size_texcoord_short2, /* SHORT2 same size as SHORT2N */
+ flags18,
+ &epsilons18,
+ adjacency18,
+ (BYTE*)exp_vertices18,
+ exp_indices18,
+ exp_face_remap18,
+ exp_vertex_remap18,
+ exp_new_num_vertices18
+ },
+ {
+ (BYTE*)vertices19,
+ indices19,
+ attributes19,
+ num_vertices19,
+ num_faces19,
+ options,
+ declaration_texcoord_ushort2n,
+ vertex_size_texcoord_short2, /* SHORT2 same size as USHORT2N */
+ flags19,
+ &epsilons19,
+ adjacency19,
+ (BYTE*)exp_vertices19,
+ exp_indices19,
+ exp_face_remap19,
+ exp_vertex_remap19,
+ exp_new_num_vertices19
+ },
+ {
+ (BYTE*)vertices20,
+ indices20,
+ attributes20,
+ num_vertices20,
+ num_faces20,
+ options,
+ declaration_normal_short4,
+ vertex_size_normal_short4,
+ flags20,
+ &epsilons20,
+ adjacency20,
+ (BYTE*)exp_vertices20,
+ exp_indices20,
+ exp_face_remap20,
+ exp_vertex_remap20,
+ exp_new_num_vertices20
+ },
+ {
+ (BYTE*)vertices21,
+ indices21,
+ attributes21,
+ num_vertices21,
+ num_faces21,
+ options,
+ declaration_normal_short4n,
+ vertex_size_normal_short4, /* SHORT4 same size as SHORT4N */
+ flags21,
+ &epsilons21,
+ adjacency21,
+ (BYTE*)exp_vertices21,
+ exp_indices21,
+ exp_face_remap21,
+ exp_vertex_remap21,
+ exp_new_num_vertices21
+ },
+ {
+ (BYTE*)vertices22,
+ indices22,
+ attributes22,
+ num_vertices22,
+ num_faces22,
+ options,
+ declaration_normal_ushort4n,
+ vertex_size_normal_short4, /* SHORT4 same size as USHORT4N */
+ flags22,
+ &epsilons22,
+ adjacency22,
+ (BYTE*)exp_vertices22,
+ exp_indices22,
+ exp_face_remap22,
+ exp_vertex_remap22,
+ exp_new_num_vertices22
+ },
+ {
+ (BYTE*)vertices23,
+ indices23,
+ attributes23,
+ num_vertices23,
+ num_faces23,
+ options,
+ declaration_texcoord_float16_2,
+ vertex_size_texcoord_float16_2,
+ flags23,
+ &epsilons23,
+ adjacency23,
+ (BYTE*)exp_vertices23,
+ exp_indices23,
+ exp_face_remap23,
+ exp_vertex_remap23,
+ exp_new_num_vertices23
+ },
+ {
+ (BYTE*)vertices24,
+ indices24,
+ attributes24,
+ num_vertices24,
+ num_faces24,
+ options,
+ declaration_texcoord_float16_4,
+ vertex_size_texcoord_float16_4,
+ flags24,
+ &epsilons24,
+ adjacency24,
+ (BYTE*)exp_vertices24,
+ exp_indices24,
+ exp_face_remap24,
+ exp_vertex_remap24,
+ exp_new_num_vertices24
+ },
+ {
+ (BYTE*)vertices25,
+ indices25,
+ attributes25,
+ num_vertices25,
+ num_faces25,
+ options,
+ declaration_texcoord10,
+ vertex_size_texcoord,
+ flags25,
+ &epsilons25,
+ adjacency25,
+ (BYTE*)exp_vertices25,
+ exp_indices25,
+ exp_face_remap25,
+ exp_vertex_remap25,
+ exp_new_num_vertices25
+ },
+ {
+ (BYTE*)vertices26,
+ indices26,
+ attributes26,
+ num_vertices26,
+ num_faces26,
+ options,
+ declaration_color2,
+ vertex_size_color,
+ flags26,
+ &epsilons26,
+ adjacency26,
+ (BYTE*)exp_vertices26,
+ exp_indices26,
+ exp_face_remap26,
+ exp_vertex_remap26,
+ exp_new_num_vertices26
+ },
+ {
+ (BYTE*)vertices27,
+ indices27,
+ attributes27,
+ num_vertices27,
+ num_faces27,
+ options,
+ declaration_color1,
+ vertex_size_color,
+ flags27,
+ &epsilons27,
+ adjacency27,
+ (BYTE*)exp_vertices27,
+ exp_indices27,
+ exp_face_remap27,
+ exp_vertex_remap27,
+ exp_new_num_vertices27
+ },
+ {
+ (BYTE*)vertices28,
+ indices28,
+ attributes28,
+ num_vertices28,
+ num_faces28,
+ options,
+ declaration_normal_udec3,
+ vertex_size_normal_udec3,
+ flags28,
+ &epsilons28,
+ adjacency28,
+ (BYTE*)exp_vertices28,
+ exp_indices28,
+ exp_face_remap28,
+ exp_vertex_remap28,
+ exp_new_num_vertices28
+ },
+ {
+ (BYTE*)vertices29,
+ indices29,
+ attributes29,
+ num_vertices29,
+ num_faces29,
+ options,
+ declaration_normal_dec3n,
+ vertex_size_normal_dec3n,
+ flags29,
+ &epsilons29,
+ adjacency29,
+ (BYTE*)exp_vertices29,
+ exp_indices29,
+ exp_face_remap29,
+ exp_vertex_remap29,
+ exp_new_num_vertices29
+ }
+ };
+#ifdef __REACTOS__
+#undef up
+#endif
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ DWORD j;
+ DWORD *vertex_remap_ptr;
+ DWORD new_num_vertices;
+
+ hr = init_test_mesh(tc[i].num_faces, tc[i].num_vertices, tc[i].options,
+ tc[i].declaration, test_context->device, &mesh,
+ tc[i].vertices, tc[i].vertex_size,
+ tc[i].indices, tc[i].attributes);
+ if (FAILED(hr))
+ {
+ skip("Couldn't initialize test mesh %d.\n", i);
+ goto cleanup;
+ }
+
+ /* Allocate out parameters */
+ adjacency_out = HeapAlloc(GetProcessHeap(), 0, VERTS_PER_FACE * tc[i].num_faces * sizeof(*adjacency_out));
+ if (!adjacency_out)
+ {
+ skip("Couldn't allocate adjacency_out array.\n");
+ goto cleanup;
+ }
+ face_remap = HeapAlloc(GetProcessHeap(), 0, tc[i].num_faces * sizeof(*face_remap));
+ if (!face_remap)
+ {
+ skip("Couldn't allocate face_remap array.\n");
+ goto cleanup;
+ }
+
+ hr = D3DXWeldVertices(mesh, tc[i].flags, tc[i].epsilons, tc[i].adjacency,
+ adjacency_out, face_remap, &vertex_remap);
+ ok(hr == D3D_OK, "Expected D3D_OK, got %#x\n", hr);
+ /* Check number of vertices*/
+ new_num_vertices = mesh->lpVtbl->GetNumVertices(mesh);
+ ok(new_num_vertices == tc[i].exp_new_num_vertices,
+ "Mesh %d: new_num_vertices == %d, expected %d.\n",
+ i, new_num_vertices, tc[i].exp_new_num_vertices);
+ /* Check index buffer */
+ if (tc[i].options & D3DXMESH_32BIT)
+ {
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, (void**)&indices);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock index buffer.\n");
+ goto cleanup;
+ }
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(indices[j] == tc[i].exp_indices[j],
+ "Mesh %d: indices[%d] == %d, expected %d\n",
+ i, j, indices[j], tc[i].exp_indices[j]);
+ }
+ }
+ else
+ {
+ hr = mesh->lpVtbl->LockIndexBuffer(mesh, 0, (void**)&indices_16bit);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock index buffer.\n");
+ goto cleanup;
+ }
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(indices_16bit[j] == tc[i].exp_indices[j],
+ "Mesh %d: indices_16bit[%d] == %d, expected %d\n",
+ i, j, indices_16bit[j], tc[i].exp_indices[j]);
+ }
+ }
+ mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ indices = NULL;
+ indices_16bit = NULL;
+ /* Check adjacency_out */
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(adjacency_out[j] == tc[i].adjacency[j],
+ "Mesh %d: adjacency_out[%d] == %d, expected %d\n",
+ i, j, adjacency_out[j], tc[i].adjacency[j]);
+ }
+ /* Check face_remap */
+ for (j = 0; j < tc[i].num_faces; j++)
+ {
+ ok(face_remap[j] == tc[i].exp_face_remap[j],
+ "Mesh %d: face_remap[%d] == %d, expected %d\n",
+ i, j, face_remap[j], tc[i].exp_face_remap[j]);
+ }
+ /* Check vertex_remap */
+ vertex_remap_ptr = vertex_remap->lpVtbl->GetBufferPointer(vertex_remap);
+ for (j = 0; j < VERTS_PER_FACE * tc[i].num_faces; j++)
+ {
+ ok(vertex_remap_ptr[j] == tc[i].exp_vertex_remap[j],
+ "Mesh %d: vertex_remap_ptr[%d] == %d, expected %d\n",
+ i, j, vertex_remap_ptr[j], tc[i].exp_vertex_remap[j]);
+ }
+ /* Check vertex buffer */
+ hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void*)&vertices);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock vertex buffer.\n");
+ goto cleanup;
+ }
+ /* Check contents of re-ordered vertex buffer */
+ for (j = 0; j < tc[i].exp_new_num_vertices; j++)
+ {
+ int index = tc[i].vertex_size*j;
+ check_vertex_components(__LINE__, i, j, &vertices[index], &tc[i].exp_vertices[index], tc[i].declaration);
+ }
+ mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ vertices = NULL;
+
+ /* Free mesh and output data */
+ HeapFree(GetProcessHeap(), 0, adjacency_out);
+ adjacency_out = NULL;
+ HeapFree(GetProcessHeap(), 0, face_remap);
+ face_remap = NULL;
+ vertex_remap->lpVtbl->Release(vertex_remap);
+ vertex_remap = NULL;
+ mesh->lpVtbl->Release(mesh);
+ mesh = NULL;
+ }
+
+cleanup:
+ HeapFree(GetProcessHeap(), 0, adjacency_out);
+ HeapFree(GetProcessHeap(), 0, face_remap);
+ if (indices) mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ if (indices_16bit) mesh->lpVtbl->UnlockIndexBuffer(mesh);
+ if (mesh) mesh->lpVtbl->Release(mesh);
+ if (vertex_remap) vertex_remap->lpVtbl->Release(vertex_remap);
+ if (vertices) mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ free_test_context(test_context);
+}
+
+static void test_clone_mesh(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ const DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ D3DVERTEXELEMENT9 declaration_pn[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_pntc[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptcn[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float16_2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float16_4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT16_4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float3[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_d3dcolor[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_ubyte4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_ubyte4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_short2[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_short4[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_short2n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_short4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_SHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_ushort2n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_USHORT2N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_ushort4n[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_ptc_float16_2_partialu[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT16_2, D3DDECLMETHOD_PARTIALU, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+ };
+ D3DVERTEXELEMENT9 declaration_pntc1[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
+ D3DDECL_END()
+ };
+ const unsigned int VERTS_PER_FACE = 3;
+ BYTE *vertices = NULL;
+ INT i;
+ struct vertex_pn
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ };
+ struct vertex_pntc
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR3 normal;
+ D3DXVECTOR2 texcoords;
+ };
+ struct vertex_ptcn
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR2 texcoords;
+ D3DXVECTOR3 normal;
+ };
+ struct vertex_ptc
+ {
+ D3DXVECTOR3 position;
+ D3DXVECTOR2 texcoords;
+ };
+ struct vertex_ptc_float16_2
+ {
+ D3DXVECTOR3 position;
+ WORD texcoords[2]; /* float16_2 */
+ };
+ struct vertex_ptc_float16_4
+ {
+ D3DXVECTOR3 position;
+ WORD texcoords[4]; /* float16_4 */
+ };
+ struct vertex_ptc_float1
+ {
+ D3DXVECTOR3 position;
+ FLOAT texcoords;
+ };
+ struct vertex_ptc_float3
+ {
+ D3DXVECTOR3 position;
+ FLOAT texcoords[3];
+ };
+ struct vertex_ptc_float4
+ {
+ D3DXVECTOR3 position;
+ FLOAT texcoords[4];
+ };
+ struct vertex_ptc_d3dcolor
+ {
+ D3DXVECTOR3 position;
+ BYTE texcoords[4];
+ };
+ struct vertex_ptc_ubyte4
+ {
+ D3DXVECTOR3 position;
+ BYTE texcoords[4];
+ };
+ struct vertex_ptc_ubyte4n
+ {
+ D3DXVECTOR3 position;
+ BYTE texcoords[4];
+ };
+ struct vertex_ptc_short2
+ {
+ D3DXVECTOR3 position;
+ SHORT texcoords[2];
+ };
+ struct vertex_ptc_short4
+ {
+ D3DXVECTOR3 position;
+ SHORT texcoords[4];
+ };
+ struct vertex_ptc_ushort2n
+ {
+ D3DXVECTOR3 position;
+ USHORT texcoords[2];
+ };
+ struct vertex_ptc_ushort4n
+ {
+ D3DXVECTOR3 position;
+ USHORT texcoords[4];
+ };
+ struct vertex_ptc_udec3
+ {
+ D3DXVECTOR3 position;
+ DWORD texcoords;
+ };
+ struct vertex_ptc_dec3n
+ {
+ D3DXVECTOR3 position;
+ DWORD texcoords;
+ };
+#ifndef __REACTOS__
+ D3DXVECTOR3 up = {0.0f, 0.0f, 1.0f};
+ D3DXVECTOR2 zero_vec2 = {0.0f, 0.0f};
+#else
+#define up {0.0f, 0.0f, 1.0f}
+#define zero_vec2 {0.0f, 0.0f}
+#endif
+ /* Test 0. Check that a mesh can be cloned if the new declaration is the
+ * same as the one used to create the mesh.
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const struct vertex_pn vertices0[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+
+ {{ 3.0f, 3.0f, 0.f}, up},
+ {{ 3.0f, 0.0f, 0.f}, up},
+ {{ 1.0f, 0.0f, 0.f}, up},
+ };
+ const UINT num_vertices0 = ARRAY_SIZE(vertices0);
+ const UINT num_faces0 = ARRAY_SIZE(vertices0) / VERTS_PER_FACE;
+ const UINT vertex_size0 = sizeof(*vertices0);
+ /* Test 1. Check that 16-bit indices are handled. */
+ const DWORD options_16bit = D3DXMESH_SYSTEMMEM;
+ /* Test 2. Check that the size of each vertex is increased and the data
+ * moved if the new declaration adds an element after the original elements.
+ */
+ const struct vertex_pntc exp_vertices2[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 2.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 0.0f, 0.0f, 0.f}, up, zero_vec2},
+
+ {{ 3.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 3.0f, 0.0f, 0.f}, up, zero_vec2},
+ {{ 1.0f, 0.0f, 0.f}, up, zero_vec2},
+ };
+ const UINT exp_vertex_size2 = sizeof(*exp_vertices2);
+ /* Test 3. Check that the size of each vertex is increased and the data
+ * moved if the new declaration adds an element between the original
+ * elements.
+ */
+ const struct vertex_ptcn exp_vertices3[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, zero_vec2, up},
+ {{ 2.0f, 3.0f, 0.f}, zero_vec2, up},
+ {{ 0.0f, 0.0f, 0.f}, zero_vec2, up},
+
+ {{ 3.0f, 3.0f, 0.f}, zero_vec2, up},
+ {{ 3.0f, 0.0f, 0.f}, zero_vec2, up},
+ {{ 1.0f, 0.0f, 0.f}, zero_vec2, up},
+ };
+ const UINT exp_vertex_size3 = sizeof(*exp_vertices3);
+ /* Test 4. Test that data types can be converted, e.g. FLOAT2 to FLOAT16_2. */
+ const struct vertex_ptc vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices4 = ARRAY_SIZE(vertices4);
+ const UINT num_faces4 = ARRAY_SIZE(vertices4) / VERTS_PER_FACE;
+ const UINT vertex_size4 = sizeof(*vertices4);
+ const struct vertex_ptc_float16_2 exp_vertices4[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
+ };
+ const UINT exp_vertex_size4 = sizeof(*exp_vertices4);
+ /* Test 5. Convert FLOAT2 to FLOAT16_4. */
+ const struct vertex_ptc vertices5[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices5 = ARRAY_SIZE(vertices5);
+ const UINT num_faces5 = ARRAY_SIZE(vertices5) / VERTS_PER_FACE;
+ const UINT vertex_size5 = sizeof(*vertices5);
+ const struct vertex_ptc_float16_4 exp_vertices5[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00, 0, 0x3c00}}, /* {1.0f, 1.0f, 0.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a, 0, 0x3c00}}, /* {0.5f, 0.7f, 0.0f, 1.0f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd, 0, 0x3c00}}, /* {-0.2f, -0.3f, 0.0f, 1.0f} */
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd, 0, 0x3c00}}, /* {0.2f, 0.3f, 0.0f, 1.0f} */
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00, 0, 0x3c00}}, /* {1.0f, 1.0f, 0.0f, 1.0f} */
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266, 0, 0x3c00}}, /* {0.1f, 0.2f, 0.0f, 1.0f} */
+ };
+ const UINT exp_vertex_size5 = sizeof(*exp_vertices5);
+ /* Test 6. Convert FLOAT2 to FLOAT1. */
+ const struct vertex_ptc vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices6 = ARRAY_SIZE(vertices6);
+ const UINT num_faces6 = ARRAY_SIZE(vertices6) / VERTS_PER_FACE;
+ const UINT vertex_size6 = sizeof(*vertices6);
+ const struct vertex_ptc_float1 exp_vertices6[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 0.5f},
+ {{ 0.0f, 0.0f, 0.f}, -0.2f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.2f},
+ {{ 3.0f, 0.0f, 0.f}, 1.0f},
+ {{ 1.0f, 0.0f, 0.f}, 0.1f},
+ };
+ const UINT exp_vertex_size6 = sizeof(*exp_vertices6);
+ /* Test 7. Convert FLOAT2 to FLOAT3. */
+ const struct vertex_ptc vertices7[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices7 = ARRAY_SIZE(vertices7);
+ const UINT num_faces7 = ARRAY_SIZE(vertices7) / VERTS_PER_FACE;
+ const UINT vertex_size7 = sizeof(*vertices7);
+ const struct vertex_ptc_float3 exp_vertices7[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f, 0.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f, 0.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f, 0.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f, 0.0f}},
+ };
+ const UINT exp_vertex_size7 = sizeof(*exp_vertices7);
+ /* Test 8. Convert FLOAT2 to FLOAT4. */
+ const struct vertex_ptc vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices8 = ARRAY_SIZE(vertices8);
+ const UINT num_faces8 = ARRAY_SIZE(vertices8) / VERTS_PER_FACE;
+ const UINT vertex_size8 = sizeof(*vertices8);
+ const struct vertex_ptc_float4 exp_vertices8[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f, 0.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f, 0.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f, 0.0f, 1.0f}},
+ };
+ const UINT exp_vertex_size8 = sizeof(*exp_vertices8);
+ /* Test 9. Convert FLOAT2 to D3DCOLOR. */
+ const struct vertex_ptc vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.4f, -0.6f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 2.0f, 256.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.11f, 0.2f}},
+ };
+ const UINT num_vertices9 = ARRAY_SIZE(vertices9);
+ const UINT num_faces9 = ARRAY_SIZE(vertices9) / VERTS_PER_FACE;
+ const UINT vertex_size9 = sizeof(*vertices9);
+ const struct vertex_ptc_d3dcolor exp_vertices9[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 255, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 179, 128, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 77, 51, 255}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 255, 255, 255}},
+ {{ 1.0f, 0.0f, 0.f}, {0, 51, 28, 255}},
+ };
+ const UINT exp_vertex_size9 = sizeof(*exp_vertices9);
+ /* Test 10. Convert FLOAT2 to UBYTE4. */
+ const struct vertex_ptc vertices10[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 2.0f, 3.0f}},
+ {{ 0.0f, 0.0f, 0.f}, { 254.0f, 255.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 256.0f, 257.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.4f, 1.5f}},
+ {{ 1.0f, 0.0f, 0.f}, {-4.0f, -5.0f}},
+ };
+ const UINT num_vertices10 = ARRAY_SIZE(vertices10);
+ const UINT num_faces10 = ARRAY_SIZE(vertices10) / VERTS_PER_FACE;
+ const UINT vertex_size10 = sizeof(*vertices10);
+ const struct vertex_ptc_ubyte4 exp_vertices10[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 2.0f, 3.0f, 0.f}, {2, 3, 0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {254, 255, 0, 1}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {1, 2, 0, 1}},
+ {{ 1.0f, 0.0f, 0.f}, {0, 0, 0, 1}},
+ };
+ const UINT exp_vertex_size10 = sizeof(*exp_vertices10);
+ /* Test 11. Convert FLOAT2 to SHORT2. */
+ const struct vertex_ptc vertices11[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, -1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.5f, -5.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MIN}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MAX + 1.0f, SHRT_MIN - 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX + 2.0f, SHRT_MIN - 2.0f}},
+
+ {{ 4.0f, 3.0f, 0.f}, {2 * SHRT_MAX, 2 * SHRT_MIN}},
+ {{ 6.0f, 0.0f, 0.f}, {3 * SHRT_MAX, 3 * SHRT_MIN}},
+ {{ 4.0f, 0.0f, 0.f}, {4 * SHRT_MAX, 4 * SHRT_MIN}},
+ };
+ const UINT num_vertices11 = ARRAY_SIZE(vertices11);
+ const UINT num_faces11 = ARRAY_SIZE(vertices11) / VERTS_PER_FACE;
+ const UINT vertex_size11 = sizeof(*vertices11);
+ const struct vertex_ptc_short2 exp_vertices11[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {0, -4}},
+
+ {{ 3.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MIN + 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MIN}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MIN + 1, SHRT_MAX}},
+
+ {{ 4.0f, 3.0f, 0.f}, {-2, 1}},
+ {{ 6.0f, 0.0f, 0.f}, {32765, -32767}},
+ {{ 4.0f, 0.0f, 0.f}, {-4, 1}},
+ };
+ const UINT exp_vertex_size11 = sizeof(*exp_vertices11);
+ /* Test 12. Convert FLOAT2 to SHORT4. */
+ const struct vertex_ptc vertices12[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, -1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.5f, -5.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MIN}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MAX + 1.0f, SHRT_MIN - 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX + 2.0f, SHRT_MIN - 2.0f}},
+
+ {{ 4.0f, 3.0f, 0.f}, {2 * SHRT_MAX, 2 * SHRT_MIN}},
+ {{ 6.0f, 0.0f, 0.f}, {3 * SHRT_MAX, 3 * SHRT_MIN}},
+ {{ 4.0f, 0.0f, 0.f}, {4 * SHRT_MAX, 4 * SHRT_MIN}},
+ };
+ const UINT num_vertices12 = ARRAY_SIZE(vertices12);
+ const UINT num_faces12 = ARRAY_SIZE(vertices12) / VERTS_PER_FACE;
+ const UINT vertex_size12 = sizeof(*vertices12);
+ const struct vertex_ptc_short4 exp_vertices12[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1, 0, 0, 1}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {0, -4, 0, 1}},
+
+ {{ 3.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MIN + 1, 0, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MIN, 0, 1}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MIN + 1, SHRT_MAX, 0, 1}},
+
+ {{ 4.0f, 3.0f, 0.f}, {-2, 1, 0, 1}},
+ {{ 6.0f, 0.0f, 0.f}, {32765, -32767, 0, 1}},
+ {{ 4.0f, 0.0f, 0.f}, {-4, 1, 0, 1}},
+ };
+ const UINT exp_vertex_size12 = sizeof(*exp_vertices12);
+ /* Test 13. Convert FLOAT2 to UBYTE4N. */
+ const struct vertex_ptc vertices13[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 2.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.4f, -0.5f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-0.6f, -1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {UCHAR_MAX, UCHAR_MAX + 1}},
+ {{ 1.0f, 0.0f, 0.f}, {2 * UCHAR_MAX, -UCHAR_MAX}},
+ };
+ const UINT num_vertices13 = ARRAY_SIZE(vertices13);
+ const UINT num_faces13 = ARRAY_SIZE(vertices13) / VERTS_PER_FACE;
+ const UINT vertex_size13 = sizeof(*vertices13);
+ const struct vertex_ptc_ubyte4n exp_vertices13[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {255, 255, 0, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {128, 179, 0, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 0, 0, 255}},
+ {{ 3.0f, 0.0f, 0.f}, {255, 255, 0, 255}},
+ {{ 1.0f, 0.0f, 0.f}, {255, 0, 0, 255}},
+ };
+ const UINT exp_vertex_size13 = sizeof(*exp_vertices13);
+ /* Test 14. Convert FLOAT2 to SHORT2N. */
+ const struct vertex_ptc vertices14[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 2.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.6f, -1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-0.4f, -0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, {-0.9f, -0.99997}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX, SHRT_MIN}},
+ };
+ const UINT num_vertices14 = ARRAY_SIZE(vertices14);
+ const UINT num_faces14 = ARRAY_SIZE(vertices14) / VERTS_PER_FACE;
+ const UINT vertex_size14 = sizeof(*vertices14);
+ const struct vertex_ptc_short2 exp_vertices14[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MAX}},
+ {{ 2.0f, 3.0f, 0.f}, {13107, 16384}},
+ {{ 0.0f, 0.0f, 0.f}, {19660, SHRT_MIN + 2}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-13106, -16383}},
+ {{ 3.0f, 0.0f, 0.f}, {-29489, SHRT_MIN + 3}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX, SHRT_MIN + 2}},
+ };
+ const UINT exp_vertex_size14 = sizeof(*exp_vertices14);
+ /* Test 15. Convert FLOAT2 to SHORT4N. */
+ const struct vertex_ptc vertices15[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 2.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.6f, -1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-0.4f, -0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, {-0.9f, -0.99997}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX, SHRT_MIN}},
+ };
+ const UINT num_vertices15 = ARRAY_SIZE(vertices15);
+ const UINT num_faces15 = ARRAY_SIZE(vertices15) / VERTS_PER_FACE;
+ const UINT vertex_size15 = sizeof(*vertices15);
+ const struct vertex_ptc_short4 exp_vertices15[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {SHRT_MAX, SHRT_MAX, 0, SHRT_MAX}},
+ {{ 2.0f, 3.0f, 0.f}, {13107, 16384, 0, SHRT_MAX}},
+ {{ 0.0f, 0.0f, 0.f}, {19660, SHRT_MIN + 2, 0, SHRT_MAX}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-13106, -16383, 0, SHRT_MAX}},
+ {{ 3.0f, 0.0f, 0.f}, {-29489, SHRT_MIN + 3, 0, SHRT_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {SHRT_MAX, SHRT_MIN + 2, 0, SHRT_MAX}},
+ };
+ const UINT exp_vertex_size15 = sizeof(*exp_vertices15);
+ /* Test 16. Convert FLOAT2 to USHORT2N. */
+ const struct vertex_ptc vertices16[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 2.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.6f, -1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-0.4f, -0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, {-0.9f, 0.99998f}},
+ {{ 1.0f, 0.0f, 0.f}, {USHRT_MAX, 0.0f}},
+ };
+ const UINT num_vertices16 = ARRAY_SIZE(vertices16);
+ const UINT num_faces16 = ARRAY_SIZE(vertices16) / VERTS_PER_FACE;
+ const UINT vertex_size16 = sizeof(*vertices16);
+ const struct vertex_ptc_ushort2n exp_vertices16[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {USHRT_MAX, USHRT_MAX}},
+ {{ 2.0f, 3.0f, 0.f}, {26214, 32768}},
+ {{ 0.0f, 0.0f, 0.f}, {39321, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 0}},
+ {{ 3.0f, 0.0f, 0.f}, {0, USHRT_MAX - 1}},
+ {{ 1.0f, 0.0f, 0.f}, {USHRT_MAX, 0}},
+ };
+ const UINT exp_vertex_size16 = sizeof(*exp_vertices16);
+ /* Test 17. Convert FLOAT2 to USHORT4N. */
+ const struct vertex_ptc vertices17[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 2.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.4f, 0.5f}},
+ {{ 0.0f, 0.0f, 0.f}, {0.6f, -1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {-0.4f, -0.5f}},
+ {{ 3.0f, 0.0f, 0.f}, {-0.9f, 0.99998f}},
+ {{ 1.0f, 0.0f, 0.f}, {USHRT_MAX, 0.0f}},
+ };
+ const UINT num_vertices17 = ARRAY_SIZE(vertices17);
+ const UINT num_faces17 = ARRAY_SIZE(vertices17) / VERTS_PER_FACE;
+ const UINT vertex_size17 = sizeof(*vertices17);
+ const struct vertex_ptc_ushort4n exp_vertices17[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {USHRT_MAX, USHRT_MAX, 0, USHRT_MAX}},
+ {{ 2.0f, 3.0f, 0.f}, {26214, 32768, 0, USHRT_MAX}},
+ {{ 0.0f, 0.0f, 0.f}, {39321, 0, 0, USHRT_MAX}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 0, 0, USHRT_MAX}},
+ {{ 3.0f, 0.0f, 0.f}, {0, USHRT_MAX - 1, 0, USHRT_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {USHRT_MAX, 0, 0, USHRT_MAX}},
+ };
+ const UINT exp_vertex_size17 = sizeof(*exp_vertices17);
+ /* Test 18. Test that the method field is compared by converting a FLOAT2 to
+ * FLOAT16_2. where the method field has been change from
+ * D3DDECLMETHOD_DEFAULT to D3DDECLMETHOD_PARTIALU. */
+ const struct vertex_ptc vertices18[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices18 = ARRAY_SIZE(vertices18);
+ const UINT num_faces18 = ARRAY_SIZE(vertices18) / VERTS_PER_FACE;
+ const UINT vertex_size18 = sizeof(*vertices18);
+ const struct vertex_ptc_float16_2 exp_vertices18[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
+ };
+ const UINT exp_vertex_size18 = sizeof(*exp_vertices18);
+ /* Test 19. Test that data is lost if usage index changes, e.g. TEXCOORD0
+ * TEXCOORD1. */
+ const struct vertex_pntc vertices19[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, up, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, up, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, up, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, up, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, up, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices19 = ARRAY_SIZE(vertices19);
+ const UINT num_faces19 = ARRAY_SIZE(vertices19) / VERTS_PER_FACE;
+ const UINT vertex_size19 = sizeof(*vertices19);
+ const struct vertex_pntc exp_vertices19[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 2.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 0.0f, 0.0f, 0.f}, up, zero_vec2},
+
+ {{ 3.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 3.0f, 0.0f, 0.f}, up, zero_vec2},
+ {{ 1.0f, 0.0f, 0.f}, up, zero_vec2},
+ };
+ const UINT exp_vertex_size19 = sizeof(*exp_vertices19);
+ /* Test 20. Another test that data is lost if usage index changes, e.g.
+ * TEXCOORD1 to TEXCOORD0. */
+ const struct vertex_pntc vertices20[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, { 1.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, up, { 0.5f, 0.7f}},
+ {{ 0.0f, 0.0f, 0.f}, up, {-0.2f, -0.3f}},
+
+ {{ 3.0f, 3.0f, 0.f}, up, { 0.2f, 0.3f}},
+ {{ 3.0f, 0.0f, 0.f}, up, { 1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, up, { 0.1f, 0.2f}},
+ };
+ const UINT num_vertices20 = ARRAY_SIZE(vertices20);
+ const UINT num_faces20 = ARRAY_SIZE(vertices20) / VERTS_PER_FACE;
+ const UINT vertex_size20 = sizeof(*vertices20);
+ const struct vertex_pntc exp_vertices20[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 2.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 0.0f, 0.0f, 0.f}, up, zero_vec2},
+
+ {{ 3.0f, 3.0f, 0.f}, up, zero_vec2},
+ {{ 3.0f, 0.0f, 0.f}, up, zero_vec2},
+ {{ 1.0f, 0.0f, 0.f}, up, zero_vec2},
+ };
+ const UINT exp_vertex_size20 = sizeof(*exp_vertices20);
+ /* Test 21. Convert FLOAT1 to FLOAT2. */
+ const struct vertex_ptc_float1 vertices21[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 0.5f},
+ {{ 0.0f, 0.0f, 0.f}, -0.2f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.2f},
+ {{ 3.0f, 0.0f, 0.f}, 1.0f},
+ {{ 1.0f, 0.0f, 0.f}, 0.1f},
+ };
+ const UINT num_vertices21 = ARRAY_SIZE(vertices21);
+ const UINT num_faces21 = ARRAY_SIZE(vertices21) / VERTS_PER_FACE;
+ const UINT vertex_size21 = sizeof(*vertices21);
+ const struct vertex_ptc exp_vertices21[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 0.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.0f}},
+ };
+ const UINT exp_vertex_size21 = sizeof(*exp_vertices21);
+ /* Test 22. Convert FLOAT1 to FLOAT3. */
+ const struct vertex_ptc_float1 vertices22[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 0.5f},
+ {{ 0.0f, 0.0f, 0.f}, -0.2f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.2f},
+ {{ 3.0f, 0.0f, 0.f}, 1.0f},
+ {{ 1.0f, 0.0f, 0.f}, 0.1f},
+ };
+ const UINT num_vertices22 = ARRAY_SIZE(vertices22);
+ const UINT num_faces22 = ARRAY_SIZE(vertices22) / VERTS_PER_FACE;
+ const UINT vertex_size22 = sizeof(*vertices22);
+ const struct vertex_ptc_float3 exp_vertices22[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.0f, 0.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, 0.0f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.0f, 0.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 0.0f, 0.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.0f, 0.0f}},
+ };
+ const UINT exp_vertex_size22 = sizeof(*exp_vertices22);
+ /* Test 23. Convert FLOAT1 to FLOAT4. */
+ const struct vertex_ptc_float1 vertices23[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 0.5f},
+ {{ 0.0f, 0.0f, 0.f}, -0.2f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.2f},
+ {{ 3.0f, 0.0f, 0.f}, 1.0f},
+ {{ 1.0f, 0.0f, 0.f}, 0.1f},
+ };
+ const UINT num_vertices23 = ARRAY_SIZE(vertices23);
+ const UINT num_faces23 = ARRAY_SIZE(vertices23) / VERTS_PER_FACE;
+ const UINT vertex_size23 = sizeof(*vertices23);
+ const struct vertex_ptc_float4 exp_vertices23[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, { 1.0f, 0.0f, 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, { 0.5f, 0.0f, 0.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.2f, 0.0f, 0.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, { 0.2f, 0.0f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, { 1.0f, 0.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, { 0.1f, 0.0f, 0.0f, 1.0f}},
+ };
+ const UINT exp_vertex_size23 = sizeof(*exp_vertices23);
+ /* Test 24. Convert FLOAT1 to D3DCOLOR. */
+ const struct vertex_ptc_float1 vertices24[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 1.0f},
+ {{ 2.0f, 3.0f, 0.f}, 0.5f},
+ {{ 0.0f, 0.0f, 0.f}, -0.2f},
+
+ {{ 3.0f, 3.0f, 0.f}, 0.2f},
+ {{ 3.0f, 0.0f, 0.f}, 1.0f},
+ {{ 1.0f, 0.0f, 0.f}, 0.11f},
+ };
+ const UINT num_vertices24 = ARRAY_SIZE(vertices24);
+ const UINT num_faces24 = ARRAY_SIZE(vertices24) / VERTS_PER_FACE;
+ const UINT vertex_size24 = sizeof(*vertices24);
+ const struct vertex_ptc_d3dcolor exp_vertices24[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 255, 255}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 128, 255}},
+ {{ 0.0f, 0.0f, 0.f}, {0, 0, 0, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 0, 51, 255}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 255, 255}},
+ {{ 1.0f, 0.0f, 0.f}, {0, 0, 28, 255}},
+ };
+ const UINT exp_vertex_size24 = sizeof(*exp_vertices24);
+ /* Test 25. Convert FLOAT1 to ubyte4. */
+ const struct vertex_ptc_float1 vertices25[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, 0.0f},
+ {{ 2.0f, 3.0f, 0.f}, 1.4f},
+ {{ 0.0f, 0.0f, 0.f}, 1.5f},
+
+ {{ 3.0f, 3.0f, 0.f}, 255.0f},
+ {{ 3.0f, 0.0f, 0.f}, 256.0f},
+ {{ 1.0f, 0.0f, 0.f}, -1.0f},
+ };
+ const UINT num_vertices25 = ARRAY_SIZE(vertices25);
+ const UINT num_faces25 = ARRAY_SIZE(vertices25) / VERTS_PER_FACE;
+ const UINT vertex_size25 = sizeof(*vertices25);
+ const struct vertex_ptc_ubyte4 exp_vertices25[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 1}},
+ {{ 2.0f, 3.0f, 0.f}, {1, 0, 0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {2, 0, 0, 1}},
+
+ {{ 3.0f, 3.0f, 0.f}, {255, 0, 0, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {0, 0, 0, 1}},
+ {{ 1.0f, 0.0f, 0.f}, {0, 0, 0, 1}},
+ };
+ const UINT exp_vertex_size25 = sizeof(*exp_vertices25);
+ /* Test 26. Convert FLOAT4 to D3DCOLOR. */
+ const struct vertex_ptc_float4 vertices26[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.4f, 0.5f}},
+ {{ 2.0f, 3.0f, 0.f}, {-0.4f, -0.5f, -1.0f, -2.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {254.0f, 255.0f, 256.0f, 257.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.1f, 0.2f, 0.3f, 0.4f}},
+ {{ 3.0f, 0.0f, 0.f}, {0.5f, 0.6f, 0.7f, 0.8f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.9f, 0.99f, 0.995f, 0.999f}},
+ };
+ const UINT num_vertices26 = ARRAY_SIZE(vertices26);
+ const UINT num_faces26 = ARRAY_SIZE(vertices26) / VERTS_PER_FACE;
+ const UINT vertex_size26 = sizeof(*vertices26);
+ const struct vertex_ptc_d3dcolor exp_vertices26[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {102, 255, 0, 128}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, {77, 51, 26, 102}},
+ {{ 3.0f, 0.0f, 0.f}, {179, 153, 128, 204}},
+ {{ 1.0f, 0.0f, 0.f}, {254, 252, 230, 255}},
+ };
+ const UINT exp_vertex_size26 = sizeof(*exp_vertices26);
+ /* Test 27. Convert D3DCOLOR to FLOAT4. */
+ const struct vertex_ptc_d3dcolor vertices27[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {102, 255, 0, 128}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 0.0f, 0.0f, 0.f}, {255, 255, 255, 255}},
+
+ {{ 3.0f, 3.0f, 0.f}, {77, 51, 26, 102}},
+ {{ 3.0f, 0.0f, 0.f}, {179, 153, 128, 204}},
+ {{ 1.0f, 0.0f, 0.f}, {254, 252, 230, 255}},
+ };
+ const UINT num_vertices27 = ARRAY_SIZE(vertices27);
+ const UINT num_faces27 = ARRAY_SIZE(vertices27) / VERTS_PER_FACE;
+ const UINT vertex_size27 = sizeof(*vertices27);
+ const struct vertex_ptc_float4 exp_vertices27[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.4f, 0.501961f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f, 1.0f, 1.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.101961f, 0.2f, 0.301961f, 0.4f}},
+ {{ 3.0f, 0.0f, 0.f}, {0.501961f, 0.6f, 0.701961f, 0.8f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.901961f, 0.988235f, 0.996078f, 1.0f}},
+ };
+ const UINT exp_vertex_size27 = sizeof(*exp_vertices27);
+ /* Test 28. Convert UBYTE4 to FLOAT4. */
+ const struct vertex_ptc_ubyte4 vertices28[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {1, 1, 1, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0, 1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {10, 20, 30, 40}},
+ {{ 1.0f, 0.0f, 0.f}, {50, 60, 127, 255}},
+ };
+ const UINT num_vertices28 = ARRAY_SIZE(vertices28);
+ const UINT num_faces28 = ARRAY_SIZE(vertices28) / VERTS_PER_FACE;
+ const UINT vertex_size28 = sizeof(*vertices28);
+ const struct vertex_ptc_float4 exp_vertices28[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {1.0f, 1.0f, 1.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f, 0.0f, 1.0f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {10.0f, 20.0f, 30.0f, 40.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {50.0f, 60.0f, 127.0f, 255.0f}},
+ };
+ const UINT exp_vertex_size28 = sizeof(*exp_vertices28);
+ /* Test 29. Convert SHORT2 to FLOAT4. */
+ const struct vertex_ptc_short2 vertices29[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {-42, 42}},
+ };
+ const UINT num_vertices29 = ARRAY_SIZE(vertices29);
+ const UINT num_faces29 = ARRAY_SIZE(vertices29) / VERTS_PER_FACE;
+ const UINT vertex_size29 = sizeof(*vertices29);
+ const struct vertex_ptc_float4 exp_vertices29[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.0f, 1.0f }},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f, 0.0f, 0.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MAX, 0.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {-42.0f, 42.0f, 0.0f, 1.0f}},
+ };
+ const UINT exp_vertex_size29 = sizeof(*exp_vertices29);
+ /* Test 29. Convert SHORT4 to FLOAT4. */
+ const struct vertex_ptc_short4 vertices30[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0, 1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1, 1, 1, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MAX, 1, 0}},
+ {{ 1.0f, 0.0f, 0.f}, {-42, 42, SHRT_MAX, SHRT_MIN}},
+ };
+ const UINT num_vertices30 = ARRAY_SIZE(vertices30);
+ const UINT num_faces30 = ARRAY_SIZE(vertices30) / VERTS_PER_FACE;
+ const UINT vertex_size30 = sizeof(*vertices30);
+ const struct vertex_ptc_float4 exp_vertices30[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.0f, 1.0f }},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f, 0.0f, 1.0f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1.0f, 1.0f, 1.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN, SHRT_MAX, 1.0f, 0.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {-42.0f, 42.0f, SHRT_MAX, SHRT_MIN}},
+ };
+ const UINT exp_vertex_size30 = sizeof(*exp_vertices30);
+ /* Test 31. Convert UBYTE4N to FLOAT4. */
+ const struct vertex_ptc_ubyte4n vertices31[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {1, 1, 1, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0, 1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {10, 20, 30, 40}},
+ {{ 1.0f, 0.0f, 0.f}, {50, 60, 70, UCHAR_MAX}},
+ };
+ const UINT num_vertices31 = ARRAY_SIZE(vertices31);
+ const UINT num_faces31 = ARRAY_SIZE(vertices31) / VERTS_PER_FACE;
+ const UINT vertex_size31 = sizeof(*vertices31);
+ const struct vertex_ptc_float4 exp_vertices31[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {(FLOAT)1/UCHAR_MAX, (FLOAT)1/UCHAR_MAX, (FLOAT)1/UCHAR_MAX, (FLOAT)1/UCHAR_MAX}},
+ {{ 0.0f, 0.0f, 0.f}, {(FLOAT)1/UCHAR_MAX, 0.0f, (FLOAT)1/UCHAR_MAX, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, (FLOAT)1/UCHAR_MAX, 0.0f, (FLOAT)1/UCHAR_MAX}},
+ {{ 3.0f, 0.0f, 0.f}, {(FLOAT)10/UCHAR_MAX, (FLOAT)20/UCHAR_MAX, (FLOAT)30/UCHAR_MAX, (FLOAT)40/UCHAR_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {(FLOAT)50/UCHAR_MAX, (FLOAT)60/UCHAR_MAX, (FLOAT)70/UCHAR_MAX, 1.0f}},
+ };
+ const UINT exp_vertex_size31 = sizeof(*exp_vertices31);
+ /* Test 32. Convert SHORT2N to FLOAT4. */
+ const struct vertex_ptc_short2 vertices32[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN + 1, SHRT_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {-42, 42}},
+ };
+ const UINT num_vertices32 = ARRAY_SIZE(vertices32);
+ const UINT num_faces32 = ARRAY_SIZE(vertices32) / VERTS_PER_FACE;
+ const UINT vertex_size32 = sizeof(*vertices32);
+ const struct vertex_ptc_float4 exp_vertices32[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 1.0f/SHRT_MAX, 0.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f/SHRT_MAX, 0.0f, 0.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1.0f/SHRT_MAX, 1.0f/SHRT_MAX, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {-1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {-42.0f/SHRT_MAX, 42.0f/SHRT_MAX, 0.0f, 1.0f}},
+ };
+ const UINT exp_vertex_size32 = sizeof(*exp_vertices32);
+ /* Test 33. Convert SHORT4N to FLOAT4. */
+ const struct vertex_ptc_short4 vertices33[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0, 0, 0, 0}},
+ {{ 2.0f, 3.0f, 0.f}, {0, 1, 0, 1}},
+ {{ 0.0f, 0.0f, 0.f}, {1, 0, 1, 0}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1, 1, 1, 1}},
+ {{ 3.0f, 0.0f, 0.f}, {SHRT_MIN + 1, SHRT_MAX, SHRT_MIN + 1, SHRT_MAX}},
+ {{ 1.0f, 0.0f, 0.f}, {-42, 42, 1, 1}},
+ };
+ const UINT num_vertices33 = ARRAY_SIZE(vertices33);
+ const UINT num_faces33 = ARRAY_SIZE(vertices33) / VERTS_PER_FACE;
+ const UINT vertex_size33 = sizeof(*vertices33);
+ const struct vertex_ptc_float4 exp_vertices33[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.0f, 1.0f/SHRT_MAX, 0.0f, 1.0f/SHRT_MAX}},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f/SHRT_MAX, 0.0f, 1.0f/SHRT_MAX, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {1.0f/SHRT_MAX, 1.0f/SHRT_MAX, 1.0f/SHRT_MAX, 1.0f/SHRT_MAX}},
+ {{ 3.0f, 0.0f, 0.f}, {-1.0f, 1.0f, -1.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {-42.0f/SHRT_MAX, 42.0f/SHRT_MAX, 1.0f/SHRT_MAX, 1.0f/SHRT_MAX}},
+ };
+ const UINT exp_vertex_size33 = sizeof(*exp_vertices33);
+ /* Test 34. Convert FLOAT16_2 to FLOAT4. */
+ const struct vertex_ptc_float16_2 vertices34[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 2.0f, 3.0f, 0.f}, {0x3800, 0x399a}}, /* {0.5f, 0.7f} */
+ {{ 0.0f, 0.0f, 0.f}, {0xb266, 0xb4cd}}, /* {-0.2f, -0.3f} */
+
+ {{ 3.0f, 3.0f, 0.f}, {0x3266, 0x34cd}}, /* {0.2f, 0.3f} */
+ {{ 3.0f, 0.0f, 0.f}, {0x3c00, 0x3c00}}, /* {1.0f, 1.0f} */
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266}}, /* {0.1f, 0.2f} */
+ };
+ const UINT num_vertices34 = ARRAY_SIZE(vertices34);
+ const UINT num_faces34 = ARRAY_SIZE(vertices34) / VERTS_PER_FACE;
+ const UINT vertex_size34 = sizeof(*vertices34);
+ const struct vertex_ptc_float4 exp_vertices34[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {0.5f, 0.700195f, 0.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {-0.199951f, -0.300049f, 0.0f, 1.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.199951f, 0.300049f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {1.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.099976f, 0.199951f, 0.0f, 1.0f}},
+ };
+ const UINT exp_vertex_size34 = sizeof(*exp_vertices34);
+ /* Test 35. Convert FLOAT16_4 to FLOAT4. */
+ const struct vertex_ptc_float16_4 vertices35[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0x0000, 0x0000, 0x0000, 0x0000}},
+ {{ 2.0f, 3.0f, 0.f}, {0x3c00, 0x3c00, 0x3c00, 0x3c00}},
+ {{ 0.0f, 0.0f, 0.f}, {0x3c00, 0x0000, 0x3c00, 0x0000}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0x0000, 0x3c00, 0x0000, 0x3c00}},
+ {{ 3.0f, 0.0f, 0.f}, {0x3800, 0x399a, 0xb266, 0xb4cd}},
+ {{ 1.0f, 0.0f, 0.f}, {0x2e66, 0x3266, 0x2e66, 0x3266}},
+ };
+ const UINT num_vertices35 = ARRAY_SIZE(vertices35);
+ const UINT num_faces35 = ARRAY_SIZE(vertices35) / VERTS_PER_FACE;
+ const UINT vertex_size35 = sizeof(*vertices35);
+ const struct vertex_ptc_float4 exp_vertices35[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, {0.0f, 0.0f, 0.0f, 0.0f}},
+ {{ 2.0f, 3.0f, 0.f}, {1.0f, 1.0f, 1.0f, 1.0f}},
+ {{ 0.0f, 0.0f, 0.f}, {1.0f, 0.0f, 1.0f, 0.0f}},
+
+ {{ 3.0f, 3.0f, 0.f}, {0.0f, 1.0f, 0.0f, 1.0f}},
+ {{ 3.0f, 0.0f, 0.f}, {0.5f, 0.700195f, -0.199951f, -0.300049f}},
+ {{ 1.0f, 0.0f, 0.f}, {0.099976f, 0.199951f, 0.099976f, 0.199951f}},
+ };
+ const UINT exp_vertex_size35 = sizeof(*exp_vertices35);
+ /* Test 36. Check that vertex buffer sharing is ok. */
+ const struct vertex_pn vertices36[] =
+ {
+ {{ 0.0f, 3.0f, 0.f}, up},
+ {{ 2.0f, 3.0f, 0.f}, up},
+ {{ 0.0f, 0.0f, 0.f}, up},
+ };
+ const UINT num_vertices36 = ARRAY_SIZE(vertices36);
+ const UINT num_faces36 = ARRAY_SIZE(vertices36) / VERTS_PER_FACE;
+ const UINT vertex_size36 = sizeof(*vertices36);
+ const DWORD clone_options36 = options | D3DXMESH_VB_SHARE;
+ /* Common mesh data */
+ ID3DXMesh *mesh = NULL;
+ ID3DXMesh *mesh_clone = NULL;
+ struct
+ {
+ const BYTE *vertices;
+ const DWORD *indices;
+ const DWORD *attributes;
+ const UINT num_vertices;
+ const UINT num_faces;
+ const UINT vertex_size;
+ const DWORD create_options;
+ const DWORD clone_options;
+ D3DVERTEXELEMENT9 *declaration;
+ D3DVERTEXELEMENT9 *new_declaration;
+ const BYTE *exp_vertices;
+ const UINT exp_vertex_size;
+ }
+ tc[] =
+ {
+ {
+ (BYTE*)vertices0,
+ NULL,
+ NULL,
+ num_vertices0,
+ num_faces0,
+ vertex_size0,
+ options,
+ options,
+ declaration_pn,
+ declaration_pn,
+ (BYTE*)vertices0,
+ vertex_size0
+ },
+ {
+ (BYTE*)vertices0,
+ NULL,
+ NULL,
+ num_vertices0,
+ num_faces0,
+ vertex_size0,
+ options_16bit,
+ options_16bit,
+ declaration_pn,
+ declaration_pn,
+ (BYTE*)vertices0,
+ vertex_size0
+ },
+ {
+ (BYTE*)vertices0,
+ NULL,
+ NULL,
+ num_vertices0,
+ num_faces0,
+ vertex_size0,
+ options,
+ options,
+ declaration_pn,
+ declaration_pntc,
+ (BYTE*)exp_vertices2,
+ exp_vertex_size2
+ },
+ {
+ (BYTE*)vertices0,
+ NULL,
+ NULL,
+ num_vertices0,
+ num_faces0,
+ vertex_size0,
+ options,
+ options,
+ declaration_pn,
+ declaration_ptcn,
+ (BYTE*)exp_vertices3,
+ exp_vertex_size3
+ },
+ {
+ (BYTE*)vertices4,
+ NULL,
+ NULL,
+ num_vertices4,
+ num_faces4,
+ vertex_size4,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float16_2,
+ (BYTE*)exp_vertices4,
+ exp_vertex_size4
+ },
+ {
+ (BYTE*)vertices5,
+ NULL,
+ NULL,
+ num_vertices5,
+ num_faces5,
+ vertex_size5,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float16_4,
+ (BYTE*)exp_vertices5,
+ exp_vertex_size5
+ },
+ {
+ (BYTE*)vertices6,
+ NULL,
+ NULL,
+ num_vertices6,
+ num_faces6,
+ vertex_size6,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float1,
+ (BYTE*)exp_vertices6,
+ exp_vertex_size6
+ },
+ {
+ (BYTE*)vertices7,
+ NULL,
+ NULL,
+ num_vertices7,
+ num_faces7,
+ vertex_size7,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float3,
+ (BYTE*)exp_vertices7,
+ exp_vertex_size7
+ },
+ {
+ (BYTE*)vertices8,
+ NULL,
+ NULL,
+ num_vertices8,
+ num_faces8,
+ vertex_size8,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices8,
+ exp_vertex_size8
+ },
+ {
+ (BYTE*)vertices9,
+ NULL,
+ NULL,
+ num_vertices9,
+ num_faces9,
+ vertex_size9,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_d3dcolor,
+ (BYTE*)exp_vertices9,
+ exp_vertex_size9
+ },
+ {
+ (BYTE*)vertices10,
+ NULL,
+ NULL,
+ num_vertices10,
+ num_faces10,
+ vertex_size10,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_ubyte4,
+ (BYTE*)exp_vertices10,
+ exp_vertex_size10
+ },
+ {
+ (BYTE*)vertices11,
+ NULL,
+ NULL,
+ num_vertices11,
+ num_faces11,
+ vertex_size11,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_short2,
+ (BYTE*)exp_vertices11,
+ exp_vertex_size11
+ },
+ {
+ (BYTE*)vertices12,
+ NULL,
+ NULL,
+ num_vertices12,
+ num_faces12,
+ vertex_size12,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_short4,
+ (BYTE*)exp_vertices12,
+ exp_vertex_size12
+ },
+ {
+ (BYTE*)vertices13,
+ NULL,
+ NULL,
+ num_vertices13,
+ num_faces13,
+ vertex_size13,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_ubyte4n,
+ (BYTE*)exp_vertices13,
+ exp_vertex_size13
+ },
+ {
+ (BYTE*)vertices14,
+ NULL,
+ NULL,
+ num_vertices14,
+ num_faces14,
+ vertex_size14,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_short2n,
+ (BYTE*)exp_vertices14,
+ exp_vertex_size14
+ },
+ {
+ (BYTE*)vertices15,
+ NULL,
+ NULL,
+ num_vertices15,
+ num_faces15,
+ vertex_size15,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_short4n,
+ (BYTE*)exp_vertices15,
+ exp_vertex_size15
+ },
+ {
+ (BYTE*)vertices16,
+ NULL,
+ NULL,
+ num_vertices16,
+ num_faces16,
+ vertex_size16,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_ushort2n,
+ (BYTE*)exp_vertices16,
+ exp_vertex_size16
+ },
+ {
+ (BYTE*)vertices17,
+ NULL,
+ NULL,
+ num_vertices17,
+ num_faces17,
+ vertex_size17,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_ushort4n,
+ (BYTE*)exp_vertices17,
+ exp_vertex_size17
+ },
+ {
+ (BYTE*)vertices18,
+ NULL,
+ NULL,
+ num_vertices18,
+ num_faces18,
+ vertex_size18,
+ options,
+ options,
+ declaration_ptc,
+ declaration_ptc_float16_2_partialu,
+ (BYTE*)exp_vertices18,
+ exp_vertex_size18
+ },
+ {
+ (BYTE*)vertices19,
+ NULL,
+ NULL,
+ num_vertices19,
+ num_faces19,
+ vertex_size19,
+ options,
+ options,
+ declaration_pntc,
+ declaration_pntc1,
+ (BYTE*)exp_vertices19,
+ exp_vertex_size19
+ },
+ {
+ (BYTE*)vertices20,
+ NULL,
+ NULL,
+ num_vertices20,
+ num_faces20,
+ vertex_size20,
+ options,
+ options,
+ declaration_pntc1,
+ declaration_pntc,
+ (BYTE*)exp_vertices20,
+ exp_vertex_size20
+ },
+ {
+ (BYTE*)vertices21,
+ NULL,
+ NULL,
+ num_vertices21,
+ num_faces21,
+ vertex_size21,
+ options,
+ options,
+ declaration_ptc_float1,
+ declaration_ptc,
+ (BYTE*)exp_vertices21,
+ exp_vertex_size21
+ },
+ {
+ (BYTE*)vertices22,
+ NULL,
+ NULL,
+ num_vertices22,
+ num_faces22,
+ vertex_size22,
+ options,
+ options,
+ declaration_ptc_float1,
+ declaration_ptc_float3,
+ (BYTE*)exp_vertices22,
+ exp_vertex_size22
+ },
+ {
+ (BYTE*)vertices23,
+ NULL,
+ NULL,
+ num_vertices23,
+ num_faces23,
+ vertex_size23,
+ options,
+ options,
+ declaration_ptc_float1,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices23,
+ exp_vertex_size23
+ },
+ {
+ (BYTE*)vertices24,
+ NULL,
+ NULL,
+ num_vertices24,
+ num_faces24,
+ vertex_size24,
+ options,
+ options,
+ declaration_ptc_float1,
+ declaration_ptc_d3dcolor,
+ (BYTE*)exp_vertices24,
+ exp_vertex_size24
+ },
+ {
+ (BYTE*)vertices25,
+ NULL,
+ NULL,
+ num_vertices25,
+ num_faces25,
+ vertex_size25,
+ options,
+ options,
+ declaration_ptc_float1,
+ declaration_ptc_ubyte4,
+ (BYTE*)exp_vertices25,
+ exp_vertex_size25
+ },
+ {
+ (BYTE*)vertices26,
+ NULL,
+ NULL,
+ num_vertices26,
+ num_faces26,
+ vertex_size26,
+ options,
+ options,
+ declaration_ptc_float4,
+ declaration_ptc_d3dcolor,
+ (BYTE*)exp_vertices26,
+ exp_vertex_size26
+ },
+ {
+ (BYTE*)vertices27,
+ NULL,
+ NULL,
+ num_vertices27,
+ num_faces27,
+ vertex_size27,
+ options,
+ options,
+ declaration_ptc_d3dcolor,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices27,
+ exp_vertex_size27
+ },
+ {
+ (BYTE*)vertices28,
+ NULL,
+ NULL,
+ num_vertices28,
+ num_faces28,
+ vertex_size28,
+ options,
+ options,
+ declaration_ptc_ubyte4,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices28,
+ exp_vertex_size28
+ },
+ {
+ (BYTE*)vertices29,
+ NULL,
+ NULL,
+ num_vertices29,
+ num_faces29,
+ vertex_size29,
+ options,
+ options,
+ declaration_ptc_short2,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices29,
+ exp_vertex_size29
+ },
+ {
+ (BYTE*)vertices30,
+ NULL,
+ NULL,
+ num_vertices30,
+ num_faces30,
+ vertex_size30,
+ options,
+ options,
+ declaration_ptc_short4,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices30,
+ exp_vertex_size30
+ },
+ {
+ (BYTE*)vertices31,
+ NULL,
+ NULL,
+ num_vertices31,
+ num_faces31,
+ vertex_size31,
+ options,
+ options,
+ declaration_ptc_ubyte4n,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices31,
+ exp_vertex_size31
+ },
+ {
+ (BYTE*)vertices32,
+ NULL,
+ NULL,
+ num_vertices32,
+ num_faces32,
+ vertex_size32,
+ options,
+ options,
+ declaration_ptc_short2n,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices32,
+ exp_vertex_size32
+ },
+ {
+ (BYTE*)vertices33,
+ NULL,
+ NULL,
+ num_vertices33,
+ num_faces33,
+ vertex_size33,
+ options,
+ options,
+ declaration_ptc_short4n,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices33,
+ exp_vertex_size33
+ },
+ {
+ (BYTE*)vertices34,
+ NULL,
+ NULL,
+ num_vertices34,
+ num_faces34,
+ vertex_size34,
+ options,
+ options,
+ declaration_ptc_float16_2,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices34,
+ exp_vertex_size34
+ },
+ {
+ (BYTE*)vertices35,
+ NULL,
+ NULL,
+ num_vertices35,
+ num_faces35,
+ vertex_size35,
+ options,
+ options,
+ declaration_ptc_float16_4,
+ declaration_ptc_float4,
+ (BYTE*)exp_vertices35,
+ exp_vertex_size35
+ },
+ {
+ (BYTE*)vertices36,
+ NULL,
+ NULL,
+ num_vertices36,
+ num_faces36,
+ vertex_size36,
+ options,
+ clone_options36,
+ declaration_pn,
+ declaration_pn,
+ (BYTE*)vertices36,
+ vertex_size36
+ },
+ };
+#ifdef __REACTOS__
+#undef up
+#undef zero_vec2
+#endif
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ UINT j;
+ D3DVERTEXELEMENT9 new_declaration[MAX_FVF_DECL_SIZE];
+ UINT exp_new_decl_length, new_decl_length;
+ UINT exp_new_decl_size, new_decl_size;
+
+ hr = init_test_mesh(tc[i].num_faces, tc[i].num_vertices,
+ tc[i].create_options,
+ tc[i].declaration,
+ test_context->device, &mesh,
+ tc[i].vertices, tc[i].vertex_size,
+ tc[i].indices, tc[i].attributes);
+ if (FAILED(hr))
+ {
+ skip("Couldn't initialize test mesh %d. Got %x expected D3D_OK\n", i, hr);
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->CloneMesh(mesh, tc[i].clone_options, tc[i].new_declaration,
+ test_context->device, &mesh_clone);
+ ok(hr == D3D_OK, "CloneMesh test case %d failed. Got %x\n, expected D3D_OK\n", i, hr);
+
+ hr = mesh_clone->lpVtbl->GetDeclaration(mesh_clone, new_declaration);
+ ok(hr == D3D_OK, "GetDeclaration test case %d failed. Got %x\n, expected D3D_OK\n", i, hr);
+ /* Check declaration elements */
+ for (j = 0; tc[i].new_declaration[j].Stream != 0xFF; j++)
+ {
+ ok(memcmp(&tc[i].new_declaration[j], &new_declaration[j], sizeof(*new_declaration)) == 0,
+ "Test case %d failed. Declaration element %d did not match.\n", i, j);
+ }
+
+ /* Check declaration length */
+ exp_new_decl_length = D3DXGetDeclLength(tc[i].new_declaration);
+ new_decl_length = D3DXGetDeclLength(new_declaration);
+ ok(new_decl_length == exp_new_decl_length,
+ "Test case %d failed. Got new declaration length %d, expected %d\n",
+ i, new_decl_length, exp_new_decl_length);
+
+ /* Check declaration size */
+ exp_new_decl_size = D3DXGetDeclVertexSize(tc[i].new_declaration, 0);
+ new_decl_size = D3DXGetDeclVertexSize(new_declaration, 0);
+ ok(new_decl_size == exp_new_decl_size,
+ "Test case %d failed. Got new declaration size %d, expected %d\n",
+ i, new_decl_size, exp_new_decl_size);
+
+ /* Check vertex data in cloned mesh */
+ hr = mesh_clone->lpVtbl->LockVertexBuffer(mesh_clone, 0, (void**)&vertices);
+ if (FAILED(hr))
+ {
+ skip("Couldn't lock cloned vertex buffer.\n");
+ goto cleanup;
+ }
+ for (j = 0; j < tc[i].num_vertices; j++)
+ {
+ UINT index = tc[i].exp_vertex_size * j;
+ check_vertex_components(__LINE__, i, j, &vertices[index], &tc[i].exp_vertices[index], tc[i].new_declaration);
+ }
+ hr = mesh_clone->lpVtbl->UnlockVertexBuffer(mesh_clone);
+ if (FAILED(hr))
+ {
+ skip("Couldn't unlock vertex buffer.\n");
+ goto cleanup;
+ }
+ vertices = NULL;
+ mesh->lpVtbl->Release(mesh);
+ mesh = NULL;
+ mesh_clone->lpVtbl->Release(mesh_clone);
+ mesh_clone = NULL;
+ }
+
+ /* The following test shows that it is not possible to share a vertex buffer
+ * with D3DXMESH_VB_SHARE and change the vertex declaration at the same
+ * time. It reuses the test data from test 2.
+ */
+ hr = init_test_mesh(tc[2].num_faces, tc[2].num_vertices,
+ tc[2].create_options,
+ tc[2].declaration,
+ test_context->device, &mesh,
+ tc[2].vertices, tc[2].vertex_size,
+ tc[2].indices, tc[2].attributes);
+ if (FAILED(hr))
+ {
+ skip("Couldn't initialize test mesh for D3DXMESH_VB_SHARE case."
+ " Got %x expected D3D_OK\n", hr);
+ goto cleanup;
+ }
+
+ hr = mesh->lpVtbl->CloneMesh(mesh, tc[2].create_options | D3DXMESH_VB_SHARE,
+ tc[2].new_declaration, test_context->device,
+ &mesh_clone);
+ ok(hr == D3DERR_INVALIDCALL, "CloneMesh D3DXMESH_VB_SHARE with new"
+ " declaration. Got %x, expected D3DERR_INVALIDCALL\n",
+ hr);
+ mesh->lpVtbl->Release(mesh);
+ mesh = NULL;
+ mesh_clone = NULL;
+
+cleanup:
+ if (vertices) mesh->lpVtbl->UnlockVertexBuffer(mesh);
+ if (mesh) mesh->lpVtbl->Release(mesh);
+ if (mesh_clone) mesh_clone->lpVtbl->Release(mesh_clone);
+ free_test_context(test_context);
+}
+
+static void test_valid_mesh(void)
+{
+ HRESULT hr;
+ struct test_context *test_context = NULL;
+ UINT i;
+ const DWORD options = D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM;
+ const D3DVERTEXELEMENT9 declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END()
+ };
+ const unsigned int VERTS_PER_FACE = 3;
+ /* mesh0 (one face)
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ const D3DXVECTOR3 vertices0[] =
+ {
+ { 0.0f, 3.0f, 0.f},
+ { 2.0f, 3.0f, 0.f},
+ { 0.0f, 0.0f, 0.f},
+ };
+ const DWORD indices0[] = {0, 1, 2};
+ const unsigned int num_vertices0 = ARRAY_SIZE(vertices0);
+ const unsigned int num_faces0 = ARRAY_SIZE(indices0) / VERTS_PER_FACE;
+ const DWORD adjacency0[] = {-1, -1, -1};
+ const HRESULT exp_hr0 = D3D_OK;
+ /* mesh1 (Simple bow-tie)
+ *
+ * 0--1 1--3
+ * | / \ |
+ * |/ \|
+ * 2 4
+ */
+ const D3DXVECTOR3 vertices1[] =
+ {
+ { 0.0f, 3.0f, 0.f},
+ { 2.0f, 3.0f, 0.f},
+ { 0.0f, 0.0f, 0.f},
+
+ { 4.0f, 3.0f, 0.f},
+ { 4.0f, 0.0f, 0.f},
+ };
+ const DWORD indices1[] = {0, 1, 2, 1, 3, 4};
+ const unsigned int num_vertices1 = ARRAY_SIZE(vertices1);
+ const unsigned int num_faces1 = ARRAY_SIZE(indices1) / VERTS_PER_FACE;
+ const DWORD adjacency1[] = {-1, -1, -1, -1, -1, -1};
+ const HRESULT exp_hr1 = D3DXERR_INVALIDMESH;
+ /* Common mesh data */
+ ID3DXMesh *mesh = NULL;
+ UINT vertex_size = sizeof(D3DXVECTOR3);
+ ID3DXBuffer *errors_and_warnings = NULL;
+ struct
+ {
+ const D3DXVECTOR3 *vertices;
+ const DWORD *indices;
+ const UINT num_vertices;
+ const UINT num_faces;
+ const DWORD *adjacency;
+ const HRESULT exp_hr;
+ }
+ tc[] =
+ {
+ {
+ vertices0,
+ indices0,
+ num_vertices0,
+ num_faces0,
+ adjacency0,
+ exp_hr0,
+ },
+ {
+ vertices1,
+ indices1,
+ num_vertices1,
+ num_faces1,
+ adjacency1,
+ exp_hr1,
+ },
+ };
+
+ test_context = new_test_context();
+ if (!test_context)
+ {
+ skip("Couldn't create test context\n");
+ goto cleanup;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ hr = init_test_mesh(tc[i].num_faces, tc[i].num_vertices,
+ options, declaration,
+ test_context->device, &mesh,
+ tc[i].vertices, vertex_size,
+ tc[i].indices, NULL);
+ if (FAILED(hr))
+ {
+ skip("Couldn't initialize test mesh %d. Got %x expected D3D_OK\n", i, hr);
+ goto cleanup;
+ }
+
+ hr = D3DXValidMesh(mesh, tc[i].adjacency, &errors_and_warnings);
+ todo_wine ok(hr == tc[i].exp_hr, "D3DXValidMesh test case %d failed. "
+ "Got %x\n, expected %x\n", i, hr, tc[i].exp_hr);
+
+ /* Note errors_and_warnings is deliberately not checked because that
+ * would require copying wast amounts of the text output. */
+ if (errors_and_warnings)
+ {
+ ID3DXBuffer_Release(errors_and_warnings);
+ errors_and_warnings = NULL;
+ }
+ mesh->lpVtbl->Release(mesh);
+ mesh = NULL;
+ }
+
+cleanup:
+ if (mesh) mesh->lpVtbl->Release(mesh);
+ free_test_context(test_context);
+}
+
+static void test_optimize_faces(void)
+{
+ HRESULT hr;
+ UINT i;
+ DWORD smallest_face_remap;
+ /* mesh0
+ *
+ * 0--1
+ * | /
+ * |/
+ * 2
+ */
+ const DWORD indices0[] = {0, 1, 2};
+ const UINT num_faces0 = 1;
+ const UINT num_vertices0 = 3;
+ const DWORD exp_face_remap0[] = {0};
+ /* mesh1
+ *
+ * 0--1 3
+ * | / /|
+ * |/ / |
+ * 2 5--4
+ */
+ const DWORD indices1[] = {0, 1, 2, 3, 4, 5};
+ const UINT num_faces1 = 2;
+ const UINT num_vertices1 = 6;
+ const DWORD exp_face_remap1[] = {1, 0};
+ /* mesh2
+ *
+ * 0--1
+ * | /|
+ * |/ |
+ * 2--3
+ */
+ const DWORD indices2[] = {0, 1, 2, 1, 3, 2};
+ const UINT num_faces2 = 2;
+ const UINT num_vertices2 = 4;
+ const DWORD exp_face_remap2[] = {1, 0};
+ /* mesh3
+ *
+ * 0--1
+ * | /|
+ * |/ |
+ * 2--3
+ * | /|
+ * |/ |
+ * 4--5
+ */
+ const DWORD indices3[] = {0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 4, 5};
+ const UINT num_faces3 = 4;
+ const UINT num_vertices3 = 6;
+ const DWORD exp_face_remap3[] = {3, 2, 1, 0};
+ /* mesh4
+ *
+ * 0--1
+ * | /|
+ * |/ |
+ * 2--3
+ * | /|
+ * |/ |
+ * 4--5
+ */
+ const WORD indices4[] = {0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 4, 5};
+ const UINT num_faces4 = 4;
+ const UINT num_vertices4 = 6;
+ const DWORD exp_face_remap4[] = {3, 2, 1, 0};
+ /* Test cases are stored in the tc array */
+ struct
+ {
+ const VOID *indices;
+ const UINT num_faces;
+ const UINT num_vertices;
+ const BOOL indices_are_32bit;
+ const DWORD *exp_face_remap;
+ }
+ tc[] =
+ {
+ {
+ indices0,
+ num_faces0,
+ num_vertices0,
+ TRUE,
+ exp_face_remap0
+ },
+ {
+ indices1,
+ num_faces1,
+ num_vertices1,
+ TRUE,
+ exp_face_remap1
+ },
+ {
+ indices2,
+ num_faces2,
+ num_vertices2,
+ TRUE,
+ exp_face_remap2
+ },
+ {
+ indices3,
+ num_faces3,
+ num_vertices3,
+ TRUE,
+ exp_face_remap3
+ },
+ {
+ indices4,
+ num_faces4,
+ num_vertices4,
+ FALSE,
+ exp_face_remap4
+ },
+ };
+
+ /* Go through all test cases */
+ for (i = 0; i < ARRAY_SIZE(tc); i++)
+ {
+ DWORD j;
+ DWORD *face_remap;
+ face_remap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ tc[i].num_faces*sizeof(*face_remap));
+
+ hr = D3DXOptimizeFaces(tc[i].indices, tc[i].num_faces,
+ tc[i].num_vertices, tc[i].indices_are_32bit,
+ face_remap);
+ ok(hr == D3D_OK, "D3DXOptimizeFaces test case %d failed. "
+ "Got %x\n, expected D3D_OK\n", i, hr);
+
+ /* Compare face remap with expected face remap */
+ for (j = 0; j < tc[i].num_faces; j++)
+ {
+ ok(tc[i].exp_face_remap[j] == face_remap[j],
+ "Test case %d: Got face %d at %d, expected %d\n", i,
+ face_remap[j], j, tc[i].exp_face_remap[j]);
+ }
+
+ HeapFree(GetProcessHeap(), 0, face_remap);
+ }
+
+ /* face_remap must not be NULL */
+ hr = D3DXOptimizeFaces(tc[0].indices, tc[0].num_faces,
+ tc[0].num_vertices, tc[0].indices_are_32bit,
+ NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXOptimizeFaces passed NULL face_remap "
+ "pointer. Got %x\n, expected D3DERR_INVALIDCALL\n", hr);
+
+ /* Number of faces must be smaller than 2^15 */
+ hr = D3DXOptimizeFaces(tc[0].indices, 2 << 15,
+ tc[0].num_vertices, FALSE,
+ &smallest_face_remap);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXOptimizeFaces should not accept 2^15 "
+ "faces when using 16-bit indices. Got %x\n, expected D3DERR_INVALIDCALL\n", hr);
+}
+
+static HRESULT clear_normals(ID3DXMesh *mesh)
+{
+ HRESULT hr;
+ BYTE *vertices;
+ size_t normal_size;
+ DWORD i, num_vertices, vertex_stride;
+ const D3DXVECTOR4 normal = {NAN, NAN, NAN, NAN};
+ D3DVERTEXELEMENT9 *normal_declaration = NULL;
+ D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE] = {D3DDECL_END()};
+
+ if (FAILED(hr = mesh->lpVtbl->GetDeclaration(mesh, declaration)))
+ return hr;
+
+ for (i = 0; declaration[i].Stream != 0xff; i++)
+ {
+ if (declaration[i].Usage == D3DDECLUSAGE_NORMAL && !declaration[i].UsageIndex)
+ {
+ normal_declaration = &declaration[i];
+ break;
+ }
+ }
+
+ if (!normal_declaration)
+ return D3DERR_INVALIDCALL;
+
+ if (normal_declaration->Type == D3DDECLTYPE_FLOAT3)
+ {
+ normal_size = sizeof(D3DXVECTOR3);
+ }
+ else if (normal_declaration->Type == D3DDECLTYPE_FLOAT4)
+ {
+ normal_size = sizeof(D3DXVECTOR4);
+ }
+ else
+ {
+ trace("Cannot clear normals\n");
+ return E_NOTIMPL;
+ }
+
+ num_vertices = mesh->lpVtbl->GetNumVertices(mesh);
+ vertex_stride = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+
+ if (FAILED(hr = mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void **)&vertices)))
+ return hr;
+
+ vertices += normal_declaration->Offset;
+
+ for (i = 0; i < num_vertices; i++, vertices += vertex_stride)
+ memcpy(vertices, &normal, normal_size);
+
+ return mesh->lpVtbl->UnlockVertexBuffer(mesh);
+}
+
+static void compare_normals(unsigned int line, const char *test_name,
+ ID3DXMesh *mesh, const D3DXVECTOR3 *normals, unsigned int num_normals)
+{
+ unsigned int i;
+ BYTE *vertices;
+ DWORD num_vertices, vertex_stride;
+ D3DVERTEXELEMENT9 *normal_declaration = NULL;
+ D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE] = {D3DDECL_END()};
+
+ if (FAILED(mesh->lpVtbl->GetDeclaration(mesh, declaration)))
+ {
+ ok_(__FILE__, line)(0, "%s: Failed to get declaration\n", test_name);
+ return;
+ }
+
+ for (i = 0; declaration[i].Stream != 0xff; i++)
+ {
+ if (declaration[i].Usage == D3DDECLUSAGE_NORMAL && !declaration[i].UsageIndex)
+ {
+ normal_declaration = &declaration[i];
+ break;
+ }
+ }
+
+ if (!normal_declaration)
+ {
+ ok_(__FILE__, line)(0, "%s: Mesh has no normals\n", test_name);
+ return;
+ }
+
+ if (normal_declaration->Type != D3DDECLTYPE_FLOAT3 && normal_declaration->Type != D3DDECLTYPE_FLOAT4)
+ {
+ ok_(__FILE__, line)(0, "%s: Mesh has invalid normals type\n", test_name);
+ return;
+ }
+
+ num_vertices = mesh->lpVtbl->GetNumVertices(mesh);
+ vertex_stride = mesh->lpVtbl->GetNumBytesPerVertex(mesh);
+
+ ok_(__FILE__, line)(num_vertices == num_normals, "%s: Expected %u vertices, got %u\n", test_name,
+ num_normals, num_vertices);
+
+ if (FAILED(mesh->lpVtbl->LockVertexBuffer(mesh, 0, (void **)&vertices)))
+ {
+ ok_(__FILE__, line)(0, "%s: Failed to compare normals\n", test_name);
+ return;
+ }
+
+ vertices += normal_declaration->Offset;
+
+ for (i = 0; i < min(num_vertices, num_normals); i++, vertices += vertex_stride)
+ {
+ if (normal_declaration->Type == D3DDECLTYPE_FLOAT3)
+ {
+ const D3DXVECTOR3 *n = (D3DXVECTOR3 *)vertices;
+ ok_(__FILE__, line)(compare_vec3(*n, normals[i]),
+ "%s: normal %2u, expected (%f, %f, %f), got (%f, %f, %f)\n",
+ test_name, i, normals[i].x, normals[i].y, normals[i].z, n->x, n->y, n->z);
+ }
+ else
+ {
+ const D3DXVECTOR4 *n = (D3DXVECTOR4 *)vertices;
+ const D3DXVECTOR4 normal = {normals[i].x, normals[i].y, normals[i].z, 1.0f};
+ ok_(__FILE__, line)(compare_vec4(*n, normal),
+ "%s: normal %2u, expected (%f, %f, %f, %f), got (%f, %f, %f, %f)\n",
+ test_name, i, normals[i].x, normals[i].y, normals[i].z, 1.0f,
+ n->x, n->y, n->z, n->w);
+ }
+ }
+
+ mesh->lpVtbl->UnlockVertexBuffer(mesh);
+}
+
+static HRESULT compute_normals_D3DXComputeNormals(ID3DXMesh *mesh, const DWORD *adjacency)
+{
+ return D3DXComputeNormals((ID3DXBaseMesh *)mesh, adjacency);
+}
+
+static HRESULT compute_normals_D3DXComputeTangentFrameEx(ID3DXMesh *mesh, const DWORD *adjacency)
+{
+ return D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS,
+ adjacency, -1.01f, -0.01f, -1.01f, NULL, NULL);
+}
+
+static void test_compute_normals(void)
+{
+ HRESULT hr;
+ ULONG refcount;
+ ID3DXMesh *mesh, *cloned_mesh;
+ ID3DXBuffer *adjacency;
+ IDirect3DDevice9 *device;
+ struct test_context *test_context;
+ unsigned int i;
+
+ static const struct compute_normals_func
+ {
+ const char *name;
+ HRESULT (*apply)(ID3DXMesh *mesh, const DWORD *adjacency);
+ }
+ compute_normals_funcs[] =
+ {
+ {"D3DXComputeNormals", compute_normals_D3DXComputeNormals },
+ {"D3DXComputeTangentFrameEx", compute_normals_D3DXComputeTangentFrameEx}
+ };
+
+ static const D3DXVECTOR3 box_normals[24] =
+ {
+ {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f},
+ { 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f},
+ { 1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f},
+ { 0.0f,-1.0f, 0.0f}, { 0.0f,-1.0f, 0.0f}, { 0.0f,-1.0f, 0.0f}, { 0.0f,-1.0f, 0.0f},
+ { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f},
+ { 0.0f, 0.0f,-1.0f}, { 0.0f, 0.0f,-1.0f}, { 0.0f, 0.0f,-1.0f}, { 0.0f, 0.0f,-1.0f}
+ };
+ const float box_normal_component = 1.0f / sqrtf(3.0f);
+ const D3DXVECTOR3 box_normals_adjacency[24] =
+ {
+ {-box_normal_component, -box_normal_component, -box_normal_component},
+ {-box_normal_component, -box_normal_component, box_normal_component},
+ {-box_normal_component, box_normal_component, box_normal_component},
+ {-box_normal_component, box_normal_component, -box_normal_component},
+ {-box_normal_component, box_normal_component, -box_normal_component},
+ {-box_normal_component, box_normal_component, box_normal_component},
+ { box_normal_component, box_normal_component, box_normal_component},
+ { box_normal_component, box_normal_component, -box_normal_component},
+ { box_normal_component, box_normal_component, -box_normal_component},
+ { box_normal_component, box_normal_component, box_normal_component},
+ { box_normal_component, -box_normal_component, box_normal_component},
+ { box_normal_component, -box_normal_component, -box_normal_component},
+ {-box_normal_component, -box_normal_component, box_normal_component},
+ {-box_normal_component, -box_normal_component, -box_normal_component},
+ { box_normal_component, -box_normal_component, -box_normal_component},
+ { box_normal_component, -box_normal_component, box_normal_component},
+ {-box_normal_component, -box_normal_component, box_normal_component},
+ { box_normal_component, -box_normal_component, box_normal_component},
+ { box_normal_component, box_normal_component, box_normal_component},
+ {-box_normal_component, box_normal_component, box_normal_component},
+ {-box_normal_component, -box_normal_component, -box_normal_component},
+ {-box_normal_component, box_normal_component, -box_normal_component},
+ { box_normal_component, box_normal_component, -box_normal_component},
+ { box_normal_component, -box_normal_component, -box_normal_component}
+ };
+ static const D3DXVECTOR3 box_normals_adjacency_area[24] =
+ {
+ {-0.666667f, -0.333333f, -0.666667f}, {-0.333333f, -0.666667f, 0.666667f},
+ {-0.816496f, 0.408248f, 0.408248f}, {-0.408248f, 0.816496f, -0.408248f},
+ {-0.408248f, 0.816496f, -0.408248f}, {-0.816496f, 0.408248f, 0.408248f},
+ { 0.333333f, 0.666667f, 0.666667f}, { 0.666667f, 0.333333f, -0.666667f},
+ { 0.666667f, 0.333333f, -0.666667f}, { 0.333333f, 0.666667f, 0.666667f},
+ { 0.816496f, -0.408248f, 0.408248f}, { 0.408248f, -0.816496f, -0.408248f},
+ {-0.333333f, -0.666667f, 0.666667f}, {-0.666667f, -0.333333f, -0.666667f},
+ { 0.408248f, -0.816496f, -0.408248f}, { 0.816496f, -0.408248f, 0.408248f},
+ {-0.333333f, -0.666667f, 0.666667f}, { 0.816497f, -0.408248f, 0.408248f},
+ { 0.333333f, 0.666667f, 0.666667f}, {-0.816497f, 0.408248f, 0.408248f},
+ {-0.666667f, -0.333333f, -0.666667f}, {-0.408248f, 0.816497f, -0.408248f},
+ { 0.666667f, 0.333333f, -0.666667f}, { 0.408248f, -0.816496f, -0.408248f}
+ };
+ static const D3DXVECTOR3 box_normals_position1f[24] = {{0}};
+ static const D3DXVECTOR3 box_normals_position2f[24] =
+ {
+ {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f},
+ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f},
+ {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f}
+ };
+
+ static const D3DXVECTOR3 sphere_normals[22] =
+ {
+ { 0.000000f, -0.000000f, 1.000000f}, { 0.000000f, 0.582244f, 0.813014f},
+ { 0.582244f, -0.000000f, 0.813014f}, {-0.000000f, -0.582244f, 0.813014f},
+ {-0.582244f, 0.000000f, 0.813014f}, {-0.000000f, 0.890608f, 0.454772f},
+ { 0.890608f, 0.000000f, 0.454772f}, { 0.000000f, -0.890608f, 0.454772f},
+ {-0.890608f, -0.000000f, 0.454772f}, { 0.000000f, 1.000000f, -0.000000f},
+ { 1.000000f, -0.000000f, -0.000000f}, {-0.000000f, -1.000000f, -0.000000f},
+ {-1.000000f, 0.000000f, -0.000000f}, { 0.000000f, 0.890608f, -0.454773f},
+ { 0.890608f, -0.000000f, -0.454772f}, {-0.000000f, -0.890608f, -0.454773f},
+ {-0.890608f, 0.000000f, -0.454773f}, { 0.000000f, 0.582244f, -0.813015f},
+ { 0.582244f, -0.000000f, -0.813015f}, { 0.000000f, -0.582244f, -0.813015f},
+ {-0.582243f, 0.000000f, -0.813015f}, { 0.000000f, 0.000000f, -1.000000f}
+ };
+ static const D3DXVECTOR3 sphere_normals_area[22] =
+ {
+ { 0.000000f, -0.000000f, 1.000000f}, {-0.215311f, 0.554931f, 0.803550f},
+ { 0.554931f, 0.215311f, 0.803550f}, { 0.215311f, -0.554931f, 0.803550f},
+ {-0.554931f, -0.215311f, 0.803550f}, {-0.126638f, 0.872121f, 0.472618f},
+ { 0.872121f, 0.126638f, 0.472618f}, { 0.126638f, -0.872121f, 0.472618f},
+ {-0.872121f, -0.126637f, 0.472618f}, { 0.000000f, 1.000000f, -0.000000f},
+ { 1.000000f, -0.000000f, -0.000000f}, {-0.000000f, -1.000000f, -0.000000f},
+ {-1.000000f, 0.000000f, -0.000000f}, { 0.126638f, 0.872121f, -0.472618f},
+ { 0.872121f, -0.126638f, -0.472618f}, {-0.126638f, -0.872121f, -0.472618f},
+ {-0.872121f, 0.126638f, -0.472618f}, { 0.215311f, 0.554931f, -0.803550f},
+ { 0.554931f, -0.215311f, -0.803550f}, {-0.215311f, -0.554931f, -0.803550f},
+ {-0.554931f, 0.215311f, -0.803550f}, { 0.000000f, 0.000000f, -1.000000f}
+ };
+ static const D3DXVECTOR3 sphere_normals_equal[22] =
+ {
+ { 0.000000f, -0.000000f, 1.000000f}, {-0.134974f, 0.522078f, 0.842150f},
+ { 0.522078f, 0.134974f, 0.842150f}, { 0.134974f, -0.522078f, 0.842150f},
+ {-0.522078f, -0.134974f, 0.842150f}, {-0.026367f, 0.857121f, 0.514440f},
+ { 0.857121f, 0.026367f, 0.514440f}, { 0.026367f, -0.857121f, 0.514440f},
+ {-0.857121f, -0.026367f, 0.514440f}, { 0.000000f, 1.000000f, -0.000000f},
+ { 1.000000f, -0.000000f, -0.000000f}, {-0.000000f, -1.000000f, -0.000000f},
+ {-1.000000f, 0.000000f, -0.000000f}, { 0.026367f, 0.857121f, -0.514440f},
+ { 0.857121f, -0.026367f, -0.514440f}, {-0.026367f, -0.857121f, -0.514440f},
+ {-0.857121f, 0.026367f, -0.514440f}, { 0.134975f, 0.522078f, -0.842150f},
+ { 0.522078f, -0.134975f, -0.842150f}, {-0.134974f, -0.522078f, -0.842150f},
+ {-0.522078f, 0.134974f, -0.842150f}, { 0.000000f, 0.000000f, -1.000000f}
+ };
+
+ static const D3DVERTEXELEMENT9 position3f_normal1f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ static const D3DVERTEXELEMENT9 position3f_normal2f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ static const D3DVERTEXELEMENT9 normal4f_position3f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ {0, sizeof(D3DXVECTOR4), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END()
+ };
+ static const D3DVERTEXELEMENT9 position1f_normal3f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, sizeof(float), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ static const D3DVERTEXELEMENT9 position2f_normal3f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, sizeof(D3DXVECTOR2), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+ static const D3DVERTEXELEMENT9 position4f_normal3f_declaration[] =
+ {
+ {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, sizeof(D3DXVECTOR4), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
+ D3DDECL_END()
+ };
+
+ for (i = 0; i < ARRAY_SIZE(compute_normals_funcs); i++)
+ {
+ hr = compute_normals_funcs[i].apply(NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%s returned %#x, expected D3DERR_INVALIDCALL\n", compute_normals_funcs[i].name, hr);
+ }
+
+ if (!(test_context = new_test_context()))
+ {
+ skip("Couldn't create test context\n");
+ return;
+ }
+ device = test_context->device;
+
+ hr = D3DXCreateBox(device, 1.0f, 1.0f, 1.0f, &mesh, &adjacency);
+ ok(SUCCEEDED(hr), "D3DXCreateBox failed %#x\n", hr);
+
+ /* Check wrong input */
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE, NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DDECLUSAGE_NORMAL, 0,
+ D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_BY_AREA | D3DXTANGENT_WEIGHT_EQUAL,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, 0, NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 1, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DX_DEFAULT, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_CALCULATE_NORMALS,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "D3DXComputeTangentFrameEx returned %#x, expected D3DERR_INVALIDCALL\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(compute_normals_funcs); i++)
+ {
+ const struct compute_normals_func *func = &compute_normals_funcs[i];
+
+ /* Mesh without normals */
+ hr = mesh->lpVtbl->CloneMeshFVF(mesh, 0, D3DFVF_XYZ, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMeshFVF failed %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%s returned %#x, expected D3DERR_INVALIDCALL\n", func->name, hr);
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh without positions */
+ hr = mesh->lpVtbl->CloneMeshFVF(mesh, 0, D3DFVF_NORMAL, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMeshFVF failed %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%s returned %#x, expected D3DERR_INVALIDCALL\n", func->name, hr);
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh with D3DDECLTYPE_FLOAT1 normals */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, position3f_normal1f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%s returned %#x, expected D3DERR_INVALIDCALL\n", func->name, hr);
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh with D3DDECLTYPE_FLOAT2 normals */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, position3f_normal2f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "%s returned %#x, expected D3DERR_INVALIDCALL\n", func->name, hr);
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh without adjacency data */
+ hr = clear_normals(mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(mesh, NULL);
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, mesh, box_normals, ARRAY_SIZE(box_normals));
+
+ /* Mesh with adjacency data */
+ hr = clear_normals(mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, mesh, box_normals_adjacency, ARRAY_SIZE(box_normals_adjacency));
+
+ /* Mesh with custom vertex format, D3DDECLTYPE_FLOAT4 normals and adjacency */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, normal4f_position3f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = clear_normals(cloned_mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, cloned_mesh, box_normals_adjacency, ARRAY_SIZE(box_normals_adjacency));
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh with D3DDECLTYPE_FLOAT1 positions and D3DDECLTYPE_FLOAT3 normals */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, position1f_normal3f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = clear_normals(cloned_mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, cloned_mesh, box_normals_position1f, ARRAY_SIZE(box_normals_position1f));
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh with D3DDECLTYPE_FLOAT2 positions and D3DDECLTYPE_FLOAT3 normals */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, position2f_normal3f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = clear_normals(cloned_mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, cloned_mesh, box_normals_position2f, ARRAY_SIZE(box_normals_position2f));
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+
+ /* Mesh with D3DDECLTYPE_FLOAT4 positions and D3DDECLTYPE_FLOAT3 normals */
+ hr = mesh->lpVtbl->CloneMesh(mesh, 0, position4f_normal3f_declaration, device, &cloned_mesh);
+ ok(SUCCEEDED(hr), "CloneMesh failed %#x\n", hr);
+
+ hr = clear_normals(cloned_mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(cloned_mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, cloned_mesh, box_normals_adjacency, ARRAY_SIZE(box_normals_adjacency));
+
+ refcount = cloned_mesh->lpVtbl->Release(cloned_mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+ }
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_BY_AREA,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, box_normals, ARRAY_SIZE(box_normals));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_BY_AREA,
+ ID3DXBuffer_GetBufferPointer(adjacency), -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, box_normals_adjacency_area, ARRAY_SIZE(box_normals_adjacency_area));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_EQUAL,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, box_normals, ARRAY_SIZE(box_normals));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_EQUAL,
+ ID3DXBuffer_GetBufferPointer(adjacency), -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, box_normals_adjacency_area, ARRAY_SIZE(box_normals_adjacency_area));
+
+ refcount = mesh->lpVtbl->Release(mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+ refcount = ID3DXBuffer_Release(adjacency);
+ ok(!refcount, "Buffer has %u references left\n", refcount);
+
+ hr = D3DXCreateSphere(device, 1.0f, 4, 6, &mesh, &adjacency);
+ ok(SUCCEEDED(hr), "D3DXCreateSphere failed %#x\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(compute_normals_funcs); i++)
+ {
+ const struct compute_normals_func *func = &compute_normals_funcs[i];
+
+ /* Sphere without adjacency data */
+ hr = clear_normals(mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(mesh, NULL);
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, mesh, sphere_normals, ARRAY_SIZE(sphere_normals));
+
+ /* Sphere with adjacency data */
+ hr = clear_normals(mesh);
+ ok(SUCCEEDED(hr), "Failed to clear normals, returned %#x\n", hr);
+
+ hr = func->apply(mesh, ID3DXBuffer_GetBufferPointer(adjacency));
+ ok(hr == D3D_OK, "%s returned %#x, expected D3D_OK\n", func->name, hr);
+
+ compare_normals(__LINE__, func->name, mesh, sphere_normals, ARRAY_SIZE(sphere_normals));
+ }
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_BY_AREA,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, sphere_normals_area, ARRAY_SIZE(sphere_normals_area));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_BY_AREA,
+ ID3DXBuffer_GetBufferPointer(adjacency), -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, sphere_normals_area, ARRAY_SIZE(sphere_normals_area));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_EQUAL,
+ NULL, -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, sphere_normals_equal, ARRAY_SIZE(sphere_normals_equal));
+
+ hr = D3DXComputeTangentFrameEx(mesh, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
+ D3DDECLUSAGE_NORMAL, 0, D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_CALCULATE_NORMALS | D3DXTANGENT_WEIGHT_EQUAL,
+ ID3DXBuffer_GetBufferPointer(adjacency), -1.01f, -0.01f, -1.01f, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXComputeTangentFrameEx returned %#x, expected D3D_OK\n", hr);
+
+ compare_normals(__LINE__, "D3DXComputeTangentFrameEx", mesh, sphere_normals_equal, ARRAY_SIZE(sphere_normals_equal));
+
+ refcount = mesh->lpVtbl->Release(mesh);
+ ok(!refcount, "Mesh has %u references left\n", refcount);
+ refcount = ID3DXBuffer_Release(adjacency);
+ ok(!refcount, "Buffer has %u references left\n", refcount);
+
+ free_test_context(test_context);
+}
+
+static void D3DXCreateAnimationControllerTest(void)
+{
+ HRESULT hr;
+ ID3DXAnimationController *animation;
+ UINT value;
+
+ hr = D3DXCreateAnimationController(0, 0, 0, 0, NULL);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+
+ animation = (void*)0xdeadbeef;
+ hr = D3DXCreateAnimationController(0, 1, 1, 1, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+ ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation);
+
+ animation = (void*)0xdeadbeef;
+ hr = D3DXCreateAnimationController(1, 0, 1, 1, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+ ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation);
+
+ animation = (void*)0xdeadbeef;
+ hr = D3DXCreateAnimationController(1, 1, 0, 1, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+ ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation);
+
+ animation = (void*)0xdeadbeef;
+ hr = D3DXCreateAnimationController(1, 1, 1, 0, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+ ok(animation == (void*)0xdeadbeef, "Got unexpected animation %p.\n", animation);
+
+ hr = D3DXCreateAnimationController(1, 1, 1, 1, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+
+ value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation);
+ ok(value == 1, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumAnimationSets(animation);
+ ok(value == 1, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumTracks(animation);
+ ok(value == 1, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumEvents(animation);
+ ok(value == 1, "Got unexpected value %u.\n", value);
+
+ animation->lpVtbl->Release(animation);
+
+ hr = D3DXCreateAnimationController(100, 101, 102, 103, &animation);
+ ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+
+ value = animation->lpVtbl->GetMaxNumAnimationOutputs(animation);
+ ok(value == 100, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumAnimationSets(animation);
+ ok(value == 101, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumTracks(animation);
+ ok(value == 102, "Got unexpected value %u.\n", value);
+
+ value = animation->lpVtbl->GetMaxNumEvents(animation);
+ ok(value == 103, "Got unexpected value %u.\n", value);
+
+ animation->lpVtbl->Release(animation);
+}
+
+static void test_D3DXFrameFind(void)
+{
+ static char n1[] = "name1";
+ static char n2[] = "name2";
+ static char n3[] = "name3";
+ static char n4[] = "name4";
+ static char n5[] = "name5";
+ static char n6[] = "name6";
+ static char N1[] = "Name1";
+ D3DXFRAME root, sibling, sibling2, child, *ret;
+ D3DXFRAME child2, child3;
+
+ ret = D3DXFrameFind(NULL, NULL);
+ ok(ret == NULL, "Unexpected frame, %p.\n", ret);
+
+ ret = D3DXFrameFind(NULL, "test");
+ ok(ret == NULL, "Unexpected frame, %p.\n", ret);
+
+ memset(&root, 0, sizeof(root));
+
+ ret = D3DXFrameFind(&root, NULL);
+ ok(ret == &root, "Unexpected frame, %p.\n", ret);
+
+ root.Name = n1;
+ ret = D3DXFrameFind(&root, NULL);
+ ok(ret == NULL, "Unexpected frame, %p.\n", ret);
+
+ ret = D3DXFrameFind(&root, n1);
+ ok(ret == &root, "Unexpected frame, %p.\n", ret);
+
+ ret = D3DXFrameFind(&root, N1);
+ ok(ret == NULL, "Unexpected frame, %p.\n", ret);
+
+ /* Test siblings order traversal. */
+ memset(&sibling, 0, sizeof(sibling));
+ sibling.Name = n2;
+ root.pFrameSibling = &sibling;
+ ret = D3DXFrameFind(&root, n2);
+ ok(ret == &sibling, "Unexpected frame, %p.\n", ret);
+
+ memset(&sibling2, 0, sizeof(sibling2));
+ sibling2.Name = n2;
+ sibling.pFrameSibling = &sibling2;
+ ret = D3DXFrameFind(&root, n2);
+ ok(ret == &sibling, "Unexpected frame, %p.\n", ret);
+
+ sibling2.Name = n3;
+ ret = D3DXFrameFind(&root, n3);
+ ok(ret == &sibling2, "Unexpected frame, %p.\n", ret);
+
+ /* Siblings first. */
+ memset(&child, 0, sizeof(child));
+ child.Name = n2;
+ root.pFrameFirstChild = &child;
+ ret = D3DXFrameFind(&root, n2);
+ ok(ret == &sibling, "Unexpected frame, %p.\n", ret);
+
+ child.Name = n4;
+ ret = D3DXFrameFind(&root, n4);
+ ok(ret == &child, "Unexpected frame, %p.\n", ret);
+
+ /* Link a grandchild and another one for sibling. */
+ memset(&child2, 0, sizeof(child2));
+ memset(&child3, 0, sizeof(child3));
+ child2.Name = child3.Name = n5;
+ sibling.pFrameFirstChild = &child2;
+ child.pFrameFirstChild = &child3;
+ ret = D3DXFrameFind(&root, n5);
+ ok(ret == &child2, "Unexpected frame, %p.\n", ret);
+
+ child3.Name = n6;
+ ret = D3DXFrameFind(&root, n6);
+ ok(ret == &child3, "Unexpected frame, %p.\n", ret);
+}
+
+START_TEST(mesh)
+{
+ D3DXBoundProbeTest();
+ D3DXComputeBoundingBoxTest();
+ D3DXComputeBoundingSphereTest();
+ D3DXGetFVFVertexSizeTest();
+ D3DXIntersectTriTest();
+ D3DXCreateMeshTest();
+ D3DXCreateMeshFVFTest();
+ D3DXLoadMeshTest();
+ D3DXCreateBoxTest();
+ D3DXCreatePolygonTest();
+ D3DXCreateSphereTest();
+ D3DXCreateCylinderTest();
+ D3DXCreateTextTest();
+ D3DXCreateTorusTest();
+ D3DXCreateAnimationControllerTest();
+ test_get_decl_length();
+ test_get_decl_vertex_size();
+ test_fvf_decl_conversion();
+ D3DXGenerateAdjacencyTest();
+ test_update_semantics();
+ test_create_skin_info();
+ test_convert_adjacency_to_point_reps();
+ test_convert_point_reps_to_adjacency();
+ test_weld_vertices();
+ test_clone_mesh();
+ test_valid_mesh();
+ test_optimize_faces();
+ test_compute_normals();
+ test_D3DXFrameFind();
+}
--- /dev/null
+#define REGISTER r0
+vs.1.1
--- /dev/null
+/*
+ * Copyright 2009 Tony Wasserka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_D3DX9_36_TEST_RESOURCES_H
+#define __WINE_D3DX9_36_TEST_RESOURCES_H
+
+#define IDB_BITMAP_1x1 10
+#define IDD_BITMAPDATA_1x1 11
+#define IDS_STRING 12
+
+#define IDB_ASMSHADER 20
+
+#endif /* __WINE_D3DX9_36_TEST_RESOURCES_H */
--- /dev/null
+/*
+ * Copyright 2009 Tony Wasserka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "resources.h"
+
+STRINGTABLE
+{
+ IDS_STRING "nobitmap"
+}
+
+/* @makedep: bmp1x1.bmp */
+IDB_BITMAP_1x1 BITMAP bmp1x1.bmp
+IDD_BITMAPDATA_1x1 RCDATA bmp1x1.bmp
+
+/* @makedep: res.vsh */
+IDB_ASMSHADER RCDATA res.vsh
--- /dev/null
+/*
+ * Copyright 2008 Luis Busquets
+ * Copyright 2011 Travis Athougies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+#include "d3dx9.h"
+
+#define FCC_TEXT MAKEFOURCC('T','E','X','T')
+#define FCC_CTAB MAKEFOURCC('C','T','A','B')
+
+static const DWORD shader_zero[] = {0x0};
+
+static const DWORD shader_invalid[] = {0xeeee0100};
+
+static const DWORD shader_empty[] = {0xfffe0200, 0x0000ffff};
+
+static const DWORD simple_fx[] = {0x46580000, 0x0002fffe, FCC_TEXT, 0x00000000, 0x0000ffff};
+
+static const DWORD simple_tx[] = {0x54580000, 0x0002fffe, FCC_TEXT, 0x00000000, 0x0000ffff};
+
+static const DWORD simple_7ffe[] = {0x7ffe0000, 0x0002fffe, FCC_TEXT, 0x00000000, 0x0000ffff};
+
+static const DWORD simple_7fff[] = {0x7fff0000, 0x0002fffe, FCC_TEXT, 0x00000000, 0x0000ffff};
+
+static const DWORD simple_vs[] = {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
+ 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
+ 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
+ 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
+ 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
+ 0x0000ffff}; /* END */
+
+static const DWORD simple_ps[] = {
+ 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 */
+
+static const DWORD shader_with_ctab[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0002fffe, FCC_TEXT, 0x00000000, /* TEXT comment */
+ 0x0008fffe, FCC_CTAB, 0x0000001c, 0x00000010, 0xfffe0300, 0x00000000, /* CTAB comment */
+ 0x00000000, 0x00000000, 0x00000000,
+ 0x0004fffe, FCC_TEXT, 0x00000000, 0x00000000, 0x00000000, /* TEXT comment */
+ 0x0000ffff}; /* END */
+
+static const DWORD shader_with_invalid_ctab[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0005fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000a9, 0xfffe0300,
+ 0x00000000, 0x00000000,
+ 0x0000ffff}; /* END */
+
+static const DWORD shader_with_ctab_constants[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x002efffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000a4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header */
+ 0x0000009c,
+ 0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000, /* Constant 1 desc */
+ 0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000, /* Constant 2 desc */
+ 0x00000090, 0x00040002, 0x00000003, 0x00000080, 0x00000000, /* Constant 3 desc */
+ 0x736e6f43, 0x746e6174, 0xabab0031, /* Constant 1 name string */
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0032, /* Constant 2 name string */
+ 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* Constant 2 & 3 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0033, /* Constant 3 name string */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
+static const DWORD ctab_basic[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0040fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000ec, 0xfffe0300, 0x00000005, 0x0000001c, 0x20008100, /* Header */
+ 0x000000e4,
+ 0x00000080, 0x00060002, 0x00000001, 0x00000084, 0x00000000, /* Constant 1 desc (f) */
+ 0x00000094, 0x00070002, 0x00000001, 0x00000098, 0x00000000, /* Constant 2 desc (f4) */
+ 0x000000A8, 0x00040002, 0x00000001, 0x000000AC, 0x00000000, /* Constant 3 desc (i) */
+ 0x000000BC, 0x00050002, 0x00000001, 0x000000C0, 0x00000000, /* Constant 4 desc (i4) */
+ 0x000000D0, 0x00000002, 0x00000004, 0x000000D4, 0x00000000, /* Constant 5 desc (mvp) */
+ 0xabab0066, 0x00030000, 0x00010001, 0x00000001, 0x00000000, /* Constant 1 name/type desc */
+ 0xab003466, 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 2 name/type desc */
+ 0xabab0069, 0x00020000, 0x00010001, 0x00000001, 0x00000000, /* Constant 3 name/type desc */
+ 0xab003469, 0x00020001, 0x00040001, 0x00000001, 0x00000000, /* Constant 4 name/type desc */
+ 0x0070766d, 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* Constant 5 name/type desc */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
+static const D3DXCONSTANT_DESC ctab_basic_expected[] = {
+ {"mvp", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL},
+ {"i", D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL},
+ {"i4", D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 4, 1, 0, 16, NULL},
+ {"f", D3DXRS_FLOAT4, 6, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL},
+ {"f4", D3DXRS_FLOAT4, 7, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 1, 0, 16, NULL}};
+
+static const DWORD ctab_matrices[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0032fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header */
+ 0x000000ac,
+ 0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000, /* Constant 1 desc (fmatrix3x1) */
+ 0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000, /* Constant 2 desc (fmatrix4x4) */
+ 0x00000090, 0x00040002, 0x00000002, 0x0000009c, 0x00000000, /* Constant 3 desc (imatrix2x3) */
+ 0x74616D66, 0x33786972, 0xab003178, /* Constant 1 name */
+ 0x00030003, 0x00010003, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x74616D66, 0x34786972, 0xab003478, /* Constant 2 name */
+ 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* Constant 2 type desc */
+ 0x74616D69, 0x32786972, 0xab003378, /* Constant 3 name */
+ 0x00020002, 0x00030002, 0x00000001, 0x00000000, /* Constant 3 type desc */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
+static const D3DXCONSTANT_DESC ctab_matrices_expected[] = {
+ {"fmatrix4x4", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL},
+ {"imatrix2x3", D3DXRS_FLOAT4, 4, 2, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 2, 3, 1, 0, 24, NULL},
+ {"fmatrix3x1", D3DXRS_FLOAT4, 7, 1, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL},
+};
+
+static const DWORD ctab_matrices2[] = {
+ 0xfffe0200, /* vs_2_0 */
+ 0x0058fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x0000012b, 0xfffe0200, 0x00000006, 0x0000001c, 0x00000100, /* Header */
+ 0x00000124,
+ 0x00000094, 0x00070002, 0x00000003, 0x0000009c, 0x00000000, /* Constant 1 desc (c2x3) */
+ 0x000000ac, 0x000d0002, 0x00000002, 0x000000b4, 0x00000000, /* Constant 2 desc (c3x2) */
+ 0x000000c4, 0x000a0002, 0x00000003, 0x000000cc, 0x00000000, /* Constant 3 desc (c3x3) */
+ 0x000000dc, 0x000f0002, 0x00000002, 0x000000e4, 0x00000000, /* Constant 4 desc (r2x3) */
+ 0x000000f4, 0x00040002, 0x00000003, 0x000000fc, 0x00000000, /* Constant 5 desc (r3x2) */
+ 0x0000010c, 0x00000002, 0x00000004, 0x00000114, 0x00000000, /* Constant 6 desc (r4x4) */
+ 0x33783263, 0xababab00, /* Constant 1 name */
+ 0x00030003, 0x00030002, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x32783363, 0xababab00, /* Constant 2 name */
+ 0x00030003, 0x00020003, 0x00000001, 0x00000000, /* Constant 2 type desc */
+ 0x33783363, 0xababab00, /* Constant 3 name */
+ 0x00030003, 0x00030003, 0x00000001, 0x00000000, /* Constant 3 type desc */
+ 0x33783272, 0xababab00, /* Constant 4 name */
+ 0x00030002, 0x00030002, 0x00000001, 0x00000000, /* Constant 4 type desc */
+ 0x32783372, 0xababab00, /* Constant 5 name */
+ 0x00030002, 0x00020003, 0x00000001, 0x00000000, /* Constant 5 type desc */
+ 0x34783472, 0xababab00, /* Constant 6 name */
+ 0x00030002, 0x00040004, 0x00000001, 0x00000000, /* Constant 6 type desc */
+ 0x325f7376, 0x4100305f, 0x41414141, 0x00414141, /* Target and Creator name */
+ 0x0000ffff}; /* END */
+
+static const D3DXCONSTANT_DESC ctab_matrices2_expected[] = {
+ {"c2x3", D3DXRS_FLOAT4, 7, 3, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL},
+ {"c3x2", D3DXRS_FLOAT4, 13, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL},
+ {"c3x3", D3DXRS_FLOAT4, 10, 3, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 3, 1, 0, 36, NULL},
+ {"r2x3", D3DXRS_FLOAT4, 15, 2, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL},
+ {"r3x2", D3DXRS_FLOAT4, 4, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL},
+ {"r4x4", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL}};
+
+static const DWORD ctab_arrays[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0052fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x0000013c, 0xfffe0300, 0x00000006, 0x0000001c, 0x20008100, /* Header */
+ 0x00000134,
+ 0x00000094, 0x000E0002, 0x00000002, 0x0000009c, 0x00000000, /* Constant 1 desc (barray) */
+ 0x000000ac, 0x00100002, 0x00000002, 0x000000b8, 0x00000000, /* Constant 2 desc (bvecarray) */
+ 0x000000c8, 0x00080002, 0x00000004, 0x000000d0, 0x00000000, /* Constant 3 desc (farray) */
+ 0x000000e0, 0x00000002, 0x00000008, 0x000000ec, 0x00000000, /* Constant 4 desc (fmtxarray) */
+ 0x000000fc, 0x000C0002, 0x00000002, 0x00000108, 0x00000000, /* Constant 5 desc (fvecarray) */
+ 0x00000118, 0x00120002, 0x00000001, 0x00000124, 0x00000000, /* Constant 6 desc (ivecarray) */
+ 0x72726162, 0xab007961, /* Constant 1 name */
+ 0x00010000, 0x00010001, 0x00000002, 0x00000000, /* Constant 1 type desc */
+ 0x63657662, 0x61727261, 0xabab0079, /* Constant 2 name */
+ 0x00010001, 0x00030001, 0x00000003, 0x00000000, /* Constant 2 type desc */
+ 0x72726166, 0xab007961, /* Constant 3 name */
+ 0x00030000, 0x00010001, 0x00000004, 0x00000000, /* constant 3 type desc */
+ 0x78746d66, 0x61727261, 0xabab0079, /* Constant 4 name */
+ 0x00030002, 0x00040004, 0x00000002, 0x00000000, /* Constant 4 type desc */
+ 0x63657666, 0x61727261, 0xabab0079, /* Constant 5 name */
+ 0x00030001, 0x00040001, 0x00000002, 0x00000000, /* Constant 5 type desc */
+ 0x63657669, 0x61727261, 0xabab0079, /* Constant 6 name */
+ 0x00020001, 0x00040001, 0x00000001, 0x00000000, /* Constant 6 type desc */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
+static const D3DXCONSTANT_DESC ctab_arrays_expected[] = {
+ {"fmtxarray", D3DXRS_FLOAT4, 0, 8, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4, 2, 0, 128, NULL},
+ {"farray", D3DXRS_FLOAT4, 8, 4, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 4, 0, 16, NULL},
+ {"fvecarray", D3DXRS_FLOAT4, 12, 2, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 2, 0, 32, NULL},
+ {"barray", D3DXRS_FLOAT4, 14, 2, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 2, 0, 8, NULL},
+ {"bvecarray", D3DXRS_FLOAT4, 16, 2, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 3, 0, 36, NULL},
+ {"ivecarray", D3DXRS_FLOAT4, 18, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 4, 1, 0, 16, NULL}};
+
+static const DWORD ctab_with_default_values[] = {
+ 0xfffe0200, /* vs_2_0 */
+ 0x007bfffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000001b7, 0xfffe0200, 0x00000005, 0x0000001c, /* header */
+ 0x00000100, 0x000001b0,
+ 0x00000080, 0x00080002, 0x00000003, 0x00000084, 0x00000094, /* constant 1 desc (arr) */
+ 0x000000c4, 0x000c0002, 0x00000001, 0x000000c8, 0x000000d8, /* constant 2 desc (flt) */
+ 0x000000e8, 0x00040002, 0x00000004, 0x000000f0, 0x00000100, /* constant 3 desc (mat3) */
+ 0x00000140, 0x00000002, 0x00000004, 0x000000f0, 0x00000148, /* constant 4 desc (mat4) */
+ 0x00000188, 0x000b0002, 0x00000001, 0x00000190, 0x000001a0, /* constant 5 desc (vec4) */
+ 0x00727261, /* constant 1 name */
+ 0x00030000, 0x00010001, 0x00000003, 0x00000000, /* constant 1 type desc */
+ 0x42c80000, 0x00000000, 0x00000000, 0x00000000, /* constant 1 default value */
+ 0x43480000, 0x00000000, 0x00000000, 0x00000000,
+ 0x43960000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00746c66, /* constant 2 name */
+ 0x00030000, 0x00010001, 0x00000001, 0x00000000, /* constant 2 type desc */
+ 0x411fd70a, 0x00000000, 0x00000000, 0x00000000, /* constant 2 default value */
+ 0x3374616d, /* constant 3 name */
+ 0xababab00,
+ 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* constant 3 & 4 type desc */
+ 0x41300000, 0x425c0000, 0x42c60000, 0x44a42000, /* constat 3 default value */
+ 0x41b00000, 0x42840000, 0x447c8000, 0x44b0c000,
+ 0x42040000, 0x429a0000, 0x448ae000, 0x44bd6000,
+ 0x42300000, 0x42b00000, 0x44978000, 0x44ca0000,
+ 0x3474616d, /* constant 4 name */
+ 0xababab00,
+ 0x3f800000, 0x40a00000, 0x41100000, 0x41500000, /* constant 4 default value */
+ 0x40000000, 0x40c00000, 0x41200000, 0x41600000,
+ 0x40400000, 0x40e00000, 0x41300000, 0x41700000,
+ 0x40800000, 0x41000000, 0x41400000, 0x41800000,
+ 0x34636576, /* constant 5 name */
+ 0xababab00,
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* constant 5 type desc */
+ 0x41200000, 0x41a00000, 0x41f00000, 0x42200000, /* constant 5 default value */
+ 0x325f7376, 0x4d004141, 0x41414141, 0x00000000, /* target & creator string */
+ 0x0000ffff}; /* END */
+
+static const float mat4_default_value[] = {1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16};
+static const float mat3_default_value[] = {11, 55, 99, 1313, 22, 66, 1010, 1414, 33, 77, 1111, 1515, 44, 88, 1212, 1616};
+static const float arr_default_value[] = {100, 0, 0, 0, 200, 0, 0, 0, 300, 0, 0, 0};
+static const float vec4_default_value[] = {10, 20, 30, 40};
+static const float flt_default_value[] = {9.99, 0, 0, 0};
+
+static const D3DXCONSTANT_DESC ctab_with_default_values_expected[] = {
+ {"mat4", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat4_default_value},
+ {"mat3", D3DXRS_FLOAT4, 4, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, mat3_default_value},
+ {"arr", D3DXRS_FLOAT4, 8, 3, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 3, 0, 12, arr_default_value},
+ {"vec4", D3DXRS_FLOAT4, 11, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 1, 0, 16, vec4_default_value},
+ {"flt", D3DXRS_FLOAT4, 12, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, flt_default_value}};
+
+static const DWORD ctab_samplers[] = {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0032fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000b4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header */
+ 0x000000ac,
+ 0x00000058, 0x00020002, 0x00000001, 0x00000064, 0x00000000, /* Constant 1 desc (notsampler) */
+ 0x00000074, 0x00000003, 0x00000001, 0x00000080, 0x00000000, /* Constant 2 desc (sampler1) */
+ 0x00000090, 0x00030003, 0x00000001, 0x0000009c, 0x00000000, /* Constant 3 desc (sampler2) */
+ 0x73746f6e, 0x6c706d61, 0xab007265, /* Constant 1 name */
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x706d6173, 0x3172656c, 0xababab00, /* Constant 2 name */
+ 0x000c0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 2 type desc */
+ 0x706d6173, 0x3272656c, 0xababab00, /* Constant 3 name */
+ 0x000d0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 3 type desc */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff}; /* END */
+
+static const D3DXCONSTANT_DESC ctab_samplers_expected[] = {
+ {"sampler1", D3DXRS_SAMPLER, 0, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER2D, 1, 1, 1, 0, 4, NULL},
+ {"sampler2", D3DXRS_SAMPLER, 3, 1, D3DXPC_OBJECT, D3DXPT_SAMPLER3D, 1, 1, 1, 0, 4, NULL},
+ {"notsampler", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 4, 1, 0, 16, NULL}};
+
+static const DWORD fx_shader_with_ctab[] =
+{
+ 0x46580200, /* FX20 */
+ 0x002efffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x000000a4, 0xfffe0300, 0x00000003, 0x0000001c, 0x20008100, /* Header */
+ 0x0000009c,
+ 0x00000058, 0x00070002, 0x00000001, 0x00000064, 0x00000000, /* Constant 1 desc */
+ 0x00000074, 0x00000002, 0x00000004, 0x00000080, 0x00000000, /* Constant 2 desc */
+ 0x00000090, 0x00040002, 0x00000003, 0x00000080, 0x00000000, /* Constant 3 desc */
+ 0x736e6f43, 0x746e6174, 0xabab0031, /* Constant 1 name string */
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0032, /* Constant 2 name string */
+ 0x00030003, 0x00040004, 0x00000001, 0x00000000, /* Constant 2 & 3 type desc */
+ 0x736e6f43, 0x746e6174, 0xabab0033, /* Constant 3 name string */
+ 0x335f7376, 0xab00305f, /* Target name string */
+ 0x656e6957, 0x6f727020, 0x7463656a, 0xababab00, /* Creator name string */
+ 0x0000ffff /* END */
+};
+
+static void test_get_shader_size(void)
+{
+ UINT shader_size, expected;
+
+ shader_size = D3DXGetShaderSize(simple_vs);
+ expected = sizeof(simple_vs);
+ ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
+
+ shader_size = D3DXGetShaderSize(simple_ps);
+ expected = sizeof(simple_ps);
+ ok(shader_size == expected, "Got shader size %u, expected %u\n", shader_size, expected);
+
+ shader_size = D3DXGetShaderSize(NULL);
+ ok(shader_size == 0, "Got shader size %u, expected 0\n", shader_size);
+}
+
+static void test_get_shader_version(void)
+{
+ DWORD shader_version;
+
+ shader_version = D3DXGetShaderVersion(simple_vs);
+ ok(shader_version == D3DVS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
+ shader_version, D3DVS_VERSION(1, 1));
+
+ shader_version = D3DXGetShaderVersion(simple_ps);
+ ok(shader_version == D3DPS_VERSION(1, 1), "Got shader version 0x%08x, expected 0x%08x\n",
+ shader_version, D3DPS_VERSION(1, 1));
+
+ shader_version = D3DXGetShaderVersion(NULL);
+ ok(shader_version == 0, "Got shader version 0x%08x, expected 0\n", shader_version);
+}
+
+static void test_find_shader_comment(void)
+{
+ const void *data = (void *)0xdeadbeef;
+ HRESULT hr;
+ UINT size = 100;
+
+ hr = D3DXFindShaderComment(NULL, MAKEFOURCC('C','T','A','B'), &data, &size);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), NULL, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(size == 28, "Got %u, expected 28\n", size);
+
+ hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == shader_with_ctab + 6, "Got result %p, expected %p\n", data, shader_with_ctab + 6);
+
+ hr = D3DXFindShaderComment(shader_with_ctab, 0, &data, &size);
+ ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('X','X','X','X'), &data, &size);
+ ok(hr == S_FALSE, "Got result %x, expected 1 (S_FALSE)\n", hr);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(shader_with_ctab, MAKEFOURCC('C','T','A','B'), &data, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == shader_with_ctab + 6, "Got result %p, expected %p\n", data, shader_with_ctab + 6);
+ ok(size == 28, "Got result %u, expected 28\n", size);
+
+ hr = D3DXFindShaderComment(shader_zero, MAKEFOURCC('C','T','A','B'), &data, &size);
+ ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(shader_invalid, MAKEFOURCC('C','T','A','B'), &data, &size);
+ ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(shader_empty, MAKEFOURCC('C','T','A','B'), &data, &size);
+ ok(hr == S_FALSE, "Got result %x, expected %x (S_FALSE)\n", hr, S_FALSE);
+ ok(!data, "Got %p, expected NULL\n", data);
+ ok(!size, "Got %u, expected 0\n", size);
+
+ hr = D3DXFindShaderComment(simple_fx, FCC_TEXT, &data, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == simple_fx + 3, "Got result %p, expected %p\n", data, simple_fx + 3);
+ ok(size == 4, "Got result %u, expected 4\n", size);
+
+ hr = D3DXFindShaderComment(simple_tx, FCC_TEXT, &data, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == simple_tx + 3, "Got result %p, expected %p\n", data, simple_tx + 3);
+ ok(size == 4, "Got result %u, expected 4\n", size);
+
+ hr = D3DXFindShaderComment(simple_7ffe, FCC_TEXT, &data, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == simple_7ffe + 3, "Got result %p, expected %p\n", data, simple_7ffe + 3);
+ ok(size == 4, "Got result %u, expected 4\n", size);
+
+ hr = D3DXFindShaderComment(simple_7fff, FCC_TEXT, &data, &size);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(data == simple_7fff + 3, "Got result %p, expected %p\n", data, simple_7fff + 3);
+ ok(size == 4, "Got result %u, expected 4\n", size);
+}
+
+static void test_get_shader_constant_table_ex(void)
+{
+ ID3DXConstantTable *constant_table;
+ HRESULT hr;
+ void *data;
+ DWORD size;
+ D3DXCONSTANTTABLE_DESC desc;
+
+ constant_table = (ID3DXConstantTable *)0xdeadbeef;
+ hr = D3DXGetShaderConstantTableEx(NULL, 0, &constant_table);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ ok(constant_table == NULL, "D3DXGetShaderConstantTableEx() failed, got %p\n", constant_table);
+
+ constant_table = (ID3DXConstantTable *)0xdeadbeef;
+ hr = D3DXGetShaderConstantTableEx(shader_zero, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(constant_table == NULL, "D3DXGetShaderConstantTableEx() failed, got %p\n", constant_table);
+
+ constant_table = (ID3DXConstantTable *)0xdeadbeef;
+ hr = D3DXGetShaderConstantTableEx(shader_invalid, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
+ ok(constant_table == NULL, "D3DXGetShaderConstantTableEx() failed, got %p\n", constant_table);
+
+ constant_table = (ID3DXConstantTable *)0xdeadbeef;
+ hr = D3DXGetShaderConstantTableEx(shader_empty, 0, &constant_table);
+ ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
+ ok(constant_table == NULL, "D3DXGetShaderConstantTableEx() failed, got %p\n", constant_table);
+
+ /* No CTAB data */
+ constant_table = (ID3DXConstantTable *)0xdeadbeef;
+ hr = D3DXGetShaderConstantTableEx(simple_ps, 0, &constant_table);
+ ok(hr == D3DXERR_INVALIDDATA, "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
+ ok(constant_table == NULL, "D3DXGetShaderConstantTableEx() failed, got %p\n", constant_table);
+
+ /* With invalid CTAB data */
+ hr = D3DXGetShaderConstantTableEx(shader_with_invalid_ctab, 0, &constant_table);
+ ok(hr == D3DXERR_INVALIDDATA || broken(hr == D3D_OK), /* winxp 64-bit, w2k3 64-bit */
+ "Got result %x, expected %x (D3DXERR_INVALIDDATA)\n", hr, D3DXERR_INVALIDDATA);
+ if (constant_table) ID3DXConstantTable_Release(constant_table);
+
+ hr = D3DXGetShaderConstantTableEx(simple_fx, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!constant_table, "D3DXGetShaderConstantTableEx() returned a non-NULL constant table.\n");
+
+ hr = D3DXGetShaderConstantTableEx(simple_tx, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!constant_table, "D3DXGetShaderConstantTableEx() returned a non-NULL constant table.\n");
+
+ hr = D3DXGetShaderConstantTableEx(shader_with_ctab, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(constant_table != NULL, "D3DXGetShaderConstantTableEx() failed, got NULL\n");
+
+ if (constant_table)
+ {
+ size = ID3DXConstantTable_GetBufferSize(constant_table);
+ ok(size == 28, "Got result %x, expected 28\n", size);
+
+ data = ID3DXConstantTable_GetBufferPointer(constant_table);
+ ok(!memcmp(data, shader_with_ctab + 6, size), "Retrieved wrong CTAB data\n");
+
+ hr = ID3DXConstantTable_GetDesc(constant_table, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+
+ hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(desc.Creator == (const char *)data + 0x10, "Got result %p, expected %p\n",
+ desc.Creator, (const char *)data + 0x10);
+ ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
+ ok(desc.Constants == 0, "Got result %x, expected 0\n", desc.Constants);
+
+ ID3DXConstantTable_Release(constant_table);
+ }
+
+ hr = D3DXGetShaderConstantTableEx(shader_with_ctab_constants, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(constant_table != NULL, "D3DXGetShaderConstantTableEx() failed, got NULL\n");
+
+ if (constant_table)
+ {
+ D3DXHANDLE constant;
+ D3DXCONSTANT_DESC constant_desc;
+ D3DXCONSTANT_DESC constant_desc_save;
+ UINT nb;
+
+ /* Test GetDesc */
+ hr = ID3DXConstantTable_GetDesc(constant_table, &desc);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(desc.Creator, "Wine project"), "Got result '%s', expected 'Wine project'\n", desc.Creator);
+ ok(desc.Version == D3DVS_VERSION(3, 0), "Got result %x, expected %x\n", desc.Version, D3DVS_VERSION(3, 0));
+ ok(desc.Constants == 3, "Got result %x, expected 3\n", desc.Constants);
+
+ /* Test GetConstant */
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant1"), "Got result '%s', expected 'Constant1'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_VECTOR, "Got result %x, expected %u (D3DXPC_VECTOR)\n",
+ constant_desc.Class, D3DXPC_VECTOR);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 1, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 1);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant2"), "Got result '%s', expected 'Constant2'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
+ constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 2);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!strcmp(constant_desc.Name, "Constant3"), "Got result '%s', expected 'Constant3'\n",
+ constant_desc.Name);
+ ok(constant_desc.Class == D3DXPC_MATRIX_COLUMNS, "Got result %x, expected %u (D3DXPC_MATRIX_COLUMNS)\n",
+ constant_desc.Class, D3DXPC_MATRIX_COLUMNS);
+ ok(constant_desc.Type == D3DXPT_FLOAT, "Got result %x, expected %u (D3DXPT_FLOAT)\n",
+ constant_desc.Type, D3DXPT_FLOAT);
+ ok(constant_desc.Rows == 4, "Got result %x, expected 1\n", constant_desc.Rows);
+ ok(constant_desc.Columns == 4, "Got result %x, expected 4\n", constant_desc.Columns);
+ constant_desc_save = constant_desc; /* For GetConstantDesc test */
+
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 3);
+ ok(constant == NULL, "Got result %p, expected NULL\n", constant);
+
+ /* Test GetConstantByName */
+ constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant unknown");
+ ok(constant == NULL, "Got result %p, expected NULL\n", constant);
+ constant = ID3DXConstantTable_GetConstantByName(constant_table, NULL, "Constant3");
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
+
+ /* Test GetConstantDesc */
+ constant = ID3DXConstantTable_GetConstant(constant_table, NULL, 0);
+ ok(constant != NULL, "No constant found\n");
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, NULL, &constant_desc, &nb);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, NULL, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, constant, &constant_desc, NULL);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant unknown", &constant_desc, &nb);
+ ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
+ hr = ID3DXConstantTable_GetConstantDesc(constant_table, "Constant3", &constant_desc, &nb);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
+ ok(!memcmp(&constant_desc, &constant_desc_save, sizeof(D3DXCONSTANT_DESC)), "Got different constant data\n");
+
+ ID3DXConstantTable_Release(constant_table);
+ }
+
+ hr = D3DXGetShaderConstantTableEx(fx_shader_with_ctab, 0, &constant_table);
+ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK).\n", hr);
+ ok(!constant_table, "D3DXGetShaderConstantTableEx() returned a non-NULL constant table.\n");
+}
+
+static void test_constant_table(const char *test_name, const DWORD *ctable_fn,
+ const D3DXCONSTANT_DESC *expecteds, UINT count)
+{
+ UINT i;
+ ID3DXConstantTable *ctable;
+
+ HRESULT res;
+
+ /* Get the constant table from the shader itself */
+ res = D3DXGetShaderConstantTable(ctable_fn, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on %s: got %08x\n", test_name, res);
+
+ for (i = 0; i < count; i++)
+ {
+ const D3DXCONSTANT_DESC *expected = &expecteds[i];
+ D3DXHANDLE const_handle;
+ D3DXCONSTANT_DESC actual;
+ UINT pCount = 1;
+
+ const_handle = ID3DXConstantTable_GetConstantByName(ctable, NULL, expected->Name);
+
+ res = ID3DXConstantTable_GetConstantDesc(ctable, const_handle, &actual, &pCount);
+ ok(SUCCEEDED(res), "%s in %s: ID3DXConstantTable_GetConstantDesc returned %08x\n", expected->Name,
+ test_name, res);
+ ok(pCount == 1, "%s in %s: Got more or less descriptions: %d\n", expected->Name, test_name, pCount);
+
+ ok(strcmp(actual.Name, expected->Name) == 0,
+ "%s in %s: Got different names: Got %s, expected %s\n", expected->Name,
+ test_name, actual.Name, expected->Name);
+ ok(actual.RegisterSet == expected->RegisterSet,
+ "%s in %s: Got different register sets: Got %d, expected %d\n",
+ expected->Name, test_name, actual.RegisterSet, expected->RegisterSet);
+ ok(actual.RegisterIndex == expected->RegisterIndex,
+ "%s in %s: Got different register indices: Got %d, expected %d\n",
+ expected->Name, test_name, actual.RegisterIndex, expected->RegisterIndex);
+ ok(actual.RegisterCount == expected->RegisterCount,
+ "%s in %s: Got different register counts: Got %d, expected %d\n",
+ expected->Name, test_name, actual.RegisterCount, expected->RegisterCount);
+ ok(actual.Class == expected->Class,
+ "%s in %s: Got different classes: Got %d, expected %d\n", expected->Name,
+ test_name, actual.Class, expected->Class);
+ ok(actual.Type == expected->Type,
+ "%s in %s: Got different types: Got %d, expected %d\n", expected->Name,
+ test_name, actual.Type, expected->Type);
+ ok(actual.Rows == expected->Rows && actual.Columns == expected->Columns,
+ "%s in %s: Got different dimensions: Got (%d, %d), expected (%d, %d)\n",
+ expected->Name, test_name, actual.Rows, actual.Columns, expected->Rows,
+ expected->Columns);
+ ok(actual.Elements == expected->Elements,
+ "%s in %s: Got different element count: Got %d, expected %d\n",
+ expected->Name, test_name, actual.Elements, expected->Elements);
+ ok(actual.StructMembers == expected->StructMembers,
+ "%s in %s: Got different struct member count: Got %d, expected %d\n",
+ expected->Name, test_name, actual.StructMembers, expected->StructMembers);
+ ok(actual.Bytes == expected->Bytes,
+ "%s in %s: Got different byte count: Got %d, expected %d\n",
+ expected->Name, test_name, actual.Bytes, expected->Bytes);
+
+ if (!expected->DefaultValue)
+ {
+ ok(actual.DefaultValue == NULL,
+ "%s in %s: Got different default value: expected NULL\n",
+ expected->Name, test_name);
+ }
+ else
+ {
+ ok(actual.DefaultValue != NULL,
+ "%s in %s: Got different default value: expected non-NULL\n",
+ expected->Name, test_name);
+ ok(memcmp(actual.DefaultValue, expected->DefaultValue, expected->Bytes) == 0,
+ "%s in %s: Got different default value\n", expected->Name, test_name);
+ }
+ }
+
+ /* Finally, release the constant table */
+ ID3DXConstantTable_Release(ctable);
+}
+
+static void test_constant_tables(void)
+{
+ test_constant_table("test_basic", ctab_basic, ctab_basic_expected,
+ ARRAY_SIZE(ctab_basic_expected));
+ test_constant_table("test_matrices", ctab_matrices, ctab_matrices_expected,
+ ARRAY_SIZE(ctab_matrices_expected));
+ test_constant_table("test_matrices2", ctab_matrices2, ctab_matrices2_expected,
+ ARRAY_SIZE(ctab_matrices2_expected));
+ test_constant_table("test_arrays", ctab_arrays, ctab_arrays_expected,
+ ARRAY_SIZE(ctab_arrays_expected));
+ test_constant_table("test_default_values", ctab_with_default_values, ctab_with_default_values_expected,
+ ARRAY_SIZE(ctab_with_default_values_expected));
+ test_constant_table("test_samplers", ctab_samplers, ctab_samplers_expected,
+ ARRAY_SIZE(ctab_samplers_expected));
+}
+
+static void test_setting_basic_table(IDirect3DDevice9 *device)
+{
+ static const D3DXMATRIX mvp = {{{
+ 0.514f, 0.626f, 0.804f, 0.786f,
+ 0.238f, 0.956f, 0.374f, 0.483f,
+ 0.109f, 0.586f, 0.900f, 0.255f,
+ 0.898f, 0.411f, 0.932f, 0.275f}}};
+ static const D3DXVECTOR4 f4 = {0.350f, 0.526f, 0.925f, 0.021f};
+ static const float f = 0.12543f;
+ static const int i = 321;
+ static const D3DXMATRIX *matrix_pointer[] = {&mvp};
+
+ ID3DXConstantTable *ctable;
+
+ HRESULT res;
+ float out[16];
+ ULONG refcnt;
+
+ /* Get the constant table from the shader itself */
+ res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
+
+ /* Set constants */
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable mvp: got 0x%08x\n", res);
+
+ res = ID3DXConstantTable_SetInt(ctable, device, "i", i + 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
+
+ /* Check that setting i again will overwrite the previous value */
+ res = ID3DXConstantTable_SetInt(ctable, device, "i", i);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetInt failed on variable i: got 0x%08x\n", res);
+
+ res = ID3DXConstantTable_SetFloat(ctable, device, "f", f);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f: got 0x%08x\n", res);
+
+ res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f4: got 0x%08x\n", res);
+
+ /* Get constants back and validate */
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14,
+ "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
+ ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24,
+ "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
+ ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34,
+ "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
+ ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44,
+ "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 1);
+ ok(out[0] == (float)i && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable i was not set correctly, out={%f, %f, %f, %f}, should be {%d, 0.0, 0.0, 0.0}\n",
+ out[0], out[1], out[2], out[3], i);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly, out={%f, %f, %f, %f}, should be {%f, 0.0, 0.0, 0.0}\n",
+ out[0], out[1], out[2], out[3], f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(memcmp(out, &f4, sizeof(f4)) == 0,
+ "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
+
+ /* Finally test using a set* function for one type to set a variable of another type (should succeed) */
+ res = ID3DXConstantTable_SetVector(ctable, device, "f", &f4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == f4.x && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly by ID3DXConstantTable_SetVector, got %f, should be %f\n",
+ out[0], f4.x);
+
+ memset(out, 0, sizeof(out));
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "f", &mvp);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable f: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly by ID3DXConstantTable_SetMatrix, got %f, should be %f\n",
+ out[0], S(U(mvp))._11);
+
+ /* Clear registers */
+ memset(out, 0, sizeof(out));
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 0, out, 4);
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 7, out, 1);
+
+ /* SetVector shouldn't change the value of a matrix constant */
+ res = ID3DXConstantTable_SetVector(ctable, device, "mvp", &f4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed on variable f: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
+ && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
+ "The variable mvp was not set correctly by ID3DXConstantTable_SetVector, "
+ "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
+ "should be all 0.0f\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ out[12], out[13], out[14], out[15]);
+
+ res = ID3DXConstantTable_SetFloat(ctable, device, "mvp", f);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable mvp: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == 0.0f && out[9] == 0.0f && out[10] == 0.0f && out[11] == 0.0f
+ && out[12] == 0.0f && out[13] == 0.0f && out[14] == 0.0f && out[15] == 0.0f,
+ "The variable mvp was not set correctly by ID3DXConstantTable_SetFloat, "
+ "got {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f %f; %f, %f, %f, %f}, "
+ "should be all 0.0f\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ out[12], out[13], out[14], out[15]);
+
+ res = ID3DXConstantTable_SetFloat(ctable, device, "f4", f);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetFloat failed on variable f4: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f4 was not set correctly by ID3DXConstantTable_SetFloat, "
+ "got {%f, %f, %f, %f}, should be all 0.0f\n",
+ out[0], out[1], out[2], out[3]);
+
+ res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f", &mvp);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly by ID3DXConstantTable_SetMatrixTranspose, got %f, should be %f\n",
+ out[0], S(U(mvp))._11);
+
+ res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "f4", &mvp);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable f4: 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == S(U(mvp))._21 && out[2] == S(U(mvp))._31 && out[3] == S(U(mvp))._41,
+ "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixTranspose, "
+ "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ S(U(mvp))._11, S(U(mvp))._21, S(U(mvp))._31, S(U(mvp))._41);
+
+ memset(out, 0, sizeof(out));
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
+ res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, "
+ "got %f, should be %f\n",
+ out[0], S(U(mvp))._11);
+
+ res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "f4", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable f4: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == S(U(mvp))._12 && out[2] == S(U(mvp))._13 && out[3] == S(U(mvp))._14,
+ "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixPointerArray, "
+ "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
+
+ memset(out, 0, sizeof(out));
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 6, out, 1);
+ res = ID3DXConstantTable_SetMatrixTransposePointerArray(ctable, device, "f", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTransposePointerArray failed on variable f: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 6, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The variable f was not set correctly by ID3DXConstantTable_SetMatrixTransposePointerArray, "
+ "got %f, should be %f\n",
+ out[0], S(U(mvp))._11);
+
+ res = ID3DXConstantTable_SetMatrixTransposePointerArray(ctable, device, "f4", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTransposePointerArray failed on variable f4: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(out[0] == S(U(mvp))._11 && out[1] == S(U(mvp))._21 && out[2] == S(U(mvp))._31 && out[3] == S(U(mvp))._41,
+ "The variable f4 was not set correctly by ID3DXConstantTable_SetMatrixTransposePointerArray, "
+ "got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ S(U(mvp))._11, S(U(mvp))._21, S(U(mvp))._31, S(U(mvp))._41);
+
+ refcnt = ID3DXConstantTable_Release(ctable);
+ ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
+}
+
+static void test_setting_matrices_table(IDirect3DDevice9 *device)
+{
+ static const D3DXMATRIX fmatrix =
+ {{{2.001f, 1.502f, 9.003f, 1.004f,
+ 5.005f, 3.006f, 3.007f, 6.008f,
+ 9.009f, 5.010f, 7.011f, 1.012f,
+ 5.013f, 5.014f, 5.015f, 9.016f}}};
+ static const D3DXMATRIX *matrix_pointer[] = {&fmatrix};
+
+ ID3DXConstantTable *ctable;
+
+ HRESULT res;
+ float out[32];
+
+ res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "imatrix2x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable imatrix2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "fmatrix3x1", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable fmatrix3x1: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
+ ok(out[0] == (int)S(U(fmatrix))._11 && out[1] == (int)S(U(fmatrix))._12 && out[2] == (int)S(U(fmatrix))._13
+ && out[3] == 0
+ && out[4] == (int)S(U(fmatrix))._21 && out[5] == (int)S(U(fmatrix))._22 && out[6] == (int)S(U(fmatrix))._23
+ && out[7] == 0,
+ "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%d, %d, %d, %d; %d, %d, %d, %d}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ (int)S(U(fmatrix))._11, (int)S(U(fmatrix))._12, (int)S(U(fmatrix))._13, 0,
+ (int)S(U(fmatrix))._21, (int)S(U(fmatrix))._22, (int)S(U(fmatrix))._23, 0);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f,
+ "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f);
+
+ ID3DXConstantTable_Release(ctable);
+
+ res = D3DXGetShaderConstantTable(ctab_matrices2, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %#x\n", res);
+
+ /* SetMatrix */
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "c2x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "r2x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x2", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x2: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "r3x2", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r3x2: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "c3x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable c3x3: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f,
+ "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f,
+ S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "r4x4", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed on variable r4x4: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f,
+ "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 13, out, 2);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
+ "The variable c3x2 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
+ "The variable r3x2 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
+ S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 10, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == S(U(fmatrix))._33 && out[11] == 0.0f,
+ "The variable c3x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f,
+ S(U(fmatrix))._13, S(U(fmatrix))._23, S(U(fmatrix))._33, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == S(U(fmatrix))._14
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == S(U(fmatrix))._24
+ && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == S(U(fmatrix))._33 && out[11] == S(U(fmatrix))._34
+ && out[12] == S(U(fmatrix))._41 && out[13] == S(U(fmatrix))._42 && out[14] == S(U(fmatrix))._43 && out[15] == S(U(fmatrix))._44,
+ "The variable r4x4 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, S(U(fmatrix))._14,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, S(U(fmatrix))._24,
+ S(U(fmatrix))._31, S(U(fmatrix))._32, S(U(fmatrix))._33, S(U(fmatrix))._34,
+ S(U(fmatrix))._41, S(U(fmatrix))._42, S(U(fmatrix))._43, S(U(fmatrix))._44);
+
+ /* SetMatrixTranspose */
+ res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "c2x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable c2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrixTranspose(ctable, device, "r2x3", &fmatrix);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTranspose failed on variable r2x3: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
+ "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
+ S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
+ "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
+
+ /* SetMatrixPointerArray */
+ res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "c2x3", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable c2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrixPointerArray(ctable, device, "r2x3", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixPointerArray failed on variable r2x3: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._13 && out[9] == S(U(fmatrix))._23 && out[10] == 0.0f && out[11] == 0.0f,
+ "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, 0.0f, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, 0.0f, 0.0f,
+ S(U(fmatrix))._13, S(U(fmatrix))._23, 0.0f, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == S(U(fmatrix))._13 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._23 && out[7] == 0.0f,
+ "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, S(U(fmatrix))._13, 0.0f,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, S(U(fmatrix))._23, 0.0f);
+
+ /* SetMatrixTransposePointerArray */
+ res = ID3DXConstantTable_SetMatrixTransposePointerArray(ctable, device, "c2x3", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTransposePointerArray failed on variable c2x3: got %#x\n", res);
+
+ res = ID3DXConstantTable_SetMatrixTransposePointerArray(ctable, device, "r2x3", matrix_pointer, 1);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixTransposePointerArray failed on variable r2x3: got %#x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 3);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._12 && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._21 && out[5] == S(U(fmatrix))._22 && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == S(U(fmatrix))._31 && out[9] == S(U(fmatrix))._32 && out[10] == 0.0f && out[11] == 0.0f,
+ "The variable c2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11],
+ S(U(fmatrix))._11, S(U(fmatrix))._12, 0.0f, 0.0f,
+ S(U(fmatrix))._21, S(U(fmatrix))._22, 0.0f, 0.0f,
+ S(U(fmatrix))._31, S(U(fmatrix))._32, 0.0f, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 15, out, 2);
+ ok(out[0] == S(U(fmatrix))._11 && out[1] == S(U(fmatrix))._21 && out[2] == S(U(fmatrix))._31 && out[3] == 0.0f
+ && out[4] == S(U(fmatrix))._12 && out[5] == S(U(fmatrix))._22 && out[6] == S(U(fmatrix))._32 && out[7] == 0.0f,
+ "The variable r2x3 was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ S(U(fmatrix))._11, S(U(fmatrix))._21, S(U(fmatrix))._31, 0.0f,
+ S(U(fmatrix))._12, S(U(fmatrix))._22, S(U(fmatrix))._32, 0.0f);
+
+ ID3DXConstantTable_Release(ctable);
+}
+
+static void test_setting_arrays_table(IDirect3DDevice9 *device)
+{
+ static const float farray[8] = {
+ 0.005f, 0.745f, 0.973f, 0.264f,
+ 0.010f, 0.020f, 0.030f, 0.040f};
+ static const D3DXMATRIX fmtxarray[2] = {
+ {{{0.001f, 0.002f, 0.003f, 0.004f,
+ 0.005f, 0.006f, 0.007f, 0.008f,
+ 0.009f, 0.010f, 0.011f, 0.012f,
+ 0.013f, 0.014f, 0.015f, 0.016f}}},
+ {{{0.010f, 0.020f, 0.030f, 0.040f,
+ 0.050f, 0.060f, 0.070f, 0.080f,
+ 0.090f, 0.100f, 0.110f, 0.120f,
+ 0.130f, 0.140f, 0.150f, 0.160f}}}};
+ static const int iarray[4] = {1, 2, 3, 4};
+ static const D3DXVECTOR4 fvecarray[2] = {
+ {0.745f, 0.997f, 0.353f, 0.237f},
+ {0.060f, 0.455f, 0.333f, 0.983f}};
+ static BOOL barray[4] = {FALSE, 100, TRUE, TRUE};
+
+ ID3DXConstantTable *ctable;
+
+ HRESULT res;
+ float out[32];
+ ULONG refcnt;
+
+ /* Clear registers */
+ memset(out, 0, sizeof(out));
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 8, out, 4);
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 12, out, 4);
+
+ /* Get the constant table from the shader */
+ res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got 0x%08x\n", res);
+
+ /* Set constants */
+
+ /* Make sure that we cannot set registers that do not belong to this constant */
+ res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 8);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 8);
+ ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
+ "The in-bounds elements of the array were not set, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
+ ok(out[16] == 0.0f && out[20] == 0.0f && out[24] == 0.0f && out[28] == 0.0f,
+ "The excess elements of the array were set, out={%f, %f, %f, %f}, should be all 0.0f\n",
+ out[16], out[20], out[24], out[28]);
+
+ /* ivecarray takes up only 1 register, but a matrix takes up 4, so no elements should be set */
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "ivecarray", &fmtxarray[0]);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 18, out, 4);
+ ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f,
+ "The array was set, out={%f, %f, %f, %f}, should be all 0.0f\n", out[0], out[1], out[2], out[3]);
+
+ /* Try setting an integer array to an array declared as a float array */
+ res = ID3DXConstantTable_SetIntArray(ctable, device, "farray", iarray, 4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetIntArray failed: got 0x%08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
+ ok(out[0] == iarray[0] && out[4] == iarray[1] && out[8] == iarray[2] && out[12] == iarray[3],
+ "SetIntArray did not properly set a float array: out={%f, %f, %f, %f}, should be {%d, %d, %d, %d}\n",
+ out[0], out[4], out[8], out[12], iarray[0], iarray[1], iarray[2], iarray[3]);
+
+ res = ID3DXConstantTable_SetFloatArray(ctable, device, "farray", farray, 4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetFloatArray failed: got x0%08x\n", res);
+
+ res = ID3DXConstantTable_SetVectorArray(ctable, device, "fvecarray", fvecarray, 2);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetVectorArray failed: got 0x%08x\n", res);
+
+ res = ID3DXConstantTable_SetMatrixArray(ctable, device, "fmtxarray", fmtxarray, 2);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrixArray failed: got 0x%08x\n", res);
+
+ res = ID3DXConstantTable_SetBoolArray(ctable, device, "barray", barray, 2);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetBoolArray failed: got 0x%08x\n", res);
+
+ /* Read back constants */
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
+ ok(out[0] == farray[0] && out[4] == farray[1] && out[8] == farray[2] && out[12] == farray[3],
+ "The variable farray was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[4], out[8], out[12], farray[0], farray[1], farray[2], farray[3]);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
+ ok(out[0] == fvecarray[0].x && out[1] == fvecarray[0].y && out[2] == fvecarray[0].z && out[3] == fvecarray[0].w &&
+ out[4] == fvecarray[1].x && out[5] == fvecarray[1].y && out[6] == fvecarray[1].z && out[7] == fvecarray[1].w,
+ "The variable fvecarray was not set correctly, out={{%f, %f, %f, %f}, {%f, %f, %f, %f}}, should be "
+ "{{%f, %f, %f, %f}, {%f, %f, %f, %f}}\n", out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ fvecarray[0].x, fvecarray[0].y, fvecarray[0].z, fvecarray[0].w, fvecarray[1].x, fvecarray[1].y,
+ fvecarray[1].z, fvecarray[1].w);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
+ ok(out[0] == 0.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == 1.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
+ "The variable barray was not set correctly, out={%f, %f %f, %f; %f, %f, %f, %f}, should be {%f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 8);
+ /* Just check a few elements in each matrix to make sure fmtxarray was set row-major */
+ ok(out[0] == S(U(fmtxarray[0]))._11 && out[1] == S(U(fmtxarray[0]))._12 && out[2] == S(U(fmtxarray[0]))._13 && out[3] == S(U(fmtxarray[0]))._14,
+ "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], S(U(fmtxarray[0]))._11, S(U(fmtxarray[0]))._12, S(U(fmtxarray[0]))._13, S(U(fmtxarray[0]))._14);
+ ok(out[16] == S(U(fmtxarray[1]))._11 && out[17] == S(U(fmtxarray[1]))._12 && out[18] == S(U(fmtxarray[1]))._13 && out[19] == S(U(fmtxarray[1]))._14,
+ "The variable fmtxarray was not set row-major, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[16], out[17], out[18], out[19], S(U(fmtxarray[1]))._11, S(U(fmtxarray[1]))._12, S(U(fmtxarray[1]))._13, S(U(fmtxarray[1]))._14);
+
+ refcnt = ID3DXConstantTable_Release(ctable);
+ ok(refcnt == 0, "The constant table reference count was %u, should be 0\n", refcnt);
+}
+
+static void test_SetDefaults(IDirect3DDevice9 *device)
+{
+ static const D3DXMATRIX mvp = {{{
+ 0.51f, 0.62f, 0.80f, 0.78f,
+ 0.23f, 0.95f, 0.37f, 0.48f,
+ 0.10f, 0.58f, 0.90f, 0.25f,
+ 0.89f, 0.41f, 0.93f, 0.27f}}};
+ static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
+
+ float out[16];
+
+ HRESULT res;
+ ID3DXConstantTable *ctable;
+
+ res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetVector(ctable, device, "f4", &f4);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetVector failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetMatrix(ctable, device, "mvp", &mvp);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetMatrix failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetDefaults(ctable, device);
+ ok(res == D3D_OK, "ID3dXConstantTable_SetDefaults failed: got %08x\n", res);
+
+ /* SetDefaults doesn't change constants without default values */
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14,
+ "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
+ ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24,
+ "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
+ ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34,
+ "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
+ ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44,
+ "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(memcmp(out, &f4, sizeof(f4)) == 0,
+ "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
+
+ ID3DXConstantTable_Release(ctable);
+
+ res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetDefaults(ctable, device);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetDefaults failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(memcmp(out, mat4_default_value, sizeof(mat4_default_value)) == 0,
+ "The variable mat4 was not set correctly to default value\n");
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 4);
+ ok(memcmp(out, mat3_default_value, sizeof(mat3_default_value)) == 0,
+ "The variable mat3 was not set correctly to default value\n");
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
+ ok(memcmp(out, arr_default_value, sizeof(arr_default_value)) == 0,
+ "The variable array was not set correctly to default value\n");
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 11, out, 1);
+ ok(memcmp(out, vec4_default_value, sizeof(vec4_default_value)) == 0,
+ "The variable vec4 was not set correctly to default value\n");
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 1);
+ ok(memcmp(out, flt_default_value, sizeof(flt_default_value)) == 0,
+ "The variable flt was not set correctly to default value\n");
+
+ ID3DXConstantTable_Release(ctable);
+}
+
+static void test_SetValue(IDirect3DDevice9 *device)
+{
+ static const D3DXMATRIX mvp = {{{
+ 0.51f, 0.62f, 0.80f, 0.78f,
+ 0.23f, 0.95f, 0.37f, 0.48f,
+ 0.10f, 0.58f, 0.90f, 0.25f,
+ 0.89f, 0.41f, 0.93f, 0.27f}}};
+ static const D3DXVECTOR4 f4 = {0.2f, 0.4f, 0.8f, 1.2f};
+ static const FLOAT arr[] = {0.33f, 0.55f, 0.96f, 1.00f,
+ 1.00f, 1.00f, 1.00f, 1.00f,
+ 1.00f, 1.00f, 1.00f, 1.00f};
+ static int imatrix[] = {1, 2, 3, 4, 5, 6};
+ static float fmatrix[] = {1.1f, 2.2f, 3.3f, 4.4f};
+ static BOOL barray[] = {TRUE, FALSE};
+ static float fvecarray[] = {9.1f, 9.2f, 9.3f, 9.4f, 9.5f, 9.6f, 9.7f, 9.8f};
+ static float farray[] = {2.2f, 3.3f};
+
+ static const float def[16] = {5.5f, 5.5f, 5.5f, 5.5f,
+ 5.5f, 5.5f, 5.5f, 5.5f,
+ 5.5f, 5.5f, 5.5f, 5.5f,
+ 5.5f, 5.5f, 5.5f, 5.5f};
+ float out[16];
+
+ HRESULT res;
+ ID3DXConstantTable *ctable;
+
+ res = D3DXGetShaderConstantTable(ctab_basic, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 7, def, 1);
+
+ /* SetValue called with 0 bytes size doesn't change value */
+ res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, 0);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(memcmp(out, def, sizeof(f4)) == 0,
+ "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], def[0], def[1], def[2], def[3]);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "f4", &f4, sizeof(f4));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 1);
+ ok(memcmp(out, &f4, sizeof(f4)) == 0,
+ "The variable f4 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], f4.x, f4.y, f4.z, f4.w);
+
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 0, def, 4);
+
+ /* SetValue called with size smaller than constant size doesn't change value */
+ res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp) / 2);
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue returned %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(memcmp(out, def, sizeof(def)) == 0,
+ "The variable mvp was not set correctly, out={%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[4], out[ 8], out[12],
+ out[1], out[5], out[ 9], out[13],
+ out[2], out[6], out[10], out[14],
+ out[3], out[7], out[11], out[15],
+ def[0], def[4], def[ 8], def[12],
+ def[1], def[5], def[ 9], def[13],
+ def[2], def[6], def[10], def[14],
+ def[3], def[7], def[11], def[15]);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "mvp", &mvp, sizeof(mvp));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 0, out, 4);
+ ok(out[0] == S(U(mvp))._11 && out[4] == S(U(mvp))._12 && out[8] == S(U(mvp))._13 && out[12] == S(U(mvp))._14,
+ "The first row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[4], out[8], out[12], S(U(mvp))._11, S(U(mvp))._12, S(U(mvp))._13, S(U(mvp))._14);
+ ok(out[1] == S(U(mvp))._21 && out[5] == S(U(mvp))._22 && out[9] == S(U(mvp))._23 && out[13] == S(U(mvp))._24,
+ "The second row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[1], out[5], out[9], out[13], S(U(mvp))._21, S(U(mvp))._22, S(U(mvp))._23, S(U(mvp))._24);
+ ok(out[2] == S(U(mvp))._31 && out[6] == S(U(mvp))._32 && out[10] == S(U(mvp))._33 && out[14] == S(U(mvp))._34,
+ "The third row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[2], out[6], out[10], out[14], S(U(mvp))._31, S(U(mvp))._32, S(U(mvp))._33, S(U(mvp))._34);
+ ok(out[3] == S(U(mvp))._41 && out[7] == S(U(mvp))._42 && out[11] == S(U(mvp))._43 && out[15] == S(U(mvp))._44,
+ "The fourth row of mvp was not set correctly, got {%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[3], out[7], out[11], out[15], S(U(mvp))._41, S(U(mvp))._42, S(U(mvp))._43, S(U(mvp))._44);
+
+ ID3DXConstantTable_Release(ctable);
+
+ res = D3DXGetShaderConstantTable(ctab_with_default_values, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "arr", arr, sizeof(arr));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 3);
+ ok(out[0] == arr[0] && out[4] == arr[1] && out[8] == arr[2]
+ && out[1] == 0 && out[2] == 0 && out[3] == 0 && out[5] == 0 && out[6] == 0 && out[7] == 0
+ && out[9] == 0 && out[10] == 0 && out[11] == 0,
+ "The variable arr was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f}, "
+ "should be {0.33, 0, 0, 0, 0.55, 0, 0, 0, 0.96, 0, 0, 0}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7], out[8], out[9], out[10], out[11]);
+
+ ID3DXConstantTable_Release(ctable);
+
+ res = D3DXGetShaderConstantTable(ctab_matrices, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "fmatrix3x1", fmatrix, sizeof(fmatrix));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "imatrix2x3", imatrix, sizeof(imatrix));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 4, out, 2);
+ ok(out[0] == imatrix[0] && out[1] == imatrix[1] && out[2] == imatrix[2] && out[3] == 0.0f
+ && out[4] == imatrix[3] && out[5] == imatrix[4] && out[6] == imatrix[5] && out[7] == 0.0f,
+ "The variable imatrix2x3 was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
+ "should be {%d, %d, %d, 0, %d, %d, %d, 0}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ imatrix[0], imatrix[1], imatrix[2], imatrix[3], imatrix[4], imatrix[5]);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 7, out, 2);
+ ok(out[0] == fmatrix[0] && out[1] == fmatrix[1] && out[2] == fmatrix[2] && out[3] == 0.0f,
+ "The variable fmatrix3x1 was not set correctly, out={%f, %f, %f, %f}, should be {%f, %f, %f, %f}\n",
+ out[0], out[1] ,out[2], out[4],
+ fmatrix[0], fmatrix[1], fmatrix[2], 0.0f);
+
+ ID3DXConstantTable_Release(ctable);
+
+ res = D3DXGetShaderConstantTable(ctab_arrays, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "barray", barray, sizeof(barray));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ res = ID3DXConstantTable_SetValue(ctable, device, "fvecarray", fvecarray, sizeof(fvecarray));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ IDirect3DDevice9_SetVertexShaderConstantF(device, 8, def, 4);
+ res = ID3DXConstantTable_SetValue(ctable, device, "farray", farray, sizeof(farray));
+ ok(res == D3D_OK, "ID3DXConstantTable_SetValue failed: got %08x\n", res);
+
+ /* 2 elements of farray were set */
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 8, out, 4);
+ ok(out[0] == farray[0] && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == farray[1] && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f
+ && out[8] == def[8] && out[9] == def[9] && out[10] == def[10] && out[11] == def[11]
+ && out[12] == def[12] && out[13] == def[13] && out[14] == def[14] && out[15] == def[15],
+ "The variable farray was not set correctly, should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ out[8], out[9], out[10], out[11], out[12], out[13], out[14], out[15],
+ farray[0], 0.0f, 0.0f, 0.0f,
+ farray[1], 0.0f, 0.0f, 0.0f,
+ def[8], def[9], def[10], def[11],
+ def[12], def[13], def[14], def[15]);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 12, out, 2);
+ ok(out[0] == fvecarray[0] && out[1] == fvecarray[1] && out[2] == fvecarray[2] && out[3] == fvecarray[3]
+ && out[4] == fvecarray[4] && out[5] == fvecarray[5] && out[6] == fvecarray[6] && out[7] == fvecarray[7],
+ "The variable fvecarray was not set correctly, out ={%f, %f, %f, %f, %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ fvecarray[0], fvecarray[1], fvecarray[2], fvecarray[3], fvecarray[4], fvecarray[5], fvecarray[6], fvecarray[7]);
+
+ IDirect3DDevice9_GetVertexShaderConstantF(device, 14, out, 2);
+ ok(out[0] == 1.0f && out[1] == 0.0f && out[2] == 0.0f && out[3] == 0.0f
+ && out[4] == 0.0f && out[5] == 0.0f && out[6] == 0.0f && out[7] == 0.0f,
+ "The variable barray was not set correctly, out={%f, %f, %f, %f, %f, %f, %f, %f}, "
+ "should be {%f, %f, %f, %f, %f, %f, %f, %f}\n",
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
+
+ ID3DXConstantTable_Release(ctable);
+}
+
+static void test_setting_constants(void)
+{
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+ ULONG refcnt;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ test_setting_basic_table(device);
+ test_setting_matrices_table(device);
+ test_setting_arrays_table(device);
+ test_SetDefaults(device);
+ test_SetValue(device);
+
+ /* Release resources */
+ refcnt = IDirect3DDevice9_Release(device);
+ ok(refcnt == 0, "The Direct3D device reference count was %u, should be 0\n", refcnt);
+
+ refcnt = IDirect3D9_Release(d3d);
+ ok(refcnt == 0, "The Direct3D object referenct count was %u, should be 0\n", refcnt);
+
+ if (wnd) DestroyWindow(wnd);
+}
+
+static void test_get_sampler_index(void)
+{
+ ID3DXConstantTable *ctable;
+
+ HRESULT res;
+ UINT index;
+
+ ULONG refcnt;
+
+ res = D3DXGetShaderConstantTable(ctab_samplers, &ctable);
+ ok(res == D3D_OK, "D3DXGetShaderConstantTable failed on ctab_samplers: got %08x\n", res);
+
+ index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler1");
+ ok(index == 0, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 0\n", index);
+
+ index = ID3DXConstantTable_GetSamplerIndex(ctable, "sampler2");
+ ok(index == 3, "ID3DXConstantTable_GetSamplerIndex returned wrong index: Got %d, expected 3\n", index);
+
+ index = ID3DXConstantTable_GetSamplerIndex(ctable, "nonexistent");
+ ok(index == -1, "ID3DXConstantTable_GetSamplerIndex found nonexistent sampler: Got %d\n",
+ index);
+
+ index = ID3DXConstantTable_GetSamplerIndex(ctable, "notsampler");
+ ok(index == -1, "ID3DXConstantTable_GetSamplerIndex succeeded on non-sampler constant: Got %d\n",
+ index);
+
+ refcnt = ID3DXConstantTable_Release(ctable);
+ ok(refcnt == 0, "The ID3DXConstantTable reference count was %u, should be 0\n", refcnt);
+}
+
+/*
+ * fxc.exe /Tps_3_0
+ */
+#if 0
+sampler s;
+sampler1D s1D;
+sampler2D s2D;
+sampler3D s3D;
+samplerCUBE scube;
+float4 init;
+float4 main(float3 tex : TEXCOORD0) : COLOR
+{
+ float4 tmp = init;
+ tmp = tmp + tex1D(s1D, tex.x);
+ tmp = tmp + tex1D(s1D, tex.y);
+ tmp = tmp + tex3D(s3D, tex.xyz);
+ tmp = tmp + tex1D(s, tex.x);
+ tmp = tmp + tex2D(s2D, tex.xy);
+ tmp = tmp + texCUBE(scube, tex.xyz);
+ return tmp;
+}
+#endif
+static const DWORD get_shader_samplers_blob[] =
+{
+ 0xffff0300, /* ps_3_0 */
+ 0x0054fffe, FCC_CTAB, /* CTAB comment */
+ 0x0000001c, 0x0000011b, 0xffff0300, 0x00000006, 0x0000001c, 0x00000100, /* Header */
+ 0x00000114,
+ 0x00000094, 0x00000002, 0x00000001, 0x0000009c, 0x00000000, /* Constant 1 desc (init) */
+ 0x000000ac, 0x00040003, 0x00000001, 0x000000b0, 0x00000000, /* Constant 2 desc (s) */
+ 0x000000c0, 0x00000003, 0x00000001, 0x000000c4, 0x00000000, /* Constant 3 desc (s1D) */
+ 0x000000d4, 0x00010003, 0x00000001, 0x000000d8, 0x00000000, /* Constant 4 desc (s2D) */
+ 0x000000e8, 0x00030003, 0x00000001, 0x000000ec, 0x00000000, /* Constant 5 desc (s3D) */
+ 0x000000fc, 0x00020003, 0x00000001, 0x00000104, 0x00000000, /* Constant 6 desc (scube) */
+ 0x74696e69, 0xababab00, /* Constant 1 name */
+ 0x00030001, 0x00040001, 0x00000001, 0x00000000, /* Constant 1 type desc */
+ 0xabab0073, /* Constant 2 name */
+ 0x000c0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 2 type desc */
+ 0x00443173, /* Constant 3 name */
+ 0x000b0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 3 type desc */
+ 0x00443273, /* Constant 4 name */
+ 0x000c0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 4 type desc */
+ 0x00443373, /* Constant 5 name */
+ 0x000d0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 5 type desc */
+ 0x62756373, 0xabab0065, /* Constant 6 name */
+ 0x000e0004, 0x00010001, 0x00000001, 0x00000000, /* Constant 6 type desc */
+ 0x335f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, /* Target/Creator name string */
+ 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+ 0x332e3235, 0x00313131,
+ 0x0200001f, 0x80000005, 0x90070000, 0x0200001f, 0x90000000, 0xa00f0800, /* shader */
+ 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x98000000, 0xa00f0802,
+ 0x0200001f, 0xa0000000, 0xa00f0803, 0x0200001f, 0x90000000, 0xa00f0804,
+ 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, 0x03000002, 0x800f0000,
+ 0x80e40000, 0xa0e40000, 0x03000042, 0x800f0001, 0x90550000, 0xa0e40800,
+ 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
+ 0x90e40000, 0xa0e40803, 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001,
+ 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40804, 0x03000002, 0x800f0000,
+ 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40801,
+ 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, 0x03000042, 0x800f0001,
+ 0x90e40000, 0xa0e40802, 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001,
+ 0x0000ffff, /* END */
+};
+
+static void test_get_shader_samplers(void)
+{
+ const char *samplers[16] = {NULL}; /* maximum number of sampler registers v/ps 3.0 = 16 */
+ const char *sampler_orig;
+ UINT count = 2;
+ HRESULT hr;
+
+if (0)
+{
+ /* crashes if bytecode is NULL */
+ hr = D3DXGetShaderSamplers(NULL, NULL, &count);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+}
+
+ hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+
+ samplers[5] = "dummy";
+
+ hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, NULL);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+
+ /* check that sampler points to shader blob */
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x2e];
+ ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x33];
+ ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x38];
+ ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x3d];
+ ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x42];
+ ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
+
+ ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
+
+ /* reset samplers */
+ memset(samplers, 0, sizeof(samplers));
+ samplers[5] = "dummy";
+
+ hr = D3DXGetShaderSamplers(get_shader_samplers_blob, NULL, &count);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+ ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
+
+ hr = D3DXGetShaderSamplers(get_shader_samplers_blob, samplers, &count);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+ ok(count == 5, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 5);
+
+ /* check that sampler points to shader blob */
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x2e];
+ ok(sampler_orig == samplers[0], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[0], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x33];
+ ok(sampler_orig == samplers[1], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[1], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x38];
+ ok(sampler_orig == samplers[2], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[2], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x3d];
+ ok(sampler_orig == samplers[3], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[3], sampler_orig);
+
+ sampler_orig = (const char *)&get_shader_samplers_blob[0x42];
+ ok(sampler_orig == samplers[4], "D3DXGetShaderSamplers failed, got %p, expected %p\n", samplers[4], sampler_orig);
+
+ ok(!strcmp(samplers[5], "dummy"), "D3DXGetShaderSamplers failed, got \"%s\", expected \"%s\"\n", samplers[5], "dummy");
+
+ /* check without ctab */
+ hr = D3DXGetShaderSamplers(simple_vs, samplers, &count);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+ ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
+
+ /* check invalid ctab */
+ hr = D3DXGetShaderSamplers(shader_with_invalid_ctab, samplers, &count);
+ ok(hr == D3D_OK, "D3DXGetShaderSamplers failed, got %x, expected %x\n", hr, D3D_OK);
+ ok(count == 0, "D3DXGetShaderSamplers failed, got %u, expected %u\n", count, 0);
+}
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+float f = {1.1f}, f_2[2] = {2.1f, 2.2f};
+struct {float f; int i;} s = {3.1f, 31},
+s_2[2] = {{4.1f, 41}, {4.2f, 42}},
+s_3[3] = {{5.1f, 51}, {5.2f, 52}, {5.3f, 53}};
+struct {int i1; int i2; float2 f_2; row_major float3x1 r[2];}
+p[2] = {{11, 12, {13.1, 14.1}, {{3.11, 3.21, 3.31}, {3.41, 3.51, 3.61}}},
+ {15, 16, {17.1, 18.1}, {{4.11, 4.21, 4.31}, {4.41, 4.51, 4.61}}}};
+int i[1] = {6};
+float2x3 f23[2] = {{0.11, 0.21, 0.31, 0.41, 0.51, 0.61}, {0.12, 0.22, 0.32, 0.42, 0.52, 0.62}};
+float3x2 f32[2] = {{1.11, 1.21, 1.31, 1.41, 1.51, 1.61}, {1.12, 1.22, 1.32, 1.42, 1.52, 1.62}};
+float3 v[2] = {{2.11, 2.21, 2.31}, {2.41, 2.51, 2.61}};
+row_major float3x1 r31[2] = {{3.11, 3.21, 3.31}, {3.41, 3.51, 3.61}};
+row_major float1x3 r13[2] = {{4.11, 4.21, 4.31}, {4.41, 4.51, 4.61}};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0.0f;
+ tmp.zyw = v[1] + r13[1] + r31[1] + p[1].r[1];
+ tmp.x += f * f_2[1] * pos.x * p[1].f_2.y;
+ tmp.y += s.f * pos.y * s_2[0].i;
+ tmp.z += s_3[0].f * pos.z * s_3[2].f * i[0] * f23[1]._11 * f32[1]._32;
+ return tmp;
+}
+#endif
+static const DWORD test_get_shader_constant_variables_blob[] =
+{
+0xfffe0300, 0x0185fffe, 0x42415443, 0x0000001c, 0x000005df, 0xfffe0300, 0x0000000c, 0x0000001c,
+0x00000100, 0x000005d8, 0x0000010c, 0x002d0002, 0x00000001, 0x00000110, 0x00000120, 0x00000130,
+0x001d0002, 0x00000004, 0x00000134, 0x00000144, 0x000001a4, 0x00210002, 0x00000004, 0x000001a8,
+0x000001b8, 0x000001f8, 0x00250002, 0x00000002, 0x000001fc, 0x0000020c, 0x0000022c, 0x002f0002,
+0x00000001, 0x00000230, 0x00000240, 0x00000250, 0x00000002, 0x00000012, 0x000002b0, 0x000002c0,
+0x000003e0, 0x002b0002, 0x00000002, 0x000003e4, 0x000003f4, 0x00000414, 0x00120002, 0x00000006,
+0x00000418, 0x00000428, 0x00000488, 0x002e0002, 0x00000001, 0x000004ac, 0x000004bc, 0x000004dc,
+0x00270002, 0x00000002, 0x000004e0, 0x000004f0, 0x00000530, 0x00180002, 0x00000005, 0x00000534,
+0x00000544, 0x000005a4, 0x00290002, 0x00000002, 0x000005a8, 0x000005b8, 0xabab0066, 0x00030000,
+0x00010001, 0x00000001, 0x00000000, 0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000, 0x00333266,
+0x00030003, 0x00030002, 0x00000002, 0x00000000, 0x3de147ae, 0x3ed1eb85, 0x00000000, 0x00000000,
+0x3e570a3d, 0x3f028f5c, 0x00000000, 0x00000000, 0x3e9eb852, 0x3f1c28f6, 0x00000000, 0x00000000,
+0x3df5c28f, 0x3ed70a3d, 0x00000000, 0x00000000, 0x3e6147ae, 0x3f051eb8, 0x00000000, 0x00000000,
+0x3ea3d70a, 0x3f1eb852, 0x00000000, 0x00000000, 0x00323366, 0x00030003, 0x00020003, 0x00000002,
+0x00000000, 0x3f8e147b, 0x3fa7ae14, 0x3fc147ae, 0x00000000, 0x3f9ae148, 0x3fb47ae1, 0x3fce147b,
+0x00000000, 0x3f8f5c29, 0x3fa8f5c3, 0x3fc28f5c, 0x00000000, 0x3f9c28f6, 0x3fb5c28f, 0x3fcf5c29,
+0x00000000, 0x00325f66, 0x00030000, 0x00010001, 0x00000002, 0x00000000, 0x40066666, 0x00000000,
+0x00000000, 0x00000000, 0x400ccccd, 0x00000000, 0x00000000, 0x00000000, 0xabab0069, 0x00020000,
+0x00010001, 0x00000001, 0x00000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x31690070,
+0xababab00, 0x00020000, 0x00010001, 0x00000001, 0x00000000, 0xab003269, 0x00030001, 0x00020001,
+0x00000001, 0x00000000, 0xabab0072, 0x00030002, 0x00010003, 0x00000002, 0x00000000, 0x00000252,
+0x00000258, 0x00000268, 0x00000258, 0x000001f8, 0x0000026c, 0x0000027c, 0x00000280, 0x00000005,
+0x000a0001, 0x00040002, 0x00000290, 0x41300000, 0x00000000, 0x00000000, 0x00000000, 0x41400000,
+0x00000000, 0x00000000, 0x00000000, 0x4151999a, 0x4161999a, 0x00000000, 0x00000000, 0x40470a3d,
+0x00000000, 0x00000000, 0x00000000, 0x404d70a4, 0x00000000, 0x00000000, 0x00000000, 0x4053d70a,
+0x00000000, 0x00000000, 0x00000000, 0x405a3d71, 0x00000000, 0x00000000, 0x00000000, 0x4060a3d7,
+0x00000000, 0x00000000, 0x00000000, 0x40670a3d, 0x00000000, 0x00000000, 0x00000000, 0x41700000,
+0x00000000, 0x00000000, 0x00000000, 0x41800000, 0x00000000, 0x00000000, 0x00000000, 0x4188cccd,
+0x4190cccd, 0x00000000, 0x00000000, 0x4083851f, 0x00000000, 0x00000000, 0x00000000, 0x4086b852,
+0x00000000, 0x00000000, 0x00000000, 0x4089eb85, 0x00000000, 0x00000000, 0x00000000, 0x408d1eb8,
+0x00000000, 0x00000000, 0x00000000, 0x409051ec, 0x00000000, 0x00000000, 0x00000000, 0x4093851f,
+0x00000000, 0x00000000, 0x00000000, 0x00333172, 0x00030002, 0x00030001, 0x00000002, 0x00000000,
+0x4083851f, 0x4086b852, 0x4089eb85, 0x00000000, 0x408d1eb8, 0x409051ec, 0x4093851f, 0x00000000,
+0x00313372, 0x00030002, 0x00010003, 0x00000002, 0x00000000, 0x40470a3d, 0x00000000, 0x00000000,
+0x00000000, 0x404d70a4, 0x00000000, 0x00000000, 0x00000000, 0x4053d70a, 0x00000000, 0x00000000,
+0x00000000, 0x405a3d71, 0x00000000, 0x00000000, 0x00000000, 0x4060a3d7, 0x00000000, 0x00000000,
+0x00000000, 0x40670a3d, 0x00000000, 0x00000000, 0x00000000, 0xabab0073, 0x00030000, 0x00010001,
+0x00000001, 0x00000000, 0x0000010c, 0x0000048c, 0x0000022c, 0x00000258, 0x00000005, 0x00020001,
+0x00020001, 0x0000049c, 0x40466666, 0x00000000, 0x00000000, 0x00000000, 0x41f80000, 0x00000000,
+0x00000000, 0x00000000, 0x00325f73, 0x00000005, 0x00020001, 0x00020002, 0x0000049c, 0x40833333,
+0x00000000, 0x00000000, 0x00000000, 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x40866666,
+0x00000000, 0x00000000, 0x00000000, 0x42280000, 0x00000000, 0x00000000, 0x00000000, 0x00335f73,
+0x00000005, 0x00020001, 0x00020003, 0x0000049c, 0x40a33333, 0x00000000, 0x00000000, 0x00000000,
+0x424c0000, 0x00000000, 0x00000000, 0x00000000, 0x40a66666, 0x00000000, 0x00000000, 0x00000000,
+0x42500000, 0x00000000, 0x00000000, 0x00000000, 0x40a9999a, 0x00000000, 0x00000000, 0x00000000,
+0x42540000, 0x00000000, 0x00000000, 0x00000000, 0xabab0076, 0x00030001, 0x00030001, 0x00000002,
+0x00000000, 0x40070a3d, 0x400d70a4, 0x4013d70a, 0x00000000, 0x401a3d71, 0x4020a3d7, 0x40270a3d,
+0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x0200001f,
+0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x02000001, 0x80070000, 0xa0e4002a,
+0x03000002, 0x80070000, 0x80e40000, 0xa0e4002c, 0x03000002, 0x80040000, 0x80aa0000, 0xa0000017,
+0x03000002, 0xe0080000, 0x80aa0000, 0xa0000011, 0x02000001, 0x80010001, 0xa000002d, 0x03000005,
+0x80040000, 0x80000001, 0xa0000026, 0x03000005, 0x80040000, 0x80aa0000, 0x90000000, 0x03000005,
+0xe0010000, 0x80aa0000, 0xa055000b, 0x03000002, 0x80020000, 0x80550000, 0xa0000016, 0x03000002,
+0x80010000, 0x80000000, 0xa0000015, 0x03000002, 0x80010000, 0x80000000, 0xa000000f, 0x03000002,
+0x80020000, 0x80550000, 0xa0000010, 0x03000005, 0x80040000, 0xa000002e, 0x90550000, 0x04000004,
+0xe0020000, 0x80aa0000, 0xa0000028, 0x80550000, 0x03000005, 0x80020000, 0xa0000018, 0x90aa0000,
+0x03000005, 0x80020000, 0x80550000, 0xa000001c, 0x03000005, 0x80020000, 0x80550000, 0xa000002f,
+0x03000005, 0x80020000, 0x80550000, 0xa0000020, 0x04000004, 0xe0040000, 0x80550000, 0xa0aa0024,
+0x80000000, 0x0000ffff,
+};
+
+const struct
+{
+ const char *fullname;
+ D3DXCONSTANT_DESC desc;
+ UINT ctaboffset;
+}
+test_get_shader_constant_variables_data[] =
+{
+ {"f", {"f", D3DXRS_FLOAT4, 45, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 72},
+ {"f23", {"f23", D3DXRS_FLOAT4, 29, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 2, 3, 2, 0, 48, NULL}, 81},
+ {"f23[0]", {"f23", D3DXRS_FLOAT4, 29, 3, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL}, 81},
+ {"f23[1]", {"f23", D3DXRS_FLOAT4, 32, 1, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 2, 3, 1, 0, 24, NULL}, 93},
+ {"f32", {"f32", D3DXRS_FLOAT4, 33, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 2, 0, 48, NULL}, 110},
+ {"f32[0]", {"f32", D3DXRS_FLOAT4, 33, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 110},
+ {"f32[1]", {"f32", D3DXRS_FLOAT4, 35, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 118},
+ {"f_2", {"f_2", D3DXRS_FLOAT4, 37, 2, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 2, 0, 8, NULL}, 131},
+ {"f_2[0]", {"f_2", D3DXRS_FLOAT4, 37, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 131},
+ {"f_2[1]", {"f_2", D3DXRS_FLOAT4, 38, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 135},
+ {"i", {"i", D3DXRS_FLOAT4, 47, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 144},
+ {"i[0]", {"i", D3DXRS_FLOAT4, 47, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 144},
+ {"p", {"p", D3DXRS_FLOAT4, 0, 18, D3DXPC_STRUCT, D3DXPT_VOID, 1, 10, 2, 4, 80, NULL}, 176},
+ {"p[0]", {"p", D3DXRS_FLOAT4, 0, 9, D3DXPC_STRUCT, D3DXPT_VOID, 1, 10, 1, 4, 40, NULL}, 176},
+ {"p[0].i1", {"i1", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 176},
+ {"p[0].i2", {"i2", D3DXRS_FLOAT4, 1, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 180},
+ {"p[0].f_2", {"f_2", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 2, 1, 0, 8, NULL}, 184},
+ {"p[0].r", {"r", D3DXRS_FLOAT4, 3, 6, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 2, 0, 24, NULL}, 188},
+ {"p[0].r[0]", {"r", D3DXRS_FLOAT4, 3, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 188},
+ {"p[0].r[1]", {"r", D3DXRS_FLOAT4, 6, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 200},
+ {"p[1]", {"p", D3DXRS_FLOAT4, 9, 9, D3DXPC_STRUCT, D3DXPT_VOID, 1, 10, 1, 4, 40, NULL}, 212},
+ {"p[1].i1", {"i1", D3DXRS_FLOAT4, 9, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 212},
+ {"p[1].i2", {"i2", D3DXRS_FLOAT4, 10, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 216},
+ {"p[1].f_2", {"f_2", D3DXRS_FLOAT4, 11, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 2, 1, 0, 8, NULL}, 220},
+ {"p[1].r", {"r", D3DXRS_FLOAT4, 12, 6, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 2, 0, 24, NULL}, 224},
+ {"p[1].r[0]", {"r", D3DXRS_FLOAT4, 12, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 224},
+ {"p[1].r[1]", {"r", D3DXRS_FLOAT4, 15, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 236},
+ {"r13", {"r13", D3DXRS_FLOAT4, 43, 2, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 3, 2, 0, 24, NULL}, 253},
+ {"r13[0]", {"r13", D3DXRS_FLOAT4, 43, 1, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 253},
+ {"r13[1]", {"r13", D3DXRS_FLOAT4, 44, 1, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 257},
+ {"r31", {"r31", D3DXRS_FLOAT4, 18, 6, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 2, 0, 24, NULL}, 266},
+ {"r31[0]", {"r31", D3DXRS_FLOAT4, 18, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 266},
+ {"r31[1]", {"r31", D3DXRS_FLOAT4, 21, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 1, 1, 0, 12, NULL}, 278},
+ {"s", {"s", D3DXRS_FLOAT4, 46, 1, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 303},
+ {"s.f", {"f", D3DXRS_FLOAT4, 46, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 303},
+ {"s.i", {"i", D3DXRS_FLOAT4, 47, 0, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 307},
+ {"s_2", {"s_2", D3DXRS_FLOAT4, 39, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 2, 2, 16, NULL}, 316},
+ {"s_2[0]", {"s_2", D3DXRS_FLOAT4, 39, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 316},
+ {"s_2[0].f", {"f", D3DXRS_FLOAT4, 39, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 316},
+ {"s_2[0].i", {"i", D3DXRS_FLOAT4, 40, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 320},
+ {"s_2[1]", {"s_2", D3DXRS_FLOAT4, 41, 0, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 324},
+ {"s_2[1].f", {"f", D3DXRS_FLOAT4, 41, 0, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 324},
+ {"s_2[1].i", {"i", D3DXRS_FLOAT4, 41, 0, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 328},
+ {"s_3", {"s_3", D3DXRS_FLOAT4, 24, 5, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 3, 2, 24, NULL}, 337},
+ {"s_3[0]", {"s_3", D3DXRS_FLOAT4, 24, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 337},
+ {"s_3[0].f", {"f", D3DXRS_FLOAT4, 24, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 337},
+ {"s_3[0].i", {"i", D3DXRS_FLOAT4, 25, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 341},
+ {"s_3[1]", {"s_3", D3DXRS_FLOAT4, 26, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 345},
+ {"s_3[1].f", {"f", D3DXRS_FLOAT4, 26, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 345},
+ {"s_3[1].i", {"i", D3DXRS_FLOAT4, 27, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 349},
+ {"s_3[2]", {"s_3", D3DXRS_FLOAT4, 28, 1, D3DXPC_STRUCT, D3DXPT_VOID, 1, 2, 1, 2, 8, NULL}, 353},
+ {"s_3[2].f", {"f", D3DXRS_FLOAT4, 28, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 353},
+ {"s_3[2].i", {"i", D3DXRS_FLOAT4, 29, 0, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 357},
+ {"v", {"v", D3DXRS_FLOAT4, 41, 2, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 2, 0, 24, NULL}, 366},
+ {"v[0]", {"v", D3DXRS_FLOAT4, 41, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 366},
+ {"v[1]", {"v", D3DXRS_FLOAT4, 42, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 370},
+};
+
+static void test_get_shader_constant_variables(void)
+{
+ ID3DXConstantTable *ctable;
+ HRESULT hr;
+ ULONG count;
+ UINT i;
+ UINT nr = 1;
+ D3DXHANDLE constant, element;
+ D3DXCONSTANT_DESC desc;
+ DWORD *ctab;
+
+ hr = D3DXGetShaderConstantTable(test_get_shader_constant_variables_blob, &ctable);
+ ok(hr == D3D_OK, "D3DXGetShaderConstantTable failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ ctab = ID3DXConstantTable_GetBufferPointer(ctable);
+ ok(ctab[0] == test_get_shader_constant_variables_blob[3], "ID3DXConstantTable_GetBufferPointer failed\n");
+
+ for (i = 0; i < ARRAY_SIZE(test_get_shader_constant_variables_data); ++i)
+ {
+ const char *fullname = test_get_shader_constant_variables_data[i].fullname;
+ const D3DXCONSTANT_DESC *expected_desc = &test_get_shader_constant_variables_data[i].desc;
+ UINT ctaboffset = test_get_shader_constant_variables_data[i].ctaboffset;
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, fullname);
+ ok(constant != NULL, "GetConstantByName \"%s\" failed\n", fullname);
+
+ hr = ID3DXConstantTable_GetConstantDesc(ctable, constant, &desc, &nr);
+ ok(hr == D3D_OK, "GetConstantDesc \"%s\" failed, got %08x, expected %08x\n", fullname, hr, D3D_OK);
+
+ ok(!strcmp(expected_desc->Name, desc.Name), "GetConstantDesc \"%s\" failed, got \"%s\", expected \"%s\"\n",
+ fullname, desc.Name, expected_desc->Name);
+ ok(expected_desc->RegisterSet == desc.RegisterSet, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.RegisterSet, expected_desc->RegisterSet);
+ ok(expected_desc->RegisterIndex == desc.RegisterIndex, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.RegisterIndex, expected_desc->RegisterIndex);
+ ok(expected_desc->RegisterCount == desc.RegisterCount, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.RegisterCount, expected_desc->RegisterCount);
+ ok(expected_desc->Class == desc.Class, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Class, expected_desc->Class);
+ ok(expected_desc->Type == desc.Type, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.Type, expected_desc->Type);
+ ok(expected_desc->Rows == desc.Rows, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.Rows, expected_desc->Rows);
+ ok(expected_desc->Columns == desc.Columns, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Columns, expected_desc->Columns);
+ ok(expected_desc->Elements == desc.Elements, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Elements, expected_desc->Elements);
+ ok(expected_desc->StructMembers == desc.StructMembers, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.StructMembers, expected_desc->StructMembers);
+ ok(expected_desc->Bytes == desc.Bytes, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Bytes, expected_desc->Bytes);
+ ok(ctaboffset == (DWORD *)desc.DefaultValue - ctab, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, (UINT)((DWORD *)desc.DefaultValue - ctab), ctaboffset);
+ }
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, NULL, 0);
+ ok(element == NULL, "GetConstantElement failed\n");
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "i");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "i[0]");
+ ok(constant == element, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "i", 0);
+ ok(element == constant, "GetConstantElement failed, got %p, expected %p\n", element, constant);
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstant(ctable, NULL, 0);
+ ok(element == constant, "GetConstant failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstant(ctable, "invalid", 0);
+ ok(element == NULL, "GetConstant failed\n");
+
+ element = ID3DXConstantTable_GetConstant(ctable, "f", 0);
+ ok(element == NULL, "GetConstant failed\n");
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f[0]");
+ ok(constant == element, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f[1]");
+ ok(NULL == element, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f[0][0]");
+ ok(constant == element, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f.");
+ ok(element == NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "f", 0);
+ ok(element == constant, "GetConstantElement failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "f", 1);
+ ok(element == NULL, "GetConstantElement failed\n");
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f_2[0]");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f_2");
+ ok(element != constant, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "f_2", 0);
+ ok(element == constant, "GetConstantElement failed, got %p, expected %p\n", element, constant);
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "f_2[1]");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "f_2", 1);
+ ok(element == constant, "GetConstantElement failed, got %p, expected %p\n", element, constant);
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "s_2[0].f");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstant(ctable, "s_2[0]", 0);
+ ok(element == constant, "GetConstant failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, "s_2[0]", "f");
+ ok(element == constant, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ element = ID3DXConstantTable_GetConstantByName(ctable, "s_2[0]", "invalid");
+ ok(element == NULL, "GetConstantByName failed\n");
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, "s_2[0]");
+ ok(constant != NULL, "GetConstantByName failed\n");
+
+ element = ID3DXConstantTable_GetConstantElement(ctable, "s_2[0]", 0);
+ ok(constant == element, "GetConstantByName failed, got %p, expected %p\n", element, constant);
+
+ count = ID3DXConstantTable_Release(ctable);
+ ok(count == 0, "Release failed, got %u, expected %u\n", count, 0);
+}
+
+#define REGISTER_OUTPUT_SIZE 48
+
+enum Type {SetFloat, SetInt, SetBool, SetIntArray, SetBoolArray, SetFloatArray, SetMatrix,
+ SetMatrixTranspose, SetMatrixArray, SetMatrixTransposeArray, SetVector, SetVectorArray,
+ SetValue, SetMatrixPointerArray, SetMatrixTransposePointerArray};
+
+struct registerset_test
+{
+ enum Type type;
+ UINT in_index;
+ UINT in_count_min;
+ UINT in_count_max;
+ UINT out_count;
+ DWORD out[REGISTER_OUTPUT_SIZE];
+};
+
+struct registerset_constants
+{
+ const char *fullname;
+ D3DXCONSTANT_DESC desc;
+ UINT ctaboffset;
+};
+
+static const DWORD registerset_test_input[][REGISTER_OUTPUT_SIZE] =
+{
+ /* float */
+ {0x40000123, 0x00000000, 0x40800123, 0x40a00123,
+ 0x40c00123, 0x40e00123, 0x41000123, 0x41100123,
+ 0x41200123, 0x41300123, 0x41400123, 0x41500123,
+ 0x41600123, 0x41700123, 0x41800123, 0x41900123,
+ 0x41a00123, 0x41b00123, 0x41c00123, 0x41d00123,
+ 0x00000000, 0x41f00123, 0x42000123, 0x42100123,
+ 0x00000000, 0x42300123, 0x42400123, 0x42500123,
+ 0x42600123, 0x42700123, 0x42800123, 0x42900123,
+ 0x43000123, 0x43100123, 0x43200123, 0x43300123,
+ 0x43400123, 0x43500123, 0x43600123, 0x43700123,
+ 0x43800123, 0x43900123, 0x43a00123, 0x43b00123,
+ 0x43c00123, 0x43d00123, 0x43e00123, 0x43f00123},
+ /* int */
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005,
+ 0x00000000, 0x00000007, 0x00000008, 0x00000009,
+ 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d,
+ 0x0000000e, 0x0000000f, 0x00000010, 0x00000011,
+ 0x00000012, 0x00000000, 0x00000000, 0x00000015,
+ 0x00000016, 0x00000017, 0x00000018, 0x00000019,
+ 0x0000001a, 0x0000001b, 0x0000001c, 0x0000001d,
+ 0x0000001e, 0x0000001f, 0x00000020, 0x00000021,
+ 0x00000022, 0x00000023, 0x00000024, 0x00000025,
+ 0x00000026, 0x00000027, 0x00000028, 0x00000029,
+ 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d,
+ 0x0000002e, 0x0000002f, 0x00000030, 0x00000031},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool b = 1;
+int n = 8;
+float f = 5.1;
+int nf = 11;
+bool bf = 1;
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (b) for (i = 0; i < n; i++) tmp.x += pos.z * f * nf;
+ else for (i = 0; i < n; i++) tmp.y += pos.y * f * bf;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_scalar[] =
+{
+0xfffe0300, 0x0051fffe, 0x42415443, 0x0000001c, 0x0000010f, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x00000108, 0x00000080, 0x00000000, 0x00000001, 0x00000084, 0x00000094, 0x00000098,
+0x00020002, 0x00000001, 0x00000084, 0x0000009c, 0x000000ac, 0x00000002, 0x00000001, 0x000000b0,
+0x000000c0, 0x000000d0, 0x00000001, 0x00000001, 0x000000d4, 0x000000e4, 0x000000f4, 0x00010002,
+0x00000001, 0x000000d4, 0x000000f8, 0xabab0062, 0x00010000, 0x00010001, 0x00000001, 0x00000000,
+0xffffffff, 0xab006662, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0xabab0066, 0x00030000,
+0x00010001, 0x00000001, 0x00000000, 0x40a33333, 0x00000000, 0x00000000, 0x00000000, 0xabab006e,
+0x00020000, 0x00010001, 0x00000001, 0x00000000, 0x00000008, 0x00000000, 0x00000001, 0x00000000,
+0xab00666e, 0x41300000, 0x00000000, 0x00000000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369,
+0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072,
+0x392e3932, 0x332e3235, 0x00313131, 0x05000051, 0xa00f0003, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028,
+0xe0e40800, 0x03000005, 0x80010000, 0xa0000000, 0x90aa0000, 0x02000001, 0x80010001, 0xa0000003,
+0x01000026, 0xf0e40000, 0x04000004, 0x80010001, 0x80000000, 0xa0000001, 0x80000001, 0x00000027,
+0x02000001, 0x80020001, 0xa0000003, 0x0000002a, 0x03000005, 0x80010000, 0xa0000000, 0x90550000,
+0x02000001, 0x80020001, 0xa0000003, 0x01000026, 0xf0e40000, 0x04000004, 0x80020001, 0x80000000,
+0xa0000002, 0x80550001, 0x00000027, 0x02000001, 0x80010001, 0xa0000003, 0x0000002b, 0x02000001,
+0xe0030000, 0x80e40001, 0x02000001, 0xe00c0000, 0xa0000003, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_scalar_float[] =
+{
+ {"f", {"f", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 48},
+};
+
+static const struct registerset_test registerset_test_scalar_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x40000123}},
+ {SetInt, 1, 0, 0, 4, {0x40000000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x40000000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, REGISTER_OUTPUT_SIZE, 4, {0x40000123}},
+ {SetValue, 0, 0, 3},
+ {SetValue, 0, 4, REGISTER_OUTPUT_SIZE * 4, 4, {0x40000123}},
+ {SetVector, 0, 0, 0, 4, {0x40000123}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x40000123}},
+ {SetMatrix, 0, 0, 0, 4, {0x40000123},},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x40000123},},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_int[] =
+{
+ {"n", {"n", D3DXRS_INT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 57},
+};
+
+static const struct registerset_test registerset_test_scalar_int[] =
+{
+ {SetFloat, 0, 0, 0, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetInt, 1, 0, 0, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetBool, 1, 0, 0, 4,
+ {0x00000001, 0x00000000, 0x00000001}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000001, 0x00000000, 0x00000001}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, REGISTER_OUTPUT_SIZE * 4, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetVector, 0, 0, 0, 4,
+ {0x00000002, 0x00000000, 0x00000001},},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000002, 0x00000000, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_int_float[] =
+{
+ {"nf", {"nf", D3DXRS_FLOAT4, 1, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 62},
+};
+
+static const struct registerset_test registerset_test_scalar_int_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x40000000}},
+ {SetInt, 1, 0, 0, 4, {0x40000000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x40000000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, REGISTER_OUTPUT_SIZE, 4, {0x40000000}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, REGISTER_OUTPUT_SIZE * 4, 4, {0x40000000}},
+ {SetVector, 0, 0, 0, 4, {0x40000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x40000000}},
+ {SetMatrix, 0, 0, 0, 4, {0x40000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x40000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_bool_float[] =
+{
+ {"bf", {"bf", D3DXRS_FLOAT4, 2, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 39},
+};
+
+static const struct registerset_test registerset_test_scalar_bool_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x3f800000}},
+ {SetInt, 1, 0, 0, 4, {0x3f800000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x3f800000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, REGISTER_OUTPUT_SIZE, 4, {0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, REGISTER_OUTPUT_SIZE, 4, {0x3f800000}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, REGISTER_OUTPUT_SIZE * 4, 4, {0x3f800000}},
+ {SetVector, 0, 0, 0, 4, {0x3f800000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x3f800000}},
+ {SetMatrix, 0, 0, 0, 4, {0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_bool[] =
+{
+ {"b", {"b", D3DXRS_BOOL, 0, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 37},
+};
+
+static const struct registerset_test registerset_test_scalar_bool[] =
+{
+ {SetFloat, 0, 0, 0, 1, {0x00000001}},
+ {SetInt, 1, 0, 0, 1, {0x00000001}},
+ {SetBool, 1, 0, 0, 1, {0x00000002}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, REGISTER_OUTPUT_SIZE, 1, {0x00000001}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, REGISTER_OUTPUT_SIZE, 1, {0x00000002}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, REGISTER_OUTPUT_SIZE, 1, {0x00000001}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, REGISTER_OUTPUT_SIZE * 4, 1, {0x00000002}},
+ {SetVector, 0, 0, 0, 1, {0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 1, {0x00000001}},
+ {SetMatrix, 0, 0, 0, 1, {0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 1, {0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 1, {0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 1, {0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 1, {0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 1, {0x00000001}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool ab[2] = {1, 0};
+int an[2] = {32, 33};
+float af[2] = {3.1, 3.2};
+int anf[2] = {14, 15};
+bool abf[2] = {1, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (ab[1]) for (i = 0; i < an[1]; i++) tmp.x += pos.z * af[0] * anf[1];
+ else for (i = 0; i < an[0]; i++) tmp.y += pos.y * af[1] * abf[1];
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_scalar_array[] =
+{
+0xfffe0300, 0x006afffe, 0x42415443, 0x0000001c, 0x00000173, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000016c, 0x00000080, 0x00000000, 0x00000002, 0x00000084, 0x00000094, 0x0000009c,
+0x00040002, 0x00000002, 0x000000a0, 0x000000b0, 0x000000d0, 0x00000002, 0x00000002, 0x000000d4,
+0x000000e4, 0x00000104, 0x00000001, 0x00000002, 0x00000108, 0x00000118, 0x00000138, 0x00020002,
+0x00000002, 0x0000013c, 0x0000014c, 0xab006261, 0x00010000, 0x00010001, 0x00000002, 0x00000000,
+0xffffffff, 0x00000000, 0x00666261, 0x00010000, 0x00010001, 0x00000002, 0x00000000, 0x3f800000,
+0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0xab006661,
+0x00030000, 0x00010001, 0x00000002, 0x00000000, 0x40466666, 0x00000000, 0x00000000, 0x00000000,
+0x404ccccd, 0x00000000, 0x00000000, 0x00000000, 0xab006e61, 0x00020000, 0x00010001, 0x00000002,
+0x00000000, 0x00000020, 0x00000000, 0x00000001, 0x00000000, 0x00000021, 0x00000000, 0x00000001,
+0x00000000, 0x00666e61, 0x00020000, 0x00010001, 0x00000002, 0x00000000, 0x41600000, 0x00000000,
+0x00000000, 0x00000000, 0x41700000, 0x00000000, 0x00000000, 0x00000000, 0x335f7376, 0x4d00305f,
+0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x05000051, 0xa00f0006, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000,
+0x01000028, 0xe0e40801, 0x03000005, 0x80010000, 0xa0000000, 0x90aa0000, 0x02000001, 0x80010001,
+0xa0000006, 0x01000026, 0xf0e40001, 0x04000004, 0x80010001, 0x80000000, 0xa0000003, 0x80000001,
+0x00000027, 0x02000001, 0x80020001, 0xa0000006, 0x0000002a, 0x03000005, 0x80010000, 0xa0000001,
+0x90550000, 0x02000001, 0x80020001, 0xa0000006, 0x01000026, 0xf0e40000, 0x04000004, 0x80020001,
+0x80000000, 0xa0000005, 0x80550001, 0x00000027, 0x02000001, 0x80010001, 0xa0000006, 0x0000002b,
+0x02000001, 0xe0030000, 0x80e40001, 0x02000001, 0xe00c0000, 0xa0000006, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_scalar_array_float[] =
+{
+ {"af", {"af", D3DXRS_FLOAT4, 0, 2, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 2, 0, 8, NULL}, 57},
+ {"af[0]", {"af", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 57},
+ {"af[1]", {"af", D3DXRS_FLOAT4, 1, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 61},
+};
+
+static const struct registerset_test registerset_test_scalar_array_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x40000123}},
+ {SetInt, 1, 0, 0, 4, {0x40000000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, 1, 4, {0x40000000}},
+ {SetIntArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, 1, 4, {0x3f800000}},
+ {SetBoolArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, 1, 4, {0x40000123}},
+ {SetFloatArray, 0, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetValue, 0, 0, 3},
+ {SetValue, 0, 4, 7, 4, {0x40000123}},
+ {SetValue, 0, 8, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_array_int[] =
+{
+ {"an", {"an", D3DXRS_INT4, 0, 2, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 2, 0, 8, NULL}, 70},
+ {"an[0]", {"an", D3DXRS_INT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 70},
+ {"an[1]", {"an", D3DXRS_INT4, 1, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 74},
+};
+
+static const struct registerset_test registerset_test_scalar_array_int[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x00000002, 0x00000000, 0x00000001}},
+ {SetInt, 1, 0, 0, 4, {0x00000002, 0x00000000, 0x00000001}},
+ {SetBool, 1, 0, 0, 4, {0x00000001, 0x00000000, 0x00000001}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, 1, 4, {0x00000002, 0x00000000, 0x00000001}},
+ {SetIntArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000001}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, 1, 4, {0x00000001, 0x00000000, 0x00000001}},
+ {SetBoolArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, 1, 4, {0x00000002, 0x00000000, 0x00000001}},
+ {SetFloatArray, 0, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, 7, 4, {0x00000002, 0x00000000, 0x00000001}},
+ {SetValue, 1, 8, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000001}},
+ {SetVector, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000000, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000000, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000000, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_array_bool[] =
+{
+ {"ab", {"ab", D3DXRS_BOOL, 0, 2, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 2, 0, 8, NULL}, 37},
+ {"ab[0]", {"ab", D3DXRS_BOOL, 0, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 37},
+ {"ab[1]", {"ab", D3DXRS_BOOL, 1, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 38},
+};
+
+static const struct registerset_test registerset_test_scalar_array_bool[] =
+{
+ {SetFloat, 0, 0, 0, 1, {0x00000001}},
+ {SetInt, 1, 0, 0, 1, {0x00000001}},
+ {SetBool, 1, 0, 0, 1, {0x00000002}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, 1, 1, {0x00000001}},
+ {SetIntArray, 1, 2, REGISTER_OUTPUT_SIZE, 2, {0x00000001, 0x00000001}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, 1, 1, {0x00000002}},
+ {SetBoolArray, 1, 2, REGISTER_OUTPUT_SIZE, 2, {0x00000002, 0x00000003}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, 1, 1, {0x00000001}},
+ {SetFloatArray, 0, 2, REGISTER_OUTPUT_SIZE, 2, {0x00000001, 0x00000000}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, 7, 1, {0x00000002}},
+ {SetValue, 1, 8, REGISTER_OUTPUT_SIZE * 4, 2, {0x00000002, 0x00000003}},
+ {SetVector, 0, 0, 0, 2, {0x00000001, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 2, {0x00000001, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 2, {0x00000001, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 2, {0x00000001, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 2, {0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 2, {0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 2, {0x00000001, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 2, {0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_array_bool_float[] =
+{
+ {"abf", {"abf", D3DXRS_FLOAT4, 4, 2, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 2, 0, 8, NULL}, 44},
+ {"abf[0]", {"abf", D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 44},
+ {"abf[1]", {"abf", D3DXRS_FLOAT4, 5, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 48},
+};
+
+static const struct registerset_test registerset_test_scalar_array_bool_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x3f800000}},
+ {SetInt, 1, 0, 0, 4, {0x3f800000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, 1, 4, {0x3f800000}},
+ {SetIntArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, 1, 4, {0x3f800000}},
+ {SetBoolArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, 1, 4, {0x3f800000}},
+ {SetFloatArray, 0, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, 7, 4, {0x3f800000}},
+ {SetValue, 1, 8, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetVectorArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+};
+
+static const struct registerset_constants registerset_constants_scalar_array_int_float[] =
+{
+ {"anf", {"anf", D3DXRS_FLOAT4, 2, 2, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 2, 0, 8, NULL}, 83},
+ {"anf[0]", {"anf", D3DXRS_FLOAT4, 2, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 83},
+ {"anf[1]", {"anf", D3DXRS_FLOAT4, 3, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 87},
+};
+
+static const struct registerset_test registerset_test_scalar_array_int_float[] =
+{
+ {SetFloat, 0, 0, 0, 4, {0x40000000}},
+ {SetInt, 1, 0, 0, 4, {0x40000000}},
+ {SetBool, 1, 0, 0, 4, {0x3f800000}},
+ {SetIntArray},
+ {SetIntArray, 1, 1, 1, 4, {0x40000000}},
+ {SetIntArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000}},
+ {SetBoolArray},
+ {SetBoolArray, 1, 1, 1, 4, {0x3f800000}},
+ {SetBoolArray, 1, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray},
+ {SetFloatArray, 0, 1, 1, 4, {0x40000000}},
+ {SetFloatArray, 0, 2, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetValue, 1, 0, 3},
+ {SetValue, 1, 4, 7, 4, {0x40000000}},
+ {SetValue, 1, 8, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool3 vb = {1, 0, 1};
+int3 vn = {7, 8, 9};
+float3 vf = {5.1, 5.2, 5.3};
+int3 vnf = {11, 85, 62};
+bool3 vbf = {1, 1, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (vb.z) for (i = 0; i < vn.z; i++) tmp.x += pos.z * vf.z * vnf.z;
+ else for (i = 0; i < vn.y; i++) tmp.y += pos.y * vf.y * vbf.z;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_vector[] =
+{
+0xfffe0300, 0x0053fffe, 0x42415443, 0x0000001c, 0x00000117, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x00000110, 0x00000080, 0x00000000, 0x00000003, 0x00000084, 0x00000094, 0x000000a0,
+0x00020002, 0x00000001, 0x00000084, 0x000000a4, 0x000000b4, 0x00000002, 0x00000001, 0x000000b8,
+0x000000c8, 0x000000d8, 0x00000001, 0x00000003, 0x000000dc, 0x000000ec, 0x000000fc, 0x00010002,
+0x00000001, 0x000000dc, 0x00000100, 0xab006276, 0x00010001, 0x00030001, 0x00000001, 0x00000000,
+0xffffffff, 0x00000000, 0xffffffff, 0x00666276, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+0xab006676, 0x00030001, 0x00030001, 0x00000001, 0x00000000, 0x40a33333, 0x40a66666, 0x40a9999a,
+0x00000000, 0xab006e76, 0x00020001, 0x00030001, 0x00000001, 0x00000000, 0x00000007, 0x00000008,
+0x00000009, 0x00000000, 0x00666e76, 0x41300000, 0x42aa0000, 0x42780000, 0x00000000, 0x335f7376,
+0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320,
+0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x05000051, 0xa00f0003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000,
+0xe00f0000, 0x01000028, 0xe0e40802, 0x03000005, 0x80010000, 0xa0aa0000, 0x90aa0000, 0x02000001,
+0x80010001, 0xa0000003, 0x01000026, 0xf0e40002, 0x04000004, 0x80010001, 0x80000000, 0xa0aa0001,
+0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa0000003, 0x0000002a, 0x03000005, 0x80010000,
+0xa0550000, 0x90550000, 0x02000001, 0x80020001, 0xa0000003, 0x01000026, 0xf0e40001, 0x04000004,
+0x80020001, 0x80000000, 0xa0aa0002, 0x80550001, 0x00000027, 0x02000001, 0x80010001, 0xa0000003,
+0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001, 0xe00c0000, 0xa0000003, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_vector_float[] =
+{
+ {"vf", {"vf", D3DXRS_FLOAT4, 0, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 50},
+};
+
+static const struct registerset_test registerset_test_vector_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, REGISTER_OUTPUT_SIZE, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetValue, 0, 0, 11},
+ {SetValue, 0, 12, REGISTER_OUTPUT_SIZE * 4, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetVector, 0, 0, 0, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetMatrix, 0, 0, 0, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x40000123, 0x40c00123, 0x41200123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123, 0x40c00123, 0x41200123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000123, 0x40c00123, 0x41200123}},
+};
+
+static const struct registerset_constants registerset_constants_vector_int[] =
+{
+ {"vn", {"vn", D3DXRS_INT4, 0, 3, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 59},
+};
+
+static const struct registerset_test registerset_test_vector_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x00000002, 0x00000003, 0x00000004}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x00000001, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, REGISTER_OUTPUT_SIZE, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, REGISTER_OUTPUT_SIZE * 4, 4, {0x00000002, 0x00000003, 0x00000004}},
+ {SetVector, 0, 0, 0, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetMatrix, 0, 0, 0, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x00000002, 0x00000006, 0x0000000a}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x00000002, 0x00000006, 0x0000000a}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x00000002, 0x00000006, 0x0000000a}},
+};
+
+static const struct registerset_constants registerset_constants_vector_bool[] =
+{
+ {"vb", {"vb", D3DXRS_BOOL, 0, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 37},
+};
+
+static const struct registerset_test registerset_test_vector_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, REGISTER_OUTPUT_SIZE, 3, {0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, REGISTER_OUTPUT_SIZE, 3, {0x00000002, 0x00000003, 0x00000004}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, REGISTER_OUTPUT_SIZE, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, REGISTER_OUTPUT_SIZE * 4, 3, {0x00000002, 0x00000003, 0x00000004}},
+ {SetVector, 0, 0, 0, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 3, {0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 3, {0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 3, {0x00000001, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_vector_bool_float[] =
+{
+ {"vbf", {"vbf", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 41},
+};
+
+static const struct registerset_test registerset_test_vector_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, REGISTER_OUTPUT_SIZE, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, REGISTER_OUTPUT_SIZE * 4, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetVector, 0, 0, 0, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+};
+
+static const struct registerset_constants registerset_constants_vector_int_float[] =
+{
+ {"vnf", {"vnf", D3DXRS_FLOAT4, 1, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 64},
+};
+
+static const struct registerset_test registerset_test_vector_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, REGISTER_OUTPUT_SIZE, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, REGISTER_OUTPUT_SIZE, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, REGISTER_OUTPUT_SIZE * 4, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetVector, 0, 0, 0, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetMatrix, 0, 0, 0, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetMatrixTranspose, 0, 0, 0, 4, {0x40000000, 0x40c00000, 0x41200000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000, 0x40c00000, 0x41200000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4, {0x40000000, 0x40c00000, 0x41200000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool3 vab[2] = {1, 0, 1, 1, 0, 1};
+int3 van[2] = {70, 80, 90, 100, 110, 120};
+float3 vaf[2] = {55.1, 55.2, 55.3, 55.4, 55.5, 55.6};
+int3 vanf[2] = {130, 140, 150, 160, 170, 180};
+bool3 vabf[2] = {1, 1, 1, 1, 1, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (vab[1].z) for (i = 0; i < van[1].z; i++) tmp.x += pos.z * vaf[1].z * vanf[1].z;
+ else for (i = 0; i < van[1].y; i++) tmp.y += pos.y * vaf[0].y * vabf[1].z;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_vector_array[] =
+{
+0xfffe0300, 0x0070fffe, 0x42415443, 0x0000001c, 0x0000018b, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x00000184, 0x00000080, 0x00000000, 0x00000006, 0x00000084, 0x00000094, 0x000000ac,
+0x00040002, 0x00000002, 0x000000b4, 0x000000c4, 0x000000e4, 0x00000002, 0x00000002, 0x000000e8,
+0x000000f8, 0x00000118, 0x00000001, 0x00000006, 0x0000011c, 0x0000012c, 0x0000014c, 0x00020002,
+0x00000002, 0x00000154, 0x00000164, 0x00626176, 0x00010001, 0x00030001, 0x00000002, 0x00000000,
+0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x66626176, 0xababab00,
+0x00010001, 0x00030001, 0x00000002, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00666176, 0x00030001, 0x00030001, 0x00000002,
+0x00000000, 0x425c6666, 0x425ccccd, 0x425d3333, 0x00000000, 0x425d999a, 0x425e0000, 0x425e6666,
+0x00000000, 0x006e6176, 0x00020001, 0x00030001, 0x00000002, 0x00000000, 0x00000046, 0x00000050,
+0x0000005a, 0x00000000, 0x00000064, 0x0000006e, 0x00000078, 0x00000000, 0x666e6176, 0xababab00,
+0x00020001, 0x00030001, 0x00000002, 0x00000000, 0x43020000, 0x430c0000, 0x43160000, 0x00000000,
+0x43200000, 0x432a0000, 0x43340000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
+0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+0x332e3235, 0x00313131, 0x05000051, 0xa00f0006, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e40805,
+0x03000005, 0x80010000, 0xa0aa0001, 0x90aa0000, 0x02000001, 0x80010001, 0xa0000006, 0x01000026,
+0xf0e40005, 0x04000004, 0x80010001, 0x80000000, 0xa0aa0003, 0x80000001, 0x00000027, 0x02000001,
+0x80020001, 0xa0000006, 0x0000002a, 0x03000005, 0x80010000, 0xa0550000, 0x90550000, 0x02000001,
+0x80020001, 0xa0000006, 0x01000026, 0xf0e40004, 0x04000004, 0x80020001, 0x80000000, 0xa0aa0005,
+0x80550001, 0x00000027, 0x02000001, 0x80010001, 0xa0000006, 0x0000002b, 0x02000001, 0xe0030000,
+0x80e40001, 0x02000001, 0xe00c0000, 0xa0000006, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_vector_array_float[] =
+{
+ {"vaf", {"vaf", D3DXRS_FLOAT4, 0, 2, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 2, 0, 24, NULL}, 62},
+ {"vaf[0]", {"vaf", D3DXRS_FLOAT4, 0, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 62},
+ {"vaf[1]", {"vaf", D3DXRS_FLOAT4, 1, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 66},
+};
+
+static const struct registerset_test registerset_test_vector_array_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, 5, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x40400000, 0x40800000, 0x00000000, 0x40a00000, 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, 5, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, 5, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40a00123, 0x40c00123, 0x40e00123}},
+ {SetValue, 0, 0, 11},
+ {SetValue, 0, 12, 23, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetValue, 0, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40a00123, 0x40c00123, 0x40e00123}},
+ {SetVector, 0, 0, 0, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 4, {0x40000123, 0x00000000, 0x40800123}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+};
+
+static const struct registerset_constants registerset_constants_vector_array_int[] =
+{
+ {"van", {"van", D3DXRS_INT4, 0, 6, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 2, 0, 24, NULL}, 75},
+ {"van[0]", {"van", D3DXRS_INT4, 0, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 75},
+ {"van[1]", {"van", D3DXRS_INT4, 1, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 79},
+};
+
+static const struct registerset_test registerset_test_vector_array_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, 5, 4, {0x00000002, 0x00000003, 0x00000004}},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000000, 0x00000005, 0x00000000, 0x00000007}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, 5, 4, {0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, 5, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000005, 0x00000006, 0x00000007}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, 23, 4, {0x00000002, 0x00000003, 0x00000004}},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000000, 0x00000005, 0x00000000, 0x00000007}},
+ {SetVector, 0, 0, 0, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetVectorArray, 0, 0, 0},
+ {SetVectorArray, 0, 1, 1, 4, {0x00000002, 0x00000000, 0x00000004}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+};
+
+static const struct registerset_constants registerset_constants_vector_array_bool[] =
+{
+ {"vab", {"vab", D3DXRS_BOOL, 0, 6, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 2, 0, 24, NULL}, 37},
+ {"vab[0]", {"vab", D3DXRS_BOOL, 0, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 37},
+ {"vab[1]", {"vab", D3DXRS_BOOL, 3, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 40},
+};
+
+static const struct registerset_test registerset_test_vector_array_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, 5, 3, {0x00000001, 0x00000001, 0x00000001}},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetBoolArray, 1, 0},
+ {SetBoolArray, 1, 3, 5, 3, {0x00000002, 0x00000003, 0x00000004}},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, 5, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, 23, 3, {0x00000002, 0x00000003, 0x00000004}},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetVector, 0, 0, 0, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 3, {0x00000001, 0x00000000, 0x00000001}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_vector_array_bool_float[] =
+{
+ {"vabf", {"vabf", D3DXRS_FLOAT4, 4, 2, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 2, 0, 24, NULL}, 49},
+ {"vabf[0]", {"vabf", D3DXRS_FLOAT4, 4, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 49},
+ {"vabf[1]", {"vabf", D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 53},
+};
+
+static const struct registerset_test registerset_test_vector_array_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, 5, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, 5, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 2},
+ {SetFloatArray, 0, 3, 5, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, 23, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetVector, 0, 0, 0, 4, {0x3f800000, 0x00000000, 0x3f800000},},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 4, {0x3f800000, 0x00000000, 0x3f800000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+};
+
+static const struct registerset_constants registerset_constants_vector_array_int_float[] =
+{
+ {"vanf", {"vanf", D3DXRS_FLOAT4, 2, 2, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 2, 0, 24, NULL}, 89},
+ {"vanf[0]", {"vanf", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 89},
+ {"vanf[1]", {"vanf", D3DXRS_FLOAT4, 3, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 93},
+};
+
+static const struct registerset_test registerset_test_vector_array_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 2},
+ {SetIntArray, 1, 3, 5, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x40400000, 0x40800000, 0x00000000, 0x40a00000, 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 2},
+ {SetBoolArray, 1, 3, 5, 4, {0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 2, 0, 2,},
+ {SetFloatArray, 0, 3, 5, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40a00000, 0x40c00000, 0x40e00000}},
+ {SetValue, 1, 0, 11},
+ {SetValue, 1, 12, 23, 4, {0x40000000, 0x40400000, 0x40800000}},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000000, 0x40400000, 0x40800000, 0x00000000, 0x40a00000, 0x00000000, 0x40e00000}},
+ {SetVector, 0, 0, 0, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 4, {0x40000000, 0x00000000, 0x40800000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool3x2 cb = {1, 0, 1, 1, 0, 1};
+int3x2 cn = {4, 5, 6, 7, 8, 9};
+float3x2 cf = {15.1, 15.2, 15.3, 15.4, 15.5, 15.6};
+bool3x2 cbf = {1, 1, 0, 1, 0, 1};
+int3x2 cnf = {30, 31, 33, 32, 34, 36};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (cb._32) for (i = 0; i < cn._31; i++) tmp.x += pos.z * cf._31 * cbf._32;
+ else for (i = 0; i < cn._32; i++) tmp.y += pos.y * cf._32 * cnf._32;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_column[] =
+{
+0xfffe0300, 0x0066fffe, 0x42415443, 0x0000001c, 0x00000163, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000015c, 0x00000080, 0x00000000, 0x00000006, 0x00000084, 0x00000094, 0x000000ac,
+0x00020002, 0x00000002, 0x00000084, 0x000000b0, 0x000000d0, 0x00000002, 0x00000002, 0x000000d4,
+0x000000e4, 0x00000104, 0x00000001, 0x00000006, 0x00000108, 0x00000118, 0x00000138, 0x00040002,
+0x00000002, 0x00000108, 0x0000013c, 0xab006263, 0x00010003, 0x00020003, 0x00000001, 0x00000000,
+0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00666263, 0x3f800000,
+0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0xab006663,
+0x00030003, 0x00020003, 0x00000001, 0x00000000, 0x4171999a, 0x4174cccd, 0x41780000, 0x00000000,
+0x41733333, 0x41766666, 0x4179999a, 0x00000000, 0xab006e63, 0x00020003, 0x00020003, 0x00000001,
+0x00000000, 0x00000004, 0x00000006, 0x00000008, 0x00000000, 0x00000005, 0x00000007, 0x00000009,
+0x00000000, 0x00666e63, 0x41f00000, 0x42040000, 0x42080000, 0x00000000, 0x41f80000, 0x42000000,
+0x42100000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f0006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e40805, 0x03000005, 0x80010000,
+0xa0aa0000, 0x90aa0000, 0x02000001, 0x80010001, 0xa0000006, 0x01000026, 0xf0e40004, 0x04000004,
+0x80010001, 0x80000000, 0xa0aa0003, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa0000006,
+0x0000002a, 0x03000005, 0x80010000, 0xa0aa0001, 0x90550000, 0x02000001, 0x80020001, 0xa0000006,
+0x01000026, 0xf0e40005, 0x04000004, 0x80020001, 0x80000000, 0xa0aa0005, 0x80550001, 0x00000027,
+0x02000001, 0x80010001, 0xa0000006, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001,
+0xe00c0000, 0xa0000006, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_column_float[] =
+{
+ {"cf", {"cf", D3DXRS_FLOAT4, 0, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 57},
+};
+
+static const struct registerset_test registerset_test_column_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 0, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+};
+
+static const struct registerset_constants registerset_constants_column_int[] =
+{
+ {"cn", {"cn", D3DXRS_INT4, 0, 6, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 70},
+};
+
+static const struct registerset_test registerset_test_column_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000004, 0x00000006, 0x00000000, 0x00000000, 0x00000005, 0x00000007}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+};
+
+static const struct registerset_constants registerset_constants_column_bool[] =
+{
+ {"cb", {"cb", D3DXRS_BOOL, 0, 6, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 37},
+};
+
+static const struct registerset_test registerset_test_column_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 6,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_column_int_float[] =
+{
+ {"cnf", {"cnf", D3DXRS_FLOAT4, 4, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 79},
+};
+
+static const struct registerset_test registerset_test_column_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x40800000, 0x40c00000, 0x00000000, 0x00000000, 0x40a00000, 0x40e00000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetValue, 0, 0, 23},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+};
+
+static const struct registerset_constants registerset_constants_column_bool_float[] =
+{
+ {"cbf", {"cbf", D3DXRS_FLOAT4, 2, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 44},
+};
+
+static const struct registerset_test registerset_test_column_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+bool3x2 cab[2] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1};
+int3x2 can[2] = {14, 15, 16, 71, 18, 19, 55, 63, 96, 96, 97, 13};
+float3x2 caf[2] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 1.2, 1.3, 1.4};
+bool3x2 cabf[2] = {1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1};
+int3x2 canf[2] = {300, 301, 303, 302, 304, 306, 350, 365, 654, 612, 326, 999};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (cab[1]._32) for (i = 0; i < can[1]._31; i++) tmp.x += pos.z * caf[1]._31 * cabf[1]._32;
+ else for (i = 0; i < can[1]._32; i++) tmp.y += pos.y * caf[1]._32 * canf[1]._32;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_column_array[] =
+{
+0xfffe0300, 0x0096fffe, 0x42415443, 0x0000001c, 0x00000223, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000021c, 0x00000080, 0x00000000, 0x0000000c, 0x00000084, 0x00000094, 0x000000c4,
+0x00040002, 0x00000004, 0x000000cc, 0x000000dc, 0x0000011c, 0x00000002, 0x00000004, 0x00000120,
+0x00000130, 0x00000170, 0x00000001, 0x0000000c, 0x00000174, 0x00000184, 0x000001c4, 0x00080002,
+0x00000004, 0x000001cc, 0x000001dc, 0x00626163, 0x00010003, 0x00020003, 0x00000002, 0x00000000,
+0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x66626163, 0xababab00, 0x00010003, 0x00020003,
+0x00000002, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
+0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
+0x3f800000, 0x00000000, 0x00666163, 0x00030003, 0x00020003, 0x00000002, 0x00000000, 0x3f8ccccd,
+0x40533333, 0x40b00000, 0x00000000, 0x400ccccd, 0x408ccccd, 0x40d33333, 0x00000000, 0x40f66666,
+0x411e6666, 0x3fa66666, 0x00000000, 0x410ccccd, 0x3f99999a, 0x3fb33333, 0x00000000, 0x006e6163,
+0x00020003, 0x00020003, 0x00000002, 0x00000000, 0x0000000e, 0x00000010, 0x00000012, 0x00000000,
+0x0000000f, 0x00000047, 0x00000013, 0x00000000, 0x00000037, 0x00000060, 0x00000061, 0x00000000,
+0x0000003f, 0x00000060, 0x0000000d, 0x00000000, 0x666e6163, 0xababab00, 0x00020003, 0x00020003,
+0x00000002, 0x00000000, 0x43960000, 0x43978000, 0x43980000, 0x00000000, 0x43968000, 0x43970000,
+0x43990000, 0x00000000, 0x43af0000, 0x44238000, 0x43a30000, 0x00000000, 0x43b68000, 0x44190000,
+0x4479c000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e4080b, 0x03000005, 0x80010000,
+0xa0aa0002, 0x90aa0000, 0x02000001, 0x80010001, 0xa000000c, 0x01000026, 0xf0e4000a, 0x04000004,
+0x80010001, 0x80000000, 0xa0aa0007, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa000000c,
+0x0000002a, 0x03000005, 0x80010000, 0xa0aa0003, 0x90550000, 0x02000001, 0x80020001, 0xa000000c,
+0x01000026, 0xf0e4000b, 0x04000004, 0x80020001, 0x80000000, 0xa0aa000b, 0x80550001, 0x00000027,
+0x02000001, 0x80010001, 0xa000000c, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001,
+0xe00c0000, 0xa000000c, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_column_array_float[] =
+{
+ {"caf", {"caf", D3DXRS_FLOAT4, 0, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 2, 0, 48, NULL}, 76},
+ {"caf[0]", {"caf", D3DXRS_FLOAT4, 0, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 76},
+ {"caf[1]", {"caf", D3DXRS_FLOAT4, 2, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 84},
+};
+
+static const struct registerset_test registerset_test_column_array_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000, 0x00000000,
+ 0x41000000, 0x41200000, 0x41400000, 0x00000000, 0x41100000, 0x41300000, 0x41500000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 8,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123, 0x00000000,
+ 0x41000123, 0x41200123, 0x41400123, 0x00000000, 0x41100123, 0x41300123, 0x41500123}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 0, 24, 47, 8,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123}},
+ {SetValue, 0, 48, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x40000123, 0x40800123, 0x40c00123, 0x00000000, 0x00000000, 0x40a00123, 0x40e00123, 0x00000000,
+ 0x41000123, 0x41200123, 0x41400123, 0x00000000, 0x41100123, 0x41300123, 0x41500123}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, 3, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetVectorArray, 0, 4, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x41600123, 0x41a00123, 0x00000000, 0x00000000, 0x41700123, 0x41b00123, 0x41f00123}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x41a00123, 0x00000000, 0x00000000, 0x00000000, 0x41b00123, 0x41f00123, 0x42300123}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41a00123, 0x41b00123, 0x41c00123, 0x00000000, 0x00000000, 0x41f00123, 0x42000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x41900123, 0x41d00123, 0x42100123, 0x00000000, 0x41a00123, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 8,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41900123, 0x41a00123, 0x41b00123, 0x00000000, 0x41d00123, 0x00000000, 0x41f00123}},
+};
+
+static const struct registerset_constants registerset_constants_column_array_int[] =
+{
+ {"can", {"can", D3DXRS_INT4, 0, 12, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 2, 0, 48, NULL}, 97},
+ {"can[0]", {"can", D3DXRS_INT4, 0, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 97},
+ {"can[1]", {"can", D3DXRS_INT4, 2, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 105},
+};
+
+static const struct registerset_test registerset_test_column_array_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 8,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007, 0x00000000,
+ 0x00000008, 0x0000000a, 0x0000000c, 0x00000000, 0x00000009, 0x0000000b, 0x0000000d}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 8,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 8,
+ {0x00000002, 0x00000004, 0x00000006, 0x00000000, 0x00000000, 0x00000005, 0x00000007}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000002, 0x00000004, 0x00000006, 0x00000000, 0x00000000, 0x00000005, 0x00000007, 0x00000000,
+ 0x00000008, 0x0000000a, 0x0000000c, 0x00000000, 0x00000009, 0x0000000b, 0x0000000d}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 8,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000000, 0x00000003, 0x00000005, 0x00000007, 0x00000000,
+ 0x00000008, 0x0000000a, 0x0000000c, 0x00000000, 0x00000009, 0x0000000b, 0x0000000d}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, 3, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetVectorArray, 0, 4, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b, 0x00000000,
+ 0x0000000e, 0x00000014, 0x00000000, 0x00000000, 0x0000000f, 0x00000016, 0x0000001e}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b, 0x00000000,
+ 0x00000014, 0x00000000, 0x00000000, 0x00000000, 0x00000016, 0x0000001e, 0x0000002c}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008, 0x00000000,
+ 0x00000014, 0x00000016, 0x00000018, 0x00000000, 0x00000000, 0x0000001e, 0x00000020}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 8,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000006, 0x0000000a, 0x00000000, 0x00000000, 0x00000007, 0x0000000b, 0x00000000,
+ 0x00000012, 0x0000001a, 0x00000024, 0x00000000, 0x00000014, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 8,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000004, 0x00000000, 0x00000006, 0x00000007, 0x00000008, 0x00000000,
+ 0x00000012, 0x00000014, 0x00000016, 0x00000000, 0x0000001a, 0x00000000, 0x0000001e}},
+};
+
+static const struct registerset_constants registerset_constants_column_array_bool[] =
+{
+ {"cab", {"cab", D3DXRS_BOOL, 0, 12, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 2, 0, 48, NULL}, 37},
+ {"cab[0]", {"cab", D3DXRS_BOOL, 0, 6, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 37},
+ {"cab[1]", {"cab", D3DXRS_BOOL, 6, 6, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 43},
+};
+
+static const struct registerset_test registerset_test_column_array_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 6,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007, 0x00000008, 0x0000000a,
+ 0x0000000c, 0x00000009, 0x0000000b, 0x0000000d}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 6,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x00000005, 0x00000007, 0x00000008, 0x0000000a,
+ 0x0000000c, 0x00000009, 0x0000000b, 0x0000000d}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, 3, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetVectorArray, 0, 4, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_column_array_int_float[] =
+{
+ {"canf", {"canf", D3DXRS_FLOAT4, 8, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 2, 0, 48, NULL}, 119},
+ {"canf[0]", {"canf", D3DXRS_FLOAT4, 8, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 119},
+ {"canf[1]", {"canf", D3DXRS_FLOAT4, 10, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 127},
+};
+
+static const struct registerset_test registerset_test_column_array_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000, 0x00000000,
+ 0x41000000, 0x41200000, 0x41400000, 0x00000000, 0x41100000, 0x41300000, 0x41500000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 8,
+ {0x40000000, 0x40800000, 0x40c00000, 0x00000000, 0x00000000, 0x40a00000, 0x40e00000}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x40800000, 0x40c00000, 0x00000000, 0x00000000, 0x40a00000, 0x40e00000, 0x00000000,
+ 0x41000000, 0x41200000, 0x41400000, 0x00000000, 0x41100000, 0x41300000, 0x41500000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 8,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x40000000, 0x40800000, 0x00000000, 0x00000000, 0x40400000, 0x40a00000, 0x40e00000, 0x00000000,
+ 0x41000000, 0x41200000, 0x41400000, 0x00000000, 0x41100000, 0x41300000, 0x41500000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},/*16*/
+ {SetVectorArray, 0, 2, 3, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetVectorArray, 0, 4, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000, 0x00000000,
+ 0x41600000, 0x41a00000, 0x00000000, 0x00000000, 0x41700000, 0x41b00000, 0x41f00000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000, 0x00000000,
+ 0x41a00000, 0x00000000, 0x00000000, 0x00000000, 0x41b00000, 0x41f00000, 0x42300000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000, 0x00000000,
+ 0x41a00000, 0x41b00000, 0x41c00000, 0x00000000, 0x00000000, 0x41f00000, 0x42000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 8,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000000, 0x40c00000, 0x41200000, 0x00000000, 0x00000000, 0x40e00000, 0x41300000, 0x00000000,
+ 0x41900000, 0x41d00000, 0x42100000, 0x00000000, 0x41a00000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 8,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000000, 0x00000000, 0x40800000, 0x00000000, 0x40c00000, 0x40e00000, 0x41000000, 0x00000000,
+ 0x41900000, 0x41a00000, 0x41b00000, 0x00000000, 0x41d00000, 0x00000000, 0x41f00000}},
+};
+
+static const struct registerset_constants registerset_constants_column_array_bool_float[] =
+{
+ {"cabf", {"cabf", D3DXRS_FLOAT4, 4, 4, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 2, 0, 48, NULL}, 55},
+ {"cabf[0]", {"cabf", D3DXRS_FLOAT4, 4, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 55},
+ {"cabf[1]", {"cabf", D3DXRS_FLOAT4, 6, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 63},
+};
+
+static const struct registerset_test registerset_test_column_array_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 8,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, 3, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetVectorArray, 0, 4, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 8,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 8,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+row_major bool3x2 rb = {1, 1, 0, 0, 1, 1};
+row_major int3x2 rn = {80, 81, 82, 83, 84, 85};
+row_major float3x2 rf = {95.1, 95.2, 95.3, 95.4, 95.5, 95.6};
+row_major bool3x2 rbf = {1, 1, 1, 1, 0, 1};
+row_major int3x2 rnf = {37, 13, 98, 54, 77, 36};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (rb._32) for (i = 0; i < rn._31; i++) tmp.x += pos.z * rf._31 * rbf._32;
+ else for (i = 0; i < rn._32; i++) tmp.y += pos.y * rf._32 * rnf._32;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_row[] =
+{
+0xfffe0300, 0x0076fffe, 0x42415443, 0x0000001c, 0x000001a3, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000019c, 0x00000080, 0x00000000, 0x00000006, 0x00000084, 0x00000094, 0x000000ac,
+0x00030002, 0x00000003, 0x00000084, 0x000000b0, 0x000000e0, 0x00000002, 0x00000003, 0x000000e4,
+0x000000f4, 0x00000124, 0x00000001, 0x00000006, 0x00000128, 0x00000138, 0x00000168, 0x00060002,
+0x00000003, 0x00000128, 0x0000016c, 0xab006272, 0x00010002, 0x00020003, 0x00000001, 0x00000000,
+0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00666272, 0x3f800000,
+0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+0x3f800000, 0x00000000, 0x00000000, 0xab006672, 0x00030002, 0x00020003, 0x00000001, 0x00000000,
+0x42be3333, 0x42be6666, 0x00000000, 0x00000000, 0x42be999a, 0x42becccd, 0x00000000, 0x00000000,
+0x42bf0000, 0x42bf3333, 0x00000000, 0x00000000, 0xab006e72, 0x00020002, 0x00020003, 0x00000001,
+0x00000000, 0x00000050, 0x00000051, 0x00000001, 0x00000000, 0x00000052, 0x00000053, 0x00000001,
+0x00000000, 0x00000054, 0x00000055, 0x00000001, 0x00000000, 0x00666e72, 0x42140000, 0x41500000,
+0x00000000, 0x00000000, 0x42c40000, 0x42580000, 0x00000000, 0x00000000, 0x429a0000, 0x42100000,
+0x00000000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f0009, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e40805, 0x03000005, 0x80010000,
+0xa0000002, 0x90aa0000, 0x02000001, 0x80010001, 0xa0000009, 0x01000026, 0xf0e40004, 0x04000004,
+0x80010001, 0x80000000, 0xa0550005, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa0000009,
+0x0000002a, 0x03000005, 0x80010000, 0xa0550002, 0x90550000, 0x02000001, 0x80020001, 0xa0000009,
+0x01000026, 0xf0e40005, 0x04000004, 0x80020001, 0x80000000, 0xa0550008, 0x80550001, 0x00000027,
+0x02000001, 0x80010001, 0xa0000009, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001,
+0xe00c0000, 0xa0000009, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_row_float[] =
+{
+ {"rf", {"rf", D3DXRS_FLOAT4, 0, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 61},
+};
+
+static const struct registerset_test registerset_test_row_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 0, 24, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+};
+
+static const struct registerset_constants registerset_constants_row_int[] =
+{
+ {"rn", {"rn", D3DXRS_INT4, 0, 6, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 78},
+};
+
+static const struct registerset_test registerset_test_row_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000006, 0x00000007, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_row_bool[] =
+{
+ {"rb", {"rb", D3DXRS_BOOL, 0, 6, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 37},
+};
+
+static const struct registerset_test registerset_test_row_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 0, 0, 5,},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetBoolArray, 0, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, REGISTER_OUTPUT_SIZE / 4, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001},},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_row_int_float[] =
+{
+ {"rnf", {"rnf", D3DXRS_FLOAT4, 6, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 91},
+};
+
+static const struct registerset_test registerset_test_row_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x40c00000, 0x40e00000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+};
+
+static const struct registerset_constants registerset_constants_row_bool_float[] =
+{
+ {"rbf", {"rbf", D3DXRS_FLOAT4, 3, 3, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 44},
+};
+
+static const struct registerset_test registerset_test_row_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+row_major bool3x2 rab[2] = {1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1};
+row_major int3x2 ran[2] = {4, 5, 6, 1, 8, 1, 5, 3, 9, 6, 7, 3};
+row_major float3x2 raf[2] = {1.5, 2.8, 3.3, 4.9, 5.9, 6.8, 7.9, 8.5, 9.4, 1.3, 1.2, 1.1};
+row_major bool3x2 rabf[2] = {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1};
+row_major int3x2 ranf[2] = {35, 40, 60, 80, 70, 56, 37, 13, 98, 54, 77, 36};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (rab[1]._32) for (i = 0; i < ran[1]._31; i++) tmp.x += pos.z * raf[1]._31 * rabf[1]._32;
+ else for (i = 0; i < ran[1]._32; i++) tmp.y += pos.y * raf[1]._32 * ranf[1]._32;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_row_array[] =
+{
+0xfffe0300, 0x00b6fffe, 0x42415443, 0x0000001c, 0x000002a3, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000029c, 0x00000080, 0x00000000, 0x0000000c, 0x00000084, 0x00000094, 0x000000c4,
+0x00060002, 0x00000006, 0x000000cc, 0x000000dc, 0x0000013c, 0x00000002, 0x00000006, 0x00000140,
+0x00000150, 0x000001b0, 0x00000001, 0x0000000c, 0x000001b4, 0x000001c4, 0x00000224, 0x000c0002,
+0x00000006, 0x0000022c, 0x0000023c, 0x00626172, 0x00010002, 0x00020003, 0x00000002, 0x00000000,
+0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x66626172, 0xababab00, 0x00010002, 0x00020003,
+0x00000002, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
+0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
+0x00000000, 0x00000000, 0x00666172, 0x00030002, 0x00020003, 0x00000002, 0x00000000, 0x3fc00000,
+0x40333333, 0x00000000, 0x00000000, 0x40533333, 0x409ccccd, 0x00000000, 0x00000000, 0x40bccccd,
+0x40d9999a, 0x00000000, 0x00000000, 0x40fccccd, 0x41080000, 0x00000000, 0x00000000, 0x41166666,
+0x3fa66666, 0x00000000, 0x00000000, 0x3f99999a, 0x3f8ccccd, 0x00000000, 0x00000000, 0x006e6172,
+0x00020002, 0x00020003, 0x00000002, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+0x00000006, 0x00000001, 0x00000001, 0x00000000, 0x00000008, 0x00000001, 0x00000001, 0x00000000,
+0x00000005, 0x00000003, 0x00000001, 0x00000000, 0x00000009, 0x00000006, 0x00000001, 0x00000000,
+0x00000007, 0x00000003, 0x00000001, 0x00000000, 0x666e6172, 0xababab00, 0x00020002, 0x00020003,
+0x00000002, 0x00000000, 0x420c0000, 0x42200000, 0x00000000, 0x00000000, 0x42700000, 0x42a00000,
+0x00000000, 0x00000000, 0x428c0000, 0x42600000, 0x00000000, 0x00000000, 0x42140000, 0x41500000,
+0x00000000, 0x00000000, 0x42c40000, 0x42580000, 0x00000000, 0x00000000, 0x429a0000, 0x42100000,
+0x00000000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f0012, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e4080b, 0x03000005, 0x80010000,
+0xa0000005, 0x90aa0000, 0x02000001, 0x80010001, 0xa0000012, 0x01000026, 0xf0e4000a, 0x04000004,
+0x80010001, 0x80000000, 0xa055000b, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa0000012,
+0x0000002a, 0x03000005, 0x80010000, 0xa0550005, 0x90550000, 0x02000001, 0x80020001, 0xa0000012,
+0x01000026, 0xf0e4000b, 0x04000004, 0x80020001, 0x80000000, 0xa0550011, 0x80550001, 0x00000027,
+0x02000001, 0x80010001, 0xa0000012, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001,
+0xe00c0000, 0xa0000012, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_row_array_float[] =
+{
+ {"raf", {"raf", D3DXRS_FLOAT4, 0, 6, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 2, 0, 48, NULL}, 84},
+ {"raf[0]", {"raf", D3DXRS_FLOAT4, 0, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 84},
+ {"raf[1]", {"raf", D3DXRS_FLOAT4, 3, 3, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 3, 2, 1, 0, 24, NULL}, 96},
+};
+
+static const struct registerset_test registerset_test_row_array_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000, 0x00000000, 0x00000000, 0x41000000, 0x41100000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41400000, 0x41500000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123, 0x00000000, 0x00000000, 0x41000123, 0x41100123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123, 0x00000000, 0x00000000, 0x41400123, 0x41500123}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 0, 24, 47, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123}},
+ {SetValue, 0, 48, REGISTER_OUTPUT_SIZE * 4, 24,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000, 0x00000000,
+ 0x40c00123, 0x40e00123, 0x00000000, 0x00000000, 0x41000123, 0x41100123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123, 0x00000000, 0x00000000, 0x41400123, 0x41500123}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, 5, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetVectorArray, 0, 6, REGISTER_OUTPUT_SIZE / 4, 24,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123, 0x00000000, 0x00000000, 0x41600123, 0x41700123, 0x00000000, 0x00000000,
+ 0x41a00123, 0x41b00123, 0x00000000, 0x00000000, 0x00000000, 0x41f00123}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123, 0x00000000, 0x00000000, 0x41a00123, 0x41b00123, 0x00000000, 0x00000000,
+ 0x00000000, 0x41f00123, 0x00000000, 0x00000000, 0x00000000, 0x42300123}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123, 0x00000000, 0x00000000, 0x41a00123, 0x00000000, 0x00000000, 0x00000000,
+ 0x41b00123, 0x41f00123, 0x00000000, 0x00000000, 0x41c00123, 0x42000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 12,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x40c00123, 0x40e00123, 0x00000000, 0x00000000,
+ 0x41200123, 0x41300123, 0x00000000, 0x00000000, 0x41900123, 0x41a00123, 0x00000000, 0x00000000,
+ 0x41d00123, 0x00000000, 0x00000000, 0x00000000, 0x42100123, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 12,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000123, 0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x00000000, 0x00000000,
+ 0x40800123, 0x41000123, 0x00000000, 0x00000000, 0x41900123, 0x41d00123, 0x00000000, 0x00000000,
+ 0x41a00123, 0x00000000, 0x00000000, 0x00000000, 0x41b00123, 0x41f00123}},
+};
+
+static const struct registerset_constants registerset_constants_row_array_int[] =
+{
+ {"ran", {"ran", D3DXRS_INT4, 0, 12, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 2, 0, 48, NULL}, 113},
+ {"ran[0]", {"ran", D3DXRS_INT4, 0, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 113},
+ {"ran[1]", {"ran", D3DXRS_INT4, 3, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 125},
+};
+
+static const struct registerset_test registerset_test_row_array_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 12,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x0000000c, 0x0000000d, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000006, 0x00000007, 0x00000001}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000006, 0x00000007, 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x0000000c, 0x0000000d, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 12,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 24,
+ {0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000007, 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x0000000c, 0x0000000d, 0x00000001}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, 5, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetVectorArray, 0, 6, REGISTER_OUTPUT_SIZE / 4, 24,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x0000000e, 0x0000000f, 0x00000001, 0x00000000,
+ 0x00000014, 0x00000016, 0x00000001, 0x00000000, 0x00000000, 0x0000001e, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x00000014, 0x00000016, 0x00000001, 0x00000000,
+ 0x00000000, 0x0000001e, 0x00000001, 0x00000000, 0x00000000, 0x0000002c, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001, 0x00000000, 0x00000014, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000016, 0x0000001e, 0x00000001, 0x00000000, 0x00000018, 0x00000020, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 12,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000006, 0x00000007, 0x00000001, 0x00000000,
+ 0x0000000a, 0x0000000b, 0x00000001, 0x00000000, 0x00000012, 0x00000014, 0x00000001, 0x00000000,
+ 0x0000001a, 0x00000000, 0x00000001, 0x00000000, 0x00000024, 0x00000000, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 12,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x00000002, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000008, 0x00000001, 0x00000000, 0x00000012, 0x0000001a, 0x00000001, 0x00000000,
+ 0x00000014, 0x00000000, 0x00000001, 0x00000000, 0x00000016, 0x0000001e, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_row_array_bool[] =
+{
+ {"rab", {"rab", D3DXRS_BOOL, 0, 12, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 2, 0, 48, NULL}, 37},
+ {"rab[0]", {"rab", D3DXRS_BOOL, 0, 6, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 37},
+ {"rab[1]", {"rab", D3DXRS_BOOL, 6, 6, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 43},
+};
+
+static const struct registerset_test registerset_test_row_array_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5,},
+ {SetIntArray, 1, 6, 11, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007, 0x00000008, 0x00000009,
+ 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 12,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007, 0x00000008, 0x00000009,
+ 0x0000000a, 0x0000000b, 0x0000000c, 0x0000000d}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, 5, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetVectorArray, 0, 6, REGISTER_OUTPUT_SIZE / 4, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000000, 0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 6,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 12,
+ {0x00000001, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_row_array_int_float[] =
+{
+ {"ranf", {"ranf", D3DXRS_FLOAT4, 12, 6, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 2, 0, 48, NULL}, 143},
+ {"ranf[0]", {"ranf", D3DXRS_FLOAT4, 12, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 143},
+ {"ranf[1]", {"ranf", D3DXRS_FLOAT4, 15, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 155},
+};
+
+static const struct registerset_test registerset_test_row_array_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000,}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000, 0x00000000, 0x00000000, 0x41000000, 0x41100000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41400000, 0x41500000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x40c00000, 0x40e00000}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x40c00000, 0x40e00000, 0x00000000, 0x00000000, 0x41000000, 0x41100000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41400000, 0x41500000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 12,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 24,
+ {0x40000000, 0x40400000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x40e00000, 0x00000000, 0x00000000, 0x41000000, 0x41100000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41400000, 0x41500000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, 5, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetVectorArray, 0, 6, REGISTER_OUTPUT_SIZE / 4, 24,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41600000, 0x41700000, 0x00000000, 0x00000000,
+ 0x41a00000, 0x41b00000, 0x00000000, 0x00000000, 0x00000000, 0x41f00000}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41a00000, 0x41b00000, 0x00000000, 0x00000000,
+ 0x00000000, 0x41f00000, 0x00000000, 0x00000000, 0x00000000, 0x42300000}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000, 0x00000000, 0x00000000, 0x41a00000, 0x00000000, 0x00000000, 0x00000000,
+ 0x41b00000, 0x41f00000, 0x00000000, 0x00000000, 0x41c00000, 0x42000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 12,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40c00000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x41200000, 0x41300000, 0x00000000, 0x00000000, 0x41900000, 0x41a00000, 0x00000000, 0x00000000,
+ 0x41d00000, 0x00000000, 0x00000000, 0x00000000, 0x42100000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 12,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x40000000, 0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x00000000, 0x00000000,
+ 0x40800000, 0x41000000, 0x00000000, 0x00000000, 0x41900000, 0x41d00000, 0x00000000, 0x00000000,
+ 0x41a00000, 0x00000000, 0x00000000, 0x00000000, 0x41b00000, 0x41f00000}},
+};
+
+static const struct registerset_constants registerset_constants_row_array_bool_float[] =
+{
+ {"rabf", {"rabf", D3DXRS_FLOAT4, 6, 6, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 2, 0, 48, NULL}, 55},
+ {"rabf[0]", {"rabf", D3DXRS_FLOAT4, 6, 3, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 55},
+ {"rabf[1]", {"rabf", D3DXRS_FLOAT4, 9, 3, D3DXPC_MATRIX_ROWS, D3DXPT_BOOL, 3, 2, 1, 0, 24, NULL}, 67},
+};
+
+static const struct registerset_test registerset_test_row_array_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, 11, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetIntArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, 11, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, 11, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetFloatArray, 0, 12, REGISTER_OUTPUT_SIZE, 24,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, 47, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000}},
+ {SetValue, 1, 48, REGISTER_OUTPUT_SIZE * 4, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 2},
+ {SetVectorArray, 0, 3, 5, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetVectorArray, 0, 6, REGISTER_OUTPUT_SIZE / 4, 24,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposeArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 12,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixPointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 12,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000}},
+ {SetMatrixTransposePointerArray, 0, 2, REGISTER_OUTPUT_SIZE / 16, 24,
+ {0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+struct {bool b; bool3 vb;} sb = {1, 1, 0, 1};
+struct {int n; int3 vn;} sn = {11, 12, 13, 14};
+struct {float f; float3 vf;} sf = {1.1f, 2.2f, 3.3f, 4.4f};
+struct {int nf; int3 vnf;} snf = {31, 32, 33, 34};
+struct {bool bf; bool3 vbf;} sbf = {1, 0, 0, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (sb.vb.z) for (i = 0; i < sn.n; i++) tmp.x += pos.z * sf.vf.x * snf.vnf.z;
+ else for (i = 0; i < sn.vn.z; i++) tmp.y += pos.y * sf.vf.z * sbf.vbf.y;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_struct[] =
+{
+0xfffe0300, 0x00a2fffe, 0x42415443, 0x0000001c, 0x00000253, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x0000024c, 0x00000080, 0x00000000, 0x00000004, 0x000000bc, 0x000000cc, 0x000000dc,
+0x00040002, 0x00000002, 0x000000f8, 0x00000108, 0x00000128, 0x00000002, 0x00000002, 0x00000164,
+0x00000174, 0x00000194, 0x00000001, 0x00000004, 0x000001d0, 0x000001e0, 0x00000200, 0x00020002,
+0x00000002, 0x0000021c, 0x0000022c, 0x62006273, 0xababab00, 0x00010000, 0x00010001, 0x00000001,
+0x00000000, 0xab006276, 0x00010001, 0x00030001, 0x00000001, 0x00000000, 0x00000083, 0x00000088,
+0x00000098, 0x0000009c, 0x00000005, 0x00040001, 0x00020001, 0x000000ac, 0xffffffff, 0xffffffff,
+0x00000000, 0xffffffff, 0x00666273, 0x76006662, 0xab006662, 0x000000e0, 0x00000088, 0x000000e3,
+0x0000009c, 0x00000005, 0x00040001, 0x00020001, 0x000000e8, 0x3f800000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x66006673, 0xababab00, 0x00030000,
+0x00010001, 0x00000001, 0x00000000, 0xab006676, 0x00030001, 0x00030001, 0x00000001, 0x00000000,
+0x0000012b, 0x00000130, 0x00000140, 0x00000144, 0x00000005, 0x00040001, 0x00020001, 0x00000154,
+0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000, 0x400ccccd, 0x40533333, 0x408ccccd, 0x00000000,
+0x6e006e73, 0xababab00, 0x00020000, 0x00010001, 0x00000001, 0x00000000, 0xab006e76, 0x00020001,
+0x00030001, 0x00000001, 0x00000000, 0x00000197, 0x0000019c, 0x000001ac, 0x000001b0, 0x00000005,
+0x00040001, 0x00020001, 0x000001c0, 0x0000000b, 0x00000000, 0x00000001, 0x00000000, 0x0000000c,
+0x0000000d, 0x0000000e, 0x00000000, 0x00666e73, 0x7600666e, 0xab00666e, 0x00000204, 0x0000019c,
+0x00000207, 0x000001b0, 0x00000005, 0x00040001, 0x00020001, 0x0000020c, 0x41f80000, 0x00000000,
+0x00000000, 0x00000000, 0x42000000, 0x42040000, 0x42080000, 0x00000000, 0x335f7376, 0x4d00305f,
+0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970,
+0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x05000051, 0xa00f0006, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000,
+0x01000028, 0xe0e40803, 0x03000005, 0x80010000, 0xa0000001, 0x90aa0000, 0x02000001, 0x80010001,
+0xa0000006, 0x01000026, 0xf0e40000, 0x04000004, 0x80010001, 0x80000000, 0xa0aa0003, 0x80000001,
+0x00000027, 0x02000001, 0x80020001, 0xa0000006, 0x0000002a, 0x03000005, 0x80010000, 0xa0aa0001,
+0x90550000, 0x02000001, 0x80020001, 0xa0000006, 0x01000026, 0xf0e40003, 0x04000004, 0x80020001,
+0x80000000, 0xa0550005, 0x80550001, 0x00000027, 0x02000001, 0x80010001, 0xa0000006, 0x0000002b,
+0x02000001, 0xe0030000, 0x80e40001, 0x02000001, 0xe00c0000, 0xa0000006, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_struct_float[] =
+{
+ {"sf", {"sf", D3DXRS_FLOAT4, 0, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 93},
+ {"sf.f", {"f", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 93},
+ {"sf.vf", {"vf", D3DXRS_FLOAT4, 1, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 97},
+};
+
+static const struct registerset_test registerset_test_struct_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetValue, 0, 0, 15},
+ {SetValue, 0, 16, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+};
+
+static const struct registerset_constants registerset_constants_struct_int[] =
+{
+ {"sn", {"sn", D3DXRS_INT4, 0, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 120},
+ {"sn.n", {"n", D3DXRS_INT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 120},
+ {"sn.vn", {"vn", D3DXRS_INT4, 1, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 124},
+};
+
+static const struct registerset_test registerset_test_struct_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000004, 0x00000005, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000004, 0x00000005, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+};
+
+static const struct registerset_constants registerset_constants_struct_bool[] =
+{
+ {"sb", {"sb", D3DXRS_BOOL, 0, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 51},
+ {"sb.b", {"b", D3DXRS_BOOL, 0, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 51},
+ {"sb.vb", {"vb", D3DXRS_BOOL, 1, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 52},
+};
+
+static const struct registerset_test registerset_test_struct_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, REGISTER_OUTPUT_SIZE * 4, 4,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005}},
+ {SetVector, 0, 0, 0, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_struct_int_float[] =
+{
+ {"snf", {"snf", D3DXRS_FLOAT4, 2, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 139},
+ {"snf.nf", {"nf", D3DXRS_FLOAT4, 2, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 139},
+ {"snf.vnf", {"vnf", D3DXRS_FLOAT4, 3, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 143},
+};
+
+static const struct registerset_test registerset_test_struct_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+};
+
+static const struct registerset_constants registerset_constants_struct_bool_float[] =
+{
+ {"sbf", {"sbf", D3DXRS_FLOAT4, 4, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 66},
+ {"sbf.bf", {"bf", D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 66},
+ {"sbf.vbf", {"vbf", D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 70},
+};
+
+static const struct registerset_test registerset_test_struct_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+struct {bool b; bool3 vb;} sab[2] = {1, 1, 0, 1, 0, 1, 0, 1};
+struct {int n; int3 vn;} san[2] = {21, 22, 23, 24, 25, 26, 27, 28};
+struct {float f; float3 vf;} saf[2] = {1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f};
+struct {int nf; int3 vnf;} sanf[2] = {41, 0, 43, 44, 41, 42, 43, 44};
+struct {bool bf; bool3 vbf;} sabf[2] = {1, 0, 0, 1, 1, 1, 0, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (sab[1].vb.z) for (i = 0; i < san[1].n; i++) tmp.x += pos.z * saf[1].vf.x * sanf[1].vnf.z;
+ else for (i = 0; i < san[1].vn.z; i++) tmp.y += pos.y * saf[1].vf.z * sabf[1].vbf.y;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_struct_array[] =
+{
+0xfffe0300, 0x00c6fffe, 0x42415443, 0x0000001c, 0x000002e3, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x000002dc, 0x00000080, 0x00000000, 0x00000008, 0x000000bc, 0x000000cc, 0x000000ec,
+0x00080002, 0x00000004, 0x00000108, 0x00000118, 0x00000158, 0x00000002, 0x00000004, 0x00000194,
+0x000001a4, 0x000001e4, 0x00000001, 0x00000008, 0x00000220, 0x00000230, 0x00000270, 0x00040002,
+0x00000004, 0x0000028c, 0x0000029c, 0x00626173, 0xabab0062, 0x00010000, 0x00010001, 0x00000001,
+0x00000000, 0xab006276, 0x00010001, 0x00030001, 0x00000001, 0x00000000, 0x00000084, 0x00000088,
+0x00000098, 0x0000009c, 0x00000005, 0x00040001, 0x00020002, 0x000000ac, 0xffffffff, 0xffffffff,
+0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x66626173, 0x00666200,
+0x00666276, 0x000000f1, 0x00000088, 0x000000f4, 0x0000009c, 0x00000005, 0x00040001, 0x00020002,
+0x000000f8, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
+0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000,
+0x00000000, 0x00666173, 0xabab0066, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0xab006676,
+0x00030001, 0x00030001, 0x00000001, 0x00000000, 0x0000015c, 0x00000160, 0x00000170, 0x00000174,
+0x00000005, 0x00040001, 0x00020002, 0x00000184, 0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000,
+0x40066666, 0x40466666, 0x40833333, 0x00000000, 0x40a33333, 0x00000000, 0x00000000, 0x00000000,
+0x40c33333, 0x40e33333, 0x4101999a, 0x00000000, 0x006e6173, 0xabab006e, 0x00020000, 0x00010001,
+0x00000001, 0x00000000, 0xab006e76, 0x00020001, 0x00030001, 0x00000001, 0x00000000, 0x000001e8,
+0x000001ec, 0x000001fc, 0x00000200, 0x00000005, 0x00040001, 0x00020002, 0x00000210, 0x00000015,
+0x00000000, 0x00000001, 0x00000000, 0x00000016, 0x00000017, 0x00000018, 0x00000000, 0x00000019,
+0x00000000, 0x00000001, 0x00000000, 0x0000001a, 0x0000001b, 0x0000001c, 0x00000000, 0x666e6173,
+0x00666e00, 0x00666e76, 0x00000275, 0x000001ec, 0x00000278, 0x00000200, 0x00000005, 0x00040001,
+0x00020002, 0x0000027c, 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x422c0000,
+0x42300000, 0x00000000, 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x42280000, 0x422c0000,
+0x42300000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x01000028, 0xe0e40807, 0x03000005, 0x80010000,
+0xa0000003, 0x90aa0000, 0x02000001, 0x80010001, 0xa000000c, 0x01000026, 0xf0e40004, 0x04000004,
+0x80010001, 0x80000000, 0xa0aa0007, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa000000c,
+0x0000002a, 0x03000005, 0x80010000, 0xa0aa0003, 0x90550000, 0x02000001, 0x80020001, 0xa000000c,
+0x01000026, 0xf0e40007, 0x04000004, 0x80020001, 0x80000000, 0xa055000b, 0x80550001, 0x00000027,
+0x02000001, 0x80010001, 0xa000000c, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001,
+0xe00c0000, 0xa000000c, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_struct_array_float[] =
+{
+ {"saf", {"saf", D3DXRS_FLOAT4, 0, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 2, 2, 32, NULL}, 105},
+ {"saf[0]", {"saf", D3DXRS_FLOAT4, 0, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 105},
+ {"saf[0].f", {"f", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 105},
+ {"saf[0].vf", {"vf", D3DXRS_FLOAT4, 1, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 109},
+ {"saf[1]", {"saf", D3DXRS_FLOAT4, 2, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 113},
+ {"saf[1].f", {"f", D3DXRS_FLOAT4, 2, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 113},
+ {"saf[1].vf", {"vf", D3DXRS_FLOAT4, 3, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 117},
+};
+
+static const struct registerset_test registerset_test_struct_array_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, 7, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetIntArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, 7, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetBoolArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, 7, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetFloatArray, 0, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x41000123, 0x41100123, 0x00000000}},
+ {SetValue, 0, 0, 15},
+ {SetValue, 0, 16, 31, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetValue, 0, 32, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x41000123, 0x41100123, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 8,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800123, 0x40a00123, 0x00000000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x41000123, 0x41100123, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x41000123, 0x41100123, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40c00123, 0x00000000, 0x00000000, 0x00000000, 0x40e00123, 0x41000123, 0x41100123, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+};
+
+static const struct registerset_constants registerset_constants_struct_array_int[] =
+{
+ {"san", {"san", D3DXRS_INT4, 0, 8, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 2, 2, 32, NULL}, 140},
+ {"san[0]", {"san", D3DXRS_INT4, 0, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 140},
+ {"san[0].n", {"n", D3DXRS_INT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 140},
+ {"san[0].vn", {"vn", D3DXRS_INT4, 1, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 144},
+ {"san[1]", {"san", D3DXRS_INT4, 2, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 148},
+ {"san[1].n", {"n", D3DXRS_INT4, 2, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 148},
+ {"san[1].vn", {"vn", D3DXRS_INT4, 3, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 152},
+};
+
+static const struct registerset_test registerset_test_struct_array_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, 7, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000004, 0x00000005, 0x00000000}},
+ {SetIntArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, 7, 8,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000}},
+ {SetBoolArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, 7, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetFloatArray, 0, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000006, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, 31, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000004, 0x00000005, 0x00000000}},
+ {SetValue, 1, 32, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 8,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000005, 0x00000000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x00000006, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x00000006, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000},},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000006, 0x00000000, 0x00000001, 0x00000000, 0x00000007, 0x00000008, 0x00000009, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+};
+
+static const struct registerset_constants registerset_constants_struct_array_bool[] =
+{
+ {"sab", {"sab", D3DXRS_BOOL, 0, 8, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 2, 2, 32, NULL}, 51},
+ {"sab[0]", {"sab", D3DXRS_BOOL, 0, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 51},
+ {"sab[0].b", {"b", D3DXRS_BOOL, 0, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 51},
+ {"sab[0].vb", {"vb", D3DXRS_BOOL, 1, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 52},
+ {"sab[1]", {"sab", D3DXRS_BOOL, 4, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 55},
+ {"sab[1].b", {"b", D3DXRS_BOOL, 4, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 55},
+ {"sab[1].vb", {"vb", D3DXRS_BOOL, 5, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 56},
+};
+
+static const struct registerset_test registerset_test_struct_array_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, 7, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetIntArray, 1, 8, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, 7, 4,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005}},
+ {SetBoolArray, 1, 8, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000000, 0x00000007, 0x00000008, 0x00000009}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, 7, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetFloatArray, 0, 8, REGISTER_OUTPUT_SIZE, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, 31, 4,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005}},
+ {SetValue, 1, 32, REGISTER_OUTPUT_SIZE * 4, 4,
+ {0x00000000, 0x00000007, 0x00000008, 0x00000009}},
+ {SetVector, 0, 0, 0, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 4,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 4,
+ {0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 4,
+ {0x00000000, 0x00000001, 0x00000001, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_struct_array_int_float[] =
+{
+ {"sanf", {"sanf", D3DXRS_FLOAT4, 4, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 2, 2, 32, NULL}, 167},
+ {"sanf[0]", {"sanf", D3DXRS_FLOAT4, 4, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 167},
+ {"sanf[0].nf", {"nf", D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 167},
+ {"sanf[0].vnf", {"vnf", D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 171},
+ {"sanf[1]", {"sanf", D3DXRS_FLOAT4, 6, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 175},
+ {"sanf[1].nf", {"nf", D3DXRS_FLOAT4, 6, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 175},
+ {"sanf[1].vnf", {"vnf", D3DXRS_FLOAT4, 7, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 179},
+};
+
+static const struct registerset_test registerset_test_struct_array_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, 7, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetIntArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, 7, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetBoolArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, 7, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetFloatArray, 0, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, 31, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetValue, 1, 32, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 8,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x40800000, 0x40a00000, 0x00000000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x40c00000, 0x00000000, 0x00000000, 0x00000000, 0x40e00000, 0x41000000, 0x41100000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+};
+
+static const struct registerset_constants registerset_constants_struct_array_bool_float[] =
+{
+ {"sabf", {"sabf", D3DXRS_FLOAT4, 8, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 2, 2, 32, NULL}, 70},
+ {"sabf[0]", {"sabf", D3DXRS_FLOAT4, 8, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 70},
+ {"sabf[0].bf", {"bf", D3DXRS_FLOAT4, 8, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 70},
+ {"sabf[0].vbf", {"vbf", D3DXRS_FLOAT4, 9, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 74},
+ {"sabf[1]", {"sabf", D3DXRS_FLOAT4, 10, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 78},
+ {"sabf[1].bf", {"bf", D3DXRS_FLOAT4, 10, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 78},
+ {"sabf[1].vbf", {"vbf", D3DXRS_FLOAT4, 11, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 82},
+};
+
+static const struct registerset_test registerset_test_struct_array_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 3},
+ {SetIntArray, 1, 4, 7, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetIntArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetBoolArray, 1, 0, 3},
+ {SetBoolArray, 1, 4, 7, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetBoolArray, 1, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 0, 3},
+ {SetFloatArray, 0, 4, 7, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetFloatArray, 0, 8, REGISTER_OUTPUT_SIZE, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetValue, 1, 0, 15},
+ {SetValue, 1, 16, 31, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetValue, 1, 32, REGISTER_OUTPUT_SIZE * 4, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetVector, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetVectorArray},
+ {SetVectorArray, 0, 1, 1, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrix, 0, 0, 0, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000}},
+ {SetMatrixTranspose, 0, 0, 0, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8,
+ {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 8},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+struct {bool b; struct {bool b; bool3 vb;} s; bool b1;} ssb = {1, 1, 0, 1, 1, 0};
+struct {int n; struct {int n; int3 vn;} s; int n1;} ssn = {71, 72, 73, 74, 75, 76};
+struct {float f; struct {float f; float3 vf;} s; float f1;} ssf = {1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f};
+struct {int nf; struct {int nf; int3 vnf;} s; int nf1;} ssnf = {41, 0, 43, 44, 41, 42};
+struct {bool bf; struct {bool bf; bool3 vbf;} s; bool bf1;} ssbf = {1, 0, 0, 1, 1, 0};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int i;
+ if (ssb.b1) for (i = 0; i < ssn.n1; i++) tmp.x += pos.z * ssf.f1 * ssnf.nf1;
+ else for (i = 0; i < ssn.s.vn.z; i++) tmp.y += pos.y * ssf.s.vf.z * ssbf.bf1;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_struct_struct[] =
+{
+0xfffe0300, 0x00fcfffe, 0x42415443, 0x0000001c, 0x000003bb, 0xfffe0300, 0x00000005, 0x0000001c,
+0x00000100, 0x000003b4, 0x00000080, 0x00000000, 0x00000006, 0x000000ec, 0x000000fc, 0x00000114,
+0x00080002, 0x00000004, 0x0000015c, 0x0000016c, 0x000001ac, 0x00000002, 0x00000004, 0x00000214,
+0x00000224, 0x00000264, 0x00000001, 0x00000006, 0x000002cc, 0x000002dc, 0x0000031c, 0x00040002,
+0x00000004, 0x00000364, 0x00000374, 0x00627373, 0xabab0062, 0x00010000, 0x00010001, 0x00000001,
+0x00000000, 0x62760073, 0xababab00, 0x00010001, 0x00030001, 0x00000001, 0x00000000, 0x00000084,
+0x00000088, 0x0000009a, 0x000000a0, 0x00000005, 0x00040001, 0x00020001, 0x000000b0, 0xab003162,
+0x00000084, 0x00000088, 0x00000098, 0x000000c0, 0x000000d0, 0x00000088, 0x00000005, 0x00060001,
+0x00030001, 0x000000d4, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+0x66627373, 0x00666200, 0x00666276, 0x00000119, 0x00000088, 0x0000011c, 0x000000a0, 0x00000005,
+0x00040001, 0x00020001, 0x00000120, 0x00316662, 0x00000119, 0x00000088, 0x00000098, 0x00000130,
+0x00000140, 0x00000088, 0x00000005, 0x00060001, 0x00030001, 0x00000144, 0x3f800000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000,
+0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00667373, 0xabab0066,
+0x00030000, 0x00010001, 0x00000001, 0x00000000, 0xab006676, 0x00030001, 0x00030001, 0x00000001,
+0x00000000, 0x000001b0, 0x000001b4, 0x000001c4, 0x000001c8, 0x00000005, 0x00040001, 0x00020001,
+0x000001d8, 0xab003166, 0x000001b0, 0x000001b4, 0x00000098, 0x000001e8, 0x000001f8, 0x000001b4,
+0x00000005, 0x00060001, 0x00030001, 0x000001fc, 0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000,
+0x40066666, 0x00000000, 0x00000000, 0x00000000, 0x40466666, 0x40833333, 0x40a33333, 0x00000000,
+0x40c33333, 0x00000000, 0x00000000, 0x00000000, 0x006e7373, 0xabab006e, 0x00020000, 0x00010001,
+0x00000001, 0x00000000, 0xab006e76, 0x00020001, 0x00030001, 0x00000001, 0x00000000, 0x00000268,
+0x0000026c, 0x0000027c, 0x00000280, 0x00000005, 0x00040001, 0x00020001, 0x00000290, 0xab00316e,
+0x00000268, 0x0000026c, 0x00000098, 0x000002a0, 0x000002b0, 0x0000026c, 0x00000005, 0x00060001,
+0x00030001, 0x000002b4, 0x00000047, 0x00000000, 0x00000001, 0x00000000, 0x00000048, 0x00000000,
+0x00000001, 0x00000000, 0x00000049, 0x0000004a, 0x0000004b, 0x00000000, 0x0000004c, 0x00000000,
+0x00000001, 0x00000000, 0x666e7373, 0x00666e00, 0x00666e76, 0x00000321, 0x0000026c, 0x00000324,
+0x00000280, 0x00000005, 0x00040001, 0x00020001, 0x00000328, 0x0031666e, 0x00000321, 0x0000026c,
+0x00000098, 0x00000338, 0x00000348, 0x0000026c, 0x00000005, 0x00060001, 0x00030001, 0x0000034c,
+0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x422c0000, 0x42300000, 0x42240000, 0x00000000, 0x42280000, 0x00000000, 0x00000000, 0x00000000,
+0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x05000051, 0xa00f000c,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f,
+0x80000000, 0xe00f0000, 0x01000028, 0xe0e40805, 0x03000005, 0x80010000, 0xa0000003, 0x90aa0000,
+0x02000001, 0x80010001, 0xa000000c, 0x01000026, 0xf0e40005, 0x04000004, 0x80010001, 0x80000000,
+0xa0000007, 0x80000001, 0x00000027, 0x02000001, 0x80020001, 0xa000000c, 0x0000002a, 0x03000005,
+0x80010000, 0xa0aa0002, 0x90550000, 0x02000001, 0x80020001, 0xa000000c, 0x01000026, 0xf0e40004,
+0x04000004, 0x80020001, 0x80000000, 0xa000000b, 0x80550001, 0x00000027, 0x02000001, 0x80010001,
+0xa000000c, 0x0000002b, 0x02000001, 0xe0030000, 0x80e40001, 0x02000001, 0xe00c0000, 0xa000000c,
+0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_struct_struct_float[] =
+{
+ {"ssf", {"ssf", D3DXRS_FLOAT4, 0, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 6, 1, 3, 24, NULL}, 137},
+ {"ssf.f", {"f", D3DXRS_FLOAT4, 0, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 137},
+ {"ssf.s", {"s", D3DXRS_FLOAT4, 1, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 141},
+ {"ssf.s.f", {"f", D3DXRS_FLOAT4, 1, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 141},
+ {"ssf.s.vf", {"vf", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 145},
+ {"ssf.f1", {"f1", D3DXRS_FLOAT4, 3, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 149},
+};
+
+static const struct registerset_test registerset_test_struct_struct_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x00000000, 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800123, 0x40a00123, 0x40c00123, 0x00000000, 0x40e00123}},
+ {SetValue, 0, 0, 23},
+ {SetValue, 0, 24, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800123, 0x40a00123, 0x40c00123, 0x00000000, 0x40e00123}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800123, 0x40a00123, 0x40c00123, 0x00000000, 0x40e00123}},
+ {SetMatrix, 0, 0, 0, 16,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800123, 0x40a00123, 0x40c00123, 0x00000000, 0x40e00123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000123, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800123, 0x40a00123, 0x40c00123, 0x00000000, 0x40e00123}},
+ {SetMatrixTranspose, 0, 0, 0, 16, {0x40000123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000123}},
+};
+
+static const struct registerset_constants registerset_constants_struct_struct_int[] =
+{
+ {"ssn", {"ssn", D3DXRS_INT4, 0, 6, D3DXPC_STRUCT, D3DXPT_VOID, 1, 6, 1, 3, 24, NULL}, 183},
+ {"ssn.n", {"n", D3DXRS_INT4, 0, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 183},
+ {"ssn.s", {"s", D3DXRS_INT4, 1, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 187},
+ {"ssn.s.n", {"n", D3DXRS_INT4, 1, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 187},
+ {"ssn.s.vn", {"vn", D3DXRS_INT4, 2, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 191},
+ {"ssn.n1", {"n1", D3DXRS_INT4, 3, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 195},
+};
+
+static const struct registerset_test registerset_test_struct_struct_int[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000006, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000006, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000006, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000005, 0x00000006, 0x00000000, 0x00000007, 0x00000000, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_struct_struct_bool[] =
+{
+ {"ssb", {"ssb", D3DXRS_BOOL, 0, 6, D3DXPC_STRUCT, D3DXPT_VOID, 1, 6, 1, 3, 24, NULL}, 63},
+ {"ssb.b", {"b", D3DXRS_BOOL, 0, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 63},
+ {"ssb.s", {"s", D3DXRS_BOOL, 1, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 64},
+ {"ssb.s.b", {"b", D3DXRS_BOOL, 1, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 64},
+ {"ssb.s.vb", {"vb", D3DXRS_BOOL, 2, 3, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 65},
+ {"ssb.b1", {"b1", D3DXRS_BOOL, 5, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 68},
+};
+
+static const struct registerset_test registerset_test_struct_struct_bool[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 6,
+ {0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000000, 0x00000007}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrix, 0, 0, 0, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTranspose, 0, 0, 0, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x00000001, 0x00000001}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 6,
+ {0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000001}},
+};
+
+static const struct registerset_constants registerset_constants_struct_struct_int_float[] =
+{
+ {"ssnf", {"ssnf", D3DXRS_FLOAT4, 4, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 6, 1, 3, 24, NULL}, 221},
+ {"ssnf.nf", {"nf", D3DXRS_FLOAT4, 4, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 221},
+ {"ssnf.s", {"s", D3DXRS_FLOAT4, 5, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 225},
+ {"ssnf.s.nf", {"nf", D3DXRS_FLOAT4, 5, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 225},
+ {"ssnf.s.vnf", {"vnf", D3DXRS_FLOAT4, 6, 1, D3DXPC_VECTOR, D3DXPT_INT, 1, 3, 1, 0, 12, NULL}, 229},
+ {"ssnf.nf1", {"nf1", D3DXRS_FLOAT4, 7, 1, D3DXPC_SCALAR, D3DXPT_INT, 1, 1, 1, 0, 4, NULL}, 233},
+};
+
+static const struct registerset_test registerset_test_struct_struct_int_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x00000000, 0x00000000, 0x40e00000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x40c00000, 0x00000000, 0x40e00000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x40400000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x00000000, 0x00000000, 0x40e00000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x40c00000, 0x00000000, 0x40e00000}},
+ {SetMatrix, 0, 0, 0, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x40c00000, 0x00000000, 0x40e00000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x40800000, 0x40a00000, 0x40c00000, 0x00000000, 0x40e00000}},
+ {SetMatrixTranspose, 0, 0, 0, 16, {0x40000000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x40000000}},
+};
+
+static const struct registerset_constants registerset_constants_struct_struct_bool_float[] =
+{
+ {"ssbf", {"ssbf", D3DXRS_FLOAT4, 8, 4, D3DXPC_STRUCT, D3DXPT_VOID, 1, 6, 1, 3, 24, NULL}, 91},
+ {"ssbf.bf", {"bf", D3DXRS_FLOAT4, 8, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 91},
+ {"ssbf.s", {"s", D3DXRS_FLOAT4, 9, 2, D3DXPC_STRUCT, D3DXPT_VOID, 1, 4, 1, 2, 16, NULL}, 95},
+ {"ssbf.s.bf", {"bf", D3DXRS_FLOAT4, 9, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 95},
+ {"ssbf.s.vbf", {"vbf", D3DXRS_FLOAT4, 10, 1, D3DXPC_VECTOR, D3DXPT_BOOL, 1, 3, 1, 0, 12, NULL}, 99},
+ {"ssbf.bf1", {"bf1", D3DXRS_FLOAT4, 11, 1, D3DXPC_SCALAR, D3DXPT_BOOL, 1, 1, 1, 0, 4, NULL}, 103},
+};
+
+static const struct registerset_test registerset_test_struct_struct_bool_float[] =
+{
+ {SetInt},
+ {SetBool},
+ {SetFloat},
+ {SetIntArray, 1, 0, 5},
+ {SetIntArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetBoolArray, 1, 0, 5},
+ {SetBoolArray, 1, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetFloatArray, 0, 0, 5},
+ {SetFloatArray, 0, 6, REGISTER_OUTPUT_SIZE, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetValue, 1, 0, 23},
+ {SetValue, 1, 24, REGISTER_OUTPUT_SIZE * 4, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000}},
+ {SetVector},
+ {SetVectorArray, 0, 0, 1},
+ {SetVectorArray, 0, 2, REGISTER_OUTPUT_SIZE / 4, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrix, 0, 0, 0, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16,
+ {0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000}},
+ {SetMatrixTranspose, 0, 0, 0, 16, {0x3f800000}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x3f800000}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x3f800000}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, REGISTER_OUTPUT_SIZE / 16, 16, {0x3f800000}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+row_major int3x2 ran[2] = {4, 5, 6, 1, 8, 1, 2, 3, 4, 7, 9, 1};
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ int k;
+ for (k = 0; k < ran[1]._21; k++)
+ tmp.y += pos.y + tmp.x;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_special_int[] =
+{
+0xfffe0300, 0x0038fffe, 0x42415443, 0x0000001c, 0x000000ab, 0xfffe0300, 0x00000001, 0x0000001c,
+0x00000100, 0x000000a4, 0x00000030, 0x00000001, 0x00000009, 0x00000034, 0x00000044, 0x006e6172,
+0x00020002, 0x00020003, 0x00000002, 0x00000000, 0x00000004, 0x00000005, 0x00000001, 0x00000000,
+0x00000006, 0x00000001, 0x00000001, 0x00000000, 0x00000008, 0x00000001, 0x00000001, 0x00000000,
+0x00000002, 0x00000003, 0x00000001, 0x00000000, 0x00000004, 0x00000007, 0x00000001, 0x00000000,
+0x00000009, 0x00000001, 0x00000001, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
+0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+0x332e3235, 0x00313131, 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x02000001, 0x80010000,
+0xa0000000, 0x01000026, 0xf0e40008, 0x03000002, 0x80010000, 0x80000000, 0x90550000, 0x00000027,
+0x02000001, 0xe0020000, 0x80000000, 0x02000001, 0xe00d0000, 0xa0000000, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_special_int[] =
+{
+ {"ran", {"ran", D3DXRS_INT4, 0, 9, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 2, 0, 48, NULL}, 17},
+ {"ran[0]", {"ran", D3DXRS_INT4, 0, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 17},
+ {"ran[1]", {"ran", D3DXRS_INT4, 3, 3, D3DXPC_MATRIX_ROWS, D3DXPT_INT, 3, 2, 1, 0, 24, NULL}, 29},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+float3 vaf[10];
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ tmp.y += pos.y + vaf[8].x;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_bigvec[] =
+{
+0xfffe0300, 0x0020fffe, 0x42415443, 0x0000001c, 0x0000004b, 0xfffe0300, 0x00000001, 0x0000001c,
+0x00000100, 0x00000044, 0x00000030, 0x00000002, 0x00000009, 0x00000034, 0x00000000, 0x00666176,
+0x00030001, 0x00030001, 0x0000000a, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73,
+0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932,
+0x332e3235, 0x00313131, 0x05000051, 0xa00f0009, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x80000000, 0xe00f0000, 0x03000002, 0xe0020000,
+0xa0000008, 0x90550000, 0x02000001, 0xe00d0000, 0xa0000009, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_bigvec_float[] =
+{
+ {"vaf", {"vaf", D3DXRS_FLOAT4, 0, 9, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 10, 0, 120, NULL}, 0},
+ {"vaf[0]", {"vaf", D3DXRS_FLOAT4, 0, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[1]", {"vaf", D3DXRS_FLOAT4, 1, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[2]", {"vaf", D3DXRS_FLOAT4, 2, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[3]", {"vaf", D3DXRS_FLOAT4, 3, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[4]", {"vaf", D3DXRS_FLOAT4, 4, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[5]", {"vaf", D3DXRS_FLOAT4, 5, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[6]", {"vaf", D3DXRS_FLOAT4, 6, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[7]", {"vaf", D3DXRS_FLOAT4, 7, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[8]", {"vaf", D3DXRS_FLOAT4, 8, 1, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+ {"vaf[9]", {"vaf", D3DXRS_FLOAT4, 9, 0, D3DXPC_VECTOR, D3DXPT_FLOAT, 1, 3, 1, 0, 12, NULL}, 0},
+};
+
+static const struct registerset_test registerset_test_bigvec_float[] =
+{
+ {SetMatrix, 0, 0, 0, 16,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123}},
+ {SetMatrixArray},
+ {SetMatrixArray, 0, 1, 1, 16,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123}},
+ {SetMatrixArray, 0, 2, 2, 32,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123, 0x00000000,
+ 0x41a00123, 0x41b00123, 0x41c00123, 0x00000000, 0x00000000, 0x41f00123, 0x42000123, 0x00000000,
+ 0x00000000, 0x42300123, 0x42400123, 0x00000000, 0x42600123, 0x42700123, 0x42800123}},
+ {SetMatrixArray, 0, 3, REGISTER_OUTPUT_SIZE / 16, 36,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123, 0x00000000,
+ 0x41a00123, 0x41b00123, 0x41c00123, 0x00000000, 0x00000000, 0x41f00123, 0x42000123, 0x00000000,
+ 0x00000000, 0x42300123, 0x42400123, 0x00000000, 0x42600123, 0x42700123, 0x42800123, 0x00000000,
+ 0x43000123, 0x43100123, 0x43200123}},
+ {SetMatrixTranspose, 0, 0, 0, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123}},
+ {SetMatrixTransposeArray},
+ {SetMatrixTransposeArray, 0, 1, 1, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123}},
+ {SetMatrixTransposeArray, 0, 2, 2, 32,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123, 0x00000000,
+ 0x41a00123, 0x00000000, 0x00000000, 0x00000000, 0x41b00123, 0x41f00123, 0x42300123, 0x00000000,
+ 0x41c00123, 0x42000123, 0x42400123, 0x00000000, 0x41d00123, 0x42100123, 0x42500123}},
+ {SetMatrixTransposeArray, 0, 3, REGISTER_OUTPUT_SIZE / 16, 36,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123, 0x00000000,
+ 0x41a00123, 0x00000000, 0x00000000, 0x00000000, 0x41b00123, 0x41f00123, 0x42300123, 0x00000000,
+ 0x41c00123, 0x42000123, 0x42400123, 0x00000000, 0x41d00123, 0x42100123, 0x42500123, 0x00000000,
+ 0x43000123, 0x43400123, 0x43800123}},
+ {SetMatrixPointerArray},
+ {SetMatrixPointerArray, 0, 1, 1, 16,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123}},
+ {SetMatrixPointerArray, 0, 2, 2, 32,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123, 0x00000000,
+ 0x41900123, 0x41a00123, 0x41b00123, 0x00000000, 0x41d00123, 0x00000000, 0x41f00123, 0x00000000,
+ 0x42100123, 0x00000000, 0x42300123, 0x00000000, 0x42500123, 0x42600123, 0x42700123}},
+ {SetMatrixPointerArray, 0, 3, REGISTER_OUTPUT_SIZE / 16, 36,
+ {0x40000123, 0x00000000, 0x40800123, 0x00000000, 0x40c00123, 0x40e00123, 0x41000123, 0x00000000,
+ 0x41200123, 0x41300123, 0x41400123, 0x00000000, 0x41600123, 0x41700123, 0x41800123, 0x00000000,
+ 0x41900123, 0x41a00123, 0x41b00123, 0x00000000, 0x41d00123, 0x00000000, 0x41f00123, 0x00000000,
+ 0x42100123, 0x00000000, 0x42300123, 0x00000000, 0x42500123, 0x42600123, 0x42700123, 0x00000000,
+ 0x42800123, 0x42900123, 0x43000123}},
+ {SetMatrixTransposePointerArray},
+ {SetMatrixTransposePointerArray, 0, 1, 1, 16,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123}},
+ {SetMatrixTransposePointerArray, 0, 2, 2, 32,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123, 0x00000000,
+ 0x41900123, 0x41d00123, 0x42100123, 0x00000000, 0x41a00123, 0x00000000, 0x00000000, 0x00000000,
+ 0x41b00123, 0x41f00123, 0x42300123, 0x00000000, 0x41c00123, 0x42000123, 0x42400123}},
+ {SetMatrixTransposePointerArray, 0, 3, REGISTER_OUTPUT_SIZE / 16, 36,
+ {0x40000123, 0x40c00123, 0x41200123, 0x00000000, 0x00000000, 0x40e00123, 0x41300123, 0x00000000,
+ 0x40800123, 0x41000123, 0x41400123, 0x00000000, 0x40a00123, 0x41100123, 0x41500123, 0x00000000,
+ 0x41900123, 0x41d00123, 0x42100123, 0x00000000, 0x41a00123, 0x00000000, 0x00000000, 0x00000000,
+ 0x41b00123, 0x41f00123, 0x42300123, 0x00000000, 0x41c00123, 0x42000123, 0x42400123, 0x00000000,
+ 0x42800123, 0x43200123, 0x43600123}},
+};
+
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+float4x4 cf = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8};
+float f = 33.33;
+float4 main(float4 pos : POSITION) : POSITION
+{
+ float4 tmp = 0;
+ tmp.y += cf._22;
+ tmp.z = f;
+ return tmp;
+}
+#endif
+static const DWORD registerset_blob_matrix_column_clamp[] =
+{
+0xfffe0300, 0x003efffe, 0x42415443, 0x0000001c, 0x000000c3, 0xfffe0300, 0x00000002, 0x0000001c,
+0x00000100, 0x000000bc, 0x00000044, 0x00000002, 0x00000002, 0x00000048, 0x00000058, 0x00000098,
+0x00020002, 0x00000001, 0x0000009c, 0x000000ac, 0xab006663, 0x00030003, 0x00040004, 0x00000001,
+0x00000000, 0x3f8ccccd, 0x40b00000, 0x411e6666, 0x3fc00000, 0x400ccccd, 0x40d33333, 0x3f99999a,
+0x3fcccccd, 0x40533333, 0x40f66666, 0x3fa66666, 0x3fd9999a, 0x408ccccd, 0x410ccccd, 0x3fb33333,
+0x3fe66666, 0xabab0066, 0x00030000, 0x00010001, 0x00000001, 0x00000000, 0x420551ec, 0x00000000,
+0x00000000, 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820,
+0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131,
+0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
+0xe00f0000, 0x02000001, 0x80020000, 0xa0550001, 0x03000005, 0xe00b0000, 0x80550000, 0xa0240003,
+0x02000001, 0xe0040000, 0xa0000002, 0x0000ffff,
+};
+
+static const struct registerset_constants registerset_constants_matrix_column_clamp[] =
+{
+ {"cf", {"cf", D3DXRS_FLOAT4, 0, 2, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4, 1, 0, 64, NULL}, 0},
+ {"f", {"f", D3DXRS_FLOAT4, 2, 1, D3DXPC_SCALAR, D3DXPT_FLOAT, 1, 1, 1, 0, 4, NULL}, 0},
+};
+
+static const struct registerset_test registerset_test_matrix_column_clamp[] =
+{
+ {SetMatrix, 0, 0, 0, 8,
+ {0x40000123, 0x40c00123, 0x41200123, 0x41600123, 0x00000000, 0x40e00123, 0x41300123, 0x41700123}},
+};
+
+static const struct
+{
+ const char *name;
+ const char *var;
+ UINT start;
+ D3DXREGISTER_SET regset;
+ const DWORD *blob;
+ const struct registerset_test *tests;
+ UINT test_count;
+ const struct registerset_constants *constants;
+ UINT constant_count;
+}
+registerset_data[] =
+{
+ /* scalar */
+ {"float", "f", 0, D3DXRS_FLOAT4, registerset_blob_scalar,
+ registerset_test_scalar_float, ARRAY_SIZE(registerset_test_scalar_float),
+ registerset_constants_scalar_float, ARRAY_SIZE(registerset_constants_scalar_float)},
+ {"int", "n", 0, D3DXRS_INT4, registerset_blob_scalar,
+ registerset_test_scalar_int, ARRAY_SIZE(registerset_test_scalar_int),
+ registerset_constants_scalar_int, ARRAY_SIZE(registerset_constants_scalar_int)},
+ {"int float", "nf", 4, D3DXRS_FLOAT4, registerset_blob_scalar,
+ registerset_test_scalar_int_float, ARRAY_SIZE(registerset_test_scalar_int_float),
+ registerset_constants_scalar_int_float, ARRAY_SIZE(registerset_constants_scalar_int_float)},
+ {"bool float", "bf", 8, D3DXRS_FLOAT4, registerset_blob_scalar,
+ registerset_test_scalar_bool_float, ARRAY_SIZE(registerset_test_scalar_bool_float),
+ registerset_constants_scalar_bool_float, ARRAY_SIZE(registerset_constants_scalar_bool_float)},
+ {"bool", "b", 0, D3DXRS_BOOL, registerset_blob_scalar,
+ registerset_test_scalar_bool, ARRAY_SIZE(registerset_test_scalar_bool),
+ registerset_constants_scalar_bool, ARRAY_SIZE(registerset_constants_scalar_bool)},
+ /* scalar array */
+ {"float [2]", "af", 0, D3DXRS_FLOAT4, registerset_blob_scalar_array,
+ registerset_test_scalar_array_float, ARRAY_SIZE(registerset_test_scalar_array_float),
+ registerset_constants_scalar_array_float, ARRAY_SIZE(registerset_constants_scalar_array_float)},
+ {"int [2]", "an", 0, D3DXRS_INT4, registerset_blob_scalar_array,
+ registerset_test_scalar_array_int, ARRAY_SIZE(registerset_test_scalar_array_int),
+ registerset_constants_scalar_array_int, ARRAY_SIZE(registerset_constants_scalar_array_int)},
+ {"bool [2]", "ab", 0, D3DXRS_BOOL, registerset_blob_scalar_array,
+ registerset_test_scalar_array_bool, ARRAY_SIZE(registerset_test_scalar_array_bool),
+ registerset_constants_scalar_array_bool, ARRAY_SIZE(registerset_constants_scalar_array_bool)},
+ {"int float [2]", "anf", 8, D3DXRS_FLOAT4, registerset_blob_scalar_array,
+ registerset_test_scalar_array_int_float, ARRAY_SIZE(registerset_test_scalar_array_int_float),
+ registerset_constants_scalar_array_int_float, ARRAY_SIZE(registerset_constants_scalar_array_int_float)},
+ {"bool float [2]", "abf", 16, D3DXRS_FLOAT4, registerset_blob_scalar_array,
+ registerset_test_scalar_array_bool_float, ARRAY_SIZE(registerset_test_scalar_array_bool_float),
+ registerset_constants_scalar_array_bool_float, ARRAY_SIZE(registerset_constants_scalar_array_bool_float)},
+ /* vector */
+ {"float 3", "vf", 0, D3DXRS_FLOAT4, registerset_blob_vector,
+ registerset_test_vector_float, ARRAY_SIZE(registerset_test_vector_float),
+ registerset_constants_vector_float, ARRAY_SIZE(registerset_constants_vector_float)},
+ {"int 3", "vn", 0, D3DXRS_INT4, registerset_blob_vector,
+ registerset_test_vector_int, ARRAY_SIZE(registerset_test_vector_int),
+ registerset_constants_vector_int, ARRAY_SIZE(registerset_constants_vector_int)},
+ {"bool 3", "vb", 0, D3DXRS_BOOL, registerset_blob_vector,
+ registerset_test_vector_bool, ARRAY_SIZE(registerset_test_vector_bool),
+ registerset_constants_vector_bool, ARRAY_SIZE(registerset_constants_vector_bool)},
+ {"bool float 3", "vbf", 8, D3DXRS_FLOAT4, registerset_blob_vector,
+ registerset_test_vector_bool_float, ARRAY_SIZE(registerset_test_vector_bool_float),
+ registerset_constants_vector_bool_float, ARRAY_SIZE(registerset_constants_vector_bool_float)},
+ {"int float 3", "vnf", 4, D3DXRS_FLOAT4, registerset_blob_vector,
+ registerset_test_vector_int_float, ARRAY_SIZE(registerset_test_vector_int_float),
+ registerset_constants_vector_int_float, ARRAY_SIZE(registerset_constants_vector_int_float)},
+ /* vector array */
+ {"float 3 [2]", "vaf", 0, D3DXRS_FLOAT4, registerset_blob_vector_array,
+ registerset_test_vector_array_float, ARRAY_SIZE(registerset_test_vector_array_float),
+ registerset_constants_vector_array_float, ARRAY_SIZE(registerset_constants_vector_array_float)},
+ {"int 3 [2]", "van", 0, D3DXRS_INT4, registerset_blob_vector_array,
+ registerset_test_vector_array_int, ARRAY_SIZE(registerset_test_vector_array_int),
+ registerset_constants_vector_array_int, ARRAY_SIZE(registerset_constants_vector_array_int)},
+ {"bool 3 [2]", "vab", 0, D3DXRS_BOOL, registerset_blob_vector_array,
+ registerset_test_vector_array_bool, ARRAY_SIZE(registerset_test_vector_array_bool),
+ registerset_constants_vector_array_bool, ARRAY_SIZE(registerset_constants_vector_array_bool)},
+ {"bool float 3 [2]", "vabf", 16, D3DXRS_FLOAT4, registerset_blob_vector_array,
+ registerset_test_vector_array_bool_float, ARRAY_SIZE(registerset_test_vector_array_bool_float),
+ registerset_constants_vector_array_bool_float, ARRAY_SIZE(registerset_constants_vector_array_bool_float)},
+ {"int float 3 [2]", "vanf", 8, D3DXRS_FLOAT4, registerset_blob_vector_array,
+ registerset_test_vector_array_int_float, ARRAY_SIZE(registerset_test_vector_array_int_float),
+ registerset_constants_vector_array_int_float, ARRAY_SIZE(registerset_constants_vector_array_int_float)},
+ /* matrix column */
+ {"float c3x2", "cf", 0, D3DXRS_FLOAT4, registerset_blob_column,
+ registerset_test_column_float, ARRAY_SIZE(registerset_test_column_float),
+ registerset_constants_column_float, ARRAY_SIZE(registerset_constants_column_float)},
+ {"int c3x2", "cn", 0, D3DXRS_INT4, registerset_blob_column,
+ registerset_test_column_int, ARRAY_SIZE(registerset_test_column_int),
+ registerset_constants_column_int, ARRAY_SIZE(registerset_constants_column_int)},
+ {"bool c3x2", "cb", 0, D3DXRS_BOOL, registerset_blob_column,
+ registerset_test_column_bool, ARRAY_SIZE(registerset_test_column_bool),
+ registerset_constants_column_bool, ARRAY_SIZE(registerset_constants_column_bool)},
+ {"bool float c3x2", "cbf", 8, D3DXRS_FLOAT4, registerset_blob_column,
+ registerset_test_column_bool_float, ARRAY_SIZE(registerset_test_column_bool_float),
+ registerset_constants_column_bool_float, ARRAY_SIZE(registerset_constants_column_bool_float)},
+ {"int float c3x2", "cnf", 16, D3DXRS_FLOAT4, registerset_blob_column,
+ registerset_test_column_int_float, ARRAY_SIZE(registerset_test_column_int_float),
+ registerset_constants_column_int_float, ARRAY_SIZE(registerset_constants_column_int_float)},
+ /* matrix column array */
+ {"float c3x2 [2]", "caf", 0, D3DXRS_FLOAT4, registerset_blob_column_array,
+ registerset_test_column_array_float, ARRAY_SIZE(registerset_test_column_array_float),
+ registerset_constants_column_array_float, ARRAY_SIZE(registerset_constants_column_array_float)},
+ {"int c3x2 [2]", "can", 0, D3DXRS_INT4, registerset_blob_column_array,
+ registerset_test_column_array_int, ARRAY_SIZE(registerset_test_column_array_int),
+ registerset_constants_column_array_int, ARRAY_SIZE(registerset_constants_column_array_int)},
+ {"bool c3x2 [2]", "cab", 0, D3DXRS_BOOL, registerset_blob_column_array,
+ registerset_test_column_array_bool, ARRAY_SIZE(registerset_test_column_array_bool),
+ registerset_constants_column_array_bool, ARRAY_SIZE(registerset_constants_column_array_bool)},
+ {"bool float c3x2 [2]", "cabf", 16, D3DXRS_FLOAT4, registerset_blob_column_array,
+ registerset_test_column_array_bool_float, ARRAY_SIZE(registerset_test_column_array_bool_float),
+ registerset_constants_column_array_bool_float, ARRAY_SIZE(registerset_constants_column_array_bool_float)},
+ {"int float c3x2 [2]", "canf", 32, D3DXRS_FLOAT4, registerset_blob_column_array,
+ registerset_test_column_array_int_float, ARRAY_SIZE(registerset_test_column_array_int_float),
+ registerset_constants_column_array_int_float, ARRAY_SIZE(registerset_constants_column_array_int_float)},
+ /* matrix row */
+ {"float r3x2", "rf", 0, D3DXRS_FLOAT4, registerset_blob_row,
+ registerset_test_row_float, ARRAY_SIZE(registerset_test_row_float),
+ registerset_constants_row_float, ARRAY_SIZE(registerset_constants_row_float)},
+ {"int r3x2", "rn", 0, D3DXRS_INT4, registerset_blob_row,
+ registerset_test_row_int, ARRAY_SIZE(registerset_test_row_int),
+ registerset_constants_row_int, ARRAY_SIZE(registerset_constants_row_int)},
+ {"bool r3x2", "rb", 0, D3DXRS_BOOL, registerset_blob_row,
+ registerset_test_row_bool, ARRAY_SIZE(registerset_test_row_bool),
+ registerset_constants_row_bool, ARRAY_SIZE(registerset_constants_row_bool)},
+ {"bool float r3x2", "rbf", 12, D3DXRS_FLOAT4, registerset_blob_row,
+ registerset_test_row_bool_float, ARRAY_SIZE(registerset_test_row_bool_float),
+ registerset_constants_row_bool_float, ARRAY_SIZE(registerset_constants_row_bool_float)},
+ {"int float r3x2", "rnf", 24, D3DXRS_FLOAT4, registerset_blob_row,
+ registerset_test_row_int_float, ARRAY_SIZE(registerset_test_row_int_float),
+ registerset_constants_row_int_float, ARRAY_SIZE(registerset_constants_row_int_float)},
+ /* matrix row array */
+ {"float 3x2 [2]", "raf", 0, D3DXRS_FLOAT4, registerset_blob_row_array,
+ registerset_test_row_array_float, ARRAY_SIZE(registerset_test_row_array_float),
+ registerset_constants_row_array_float, ARRAY_SIZE(registerset_constants_row_array_float)},
+ {"int 3x2 [2]", "ran", 0, D3DXRS_INT4, registerset_blob_row_array,
+ registerset_test_row_array_int, ARRAY_SIZE(registerset_test_row_array_int),
+ registerset_constants_row_array_int, ARRAY_SIZE(registerset_constants_row_array_int)},
+ {"bool 3x2 [2]", "rab", 0, D3DXRS_BOOL, registerset_blob_row_array,
+ registerset_test_row_array_bool, ARRAY_SIZE(registerset_test_row_array_bool),
+ registerset_constants_row_array_bool, ARRAY_SIZE(registerset_constants_row_array_bool)},
+ {"bool float 3x2 [2]", "rabf", 24, D3DXRS_FLOAT4, registerset_blob_row_array,
+ registerset_test_row_array_bool_float, ARRAY_SIZE(registerset_test_row_array_bool_float),
+ registerset_constants_row_array_bool_float, ARRAY_SIZE(registerset_constants_row_array_bool_float)},
+ {"int float 3x2 [2]", "ranf", 48, D3DXRS_FLOAT4, registerset_blob_row_array,
+ registerset_test_row_array_int_float, ARRAY_SIZE(registerset_test_row_array_int_float),
+ registerset_constants_row_array_int_float, ARRAY_SIZE(registerset_constants_row_array_int_float)},
+ /* struct */
+ {"struct float", "sf", 0, D3DXRS_FLOAT4, registerset_blob_struct,
+ registerset_test_struct_float, ARRAY_SIZE(registerset_test_struct_float),
+ registerset_constants_struct_float, ARRAY_SIZE(registerset_constants_struct_float)},
+ {"struct int", "sn", 0, D3DXRS_INT4, registerset_blob_struct,
+ registerset_test_struct_int, ARRAY_SIZE(registerset_test_struct_int),
+ registerset_constants_struct_int, ARRAY_SIZE(registerset_constants_struct_int)},
+ {"struct bool", "sb", 0, D3DXRS_BOOL, registerset_blob_struct,
+ registerset_test_struct_bool, ARRAY_SIZE(registerset_test_struct_bool),
+ registerset_constants_struct_bool, ARRAY_SIZE(registerset_constants_struct_bool)},
+ {"struct bool float", "sbf", 16, D3DXRS_FLOAT4, registerset_blob_struct,
+ registerset_test_struct_bool_float, ARRAY_SIZE(registerset_test_struct_bool_float),
+ registerset_constants_struct_bool_float, ARRAY_SIZE(registerset_constants_struct_bool_float)},
+ {"struct int float", "snf", 8, D3DXRS_FLOAT4, registerset_blob_struct,
+ registerset_test_struct_int_float, ARRAY_SIZE(registerset_test_struct_int_float),
+ registerset_constants_struct_int_float, ARRAY_SIZE(registerset_constants_struct_int_float)},
+ /* struct array */
+ {"struct float [2]", "saf", 0, D3DXRS_FLOAT4, registerset_blob_struct_array,
+ registerset_test_struct_array_float, ARRAY_SIZE(registerset_test_struct_array_float),
+ registerset_constants_struct_array_float, ARRAY_SIZE(registerset_constants_struct_array_float)},
+ {"struct int [2]", "san", 0, D3DXRS_INT4, registerset_blob_struct_array,
+ registerset_test_struct_array_int, ARRAY_SIZE(registerset_test_struct_array_int),
+ registerset_constants_struct_array_int, ARRAY_SIZE(registerset_constants_struct_array_int)},
+ {"struct bool [2]", "sab", 0, D3DXRS_BOOL, registerset_blob_struct_array,
+ registerset_test_struct_array_bool, ARRAY_SIZE(registerset_test_struct_array_bool),
+ registerset_constants_struct_array_bool, ARRAY_SIZE(registerset_constants_struct_array_bool)},
+ {"struct bool float [2]", "sabf", 32, D3DXRS_FLOAT4, registerset_blob_struct_array,
+ registerset_test_struct_array_bool_float, ARRAY_SIZE(registerset_test_struct_array_bool_float),
+ registerset_constants_struct_array_bool_float, ARRAY_SIZE(registerset_constants_struct_array_bool_float)},
+ {"struct int float [2]", "sanf", 16, D3DXRS_FLOAT4, registerset_blob_struct_array,
+ registerset_test_struct_array_int_float, ARRAY_SIZE(registerset_test_struct_array_int_float),
+ registerset_constants_struct_array_int_float, ARRAY_SIZE(registerset_constants_struct_array_int_float)},
+ /* struct struct */
+ {"struct struct float", "ssf", 0, D3DXRS_FLOAT4, registerset_blob_struct_struct,
+ registerset_test_struct_struct_float, ARRAY_SIZE(registerset_test_struct_struct_float),
+ registerset_constants_struct_struct_float, ARRAY_SIZE(registerset_constants_struct_struct_float)},
+ {"struct struct int", "ssn", 0, D3DXRS_INT4, registerset_blob_struct_struct,
+ registerset_test_struct_struct_int, ARRAY_SIZE(registerset_test_struct_struct_int),
+ registerset_constants_struct_struct_int, ARRAY_SIZE(registerset_constants_struct_struct_int)},
+ {"struct struct bool", "ssb", 0, D3DXRS_BOOL, registerset_blob_struct_struct,
+ registerset_test_struct_struct_bool, ARRAY_SIZE(registerset_test_struct_struct_bool),
+ registerset_constants_struct_struct_bool, ARRAY_SIZE(registerset_constants_struct_struct_bool)},
+ {"struct struct bool float", "ssbf", 32, D3DXRS_FLOAT4, registerset_blob_struct_struct,
+ registerset_test_struct_struct_bool_float, ARRAY_SIZE(registerset_test_struct_struct_bool_float),
+ registerset_constants_struct_struct_bool_float, ARRAY_SIZE(registerset_constants_struct_struct_bool_float)},
+ {"struct struct int float", "ssnf", 16, D3DXRS_FLOAT4, registerset_blob_struct_struct,
+ registerset_test_struct_struct_int_float, ARRAY_SIZE(registerset_test_struct_struct_int_float),
+ registerset_constants_struct_struct_int_float, ARRAY_SIZE(registerset_constants_struct_struct_int_float)},
+ /* special */
+ {"int ran", "ran", 0, D3DXRS_INT4, registerset_blob_special_int, NULL, 0,
+ registerset_constants_special_int, ARRAY_SIZE(registerset_constants_special_int)},
+ {"bigvec", "vaf", 0, D3DXRS_FLOAT4, registerset_blob_bigvec,
+ registerset_test_bigvec_float, ARRAY_SIZE(registerset_test_bigvec_float),
+ registerset_constants_bigvec_float, ARRAY_SIZE(registerset_constants_bigvec_float)},
+ {"cf", "cf", 0, D3DXRS_FLOAT4, registerset_blob_matrix_column_clamp,
+ registerset_test_matrix_column_clamp, ARRAY_SIZE(registerset_test_matrix_column_clamp),
+ registerset_constants_matrix_column_clamp, ARRAY_SIZE(registerset_constants_matrix_column_clamp)},
+};
+
+static void registerset_clear(IDirect3DDevice9 *device)
+{
+ DWORD zero[1024];
+ HRESULT hr;
+
+ memset(zero, 0xde, 4096);
+
+ hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, (FLOAT*)zero, 256);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, (FLOAT*)zero, 224);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_SetVertexShaderConstantB(device, 0, (BOOL*)zero, 16);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_SetPixelShaderConstantB(device, 0, (BOOL*)zero, 16);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, (INT*)zero, 16);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+
+ hr = IDirect3DDevice9_SetPixelShaderConstantI(device, 0, (INT*)zero, 16);
+ ok(hr == D3D_OK, "Clear failed, got %08x, expected %08x\n", hr, D3D_OK);
+}
+
+static UINT registerset_compare(IDirect3DDevice9 *device, BOOL is_vs, D3DXREGISTER_SET regset,
+ UINT start, UINT in_count, const DWORD *expected)
+{
+ DWORD ret[1024] = {0};
+ HRESULT hr;
+ UINT count = 1024, i, err = 0;
+
+ memset(ret, 0xde, 4096);
+
+ /* get shader constants */
+ switch (regset)
+ {
+ case D3DXRS_BOOL:
+ count = 16;
+ if (is_vs) hr = IDirect3DDevice9_GetVertexShaderConstantB(device, 0, (BOOL*)ret, 16);
+ else hr = IDirect3DDevice9_GetPixelShaderConstantB(device, 0, (BOOL*)ret, 16);
+ ok(hr == D3D_OK, "Get*ShaderConstantB failed, got %08x\n", hr);
+ break;
+
+ case D3DXRS_INT4:
+ count = 256;
+ if (is_vs) hr = IDirect3DDevice9_GetVertexShaderConstantI(device, 0, (INT*)ret, 16);
+ else hr = IDirect3DDevice9_GetPixelShaderConstantI(device, 0, (INT*)ret, 16);
+ ok(hr == D3D_OK, "Get*ShaderConstantI failed, got %08x\n", hr);
+ break;
+
+ case D3DXRS_FLOAT4:
+ if (is_vs) hr = IDirect3DDevice9_GetVertexShaderConstantF(device, 0, (FLOAT*)ret, 256);
+ else
+ {
+ count = 896;
+ hr = IDirect3DDevice9_GetPixelShaderConstantF(device, 0, (FLOAT*)ret, 224);
+ }
+ ok(hr == D3D_OK, "Get*ShaderConstantF failed, got %08x\n", hr);
+ break;
+
+ default:
+ ok(0, "This should not happen!\n");
+ break;
+ }
+
+ /* compare shader constants */
+ for (i = 0; i < count; ++i)
+ {
+ DWORD value = 0xdededede;
+ if (i >= start && i < start + in_count) value = expected[i - start];
+
+ ok(ret[i] == value, "Get*ShaderConstant failed, %u got 0x%x(%f) expected 0x%x(%f)\n", i,
+ ret[i], ((FLOAT *)ret)[i], value, *((FLOAT *)&value));
+ if (ret[i] != value) err++;
+ }
+
+ return err;
+}
+
+static UINT registerset_compare_all(IDirect3DDevice9 *device, BOOL is_vs, D3DXREGISTER_SET regset,
+ UINT start, UINT in_count, const DWORD *expected)
+{
+ D3DXREGISTER_SET regsets[] = {D3DXRS_BOOL, D3DXRS_INT4, D3DXRS_FLOAT4};
+ UINT err = 0, i;
+
+ for (i = 0; i < ARRAY_SIZE(regsets); i++)
+ {
+ if (regset == regsets[i])
+ err += registerset_compare(device, is_vs, regset, start, in_count, expected);
+ else
+ err += registerset_compare(device, is_vs, regsets[i], 0, 0, NULL);
+
+ err += registerset_compare(device, !is_vs, regsets[i], 0, 0, NULL);
+ }
+
+ return err;
+}
+
+static HRESULT registerset_apply(ID3DXConstantTable *ctable, IDirect3DDevice9 *device, D3DXHANDLE constant,
+ UINT index, DWORD count, enum Type type)
+{
+ const DWORD *in = registerset_test_input[index];
+ const D3DXMATRIX *inp[REGISTER_OUTPUT_SIZE / 16];
+ unsigned int i;
+
+ /* overlap, to see the difference between Array and PointerArray */
+ for (i = 0; i < REGISTER_OUTPUT_SIZE / 16; i++)
+ {
+ inp[i] = (D3DXMATRIX *)&in[i * 15];
+ }
+
+ switch (type)
+ {
+ case SetInt:
+ return ID3DXConstantTable_SetInt(ctable, device, constant, *((INT *)in));
+ case SetFloat:
+ return ID3DXConstantTable_SetFloat(ctable, device, constant, *((FLOAT *)in));
+ case SetBool:
+ return ID3DXConstantTable_SetBool(ctable, device, constant, *((BOOL *)in));
+ case SetIntArray:
+ return ID3DXConstantTable_SetIntArray(ctable, device, constant, (INT *)in, count);
+ case SetBoolArray:
+ return ID3DXConstantTable_SetBoolArray(ctable, device, constant, (BOOL *)in, count);
+ case SetFloatArray:
+ return ID3DXConstantTable_SetFloatArray(ctable, device, constant, (FLOAT *)in, count);
+ case SetMatrix:
+ return ID3DXConstantTable_SetMatrix(ctable, device, constant, (D3DXMATRIX *)in);
+ case SetMatrixTranspose:
+ return ID3DXConstantTable_SetMatrixTranspose(ctable, device, constant, (D3DXMATRIX *)in);
+ case SetMatrixArray:
+ return ID3DXConstantTable_SetMatrixArray(ctable, device, constant, (D3DXMATRIX *)in, count);
+ case SetMatrixTransposeArray:
+ return ID3DXConstantTable_SetMatrixTransposeArray(ctable, device, constant, (D3DXMATRIX *)in, count);
+ case SetVector:
+ return ID3DXConstantTable_SetVector(ctable, device, constant, (D3DXVECTOR4 *)in);
+ case SetVectorArray:
+ return ID3DXConstantTable_SetVectorArray(ctable, device, constant, (D3DXVECTOR4 *)in, count);
+ case SetValue:
+ return ID3DXConstantTable_SetValue(ctable, device, constant, in, count);
+ case SetMatrixPointerArray:
+ return ID3DXConstantTable_SetMatrixPointerArray(ctable, device, constant, inp, count);
+ case SetMatrixTransposePointerArray:
+ return ID3DXConstantTable_SetMatrixTransposePointerArray(ctable, device, constant, inp, count);
+ }
+
+ ok(0, "This should not happen!\n");
+ return D3D_OK;
+}
+
+static void test_registerset(void)
+{
+ UINT k;
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+ ULONG count;
+ D3DCAPS9 caps;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
+ || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ {
+ skip("Skipping: Test requires VS >= 3 and PS >= 3.\n");
+ IDirect3DDevice9_Release(device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ for (k = 0; k < ARRAY_SIZE(registerset_data); ++k)
+ {
+ const char *tablename = registerset_data[k].name;
+ const char *name = registerset_data[k].var;
+ ID3DXConstantTable *ctable;
+ D3DXCONSTANTTABLE_DESC tdesc;
+ D3DXHANDLE constant;
+ UINT i;
+ BOOL is_vs;
+ DWORD *ctab;
+
+ hr = D3DXGetShaderConstantTable(registerset_data[k].blob, &ctable);
+ ok(hr == D3D_OK, "D3DXGetShaderConstantTable \"%s\" failed, got %08x, expected %08x\n", tablename, hr, D3D_OK);
+
+ hr = ID3DXConstantTable_GetDesc(ctable, &tdesc);
+ ok(hr == D3D_OK, "GetDesc \"%s\" failed, got %08x, expected %08x\n", tablename, hr, D3D_OK);
+
+ ctab = ID3DXConstantTable_GetBufferPointer(ctable);
+ ok(ctab[0] == registerset_data[k].blob[3], "ID3DXConstantTable_GetBufferPointer failed\n");
+
+ is_vs = (tdesc.Version & 0xFFFF0000) == 0xFFFE0000;
+
+ for (i = 0; i < registerset_data[k].constant_count; ++i)
+ {
+ const char *fullname = registerset_data[k].constants[i].fullname;
+ const D3DXCONSTANT_DESC *expected_desc = ®isterset_data[k].constants[i].desc;
+ D3DXCONSTANT_DESC desc;
+ UINT nr = 0;
+ UINT ctaboffset = registerset_data[k].constants[i].ctaboffset;
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, fullname);
+ ok(constant != NULL, "GetConstantByName \"%s\" failed\n", fullname);
+
+ hr = ID3DXConstantTable_GetConstantDesc(ctable, constant, &desc, &nr);
+ ok(hr == D3D_OK, "GetConstantDesc \"%s\" failed, got %08x, expected %08x\n", fullname, hr, D3D_OK);
+
+ ok(!strcmp(expected_desc->Name, desc.Name), "GetConstantDesc \"%s\" failed, got \"%s\", expected \"%s\"\n",
+ fullname, desc.Name, expected_desc->Name);
+ ok(expected_desc->RegisterSet == desc.RegisterSet, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.RegisterSet, expected_desc->RegisterSet);
+ ok(expected_desc->RegisterIndex == desc.RegisterIndex,
+ "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.RegisterIndex, expected_desc->RegisterIndex);
+ ok(expected_desc->RegisterCount == desc.RegisterCount,
+ "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.RegisterCount, expected_desc->RegisterCount);
+ ok(expected_desc->Class == desc.Class, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Class, expected_desc->Class);
+ ok(expected_desc->Type == desc.Type, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.Type, expected_desc->Type);
+ ok(expected_desc->Rows == desc.Rows, "GetConstantDesc \"%s\" failed, got %#x, expected %#x\n",
+ fullname, desc.Rows, expected_desc->Rows);
+ ok(expected_desc->Columns == desc.Columns, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Columns, expected_desc->Columns);
+ ok(expected_desc->Elements == desc.Elements, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Elements, expected_desc->Elements);
+ ok(expected_desc->StructMembers == desc.StructMembers,
+ "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.StructMembers, expected_desc->StructMembers);
+ ok(expected_desc->Bytes == desc.Bytes, "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, desc.Bytes, expected_desc->Bytes);
+ if (ctaboffset)
+ {
+ ok(ctaboffset == (DWORD *)desc.DefaultValue - ctab,
+ "GetConstantDesc \"%s\" failed, got %u, expected %u\n",
+ fullname, (UINT)((DWORD *)desc.DefaultValue - ctab), ctaboffset);
+ }
+ }
+
+ constant = ID3DXConstantTable_GetConstantByName(ctable, NULL, name);
+ ok(constant != NULL, "GetConstantByName \"%s\" \"%s\" failed\n", tablename, name);
+
+ for (i = 0; i < registerset_data[k].test_count; ++i)
+ {
+ const struct registerset_test *test = ®isterset_data[k].tests[i];
+ UINT ret;
+
+ registerset_clear(device);
+
+ hr = registerset_apply(ctable, device, constant, test->in_index, test->in_count_min, test->type);
+ ok(hr == D3D_OK, "Set* \"%s\" index %u, count %u failed, got %x, expected %x\n", tablename, i,
+ test->in_count_min, hr, D3D_OK);
+
+ ret = registerset_compare_all(device, is_vs, registerset_data[k].regset,
+ registerset_data[k].start, test->out_count, test->out);
+ ok(ret == 0, "Get*ShaderConstant \"%s\" index %u, count %u failed\n", tablename, i, test->in_count_min);
+
+ if (test->in_count_max > test->in_count_min)
+ {
+ registerset_clear(device);
+
+ hr = registerset_apply(ctable, device, constant, test->in_index, test->in_count_max, test->type);
+ ok(hr == D3D_OK, "Set* \"%s\" index %u, count %u failed, got %x, expected %x\n", tablename, i,
+ test->in_count_max, hr, D3D_OK);
+
+ ret = registerset_compare_all(device, is_vs, registerset_data[k].regset,
+ registerset_data[k].start, test->out_count, test->out);
+ ok(ret == 0, "Get*ShaderConstant \"%s\" index %u, count %u failed\n", tablename, i, test->in_count_max);
+ }
+ }
+
+ count = ID3DXConstantTable_Release(ctable);
+ ok(count == 0, "Release \"%s\" failed, got %u, expected %u\n", tablename, count, 0);
+ }
+
+ /* Release resources */
+ count = IDirect3DDevice9_Release(device);
+ ok(count == 0, "The Direct3D device reference count was %u, should be 0\n", count);
+
+ count = IDirect3D9_Release(d3d);
+ ok(count == 0, "The Direct3D object referenct count was %u, should be 0\n", count);
+
+ if (wnd) DestroyWindow(wnd);
+}
+
+/*
+ * For D3DXRS_INT4 (int_count, ints[]):
+ * Native seems to just set the following shader blob up to the register count, which in bad cases is up
+ * to 4 times larger than the actual correct value. This explanes where the "bogus" values for these cases
+ * come from. Somehow they forgot that the registers are INT4 and not INT.
+ */
+static const struct
+{
+ const char *name;
+ const DWORD *blob;
+ unsigned int float_count;
+ unsigned int int_count;
+ unsigned int bool_count;
+ const DWORD floats[1024];
+ const DWORD ints[256];
+ const DWORD bools[16];
+}
+registerset_defaults_data[] =
+{
+ {"scalar", registerset_blob_scalar, 12, 4, 1,
+ {0x40a33333, 0x00000000, 0x00000000, 0x00000000, 0x41300000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000008, 0x00000000, 0x00000001},
+ {0xffffffff}},
+ {"scalar array", registerset_blob_scalar_array, 24, 8, 2,
+ {0x40466666, 0x00000000, 0x00000000, 0x00000000, 0x404ccccd, 0x00000000, 0x00000000, 0x00000000,
+ 0x41600000, 0x00000000, 0x00000000, 0x00000000, 0x41700000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000020, 0x00000000, 0x00000001, 0x00000000, 0x00000021, 0x00000000, 0x00000001, 0x00000000},
+ {0xffffffff, 0x00000000}},
+ {"vector", registerset_blob_vector, 12, 12, 3,
+ {0x40a33333, 0x40a66666, 0x40a9999a, 0x00000000, 0x41300000, 0x42aa0000, 0x42780000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000},
+ {0x00000007, 0x00000008, 0x00000009, 0x00000000, 0x00666e76, 0x41300000, 0x42aa0000, 0x42780000,
+ 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369},
+ {0xffffffff, 0x00000000, 0xffffffff}},
+ {"vector array", registerset_blob_vector_array, 24, 24, 6,
+ {0x425c6666, 0x425ccccd, 0x425d3333, 0x00000000, 0x425d999a, 0x425e0000, 0x425e6666, 0x00000000,
+ 0x43020000, 0x430c0000, 0x43160000, 0x00000000, 0x43200000, 0x432a0000, 0x43340000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000},
+ {0x00000046, 0x00000050, 0x0000005a, 0x00000000, 0x00000064, 0x0000006e, 0x00000078, 0x00000000,
+ 0x666e6176, 0xababab00, 0x00020001, 0x00030001, 0x00000002, 0x00000000, 0x43020000, 0x430c0000,
+ 0x43160000, 0x00000000, 0x43200000, 0x432a0000, 0x43340000, 0x00000000, 0x335f7376, 0x4d00305f},
+ {0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"column", registerset_blob_column, 24, 24, 6,
+ {0x4171999a, 0x4174cccd, 0x41780000, 0x00000000, 0x41733333, 0x41766666, 0x4179999a, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x41f00000, 0x42040000, 0x42080000, 0x00000000, 0x41f80000, 0x42000000, 0x42100000, 0x00000000},
+ {0x00000004, 0x00000006, 0x00000008, 0x00000000, 0x00000005, 0x00000007, 0x00000009, 0x00000000,
+ 0x00666e63, 0x41f00000, 0x42040000, 0x42080000, 0x00000000, 0x41f80000, 0x42000000, 0x42100000,
+ 0x00000000, 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c},
+ {0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"column array", registerset_blob_column_array, 48, 48, 12,
+ {0x3f8ccccd, 0x40533333, 0x40b00000, 0x00000000, 0x400ccccd, 0x408ccccd, 0x40d33333, 0x00000000,
+ 0x40f66666, 0x411e6666, 0x3fa66666, 0x00000000, 0x410ccccd, 0x3f99999a, 0x3fb33333, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, 0x00000000,
+ 0x43960000, 0x43978000, 0x43980000, 0x00000000, 0x43968000, 0x43970000, 0x43990000, 0x00000000,
+ 0x43af0000, 0x44238000, 0x43a30000, 0x00000000, 0x43b68000, 0x44190000, 0x4479c000, 0x00000000},
+ {0x0000000e, 0x00000010, 0x00000012, 0x00000000, 0x0000000f, 0x00000047, 0x00000013, 0x00000000,
+ 0x00000037, 0x00000060, 0x00000061, 0x00000000, 0x0000003f, 0x00000060, 0x0000000d, 0x00000000,
+ 0x666e6163, 0xababab00, 0x00020003, 0x00020003, 0x00000002, 0x00000000, 0x43960000, 0x43978000,
+ 0x43980000, 0x00000000, 0x43968000, 0x43970000, 0x43990000, 0x00000000, 0x43af0000, 0x44238000,
+ 0x43a30000, 0x00000000, 0x43b68000, 0x44190000, 0x4479c000, 0x00000000, 0x335f7376, 0x4d00305f,
+ 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970},
+ {0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"row", registerset_blob_row, 36, 24, 6,
+ {0x42be3333, 0x42be6666, 0x00000000, 0x00000000, 0x42be999a, 0x42becccd, 0x00000000, 0x00000000,
+ 0x42bf0000, 0x42bf3333, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x42140000, 0x41500000, 0x00000000, 0x00000000, 0x42c40000, 0x42580000, 0x00000000, 0x00000000,
+ 0x429a0000, 0x42100000, 0x00000000, 0x00000000},
+ {0x00000050, 0x00000051, 0x00000001, 0x00000000, 0x00000052, 0x00000053, 0x00000001, 0x00000000,
+ 0x00000054, 0x00000055, 0x00000001, 0x00000000, 0x00666e72, 0x42140000, 0x41500000, 0x00000000,
+ 0x00000000, 0x42c40000, 0x42580000, 0x00000000, 0x00000000, 0x429a0000, 0x42100000, 0x00000000},
+ {0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff}},
+ {"row array", registerset_blob_row_array, 72, 48, 12,
+ {0x3fc00000, 0x40333333, 0x00000000, 0x00000000, 0x40533333, 0x409ccccd, 0x00000000, 0x00000000,
+ 0x40bccccd, 0x40d9999a, 0x00000000, 0x00000000, 0x40fccccd, 0x41080000, 0x00000000, 0x00000000,
+ 0x41166666, 0x3fa66666, 0x00000000, 0x00000000, 0x3f99999a, 0x3f8ccccd, 0x00000000, 0x00000000,
+ 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000,
+ 0x420c0000, 0x42200000, 0x00000000, 0x00000000, 0x42700000, 0x42a00000, 0x00000000, 0x00000000,
+ 0x428c0000, 0x42600000, 0x00000000, 0x00000000, 0x42140000, 0x41500000, 0x00000000, 0x00000000,
+ 0x42c40000, 0x42580000, 0x00000000, 0x00000000, 0x429a0000, 0x42100000, 0x00000000, 0x00000000},
+ {0x00000004, 0x00000005, 0x00000001, 0x00000000, 0x00000006, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000008, 0x00000001, 0x00000001, 0x00000000, 0x00000005, 0x00000003, 0x00000001, 0x00000000,
+ 0x00000009, 0x00000006, 0x00000001, 0x00000000, 0x00000007, 0x00000003, 0x00000001, 0x00000000,
+ 0x666e6172, 0xababab00, 0x00020002, 0x00020003, 0x00000002, 0x00000000, 0x420c0000, 0x42200000,
+ 0x00000000, 0x00000000, 0x42700000, 0x42a00000, 0x00000000, 0x00000000, 0x428c0000, 0x42600000,
+ 0x00000000, 0x00000000, 0x42140000, 0x41500000, 0x00000000, 0x00000000, 0x42c40000, 0x42580000},
+ {0xffffffff, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"struct", registerset_blob_struct, 24, 16, 4,
+ {0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000, 0x400ccccd, 0x40533333, 0x408ccccd, 0x00000000,
+ 0x41f80000, 0x00000000, 0x00000000, 0x00000000, 0x42000000, 0x42040000, 0x42080000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000},
+ {0x0000000b, 0x00000000, 0x00000001, 0x00000000, 0x0000000c, 0x0000000d, 0x0000000e, 0x00000000,
+ 0x00666e73, 0x7600666e, 0xab00666e, 0x00000204, 0x0000019c, 0x00000207, 0x000001b0, 0x00000005},
+ {0xffffffff, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"struct array", registerset_blob_struct_array, 48, 32, 8,
+ {0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000, 0x40066666, 0x40466666, 0x40833333, 0x00000000,
+ 0x40a33333, 0x00000000, 0x00000000, 0x00000000, 0x40c33333, 0x40e33333, 0x4101999a, 0x00000000,
+ 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x422c0000, 0x42300000, 0x00000000,
+ 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x42280000, 0x422c0000, 0x42300000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, 0x00000000},
+ {0x00000015, 0x00000000, 0x00000001, 0x00000000, 0x00000016, 0x00000017, 0x00000018, 0x00000000,
+ 0x00000019, 0x00000000, 0x00000001, 0x00000000, 0x0000001a, 0x0000001b, 0x0000001c, 0x00000000,
+ 0x666e6173, 0x00666e00, 0x00666e76, 0x00000275, 0x000001ec, 0x00000278, 0x00000200, 0x00000005,
+ 0x00040001, 0x00020002, 0x0000027c, 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff}},
+ {"struct struct", registerset_blob_struct_struct, 48, 24, 6,
+ {0x3f8ccccd, 0x00000000, 0x00000000, 0x00000000, 0x40066666, 0x00000000, 0x00000000, 0x00000000,
+ 0x40466666, 0x40833333, 0x40a33333, 0x00000000, 0x40c33333, 0x00000000, 0x00000000, 0x00000000,
+ 0x42240000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x422c0000, 0x42300000, 0x42240000, 0x00000000, 0x42280000, 0x00000000, 0x00000000, 0x00000000,
+ 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x3f800000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000047, 0x00000000, 0x00000001, 0x00000000, 0x00000048, 0x00000000, 0x00000001, 0x00000000,
+ 0x00000049, 0x0000004a, 0x0000004b, 0x00000000, 0x0000004c, 0x00000000, 0x00000001, 0x00000000,
+ 0x666e7373, 0x00666e00, 0x00666e76, 0x00000321, 0x0000026c, 0x00000324, 0x00000280, 0x00000005},
+ {0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000}},
+ {"int ran", registerset_blob_special_int, 0, 36, 0,
+ {0x00000000},
+ {0x00000004, 0x00000005, 0x00000001, 0x00000000, 0x00000006, 0x00000001, 0x00000001, 0x00000000,
+ 0x00000008, 0x00000001, 0x00000001, 0x00000000, 0x00000002, 0x00000003, 0x00000001, 0x00000000,
+ 0x00000004, 0x00000007, 0x00000001, 0x00000000, 0x00000009, 0x00000001, 0x00000001, 0x00000000,
+ 0x335f7376, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c, 0x72656461,
+ 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932},
+ {0x00000000}},
+ /* DefaultValue = NULL */
+ {"big vector", registerset_blob_bigvec},
+ {"matrix column clamp", registerset_blob_matrix_column_clamp, 12, 0, 0,
+ {0x3f8ccccd, 0x40b00000, 0x411e6666, 0x3fc00000, 0x400ccccd, 0x40d33333, 0x3f99999a, 0x3fcccccd,
+ 0x420551ec, 0x00000000, 0x00000000, 0x00000000},
+ {0x00000000},
+ {0x00000000}},
+};
+
+static void test_registerset_defaults(void)
+{
+ UINT k;
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+ ULONG count;
+ D3DCAPS9 caps;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
+ if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
+ || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ {
+ skip("Skipping: Test requires VS >= 3 and PS >= 3.\n");
+ IDirect3DDevice9_Release(device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ for (k = 0; k < ARRAY_SIZE(registerset_defaults_data); ++k)
+ {
+ const char *tablename = registerset_defaults_data[k].name;
+ ID3DXConstantTable *ctable;
+ D3DXCONSTANTTABLE_DESC tdesc;
+ BOOL is_vs;
+ UINT ret;
+
+ hr = D3DXGetShaderConstantTable(registerset_defaults_data[k].blob, &ctable);
+ ok(hr == D3D_OK, "D3DXGetShaderConstantTable \"%s\" failed, got %08x, expected %08x\n", tablename, hr, D3D_OK);
+
+ hr = ID3DXConstantTable_GetDesc(ctable, &tdesc);
+ ok(hr == D3D_OK, "GetDesc \"%s\" failed, got %08x, expected %08x\n", tablename, hr, D3D_OK);
+
+ is_vs = (tdesc.Version & 0xFFFF0000) == 0xFFFE0000;
+
+ registerset_clear(device);
+
+ hr = ID3DXConstantTable_SetDefaults(ctable, device);
+ ok(hr == D3D_OK, "SetDefaults \"%s\" failed, got %08x, expected %08x\n", tablename, hr, D3D_OK);
+
+ ret = registerset_compare(device, is_vs, D3DXRS_FLOAT4, 0, registerset_defaults_data[k].float_count,
+ registerset_defaults_data[k].floats);
+ ok(ret == 0, "Get*ShaderConstantF \"%s\" failed\n", tablename);
+
+ ret = registerset_compare(device, is_vs, D3DXRS_INT4, 0, registerset_defaults_data[k].int_count,
+ registerset_defaults_data[k].ints);
+ ok(ret == 0, "Get*ShaderConstantI \"%s\" failed\n", tablename);
+
+ ret = registerset_compare(device, is_vs, D3DXRS_BOOL, 0, registerset_defaults_data[k].bool_count,
+ registerset_defaults_data[k].bools);
+ ok(ret == 0, "Get*ShaderConstantB \"%s\" failed\n", tablename);
+
+ count = ID3DXConstantTable_Release(ctable);
+ ok(count == 0, "Release \"%s\" failed, got %u, expected %u\n", tablename, count, 0);
+ }
+
+ /* Release resources */
+ count = IDirect3DDevice9_Release(device);
+ ok(count == 0, "The Direct3D device reference count was %u, should be 0\n", count);
+
+ count = IDirect3D9_Release(d3d);
+ ok(count == 0, "The Direct3D object referenct count was %u, should be 0\n", count);
+
+ if (wnd) DestroyWindow(wnd);
+}
+
+static void test_shader_semantics(void)
+{
+ static const DWORD invalid_1[] =
+ {
+ 0x00000200
+ },
+ invalid_2[] =
+ {
+ 0xfffe0400
+ },
+ invalid_3[] =
+ {
+ 0xfffe0000
+ },
+ vs_1_1[] =
+ {
+ 0xfffe0101, /* vs_1_1 */
+ 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x0000001f, 0x80000003, 0x900f0001, /* dcl_normal v1 */
+ 0x0000001f, 0x8001000a, 0x900f0002, /* dcl_color1 v2 */
+ 0x0000001f, 0x80000005, 0x900f0003, /* dcl_texcoord0 v3 */
+ 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x00000001, 0xd00f0001, 0x90e40002, /* mov oD1, v2 */
+ 0x00000001, 0xe0070000, 0x90e40001, /* mov oT0.xyz, v1 */
+ 0x00000001, 0xc00f0001, 0x90ff0002, /* mov oFog, v2.w */
+ 0x00000001, 0xc00f0002, 0x90ff0001, /* mov oPts, v1.w */
+ 0x0000ffff
+ },
+ vs_2_0[] =
+ {
+ 0xfffe0200, /* vs_2_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x0200001f, 0x80000003, 0x900f0001, /* dcl_normal v1 */
+ 0x0200001f, 0x8001000a, 0x900f0002, /* dcl_color1 v2 */
+ 0x0200001f, 0x80000005, 0x900f0003, /* dcl_texcoord0 v3 */
+ 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
+ 0x02000001, 0xd00f0001, 0x90e40002, /* mov oD1, v2 */
+ 0x02000001, 0xe0070000, 0x90e40003, /* mov oT0.xyz, v3 */
+ 0x02000001, 0xc00f0001, 0x90ff0002, /* mov oFog, v2.w */
+ 0x02000001, 0xc00f0002, 0x90ff0001, /* mov oPts, v1.w */
+ 0x0000ffff
+ },
+ vs_3_0[] =
+ {
+ 0xfffe0300, /* vs_3_0 */
+ 0x0002fffe, 0x0200000f, 0x00000000, /* comment */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
+ 0x0200001f, 0x80000003, 0x900f0001, /* dcl_normal v1 */
+ 0x0200001f, 0x8001000a, 0x900f0002, /* dcl_color1 v2 */
+ 0x0200001f, 0x80000005, 0x900f0003, /* dcl_texcoord0 v3 */
+ 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
+ 0x0200001f, 0x8001000a, 0xe00f0001, /* dcl_color1 o1 */
+ 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
+ 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
+ 0x0200001f, 0x80000004, 0xe00f0004, /* dcl_psize o4 */
+ 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
+ 0x02000001, 0xe00f0001, 0x90e40002, /* mov o1, v2 */
+ 0x02000001, 0xe0070002, 0x90e40003, /* mov o2.xyz, v3 */
+ 0x02000001, 0xe00f0003, 0x90ff0002, /* mov o3, v2.w */
+ 0x02000001, 0xe00f0004, 0x90ff0001, /* mov o4, v1.w */
+ 0x0000ffff
+ },
+ ps_1_1[] =
+ {
+ 0xffff0101, /* ps_1_1 */
+ 0x00000042, 0xb00f0000, /* tex t0 */
+ 0x00000002, 0x800f0000, 0x90e40000, 0xb0e40000, /* add r0, v0, t0 */
+ 0x0000ffff
+ },
+ ps_2_0[] =
+ {
+ 0xffff0200, /* ps_2_0 */
+ 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
+ 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
+ 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
+ 0x0000ffff
+ },
+ ps_3_0[] =
+ {
+ 0xffff0300, /* ps_3_0 */
+ 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1 v0 */
+ 0x0200001f, 0x80000003, 0x900f0001, /* dcl_normal v1 */
+ 0x0200001f, 0x80000005, 0x900f0002, /* dcl_texcoord0 v2 */
+ 0x0200001f, 0x8000000b, 0x900f0003, /* dcl_fog v3 */
+ 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
+ 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
+ 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
+ 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
+ 0x03000002, 0x800f0800, 0x80e40000, 0x90e40003, /* add oC0, r0, v3 */
+ 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
+ 0x03000005, 0x800f0801, 0x80e40001, 0x90e40002, /* mul oC1, r1, v2 */
+ 0x02000001, 0x800f0802, 0x90441000, /* mov oC2, vPos.xyxy */
+ 0x04000058, 0x800f0803, 0x90e41001, 0x90e40000, 0xa0e40000, /* cmp oC3, vFace, v0, c0 */
+ 0x02000001, 0x900f0800, 0x90ff0001, /* mov oDepth, v1.w */
+ 0x0000ffff
+ };
+ static const struct
+ {
+ const DWORD *shader;
+ D3DXSEMANTIC expected_input[MAXD3DDECLLENGTH];
+ D3DXSEMANTIC expected_output[MAXD3DDECLLENGTH];
+ }
+ tests[] =
+ {
+ {vs_1_1, {{0, 0}, {3, 0}, {10, 1}, {5, 0}, {~0, ~0}}, {{5, 0}, {10, 1}, {0, 0}, {11, 0}, {4, 0}, {~0, ~0}}},
+ {vs_2_0, {{0, 0}, {3, 0}, {10, 1}, {5, 0}, {~0, ~0}}, {{5, 0}, {10, 1}, {0, 0}, {11, 0}, {4, 0}, {~0, ~0}}},
+ {vs_3_0, {{0, 0}, {3, 0}, {10, 1}, {5, 0}, {~0, ~0}}, {{0, 0}, {10, 1}, {5, 0}, {11, 0}, {4, 0}, {~0, ~0}}},
+ {ps_1_1, {{5, 0}, {10, 0}, {~0, ~0}}, {{10, 0}, {~0, ~0}}},
+ {ps_2_0, {{10, 0}, {5, 0}, {~0, ~0}}, {{10, 0}, {~0, ~0}}},
+ {ps_3_0, {{10, 1}, {3,0}, {5, 0}, {11, 0}, {~0, ~0}}, {{10, 0}, {10, 1}, {10, 2}, {10, 3}, {12, 0}, {~0, ~0}}},
+ };
+ D3DXSEMANTIC semantics[MAXD3DDECLLENGTH];
+ unsigned int count, count2;
+ unsigned int i, j;
+ HRESULT hr;
+
+ hr = D3DXGetShaderInputSemantics(invalid_1, NULL, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "Unexpected hr %#x.\n", hr);
+ hr = D3DXGetShaderInputSemantics(invalid_2, NULL, NULL);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ hr = D3DXGetShaderInputSemantics(invalid_3, NULL, NULL);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = D3DXGetShaderInputSemantics(vs_1_1, NULL, NULL);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ hr = D3DXGetShaderInputSemantics(vs_1_1, semantics, NULL);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
+ const DWORD *shader = tests[i].shader;
+
+ hr = D3DXGetShaderInputSemantics(shader, NULL, &count);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ hr = D3DXGetShaderInputSemantics(shader, semantics, &count2);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ ok(count == count2, "Semantics count %u differs from previous count %u.\n", count2, count);
+ for (j = 0; j < count; ++j)
+ {
+ ok(semantics[j].Usage == tests[i].expected_input[j].Usage
+ && semantics[j].UsageIndex == tests[i].expected_input[j].UsageIndex,
+ "Unexpected semantic %u, %u, test %u, idx %u.\n",
+ semantics[j].Usage, semantics[j].UsageIndex, i, j);
+ }
+ ok(tests[i].expected_input[j].Usage == ~0 && tests[i].expected_input[j].UsageIndex == ~0,
+ "Unexpected semantics count %u.\n", count);
+ hr = D3DXGetShaderOutputSemantics(shader, NULL, &count);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ hr = D3DXGetShaderOutputSemantics(shader, semantics, &count2);
+ ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+ ok(count == count2, "Semantics count %u differs from previous count %u.\n", count2, count);
+ for (j = 0; j < count; ++j)
+ {
+ ok(semantics[j].Usage == tests[i].expected_output[j].Usage
+ && semantics[j].UsageIndex == tests[i].expected_output[j].UsageIndex,
+ "Unexpected semantic %u, %u, test %u, idx %u.\n",
+ semantics[j].Usage, semantics[j].UsageIndex, i, j);
+ }
+ ok(tests[i].expected_output[j].Usage == ~0 && tests[i].expected_output[j].UsageIndex == ~0,
+ "Unexpected semantics count %u.\n", count);
+ }
+}
+
+START_TEST(shader)
+{
+ test_get_shader_size();
+ test_get_shader_version();
+ test_find_shader_comment();
+ test_get_shader_constant_table_ex();
+ test_constant_tables();
+ test_setting_constants();
+ test_get_sampler_index();
+ test_get_shader_samplers();
+ test_get_shader_constant_variables();
+ test_registerset();
+ test_registerset_defaults();
+ test_shader_semantics();
+}
--- /dev/null
+/*
+ * Tests for the D3DX9 surface functions
+ *
+ * Copyright 2009 Tony Wasserka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include <assert.h>
+#include "wine/test.h"
+#include "d3dx9tex.h"
+#include "resources.h"
+
+#define check_release(obj, exp) _check_release(__LINE__, obj, exp)
+static inline void _check_release(unsigned int line, IUnknown *obj, int exp)
+{
+ int ref = IUnknown_Release(obj);
+ ok_(__FILE__, line)(ref == exp, "Invalid refcount. Expected %d, got %d\n", exp, ref);
+}
+
+/* 1x1 bmp (1 bpp) */
+static const unsigned char bmp_1bpp[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
+0x00,0x00
+};
+
+/* 1x1 bmp (2 bpp) */
+static const unsigned char bmp_2bpp[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
+0x00,0x00
+};
+
+/* 1x1 bmp (4 bpp) */
+static const unsigned char bmp_4bpp[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
+0x00,0x00
+};
+
+/* 1x1 bmp (8 bpp) */
+static const unsigned char bmp_8bpp[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xf1,0xf2,0xf3,0x80,0xf4,0xf5,0xf6,0x81,0x00,0x00,
+0x00,0x00
+};
+
+static const unsigned char png_grayscale[] =
+{
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
+ 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x3a, 0x7e, 0x9b, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44,
+ 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0x0f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x1b,
+ 0xb6, 0xee, 0x56, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
+ 0x60, 0x82
+};
+
+/* 2x2 A8R8G8B8 pixel data */
+static const unsigned char pixdata[] = {
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+};
+
+/* invalid image file */
+static const unsigned char noimage[4] = {
+0x11,0x22,0x33,0x44
+};
+
+/* 2x2 24-bit dds, 2 mipmaps */
+static const unsigned char dds_24bit[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
+0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+};
+
+/* 2x2 16-bit dds, no mipmaps */
+static const unsigned char dds_16bit[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
+0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
+};
+
+/* 4x4 cube map dds */
+static const unsigned char dds_cube_map[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
+0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50
+};
+
+/* 4x4x2 volume map dds, 2 mipmaps */
+static const unsigned char dds_volume_map[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
+0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
+0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
+};
+
+static HRESULT create_file(const char *filename, const unsigned char *data, const unsigned int size)
+{
+ DWORD received;
+ HANDLE hfile;
+
+ hfile = CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if(hfile == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError());
+
+ if(WriteFile(hfile, data, size, &received, NULL))
+ {
+ CloseHandle(hfile);
+ return D3D_OK;
+ }
+
+ CloseHandle(hfile);
+ return D3DERR_INVALIDCALL;
+}
+
+/* dds_header.flags */
+#define DDS_CAPS 0x00000001
+#define DDS_HEIGHT 0x00000002
+#define DDS_WIDTH 0x00000004
+#define DDS_PITCH 0x00000008
+#define DDS_PIXELFORMAT 0x00001000
+#define DDS_MIPMAPCOUNT 0x00020000
+#define DDS_LINEARSIZE 0x00080000
+
+/* dds_header.caps */
+#define DDSCAPS_ALPHA 0x00000002
+#define DDS_CAPS_TEXTURE 0x00001000
+
+/* dds_pixel_format.flags */
+#define DDS_PF_ALPHA 0x00000001
+#define DDS_PF_ALPHA_ONLY 0x00000002
+#define DDS_PF_FOURCC 0x00000004
+#define DDS_PF_RGB 0x00000040
+#define DDS_PF_LUMINANCE 0x00020000
+#define DDS_PF_BUMPDUDV 0x00080000
+
+struct dds_pixel_format
+{
+ DWORD size;
+ DWORD flags;
+ DWORD fourcc;
+ DWORD bpp;
+ DWORD rmask;
+ DWORD gmask;
+ DWORD bmask;
+ DWORD amask;
+};
+
+struct dds_header
+{
+ DWORD size;
+ DWORD flags;
+ DWORD height;
+ DWORD width;
+ DWORD pitch_or_linear_size;
+ DWORD depth;
+ DWORD miplevels;
+ DWORD reserved[11];
+ struct dds_pixel_format pixel_format;
+ DWORD caps;
+ DWORD caps2;
+ DWORD caps3;
+ DWORD caps4;
+ DWORD reserved2;
+};
+
+/* fills dds_header with reasonable default values */
+static void fill_dds_header(struct dds_header *header)
+{
+ memset(header, 0, sizeof(*header));
+
+ header->size = sizeof(*header);
+ header->flags = DDS_CAPS | DDS_WIDTH | DDS_HEIGHT | DDS_PIXELFORMAT;
+ header->height = 4;
+ header->width = 4;
+ header->pixel_format.size = sizeof(header->pixel_format);
+ /* X8R8G8B8 */
+ header->pixel_format.flags = DDS_PF_RGB;
+ header->pixel_format.fourcc = 0;
+ header->pixel_format.bpp = 32;
+ header->pixel_format.rmask = 0xff0000;
+ header->pixel_format.gmask = 0x00ff00;
+ header->pixel_format.bmask = 0x0000ff;
+ header->pixel_format.amask = 0;
+ header->caps = DDS_CAPS_TEXTURE;
+}
+
+#define check_dds_pixel_format(flags, fourcc, bpp, rmask, gmask, bmask, amask, format) \
+ check_dds_pixel_format_(__LINE__, flags, fourcc, bpp, rmask, gmask, bmask, amask, format)
+static void check_dds_pixel_format_(unsigned int line,
+ DWORD flags, DWORD fourcc, DWORD bpp,
+ DWORD rmask, DWORD gmask, DWORD bmask, DWORD amask,
+ D3DFORMAT expected_format)
+{
+ HRESULT hr;
+ D3DXIMAGE_INFO info;
+ struct
+ {
+ DWORD magic;
+ struct dds_header header;
+ BYTE data[256];
+ } dds;
+
+ dds.magic = MAKEFOURCC('D','D','S',' ');
+ fill_dds_header(&dds.header);
+ dds.header.pixel_format.flags = flags;
+ dds.header.pixel_format.fourcc = fourcc;
+ dds.header.pixel_format.bpp = bpp;
+ dds.header.pixel_format.rmask = rmask;
+ dds.header.pixel_format.gmask = gmask;
+ dds.header.pixel_format.bmask = bmask;
+ dds.header.pixel_format.amask = amask;
+ memset(dds.data, 0, sizeof(dds.data));
+
+ hr = D3DXGetImageInfoFromFileInMemory(&dds, sizeof(dds), &info);
+ ok_(__FILE__, line)(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x for pixel format %#x, expected %#x\n",
+ hr, expected_format, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ ok_(__FILE__, line)(info.Format == expected_format, "D3DXGetImageInfoFromFileInMemory returned format %#x, expected %#x\n",
+ info.Format, expected_format);
+ }
+}
+
+static void test_dds_header_handling(void)
+{
+ int i;
+ HRESULT hr;
+ D3DXIMAGE_INFO info;
+ struct
+ {
+ DWORD magic;
+ struct dds_header header;
+ BYTE data[4096 * 1024];
+ } *dds;
+
+ struct
+ {
+ struct dds_pixel_format pixel_format;
+ DWORD flags;
+ DWORD width;
+ DWORD height;
+ DWORD pitch;
+ DWORD miplevels;
+ DWORD pixel_data_size;
+ struct
+ {
+ HRESULT hr;
+ UINT miplevels;
+ }
+ expected;
+ } tests[] = {
+ /* pitch is ignored */
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, 0, 4, 4, 0, 0,
+ 63 /* pixel data size */, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 0 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 2 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 3 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 4 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 16 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, 1024 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, DDS_PITCH, 4, 4, -1 /* pitch */, 0,
+ 64, { D3D_OK, 1 } },
+ /* linear size is ignored */
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 4, 4, 0, 0,
+ 7 /* pixel data size */, { D3DXERR_INVALIDDATA, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 0 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 1 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 2 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 9 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, 16 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_LINEARSIZE, 4, 4, -1 /* linear size */, 0,
+ 8, { D3D_OK, 1 } },
+ /* integer overflows */
+ { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000000, 0x80000000 /* 0x80000000 * 0x80000000 * 4 = 0 */, 0, 0,
+ 64, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x8000100, 0x800100 /* 0x8000100 * 0x800100 * 4 = 262144 */, 0, 0,
+ 64, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0, 0,
+ 4, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0 }, 0, 0x80000001, 0x80000001 /* 0x80000001 * 0x80000001 * 4 = 4 */, 0, 0,
+ 3 /* pixel data size */, { D3DXERR_INVALIDDATA, 0 } },
+ /* file size is validated */
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 64, 0, 0, 49151, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 64, 0, 0, 49152, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 65279, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 65280, { D3D_OK, 4 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 9, 65540, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 64, 0, 9, 65541, { D3D_OK, 9 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196607, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196608, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 196609, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 1, 196607, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 1, 196608, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 196607, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 196608, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 400000, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 262142, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 262143, { D3D_OK, 9 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 10, 262145, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 10, 262146, { D3D_OK, 10 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 262175, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 262176, { D3D_OK, 20 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 32767, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 32768, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 32767, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 32768, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 43703, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 43704, { D3D_OK, 9 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 43791, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 43792, { D3D_OK, 20 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 65535, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, 0, 256, 256, 0, 0, 65536, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 65535, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 0, 65536, { D3D_OK, 1 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 87407, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 9, 87408, { D3D_OK, 9 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 87583, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 256, 0, 20, 87584, { D3D_OK, 20 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 21759, { D3DXERR_INVALIDDATA, 0 } },
+ { { 32, DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 }, DDS_MIPMAPCOUNT, 256, 64, 0, 4, 21760, { D3D_OK, 4 } },
+ /* DDS_MIPMAPCOUNT is ignored */
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 0, 262146, { D3D_OK, 1 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 2, 262146, { D3D_OK, 2 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 9, 262146, { D3D_OK, 9 } },
+ { { 32, DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0x000000 }, 0, 256, 256, 0, 10, 262146, { D3D_OK, 10 } },
+ };
+
+ dds = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dds));
+ if (!dds)
+ {
+ skip("Failed to allocate memory.\n");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
+ {
+ DWORD file_size = sizeof(dds->magic) + sizeof(dds->header) + tests[i].pixel_data_size;
+ assert(file_size <= sizeof(*dds));
+
+ dds->magic = MAKEFOURCC('D','D','S',' ');
+ fill_dds_header(&dds->header);
+ dds->header.flags |= tests[i].flags;
+ dds->header.width = tests[i].width;
+ dds->header.height = tests[i].height;
+ dds->header.pitch_or_linear_size = tests[i].pitch;
+ dds->header.miplevels = tests[i].miplevels;
+ dds->header.pixel_format = tests[i].pixel_format;
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds, file_size, &info);
+ ok(hr == tests[i].expected.hr, "%d: D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n",
+ i, hr, tests[i].expected.hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(info.MipLevels == tests[i].expected.miplevels, "%d: Got MipLevels %u, expected %u\n",
+ i, info.MipLevels, tests[i].expected.miplevels);
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, dds);
+}
+
+static void test_D3DXGetImageInfo(void)
+{
+ HRESULT hr;
+ D3DXIMAGE_INFO info;
+ BOOL testdummy_ok, testbitmap_ok;
+
+ hr = create_file("testdummy.bmp", noimage, sizeof(noimage)); /* invalid image */
+ testdummy_ok = SUCCEEDED(hr);
+
+ hr = create_file("testbitmap.bmp", bmp_1bpp, sizeof(bmp_1bpp)); /* valid image */
+ testbitmap_ok = SUCCEEDED(hr);
+
+ /* D3DXGetImageInfoFromFile */
+ if(testbitmap_ok) {
+ hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileA("testbitmap.bmp", NULL); /* valid image, second parameter is NULL */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
+ } else skip("Couldn't create \"testbitmap.bmp\"\n");
+
+ if(testdummy_ok) {
+ hr = D3DXGetImageInfoFromFileA("testdummy.bmp", NULL); /* invalid image, second parameter is NULL */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileA("testdummy.bmp", &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+ } else skip("Couldn't create \"testdummy.bmp\"\n");
+
+ hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileA("filedoesnotexist.bmp", NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileA("", &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileA(NULL, &info);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileA(NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* D3DXGetImageInfoFromResource */
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &info); /* RT_BITMAP */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &info); /* RT_RCDATA */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, MAKEINTRESOURCEA(IDS_STRING), NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, "resourcedoesnotexist", NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromResourceA(NULL, NULL, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+
+ /* D3DXGetImageInfoFromFileInMemory */
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, sizeof(bmp_1bpp), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, sizeof(bmp_1bpp)+5, &info); /* too large size */
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, sizeof(bmp_1bpp), NULL);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), NULL);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXGetImageInfoFromFileInMemory(noimage, sizeof(noimage), &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ todo_wine {
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, sizeof(bmp_1bpp)-1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+ }
+
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp+1, sizeof(bmp_1bpp)-1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, 0, &info);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, &info);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(noimage, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, &info);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(NULL, 4, &info);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXGetImageInfoFromFileInMemory(NULL, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* test BMP support */
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_1bpp, sizeof(bmp_1bpp), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.Format == D3DFMT_P8, "Got format %u, expected %u\n", info.Format, D3DFMT_P8);
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_2bpp, sizeof(bmp_2bpp), &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_4bpp, sizeof(bmp_4bpp), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.Format == D3DFMT_P8, "Got format %u, expected %u\n", info.Format, D3DFMT_P8);
+ hr = D3DXGetImageInfoFromFileInMemory(bmp_8bpp, sizeof(bmp_8bpp), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.Format == D3DFMT_P8, "Got format %u, expected %u\n", info.Format, D3DFMT_P8);
+
+ /* Grayscale PNG */
+ hr = D3DXGetImageInfoFromFileInMemory(png_grayscale, sizeof(png_grayscale), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.Format == D3DFMT_L8, "Got format %u, expected %u\n", info.Format, D3DFMT_L8);
+
+ /* test DDS support */
+ hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (hr == D3D_OK) {
+ ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
+ ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.MipLevels == 2, "Got miplevels %u, expected 2\n", info.MipLevels);
+ ok(info.Format == D3DFMT_R8G8B8, "Got format %#x, expected %#x\n", info.Format, D3DFMT_R8G8B8);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ } else skip("Couldn't get image info from 24-bit DDS file in memory\n");
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (hr == D3D_OK) {
+ ok(info.Width == 2, "Got width %u, expected 2\n", info.Width);
+ ok(info.Height == 2, "Got height %u, expected 2\n", info.Height);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
+ ok(info.Format == D3DFMT_X1R5G5B5, "Got format %#x, expected %#x\n", info.Format, D3DFMT_X1R5G5B5);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ } else skip("Couldn't get image info from 16-bit DDS file in memory\n");
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (hr == D3D_OK) {
+ ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
+ ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
+ ok(info.Depth == 1, "Got depth %u, expected 1\n", info.Depth);
+ ok(info.MipLevels == 1, "Got miplevels %u, expected 1\n", info.MipLevels);
+ ok(info.Format == D3DFMT_DXT5, "Got format %#x, expected %#x\n", info.Format, D3DFMT_DXT5);
+ ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ } else skip("Couldn't get image info from cube map in memory\n");
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map), &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (hr == D3D_OK) {
+ ok(info.Width == 4, "Got width %u, expected 4\n", info.Width);
+ ok(info.Height == 4, "Got height %u, expected 4\n", info.Height);
+ ok(info.Depth == 2, "Got depth %u, expected 2\n", info.Depth);
+ ok(info.MipLevels == 3, "Got miplevels %u, expected 3\n", info.MipLevels);
+ ok(info.Format == D3DFMT_DXT3, "Got format %#x, expected %#x\n", info.Format, D3DFMT_DXT3);
+ ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got image file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ } else skip("Couldn't get image info from volume map in memory\n");
+
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0, D3DFMT_DXT1);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_DXT2, 0, 0, 0, 0, 0, D3DFMT_DXT2);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_DXT3, 0, 0, 0, 0, 0, D3DFMT_DXT3);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0, D3DFMT_DXT4);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_DXT5, 0, 0, 0, 0, 0, D3DFMT_DXT5);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, D3DFMT_R8G8_B8G8);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, D3DFMT_G8R8_G8B8);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_UYVY, 0, 0, 0, 0, 0, D3DFMT_UYVY);
+ check_dds_pixel_format(DDS_PF_FOURCC, D3DFMT_YUY2, 0, 0, 0, 0, 0, D3DFMT_YUY2);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 16, 0xf800, 0x07e0, 0x001f, 0, D3DFMT_R5G6B5);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x7c00, 0x03e0, 0x001f, 0x8000, D3DFMT_A1R5G5B5);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x0f00, 0x00f0, 0x000f, 0xf000, D3DFMT_A4R4G4B4);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 8, 0xe0, 0x1c, 0x03, 0, D3DFMT_R3G3B2);
+ check_dds_pixel_format(DDS_PF_ALPHA_ONLY, 0, 8, 0, 0, 0, 0xff, D3DFMT_A8);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 16, 0x00e0, 0x001c, 0x0003, 0xff00, D3DFMT_A8R3G3B2);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 16, 0xf00, 0x0f0, 0x00f, 0, D3DFMT_X4R4G4B4);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000, D3DFMT_A2B10G10R10);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000003ff, 0x000ffc00, 0x3ff00000, 0xc0000000, D3DFMT_A2R10G10B10);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, D3DFMT_A8R8G8B8);
+ check_dds_pixel_format(DDS_PF_RGB | DDS_PF_ALPHA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000, D3DFMT_A8B8G8R8);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0xff0000, 0x00ff00, 0x0000ff, 0, D3DFMT_X8R8G8B8);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0x0000ff, 0x00ff00, 0xff0000, 0, D3DFMT_X8B8G8R8);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 24, 0xff0000, 0x00ff00, 0x0000ff, 0, D3DFMT_R8G8B8);
+ check_dds_pixel_format(DDS_PF_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_G16R16);
+ check_dds_pixel_format(DDS_PF_LUMINANCE, 0, 8, 0xff, 0, 0, 0, D3DFMT_L8);
+ check_dds_pixel_format(DDS_PF_LUMINANCE, 0, 16, 0xffff, 0, 0, 0, D3DFMT_L16);
+ check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 16, 0x00ff, 0, 0, 0xff00, D3DFMT_A8L8);
+ check_dds_pixel_format(DDS_PF_LUMINANCE | DDS_PF_ALPHA, 0, 8, 0x0f, 0, 0, 0xf0, D3DFMT_A4L4);
+ check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0, 0, D3DFMT_V8U8);
+ check_dds_pixel_format(DDS_PF_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0, 0, D3DFMT_V16U16);
+
+ test_dds_header_handling();
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_16bit, sizeof(dds_16bit) - 1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_24bit, sizeof(dds_24bit) - 1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_cube_map, sizeof(dds_cube_map) - 1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXGetImageInfoFromFileInMemory(dds_volume_map, sizeof(dds_volume_map) - 1, &info);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+
+ /* cleanup */
+ if(testdummy_ok) DeleteFileA("testdummy.bmp");
+ if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
+}
+
+#define check_pixel_2bpp(lockrect, x, y, color) _check_pixel_2bpp(__LINE__, lockrect, x, y, color)
+static inline void _check_pixel_2bpp(unsigned int line, const D3DLOCKED_RECT *lockrect, int x, int y, WORD expected_color)
+{
+ WORD color = ((WORD*)lockrect->pBits)[x + y * lockrect->Pitch / 2];
+ ok_(__FILE__, line)(color == expected_color, "Got color 0x%04x, expected 0x%04x\n", color, expected_color);
+}
+
+#define check_pixel_4bpp(lockrect, x, y, color) _check_pixel_4bpp(__LINE__, lockrect, x, y, color)
+static inline void _check_pixel_4bpp(unsigned int line, const D3DLOCKED_RECT *lockrect, int x, int y, DWORD expected_color)
+{
+ DWORD color = ((DWORD*)lockrect->pBits)[x + y * lockrect->Pitch / 4];
+ ok_(__FILE__, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x\n", color, expected_color);
+}
+
+static void test_D3DXLoadSurface(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ BOOL testdummy_ok, testbitmap_ok;
+ IDirect3DTexture9 *tex;
+ IDirect3DSurface9 *surf, *newsurf;
+ RECT rect, destrect;
+ D3DLOCKED_RECT lockrect;
+ const WORD pixdata_a8r3g3b2[] = { 0x57df, 0x98fc, 0xacdd, 0xc891 };
+ const WORD pixdata_a1r5g5b5[] = { 0x46b5, 0x99c8, 0x06a2, 0x9431 };
+ const WORD pixdata_r5g6b5[] = { 0x9ef6, 0x658d, 0x0aee, 0x42ee };
+ const WORD pixdata_a8l8[] = { 0xff00, 0x00ff, 0xff30, 0x7f7f };
+ const DWORD pixdata_g16r16[] = { 0x07d23fbe, 0xdc7f44a4, 0xe4d8976b, 0x9a84fe89 };
+ const DWORD pixdata_a8b8g8r8[] = { 0xc3394cf0, 0x235ae892, 0x09b197fd, 0x8dc32bf6 };
+ const DWORD pixdata_a2r10g10b10[] = { 0x57395aff, 0x5b7668fd, 0xb0d856b5, 0xff2c61d6 };
+
+ hr = create_file("testdummy.bmp", noimage, sizeof(noimage)); /* invalid image */
+ testdummy_ok = SUCCEEDED(hr);
+
+ hr = create_file("testbitmap.bmp", bmp_1bpp, sizeof(bmp_1bpp)); /* valid image */
+ testbitmap_ok = SUCCEEDED(hr);
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
+ if(FAILED(hr)) {
+ skip("Failed to create a surface (%#x)\n", hr);
+ if(testdummy_ok) DeleteFileA("testdummy.bmp");
+ if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
+ return;
+ }
+
+ /* D3DXLoadSurfaceFromFile */
+ if(testbitmap_ok) {
+ hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromFileA(NULL, NULL, NULL, "testbitmap.bmp", NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ } else skip("Couldn't create \"testbitmap.bmp\"\n");
+
+ if(testdummy_ok) {
+ hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "testdummy.bmp", NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+ } else skip("Couldn't create \"testdummy.bmp\"\n");
+
+ hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromFileA(surf, NULL, NULL, "", NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFile returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+
+ /* D3DXLoadSurfaceFromResource */
+ hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL,
+ MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL,
+ MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXLoadSurfaceFromResourceA(NULL, NULL, NULL, NULL,
+ MAKEINTRESOURCEA(IDB_BITMAP_1x1), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromResourceA(surf, NULL, NULL, NULL,
+ MAKEINTRESOURCEA(IDS_STRING), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+
+ /* D3DXLoadSurfaceFromFileInMemory */
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, noimage, sizeof(noimage), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, 0, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 8, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromFileInMemory(NULL, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* D3DXLoadSurfaceFromMemory */
+ SetRect(&rect, 0, 0, 2, 2);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, 0, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, NULL, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromMemory(NULL, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata, D3DFMT_UNKNOWN, sizeof(pixdata), NULL, &rect, D3DX_DEFAULT, 0);
+ ok(hr == E_FAIL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, E_FAIL);
+
+ SetRect(&destrect, -1, -1, 1, 1); /* destination rect is partially outside texture boundaries */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ SetRect(&destrect, 255, 255, 257, 257); /* destination rect is partially outside texture boundaries */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ SetRect(&destrect, 1, 1, 0, 0); /* left > right, top > bottom */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ SetRect(&destrect, 1, 2, 1, 2); /* left = right, top = bottom */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ /* fails when debug version of d3d9 is used */
+ ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ SetRect(&destrect, 257, 257, 257, 257); /* left = right, top = bottom, but invalid values */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, &destrect, pixdata, D3DFMT_A8R8G8B8, sizeof(pixdata), NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* D3DXLoadSurfaceFromSurface */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &newsurf, NULL);
+ if(SUCCEEDED(hr)) {
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromSurface(NULL, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ check_release((IUnknown*)newsurf, 0);
+ } else skip("Failed to create a second surface\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DSurface9_Release(newsurf);
+ IDirect3DTexture9_Release(tex);
+ } else skip("Failed to create texture\n");
+
+ /* non-lockable render target */
+ hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &newsurf, NULL);
+ if (SUCCEEDED(hr)) {
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DSurface9_Release(newsurf);
+ } else skip("Failed to create render target surface\n");
+
+ /* non-lockable multisampled render target */
+ hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &newsurf, NULL);
+ if (SUCCEEDED(hr)) {
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DSurface9_Release(newsurf);
+ } else skip("Failed to create multisampled render target.\n");
+
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &newsurf);
+ ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget returned %#x, expected %#x.\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0xff000000);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_TRIANGLE | D3DX_FILTER_MIRROR, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_LINEAR, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromSurface returned %#x, expected %#x.\n", hr, D3D_OK);
+
+ IDirect3DSurface9_Release(newsurf);
+
+ check_release((IUnknown*)surf, 0);
+
+
+ /* test color conversion */
+ /* A8R8G8B8 */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf, NULL);
+ if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
+ else {
+ PALETTEENTRY palette;
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_4bpp(&lockrect, 0, 0, 0x57dbffff);
+ check_pixel_4bpp(&lockrect, 1, 0, 0x98ffff00);
+ check_pixel_4bpp(&lockrect, 0, 1, 0xacdbff55);
+ check_pixel_4bpp(&lockrect, 1, 1, 0xc8929255);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_4bpp(&lockrect, 0, 0, 0x008cadad);
+ check_pixel_4bpp(&lockrect, 1, 0, 0xff317342);
+ check_pixel_4bpp(&lockrect, 0, 1, 0x0008ad10);
+ check_pixel_4bpp(&lockrect, 1, 1, 0xff29088c);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_4bpp(&lockrect, 0, 0, 0xff9cdfb5);
+ check_pixel_4bpp(&lockrect, 1, 0, 0xff63b26b);
+ check_pixel_4bpp(&lockrect, 0, 1, 0xff085d73);
+ check_pixel_4bpp(&lockrect, 1, 1, 0xff425d73);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ todo_wine {
+ check_pixel_4bpp(&lockrect, 0, 0, 0xff3f08ff);
+ }
+ check_pixel_4bpp(&lockrect, 1, 0, 0xff44dcff);
+ check_pixel_4bpp(&lockrect, 0, 1, 0xff97e4ff);
+ check_pixel_4bpp(&lockrect, 1, 1, 0xfffe9aff);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_4bpp(&lockrect, 0, 0, 0xc3f04c39);
+ check_pixel_4bpp(&lockrect, 1, 0, 0x2392e85a);
+ check_pixel_4bpp(&lockrect, 0, 1, 0x09fd97b1);
+ check_pixel_4bpp(&lockrect, 1, 1, 0x8df62bc3);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_4bpp(&lockrect, 0, 0, 0x555c95bf);
+ check_pixel_4bpp(&lockrect, 1, 0, 0x556d663f);
+ check_pixel_4bpp(&lockrect, 0, 1, 0xaac385ad);
+ todo_wine {
+ check_pixel_4bpp(&lockrect, 1, 1, 0xfffcc575);
+ }
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
+ D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_4bpp(&lockrect, 0, 0, 0xff000000);
+ check_pixel_4bpp(&lockrect, 1, 0, 0x00ffffff);
+ check_pixel_4bpp(&lockrect, 0, 1, 0xff303030);
+ check_pixel_4bpp(&lockrect, 1, 1, 0x7f7f7f7f);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ /* Test D3DXLoadSurfaceFromMemory with indexed color image */
+ if (0)
+ {
+ /* Crashes on Nvidia Win10. */
+ palette.peRed = bmp_1bpp[56];
+ palette.peGreen = bmp_1bpp[55];
+ palette.peBlue = bmp_1bpp[54];
+ palette.peFlags = bmp_1bpp[57]; /* peFlags is the alpha component in DX8 and higher */
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, &bmp_1bpp[62],
+ D3DFMT_P8, 1, (const PALETTEENTRY *)&palette, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x\n", hr);
+ ok(*(DWORD*)lockrect.pBits == 0x80f3f2f1, "Pixel color mismatch: got %#x, expected 0x80f3f2f1\n", *(DWORD*)lockrect.pBits);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x\n", hr);
+ }
+
+ /* Test D3DXLoadSurfaceFromFileInMemory with indexed color image (alpha is not taken into account for bmp file) */
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, bmp_1bpp, sizeof(bmp_1bpp), NULL, D3DX_FILTER_NONE, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x\n", hr);
+ ok(*(DWORD*)lockrect.pBits == 0xfff3f2f1, "Pixel color mismatch: got %#x, expected 0xfff3f2f1\n", *(DWORD*)lockrect.pBits);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x\n", hr);
+
+ check_release((IUnknown*)surf, 0);
+ }
+
+ /* A1R5G5B5 */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_A1R5G5B5, D3DPOOL_DEFAULT, &surf, NULL);
+ if(FAILED(hr)) skip("Failed to create a surface (%#x)\n", hr);
+ else {
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2, D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x6fff);
+ check_pixel_2bpp(&lockrect, 1, 0, 0xffe0);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xefea);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xca4a);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5, D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x46b5);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x99c8);
+ check_pixel_2bpp(&lockrect, 0, 1, 0x06a2);
+ check_pixel_2bpp(&lockrect, 1, 1, 0x9431);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5, D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_2bpp(&lockrect, 0, 0, 0xcf76);
+ check_pixel_2bpp(&lockrect, 1, 0, 0xb2cd);
+ check_pixel_2bpp(&lockrect, 0, 1, 0x856e);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xa16e);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16, D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ todo_wine {
+ check_pixel_2bpp(&lockrect, 0, 0, 0xa03f);
+ }
+ check_pixel_2bpp(&lockrect, 1, 0, 0xa37f);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xcb9f);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xfe7f);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8, D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ todo_wine {
+ check_pixel_2bpp(&lockrect, 0, 0, 0xf527);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x4b8b);
+ }
+ check_pixel_2bpp(&lockrect, 0, 1, 0x7e56);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xf8b8);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10, D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x2e57);
+ todo_wine {
+ check_pixel_2bpp(&lockrect, 1, 0, 0x3588);
+ }
+ check_pixel_2bpp(&lockrect, 0, 1, 0xe215);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xff0e);
+ IDirect3DSurface9_UnlockRect(surf);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
+ D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x8000);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x7fff);
+ check_pixel_2bpp(&lockrect, 0, 1, 0x98c6);
+ check_pixel_2bpp(&lockrect, 1, 1, 0x3def);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ check_release((IUnknown*)surf, 0);
+ }
+
+ /* A8L8 */
+ hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8L8, D3DPOOL_MANAGED, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create A8L8 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &surf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8r3g3b2,
+ D3DFMT_A8R3G3B2, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x57f7);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x98ed);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xaceb);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xc88d);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a1r5g5b5,
+ D3DFMT_A1R5G5B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x00a6);
+ check_pixel_2bpp(&lockrect, 1, 0, 0xff62);
+ check_pixel_2bpp(&lockrect, 0, 1, 0x007f);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xff19);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_r5g6b5,
+ D3DFMT_R5G6B5, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0xffce);
+ check_pixel_2bpp(&lockrect, 1, 0, 0xff9c);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xff4d);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xff59);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_g16r16,
+ D3DFMT_G16R16, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0xff25);
+ check_pixel_2bpp(&lockrect, 1, 0, 0xffbe);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xffd6);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xffb6);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8b8g8r8,
+ D3DFMT_A8B8G8R8, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0xc36d);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x23cb);
+ check_pixel_2bpp(&lockrect, 0, 1, 0x09af);
+ check_pixel_2bpp(&lockrect, 1, 1, 0x8d61);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a2r10g10b10,
+ D3DFMT_A2R10G10B10, 8, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0x558c);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x5565);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xaa95);
+ check_pixel_2bpp(&lockrect, 1, 1, 0xffcb);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ hr = D3DXLoadSurfaceFromMemory(surf, NULL, NULL, pixdata_a8l8,
+ D3DFMT_A8L8, 4, NULL, &rect, D3DX_FILTER_NONE, 0);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+ hr = IDirect3DSurface9_LockRect(surf, &lockrect, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
+ check_pixel_2bpp(&lockrect, 0, 0, 0xff00);
+ check_pixel_2bpp(&lockrect, 1, 0, 0x00ff);
+ check_pixel_2bpp(&lockrect, 0, 1, 0xff30);
+ check_pixel_2bpp(&lockrect, 1, 1, 0x7f7f);
+ hr = IDirect3DSurface9_UnlockRect(surf);
+ ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
+
+ check_release((IUnknown*)surf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ /* DXT1, DXT2, DXT3, DXT4, DXT5 */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
+ if (FAILED(hr))
+ skip("Failed to create R8G8B8 surface, hr %#x.\n", hr);
+ else
+ {
+ hr = D3DXLoadSurfaceFromFileInMemory(surf, NULL, NULL, dds_24bit, sizeof(dds_24bit), NULL, D3DX_FILTER_NONE, 0, NULL);
+ ok(SUCCEEDED(hr), "Failed to load surface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT2, D3DPOOL_SYSTEMMEM, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create DXT2 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT2 format.\n");
+ check_release((IUnknown*)newsurf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT3, D3DPOOL_SYSTEMMEM, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create DXT3 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT3 format.\n");
+ check_release((IUnknown*)newsurf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT4, D3DPOOL_SYSTEMMEM, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create DXT4 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT4 format.\n");
+ check_release((IUnknown*)newsurf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT5, D3DPOOL_SYSTEMMEM, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create DXT5 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT5 format.\n");
+ check_release((IUnknown*)newsurf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &tex, NULL);
+ if (FAILED(hr))
+ skip("Failed to create DXT1 texture, hr %#x.\n", hr);
+ else
+ {
+ hr = IDirect3DTexture9_GetSurfaceLevel(tex, 0, &newsurf);
+ ok(SUCCEEDED(hr), "Failed to get the surface, hr %#x.\n", hr);
+ hr = D3DXLoadSurfaceFromSurface(newsurf, NULL, NULL, surf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels to DXT1 format.\n");
+
+ hr = D3DXLoadSurfaceFromSurface(surf, NULL, NULL, newsurf, NULL, NULL, D3DX_FILTER_NONE, 0);
+ todo_wine ok(SUCCEEDED(hr), "Failed to convert pixels from DXT1 format.\n");
+
+ check_release((IUnknown*)newsurf, 1);
+ check_release((IUnknown*)tex, 0);
+ }
+
+ check_release((IUnknown*)surf, 0);
+ }
+
+ /* cleanup */
+ if(testdummy_ok) DeleteFileA("testdummy.bmp");
+ if(testbitmap_ok) DeleteFileA("testbitmap.bmp");
+}
+
+static void test_D3DXSaveSurfaceToFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ RECT rect;
+ ID3DXBuffer *buffer;
+ IDirect3DSurface9 *surface;
+ struct
+ {
+ DWORD magic;
+ struct dds_header header;
+ BYTE *data;
+ } *dds;
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
+ if (FAILED(hr)) {
+ skip("Couldn't create surface\n");
+ return;
+ }
+
+ SetRectEmpty(&rect);
+ hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_BMP, surface, NULL, &rect);
+ /* fails with the debug version of d3d9 */
+ ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) {
+ DWORD size = ID3DXBuffer_GetBufferSize(buffer);
+ ok(size > 0, "ID3DXBuffer_GetBufferSize returned %u, expected > 0\n", size);
+ ID3DXBuffer_Release(buffer);
+ }
+
+ SetRectEmpty(&rect);
+ hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, &rect);
+ todo_wine ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ dds = ID3DXBuffer_GetBufferPointer(buffer);
+
+ ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#x.\n", dds->magic);
+ ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %u.\n", dds->header.size);
+ ok(!dds->header.height, "Got unexpected height %u.\n", dds->header.height);
+ ok(!dds->header.width, "Got unexpected width %u.\n", dds->header.width);
+ ok(!dds->header.depth, "Got unexpected depth %u.\n", dds->header.depth);
+ ok(!dds->header.miplevels, "Got unexpected miplevels %u.\n", dds->header.miplevels);
+ ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %u.\n", dds->header.pitch_or_linear_size);
+ ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#x.\n", dds->header.caps);
+ ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT),
+ "Got unexpected flags %#x.\n", dds->header.flags);
+ ID3DXBuffer_Release(buffer);
+ }
+
+ hr = D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_DDS, surface, NULL, NULL);
+ ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ dds = ID3DXBuffer_GetBufferPointer(buffer);
+ ok(dds->magic == MAKEFOURCC('D','D','S',' '), "Got unexpected DDS signature %#x.\n", dds->magic);
+ ok(dds->header.size == sizeof(dds->header), "Got unexpected DDS size %u.\n", dds->header.size);
+ ok(dds->header.height == 4, "Got unexpected height %u.\n", dds->header.height);
+ ok(dds->header.width == 4, "Got unexpected width %u.\n", dds->header.width);
+ ok(!dds->header.depth, "Got unexpected depth %u.\n", dds->header.depth);
+ ok(!dds->header.miplevels, "Got unexpected miplevels %u.\n", dds->header.miplevels);
+ ok(!dds->header.pitch_or_linear_size, "Got unexpected pitch_or_linear_size %u.\n", dds->header.pitch_or_linear_size);
+ todo_wine ok(dds->header.caps == (DDS_CAPS_TEXTURE | DDSCAPS_ALPHA), "Got unexpected caps %#x.\n", dds->header.caps);
+ ok(dds->header.flags == (DDS_CAPS | DDS_HEIGHT | DDS_WIDTH | DDS_PIXELFORMAT),
+ "Got unexpected flags %#x.\n", dds->header.flags);
+ ID3DXBuffer_Release(buffer);
+
+ IDirect3DSurface9_Release(surface);
+}
+
+static void test_D3DXSaveSurfaceToFile(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DSurface9 *surface;
+ RECT rect;
+ D3DLOCKED_RECT lock_rect;
+ D3DXIMAGE_INFO image_info;
+ const BYTE pixels[] = { 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0xff, 0x00, 0x00, 0xff };
+ DWORD pitch = sizeof(pixels) / 2;
+
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 2, D3DFMT_R8G8B8, D3DPOOL_SCRATCH, &surface, NULL);
+ if (FAILED(hr)) {
+ skip("Couldn't create surface\n");
+ return;
+ }
+
+ SetRect(&rect, 0, 0, 2, 2);
+ hr = D3DXLoadSurfaceFromMemory(surface, NULL, NULL, pixels, D3DFMT_R8G8B8, pitch, NULL, &rect, D3DX_FILTER_NONE, 0);
+ if (SUCCEEDED(hr)) {
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadSurfaceFromFileA(surface, NULL, NULL, "saved_surface.bmp", NULL, D3DX_FILTER_NONE, 0, &image_info);
+ ok(hr == D3D_OK, "Couldn't load saved surface %#x\n", hr);
+ if (FAILED(hr)) goto next_tests;
+
+ ok(image_info.Width == 2, "Wrong width %u\n", image_info.Width);
+ ok(image_info.Height == 2, "Wrong height %u\n", image_info.Height);
+ ok(image_info.Format == D3DFMT_R8G8B8, "Wrong format %#x\n", image_info.Format);
+ ok(image_info.ImageFileFormat == D3DXIFF_BMP, "Wrong file format %u\n", image_info.ImageFileFormat);
+
+ hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock surface %#x\n", hr);
+ if (FAILED(hr)) goto next_tests;
+
+ ok(!memcmp(lock_rect.pBits, pixels, pitch), "Pixel data mismatch in first row\n");
+ ok(!memcmp((BYTE *)lock_rect.pBits + lock_rect.Pitch, pixels + pitch, pitch), "Pixel data mismatch in second row\n");
+
+ IDirect3DSurface9_UnlockRect(surface);
+ } else skip("Couldn't fill surface\n");
+
+next_tests:
+ hr = D3DXSaveSurfaceToFileA(NULL, D3DXIFF_BMP, surface, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* PPM and TGA are supported, even though MSDN claims they aren't */
+ todo_wine {
+ hr = D3DXSaveSurfaceToFileA("saved_surface.ppm", D3DXIFF_PPM, surface, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.tga", D3DXIFF_TGA, surface, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+ }
+
+ hr = D3DXSaveSurfaceToFileA("saved_surface.dds", D3DXIFF_DDS, surface, NULL, NULL);
+ ok(hr == D3D_OK, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) {
+ hr = D3DXLoadSurfaceFromFileA(surface, NULL, NULL, "saved_surface.dds", NULL, D3DX_FILTER_NONE, 0, &image_info);
+ ok(hr == D3D_OK, "Couldn't load saved surface %#x\n", hr);
+
+ if (SUCCEEDED(hr)) {
+ ok(image_info.Width == 2, "Wrong width %u\n", image_info.Width);
+ ok(image_info.Format == D3DFMT_R8G8B8, "Wrong format %#x\n", image_info.Format);
+ ok(image_info.ImageFileFormat == D3DXIFF_DDS, "Wrong file format %u\n", image_info.ImageFileFormat);
+
+ hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock surface %#x\n", hr);
+ if (SUCCEEDED(hr)) {
+ ok(!memcmp(lock_rect.pBits, pixels, pitch), "Pixel data mismatch in first row\n");
+ ok(!memcmp((BYTE *)lock_rect.pBits + lock_rect.Pitch, pixels + pitch, pitch), "Pixel data mismatch in second row\n");
+ IDirect3DSurface9_UnlockRect(surface);
+ }
+ }
+ } else skip("Couldn't save surface\n");
+
+ hr = D3DXSaveSurfaceToFileA("saved_surface", D3DXIFF_PFM + 1, surface, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ SetRect(&rect, 0, 0, 4, 4);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ SetRect(&rect, 2, 0, 1, 4);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ SetRect(&rect, 0, 2, 4, 1);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ SetRect(&rect, -1, -1, 2, 2);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ SetRectEmpty(&rect);
+ hr = D3DXSaveSurfaceToFileA("saved_surface.bmp", D3DXIFF_BMP, surface, NULL, &rect);
+ /* fails when debug version of d3d9 is used */
+ ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "D3DXSaveSurfaceToFileA returned %#x, expected %#x\n", hr, D3D_OK);
+
+ DeleteFileA("saved_surface.bmp");
+ DeleteFileA("saved_surface.ppm");
+ DeleteFileA("saved_surface.tga");
+ DeleteFileA("saved_surface.dds");
+
+ IDirect3DSurface9_Release(surface);
+}
+
+START_TEST(surface)
+{
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d) {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if(FAILED(hr)) {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ test_D3DXGetImageInfo();
+ test_D3DXLoadSurface(device);
+ test_D3DXSaveSurfaceToFileInMemory(device);
+ test_D3DXSaveSurfaceToFile(device);
+
+ check_release((IUnknown*)device, 0);
+ check_release((IUnknown*)d3d, 0);
+ DestroyWindow(wnd);
+}
--- /dev/null
+/* Automatically generated by make depend; DO NOT EDIT!! */
+
+#define STANDALONE
+#include <wine/test.h>
+
+extern void func_asm(void);
+extern void func_core(void);
+extern void func_effect(void);
+extern void func_line(void);
+extern void func_math(void);
+extern void func_mesh(void);
+extern void func_shader(void);
+extern void func_surface(void);
+extern void func_texture(void);
+extern void func_volume(void);
+extern void func_xfile(void);
+
+const struct test winetest_testlist[] =
+{
+ { "asm", func_asm },
+ { "core", func_core },
+ { "effect", func_effect },
+ { "line", func_line },
+ { "math", func_math },
+ { "mesh", func_mesh },
+ { "shader", func_shader },
+ { "surface", func_surface },
+ { "texture", func_texture },
+ { "volume", func_volume },
+ { "xfile", func_xfile },
+ { 0, 0 }
+};
--- /dev/null
+/*
+ * Tests for the D3DX9 texture functions
+ *
+ * Copyright 2009 Tony Wasserka
+ * Copyright 2010 Owen Rudge for CodeWeavers
+ * Copyright 2010 Matteo Bruni for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "wine/test.h"
+#include "d3dx9tex.h"
+#include "resources.h"
+
+static int has_2d_dxt3, has_2d_dxt5, has_cube_dxt5, has_3d_dxt3;
+
+/* 2x2 16-bit dds, no mipmaps */
+static const unsigned char dds_16bit[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
+0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
+};
+
+/* 2x2 24-bit dds, 2 mipmaps */
+static const unsigned char dds_24bit[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
+0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
+0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+};
+
+/* 4x4 cube map dds */
+static const unsigned char dds_cube_map[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
+0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x51,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x52,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x53,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x54,
+0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55
+};
+
+/* 4x4x2 volume map dds, 2 mipmaps */
+static const unsigned char dds_volume_map[] = {
+0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
+0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
+0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
+};
+
+static const unsigned char png_grayscale[] =
+{
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
+ 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x3a, 0x7e, 0x9b, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44,
+ 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0x0f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x1b,
+ 0xb6, 0xee, 0x56, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
+ 0x60, 0x82
+};
+
+#define ADMITTED_ERROR 0.0001f
+
+static inline float relative_error(float expected, float got)
+{
+ return expected == 0.0f ? fabs(expected - got) : fabs(1.0f - got / expected);
+}
+
+#define expect_vec4(expected, got) expect_vec4_(__LINE__, expected, got)
+static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, const D3DXVECTOR4 *got)
+{
+ ok_(__FILE__, line)(relative_error(expected->x, got->x) < ADMITTED_ERROR
+ && relative_error(expected->y, got->y) < ADMITTED_ERROR
+ && relative_error(expected->z, got->z) < ADMITTED_ERROR
+ && relative_error(expected->w, got->w) < ADMITTED_ERROR,
+ "Expected (%f, %f, %f, %f), got (%f, %f, %f, %f)\n",
+ expected->x, expected->y, expected->z, expected->w,
+ got->x, got->y, got->z, got->w);
+}
+
+static BOOL compare_color(DWORD c1, DWORD c2, BYTE max_diff)
+{
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
+ return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
+ return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
+ return FALSE;
+ c1 >>= 8; c2 >>= 8;
+ if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff)
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL is_autogenmipmap_supported(IDirect3DDevice9 *device, D3DRESOURCETYPE resource_type)
+{
+ HRESULT hr;
+ D3DCAPS9 caps;
+ IDirect3D9 *d3d9;
+ D3DDISPLAYMODE mode;
+ D3DDEVICE_CREATION_PARAMETERS params;
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+ IDirect3DDevice9_GetDirect3D(device, &d3d9);
+ IDirect3DDevice9_GetCreationParameters(device, ¶ms);
+ IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
+
+ if (!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP))
+ return FALSE;
+
+ hr = IDirect3D9_CheckDeviceFormat(d3d9, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, D3DUSAGE_AUTOGENMIPMAP, resource_type, D3DFMT_A8R8G8B8);
+
+ IDirect3D9_Release(d3d9);
+ return hr == D3D_OK;
+}
+
+static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
+{
+ UINT width, height, mipmaps;
+ D3DFORMAT format, expected;
+ D3DCAPS9 caps;
+ HRESULT hr;
+ IDirect3D9 *d3d;
+ D3DDEVICE_CREATION_PARAMETERS params;
+ D3DDISPLAYMODE mode;
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+ /* general tests */
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* width & height */
+ width = height = D3DX_DEFAULT;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+ ok(height == 256, "Returned height %d, expected %d\n", height, 256);
+
+ width = D3DX_DEFAULT;
+ hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+
+ if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
+ skip("Hardware only supports pow2 textures\n");
+ else
+ {
+ width = 62;
+ hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 62, "Returned width %d, expected %d\n", width, 62);
+
+ width = D3DX_DEFAULT; height = 63;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == height, "Returned width %d, expected %d\n", width, height);
+ ok(height == 63, "Returned height %d, expected %d\n", height, 63);
+ }
+
+ width = D3DX_DEFAULT; height = 0;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+ ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+
+ width = 0; height = 0;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+ ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+
+ width = 0;
+ hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+
+ width = 0xFFFFFFFE;
+ hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
+
+ width = caps.MaxTextureWidth-1;
+ hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
+ ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
+ else
+ ok(width == caps.MaxTextureWidth-1, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth-1);
+
+ /* mipmaps */
+ width = 64; height = 63;
+ mipmaps = 9;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
+
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2))
+ {
+ width = 284; height = 137;
+ mipmaps = 20;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ width = height = 63;
+ mipmaps = 9;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 6, "Returned mipmaps %d, expected %d\n", mipmaps, 6);
+ }
+ else
+ skip("Skipping some tests, npot2 textures unsupported\n");
+
+ mipmaps = 20;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ mipmaps = 0;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ /* mipmaps when D3DUSAGE_AUTOGENMIPMAP is set */
+ if (is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
+ {
+ mipmaps = 0;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
+ mipmaps = 1;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
+ mipmaps = 2;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
+ mipmaps = 6;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
+ }
+ else
+ skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
+
+ /* usage */
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
+
+ /* format */
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ format = D3DFMT_UNKNOWN;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DX_DEFAULT;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DFMT_R8G8B8;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
+
+ IDirect3DDevice9_GetDirect3D(device, &d3d);
+ IDirect3DDevice9_GetCreationParameters(device, ¶ms);
+ IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
+
+ if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R3G3B2)))
+ expected = D3DFMT_R3G3B2;
+ else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X4R4G4B4)))
+ expected = D3DFMT_X4R4G4B4;
+ else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5)))
+ expected = D3DFMT_X1R5G5B5;
+ else
+ expected = D3DFMT_R5G6B5;
+
+ format = D3DFMT_R3G3B2;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == expected, "Returned format %u, expected %u\n", format, expected);
+
+ if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R3G3B2)))
+ expected = D3DFMT_A8R3G3B2;
+ else
+ expected = D3DFMT_A8R8G8B8;
+
+ format = D3DFMT_A8R3G3B2;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == expected, "Returned format %u, expected %u\n", format, expected);
+
+ if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_P8)))
+ expected = D3DFMT_P8;
+ else
+ expected = D3DFMT_A8R8G8B8;
+
+ format = D3DFMT_P8;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == expected, "Returned format %u, expected %u\n", format, expected);
+
+ if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L8)))
+ expected = D3DFMT_L8;
+ else
+ expected = D3DFMT_X8R8G8B8;
+
+ format = D3DFMT_L8;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == expected, "Returned format %u, expected %u\n", format, expected);
+
+ if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
+ mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L16)))
+ expected = D3DFMT_L16;
+ else
+ expected = D3DFMT_A16B16G16R16;
+
+ format = D3DFMT_L16;
+ hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == expected, "Returned format %u, expected %u\n", format, expected);
+
+ /* Block-based texture formats and size < block size. */
+ if (has_2d_dxt5)
+ {
+ format = D3DFMT_DXT5;
+ width = 2; height = 2;
+ mipmaps = 1;
+ hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 4, "Returned width %d, expected %d\n", width, 4);
+ ok(height == 4, "Returned height %d, expected %d\n", height, 4);
+ ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
+ ok(format == D3DFMT_DXT5, "Returned format %u, expected %u\n", format, D3DFMT_DXT5);
+ }
+ else
+ {
+ skip("D3DFMT_DXT5 textures are not supported, skipping a test.\n");
+ }
+
+ IDirect3D9_Release(d3d);
+}
+
+static void test_D3DXCheckCubeTextureRequirements(IDirect3DDevice9 *device)
+{
+ UINT size, mipmaps, expected;
+ D3DFORMAT format;
+ D3DCAPS9 caps;
+ HRESULT hr;
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
+ {
+ skip("No cube textures support\n");
+ return;
+ }
+
+ /* general tests */
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckCubeTextureRequirements(NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* size */
+ size = D3DX_DEFAULT;
+ hr = D3DXCheckCubeTextureRequirements(device, &size, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(size == 256, "Returned size %d, expected %d\n", size, 256);
+
+ /* mipmaps */
+ size = 64;
+ mipmaps = 9;
+ hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
+
+ size = 284;
+ mipmaps = 20;
+ expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 10 : 9;
+ expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
+ hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
+
+ size = 63;
+ mipmaps = 9;
+ expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 7 : 6;
+ expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
+ hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
+
+ mipmaps = 0;
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ if (is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
+ {
+ mipmaps = 3;
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
+ }
+ else
+ skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
+
+ /* usage */
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
+
+ /* format */
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ format = D3DFMT_UNKNOWN;
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DX_DEFAULT;
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DFMT_R8G8B8;
+ hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
+}
+
+static void test_D3DXCheckVolumeTextureRequirements(IDirect3DDevice9 *device)
+{
+ UINT width, height, depth, mipmaps, expected;
+ D3DFORMAT format;
+ D3DCAPS9 caps;
+ HRESULT hr;
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || (caps.MaxVolumeExtent < 256))
+ {
+ skip("Limited or no volume textures support.\n");
+ return;
+ }
+
+ /* general tests */
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXCheckVolumeTextureRequirements(NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* width, height, depth */
+ width = height = depth = D3DX_DEFAULT;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+ ok(height == 256, "Returned height %d, expected %d\n", height, 256);
+ ok(depth == 1, "Returned depth %d, expected %d\n", depth, 1);
+
+ width = D3DX_DEFAULT;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 256, "Returned width %d, expected %d\n", width, 256);
+
+ width = D3DX_DEFAULT; height = 0; depth = 0;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+ ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+ ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
+
+ width = 0; height = 0; depth = 0;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+ ok(height == 1, "Returned height %d, expected %d\n", height, 1);
+ ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
+
+ width = 0;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == 1, "Returned width %d, expected %d\n", width, 1);
+
+ width = 0xFFFFFFFE;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(width == caps.MaxVolumeExtent, "Returned width %d, expected %d\n", width, caps.MaxVolumeExtent);
+
+ /* format */
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+
+ format = D3DFMT_UNKNOWN;
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DX_DEFAULT;
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ format = D3DFMT_R8G8B8;
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
+
+ format = D3DFMT_DXT3;
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ if (has_3d_dxt3)
+ ok(format == D3DFMT_DXT3, "Returned format %u, expected %u\n", format, D3DFMT_DXT3);
+ else
+ todo_wine ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
+
+ /* mipmaps */
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
+ {
+ skip("No volume textures mipmapping support\n");
+ return;
+ }
+
+ width = height = depth = 64;
+ mipmaps = 9;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
+
+ width = 284;
+ height = 143;
+ depth = 55;
+ mipmaps = 20;
+ expected = (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2 && caps.MaxVolumeExtent >= 512) ? 10 : 9;
+ hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
+
+ mipmaps = 0;
+ hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
+ ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ /* D3DUSAGE_AUTOGENMIPMAP is never supported for volume textures. */
+ ok(!is_autogenmipmap_supported(device, D3DRTYPE_VOLUMETEXTURE),
+ "D3DUSAGE_AUTOGENMIPMAP is unexpectedly supported on volume textures.\n");
+}
+
+static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DTexture9 *texture;
+ D3DSURFACE_DESC desc;
+ D3DCAPS9 caps;
+ UINT mipmaps;
+ HRESULT hr;
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+ hr = D3DXCreateTexture(NULL, 0, 0, 0, 0, D3DX_DEFAULT, D3DPOOL_DEFAULT, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* width and height tests */
+
+ hr = D3DXCreateTexture(device, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
+
+ ok(desc.Width == 256, "Returned width %d, expected %d\n", desc.Width, 256);
+ ok(desc.Height == 256, "Returned height %d, expected %d\n", desc.Height, 256);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
+
+ ok(desc.Width == 1, "Returned width %d, expected %d\n", desc.Width, 1);
+ ok(desc.Height == 1, "Returned height %d, expected %d\n", desc.Height, 1);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
+ skip("Hardware only supports pow2 textures\n");
+ else
+ {
+ hr = D3DXCreateTexture(device, D3DX_DEFAULT, 63, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok((hr == D3D_OK) ||
+ /* may not work with conditional NPOT */
+ ((hr != D3D_OK) && (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)),
+ "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
+
+ /* Conditional NPOT may create a texture with different dimensions, so allow those
+ situations instead of returning a fail */
+
+ ok(desc.Width == 63 ||
+ (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
+ "Returned width %d, expected %d\n", desc.Width, 63);
+
+ ok(desc.Height == 63 ||
+ (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
+ "Returned height %d, expected %d\n", desc.Height, 63);
+
+ IDirect3DTexture9_Release(texture);
+ }
+ }
+
+ /* mipmaps */
+
+ hr = D3DXCreateTexture(device, 64, 63, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ mipmaps = IDirect3DTexture9_GetLevelCount(texture);
+ ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ hr = D3DXCreateTexture(device, 284, 137, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ mipmaps = IDirect3DTexture9_GetLevelCount(texture);
+ ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ hr = D3DXCreateTexture(device, 0, 0, 20, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ mipmaps = IDirect3DTexture9_GetLevelCount(texture);
+ ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ hr = D3DXCreateTexture(device, 64, 64, 1, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ mipmaps = IDirect3DTexture9_GetLevelCount(texture);
+ ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+ /* usage */
+
+ hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
+ hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_DONOTCLIP, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
+ hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_POINTS, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
+ hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_RTPATCHES, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
+ hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_NPATCHES, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
+
+ /* format */
+
+ hr = D3DXCreateTexture(device, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+
+ hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ if (texture)
+ {
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
+
+ IDirect3DTexture9_Release(texture);
+ }
+
+ /* D3DXCreateTextureFromResource */
+ hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), &texture);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXCreateTextureFromResourceA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextureFromResourceA(device, NULL, NULL, &texture);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+
+ /* D3DXCreateTextureFromResourceEx */
+ hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXCreateTextureFromResourceExA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateTextureFromResourceExA(device, NULL, NULL, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+}
+
+static void test_D3DXFilterTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DTexture9 *tex;
+ IDirect3DCubeTexture9 *cubetex;
+ IDirect3DVolumeTexture9 *voltex;
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, D3DX_DEFAULT, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ /* Test different pools */
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ /* Cube texture test */
+ hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cubetex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+ IDirect3DCubeTexture9_Release(cubetex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ /* Volume texture test */
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &voltex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ DWORD level_count = IDirect3DVolumeTexture9_GetLevelCount(voltex);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_DEFAULT);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_BOX);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count - 1, D3DX_DEFAULT);
+ ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count, D3DX_DEFAULT);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DVolumeTexture9_Release(voltex);
+ }
+ else
+ skip("Failed to create volume texture\n");
+
+ /* Test textures with D3DUSAGE_AUTOGENMIPMAP usage */
+ if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
+ {
+ skip("No D3DUSAGE_AUTOGENMIPMAP supported for textures\n");
+ return;
+ }
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
+ ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+}
+
+static BOOL color_match(const DWORD *value, const DWORD *expected)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ DWORD diff = value[i] > expected[i] ? value[i] - expected[i] : expected[i] - value[i];
+ if (diff > 1) return FALSE;
+ }
+ return TRUE;
+}
+
+static void WINAPI fillfunc(D3DXVECTOR4 *value, const D3DXVECTOR2 *texcoord,
+ const D3DXVECTOR2 *texelsize, void *data)
+{
+ value->x = texcoord->x;
+ value->y = texcoord->y;
+ value->z = texelsize->x;
+ value->w = 1.0f;
+}
+
+static void test_D3DXFillTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DTexture9 *tex;
+ HRESULT hr;
+ D3DLOCKED_RECT lock_rect;
+ DWORD x, y, m;
+ DWORD v[4], e[4];
+ DWORD value, expected, size, pitch;
+
+ size = 4;
+ hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, 0, D3DFMT_A8R8G8B8,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillTexture(tex, fillfunc, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ for (m = 0; m < 3; m++)
+ {
+ hr = IDirect3DTexture9_LockRect(tex, m, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(DWORD);
+ for (y = 0; y < size; y++)
+ {
+ for (x = 0; x < size; x++)
+ {
+ value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
+ v[0] = (value >> 24) & 0xff;
+ v[1] = (value >> 16) & 0xff;
+ v[2] = (value >> 8) & 0xff;
+ v[3] = value & 0xff;
+
+ e[0] = 0xff;
+ e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
+ e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
+ e[3] = 255.0f / size + 0.5f;
+ expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, value, expected);
+ }
+ }
+ IDirect3DTexture9_UnlockRect(tex, m);
+ }
+ size >>= 1;
+ }
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillTexture(tex, fillfunc, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(WORD);
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 4; x++)
+ {
+ value = ((WORD *)lock_rect.pBits)[y * pitch + x];
+ v[0] = value >> 15;
+ v[1] = value >> 10 & 0x1f;
+ v[2] = value >> 5 & 0x1f;
+ v[3] = value & 0x1f;
+
+ e[0] = 1;
+ e[1] = (x + 0.5f) / 4.0f * 31.0f + 0.5f;
+ e[2] = (y + 0.5f) / 4.0f * 31.0f + 0.5f;
+ e[3] = 8;
+ expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, value, expected);
+ }
+ }
+ IDirect3DTexture9_UnlockRect(tex, 0);
+ }
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ /* test floating-point textures */
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A16B16G16R16F,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillTexture(tex, fillfunc, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(WORD);
+ for (y = 0; y < 4; y++)
+ {
+ WORD *ptr = (WORD *)lock_rect.pBits + y * pitch;
+ for (x = 0; x < 4; x++)
+ {
+ D3DXVECTOR4 got, expected;
+
+ D3DXFloat16To32Array((FLOAT *)&got, (D3DXFLOAT16 *)ptr, 4);
+ ptr += 4;
+
+ expected.x = (x + 0.5f) / 4.0f;
+ expected.y = (y + 0.5f) / 4.0f;
+ expected.z = 1.0f / 4.0f;
+ expected.w = 1.0f;
+
+ expect_vec4(&expected, &got);
+ }
+ }
+
+ IDirect3DTexture9_UnlockRect(tex, 0);
+ }
+ else
+ skip("Failed to lock texture\n");
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create D3DFMT_A16B16G16R16F texture\n");
+
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A32B32G32R32F,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillTexture(tex, fillfunc, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(float);
+ for (y = 0; y < 4; y++)
+ {
+ float *ptr = (float *)lock_rect.pBits + y * pitch;
+ for (x = 0; x < 4; x++)
+ {
+ D3DXVECTOR4 got, expected;
+
+ got.x = *ptr++;
+ got.y = *ptr++;
+ got.z = *ptr++;
+ got.w = *ptr++;
+
+ expected.x = (x + 0.5f) / 4.0f;
+ expected.y = (y + 0.5f) / 4.0f;
+ expected.z = 1.0f / 4.0f;
+ expected.w = 1.0f;
+
+ expect_vec4(&expected, &got);
+ }
+ }
+
+ IDirect3DTexture9_UnlockRect(tex, 0);
+ }
+ else
+ skip("Failed to lock texture\n");
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create D3DFMT_A32B32G32R32F texture\n");
+
+ /* test a compressed texture */
+ hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillTexture(tex, fillfunc, NULL);
+ todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create D3DFMT_DXT1 texture\n");
+}
+
+static void WINAPI fillfunc_cube(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
+ const D3DXVECTOR3 *texelsize, void *data)
+{
+ value->x = (texcoord->x + 1.0f) / 2.0f;
+ value->y = (texcoord->y + 1.0f) / 2.0f;
+ value->z = (texcoord->z + 1.0f) / 2.0f;
+ value->w = texelsize->x;
+}
+
+enum cube_coord
+{
+ XCOORD = 0,
+ XCOORDINV = 1,
+ YCOORD = 2,
+ YCOORDINV = 3,
+ ZERO = 4,
+ ONE = 5
+};
+
+static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
+{
+ switch (coord)
+ {
+ case XCOORD:
+ return x + 0.5f;
+ case XCOORDINV:
+ return size - x - 0.5f;
+ case YCOORD:
+ return y + 0.5f;
+ case YCOORDINV:
+ return size - y - 0.5f;
+ case ZERO:
+ return 0.0f;
+ case ONE:
+ return size;
+ default:
+ trace("Unexpected coordinate value\n");
+ return 0.0f;
+ }
+}
+
+static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DCubeTexture9 *tex;
+ HRESULT hr;
+ D3DLOCKED_RECT lock_rect;
+ DWORD x, y, f, m;
+ DWORD v[4], e[4];
+ DWORD value, expected, size, pitch;
+ enum cube_coord coordmap[6][3] =
+ {
+ {ONE, YCOORDINV, XCOORDINV},
+ {ZERO, YCOORDINV, XCOORD},
+ {XCOORD, ONE, YCOORD},
+ {XCOORD, ZERO, YCOORDINV},
+ {XCOORD, YCOORDINV, ONE},
+ {XCOORDINV, YCOORDINV, ZERO}
+ };
+
+ size = 4;
+ hr = IDirect3DDevice9_CreateCubeTexture(device, size, 0, 0, D3DFMT_A8R8G8B8,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
+ ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ for (m = 0; m < 3; m++)
+ {
+ for (f = 0; f < 6; f++)
+ {
+ hr = IDirect3DCubeTexture9_LockRect(tex, f, m, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(DWORD);
+ for (y = 0; y < size; y++)
+ {
+ for (x = 0; x < size; x++)
+ {
+ value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
+ v[0] = (value >> 24) & 0xff;
+ v[1] = (value >> 16) & 0xff;
+ v[2] = (value >> 8) & 0xff;
+ v[3] = value & 0xff;
+
+ e[0] = (f == 0) || (f == 1) ?
+ 0 : (BYTE)(255.0f / size * 2.0f + 0.5f);
+ e[1] = get_cube_coord(coordmap[f][0], x, y, size) / size * 255.0f + 0.5f;
+ e[2] = get_cube_coord(coordmap[f][1], x, y, size) / size * 255.0f + 0.5f;
+ e[3] = get_cube_coord(coordmap[f][2], x, y, size) / size * 255.0f + 0.5f;
+ expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
+ f, x, y, value, expected);
+ }
+ }
+ IDirect3DCubeTexture9_UnlockRect(tex, f, m);
+ }
+ }
+ size >>= 1;
+ }
+
+ IDirect3DCubeTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ for (f = 0; f < 6; f++)
+ {
+ hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ pitch = lock_rect.Pitch / sizeof(WORD);
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 4; x++)
+ {
+ value = ((WORD *)lock_rect.pBits)[y * pitch + x];
+ v[0] = value >> 15;
+ v[1] = value >> 10 & 0x1f;
+ v[2] = value >> 5 & 0x1f;
+ v[3] = value & 0x1f;
+
+ e[0] = (f == 0) || (f == 1) ?
+ 0 : (BYTE)(1.0f / size * 2.0f + 0.5f);
+ e[1] = get_cube_coord(coordmap[f][0], x, y, 4) / 4 * 31.0f + 0.5f;
+ e[2] = get_cube_coord(coordmap[f][1], x, y, 4) / 4 * 31.0f + 0.5f;
+ e[3] = get_cube_coord(coordmap[f][2], x, y, 4) / 4 * 31.0f + 0.5f;
+ expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
+ f, x, y, value, expected);
+ }
+ }
+ IDirect3DCubeTexture9_UnlockRect(tex, f, 0);
+ }
+ }
+
+ IDirect3DCubeTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+}
+
+static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
+ const D3DXVECTOR3 *texelsize, void *data)
+{
+ value->x = texcoord->x;
+ value->y = texcoord->y;
+ value->z = texcoord->z;
+ value->w = texelsize->x;
+}
+
+static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device)
+{
+ IDirect3DVolumeTexture9 *tex;
+ HRESULT hr;
+ D3DLOCKED_BOX lock_box;
+ DWORD x, y, z, m;
+ DWORD v[4], e[4];
+ DWORD value, expected, size, row_pitch, slice_pitch;
+
+ size = 4;
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
+ ok(hr == D3D_OK, "D3DXFillVolumeTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ for (m = 0; m < 3; m++)
+ {
+ hr = IDirect3DVolumeTexture9_LockBox(tex, m, &lock_box, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ row_pitch = lock_box.RowPitch / sizeof(DWORD);
+ slice_pitch = lock_box.SlicePitch / sizeof(DWORD);
+ for (z = 0; z < size; z++)
+ {
+ for (y = 0; y < size; y++)
+ {
+ for (x = 0; x < size; x++)
+ {
+ value = ((DWORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
+ v[0] = (value >> 24) & 0xff;
+ v[1] = (value >> 16) & 0xff;
+ v[2] = (value >> 8) & 0xff;
+ v[3] = value & 0xff;
+
+ e[0] = 255.0f / size + 0.5f;
+ e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
+ e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
+ e[3] = (z + 0.5f) / size * 255.0f + 0.5f;
+ expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, z, value, expected);
+ }
+ }
+ }
+ IDirect3DVolumeTexture9_UnlockBox(tex, m);
+ }
+ size >>= 1;
+ }
+
+ IDirect3DVolumeTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
+ D3DPOOL_MANAGED, &tex, NULL);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
+ ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
+ hr = IDirect3DVolumeTexture9_LockBox(tex, 0, &lock_box, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ row_pitch = lock_box.RowPitch / sizeof(WORD);
+ slice_pitch = lock_box.SlicePitch / sizeof(WORD);
+ for (z = 0; z < 4; z++)
+ {
+ for (y = 0; y < 4; y++)
+ {
+ for (x = 0; x < 4; x++)
+ {
+ value = ((WORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
+ v[0] = value >> 15;
+ v[1] = value >> 10 & 0x1f;
+ v[2] = value >> 5 & 0x1f;
+ v[3] = value & 0x1f;
+
+ e[0] = 1;
+ e[1] = (x + 0.5f) / 4 * 31.0f + 0.5f;
+ e[2] = (y + 0.5f) / 4 * 31.0f + 0.5f;
+ e[3] = (z + 0.5f) / 4 * 31.0f + 0.5f;
+ expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
+
+ ok(color_match(v, e),
+ "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
+ x, y, z, value, expected);
+ }
+ }
+ }
+ IDirect3DVolumeTexture9_UnlockBox(tex, 0);
+ }
+
+ IDirect3DVolumeTexture9_Release(tex);
+ }
+ else
+ skip("Failed to create texture\n");
+}
+
+static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DTexture9 *texture;
+ D3DRESOURCETYPE type;
+ D3DSURFACE_DESC desc;
+ D3DLOCKED_RECT lock_rect;
+ int i;
+ DWORD level_count;
+
+ hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit) - 1, &texture);
+ ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
+
+ /* Check that D3DXCreateTextureFromFileInMemory accepts cube texture dds file (only first face texture is loaded) */
+ hr = D3DXCreateTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &texture);
+ todo_wine_if (!has_2d_dxt5)
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ type = IDirect3DTexture9_GetType(texture);
+ ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u\n", type, D3DRTYPE_TEXTURE);
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(desc.Width == 4, "Width is %u, expected 4\n", desc.Width);
+ ok(desc.Height == 4, "Height is %u, expected 4\n", desc.Height);
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < 16; i++)
+ ok(((BYTE *)lock_rect.pBits)[i] == dds_cube_map[128 + i],
+ "Byte at index %u is 0x%02x, expected 0x%02x.\n",
+ i, ((BYTE *)lock_rect.pBits)[i], dds_cube_map[128 + i]);
+ IDirect3DTexture9_UnlockRect(texture, 0);
+ }
+ IDirect3DTexture9_Release(texture);
+
+ }
+
+ /* Volume textures work too. */
+ hr = D3DXCreateTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &texture);
+ todo_wine_if (!has_2d_dxt3)
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ type = IDirect3DTexture9_GetType(texture);
+ ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
+ level_count = IDirect3DBaseTexture9_GetLevelCount((IDirect3DBaseTexture9 *)texture);
+ todo_wine ok(level_count == 3, "Texture has %u mip levels, 3 expected.\n", level_count);
+ hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
+ ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
+ ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
+ ok(desc.Height == 4, "Height is %u, expected 4.\n", desc.Height);
+
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x.\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ for (i = 0; i < 16; ++i)
+ ok(((BYTE *)lock_rect.pBits)[i] == dds_volume_map[128 + i],
+ "Byte at index %u is 0x%02x, expected 0x%02x.\n",
+ i, ((BYTE *)lock_rect.pBits)[i], dds_volume_map[128 + i]);
+ IDirect3DTexture9_UnlockRect(texture, 0);
+ }
+ /* The lower texture levels are apparently generated by filtering the level 0 surface
+ * I.e. following levels from the file are ignored. */
+ IDirect3DTexture9_Release(texture);
+ }
+}
+
+static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DTexture9 *texture;
+ unsigned int miplevels;
+ IDirect3DSurface9 *surface;
+ D3DSURFACE_DESC desc;
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
+ 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
+ D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit), D3DX_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_FILTER_POINT), 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
+ miplevels = IDirect3DTexture9_GetLevelCount(texture);
+ ok(miplevels == 1, "Got miplevels %u, expected %u.\n", miplevels, 1);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Width == 1 && desc.Height == 1,
+ "Surface dimensions are %ux%u, expected 1x1.\n", desc.Width, desc.Height);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+
+ if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
+ {
+ skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
+ return;
+ }
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
+ IDirect3DTexture9_Release(texture);
+
+ /* Checking for color key format overrides. */
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_A1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A1R5G5B5);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X1R5G5B5, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8R8G8B8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_A8L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8L8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+ hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
+ D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
+ D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
+ ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
+ IDirect3DSurface9_GetDesc(surface, &desc);
+ ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
+ IDirect3DSurface9_Release(surface);
+ IDirect3DTexture9_Release(texture);
+}
+
+static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ ULONG ref;
+ DWORD levelcount;
+ IDirect3DCubeTexture9 *cube_texture;
+ D3DSURFACE_DESC surface_desc;
+
+ hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
+ if (SUCCEEDED(hr))
+ {
+ levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
+ todo_wine ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
+
+ hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
+ ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
+
+ ref = IDirect3DCubeTexture9_Release(cube_texture);
+ ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
+ } else skip("Couldn't create cube texture\n");
+}
+
+static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DCubeTexture9 *cube_texture;
+
+ if (!is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
+ {
+ skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
+ return;
+ }
+
+ hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT, D3DX_DEFAULT,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture);
+ todo_wine_if (!has_cube_dxt5)
+ ok(hr == D3D_OK, "D3DXCreateCubeTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
+ if (SUCCEEDED(hr)) IDirect3DCubeTexture9_Release(cube_texture);
+}
+
+static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ ULONG ref;
+ DWORD levelcount;
+ IDirect3DVolumeTexture9 *volume_texture;
+ D3DVOLUME_DESC volume_desc;
+
+ hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
+ todo_wine_if (!has_3d_dxt3)
+ ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
+ ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
+
+ hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(volume_desc.Width == 4, "Got width %u, expected 4\n", volume_desc.Width);
+ ok(volume_desc.Height == 4, "Got height %u, expected 4\n", volume_desc.Height);
+ ok(volume_desc.Depth == 2, "Got depth %u, expected 2\n", volume_desc.Depth);
+ ok(volume_desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected D3DPOOL_MANAGED\n", volume_desc.Pool);
+
+ hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
+ ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
+ ok(volume_desc.Width == 2, "Got width %u, expected 2\n", volume_desc.Width);
+ ok(volume_desc.Height == 2, "Got height %u, expected 2\n", volume_desc.Height);
+ ok(volume_desc.Depth == 1, "Got depth %u, expected 1\n", volume_desc.Depth);
+
+ ref = IDirect3DVolumeTexture9_Release(volume_texture);
+ ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
+ }
+}
+
+/* fills positive x face with red color */
+static void WINAPI fill_cube_positive_x(D3DXVECTOR4 *out, const D3DXVECTOR3 *tex_coord, const D3DXVECTOR3 *texel_size, void *data)
+{
+ memset(out, 0, sizeof(*out));
+ if (tex_coord->x > 0 && fabs(tex_coord->x) > fabs(tex_coord->y) && fabs(tex_coord->x) > fabs(tex_coord->z))
+ out->x = 1;
+}
+
+static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ IDirect3DTexture9 *texture;
+ IDirect3DCubeTexture9 *cube_texture;
+ IDirect3DVolumeTexture9 *volume_texture;
+ ID3DXBuffer *buffer;
+ void *buffer_pointer;
+ DWORD buffer_size;
+ D3DXIMAGE_INFO info;
+ D3DXIMAGE_FILEFORMAT file_format;
+
+ /* textures */
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create texture\n");
+ return;
+ }
+
+ for (file_format = D3DXIFF_BMP; file_format <= D3DXIFF_JPG; file_format++)
+ {
+ hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, (IDirect3DBaseTexture9 *)texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == file_format, "Got file format %#x, expected %#x\n", info.ImageFileFormat, file_format);
+ ID3DXBuffer_Release(buffer);
+ }
+ }
+
+ todo_wine {
+ hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ ID3DXBuffer_Release(buffer);
+ }
+ }
+
+ IDirect3DTexture9_Release(texture);
+
+ /* cube textures */
+ hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create cube texture\n");
+ return;
+ }
+
+ hr = D3DXFillCubeTexture(cube_texture, fill_cube_positive_x, NULL);
+ ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)cube_texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ IDirect3DSurface9 *surface;
+
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
+
+ /* positive x face is saved */
+ hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
+ if (SUCCEEDED(hr))
+ {
+ D3DLOCKED_RECT locked_rect;
+
+ hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, buffer_pointer, buffer_size, NULL, D3DX_FILTER_NONE, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
+ if (SUCCEEDED(hr))
+ {
+ DWORD *color = locked_rect.pBits;
+ ok(*color == 0x00ff0000, "Got color %#x, expected %#x\n", *color, 0x00ff0000);
+ IDirect3DSurface9_UnlockRect(surface);
+ }
+
+ IDirect3DSurface9_Release(surface);
+ } else skip("Failed to create surface\n");
+
+ ID3DXBuffer_Release(buffer);
+ }
+
+ todo_wine {
+ hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)cube_texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
+ ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ ID3DXBuffer_Release(buffer);
+ }
+ }
+
+ IDirect3DCubeTexture9_Release(cube_texture);
+
+ /* volume textures */
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &volume_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create volume texture\n");
+ return;
+ }
+
+ todo_wine {
+ hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)volume_texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.Depth == 1, "Got depth %u, expected %u\n", info.Depth, 1);
+ ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
+ ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
+ ID3DXBuffer_Release(buffer);
+ }
+
+ hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL);
+ ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+ if (SUCCEEDED(hr))
+ {
+ buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
+ buffer_size = ID3DXBuffer_GetBufferSize(buffer);
+ hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
+ ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
+ ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
+ ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256);
+ ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
+ ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
+ ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
+ ID3DXBuffer_Release(buffer);
+ }
+ }
+
+ IDirect3DVolumeTexture9_Release(volume_texture);
+}
+
+static void test_texture_shader(void)
+{
+ static const DWORD shader_zero[] = {0x0};
+ static const DWORD shader_invalid[] = {0xeeee0100};
+ static const DWORD shader_empty[] = {0xfffe0200, 0x0000ffff};
+#if 0
+float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
+{
+ return float4(pos, 1.0);
+}
+#endif
+ static const DWORD shader_code[] =
+ {
+ 0x54580100, 0x0015fffe, 0x42415443, 0x0000001c, 0x0000001f, 0x54580100, 0x00000000, 0x00000000,
+ 0x00000100, 0x0000001c, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
+ 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x000afffe,
+ 0x54494c43, 0x00000004, 0x00000000, 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x0014fffe, 0x434c5846, 0x00000002, 0x10000003, 0x00000001, 0x00000000,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x10000001, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
+ };
+ IDirect3DVolumeTexture9 *volume_texture;
+ IDirect3DCubeTexture9 *cube_texture;
+ D3DPRESENT_PARAMETERS d3dpp;
+ IDirect3DTexture9 *texture;
+ IDirect3DDevice9 *device;
+ ID3DXTextureShader *tx;
+ unsigned int x, y, z;
+ ID3DXBuffer *buffer;
+ unsigned int *data;
+ D3DLOCKED_RECT lr;
+ D3DLOCKED_BOX lb;
+ IDirect3D9 *d3d;
+ D3DCAPS9 caps;
+ HRESULT hr;
+ HWND wnd;
+
+ hr = D3DXCreateTextureShader(NULL, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXCreateTextureShader(NULL, &tx);
+ ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXCreateTextureShader(shader_invalid, &tx);
+ todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXCreateTextureShader(shader_zero, &tx);
+ todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXCreateTextureShader(shader_empty, &tx);
+ todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXCreateTextureShader(shader_code, &tx);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = tx->lpVtbl->GetFunction(tx, &buffer);
+ todo_wine ok(SUCCEEDED(hr), "Failed to get texture shader bytecode.\n");
+ if (FAILED(hr))
+ {
+ skip("Texture shaders not supported, skipping further tests.\n");
+ IUnknown_Release(tx);
+ return;
+ }
+ ID3DXBuffer_Release(buffer);
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window.\n");
+ IUnknown_Release(tx);
+ return;
+ }
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d)
+ {
+ skip("Couldn't create IDirect3D9 object.\n");
+ DestroyWindow(wnd);
+ IUnknown_Release(tx);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ IUnknown_Release(tx);
+ return;
+ }
+
+ IDirect3DDevice9_GetDeviceCaps(device, &caps);
+
+ hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
+ &texture, NULL);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXFillTextureTX(texture, tx);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
+ data = lr.pBits;
+ for (y = 0; y < 256; ++y)
+ {
+ for (x = 0; x < 256; ++x)
+ {
+ unsigned int expected = 0xff000000 | x << 16 | y << 8;
+ /* The third position coordinate is apparently undefined for 2D textures. */
+ unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
+
+ ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y);
+ }
+ }
+ hr = IDirect3DTexture9_UnlockRect(texture, 0);
+ ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
+
+ IDirect3DTexture9_Release(texture);
+
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
+ {
+ skip("Cube textures not supported, skipping tests.\n");
+ goto cleanup;
+ }
+
+ hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
+ &cube_texture, NULL);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXFillCubeTextureTX(cube_texture, tx);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ for (z = 0; z < 6; ++z)
+ {
+ static const char * const mapping[6][3] =
+ {
+ {"-x", "-y", "1"},
+ {"+x", "-y", "0"},
+ {"+y", "1", "+x"},
+ {"-y", "0", "+x"},
+ {"1", "-y", "+x"},
+ {"0", "-y", "-x"},
+ };
+
+ hr = IDirect3DCubeTexture9_LockRect(cube_texture, z, 0, &lr, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
+ data = lr.pBits;
+ for (y = 0; y < 256; ++y)
+ {
+ for (x = 0; x < 256; ++x)
+ {
+ unsigned int color = data[y * lr.Pitch / sizeof(*data) + x];
+ unsigned int expected = 0xff000000;
+ unsigned int i;
+
+ for (i = 0; i < 3; ++i)
+ {
+ int component;
+
+ if (mapping[z][i][0] == '0')
+ component = 0;
+ else if (mapping[z][i][0] == '1')
+ component = 255;
+ else
+ component = mapping[z][i][1] == 'x' ? x * 2 - 255 : y * 2 - 255;
+ if (mapping[z][i][0] == '-')
+ component = -component;
+ expected |= max(component, 0) << i * 8;
+ }
+ ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
+ color, x, y, z);
+ }
+ }
+ hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, z, 0);
+ ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
+ }
+
+ IDirect3DCubeTexture9_Release(cube_texture);
+
+ if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || caps.MaxVolumeExtent < 64)
+ {
+ skip("Volume textures not supported, skipping test.\n");
+ goto cleanup;
+ }
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 64, 1, 0, D3DFMT_A8R8G8B8,
+ D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = D3DXFillVolumeTextureTX(volume_texture, tx);
+ ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY);
+ ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
+ data = lb.pBits;
+ for (z = 0; z < 64; ++z)
+ {
+ for (y = 0; y < 64; ++y)
+ {
+ for (x = 0; x < 64; ++x)
+ {
+ unsigned int expected = 0xff000000 | ((x * 4 + 2) << 16) | ((y * 4 + 2) << 8) | (z * 4 + 2);
+ unsigned int color = data[z * lb.SlicePitch / sizeof(*data) + y * lb.RowPitch / sizeof(*data) + x];
+
+ ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
+ color, x, y, z);
+ }
+ }
+ }
+ hr = IDirect3DVolumeTexture9_UnlockBox(volume_texture, 0);
+ ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
+
+ IDirect3DVolumeTexture9_Release(volume_texture);
+
+ cleanup:
+ IDirect3DDevice9_Release(device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ IUnknown_Release(tx);
+}
+
+START_TEST(texture)
+{
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+ ULONG ref;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d) {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if (FAILED(hr)) {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ /* Check whether DXTn textures are supported. */
+ has_2d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
+ hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5);
+ has_2d_dxt5 = SUCCEEDED(hr);
+ hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, D3DFMT_DXT5);
+ has_cube_dxt5 = SUCCEEDED(hr);
+ has_3d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT3));
+
+ test_D3DXCheckTextureRequirements(device);
+ test_D3DXCheckCubeTextureRequirements(device);
+ test_D3DXCheckVolumeTextureRequirements(device);
+ test_D3DXCreateTexture(device);
+ test_D3DXFilterTexture(device);
+ test_D3DXFillTexture(device);
+ test_D3DXFillCubeTexture(device);
+ test_D3DXFillVolumeTexture(device);
+ test_D3DXCreateTextureFromFileInMemory(device);
+ test_D3DXCreateTextureFromFileInMemoryEx(device);
+ test_D3DXCreateCubeTextureFromFileInMemory(device);
+ test_D3DXCreateCubeTextureFromFileInMemoryEx(device);
+ test_D3DXCreateVolumeTextureFromFileInMemory(device);
+ test_D3DXSaveTextureToFileInMemory(device);
+
+ ref = IDirect3DDevice9_Release(device);
+ ok(!ref, "Device has %u references left.\n", ref);
+
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+
+ test_texture_shader();
+}
--- /dev/null
+/*
+ * Tests for the D3DX9 volume functions
+ *
+ * Copyright 2012 Józef Kucia
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "wine/test.h"
+#include "d3dx9tex.h"
+
+/* 4x4x2 volume map dds, 2 mipmaps */
+static const unsigned char dds_volume_map[] =
+{
+ 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
+ 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
+ 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
+ 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
+};
+
+#define check_pixel_4bpp(box, x, y, z, color) _check_pixel_4bpp(__LINE__, box, x, y, z, color)
+static inline void _check_pixel_4bpp(unsigned int line, const D3DLOCKED_BOX *box, int x, int y, int z, DWORD expected_color)
+{
+ DWORD color = ((DWORD *)box->pBits)[x + (y * box->RowPitch + z * box->SlicePitch) / 4];
+ ok_(__FILE__, line)(color == expected_color, "Got color 0x%08x, expected 0x%08x\n", color, expected_color);
+}
+
+static inline void set_box(D3DBOX *box, UINT left, UINT top, UINT right, UINT bottom, UINT front, UINT back)
+{
+ box->Left = left;
+ box->Top = top;
+ box->Right = right;
+ box->Bottom = bottom;
+ box->Front = front;
+ box->Back = back;
+}
+
+static void test_D3DXLoadVolumeFromMemory(IDirect3DDevice9 *device)
+{
+ int i, x, y, z;
+ HRESULT hr;
+ D3DBOX src_box, dst_box;
+ D3DLOCKED_BOX locked_box;
+ IDirect3DVolume9 *volume;
+ IDirect3DVolumeTexture9 *volume_texture;
+ const DWORD pixels[] = { 0xc3394cf0, 0x235ae892, 0x09b197fd, 0x8dc32bf6,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xffffffff,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000 };
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,
+ &volume_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create volume texture.\n");
+ return;
+ }
+
+ IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
+
+ set_box(&src_box, 0, 0, 4, 1, 0, 4);
+ set_box(&dst_box, 0, 0, 4, 1, 0, 4);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ if (FAILED(hr))
+ {
+ win_skip("D3DXLoadVolumeFromMemory failed with error %#x, skipping some tests.\n", hr);
+ return;
+ }
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, &dst_box, D3DLOCK_READONLY);
+ for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, 0, i / 4, pixels[i]);
+ IDirect3DVolume9_UnlockBox(volume);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_UNKNOWN, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == E_FAIL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, E_FAIL);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, NULL, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, NULL, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, NULL, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&src_box, 0, 0, 4, 4, 0, 1);
+ set_box(&dst_box, 0, 0, 4, 4, 0, 1);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels), NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, &dst_box, D3DLOCK_READONLY);
+ for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, i / 4, 0, pixels[i]);
+ IDirect3DVolume9_UnlockBox(volume);
+
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, NULL, pixels, D3DFMT_A8R8G8B8, 16, sizeof(pixels), NULL, &src_box, D3DX_FILTER_NONE, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, NULL, D3DLOCK_READONLY);
+ for (i = 0; i < 16; i++) check_pixel_4bpp(&locked_box, i % 4, i / 4, 0, pixels[i]);
+ for (z = 0; z < 4; z++)
+ {
+ for (y = 0; y < 256; y++)
+ {
+ for (x = 0; x < 256; x++)
+ if (z != 0 || y >= 4 || x >= 4) check_pixel_4bpp(&locked_box, x, y, z, 0);
+ }
+ }
+ IDirect3DVolume9_UnlockBox(volume);
+
+ set_box(&src_box, 0, 0, 2, 2, 1, 2);
+ set_box(&dst_box, 0, 0, 2, 2, 0, 1);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 8, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, &dst_box, D3DLOCK_READONLY);
+ for (i = 0; i < 4; i++) check_pixel_4bpp(&locked_box, i % 2, i / 2, 0, pixels[i + 4]);
+ IDirect3DVolume9_UnlockBox(volume);
+
+ set_box(&src_box, 0, 0, 2, 2, 2, 3);
+ set_box(&dst_box, 0, 0, 2, 2, 1, 2);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 8, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_LockBox(volume, &locked_box, &dst_box, D3DLOCK_READONLY);
+ for (i = 0; i < 4; i++) check_pixel_4bpp(&locked_box, i % 2, i / 2, 0, pixels[i + 8]);
+ IDirect3DVolume9_UnlockBox(volume);
+
+ set_box(&src_box, 0, 0, 4, 1, 0, 4);
+
+ set_box(&dst_box, -1, -1, 3, 0, 0, 4);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&dst_box, 254, 254, 258, 255, 0, 4);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&dst_box, 4, 1, 0, 0, 0, 4);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&dst_box, 0, 0, 0, 0, 0, 0);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&dst_box, 0, 0, 0, 0, 0, 1);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&dst_box, 300, 300, 300, 300, 0, 0);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DVolume9_Release(volume);
+ IDirect3DVolumeTexture9_Release(volume_texture);
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &volume_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create volume texture\n");
+ return;
+ }
+
+ IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
+
+ set_box(&src_box, 0, 0, 4, 1, 0, 4);
+ set_box(&dst_box, 0, 0, 4, 1, 0, 4);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 16, NULL, &src_box, D3DX_DEFAULT, 0);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DVolume9_Release(volume);
+ IDirect3DVolumeTexture9_Release(volume_texture);
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 8, 1, 1, D3DUSAGE_DYNAMIC, D3DFMT_DXT1, D3DPOOL_DEFAULT, &volume_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create volume texture\n");
+ return;
+ }
+
+ IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
+
+ set_box(&src_box, 1, 1, 7, 7, 0, 1);
+ set_box(&dst_box, 1, 1, 7, 7, 0, 1);
+ hr = D3DXLoadVolumeFromMemory(volume, NULL, &dst_box, pixels, D3DFMT_A8R8G8B8, 16, 32, NULL, &src_box, D3DX_DEFAULT, 0);
+ todo_wine ok(hr == D3D_OK, "D3DXLoadVolumeFromMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ IDirect3DVolume9_Release(volume);
+ IDirect3DVolumeTexture9_Release(volume_texture);
+}
+
+static void test_D3DXLoadVolumeFromFileInMemory(IDirect3DDevice9 *device)
+{
+ HRESULT hr;
+ D3DBOX src_box;
+ IDirect3DVolume9 *volume;
+ IDirect3DVolumeTexture9 *volume_texture;
+
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, D3DUSAGE_DYNAMIC, D3DFMT_DXT3, D3DPOOL_DEFAULT,
+ &volume_texture, NULL);
+ if (FAILED(hr))
+ {
+ skip("Failed to create volume texture\n");
+ return;
+ }
+
+ IDirect3DVolumeTexture9_GetVolumeLevel(volume_texture, 0, &volume);
+
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, NULL, sizeof(dds_volume_map), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, NULL, 0, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, 0, NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ hr = D3DXLoadVolumeFromFileInMemory(NULL, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), NULL, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&src_box, 0, 0, 4, 4, 0, 2);
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), &src_box, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3D_OK, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
+
+ set_box(&src_box, 0, 0, 0, 0, 0, 0);
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), &src_box, D3DX_DEFAULT, 0, NULL);
+ ok(hr == E_FAIL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, E_FAIL);
+
+ set_box(&src_box, 0, 0, 5, 4, 0, 2);
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), &src_box, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ set_box(&src_box, 0, 0, 4, 4, 0, 3);
+ hr = D3DXLoadVolumeFromFileInMemory(volume, NULL, NULL, dds_volume_map, sizeof(dds_volume_map), &src_box, D3DX_DEFAULT, 0, NULL);
+ ok(hr == D3DERR_INVALIDCALL, "D3DXLoadVolumeFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
+
+ IDirect3DVolume9_Release(volume);
+ IDirect3DVolumeTexture9_Release(volume_texture);
+}
+
+START_TEST(volume)
+{
+ HWND wnd;
+ IDirect3D9 *d3d;
+ IDirect3DDevice9 *device;
+ D3DPRESENT_PARAMETERS d3dpp;
+ HRESULT hr;
+
+ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+ 640, 480, NULL, NULL, NULL, NULL)))
+ {
+ skip("Couldn't create application window\n");
+ return;
+ }
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d)
+ {
+ skip("Couldn't create IDirect3D9 object\n");
+ DestroyWindow(wnd);
+ return;
+ }
+
+ ZeroMemory(&d3dpp, sizeof(d3dpp));
+ d3dpp.Windowed = TRUE;
+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
+ if(FAILED(hr))
+ {
+ skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+ return;
+ }
+
+ test_D3DXLoadVolumeFromMemory(device);
+ test_D3DXLoadVolumeFromFileInMemory(device);
+
+ IDirect3DDevice9_Release(device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(wnd);
+}
--- /dev/null
+/*
+ * Copyright 2012 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+
+#include "wine/test.h"
+#include "d3dx9.h"
+#include "d3dx9xof.h"
+
+static const char templates_bad_file_type1[] =
+"xOf 0302txt 0064\n";
+
+static const char templates_bad_file_version[] =
+"xof 0102txt 0064\n";
+
+static const char templates_bad_file_type2[] =
+"xof 0302foo 0064\n";
+
+static const char templates_bad_file_float_size[] =
+"xof 0302txt 0050\n";
+
+static const char templates_parse_error[] =
+"xof 0302txt 0064"
+"foobar;\n";
+
+static const char templates[] =
+"xof 0302txt 0064"
+"template Header"
+"{"
+"<3D82AB43-62DA-11CF-AB39-0020AF71E433>"
+"WORD major;"
+"WORD minor;"
+"DWORD flags;"
+"}\n";
+
+static char objects[] =
+"xof 0302txt 0064\n"
+"Header Object\n"
+"{\n"
+"1; 2; 3;\n"
+"}\n";
+
+static char object_noname[] =
+"xof 0302txt 0064\n"
+"Header\n"
+"{\n"
+"1; 2; 3;\n"
+"}\n";
+
+static char template_using_index_color_lower[] =
+"xof 0302txt 0064\n"
+"template MeshVertexColors\n"
+"{\n"
+"<1630B821-7842-11cf-8F52-0040333594A3>\n"
+"DWORD nVertexColors;\n"
+"array indexColor vertexColors[nVertexColors];\n"
+"}\n";
+
+static char template_using_index_color_upper[] =
+"xof 0302txt 0064\n"
+"template MeshVertexColors\n"
+"{\n"
+"<1630B821-7842-11cf-8F52-0040333594A3>\n"
+"DWORD nVertexColors;\n"
+"array IndexColor vertexColors[nVertexColors];\n"
+"}\n";
+
+static void test_templates(void)
+{
+ ID3DXFile *d3dxfile;
+ HRESULT ret;
+
+ ret = D3DXFileCreate(NULL);
+ ok(ret == E_POINTER, "D3DXCreateFile returned %#x, expected %#x\n", ret, E_POINTER);
+
+ ret = D3DXFileCreate(&d3dxfile);
+ ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates_bad_file_type1, sizeof(templates_bad_file_type1) - 1);
+ ok(ret == D3DXFERR_BADFILETYPE, "RegisterTemplates returned %#x, expected %#x\n", ret, D3DXFERR_BADFILETYPE);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates_bad_file_version, sizeof(templates_bad_file_version) - 1);
+ ok(ret == D3DXFERR_BADFILEVERSION, "RegisterTemplates returned %#x, expected %#x\n", ret, D3DXFERR_BADFILEVERSION);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates_bad_file_type2, sizeof(templates_bad_file_type2) - 1);
+ ok(ret == D3DXFERR_BADFILETYPE, "RegisterTemplates returned %#x, expected %#x\n", ret, D3DXFERR_BADFILETYPE);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates_bad_file_float_size, sizeof(templates_bad_file_float_size) - 1);
+ ok(ret == D3DXFERR_BADFILEFLOATSIZE, "RegisterTemplates returned %#x, expected %#x\n", ret, D3DXFERR_BADFILEFLOATSIZE);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates_parse_error, sizeof(templates_parse_error) - 1);
+ ok(ret == D3DXFERR_PARSEERROR, "RegisterTemplates returned %#x, expected %#x\n", ret, D3DXFERR_PARSEERROR);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates, sizeof(templates) - 1);
+ ok(ret == S_OK, "RegisterTemplates failed with %#x\n", ret);
+
+ d3dxfile->lpVtbl->Release(d3dxfile);
+}
+
+static void test_lock_unlock(void)
+{
+ ID3DXFile *d3dxfile;
+ D3DXF_FILELOADMEMORY memory;
+ ID3DXFileEnumObject *enum_object;
+ ID3DXFileData *data_object;
+ const void *data;
+ SIZE_T size;
+ HRESULT ret;
+
+ ret = D3DXFileCreate(&d3dxfile);
+ ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates, sizeof(templates) - 1);
+ ok(ret == S_OK, "RegisterTemplates failed with %#x\n", ret);
+
+ memory.lpMemory = objects;
+ memory.dSize = sizeof(objects) - 1;
+
+ ret = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &memory, D3DXF_FILELOAD_FROMMEMORY, &enum_object);
+ ok(ret == S_OK, "CreateEnumObject failed with %#x\n", ret);
+
+ ret = enum_object->lpVtbl->GetChild(enum_object, 0, &data_object);
+ ok(ret == S_OK, "GetChild failed with %#x\n", ret);
+
+ ret = data_object->lpVtbl->Unlock(data_object);
+ ok(ret == S_OK, "Unlock failed with %#x\n", ret);
+ ret = data_object->lpVtbl->Lock(data_object, &size, &data);
+ ok(ret == S_OK, "Lock failed with %#x\n", ret);
+ ret = data_object->lpVtbl->Lock(data_object, &size, &data);
+ ok(ret == S_OK, "Lock failed with %#x\n", ret);
+ ret = data_object->lpVtbl->Unlock(data_object);
+ ok(ret == S_OK, "Unlock failed with %#x\n", ret);
+ ret = data_object->lpVtbl->Unlock(data_object);
+ ok(ret == S_OK, "Unlock failed with %#x\n", ret);
+
+ data_object->lpVtbl->Release(data_object);
+ enum_object->lpVtbl->Release(enum_object);
+ d3dxfile->lpVtbl->Release(d3dxfile);
+}
+
+static void test_getname(void)
+{
+ ID3DXFile *d3dxfile;
+ D3DXF_FILELOADMEMORY memory;
+ ID3DXFileEnumObject *enum_object;
+ ID3DXFileData *data_object;
+ SIZE_T length;
+ char name[100];
+ HRESULT ret;
+
+ ret = D3DXFileCreate(&d3dxfile);
+ ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret);
+
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, templates, sizeof(templates) - 1);
+ ok(ret == S_OK, "RegisterTemplates failed with %#x\n", ret);
+
+ /* Check object with name */
+ memory.lpMemory = objects;
+ memory.dSize = sizeof(objects) - 1;
+ ret = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &memory, D3DXF_FILELOAD_FROMMEMORY, &enum_object);
+ ok(ret == S_OK, "CreateEnumObject failed with %#x\n", ret);
+ ret = enum_object->lpVtbl->GetChild(enum_object, 0, &data_object);
+ ok(ret == S_OK, "GetChild failed with %#x\n", ret);
+
+ ret = data_object->lpVtbl->GetName(data_object, NULL, NULL);
+ ok(ret == D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE);
+ ret = data_object->lpVtbl->GetName(data_object, name, NULL);
+ ok(ret == D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE);
+ ret = data_object->lpVtbl->GetName(data_object, NULL, &length);
+ ok(ret == S_OK, "GetName failed with %#x\n", ret);
+ ok(length == 7, "Returned length should be 7 instead of %ld\n", length);
+ length = sizeof(name);
+ ret = data_object->lpVtbl->GetName(data_object, name, &length);
+ ok(ret == S_OK, "GetName failed with %#x\n", ret);
+ ok(length == 7, "Returned length should be 7 instead of %ld\n", length);
+ ok(!strcmp(name, "Object"), "Returned string should be 'Object' instead of '%s'\n", name);
+ length = 3;
+ ret = data_object->lpVtbl->GetName(data_object, name, &length);
+ ok(ret== D3DXFERR_BADVALUE, "GetName returned %#x, expected %#x\n", ret, D3DXFERR_BADVALUE);
+
+ data_object->lpVtbl->Release(data_object);
+ enum_object->lpVtbl->Release(enum_object);
+
+ /* Check object without name */
+ memory.lpMemory = object_noname;
+ memory.dSize = sizeof(object_noname) - 1;
+ ret = d3dxfile->lpVtbl->CreateEnumObject(d3dxfile, &memory, D3DXF_FILELOAD_FROMMEMORY, &enum_object);
+ ok(ret == S_OK, "CreateEnumObject failed with %#x\n", ret);
+ ret = enum_object->lpVtbl->GetChild(enum_object, 0, &data_object);
+ ok(ret == S_OK, "GetChild failed with %#x\n", ret);
+
+ /* Contrary to d3dxof, d3dx9_36 returns an empty string with a null byte when no name is available.
+ * If the input size is 0, it returns a length of 1 without touching the buffer */
+ ret = data_object->lpVtbl->GetName(data_object, NULL, &length);
+ ok(ret == S_OK, "GetName failed with %#x\n", ret);
+ ok(length == 1, "Returned length should be 1 instead of %ld\n", length);
+ length = 0;
+ name[0] = 0x7f;
+ ret = data_object->lpVtbl->GetName(data_object, name, &length);
+ ok(ret == S_OK, "GetName failed with %#x\n", ret);
+ ok(length == 1, "Returned length should be 1 instead of %ld\n", length);
+ ok(name[0] == 0x7f, "First character is %#x instead of 0x7f\n", name[0]);
+ length = sizeof(name);
+ name[0] = 0x7f;
+ ret = data_object->lpVtbl->GetName(data_object, name, &length);
+ ok(ret == S_OK, "GetName failed with %#x\n", ret);
+ ok(length == 1, "Returned length should be 1 instead of %ld\n", length);
+ ok(name[0] == 0, "First character is %#x instead of 0x00\n", name[0]);
+
+ data_object->lpVtbl->Release(data_object);
+ enum_object->lpVtbl->Release(enum_object);
+ d3dxfile->lpVtbl->Release(d3dxfile);
+}
+
+static void test_type_index_color(void)
+{
+ ID3DXFile *d3dxfile;
+ HRESULT ret;
+
+ ret = D3DXFileCreate(&d3dxfile);
+ ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret);
+
+ /* Test that 'indexColor' can be used (same as IndexedColor in standard templates) and is case sensitive */
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, template_using_index_color_lower, sizeof(template_using_index_color_lower) - 1);
+ ok(ret == S_OK, "RegisterTemplates failed with %#x\n", ret);
+ ret = d3dxfile->lpVtbl->RegisterTemplates(d3dxfile, template_using_index_color_upper, sizeof(template_using_index_color_upper) - 1);
+ ok(ret == D3DXFERR_PARSEERROR, "RegisterTemplates returned %#x instead of %#x\n", ret, D3DXFERR_PARSEERROR);
+
+ d3dxfile->lpVtbl->Release(d3dxfile);
+}
+
+static void process_data(ID3DXFileData *xfile_data, int level)
+{
+ HRESULT ret;
+ char name[100];
+ GUID clsid;
+ GUID clsid_type;
+ SIZE_T len = sizeof(name);
+ int i;
+ const BYTE *data;
+ SIZE_T size;
+ SIZE_T children;
+
+ ret = xfile_data->lpVtbl->GetId(xfile_data, &clsid);
+ ok(ret == S_OK, "ID3DXFileData_GetId failed with %#x\n", ret);
+ ret = xfile_data->lpVtbl->GetName(xfile_data, name, &len);
+ ok(ret == S_OK, "ID3DXFileData_GetName failed with %#x\n", ret);
+ ret = xfile_data->lpVtbl->GetType(xfile_data, &clsid_type);
+ ok(ret == S_OK, "IDirectXFileData_GetType failed with %#x\n", ret);
+ ret = xfile_data->lpVtbl->Lock(xfile_data, &size, (const void**)&data);
+ ok(ret == S_OK, "IDirectXFileData_Lock failed with %#x\n", ret);
+
+ for (i = 0; i < level; i++)
+ printf(" ");
+
+ printf("Found object '%s' - %s - %s - %lu\n",
+ len ? name : "", wine_dbgstr_guid(&clsid), wine_dbgstr_guid(&clsid_type), size);
+
+ if (size)
+ {
+ int j;
+ for (j = 0; j < size; j++)
+ {
+ if (j && !(j%16))
+ printf("\n");
+ printf("%02x ", data[j]);
+ }
+ printf("\n");
+ }
+
+ ret = xfile_data->lpVtbl->Unlock(xfile_data);
+ ok(ret == S_OK, "ID3DXFileData_Unlock failed with %#x\n", ret);
+
+ ret = xfile_data->lpVtbl->GetChildren(xfile_data, &children);
+ ok(ret == S_OK, "ID3DXFileData_GetChildren failed with %#x\n", ret);
+
+ level++;
+
+ for (i = 0; i < children; i++)
+ {
+ ID3DXFileData *child;
+ int j;
+
+ ret = xfile_data->lpVtbl->GetChild(xfile_data, i, &child);
+ ok(ret == S_OK, "ID3DXFileData_GetChild failed with %#x\n", ret);
+ for (j = 0; j < level; j++)
+ printf(" ");
+ if (child->lpVtbl->IsReference(child))
+ printf("Found Data Reference (%d)\n", i + 1);
+ else
+ printf("Found Data (%d)\n", i + 1);
+
+ process_data(child, level);
+
+ child->lpVtbl->Release(child);
+ }
+}
+
+/* Dump an X file 'objects.x' and its related templates file 'templates.x' if they are both presents
+ * Useful for debug by comparing outputs from native and builtin dlls */
+static void test_dump(void)
+{
+ HRESULT ret;
+ ULONG ref;
+ ID3DXFile *xfile = NULL;
+ ID3DXFileEnumObject *xfile_enum_object = NULL;
+ HANDLE file;
+ void *data;
+ DWORD size;
+ SIZE_T children;
+ int i;
+
+ /* Dump data only if there is an object and a template */
+ file = CreateFileA("objects.x", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return;
+ CloseHandle(file);
+
+ file = CreateFileA("templates.x", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ return;
+
+ data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 10000);
+
+ if (!ReadFile(file, data, 10000, &size, NULL))
+ {
+ skip("Templates file is too big\n");
+ goto exit;
+ }
+
+ printf("Load templates file (%u bytes)\n", size);
+
+ ret = D3DXFileCreate(&xfile);
+ ok(ret == S_OK, "D3DXCreateFile failed with %#x\n", ret);
+
+ ret = xfile->lpVtbl->RegisterTemplates(xfile, data, size);
+ ok(ret == S_OK, "ID3DXFileImpl_RegisterTemplates failed with %#x\n", ret);
+
+ ret = xfile->lpVtbl->CreateEnumObject(xfile, (void*)"objects.x", D3DXF_FILELOAD_FROMFILE, &xfile_enum_object);
+ ok(ret == S_OK, "ID3DXFile_CreateEnumObject failed with %#x\n", ret);
+
+ ret = xfile_enum_object->lpVtbl->GetChildren(xfile_enum_object, &children);
+ ok(ret == S_OK, "ID3DXFileEnumObject_GetChildren failed with %#x\n", ret);
+
+ for (i = 0; i < children; i++)
+ {
+ ID3DXFileData *child;
+ ret = xfile_enum_object->lpVtbl->GetChild(xfile_enum_object, i, &child);
+ ok(ret == S_OK, "ID3DXFileEnumObject_GetChild failed with %#x\n", ret);
+ printf("\n");
+ process_data(child, 0);
+ child->lpVtbl->Release(child);
+ }
+
+ ref = xfile_enum_object->lpVtbl->Release(xfile_enum_object);
+ ok(ref == 0, "Got refcount %u, expected 0\n", ref);
+
+ ref = xfile->lpVtbl->Release(xfile);
+ ok(ref == 0, "Got refcount %u, expected 0\n", ref);
+
+
+exit:
+ CloseHandle(file);
+ HeapFree(GetProcessHeap(), 0, data);
+}
+
+START_TEST(xfile)
+{
+ test_templates();
+ test_lock_unlock();
+ test_getname();
+ test_type_index_color();
+ test_dump();
+}