示例#1
0
// 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;
}
示例#3
0
//-------------------------------------------------------------------------------------------------------------
// 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, &paramDesc);

			// 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;
}