int uPixelShader::LoadPS(char *filename, char *pixelprog) { int er=0; // Create the pixel shader. LPD3DXBUFFER pCode; // assembled shader code LPD3DXBUFFER pError; if(hPixelShader!=NULL) pd->DeletePixelShader( hPixelShader); if(filename==NULL) D3DXAssembleShader( pixelprog, strlen(pixelprog), 0, NULL, &pCode, &pError ); // assemble shader code else { if( D3DXAssembleShaderFromFile( filename, 0, NULL, &pCode, &pError) != D3D_OK)er=1; // assemble shader code } if(pError!=NULL) { char text[150]; char* error_text = new char[pError->GetBufferSize()+1]; memcpy(error_text,pError->GetBufferPointer(),pError->GetBufferSize()); error_text[pError->GetBufferSize()]=NULL; pError->Release(); if(filename!=NULL) sprintf( text, "ERROR in pixel shader: %s", filename); else sprintf( text, "ERROR in pixel shader: %s"); MessageBox(hWnd, error_text, text, MB_OK); delete [] error_text; hPixelShader = NULL; return 0; } else if(er==1) { MessageBox(hWnd, filename, english ? "Couldn't find file for pixel shader":"Nenajdeny subor pre pixel shader", MB_OK); return 0; } if( pd->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(), &hPixelShader ) == D3D_OK ) { pCode->Release(); return 1; } pCode->Release(); MessageBox(hWnd, filename, english ? "ERROR in pixel shader":"Chyba pri nacitavani pixel shader", MB_OK); return 0; }
bool Shader::Compile(string &shaderCode) { LPD3DXBUFFER error = nullptr; SOC_dword flags = 0; LPDIRECT3DDEVICE9 device = dynamic_cast<Device::Graphics*>(graphics)->GetD3DDevice(); bool success = true; #if _DEBUG flags |= D3DXSHADER_DEBUG; #endif success = SUCCEEDED( D3DXCreateEffect(device, shaderCode.data(), shaderCode.length(), NULL, NULL, flags, NULL, &shader, &error) ); #if _DEBUG if(error) { int size = error->GetBufferSize(); void *ack = error->GetBufferPointer(); if(ack) { char *str = new char[size]; memcpy(str, (const char*)ack, size); // sprintf(str, (const char*)ack, size); OutputDebugString(str); delete[] str; } } #endif compiled = success; if(success) GetRequiredParameters(&requiredMatrixParam, &requiredLightParam); return success; }
void ICreateHeader(const char* const varName, const char* const fileName, FILE* fp, LPD3DXBUFFER shader) { fprintf(fp, "\n\n\n"); int byteLen = shader->GetBufferSize(); int quadLen = byteLen >> 2; unsigned char* codes = (unsigned char*)shader->GetBufferPointer(); fprintf(fp, "static const uint32_t %sbyteLen = %d;\n\n", varName, byteLen); fprintf(fp, "static const uint8_t %sCodes[] = {\n", varName); int i; for( i = 0; i < quadLen-1; i++ ) { fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x,\n", *codes++); } fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x,", *codes++); fprintf(fp, "\t0x%x\n", *codes++); fprintf(fp, "\t};"); fprintf(fp, "\n\n"); fprintf(fp, "static const plShaderDecl %sDecl(\"%s\", %s, %sbyteLen, %sCodes);\n\n", varName, fileName, varName, varName, varName); fprintf(fp, "static const plShaderRegister %sRegister(&%sDecl);\n\n", varName, varName); }
GXHRESULT GShaderImpl::CompileShader(clBuffer* pIntermediateCode, GXLPCSTR szSourceCode, size_t nSourceLen, LPD3DXINCLUDE pInclude, GXDEFINITION* pMacros, CompiledType eCompiled) { LPD3DXBUFFER pShader = NULL; LPD3DXBUFFER pErrorBuf = NULL; GXHRESULT hval = GX_OK; LPCSTR szFunctionName = NULL; LPCSTR szProfile = NULL; switch(eCompiled) { case CompiledComponentPixelShder: szFunctionName = "compose_ps_main"; szProfile = "ps_3_0"; break; case CompiledPixelShder: szFunctionName = "ps_main"; szProfile = "ps_3_0"; break; case CompiledComponentVertexShder: szFunctionName = "compose_vs_main"; szProfile = "vs_3_0"; break; case CompiledVertexShder: szFunctionName = "vs_main"; szProfile = "vs_3_0"; break; default: return GX_FAIL; } if(FAILED(D3DXCompileShader((LPCSTR)szSourceCode, (UINT)nSourceLen, (D3DXMACRO*)pMacros, pInclude, szFunctionName, szProfile, NULL, &pShader, &pErrorBuf, NULL))) { LPCSTR szErrorString = (LPCSTR)pErrorBuf->GetBufferPointer(); CLOG_ERROR("Shader compiled error:\n>%s\n", szErrorString); hval = GX_FAIL; } #if 0 // Test D3DXDisassembleShader LPD3DXBUFFER pAsmBuffer = NULL; GXHRESULT hval2 = D3DXDisassembleShader((DWORD*)pShader->GetBufferPointer(), FALSE, NULL, &pAsmBuffer); if(GXSUCCEEDED(hval2) && pAsmBuffer) { LPCSTR szAsmString = (LPCSTR)pAsmBuffer->GetBufferPointer(); TRACE(szAsmString); } SAFE_RELEASE(pAsmBuffer); #endif // #if pIntermediateCode->Resize(0, FALSE); if(pShader) { pIntermediateCode->Append(pShader->GetBufferPointer(), pShader->GetBufferSize()); } SAFE_RELEASE(pErrorBuf); SAFE_RELEASE(pShader); return hval; }
bool CD3DEffect::CreateEffect() { HRESULT hr; LPD3DXBUFFER pError = NULL; std::vector<D3DXMACRO> definemacros; for( DefinesMap::const_iterator it = m_defines.begin(); it != m_defines.end(); ++it ) { D3DXMACRO m; m.Name = it->first.c_str(); if (it->second.IsEmpty()) m.Definition = NULL; else m.Definition = it->second.c_str(); definemacros.push_back( m ); } definemacros.push_back(D3DXMACRO()); definemacros.back().Name = 0; definemacros.back().Definition = 0; hr = D3DXCreateEffect(g_Windowing.Get3DDevice(), m_effectString, m_effectString.length(), &definemacros[0], NULL, 0, NULL, &m_effect, &pError ); if(hr == S_OK) return true; else if(pError) { CStdString error; error.assign((const char*)pError->GetBufferPointer(), pError->GetBufferSize()); CLog::Log(LOGERROR, "CD3DEffect::CreateEffect(): %s", error.c_str()); } else CLog::Log(LOGERROR, "CD3DEffect::CreateEffect(): call to D3DXCreateEffect() failed with %" PRId32, hr); return false; }
bool DDModel::InitFX( std::wstring filename ) { LPD3DXBUFFER pError = nullptr; LPDIRECT3DDEVICE9 pD3DDevice = DDRenderer::GetInstance()->GetDevice(); D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE]; D3DXDeclaratorFromFVF( m_MeshInfo->m_pMesh->GetFVF(), decl ); pD3DDevice->CreateVertexDeclaration( decl, &m_pDecl ); // std::wstring fullpath = L".\\Shader\\"; // fullpath.append( filename ); // if ( D3DXCreateEffectFromFileW( pD3DDevice, fullpath.c_str(), NULL, NULL, 0, NULL, &m_pEffect, NULL ) ) D3DXCreateEffectFromFileW( pD3DDevice, filename.c_str(), NULL, NULL, 0, NULL, &m_pEffect, &pError ); if ( !m_pEffect && pError ) { int size = pError->GetBufferSize(); void *ack = pError->GetBufferPointer(); if ( ack ) { wchar_t* str = new wchar_t[size]; wsprintf( str, (const wchar_t*)ack, size ); OutputDebugString( str ); delete[] str; } } m_UseShader = true; return true; }
// loading shaders LPD3DXEFFECT LoadShader(const char * filename) { LPD3DXEFFECT ret = NULL; LPD3DXBUFFER pError = NULL; DWORD dwShaderFlags = 0; #if _DEBUG dwShaderFlags |= D3DXSHADER_DEBUG; #endif D3DXCreateEffectFromFile(gpD3DDevice, filename, NULL, NULL, dwShaderFlags, NULL, &ret, &pError); // if failed at loading shaders, display compile error // to output window if (!ret && pError) { int size = pError->GetBufferSize(); void *ack = pError->GetBufferPointer(); if (ack) { char* str = new char[size]; sprintf(str, (const char*)ack, size); OutputDebugString(str); delete[] str; } } return ret; }
// 쉐이더 로딩 LPD3DXEFFECT LoadShader(const char * filename) { LPD3DXEFFECT ret = NULL; LPD3DXBUFFER pError = NULL; DWORD dwShaderFlags = 0; #if _DEBUG dwShaderFlags |= D3DXSHADER_DEBUG; #endif D3DXCreateEffectFromFile(gpD3DDevice, filename, NULL, NULL, dwShaderFlags, NULL, &ret, &pError); // 쉐이더 로딩에 실패한 경우 output창에 쉐이더 // 컴파일 에러를 출력한다. if (!ret && pError) { int size = pError->GetBufferSize(); void *ack = pError->GetBufferPointer(); if (ack) { char* str = new char[size]; sprintf(str, (const char*)ack, size); OutputDebugString(str); delete[] str; } } return ret; }
//---------------------------------------------------------------------------- PdrPixelShader::PdrPixelShader (Renderer* renderer, const PixelShader* pshader) { IDirect3DDevice9* device = renderer->mData->mDevice; // 编译汇编着色器代码 const char* programText = pshader->GetProgram(PixelShader::GetProfile())->c_str(); int shaderKey = pshader->GetShaderKey(); assertion(0!=shaderKey, "shaderKey must not be 0.\n"); std::map<int, Renderer::SharePdrData>::iterator it = renderer->mSharePdrPixelShaders.find(shaderKey); if (it != renderer->mSharePdrPixelShaders.end()) { mShader = (IDirect3DPixelShader9*)(it->second.DataPtr); mShader->AddRef(); } else { int programLength = (int)strlen(programText); LPD3DXBUFFER compiledShader = 0; LPD3DXBUFFER errors = 0; HRESULT hr = D3DXAssembleShader(programText, programLength, 0, 0, 0, &compiledShader, &errors); #ifdef _DEBUG if (errors) { DWORD size = errors->GetBufferSize(); PX2_UNUSED(size); char* data = (char*)errors->GetBufferPointer(); PX2_UNUSED(data); assertion(false, "Failed to assemble pixel shader.\n"); } #endif PX2_UNUSED(hr); assertion(hr == D3D_OK && compiledShader, "Failed to assemble pixel shader: %s\n", DXGetErrorString(hr)); // 创建像素着色器 hr = device->CreatePixelShader( (DWORD*)(compiledShader->GetBufferPointer()), &mShader); assertion(hr == D3D_OK, "Failed to create pixel shader\n"); // 释放需要释放的数据 if (compiledShader) { compiledShader->Release(); } if (errors) { errors->Release(); } renderer->mSharePdrPixelShaders[shaderKey].DataPtr = mShader; ((IDirect3DPixelShader9*)renderer->mSharePdrPixelShaders[shaderKey].DataPtr) ->AddRef(); } }
int compileHLSLToD3D9(const char* from, const char* to, const std::map<std::string, int>& attributes) { LPD3DXBUFFER errors; LPD3DXBUFFER shader; LPD3DXCONSTANTTABLE table; HRESULT hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_2_0" : "ps_2_0", 0, &shader, &errors, &table); if (FAILED(hr)) hr = D3DXCompileShaderFromFileA(from, nullptr, nullptr, "main", isVertexShader(from) ? "vs_3_0" : "ps_3_0", 0, &shader, &errors, &table); if (errors != nullptr) std::cerr << (char*)errors->GetBufferPointer(); if (!FAILED(hr)) { std::ofstream file(to, std::ios_base::binary); file.put(attributes.size()); for (std::map<std::string, int>::const_iterator attribute = attributes.begin(); attribute != attributes.end(); ++attribute) { file << attribute->first.c_str(); file.put(0); file.put(attribute->second); } D3DXCONSTANTTABLE_DESC desc; table->GetDesc(&desc); file.put(desc.Constants); for (UINT i = 0; i < desc.Constants; ++i) { D3DXHANDLE handle = table->GetConstant(nullptr, i); D3DXCONSTANT_DESC descriptions[10]; UINT count = 10; table->GetConstantDesc(handle, descriptions, &count); if (count > 1) std::cerr << "Error: Number of descriptors for one constant is greater than one." << std::endl; for (UINT i2 = 0; i2 < count; ++i2) { char regtype; switch (descriptions[i2].RegisterSet) { case D3DXRS_BOOL: regtype = 'b'; break; case D3DXRS_INT4: regtype = 'i'; break; case D3DXRS_FLOAT4: regtype = 'f'; break; case D3DXRS_SAMPLER: regtype = 's'; break; } //std::cout << descriptions[i2].Name << " " << regtype << descriptions[i2].RegisterIndex << " " << descriptions[i2].RegisterCount << std::endl; file << descriptions[i2].Name; file.put(0); file.put(regtype); file.put(descriptions[i2].RegisterIndex); file.put(descriptions[i2].RegisterCount); } } DWORD* data = (DWORD*)shader->GetBufferPointer(); for (unsigned i = 0; i < shader->GetBufferSize() / 4; ++i) { if ((data[i] & 0xffff) == 0xfffe) { //comment token unsigned size = (data[i] >> 16) & 0xffff; i += size; } else file.write((char*)&data[i], 4);
void RSManager::dumpShader(UINT32 hash, const char *directory, LPD3DXBUFFER pBuffer) { char fileNameBuffer[64]; sprintf_s(fileNameBuffer, "%s/%08x.asm", directory, hash); const char *fileName = GetDirectoryFile(fileNameBuffer); if (writeFile(fileName, static_cast<char *>(pBuffer->GetBufferPointer()), pBuffer->GetBufferSize() - 1)) { SDLOG(0, "Wrote disassembled shader to %s\n", fileNameBuffer); } else { SDLOG(0, "Failed to write disassembled shader to %s\n", fileNameBuffer); } }
void D3D9PixelShader::Reset(GraphicsDevice &graphics) { FreeMemory(); HRESULT hr; _device = graphics.CastD3D9().GetDevice(); Assert(_device != NULL, "_device == NULL"); DWORD dwShaderFlags = 0; #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_SKIPOPTIMIZATION | D3DXSHADER_DEBUG; #endif LPD3DXBUFFER pCode = NULL; LPD3DXBUFFER pErrors = NULL; PersistentAssert(Utility::FileExists(_shaderFile), String("Shader file not found: ") + _shaderFile); // Assemble the vertex shader from the file hr = D3DXCompileShaderFromFile( _shaderFile.CString(), NULL, NULL, "PShaderEntry", "ps_3_0", dwShaderFlags, &pCode, &pErrors, &_constantTable ); String ErrorString; if(pErrors) { char *ErrorMessage = (char *)pErrors->GetBufferPointer(); DWORD ErrorLength = pErrors->GetBufferSize(); ofstream file("ShaderDebug.txt"); for(UINT i = 0; i < ErrorLength; i++) { file << ErrorMessage[i]; ErrorString += String(ErrorMessage[i]); } file.close(); } PersistentAssert(!FAILED(hr), String("D3DXCompileShaderFromFile failed: ") + ErrorString); hr = _device->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(), &_shader ); if(pErrors) { pErrors->Release(); } if(pCode) { pCode->Release(); } PersistentAssert(!FAILED(hr), "CreatePixelShader failed"); }
void D3D9PixelShader::Reset(LPDIRECT3DDEVICE9 _Device) { FreeMemory(); HRESULT hr; Device = _Device; Assert(Device != NULL, "Device == NULL"); DWORD dwShaderFlags = 0; #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_SKIPOPTIMIZATION | D3DXSHADER_DEBUG; #endif LPD3DXBUFFER pCode = NULL; LPD3DXBUFFER pErrors = NULL; // Assemble the vertex shader from the file hr = D3DXCompileShaderFromFile( ShaderFile.CString(), NULL, NULL, "PShaderEntry", "ps_3_0", dwShaderFlags, &pCode, &pErrors, &ConstantTable ); String ErrorString; if(pErrors) { char *ErrorMessage = (char *)pErrors->GetBufferPointer(); DWORD ErrorLength = pErrors->GetBufferSize(); ofstream file("ShaderDebug.txt"); for(UINT i = 0; i < ErrorLength; i++) { file << ErrorMessage[i]; ErrorString += String(ErrorMessage[i]); } file.close(); } PersistentAssert(!FAILED(hr), String("D3DXCompileShaderFromFile failed: ") + ErrorString); // Create the vertex shader hr = Device->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(), &Shader ); if(pErrors) { pErrors->Release(); } if(pCode) { pCode->Release(); } PersistentAssert(!FAILED(hr), "CreatePixelShader failed"); }
LPD3DXEFFECT cCube::LoadEffect( const char* szFileName ) { LPD3DXEFFECT pEffect = NULL; // 셰이더 로딩 LPD3DXBUFFER pError = NULL; //에러 버퍼 ( 셰이더를 컴파일할때 잘못 된 문법이나 오류정보를 리턴해주는 버퍼 ) DWORD dwShaderFlag = 0; //셰이더 플레그 0 #ifdef _DEBUG dwShaderFlag = dwShaderFlag | D3DXSHADER_DEBUG; //셰이더를 디버그모드로 컴파일하겠다 ( 디버그모드로 해야 잘못된 컴파일 오류가 날때 Error 버퍼에 오류정보가 들어간다 ) #endif //fx 파일로 부터 셰이더 객체 생성 D3DXCreateEffectFromFile( g_pD3DDevice, // 디바이스 szFileName, // 불러올 셰이더 코드 파일이름 NULL, // 셰이더를 컴파일할때 추가로 사용할 #define 정의 ( 일단 NULL ) NULL, // 셰이더를 컴파일할때 #include 지시문을 처리할때 사용할 인터페이스 플레그 ( 일단 NULL ) dwShaderFlag, // 셰이더 컴파일 플레그 NULL, // 셰이더 매개변수를 공유할 메모리풀 ( 일단 NULL ) &pEffect, // 로딩될 셰이더 Effect 포인터 &pError // 셰이더를 로딩하고 컴파일할때 문제가 생기면 해당 버퍼에 에러메시지가 들어간다 ( 성공적으로 로딩되면 NULL 이 참조된다 ) ); //셰이더 파일로딩에문재가 있다면.. if( pError != NULL || pEffect == NULL ){ //문제의 내용이 뭔지 문자열로 확인 int size = pError->GetBufferSize(); char* str = new char[ size ]; //str에 버퍼에있는 내용을 저장한다. sprintf_s( str, size,(const char*)pError->GetBufferPointer() ); OutputDebugString(str); //오류내용을 출력했으니 오류버퍼 해제 SAFE_RELEASE( pError ); SAFE_DELETE_ARRAY(str); return NULL; } m_pEffect = pEffect; return pEffect; }
//---------------------------------------------------------------------------- PdrVertexShader::PdrVertexShader (Renderer* renderer, const VertexShader* vshader) { IDirect3DDevice9* device = renderer->mData->mDevice; // Compile the shader to assembly code. const char* programText = vshader->GetProgram(VertexShader::GetProfile())->c_str(); int programLength = (int)strlen(programText); LPD3DXBUFFER compiledShader = 0; LPD3DXBUFFER errors = 0; HRESULT hr = D3DXAssembleShader(programText, programLength, 0, 0, 0, &compiledShader, &errors); #ifdef _DEBUG if (errors) { DWORD size = errors->GetBufferSize(); WM5_UNUSED(size); char* data = (char*)errors->GetBufferPointer(); WM5_UNUSED(data); assertion(false, "Failed to assemble vertex shader.\n"); } #endif WM5_UNUSED(hr); assertion(hr == D3D_OK && compiledShader, "Failed to assemble vertex shader: %s\n", DXGetErrorString(hr)); // Create the vertex shader. hr = device->CreateVertexShader( (DWORD*)(compiledShader->GetBufferPointer()), &mShader); assertion(hr == D3D_OK, "Failed to create vertex shader\n"); // Release buffers, if necessary. if (compiledShader) { compiledShader->Release(); } if (errors) { errors->Release(); } }
void CRenderLayer::SaveTextureToFileInMemory(void** lpBuffer, int* pBufferSize, TextureHandle th, int iImageFormat) { if (th->is_multisampled) throw runtime_error("Cannot save multisampled textures"); // Talk about a hack... LPD3DXBUFFER buff = (LPD3DXBUFFER)(*lpBuffer); D3DXSaveTextureToFileInMemory( &buff, (D3DXIMAGE_FILEFORMAT)iImageFormat, th->texture_ptr, NULL ); if(pBufferSize) *pBufferSize = buff->GetBufferSize(); *lpBuffer = buff; }
bool GFXD3D9Shader::_saveCompiledOutput( const Torque::Path &filePath, LPD3DXBUFFER buffer, GenericConstBufferLayout *bufferLayoutF, GenericConstBufferLayout *bufferLayoutI, Vector<GFXShaderConstDesc> &samplerDescriptions ) { Torque::Path outputPath(filePath); outputPath.setExtension("csf"); // "C"ompiled "S"hader "F"ile (fancy!) FileStream f; if (!f.open(outputPath, Torque::FS::File::Write)) return false; if (!f.write(smCompiledShaderTag)) return false; // We could reverse engineer the structure in the compiled output, but this // is a bit easier because we can just read it into the struct that we want. if (!bufferLayoutF->write(&f)) return false; if (!bufferLayoutI->write(&f)) return false; U32 bufferSize = buffer->GetBufferSize(); if (!f.write(bufferSize)) return false; if (!f.write(bufferSize, buffer->GetBufferPointer())) return false; // Write out sampler descriptions. f.write( samplerDescriptions.size() ); for ( U32 i = 0; i < samplerDescriptions.size(); i++ ) { f.write( samplerDescriptions[i].name ); f.write( (U32)(samplerDescriptions[i].constType) ); f.write( samplerDescriptions[i].arraySize ); } f.close(); return true; }
void GUIBasicEffect::Initialize() { LPD3DXBUFFER pErrors = NULL; HRESULT hr = D3DXCreateEffectFromFile(MyApp::GetSingleton()->GetD3DDevice(), L"D3D9_Application_Framework\\Content\\Effects\\GUI\\BasicEffect.fx", NULL, NULL, NULL, NULL, &pEffect, &pErrors); #if defined( _DEBUG ) if ( FAILED( hr ) && pErrors != NULL && pErrors->GetBufferPointer() != NULL ) { char* aux = new char[pErrors->GetBufferSize()+sizeof("Effect Compilation Error: ")+1]; aux[0] = '\0'; aux = strcat(aux, "Effect Compilation Error: "); MyApp::GetSingleton()->Error(strcat(aux, (char *)pErrors->GetBufferPointer())); delete[] aux; } #endif if( pErrors != NULL ) pErrors->Release(); return; }
static int assemble_shader(wchar_t *filename) { LPD3DXBUFFER shader; wchar_t fname[MAX_PATH]; int rc; FILE *outfp; rc = D3DXAssembleShaderFromFile(filename, NULL, NULL, 0, &shader, NULL); if (rc != D3D_OK) return 1; _wsplitpath_s(filename, NULL, 0, NULL, 0, fname, 250, NULL, 0); lstrcatW(fname, L".out"); if ((rc = _wfopen_s(&outfp, fname, L"wb"))) return rc; fwrite(shader->GetBufferPointer(), 1, shader->GetBufferSize(), outfp); fclose(outfp); return 0; }
HRESULT RSManager::redirectCreateVertexShader(CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader) { bool shouldDump = Settings::get().getEnableShaderDumping(); bool shouldOverride = Settings::get().getEnableShaderOverride(); LPD3DXBUFFER pAssemblerBuffer = nullptr; LPD3DXBUFFER pFunctionBuffer = nullptr; UINT32 hash; if (shouldDump || shouldOverride) { if (disassembleShader(pFunction, &pAssemblerBuffer)) { hash = SuperFastHash(static_cast<char *>(pAssemblerBuffer->GetBufferPointer()), pAssemblerBuffer->GetBufferSize()); } else { shouldDump = false; shouldOverride = false; } } if (shouldDump) { dumpShader(hash, VERTEX_SHADER_DUMP_DIR, pAssemblerBuffer); } if (shouldOverride) { if (getOverrideShader(hash, VERTEX_SHADER_OVERRIDE_DIR, &pFunctionBuffer)) { pFunction = static_cast<DWORD *>(pFunctionBuffer->GetBufferPointer()); } } HRESULT result = d3ddev->CreateVertexShader(pFunction, ppShader); if (shouldDump || shouldOverride) { SDLOG(1, "Created vertex shader for hash %08x: 0x%p\n", hash, *ppShader); } SAFERELEASE(pAssemblerBuffer); SAFERELEASE(pFunctionBuffer); return result; }
static int assemble_stdin() { LPD3DXBUFFER shader; char *buf = NULL; const int block = 4096; size_t size = 0; _setmode(_fileno(stdin), O_BINARY); while (!feof(stdin)) { buf = (char*)realloc(buf, size + block); if (!buf) return 1; size += fread(buf + size, 1, block, stdin); if (ferror(stdin)) return 1; } D3DXAssembleShader(buf, size, NULL, NULL, 0, &shader, NULL); _setmode(_fileno(stdout), O_BINARY); fwrite(shader->GetBufferPointer(), 1, shader->GetBufferSize(), stdout); return 0; }
//////////////////////////////////////////////////////////////// // // CEffectTemplateImpl::CreateUnderlyingData // // // //////////////////////////////////////////////////////////////// void CEffectTemplateImpl::CreateUnderlyingData ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool bDebug ) { assert ( !m_pD3DEffect ); // Make defines bool bUsesRAWZ = CGraphics::GetSingleton ().GetRenderItemManager ()->GetDepthBufferFormat () == RFORMAT_RAWZ; std::vector < D3DXMACRO > macroList; macroList.push_back ( D3DXMACRO () ); macroList.back ().Name = "IS_DEPTHBUFFER_RAWZ"; macroList.back ().Definition = bUsesRAWZ ? "1" : "0"; macroList.push_back ( D3DXMACRO () ); macroList.back ().Name = NULL; macroList.back ().Definition = NULL; // Compile effect DWORD dwFlags = 0; // D3DXSHADER_PARTIALPRECISION, D3DXSHADER_DEBUG, D3DXFX_NOT_CLONEABLE; if ( bDebug ) dwFlags |= D3DXSHADER_DEBUG; SString strMetaPath = strFilename.Right ( strFilename.length () - strRootPath.length () ); CIncludeManager IncludeManager ( strRootPath, ExtractPath ( strMetaPath ) ); LPD3DXBUFFER pBufferErrors = NULL; HRESULT hr = D3DXCreateEffectFromFile( m_pDevice, ExtractFilename ( strMetaPath ), ¯oList[0], &IncludeManager, dwFlags, NULL, &m_pD3DEffect, &pBufferErrors ); // Handle compile errors strOutStatus = ""; if( pBufferErrors != NULL ) { strOutStatus = SStringX ( (CHAR*)pBufferErrors->GetBufferPointer() ).TrimEnd ( "\n" ); // Error messages sometimes contain the current directory. Remove that here. SString strCurrentDirectory = GetSystemCurrentDirectory(); strOutStatus = strOutStatus.ReplaceI ( strCurrentDirectory + "\\", "" ); strOutStatus = strOutStatus.ReplaceI ( strCurrentDirectory, "" ); } SAFE_RELEASE( pBufferErrors ); if( !m_pD3DEffect ) { if ( strOutStatus.empty () ) strOutStatus = SString ( "[D3DXCreateEffectFromFile failed (%08x)%s]", hr, *IncludeManager.m_strReport ); return; } // Find first valid technique D3DXHANDLE hTechnique = NULL; D3DXEFFECT_DESC EffectDesc; m_pD3DEffect->GetDesc ( &EffectDesc ); for ( uint uiAttempt = 0 ; true ; uiAttempt++ ) { SString strProblemInfo = ""; for ( uint i = 0 ; i < EffectDesc.Techniques ; i++ ) { SString strErrorExtra; D3DXHANDLE hTemp = m_pD3DEffect->GetTechnique ( i ); HRESULT hr = m_pD3DEffect->ValidateTechnique ( hTemp ); if ( SUCCEEDED( hr ) ) { // Check depth buffer rules if ( ValidateDepthBufferUsage ( hTemp, strErrorExtra ) ) { hTechnique = hTemp; break; } } // Update problem string D3DXTECHNIQUE_DESC TechniqueDesc; m_pD3DEffect->GetTechniqueDesc( hTemp, &TechniqueDesc ); strProblemInfo += SString ( "['%s' (%d/%d) failed (%08x)%s]", TechniqueDesc.Name, i, EffectDesc.Techniques, hr, *strErrorExtra ); } // Found valid technique if ( hTechnique ) break; // Error if can't find a valid technique after 2nd attempt if ( uiAttempt > 0 ) { strOutStatus = SString ( "No valid technique; [Techniques:%d %s]%s", EffectDesc.Techniques, *strProblemInfo, *IncludeManager.m_strReport ); SAFE_RELEASE ( m_pD3DEffect ); return; } // Try resetting samplers if 1st attempt failed LPDIRECT3DDEVICE9 pDevice; m_pD3DEffect->GetDevice ( &pDevice ); for ( uint i = 0 ; i < 16 ; i++ ) { pDevice->SetSamplerState ( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); pDevice->SetSamplerState ( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); pDevice->SetSamplerState ( i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); } } // Set technique m_pD3DEffect->SetTechnique( hTechnique ); // Inform user of technique name D3DXTECHNIQUE_DESC TechniqueDesc; m_pD3DEffect->GetTechniqueDesc( hTechnique, &TechniqueDesc ); strOutStatus = TechniqueDesc.Name; if ( bDebug ) { // Disassemble effect LPD3DXBUFFER pDisassembly = NULL; if ( SUCCEEDED( D3DXDisassembleEffect( m_pD3DEffect, false, &pDisassembly ) ) && pDisassembly ) { LPVOID pData = pDisassembly->GetBufferPointer(); DWORD Size = pDisassembly->GetBufferSize(); if( pData && Size ) { SString strDisassemblyContents; strDisassemblyContents.assign ( (const char*)pData, Size - 1 ); FileSave ( strFilename + ".dis", strDisassemblyContents ); } SAFE_RELEASE( pDisassembly ); } } // Copy MD5s of all loaded files m_FileMD5Map = IncludeManager.m_FileMD5Map; dassert ( !HaveFilesChanged() ); }
bool compileHLSLShaderDx9(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer) { BX_TRACE("DX9"); const char* profile = _cmdLine.findOption('p', "profile"); if (NULL == profile) { fprintf(stderr, "Shader profile must be specified.\n"); return false; } bool debug = _cmdLine.hasArg('\0', "debug"); uint32_t flags = 0; flags |= debug ? D3DXSHADER_DEBUG : 0; flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DXSHADER_AVOID_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DXSHADER_NO_PRESHADER : 0; flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DXSHADER_PARTIALPRECISION : 0; flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DXSHADER_PREFER_FLOW_CONTROL : 0; flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY : 0; bool werror = _cmdLine.hasArg('\0', "Werror"); uint32_t optimization = 3; if (_cmdLine.hasArg(optimization, 'O') ) { optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelDx9)-1); flags |= s_optimizationLevelDx9[optimization]; } else { flags |= D3DXSHADER_SKIPOPTIMIZATION; } BX_TRACE("Profile: %s", profile); BX_TRACE("Flags: 0x%08x", flags); LPD3DXBUFFER code; LPD3DXBUFFER errorMsg; LPD3DXCONSTANTTABLE constantTable; HRESULT hr; // Output preprocessed shader so that HLSL can be debugged via GPA // or PIX. Compiling through memory won't embed preprocessed shader // file path. if (debug) { std::string hlslfp = _cmdLine.findOption('o'); hlslfp += ".hlsl"; writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() ); hr = D3DXCompileShaderFromFileA(hlslfp.c_str() , NULL , NULL , "main" , profile , flags , &code , &errorMsg , &constantTable ); } else { hr = D3DXCompileShader(_code.c_str() , (uint32_t)_code.size() , NULL , NULL , "main" , profile , flags , &code , &errorMsg , &constantTable ); } if (FAILED(hr) || (werror && NULL != errorMsg) ) { const char* log = (const char*)errorMsg->GetBufferPointer(); char source[1024]; int32_t line = 0; int32_t column = 0; int32_t start = 0; int32_t end = INT32_MAX; if (3 == sscanf(log, "%[^(](%u,%u):", source, &line, &column) && 0 != line) { start = bx::uint32_imax(1, line-10); end = start + 20; } printCode(_code.c_str(), line, start, end); fprintf(stderr, "Error: 0x%08x %s\n", (uint32_t)hr, log); errorMsg->Release(); return false; } UniformArray uniforms; if (NULL != constantTable) { D3DXCONSTANTTABLE_DESC desc; hr = constantTable->GetDesc(&desc); if (FAILED(hr) ) { fprintf(stderr, "Error 0x%08x\n", (uint32_t)hr); return false; } BX_TRACE("Creator: %s 0x%08x", desc.Creator, (uint32_t /*mingw warning*/)desc.Version); BX_TRACE("Num constants: %d", desc.Constants); BX_TRACE("# cl ty RxC S By Name"); for (uint32_t ii = 0; ii < desc.Constants; ++ii) { D3DXHANDLE handle = constantTable->GetConstant(NULL, ii); D3DXCONSTANT_DESC constDesc; uint32_t count; constantTable->GetConstantDesc(handle, &constDesc, &count); BX_TRACE("%3d %2d %2d [%dx%d] %d %3d %s[%d] c%d (%d)" , ii , constDesc.Class , constDesc.Type , constDesc.Rows , constDesc.Columns , constDesc.StructMembers , constDesc.Bytes , constDesc.Name , constDesc.Elements , constDesc.RegisterIndex , constDesc.RegisterCount ); UniformType::Enum type = findUniformTypeDx9(constDesc); if (UniformType::Count != type) { Uniform un; un.name = '$' == constDesc.Name[0] ? constDesc.Name+1 : constDesc.Name; un.type = type; un.num = constDesc.Elements; un.regIndex = constDesc.RegisterIndex; un.regCount = constDesc.RegisterCount; uniforms.push_back(un); } } } uint16_t count = (uint16_t)uniforms.size(); bx::write(_writer, count); uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0; for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it) { const Uniform& un = *it; uint8_t nameSize = (uint8_t)un.name.size(); bx::write(_writer, nameSize); bx::write(_writer, un.name.c_str(), nameSize); uint8_t type = un.type|fragmentBit; bx::write(_writer, type); bx::write(_writer, un.num); bx::write(_writer, un.regIndex); bx::write(_writer, un.regCount); BX_TRACE("%s, %s, %d, %d, %d" , un.name.c_str() , getUniformTypeName(un.type) , un.num , un.regIndex , un.regCount ); } uint16_t shaderSize = (uint16_t)code->GetBufferSize(); bx::write(_writer, shaderSize); bx::write(_writer, code->GetBufferPointer(), shaderSize); uint8_t nul = 0; bx::write(_writer, nul); if (_cmdLine.hasArg('\0', "disasm") ) { LPD3DXBUFFER disasm; D3DXDisassembleShader( (const DWORD*)code->GetBufferPointer() , false , NULL , &disasm ); if (NULL != disasm) { std::string disasmfp = _cmdLine.findOption('o'); disasmfp += ".disasm"; writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), disasm->GetBufferSize() ); disasm->Release(); } } if (NULL != code) { code->Release(); } if (NULL != errorMsg) { errorMsg->Release(); } if (NULL != constantTable) { constantTable->Release(); } return true; }
HRESULT ScalingEffect::LoadEffect(const TCHAR *filename) { KillThis(); LPD3DXBUFFER lpBufferEffect = 0; LPD3DXBUFFER lpErrors = 0; LPD3DXEFFECTCOMPILER lpEffectCompiler = 0; m_strErrors += filename; m_strErrors += ":\n"; // First create an effect compiler HRESULT hr = D3DXCreateEffectCompilerFromFile(filename, NULL, NULL,NULL, &lpEffectCompiler, &lpErrors); // Errors... if(FAILED(hr)) { if(lpErrors) { m_strErrors += (char*) lpErrors->GetBufferPointer(); SAFE_RELEASE(lpErrors); } m_strErrors += "Unable to create effect compiler from "; m_strErrors += filename; } if(SUCCEEDED(hr)) { #ifdef C_D3DSHADERS_COMPILE_WITH_DEBUG hr = lpEffectCompiler->CompileEffect(D3DXSHADER_DEBUG, &lpBufferEffect, &lpErrors); #else hr = lpEffectCompiler->CompileEffect(0, &lpBufferEffect, &lpErrors); #endif // Errors... if(FAILED(hr)) { if(lpErrors) { m_strErrors += (char*) lpErrors->GetBufferPointer(); SAFE_RELEASE(lpErrors); } m_strErrors += "Unable to compile effect from "; m_strErrors += filename; } } if(SUCCEEDED(hr)) { hr = D3DXCreateEffect(m_pd3dDevice, lpBufferEffect->GetBufferPointer(), lpBufferEffect->GetBufferSize(), NULL, NULL, 0, NULL, &m_pEffect, &lpErrors); // Errors... if(FAILED(hr)) { if(lpErrors) { m_strErrors += (char*) lpErrors->GetBufferPointer(); SAFE_RELEASE(lpErrors); } m_strErrors += "Unable to create effect from compiled "; m_strErrors += filename; } } if(SUCCEEDED(hr)) { m_pEffect->GetDesc(&m_EffectDesc); hr = ParseParameters(lpEffectCompiler); } SAFE_RELEASE(lpErrors); SAFE_RELEASE(lpBufferEffect); SAFE_RELEASE(lpEffectCompiler); return hr; }
//----------------------------------------------------------------------------- // Name: InitD3D() // Desc: Initializes Direct3D //----------------------------------------------------------------------------- HRESULT InitD3D( HWND hWnd ) { // Create the D3D object. if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; // Set up the structure used to create the D3DDevice. Since we are now // using more complex geometry, we will create a device with a zbuffer. D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // Create the D3DDevice if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } // Turn on the zbuffer g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); //Turn off culling, so we see the front and back of the triangle g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ); g_pd3dDevice->LightEnable( 0, TRUE ); g_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); ////VS TUTORIAL STUFF LPD3DXBUFFER pCode; // Buffer with the assembled shader code ////VS TUTORIAL STUFF // This is our error buffer LPD3DXBUFFER pErrorMsgs = 0; // Buffer with error messages ////VS TUTORIAL STUFF for ( int i = 0; i < maxShaders; i++ ) // load all the shader files { if(FAILED(D3DXAssembleShaderFromFile( shaders[i].c_str(), NULL, NULL, 0, ////VS TUTORIAL STUFF &pCode, &pErrorMsgs ))) { // Error(s) have occured. // Allocate a character buffer the size of the ID3DXBuffer if(pErrorMsgs != 0) { char* data = new char[pErrorMsgs->GetBufferSize()]; // Copy the buffer data over memcpy( data, pErrorMsgs->GetBufferPointer(), pErrorMsgs->GetBufferSize() ); // Open a file and output the error string(s) FILE* file; fopen_s(&file,"errors.txt", "w" ); fprintf( file, "%s", data ); fclose( file ); // Release allocated objects delete[] data; pErrorMsgs->Release(); MessageBox(hWnd,L"see errors.txt",L"vertex assemble problem",NULL); } return E_FAIL; } switch ( i ) // create the vertex shader and assosiate it with the proper variable { case 0 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader); case 1 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader2); case 2 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader3); case 3 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader4); case 4 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader5); case 5 : g_pd3dDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), &g_pVertexShader6); } pCode->Release(); } cameraPos.x = 0.0f; cameraPos.y = 15.0f; cameraPos.z = 20.0f; lightPos.x = -10.0f; lightPos.y = 0.0f; lightPos.z = 3.0f; return S_OK; }
bool DepthManager::Initialize( IDirect3DDevice9* device, UINT width, UINT height ) { assert( !m_initialized ); assert( device != 0 ); m_device = device; HRESULT res; m_initialized = true; //Create texture for the depth buffer res = m_device->CreateTexture( width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &m_depthTexture, NULL ); if ( FAILED(res) ) { SETSTATUS("Failed to create depth buffer surface."); Shutdown(); return false; } // Create surface for the depth buffer res = m_depthTexture->GetSurfaceLevel( 0, &m_depthSurface ); if ( FAILED(res) ) { SETSTATUS( "Failed to get depth buffer texture from depth buffer surface."); Shutdown(); return false; } //Initialize the depth surface to all zeros. ZeroDepthBuffer(); // Create a Z-buffer for depth rendering res = m_device->CreateDepthStencilSurface( width, height, D3DFMT_D24X8, (D3DMULTISAMPLE_TYPE)0, 0, true, &m_depthZBuffer, 0 ); if ( FAILED(res) ) { SETSTATUS( "Failed to create depth z-buffer"); Shutdown(); return false; } // Load shader effect file LPD3DXBUFFER errors = 0; res = D3DXCreateEffectFromFile( m_device, "Data files\\shaders\\distantland\\Depth.fx", 0, 0, 0, 0, &m_depthEffect, &errors ); if ( FAILED(res) ) { if ( errors ) { std::ofstream err_file ("Shader Compiler Errors - Depth.fx.txt"); err_file.write ((const char*)errors->GetBufferPointer(), errors->GetBufferSize() ); err_file.close (); errors->Release(); errors = 0; } SETSTATUS ("Could not depth effect file."); Shutdown(); return false; } // Get Parameter Handles m_ehView = m_depthEffect->GetParameterByName( 0, "g_View" ); m_ehProj = m_depthEffect->GetParameterByName( 0, "g_Proj" ); m_ehWorld = m_depthEffect->GetParameterByName( 0, "g_World" ); m_ehMatrixPalette = m_depthEffect->GetParameterByName( 0, "g_MatrixPalette" ); m_ehBlendWeightCount = m_depthEffect->GetParameterByName( 0, "g_BlendWeightCount" ); m_ehAlphaTest = m_depthEffect->GetParameterByName( 0, "g_AlphaTest" ); m_ehAlphaTestTexture = m_depthEffect->GetParameterByName( 0, "AlphaTestTexture" ); // Get Technique Handles m_ehStaticDepth = m_depthEffect->GetTechniqueByName( "StaticDepth" ); m_ehNoAlphaDepth = m_depthEffect->GetTechniqueByName( "NoAlphaDepth" ); m_ehRenderGenericDepth = m_depthEffect->GetTechniqueByName( "RenderGenericDepth" ); m_ehClearDepth = m_depthEffect->GetTechniqueByName( "ClearDepth" ); if ( !m_ehView || !m_ehProj || !m_ehWorld || !m_ehMatrixPalette || !m_ehBlendWeightCount || !m_ehAlphaTest || !m_ehAlphaTestTexture || !m_ehStaticDepth || !m_ehNoAlphaDepth || !m_ehRenderGenericDepth || !m_ehClearDepth ) { SETSTATUS ( "Failed to find a necessary parameter or technique in depth shader" ); Shutdown(); return false; } return true; }
HRESULT CRender::shader_compile ( LPCSTR name, DWORD const* pSrcData, UINT SrcDataLen, LPCSTR pFunctionName, LPCSTR pTarget, DWORD Flags, void*& result ) { D3DXMACRO defines [128]; int def_it = 0; char sh_name[MAX_PATH] = ""; u32 len = 0; // options if (o.forceskinw) { defines[def_it].Name = "SKIN_COLOR"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(o.forceskinw); ++len; if (m_skinning<0) { defines[def_it].Name = "SKIN_NONE"; defines[def_it].Definition = "1"; def_it ++; sh_name[len]='1'; ++len; } else { sh_name[len]='0'; ++len; } if (0==m_skinning) { defines[def_it].Name = "SKIN_0"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(0==m_skinning); ++len; if (1==m_skinning) { defines[def_it].Name = "SKIN_1"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(1==m_skinning); ++len; if (2==m_skinning) { defines[def_it].Name = "SKIN_2"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(2==m_skinning); ++len; if (3==m_skinning) { defines[def_it].Name = "SKIN_3"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(3==m_skinning); ++len; if (4==m_skinning) { defines[def_it].Name = "SKIN_4"; defines[def_it].Definition = "1"; def_it ++; } sh_name[len]='0'+char(4==m_skinning); ++len; // finish defines[def_it].Name = 0; defines[def_it].Definition = 0; def_it ++; R_ASSERT (def_it<128); HRESULT _result = E_FAIL; string_path folder_name, folder; xr_strcpy ( folder, "r1\\objects\\r1\\" ); xr_strcat ( folder, name ); xr_strcat ( folder, "." ); char extension[3]; strncpy_s ( extension, pTarget, 2 ); xr_strcat ( folder, extension ); FS.update_path ( folder_name, "$game_shaders$", folder ); xr_strcat ( folder_name, "\\" ); m_file_set.clear( ); FS.file_list ( m_file_set, folder_name, FS_ListFiles | FS_RootOnly, "*"); string_path temp_file_name, file_name; if ( !match_shader_id(name, sh_name, m_file_set, temp_file_name) ) { string_path file; xr_strcpy ( file, "shaders_cache\\r1\\" ); xr_strcat ( file, name ); xr_strcat ( file, "." ); xr_strcat ( file, extension ); xr_strcat ( file, "\\" ); xr_strcat ( file, sh_name ); FS.update_path ( file_name, "$app_data_root$", file); } else { xr_strcpy ( file_name, folder_name ); xr_strcat ( file_name, temp_file_name ); } if (FS.exist(file_name)) { IReader* file = FS.r_open(file_name); if (file->length()>4) { u32 crc = 0; crc = file->r_u32(); boost::crc_32_type processor; processor.process_block ( file->pointer(), ((char*)file->pointer()) + file->elapsed() ); u32 const real_crc = processor.checksum( ); if ( real_crc == crc ) { _result = create_shader(pTarget, (DWORD*)file->pointer(), file->elapsed(), file_name, result, o.disasm); } } file->close(); } if (FAILED(_result)) { includer Includer; LPD3DXBUFFER pShaderBuf = NULL; LPD3DXBUFFER pErrorBuf = NULL; LPD3DXCONSTANTTABLE pConstants = NULL; LPD3DXINCLUDE pInclude = (LPD3DXINCLUDE)&Includer; _result = D3DXCompileShader((LPCSTR)pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags|D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,&pShaderBuf,&pErrorBuf,&pConstants); if (SUCCEEDED(_result)) { IWriter* file = FS.w_open(file_name); boost::crc_32_type processor; processor.process_block ( pShaderBuf->GetBufferPointer(), ((char*)pShaderBuf->GetBufferPointer()) + pShaderBuf->GetBufferSize() ); u32 const crc = processor.checksum( ); file->w_u32 (crc); file->w ( pShaderBuf->GetBufferPointer(), (u32)pShaderBuf->GetBufferSize()); FS.w_close (file); _result = create_shader(pTarget, (DWORD*)pShaderBuf->GetBufferPointer(), pShaderBuf->GetBufferSize(), file_name, result, o.disasm); } else { Log ("! ", file_name); if ( pErrorBuf ) Log ("! error: ",(LPCSTR)pErrorBuf->GetBufferPointer()); else Msg ("Can't compile shader hr=0x%08x", _result); } } return _result; }
void D3D9VertexShader::Reset(LPDIRECT3DDEVICE9 Device) { FreeMemory(); HRESULT hr; _Device = Device; Assert(Device != NULL, "Device == NULL"); _Decl.Init(Device); // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the // shader debugger. Debugging vertex shaders requires either REF or software vertex // processing, and debugging pixel shaders requires REF. The // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the // shader debugger. It enables source level debugging, prevents instruction // reordering, prevents dead code elimination, and forces the compiler to compile // against the next higher available software target, which ensures that the // unoptimized shaders do not exceed the shader model limitations. Setting these // flags will cause slower rendering since the shaders will be unoptimized and // forced into software. See the DirectX documentation for more information about // using the shader debugger. DWORD dwShaderFlags = 0; #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_SKIPOPTIMIZATION|D3DXSHADER_DEBUG; #endif LPD3DXBUFFER pCode = NULL; LPD3DXBUFFER pErrors = NULL; PersistentAssert(Utility::FileExists(_ShaderFile), String(_ShaderFile) + String(" not found.")); // Assemble the vertex shader from the file hr = D3DXCompileShaderFromFile( _ShaderFile.CString(), NULL, NULL, "VShaderEntry", "vs_3_0", dwShaderFlags, &pCode, &pErrors, &_ConstantTable ); if(pErrors) { char *ErrorMessage = (char *)pErrors->GetBufferPointer(); DWORD ErrorLength = pErrors->GetBufferSize(); ofstream file("ShaderDebug.txt"); for(UINT i = 0; i < ErrorLength; i++) { file << ErrorMessage[i]; } file.close(); } Assert(!FAILED(hr), "D3DXCompileShaderFromFile failed. See ShaderDebug.txt for details."); // Create the vertex shader hr = Device->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(), &_Shader ); if(pErrors) { pErrors->Release(); } if(pCode) { pCode->Release(); } Assert(!FAILED(hr), "CreateVertexShader failed"); }
bool CVertexShader::LoadVariant( IShaderDefines *pDefines, bool bCompile ) { // check for already compiled default version of the shader if (pDefines == NULL && m_VertexShader != NULL) return true; // check for already compiled variant of the shader if (pDefines != NULL) { unsigned long iEncoding = pDefines->GetValuesEncoding().iEncoding; SHADERVARIANTSMAP::iterator itr = m_ShaderVariants.find( iEncoding ); if (itr != m_ShaderVariants.end()) return true; } D3DXMACRO *pMacros = NULL; if (pDefines) { const int iMaxShaderDefineCount = 32; const int iValueCharSize = 64; static char szValues[iMaxShaderDefineCount][iValueCharSize]; static D3DXMACRO vMacros[iMaxShaderDefineCount + 1]; if (iMaxShaderDefineCount < pDefines->GetDefineCount()) { m_ToolBox->Log( LOGFATALERROR, _T("Shader Define Count exceeds the internal buffer!\n") ); return false; } DWORD i; for (i=0; i < pDefines->GetDefineCount(); i++) { vMacros[i].Name = pDefines->GetDefineName(i); vMacros[i].Definition = _itoa(pDefines->GetDefineValue(i), szValues[i], 10); } // null terminate macro list vMacros[i].Name = NULL; vMacros[i].Definition = NULL; pMacros = vMacros; } LPDIRECT3DVERTEXSHADER9 pShader = NULL; LPD3DXBUFFER shaderBuf = NULL; LPD3DXBUFFER pErrorMsgs = NULL; CDX9IncludeManager includeInterface; LPDIRECT3DDEVICE9 pDevice = (LPDIRECT3DDEVICE9)m_Renderer->GetAPIDevice(); if( pDevice ) { int len = _tcslen( (const TCHAR*)m_Code ); LPCSTR profile = D3DXGetVertexShaderProfile( pDevice ); bool bLoadedCompiled = false; HRESULT hr = E_FAIL; const TCHAR *szFile = GetName()->GetString(); TCHAR drive[MAX_PATH]; TCHAR directory[MAX_PATH]; TCHAR filename[MAX_PATH]; TCHAR fileext[MAX_PATH]; TCHAR szDefinesTemp[65] = { '\0' }; _tsplitpath( szFile, drive, directory, filename, fileext ); StdString szCompiledFile; szCompiledFile += drive; szCompiledFile += directory; szCompiledFile += _T("Compiled\\"); szCompiledFile += filename; if (pDefines) { szCompiledFile += _T("_enc"); szCompiledFile += _itot(pDefines->GetValuesEncoding().iEncoding, szDefinesTemp, 10); } szCompiledFile += fileext; #ifdef XBOX szCompiledFile = SetPathDrive( szCompiledFile, EngineGetToolBox()->GetDrive() ); #endif LPVOID pShaderFileData = NULL; UINT shaderLen = 0; struct _stat shaderFilestat; // checking if compiled version exists, if we can load it into a buffer and if the file stats of the shader (not compiled) are readable if (CheckFileExists(szCompiledFile) && ( _tstat( szFile, &shaderFilestat ) == 0) && LoadFileIntoBuffer( szCompiledFile, pShaderFileData, shaderLen, true )) { m_ToolBox->Log( LOGINFORMATION, _T("Reading compiled shader file: %s\n"), szCompiledFile.c_str() ); // create a shader buffer to store the compiled shader hr = D3DXCreateBuffer( shaderLen, &shaderBuf ); if (SUCCEEDED(hr)) { time_t storedMTime = 0; // get the compiled date out of the file memcpy( &storedMTime, pShaderFileData, sizeof(time_t) ); // if the stored modified time in the compiled shader file is the same as the current // modified time of the shader file if( storedMTime == shaderFilestat.st_mtime ) { // reduce the buffer size by the preamble (mod time) shaderLen -= (int)sizeof(time_t); // copy the compiled shader into the shader buffer memcpy( shaderBuf->GetBufferPointer(), ((TCHAR *) pShaderFileData)+ sizeof(time_t), shaderLen); bLoadedCompiled = true; } } SAFE_DELETE_ARRAY( pShaderFileData ); } if (!bLoadedCompiled && bCompile) { if (pDefines) EngineGetToolBox()->Log( LOGINFORMATION, _T("Compiling shader %s:%d\n"), GetName()->GetString(), pDefines->GetValuesEncoding().iEncoding ); else EngineGetToolBox()->Log( LOGINFORMATION, _T("Compiling shader %s\n"), GetName()->GetString() ); hr = D3DXCompileShader( m_Code, len,//length of string in bytes pMacros, //can add that matrix of macros here &includeInterface, //for include directories "main",//? temp profile, //vs_1_1 for example 0, //compiling options? &shaderBuf, &pErrorMsgs, NULL ); } //now actually create the shader if( hr == D3D_OK && shaderBuf ) { if (!bLoadedCompiled) { struct _stat shaderFilestat; // get the shader file's modified time if (_tstat( szFile, &shaderFilestat ) == 0) { m_ToolBox->Log( LOGINFORMATION, _T("Writing compiled shader file: %s\n"), szCompiledFile.c_str() ); // open a compiled shader file for writing FILE *fp = fopen( szCompiledFile, "wb" ); if (fp) { // write shader file's modified time fwrite( &shaderFilestat.st_mtime, sizeof(time_t), 1, fp ); // write compiled shader data fwrite( shaderBuf->GetBufferPointer(), shaderBuf->GetBufferSize(), 1, fp ); fclose(fp); } else { m_ToolBox->Log( LOGWARNING, _T("Failed to write compiled shader file: %s\n"), szCompiledFile.c_str() ); } } } hr = pDevice->CreateVertexShader( (DWORD *) shaderBuf->GetBufferPointer(), &pShader ); assert( SUCCEEDED(hr) ); if (!SUCCEEDED(hr)) { m_ToolBox->Log( LOGWARNING, _T("Failed to create shader : %s\n"), szCompiledFile.c_str() ); } SAFE_RELEASE( shaderBuf ); SAFE_RELEASE( pErrorMsgs ); if (pDefines == NULL) // we are compiling the default shader with no macro defines { assert( m_VertexShader == NULL ); // the default shader should only be compiled on Init when this is NULL m_VertexShader = pShader; } else if (pDefines != NULL) // we are compiling a variant of the shader { unsigned long iEncoding = pDefines->GetValuesEncoding().iEncoding; m_ShaderVariants[iEncoding] = pShader; } return true; } } if( pErrorMsgs ) { IHashString * name = GetName(); TCHAR* debug_errors = (TCHAR*)pErrorMsgs->GetBufferPointer(); m_ToolBox->Log( LOGERROR, _T("Could not create Vertex shader %s\nError message: %s\n"), name->GetString(), debug_errors ); SAFE_RELEASE( pErrorMsgs ); } SAFE_RELEASE( shaderBuf ); return false; }
HRESULT base_shademodel::CheckInterfaces(IDirect3DDevice9* device, CD3DX9_Dll_Loader* loader) { HRESULT hr =0; #define ERR_FXFILE_NOTFOUND " fx file not found ! " if(m_eff == NULL) { // create effect char path[MAX_PATH]; memset(path, 0, sizeof(path)); // make full fx path queryFxPath(path); strcat(path, GetName()); strcat(path, ".fx"); if(!ksfilefunc::fileExistsA(path)) { // not found if(g_additionalFxDir[0] == '\0') { // none assert( false && ERR_FXFILE_NOTFOUND ); return E_FAIL; } strcpy(path, g_additionalFxDir); strcat(path , GetName() ); strcat(path, ".fx"); if(!ksfilefunc::fileExistsA(path)) { // not found assert( false && ERR_FXFILE_NOTFOUND ); return E_FAIL; } } // create LPD3DXBUFFER errorbuffer = NULL; hr |= loader->D3DXCreateEffectFromFileA(device, path, NULL, NULL, 0, NULL, &m_eff, &errorbuffer ); std::string strError; if FAILED(hr) { if(errorbuffer) { char* temp = new char[errorbuffer->GetBufferSize() + 100]; memset(temp, 0, sizeof(temp) ); memcpy(temp, errorbuffer->GetBufferPointer(), errorbuffer->GetBufferSize() ); strError = temp; delete [] temp; temp = NULL; } else { strError = " error buffer empty !"; } #ifdef _DEBUG MessageBoxA(0, strError.c_str(), "Error create effect", MB_OK | MB_ICONERROR); #endif assert(hr==0 && " Error create effect "); } }