// loading/unloading // ---------------------------------------------------------------------------------------------- // Loads a file and turns it into a runtime resource bool ResourceManager::LoadResource(Resource * res, const WCHAR* filename) { bool ok = false; // try to create resource if (!FileUtils::Exists(filename)) { Logger::Log(OutputMessageType::Error, L"Failed to load file, '%ls' -- does not exist\n", filename); return false; } PerfTimer timer; timer.Start(); // get factory associated with 'filename' ResourceFactory * factory = GetFactory(filename); if (!factory) { return false; } ok = factory->LoadResource(res, filename); if (ok) { res->SetReady(); timer.Stop(); Logger::Log(OutputMessageType::Debug, L"%d ms Loaded %ls\n", timer.ElapsedMilliseconds(), FileUtils::Name(filename)); } else { timer.Stop(); Logger::Log(OutputMessageType::Error, L"%d ms failed to load %ls\n", timer.ElapsedMilliseconds(), filename); } return ok; }
Pmwx::Halfedge_handle InsertOneSegment( const RawCoordPair& p1, const RawCoordPair& p2, VertexIndex& index, Pmwx& ioMap) { string key1 = RawCoordToKey(p1); Point_2 pt1 = RawCoordToCoord(p1); string key2 = RawCoordToKey(p2); Point_2 pt2 = RawCoordToCoord(p2); VertexIndex::iterator i1 = index.find(key1); VertexIndex::iterator i2 = index.find(key2); Pmwx::Halfedge_handle he = Pmwx::Halfedge_handle(); #if 0 Pmwx::Locate_type loc1, loc2; ioMap.locate(pt1, loc1); ioMap.locate(pt2, loc2); CGAL_precondition_msg(loc1 != Pmwx::EDGE, "Pt1 on an edge, will cause CHAOS"); CGAL_precondition_msg(loc2 != Pmwx::EDGE, "Pt2 on an edge, will cause CHAOS"); if (i1 == index.end()) CGAL_precondition_msg(loc1 != Pmwx::VERTEX, "Pt1 on an unindexed vertex, will cause CHAOS"); if (i2 == index.end()) CGAL_precondition_msg(loc2 != Pmwx::VERTEX, "Pt2 on an unindexed vertex, will cause CHAOS"); #endif if (i1 == index.end()) { if (i2 == index.end()) { // Totally unknown segment. Pmwx::Locate_type lt; zeroV.Start(); he = ioMap.locate(pt1, lt); CGAL_precondition_msg(lt == Pmwx::FACE || lt == Pmwx::UNBOUNDED_FACE, "Inserting a segment in unknown territory but it's NOT on a face!!"); Pmwx::Face_handle fe = (lt == Pmwx::UNBOUNDED_FACE) ? ioMap.unbounded_face() : he->face(); // he = ioMap.non_intersecting_insert(PM_Curve_2(pt1, pt2)); he = ioMap.insert_in_face_interior(PM_Curve_2(pt1, pt2), fe); zeroV.Stop(); if (he != Pmwx::Halfedge_handle()) { index[key1] = he->source(); index[key2] = he->target(); } } else { // We know pt 2 but pt 1 is floating. Make a vector // using the vertex handle from 2 and 1's raw value. oneV.Start(); he = ioMap.Planar_map_2::insert_from_vertex( PM_Curve_2(i2->second->point(), pt1), i2->second); oneV.Stop(); // Now pt 1 gets stored...it is the target of the new halfedge. if (he != Pmwx::Halfedge_handle()) { index[key1] = he->target(); he = he->twin(); // This halfedge goes from 2 to 1, turn it around! } } } else { if (i2 == index.end()) { oneV.Start(); // We know pt 1 but not pt 2 he = ioMap.Planar_map_2::insert_from_vertex( PM_Curve_2(i1->second->point(), pt2), i1->second); oneV.Stop(); // Now pt 1 gets stored...it is the target of the new halfedge. if (he != Pmwx::Halfedge_handle()) index[key2] = he->target(); } else { twoV.Start(); // Both pts are known he = ioMap.Planar_map_2::insert_at_vertices( PM_Curve_2(i1->second->point(), i2->second->point()), i1->second, i2->second); twoV.Stop(); } } if (he == Pmwx::Halfedge_handle()) { return ioMap.halfedges_end(); } // Whenever we create a half edge we have to pick dominance...this works. he->mDominant = true; return he; }
//------------------------------------------------------------------------------------------------------------- // UTILITY FUNCTIONS //------------------------------------------------------------------------------------------------------------- bool Shader::CompileShaders(ID3D11Device* device, const ShaderDesc& desc) { constexpr const char * SHADER_BINARY_EXTENSION = ".bin"; mDescriptor = desc; HRESULT result; ShaderBlobs blobs; bool bPrinted = false; PerfTimer timer; timer.Start(); // COMPILE SHADER STAGES //---------------------------------------------------------------------------- for (const ShaderStageDesc& stageDesc : desc.stages) { if (stageDesc.fileName.empty()) continue; // stage.macros const std::string sourceFilePath = std::string(Renderer::sShaderRoot + stageDesc.fileName); const EShaderStage stage = GetShaderTypeFromSourceFilePath(sourceFilePath); // USE SHADER CACHE // const size_t ShaderHash = GeneratePreprocessorDefinitionsHash(stageDesc.macros); const std::string cacheFileName = stageDesc.macros.empty() ? DirectoryUtil::GetFileNameFromPath(sourceFilePath) + SHADER_BINARY_EXTENSION : DirectoryUtil::GetFileNameFromPath(sourceFilePath) + "_" + std::to_string(ShaderHash) + SHADER_BINARY_EXTENSION; const std::string cacheFilePath = Application::s_ShaderCacheDirectory + "\\" + cacheFileName; const bool bUseCachedShaders = DirectoryUtil::FileExists(cacheFilePath) && !IsCacheDirty(sourceFilePath, cacheFilePath); //--------------------------------------------------------------------------------- if (!bPrinted) // quick status print here { const char* pMsgLoad = bUseCachedShaders ? "Loading cached shader binaries" : "Compiling shader from source"; Log::Info("\t%s %s...", pMsgLoad, mName.c_str()); bPrinted = true; } //--------------------------------------------------------------------------------- if (bUseCachedShaders) { blobs.of[stage] = CompileFromCachedBinary(cacheFilePath); } else { std::string errMsg; ID3D10Blob* pBlob; if (CompileFromSource(sourceFilePath, stage, pBlob, errMsg, stageDesc.macros)) { blobs.of[stage] = pBlob; CacheShaderBinary(cacheFilePath, blobs.of[stage]); } else { Log::Error(errMsg); return false; } } CreateShaderStage(device, stage, blobs.of[stage]->GetBufferPointer(), blobs.of[stage]->GetBufferSize()); SetReflections(blobs); //CheckSignatures(); ShaderLoadDesc loadDesc = {}; loadDesc.fullPath = sourceFilePath; loadDesc.lastWriteTime = std::experimental::filesystem::last_write_time(sourceFilePath); mDirectories[stage] = loadDesc; } // INPUT LAYOUT (VS) //--------------------------------------------------------------------------- // src: https://stackoverflow.com/questions/42388979/directx-11-vertex-shader-reflection // setup the layout of the data that goes into the shader // if(mReflections.vsRefl) { D3D11_SHADER_DESC shaderDesc = {}; mReflections.vsRefl->GetDesc(&shaderDesc); std::vector<D3D11_INPUT_ELEMENT_DESC> inputLayout(shaderDesc.InputParameters); D3D_PRIMITIVE primitiveDesc = shaderDesc.InputPrimitive; for (unsigned i = 0; i < shaderDesc.InputParameters; ++i) { D3D11_SIGNATURE_PARAMETER_DESC paramDesc; mReflections.vsRefl->GetInputParameterDesc(i, ¶mDesc); // fill out input element desc D3D11_INPUT_ELEMENT_DESC elementDesc; elementDesc.SemanticName = paramDesc.SemanticName; elementDesc.SemanticIndex = paramDesc.SemanticIndex; elementDesc.InputSlot = 0; elementDesc.AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT; elementDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; elementDesc.InstanceDataStepRate = 0; // determine DXGI format if (paramDesc.Mask == 1) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32_FLOAT; } else if (paramDesc.Mask <= 3) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32_FLOAT; } else if (paramDesc.Mask <= 7) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; } else if (paramDesc.Mask <= 15) { if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_UINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_SINT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; else if (paramDesc.ComponentType == D3D_REGISTER_COMPONENT_FLOAT32) elementDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; } inputLayout[i] = elementDesc; //save element desc } // Try to create Input Layout const auto* pData = inputLayout.data(); if (pData) { result = device->CreateInputLayout( pData, shaderDesc.InputParameters, blobs.vs->GetBufferPointer(), blobs.vs->GetBufferSize(), &mpInputLayout); if (FAILED(result)) { OutputDebugString("Error creating input layout"); return false; } } } // CONSTANT BUFFERS //--------------------------------------------------------------------------- // Obtain cbuffer layout information for (EShaderStage type = EShaderStage::VS; type < EShaderStage::COUNT; type = (EShaderStage)(type + 1)) { if (mReflections.of[type]) { ReflectConstantBufferLayouts(mReflections.of[type], type); } } // Create CPU & GPU constant buffers // CPU CBuffers int constantBufferSlot = 0; for (const ConstantBufferLayout& cbLayout : m_CBLayouts) { std::vector<CPUConstantID> cpuBuffers; for (D3D11_SHADER_VARIABLE_DESC varDesc : cbLayout.variables) { CPUConstant c; CPUConstantID c_id = static_cast<CPUConstantID>(mCPUConstantBuffers.size()); c._name = varDesc.Name; c._size = varDesc.Size; c._data = new char[c._size]; memset(c._data, 0, c._size); m_constants.push_back(std::make_pair(constantBufferSlot, c_id)); mCPUConstantBuffers.push_back(c); } ++constantBufferSlot; } // GPU CBuffers D3D11_BUFFER_DESC cBufferDesc; cBufferDesc.Usage = D3D11_USAGE_DYNAMIC; cBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; cBufferDesc.MiscFlags = 0; cBufferDesc.StructureByteStride = 0; for (const ConstantBufferLayout& cbLayout : m_CBLayouts) { ConstantBufferBinding cBuffer; cBufferDesc.ByteWidth = cbLayout.desc.Size; if (FAILED(device->CreateBuffer(&cBufferDesc, NULL, &cBuffer.data))) { OutputDebugString("Error creating constant buffer"); return false; } cBuffer.dirty = true; cBuffer.shaderStage = cbLayout.stage; cBuffer.bufferSlot = cbLayout.bufSlot; mConstantBuffers.push_back(cBuffer); } // TEXTURES & SAMPLERS //--------------------------------------------------------------------------- for (int shaderStage = 0; shaderStage < EShaderStage::COUNT; ++shaderStage) { unsigned texSlot = 0; unsigned smpSlot = 0; unsigned uavSlot = 0; auto& sRefl = mReflections.of[shaderStage]; if (sRefl) { D3D11_SHADER_DESC desc = {}; sRefl->GetDesc(&desc); for (unsigned i = 0; i < desc.BoundResources; ++i) { D3D11_SHADER_INPUT_BIND_DESC shdInpDesc; sRefl->GetResourceBindingDesc(i, &shdInpDesc); switch (shdInpDesc.Type) { case D3D_SIT_SAMPLER: { SamplerBinding smp; smp.shaderStage = static_cast<EShaderStage>(shaderStage); smp.samplerSlot = smpSlot++; mSamplerBindings.push_back(smp); mShaderSamplerLookup[shdInpDesc.Name] = static_cast<int>(mSamplerBindings.size() - 1); } break; case D3D_SIT_TEXTURE: { TextureBinding tex; tex.shaderStage = static_cast<EShaderStage>(shaderStage); tex.textureSlot = texSlot++; mTextureBindings.push_back(tex); mShaderTextureLookup[shdInpDesc.Name] = static_cast<int>(mTextureBindings.size() - 1); } break; case D3D_SIT_UAV_RWTYPED: { TextureBinding tex; tex.shaderStage = static_cast<EShaderStage>(shaderStage); tex.textureSlot = uavSlot++; mTextureBindings.push_back(tex); mShaderTextureLookup[shdInpDesc.Name] = static_cast<int>(mTextureBindings.size() - 1); } break; case D3D_SIT_CBUFFER: break; default: Log::Warning("Unhandled shader input bind type in shader reflection"); break; } // switch shader input type } // bound resource } // sRefl } // shaderStage // release blobs for (unsigned type = EShaderStage::VS; type < EShaderStage::COUNT; ++type) { if (blobs.of[type]) blobs.of[type]->Release(); } return true; }