HRESULT write_buffer_to_file(const WCHAR *dst_filename, ID3DXBuffer *buffer) { HRESULT hr = S_OK; void *buffer_pointer; DWORD buffer_size; HANDLE file = CreateFileW(dst_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError()); buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer); buffer_size = ID3DXBuffer_GetBufferSize(buffer); if (!WriteFile(file, buffer_pointer, buffer_size, NULL, NULL)) hr = HRESULT_FROM_WIN32(GetLastError()); CloseHandle(file); return hr; }
static void assembleshader_test(void) { const char test1[] = { "vs.1.1\n" "mov DEF2, v0\n" }; const char testincl[] = { "#define REGISTER r0\n" "vs.1.1\n" }; const char testshader[] = { "#include \"incl.vsh\"\n" "mov REGISTER, v0\n" }; const char testshader2[] = { "#include \"incl2.vsh\"\n" "mov REGISTER, v0\n" }; const char testshader3[] = { "#include \"include/incl3.vsh\"\n" "mov REGISTER, v0\n" }; const char testincl3[] = { "#include \"incl4.vsh\"\n" }; const char testincl4_ok[] = { "#define REGISTER r0\n" "vs.1.1\n" }; const char testincl4_wrong[] = { "#error \"wrong include\"\n" }; HRESULT hr; ID3DXBuffer *shader, *messages; D3DXMACRO defines[] = { { "DEF1", "10 + 15" }, { "DEF2", "r0" }, { NULL, NULL } }; struct D3DXIncludeImpl include; HRESULT shader_vsh_res; /* 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); shader_vsh_res = create_file("shader.vsh", testshader, sizeof(testshader) - 1); if(SUCCEEDED(shader_vsh_res)) { create_file("incl.vsh", testincl, sizeof(testincl) - 1); /* D3DXAssembleShaderFromFile + #include test */ shader = NULL; messages = NULL; hr = D3DXAssembleShaderFromFileA("shader.vsh", 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); create_file("incl4.vsh", testincl4_wrong, sizeof(testincl4_wrong) - 1); if(CreateDirectoryA("include", NULL)) { create_file("include/incl3.vsh", testincl3, sizeof(testincl3) - 1); create_file("include/incl4.vsh", testincl4_ok, sizeof(testincl4_ok) - 1); /* path search #include test */ shader = NULL; messages = NULL; hr = D3DXAssembleShaderFromFileA("shader3.vsh", 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"); } 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); /* cleanup */ if(SUCCEEDED(shader_vsh_res)) { DeleteFileA("shader.vsh"); DeleteFileA("incl.vsh"); DeleteFileA("shader3.vsh"); DeleteFileA("incl4.vsh"); DeleteFileA("include/incl3.vsh"); DeleteFileA("include/incl4.vsh"); RemoveDirectoryA("include"); } }
static void d3dxpreprocess_test(void) { const char testincl[] = { "#define REGISTER r0\n" "vs.1.1\n" }; const char testshader[] = { "#include \"incl.vsh\"\n" "mov REGISTER, v0\n" }; const char testshader3[] = { "#include \"include/incl3.vsh\"\n" "mov REGISTER, v0\n" }; const char testincl3[] = { "#include \"incl4.vsh\"\n" }; const char testincl4_ok[] = { "#define REGISTER r0\n" "vs.1.1\n" }; const char testincl4_wrong[] = { "#error \"wrong include\"\n" }; HRESULT hr; ID3DXBuffer *shader, *messages; HRESULT shader_vsh_res; struct D3DXIncludeImpl include = {{&D3DXInclude_Vtbl}}; shader_vsh_res = create_file("shader.vsh", testshader, sizeof(testshader) - 1); if(SUCCEEDED(shader_vsh_res)) { create_file("incl.vsh", testincl, sizeof(testincl) - 1); create_file("shader3.vsh", testshader3, sizeof(testshader3) - 1); create_file("incl4.vsh", testincl4_wrong, sizeof(testincl4_wrong) - 1); if(CreateDirectoryA("include", NULL)) { create_file("include/incl3.vsh", testincl3, sizeof(testincl3) - 1); create_file("include/incl4.vsh", testincl4_ok, sizeof(testincl4_ok) - 1); /* path search #include test */ shader = NULL; messages = NULL; hr = D3DXPreprocessShaderFromFileA("shader3.vsh", 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", 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); } 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); /* cleanup */ if(SUCCEEDED(shader_vsh_res)) { DeleteFileA("shader.vsh"); DeleteFileA("incl.vsh"); DeleteFileA("shader3.vsh"); DeleteFileA("incl4.vsh"); DeleteFileA("include/incl3.vsh"); DeleteFileA("include/incl4.vsh"); RemoveDirectoryA("include"); } }
static void createShadersD3D9() { static HMODULE d3dx9_handle = 0; LPD3DXBUFFER vShaderBuffer = NULL; LPD3DXBUFFER pShaderBuffer = NULL; LPD3DXBUFFER errBuf = NULL; HRESULT hr; HRESULT (__stdcall * d3dx_assemble_shader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); d3dx9_handle = LoadLibraryA("d3dx9_30.dll"); if (!d3dx9_handle) { fprintf(stderr, "Could not load d3dx9_30.dll\n"); return; } d3dx_assemble_shader = (void *)GetProcAddress(d3dx9_handle, "D3DXAssembleShader"); if (!d3dx_assemble_shader) { fprintf(stderr, "Could not get address of D3DXAssembleShader\n"); goto cleanup; } /* Assemble the vertex shader into bytecode and create it */ hr = d3dx_assemble_shader(basicVertexShaderSourceD3D9, strlen(basicVertexShaderSourceD3D9), NULL, NULL, 0, &vShaderBuffer, &errBuf); if (FAILED(hr)) { fprintf(stderr, "Vertex shader assembly failed\n"); if (errBuf) { fprintf(stderr, "error: %s\n", (const char*)ID3DXBuffer_GetBufferPointer(errBuf)); ID3DXBuffer_Release(errBuf); errBuf = NULL; } goto cleanup; } hr = IDirect3DDevice9_CreateVertexShader(gDevicePtr, ID3DXBuffer_GetBufferPointer(vShaderBuffer), &gVShaderPtr); if (FAILED(hr)) { fprintf(stderr, "Vertex shader creation failed\n"); goto cleanup; } /* Assemble the pixel shader into bytecode and create it */ hr = d3dx_assemble_shader(basicPixelShaderSourceD3D9, strlen(basicPixelShaderSourceD3D9), NULL, NULL, 0, &pShaderBuffer, &errBuf); if (FAILED(hr)) { fprintf(stderr, "Pixel shader assembly failed\n"); if (errBuf) { fprintf(stderr, "error: %s\n", (const char*)ID3DXBuffer_GetBufferPointer(errBuf)); ID3DXBuffer_Release(errBuf); errBuf = NULL; } goto cleanup; } hr = IDirect3DDevice9_CreatePixelShader(gDevicePtr, ID3DXBuffer_GetBufferPointer(pShaderBuffer), &gPShaderPtr); if (FAILED(hr)) { fprintf(stderr, "Pixel shader creation failed\n"); goto cleanup; } return; cleanup: if (vShaderBuffer) ID3DXBuffer_Release(vShaderBuffer); if (pShaderBuffer) ID3DXBuffer_Release(pShaderBuffer); FreeLibrary(d3dx9_handle); }