bool RSManager::disassembleShader(CONST DWORD *pFunction, LPD3DXBUFFER *ppBuffer) { LPD3DXBUFFER buffer = nullptr; HRESULT result = D3DXDisassembleShader(pFunction, false, NULL, ppBuffer); if (result != D3D_OK) { SDLOG(0, "Failed to disassemble shader\n"); } return result == D3D_OK; }
/* extern "C" { LPCSTR WINAPI D3DXGetPixelShaderProfile (LPDIRECT3DDEVICE9 pDevice); LPCSTR WINAPI D3DXGetVertexShaderProfile (LPDIRECT3DDEVICE9 pDevice); }; */ HRESULT CRender::shader_compile ( LPCSTR name, LPCSTR pSrcData, UINT SrcDataLen, void* _pDefines, void* _pInclude, LPCSTR pFunctionName, LPCSTR pTarget, DWORD Flags, void* _ppShader, void* _ppErrorMsgs, void* _ppConstantTable) { D3DXMACRO defines [128]; int def_it = 0; CONST D3DXMACRO* pDefines = (CONST D3DXMACRO*) _pDefines; char c_smapsize [32]; char c_gloss [32]; // Msg("%s.%s", name, pTarget); if (pDefines) { // transfer existing defines for (;; def_it++) { if (0==pDefines[def_it].Name) break; defines[def_it] = pDefines[def_it]; } } // options { sprintf (c_smapsize,"%d",u32(o.smapsize)); defines[def_it].Name = "SMAP_size"; defines[def_it].Definition = c_smapsize; def_it ++ ; } if (o.fp16_filter) { defines[def_it].Name = "FP16_FILTER"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.fp16_blend) { defines[def_it].Name = "FP16_BLEND"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.HW_smap) { defines[def_it].Name = "USE_HWSMAP"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.HW_smap_PCF) { defines[def_it].Name = "USE_HWSMAP_PCF"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.HW_smap_FETCH4) { defines[def_it].Name = "USE_FETCH4"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.sjitter) { defines[def_it].Name = "USE_SJITTER"; defines[def_it].Definition = "1"; def_it ++ ; } if (HW.Caps.raster_major >= 3) { defines[def_it].Name = "USE_BRANCHING"; defines[def_it].Definition = "1"; def_it ++ ; } if (HW.Caps.geometry.bVTF) { defines[def_it].Name = "USE_VTF"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.Tshadows) { defines[def_it].Name = "USE_TSHADOWS"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.mblur) { defines[def_it].Name = "USE_MBLUR"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.sunfilter) { defines[def_it].Name = "USE_SUNFILTER"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.sunstatic) { defines[def_it].Name = "USE_R2_STATIC_SUN"; defines[def_it].Definition = "1"; def_it ++ ; } if (o.forcegloss) { sprintf (c_gloss,"%f",o.forcegloss_v); defines[def_it].Name = "FORCE_GLOSS"; defines[def_it].Definition = c_gloss; def_it ++ ; } if (o.forceskinw) { defines[def_it].Name = "SKIN_COLOR"; defines[def_it].Definition = "1"; def_it ++; } // skinning if (m_skinning<0) { defines[def_it].Name = "SKIN_NONE"; defines[def_it].Definition = "1"; def_it ++ ; } if (0==m_skinning) { defines[def_it].Name = "SKIN_0"; defines[def_it].Definition = "1"; def_it ++; } if (1==m_skinning) { defines[def_it].Name = "SKIN_1"; defines[def_it].Definition = "1"; def_it ++; } if (2==m_skinning) { defines[def_it].Name = "SKIN_2"; defines[def_it].Definition = "1"; def_it ++; } // finish defines[def_it].Name = 0; defines[def_it].Definition = 0; def_it ++; // if (0==xr_strcmp(pFunctionName,"main")) { if ('v'==pTarget[0]) pTarget = D3DXGetVertexShaderProfile (HW.pDevice); // vertex "vs_2_a"; // else pTarget = D3DXGetPixelShaderProfile (HW.pDevice); // pixel "ps_2_a"; // } LPD3DXINCLUDE pInclude = (LPD3DXINCLUDE) _pInclude; LPD3DXBUFFER* ppShader = (LPD3DXBUFFER*) _ppShader; LPD3DXBUFFER* ppErrorMsgs = (LPD3DXBUFFER*) _ppErrorMsgs; LPD3DXCONSTANTTABLE* ppConstantTable = (LPD3DXCONSTANTTABLE*)_ppConstantTable; #ifdef D3DXSHADER_USE_LEGACY_D3DX9_31_DLL // December 2006 and later HRESULT _result = D3DXCompileShader(pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags|D3DXSHADER_USE_LEGACY_D3DX9_31_DLL,ppShader,ppErrorMsgs,ppConstantTable); #else HRESULT _result = D3DXCompileShader(pSrcData,SrcDataLen,defines,pInclude,pFunctionName,pTarget,Flags,ppShader,ppErrorMsgs,ppConstantTable); #endif if (SUCCEEDED(_result) && o.disasm) { ID3DXBuffer* code = *((LPD3DXBUFFER*)_ppShader); ID3DXBuffer* disasm = 0; D3DXDisassembleShader (LPDWORD(code->GetBufferPointer()), FALSE, 0, &disasm ); string_path dname; strconcat (dname,"disasm\\",name,('v'==pTarget[0])?".vs":".ps" ); IWriter* W = FS.w_open("$logs$",dname); W->w (disasm->GetBufferPointer(),disasm->GetBufferSize()); FS.w_close (W); _RELEASE (disasm); } return _result; }
int r3dPixelShader :: LoadBinaryCache( const char* FName, const char* Path, const char* defines ) { R3D_ENSURE_MAIN_THREAD(); char FName2[512]; r3dMakeCompiledShaderName(FName2, FName, defines); if(r3d_access(FName2, 0) != 0) return 0; bool sourceAvailable = r3d_access( Path, 0 ) == 0; // is source code available? if( sourceAvailable ) { // source code is newer, have to recompile if( r3d_fstamp( Path ) > r3d_fstamp( FName2 ) ) return 0; } r3dFile* f = r3d_open( FName2, "rb" ); if( !sourceAvailable && !f ) { r3dError( "r3dPixelShader :: LoadBinaryCache: both source and cached version a missing(%s)!\n", Path ); } if (!f) return 0; char CheckSig[ sizeof BIN_VER_SIG ]; fread( CheckSig, sizeof CheckSig, 1, f ); if( memcmp( CheckSig, BIN_VER_SIG, sizeof BIN_VER_SIG ) ) { if( sourceAvailable ) { r3dError( "r3dPixelShader::LoadBinaryCache: source code is missing and cached version is unknown(%s)!\n", Path ); } else { r3dOutToLog( "r3dPixelShader::LoadBinaryCache: unsupported binary version!\n" ); } fclose( f ); return 0; } r3dTL::TArray< r3dString > Includes; ReadIncludesFromFile( f, Includes ); if( sourceAvailable ) { for( uint32_t i = 0, e = Includes.Count(); i < e; i ++ ) { char IncludeName[ 512 ]; char drive[ 16 ], dir[ 512 ], name[ 512 ], ext[ 512 ]; _splitpath( FName, drive, dir, name, ext ); sprintf( IncludeName, "%s\\%s\\%s", __r3dBaseShaderPath, dir, Includes[ i ].c_str() ); if( r3d_fstamp( IncludeName ) > r3d_fstamp( FName2 ) ) { fclose( f ); return 0; } } } size_t codeSize = f->size - ftell( f ); char* shaderCode = new char[ codeSize + 1 ]; fread( shaderCode, codeSize, 1, f ); fclose( f ); Unload(); // Create the pixel shader HRESULT hr; hr = r3dRenderer->pd3ddev->CreatePixelShader( (DWORD*)shaderCode, &m_pShader); r3dRenderer->CheckOutOfMemory( hr ) ; #ifndef FINAL_BUILD if( r_warn_shaders->GetInt() ) { ID3DXBuffer *buffer( NULL ) ; D3D_V( D3DXDisassembleShader( (DWORD*)shaderCode, FALSE, NULL, &buffer ) ) ; char* cbuff = (char*)buffer->GetBufferPointer() ; if( char* substr = strstr( cbuff, "// approximately" ) ) { int icount = 0 ; sscanf( substr, "// approximately %d", &icount ) ; if( icount > 512 ) { r3dArtBug( "Pixel Shader '%s' is %d instructions long!\n", ( r3dString( FName ) + ":" + this->Name ).c_str(), icount ) ; } } else { r3dArtBug( "Successfully disassembled the shader but couldn't find instruction count!\n" ) ; } SAFE_RELEASE( buffer ) ; } #endif delete[] shaderCode; if( FAILED(hr) ) { r3dOutToLog("Failed to create Pixel shader '%s' : \n", FName); if(hr == D3DERR_INVALIDCALL) r3dOutToLog ("Invalid Call\n"); if(hr == E_OUTOFMEMORY) r3dOutToLog ("Out of memory\n"); if(hr == D3DERR_OUTOFVIDEOMEMORY) r3dOutToLog ("Out of Video Memory\n"); // mystic DDERR_CURRENTLYNOTAVAIL if(hr == 0x88760028) r3dOutToLog ("DDERR_CURRENTLYNOTAVAIL\n"); r3dOutToLog("error=%d\n", hr); m_pShader = NULL; return 0; } //r3dOutToLog("PIXEL SHADER INIT %d\n%s<--\n\n", m_pShader, __pCodeCode); return 1; }
static UBOOL D3D9CompileShaderWrapper( const TCHAR* ShaderFilename, const TCHAR* FunctionName, const TCHAR* ShaderProfile, DWORD CompileFlags, const FShaderCompilerEnvironment& InEnvironment, const vector<D3DXMACRO>& Macros, FShaderCompilerOutput& Output, vector<FD3D9ConstantDesc>& Constants, FString& DisassemblyString, FString& ErrorString ) { const FString& SourceFile = LoadShaderSourceFile(ShaderFilename); TRefCountPtr<ID3DXBuffer> Shader; TRefCountPtr<ID3DXBuffer> Errors; FD3DIncludeEnvironment Environment(InEnvironment); TRefCountPtr<ID3DXConstantTable> ConstantTable; FTCHARToANSI AnsiSourceFile(SourceFile.c_str()); HRESULT Result = D3DXCompileShader( AnsiSourceFile, SourceFile.size(), &Macros[0], &Environment, TCHAR_TO_ANSI(FunctionName), TCHAR_TO_ANSI(ShaderProfile), CompileFlags, Shader.GetInitReference(), Errors.GetInitReference(), ConstantTable.GetInitReference()); if( FAILED(Result) ) { ErrorString = TEXT("Compile Failed without warnings!"); void* ErrorBuffer = Errors ? Errors->GetBufferPointer() : NULL; if( ErrorBuffer ) { FANSIToTCHAR Convert((ANSICHAR*)ErrorBuffer); ErrorString = Convert; } } else { // get the ShaderCode INT NumShaderBytes = Shader->GetBufferSize(); Output.ShaderCode.resize(NumShaderBytes); appMemcpy(&Output.ShaderCode[0], Shader->GetBufferPointer(), NumShaderBytes); // collect the constant table D3DXCONSTANTTABLE_DESC ConstantTableDesc; VERIFYD3DRESULT(ConstantTable->GetDesc(&ConstantTableDesc)); for(UINT ConstantIndex = 0; ConstantIndex < ConstantTableDesc.Constants; ++ConstantIndex) { D3DXHANDLE ConstantHandle = ConstantTable->GetConstant(NULL, ConstantIndex); D3DXCONSTANT_DESC ConstantDesc; UINT NumConstants = 1; VERIFYD3DRESULT(ConstantTable->GetConstantDesc(ConstantHandle, &ConstantDesc, &NumConstants)); FD3D9ConstantDesc NamedConstantDesc; appStrcpyANSI(NamedConstantDesc.Name, ConstantDesc.Name); NamedConstantDesc.bIsSampler = ConstantDesc.RegisterSet == D3DXRS_SAMPLER; NamedConstantDesc.RegisterIndex = ConstantDesc.RegisterIndex; NamedConstantDesc.RegisterCount = ConstantDesc.RegisterCount; Constants.push_back(NamedConstantDesc); } // disassemble a shader TRefCountPtr<ID3DXBuffer> DisassemblyBuffer; VERIFYD3DRESULT(D3DXDisassembleShader((const DWORD*)Shader->GetBufferPointer(), FALSE, NULL, DisassemblyBuffer.GetInitReference())); DisassemblyString = ANSI_TO_TCHAR((ANSICHAR*)DisassemblyBuffer->GetBufferPointer()); } return TRUE; }
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; }
bool GFXD3D9Shader::_compileShader( const Torque::Path &filePath, const String& target, const D3DXMACRO *defines, GenericConstBufferLayout* bufferLayoutF, GenericConstBufferLayout* bufferLayoutI, Vector<GFXShaderConstDesc> &samplerDescriptions ) { PROFILE_SCOPE( GFXD3D9Shader_CompileShader ); HRESULT res = D3DERR_INVALIDCALL; LPD3DXBUFFER code = NULL; LPD3DXBUFFER errorBuff = NULL; #ifdef TORQUE_DEBUG U32 flags = D3DXSHADER_DEBUG; #else U32 flags = 0; #endif #ifdef TORQUE_OS_XENON flags |= D3DXSHADER_PREFER_FLOW_CONTROL; #endif #ifdef D3DXSHADER_USE_LEGACY_D3DX9_31_DLL if( D3DX_SDK_VERSION >= 32 ) { // will need to use old compiler for 1_1 shaders - check for pixel // or vertex shader with appropriate version. if ((target.compare("vs1", 3) == 0) || (target.compare("vs_1", 4) == 0)) flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL; if ((target.compare("ps1", 3) == 0) || (target.compare("ps_1", 4) == 0)) flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL; } #endif #if !defined(TORQUE_OS_XENON) && (D3DX_SDK_VERSION <= 40) #error This version of the DirectX SDK is too old. Please install a newer version of the DirectX SDK: http://msdn.microsoft.com/en-us/directx/default.aspx #endif ID3DXConstantTable* table = NULL; static String sHLSLStr( "hlsl" ); static String sOBJStr( "obj" ); // Is it an HLSL shader? if ( filePath.getExtension().equal(sHLSLStr, String::NoCase) ) { FrameAllocatorMarker fam; char *buffer = NULL; // Set this so that the D3DXInclude::Open will have this // information for relative paths. smD3DXInclude->setPath( filePath.getRootAndPath() ); FileStream s; if ( !s.open( filePath, Torque::FS::File::Read ) ) { AssertISV(false, avar("GFXD3D9Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str())); if ( smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Failed to open shader file '%s'.", filePath.getFullPath().c_str() ); return false; } // Convert the path which might have virtualized // mount paths to a real file system path. Torque::Path realPath; if ( !FS::GetFSPath( filePath, realPath ) ) realPath = filePath; // Add a #line pragma so that error and warning messages // returned by the HLSL compiler report the right file. String linePragma = String::ToString( "#line 1 \"%s\"\r\n", realPath.getFullPath().c_str() ); U32 linePragmaLen = linePragma.length(); U32 bufSize = s.getStreamSize(); buffer = (char *)fam.alloc( bufSize + linePragmaLen + 1 ); dStrncpy( buffer, linePragma.c_str(), linePragmaLen ); s.read( bufSize, buffer + linePragmaLen ); buffer[bufSize+linePragmaLen] = 0; res = GFXD3DX.D3DXCompileShader( buffer, bufSize + linePragmaLen, defines, smD3DXInclude, "main", target, flags, &code, &errorBuff, &table ); } // Is it a precompiled obj shader? else if ( filePath.getExtension().equal( sOBJStr, String::NoCase ) ) { FileStream s; if(!s.open(filePath, Torque::FS::File::Read)) { AssertISV(false, avar("GFXD3D9Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str())); if ( smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Failed to open shader file '%s'.", filePath.getFullPath().c_str() ); return false; } res = GFXD3DX.D3DXCreateBuffer(s.getStreamSize(), &code); AssertISV(res == D3D_OK, "Unable to create buffer!"); s.read(s.getStreamSize(), code->GetBufferPointer()); if (res == D3D_OK) { DWORD* data = (DWORD*) code->GetBufferPointer(); res = GFXD3DX.D3DXGetShaderConstantTable(data, &table); } } else { if ( smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Unsupported shader file type '%s'.", filePath.getFullPath().c_str() ); return false; } if ( res != D3D_OK && smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Error compiling shader: %s: %s (%x)", DXGetErrorStringA(res), DXGetErrorDescriptionA(res), res ); if ( errorBuff ) { // remove \n at end of buffer U8 *buffPtr = (U8*) errorBuff->GetBufferPointer(); U32 len = dStrlen( (const char*) buffPtr ); buffPtr[len-1] = '\0'; if( res != D3D_OK ) { if ( smLogErrors ) Con::errorf( " %s", (const char*) errorBuff->GetBufferPointer() ); } else { if ( smLogWarnings ) Con::warnf( "%s", (const char*) errorBuff->GetBufferPointer() ); } } else if ( code == NULL && smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - no compiled code produced; possibly missing file '%s'.", filePath.getFullPath().c_str() ); // Create the proper shader if we have code if( code != NULL ) { #ifndef TORQUE_SHIPPING LPD3DXBUFFER disassem = NULL; D3DXDisassembleShader( (DWORD*)code->GetBufferPointer(), false, NULL, &disassem ); mDissasembly = (const char*)disassem->GetBufferPointer(); SAFE_RELEASE( disassem ); if ( gDisassembleAllShaders ) { String filename = filePath.getFullPath(); filename.replace( ".hlsl", "_dis.txt" ); FileStream *fstream = FileStream::createAndOpen( filename, Torque::FS::File::Write ); if ( fstream ) { fstream->write( mDissasembly ); fstream->close(); delete fstream; } } #endif if (target.compare("ps_", 3) == 0) res = mD3D9Device->CreatePixelShader( (DWORD*)code->GetBufferPointer(), &mPixShader ); else res = mD3D9Device->CreateVertexShader( (DWORD*)code->GetBufferPointer(), &mVertShader ); if (res == S_OK) _getShaderConstants(table, bufferLayoutF, bufferLayoutI, samplerDescriptions); #ifdef TORQUE_ENABLE_CSF_GENERATION // Ok, we've got a valid shader and constants, let's write them all out. if ( !_saveCompiledOutput(filePath, code, bufferLayoutF, bufferLayoutI) && smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Unable to save shader compile output for: %s", filePath.getFullPath().c_str() ); #endif SAFE_RELEASE(table); if ( res != S_OK && smLogErrors ) Con::errorf( "GFXD3D9Shader::_compileShader - Unable to create shader for '%s'.", filePath.getFullPath().c_str() ); } bool result = code != NULL && res == S_OK; SAFE_RELEASE( code ); SAFE_RELEASE( errorBuff ); return result; }