Bool FileSystem::Load( const PathString& fileName, void *& buffer, SizeT& size ) { FILE * pFile; if ( fopen_s( &pFile, fileName.ConstPtr(), "rb" ) ) { return false; } fseek( pFile , 0 , SEEK_END ); size = ftell( pFile ); if ( size == 0 ) { fclose( pFile ); return true; } rewind( pFile ); buffer = UnknownAllocator::Allocate( size ); if ( fread( buffer, 1, size, pFile ) != size ) { UnknownAllocator::Deallocate( buffer ); size = 0; fclose( pFile ); return false; } fclose(pFile); return true; }
Bool FileSystem::Exists( const PathString& fileName ) { HANDLE hFile = CreateFile( fileName.ConstPtr(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if ( hFile == INVALID_HANDLE_VALUE ) { return false; } CloseHandle( hFile ); return true; }
Bool FileSystem::Save( const PathString& fileName, const void * buffer, SizeT size ) { Char dir[ 256 ]; Char * fileStart; if ( GetFullPathName( fileName.ConstPtr(), 256, dir, &fileStart ) == 0 ) { return false; } *( fileStart - 1 ) = 0; if ( ! RecursiveCreateDirectory( dir ) ) { return false; } FILE * pFile; if ( fopen_s( &pFile, fileName.ConstPtr(), "wb" ) ) { return false; } if ( size == 0 ) { fclose( pFile ); return true; } if ( fwrite( buffer, 1, size, pFile ) != size ) { fclose( pFile ); return false; } fclose(pFile); return true; }
void ResourceManager::Add( const Char * name, Resource * res ) { PathString path; FileSystem::BuildPathName( name, path, FileSystem::PT_CACHE ); ResourceRequest req; req.m_res = res; StringUtils::StrCpy( req.m_path, 256, path.ConstPtr() ); if ( !res->IsPending() ) { res->m_state |= Resource::PENDING; pendingResources.PushBack( req ); } resourceTable.Insert( res->GetId(), res ); }
void ProgramCache::LoadProgramFromBinaries( Program& program ) { PathString binFileName = m_cachePath; binFileName += "/"; binFileName += program.m_name; binFileName += ".bin"; if ( FileSystem::Exists( binFileName ) ) { PathString searchStr = m_dataPath; searchStr += "/"; searchStr += program.m_name; searchStr += ".*"; Array< PathString > shaderFileNames; FileSystem::Find( searchStr.ConstPtr(), shaderFileNames ); U64 binLastWriteTime = FileSystem::GetLastWriteTime( binFileName ); Bool binIsUpToDate = true; Array< PathString >::ConstIterator it = shaderFileNames.Begin(); Array< PathString >::ConstIterator end = shaderFileNames.End(); for ( ; it != end; ++it ) { const PathString& shaderFileName = *it; if ( binLastWriteTime < FileSystem::GetLastWriteTime( shaderFileName ) ) { binIsUpToDate = false; break; } } if ( binIsUpToDate ) { SizeT size; void * buffer; if ( FileSystem::Load( binFileName, buffer, size ) ) { program.m_handle = RenderDevice::CreateProgramBinary( buffer, size ); UnknownAllocator::Deallocate( buffer ); } } } }
U64 FileSystem::GetLastWriteTime( const PathString& fileName ) { HANDLE hFile = CreateFile( fileName.ConstPtr(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ( hFile == INVALID_HANDLE_VALUE ) { return 0; } FILETIME ftCreate, ftAccess, ftWrite; if ( !GetFileTime( hFile, &ftCreate, &ftAccess, &ftWrite ) ) { CloseHandle(hFile); return 0; } CloseHandle(hFile); ULARGE_INTEGER tmp; tmp.LowPart = ftWrite.dwLowDateTime; tmp.HighPart = ftWrite.dwHighDateTime; return tmp.QuadPart; }
void ProgramCache::BuildCache() { LoadSamplerList(); PathString searchStr = m_dataPath; searchStr += "/*"; Array< PathString > shaderFileNames; FileSystem::Find( searchStr.ConstPtr(), shaderFileNames, false ); // Collect infos Array< PathString >::Iterator sIt = shaderFileNames.Begin(); Array< PathString >::Iterator sEnd = shaderFileNames.End(); for ( ; sIt != sEnd; ++sIt ) { PathString& name = *sIt; CARBON_ASSERT( name.Size() > 3 ); const Char * ext = name.End() - 3; U32 typeMask = 0; if ( StringUtils::StrCmp( ext, ".vs" ) == 0 ) { typeMask |= STB_VERTEX_SHADER; } else if ( StringUtils::StrCmp( ext, ".fs" ) == 0 ) { typeMask |= STB_FRAGMENT_SHADER; } else if ( StringUtils::StrCmp( ext, ".gs" ) == 0 ) { typeMask |= STB_GEOMETRY_SHADER; } else { CARBON_ASSERT( !"shader extension is not managed" ); continue; } name.Resize( ext - name.Begin() ); *(name.End()) = 0; U32 id = CreateId( name.ConstPtr() ); ProgramArray::Iterator program = Find( id ); if ( program == m_programs.End() ) { m_programs.PushBack( Program( id, typeMask, name.ConstPtr() ) ); program = m_programs.End() - 1; } program->m_type |= typeMask; } ProgramArray::Iterator pIt = m_programs.Begin(); ProgramArray::Iterator pEnd = m_programs.End(); for ( ; pIt != pEnd; ++pIt ) { Program& program = *pIt; LoadProgram( program ); } LoadProgramSets(); }