VertexShader::VertexShader(IDirect3DDevice9 *device, const D3DVERTEXELEMENT9* vertex_declaration, const char *shader_filename) : device(device), vertex_decl(NULL), shader(NULL) { try { if( FAILED( device->CreateVertexDeclaration(vertex_declaration, &vertex_decl) ) ) throw VertexDeclarationInitError(); ID3DXBuffer * shader_buffer = NULL; try { if( FAILED( D3DXAssembleShaderFromFileA( shader_filename, NULL, NULL, NULL, &shader_buffer, NULL ) ) ) throw VertexShaderAssemblyError(); if( FAILED( device->CreateVertexShader( (DWORD*) shader_buffer->GetBufferPointer(), &shader ) ) ) throw VertexShaderInitError(); } // using catch(...) because every caught exception is rethrown catch(...) { release_interface(shader_buffer); throw; } release_interface(shader_buffer); } // using catch(...) because every caught exception is rethrown catch(...) { release_interfaces(); throw; } }
HRESULT CD3D9ShaderMaterialRenderer::stubD3DXAssembleShaderFromFile(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs) { // wondering what I'm doing here? // see comment in CD3D9ShaderMaterialRenderer::stubD3DXAssembleShader() #if ( D3DX_SDK_VERSION < 24 ) // directly link functions, old d3d sdks didn't try to load external dlls // when linking to the d3dx9.lib #ifdef _MSC_VER #pragma comment (lib, "d3dx9.lib") #endif // invoke static linked function return D3DXAssembleShaderFromFileA(pSrcFile, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); #else { // try to load shader functions from the dll and print error if failed. // D3DXAssembleShaderFromFileA signature typedef HRESULT (WINAPI *AssembleShaderFromFileFunction)(LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs); static bool LoadFailed = false; static AssembleShaderFromFileFunction pFn = 0; if (!pFn && !LoadFailed) { // try to load dll io::path strDllName = "d3dx9_"; strDllName += (int)D3DX_SDK_VERSION; strDllName += ".dll"; HMODULE hMod = LoadLibrary(strDllName.c_str()); if (hMod) pFn = (AssembleShaderFromFileFunction)GetProcAddress(hMod, "D3DXAssembleShaderFromFileA"); if (!pFn) { LoadFailed = true; os::Printer::log("Could not load shader function D3DXAssembleShaderFromFileA from dll, shaders disabled", strDllName.c_str(), ELL_ERROR); } } if (pFn) { // call already loaded function return (*pFn)(pSrcFile, pDefines, pInclude, Flags, ppShader, ppErrorMsgs); } } #endif // D3DX_SDK_VERSION < 24 return 0; }
bool InitVertexShader() { #if DIRECTX_VERSION == 8 // shader decl DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(0, D3DVSDT_FLOAT3 ), // D3DVSDE_POSITION D3DVSD_REG(1, D3DVSDT_FLOAT3 ), // D3DVSDE_NORMAL D3DVSD_REG(2, D3DVSDT_D3DCOLOR ), // D3DVSDE_DIFFUSE D3DVSD_REG(3, D3DVSDT_FLOAT2 ), // D3DVSDE_TEXCOORD0 D3DVSD_END() }; #else D3DVERTEXELEMENT9 decl[] = { { 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 }, { 0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; #endif LPD3DXBUFFER pCode; LPD3DXBUFFER ppCompilationErrors; HRESULT res; #ifdef _DEBUG #if DIRECTX_VERSION == 8 LPD3DXBUFFER ppConstants; res = D3DXAssembleShaderFromFile("shader.vsh", D3DXASM_DEBUG, &ppConstants, &pCode, &ppCompilationErrors); #else res = D3DXAssembleShaderFromFileA("D:\\n64developing\\RiceVideo\\shaderdx9.vsh", NULL, NULL, D3DXSHADER_DEBUG, &pCode, &ppCompilationErrors); //res = D3DXAssembleShaderFromFileA("D:\\n64developing\\RiceVideo\\shaderdx9-2.vsh", NULL, NULL, D3DXSHADER_DEBUG, &pCode, &ppCompilationErrors); #endif #else #if DIRECTX_VERSION == 8 LPD3DXBUFFER ppConstants; res = D3DXAssembleShader(shaderstr, strlen(shaderstr), 0, &ppConstants, &pCode, &ppCompilationErrors); #else res = D3DXAssembleShader(shaderstr2, strlen(shaderstr2), NULL, NULL, D3DXSHADER_DEBUG, &pCode, &ppCompilationErrors); #endif #endif if( CDXGraphicsContext::IsResultGood(res,true) ) { #if DIRECTX_VERSION == 8 res = g_pD3DDev->CreateVertexShader( decl, (DWORD*)pCode->GetBufferPointer(), &gVertexShader, 0 ); #else res = g_pD3DDev->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(), &gVertexShader ); //FILE *fp = fopen("D:\\n64developing\\RiceVideo\\shaderdx9.vso","rb"); //BYTE buf[4000]; //int num = fread(buf, 1, 4000, fp); //res = g_pD3DDev->CreateVertexShader( (DWORD*)buf, &gVertexShader ); //fclose(fp); #endif pCode->Release(); if( !CDXGraphicsContext::IsResultGood(res,true) ) return false; res = g_pD3DDev->SetVertexShader( gVertexShader ); InitVertexShaderConstants(); return true; } else { if( ppCompilationErrors ) { char* str = (char*)(ppCompilationErrors->GetBufferPointer()); TRACE0(str); } return false; } }
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"); } }