コード例 #1
0
ファイル: GuiRenderer.cpp プロジェクト: nfprojects/nfengine
void GuiRendererD3D11::Leave(NFE_CONTEXT_ARG)
{
    auto pCtx = (RenderContextD3D11*)pContext;
    auto pRenderer = pCtx->GetRenderer();
    FlushQueue(pCtx);

    pCtx->ResetShader(ShaderType::Geometry);
    pCtx->D3DContext->OMSetBlendState(pRenderer->defaultBlendState, 0, 0xFFFFFFFF);
}
コード例 #2
0
ファイル: RenderUtil.cpp プロジェクト: BenKZSSS/ToyGE
	void RenderToVolumeTexture(const Ptr<Texture> & volumeTexture)
	{
		auto rc = Global::GetRenderEngine()->GetRenderContext();

		auto & quadVBs = GetQuadVBs();
		auto & quadIB = GetQuadIB();

		RenderViewport vp;
		vp.topLeftX = 0.0f;
		vp.topLeftY = 0.0f;
		vp.width = static_cast<float>(volumeTexture->GetDesc().width);
		vp.height = static_cast<float>(volumeTexture->GetDesc().height);
		vp.minDepth = 0.0f;
		vp.maxDepth = 1.0f;
		rc->SetViewport(vp);

		float2 uvMap[4];
		uvMap[0] = float2(0.0f, 0.0f);
		uvMap[1] = float2(1.0f, 0.0f);
		uvMap[2] = float2(0.0f, 1.0f);
		uvMap[3] = float2(1.0f, 1.0f);

		auto uvBufMappedData = quadVBs[1]->Map(MAP_WRITE_DISCARD);
		memcpy(uvBufMappedData.pData, uvMap, sizeof(float2) * 4);
		quadVBs[1]->UnMap();

		// Set vbs, ib
		rc->SetVertexBuffer(quadVBs);
		rc->SetIndexBuffer(quadIB);
		rc->SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_TRIANGLELIST);

		// Set rtv
		rc->SetRenderTargets({ volumeTexture->GetRenderTargetView(0, 0, volumeTexture->GetDesc().depth) });

		// Set dsv
		rc->SetDepthStencilState(DepthStencilStateTemplate<false>::Get());

		// Bind shader
		auto vs = Shader::FindOrCreate<RenderToVolumeTextureVS>();
		auto gs = Shader::FindOrCreate<RenderToVolumeTextureGS>();
		vs->Flush();
		gs->Flush();

		// Draw
		rc->DrawIndexedInstanced(quadIB->GetDesc().numElements, volumeTexture->GetDesc().depth, 0, 0, 0);

		rc->SetDepthStencilState(nullptr);
		rc->ResetShader(SHADER_GS);
	}
コード例 #3
0
ファイル: FFT.cpp プロジェクト: BenKZSSS/ToyGE
	void FFT::FFT2DRadix8(
		const Ptr<Texture> & src,
		int32_t srcMipLevel,
		int32_t srcArrayOffset,
		const Ptr<Texture> & dst,
		int32_t dstMipLevel,
		int32_t dstArrayOffset,
		bool bInverse,
		bool bIFFTScale)
	{
		auto mipSize = src->GetMipSize(srcMipLevel);

		TextureDesc texDesc;
		texDesc.width = mipSize.x();
		texDesc.height = mipSize.y();
		texDesc.depth = 1;
		texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_UNORDERED_ACCESS;
		texDesc.cpuAccess = 0;
		texDesc.format = RENDER_FORMAT_R32G32_FLOAT;
		texDesc.mipLevels = 1;
		texDesc.arraySize = 1;
		texDesc.bCube = false;
		texDesc.sampleCount = 1;
		texDesc.sampleQuality = 0;

		PooledTextureRef bfSrcRef;
		Ptr<Texture> bfSrc;
		int32_t bfSrcMipLevel = 0;
		int32_t bfSrcArrayOffset = 0;
		//if (!bInverse)
		//{
		//	bfSrcRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc });
		//	bfSrc = bfSrcRef->Get()->Cast<Texture>();
		//	FFT::FFTSetup(src, srcMipLevel, srcArrayOffset, bfSrc, 0, 0);
		//}
		//else
		{
			bfSrc = src;
			bfSrcMipLevel = srcMipLevel;
			bfSrcArrayOffset = srcArrayOffset;
		}

		PooledTextureRef bfDstRef;
		Ptr<Texture> bfDst;
		int32_t bfDstMipLevel = 0;
		int32_t bfDstArrayOffset = 0;
		if (dst->GetDesc().bindFlag & TEXTURE_BIND_UNORDERED_ACCESS && dst->GetDesc().format == RENDER_FORMAT_R32G32_FLOAT)
		{
			bfDst = dst;
			bfDstMipLevel = dstMipLevel;
			bfDstArrayOffset = dstArrayOffset;
		}
		else
		{
			bfDstRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc });
			bfDst = bfDstRef->Get()->Cast<Texture>();
		}


		std::map<String, String> macros;

		macros["FFT_2D"] = "";
		if (bInverse)
		{
			macros["FFT_INVERSE"] = "";
			if(bIFFTScale)
				macros["FFT_INVERSE_SCALE"] = "";
		}
		static int fftGroupSize = 64;
		macros["FFT_GROUP_SIZE"] = std::to_string(fftGroupSize);

		auto fftXCS = Shader::FindOrCreate<FFTRadix8_2D_XCS>(macros);
		auto fftXFinalCS = Shader::FindOrCreate<FFTRadix8_2D_X_FinalCS>(macros);
		auto fftYCS = Shader::FindOrCreate<FFTRadix8_2D_YCS>(macros);
		auto fftYFinalCS = Shader::FindOrCreate<FFTRadix8_2D_Y_FinalCS>(macros);

		auto ifftScalePS = Shader::FindOrCreate<IFFTScalePS>();

		float4 dataSize = float4((float)mipSize.x(), (float)mipSize.y(), 1.0f / (float)mipSize.x(), 1.0f / (float)mipSize.y());

		auto rc = Global::GetRenderEngine()->GetRenderContext();

		//FFT X
		{
			uint32_t numGroups = texDesc.width / fftGroupSize / 8;

			uint32_t threadCount = texDesc.width / 8;
			uint32_t ostride = threadCount;

			uint32_t istride = threadCount;
			float phaseBase = -PI2 / texDesc.width;
			if (bInverse)
				phaseBase *= -1.0f;
			while (istride > 0)
			{
				if (istride > 1)
				{
					fftXCS->SetScalar("dataSize", dataSize);
					fftXCS->SetScalar("threadCount", threadCount);
					fftXCS->SetScalar("ostride", ostride);
					fftXCS->SetScalar("istride", istride);
					fftXCS->SetScalar("phaseBase", phaseBase);

					fftXCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
					fftXCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

					fftXCS->Flush();

					rc->Compute(numGroups, texDesc.height, 1);
				}
				else
				{
					fftXFinalCS->SetScalar("dataSize", dataSize);
					fftXFinalCS->SetScalar("threadCount", threadCount);
					fftXFinalCS->SetScalar("ostride", ostride);
					fftXFinalCS->SetScalar("istride", istride);

					fftXFinalCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
					fftXFinalCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

					fftXFinalCS->Flush();

					rc->Compute(numGroups, texDesc.height, 1);
				}

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);

				istride /= 8;
				phaseBase *= 8.0f;
			}

		}

		//FFT Y
		{
			uint32_t numGroups = texDesc.height / fftGroupSize / 8;

			uint32_t threadCount = texDesc.height / 8;
			uint32_t ostride = threadCount;

			uint32_t istride = threadCount;
			float phaseBase = -PI2 / texDesc.height;
			if (bInverse)
				phaseBase *= -1.0f;
			while (istride > 0)
			{
				if (istride > 1)
				{
					fftYCS->SetScalar("dataSize", dataSize);
					fftYCS->SetScalar("threadCount", threadCount);
					fftYCS->SetScalar("ostride", ostride);
					fftYCS->SetScalar("istride", istride);
					fftYCS->SetScalar("phaseBase", phaseBase);

					fftYCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
					fftYCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

					fftYCS->Flush();

					rc->Compute(numGroups, texDesc.width, 1);
				}
				else
				{
					fftYFinalCS->SetScalar("dataSize", dataSize);
					fftYFinalCS->SetScalar("threadCount", threadCount);
					fftYFinalCS->SetScalar("ostride", ostride);
					fftYFinalCS->SetScalar("istride", istride);

					fftYFinalCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
					fftYFinalCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

					fftYFinalCS->Flush();

					rc->Compute(numGroups, texDesc.width, 1);
				}

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);

				istride /= 8;
				phaseBase *= 8.0f;
			}

		}

		rc->ResetShader(SHADER_CS);

		//Clear
		if (bfSrc != dst) //dst is result
		{
			bfSrc->CopyTo(dst, dstMipLevel, dstArrayOffset, 0, 0, 0, 0, 0);
		}
	}
コード例 #4
0
ファイル: FFT.cpp プロジェクト: BenKZSSS/ToyGE
	void FFT::FFT2DRadix2(
		const Ptr<Texture> & src,
		int32_t srcMipLevel,
		int32_t srcArrayOffset,
		const Ptr<Texture> & dst,
		int32_t dstMipLevel,
		int32_t dstArrayOffset,
		bool bInverse,
		bool bIFFTScale)
	{
		auto mipSize = src->GetMipSize(srcMipLevel);

		TextureDesc texDesc;
		texDesc.width = mipSize.x();
		texDesc.height = mipSize.y();
		texDesc.depth = 1;
		texDesc.bindFlag = TEXTURE_BIND_SHADER_RESOURCE | TEXTURE_BIND_RENDER_TARGET | TEXTURE_BIND_UNORDERED_ACCESS;
		texDesc.cpuAccess = 0;
		texDesc.format = RENDER_FORMAT_R32G32_FLOAT;
		texDesc.mipLevels = 1;
		texDesc.arraySize = 1;
		texDesc.bCube = false;
		texDesc.sampleCount = 1;
		texDesc.sampleQuality = 0;

		PooledTextureRef bfSrcRef;
		Ptr<Texture> bfSrc;
		int32_t bfSrcMipLevel = 0;
		int32_t bfSrcArrayOffset = 0;
		/*if (!bInverse)
		{
			bfSrcRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc });
			bfSrc = bfSrcRef->Get()->Cast<Texture>();
			FFT::FFTSetup(src, srcMipLevel, srcArrayOffset, bfSrc, 0, 0);
		}
		else*/
		{
			bfSrc = src;
			bfSrcMipLevel = srcMipLevel;
			bfSrcArrayOffset = srcArrayOffset;
		}

		PooledTextureRef bfDstRef;
		Ptr<Texture> bfDst;
		int32_t bfDstMipLevel = 0;
		int32_t bfDstArrayOffset = 0;
		if (dst->GetDesc().bindFlag & TEXTURE_BIND_UNORDERED_ACCESS && dst->GetDesc().format == RENDER_FORMAT_R32G32_FLOAT)
		{
			bfDst = dst;
			bfDstMipLevel = dstMipLevel;
			bfDstArrayOffset = dstArrayOffset;
		}
		else
		{
			bfDstRef = TexturePool::Instance().FindFree({ TEXTURE_2D, texDesc });
			bfDst = bfDstRef->Get()->Cast<Texture>();
		}

		
		std::map<String, String> macros;

		macros["FFT_2D"] = "";
		if (bInverse)
		{
			macros["FFT_INVERSE"] = "";
			if (bIFFTScale)
				macros["FFT_INVERSE_SCALE"] = "";
		}
		static int fftGroupSize = 64;
		macros["FFT_GROUP_SIZE"] = std::to_string(fftGroupSize);

		auto fftXCS = Shader::FindOrCreate<FFTRadix2_2D_XCS>(macros);
		auto fftYCS = Shader::FindOrCreate<FFTRadix2_2D_YCS>(macros);

		auto ifftScalePS = Shader::FindOrCreate<IFFTScalePS>();

		float4 dataSize = float4((float)mipSize.x(), (float)mipSize.y(), 1.0f / (float)mipSize.x(), 1.0f / (float)mipSize.y());

		auto rc = Global::GetRenderEngine()->GetRenderContext();

		//Butterfly X
		{
			uint32_t numGroups = std::max<uint32_t>(1, texDesc.width / fftGroupSize / 2);

			uint32_t bfLen = 2;
			while (bfLen <= static_cast<uint32_t>(texDesc.width))
			{
				fftXCS->SetScalar("dataSize", dataSize);
				fftXCS->SetScalar("butterflyLength", bfLen);

				fftXCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
				fftXCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

				fftXCS->Flush();

				rc->Compute(numGroups, texDesc.height, 1);

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);

				bfLen = bfLen << 1;
			}
			rc->ResetShader(SHADER_CS);

			if (bInverse && bIFFTScale)
			{
				float ifftScale = 1.0f / (float)texDesc.width;
				ifftScalePS->SetScalar("ifftScale", ifftScale);
				ifftScalePS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
				ifftScalePS->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get());
				ifftScalePS->Flush();

				DrawQuad({ bfDst->GetRenderTargetView(dstMipLevel, dstArrayOffset, 1) });

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);
			}
		}

		//Butterfly Y
		{
			uint32_t numGroups = std::max<uint32_t>(1, texDesc.height / fftGroupSize / 2);

			uint32_t bfLen = 2;
			while (bfLen <= static_cast<uint32_t>(texDesc.height))
			{
				fftYCS->SetScalar("dataSize", dataSize);
				fftYCS->SetScalar("butterflyLength", bfLen);

				fftYCS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
				fftYCS->SetUAV("dstTex", bfDst->GetUnorderedAccessView(bfDstMipLevel, bfDstArrayOffset, 1));

				fftYCS->Flush();

				rc->Compute(numGroups, texDesc.width, 1);

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);

				bfLen = bfLen << 1;
			}
			rc->ResetShader(SHADER_CS);

			if (bInverse && bIFFTScale)
			{
				float ifftScale = 1.0f / texDesc.height;
				ifftScalePS->SetScalar("ifftScale", ifftScale);
				ifftScalePS->SetSRV("srcTex", bfSrc->GetShaderResourceView(bfSrcMipLevel, 1, bfSrcArrayOffset, 1));
				ifftScalePS->SetSampler("pointSampler", SamplerTemplate<FILTER_MIN_MAG_MIP_POINT>::Get());
				ifftScalePS->Flush();

				DrawQuad({ bfDst->GetRenderTargetView(dstMipLevel, dstArrayOffset, 1) });

				std::swap(bfSrc, bfDst);
				std::swap(bfSrcMipLevel, bfDstMipLevel);
				std::swap(bfSrcArrayOffset, bfDstArrayOffset);
			}
		}

		//Clear
		if (bfSrc != dst) //dst is result
		{
			bfSrc->CopyTo(dst, dstMipLevel, dstArrayOffset, 0, 0, 0, 0, 0);
		}
	}
コード例 #5
0
ファイル: usp.c プロジェクト: aosp/gfx_linux_ddk
/*****************************************************************************
 Name:		PVRUniPatchFinaliseShader

 Purpose:	Generates a HW-executable shader from a patchable USP shader.

 Inputs:	pvContext	- The current USP execution context
			pvShader	- The runtime-patcheable shader for which HW code
						  should be generated
			
 Outputs:	none

 Returns:	Pointer to a structure containing the HW instructions and 
			associated meta-data needed by a driver.
*****************************************************************************/
EXPORT_FOR_TEST_ONLY PUSP_HW_SHADER IMG_CALLCONV PVRUniPatchFinaliseShader(
														IMG_PVOID pvContext,
													  	IMG_PVOID pvShader)
{
	PUSP_CONTEXT	psContext;
	PUSP_SHADER		psShader;
	PUSP_HW_SHADER	psHWShader;
	IMG_UINT32		uSmpIdx;

	psContext	= (PUSP_CONTEXT)pvContext;
	psShader	= (PUSP_SHADER)pvShader;
	psHWShader	= IMG_NULL;

	/*
		Initialize all texture control words as not set
	*/
	for(uSmpIdx=0; uSmpIdx<psShader->uTotalSmpTexCtrWrds; uSmpIdx++)
	{
		IMG_UINT32 uPlnIdx;

		psShader->psTexCtrWrds[uSmpIdx].bUsed = IMG_FALSE;

		for (uPlnIdx=0; uPlnIdx<USP_TEXFORM_MAX_PLANE_COUNT; uPlnIdx++)
		{
			psShader->psTexCtrWrds[uSmpIdx].auWords[uPlnIdx] = (IMG_UINT32)-1;
			
			psShader->psTexCtrWrds[uSmpIdx].auTexWrdIdx[uPlnIdx] = (IMG_UINT16)-1;

			psShader->psTexCtrWrds[uSmpIdx].abExtFmt[uPlnIdx] = IMG_FALSE;

			psShader->psTexCtrWrds[uSmpIdx].abReplicate[uPlnIdx] = IMG_FALSE;

			psShader->psTexCtrWrds[uSmpIdx].aeUnPackFmts[uPlnIdx] = USP_REGFMT_UNKNOWN;
			
			psShader->psTexCtrWrds[uSmpIdx].auSwizzle[uPlnIdx] = (IMG_UINT32)-1;

			psShader->psTexCtrWrds[uSmpIdx].abMinPack[uPlnIdx] = IMG_FALSE;

			psShader->psTexCtrWrds[uSmpIdx].auTagSize[uPlnIdx] = 0;
		}
	}

	/*
		Add texture formats to USP sample blocks
	*/
	if	(!HandleUSPSampleTextureFormat(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error adding sample data to shader for finalisation\n"));
		return IMG_NULL;
	}

	/*
		Insert preamble code as required
	*/
	if	(!FinaliseShaderPreamble(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising shader preamble code\n"));
		return IMG_NULL;
	}

	/*
		Finalise the location of results and temporary data used for samples
	*/
	if	(!FinaliseResultLocations(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising result locations\n"));
		return IMG_NULL;
	}

	/*
		Generate code for samples
	*/
	if	(!FinaliseSamples(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising texture-samples\n"));
		return IMG_NULL;
	}

	/*
	  Generate code for texture writes
	*/
	if  (!FinaliseTextureWriteList(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising texture write list\n"));
		return IMG_NULL;
	}

	/*
		Finalise the overall register counts now that we know how many
		are required by samples
	*/
	if	(!FinaliseRegCounts(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising temp/pa counts\n"));
		return IMG_NULL;
	}

	/*
		Finalise the shader results
	*/
	if	(!FinaliseResults(psContext, psShader))
	{
		USP_DBGPRINT(("PVRUniPatchFinaliseShader: Error finalising results\n"));
		return IMG_NULL;
	}

	/*
		Finalise the instructions within all blocks
	*/
	if	(!FinaliseInstructions(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising instructions\n"));
		return IMG_NULL;
	}

	/*
		Fixup branch destinations now that we have generated all instructions
	*/
	if	(!FinaliseBranches(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error finalising branch destinations\n"));
		return IMG_NULL;
	}
	
	/*
		Remove excess trailing iterations that may have been added by the USC to
		stop the USP overwriting shader results when in PA registers
	*/
	if	(!RemoveDummyIterations(psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error removing excess PS input data\n" ));
		return IMG_NULL;
	}

	/*
		Generate the HW structure encapsulating the finalised shader code
	*/
	psHWShader = CreateHWShader(psContext, psShader);
	if	(!psHWShader)
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Failed to create HW shader\n"));
		return IMG_NULL;
	}

	/*
		Reset any data that is altered during finalisation
	*/
	if	(!ResetShader(psContext, psShader))
	{
		USP_DBGPRINT(( "PVRUniPatchFinaliseShader: Error resetting shader for finalisation\n"));
		psContext->pfnFree(psHWShader);
		return IMG_NULL;
	}

	return psHWShader;
}
コード例 #6
0
	void ImageBasedLensFlare::LensBlur(const Ptr<Texture> & setupTex, const Ptr<Texture> & target)
	{
		int32_t tileSize = 9;

		//Extract Sprite Points
		int32_t extractWidth = (setupTex->GetDesc().width + tileSize - 1) / tileSize;
		int32_t extractHeight = (setupTex->GetDesc().height + tileSize - 1) / tileSize;

		RenderBufferDesc spPointsBufDesc;
		spPointsBufDesc.bindFlag = BUFFER_BIND_SHADER_RESOURCE | BUFFER_BIND_UNORDERED_ACCESS;
		spPointsBufDesc.elementSize = sizeof(float2) + sizeof(float3);
		spPointsBufDesc.numElements = extractWidth * extractHeight;
		spPointsBufDesc.cpuAccess = 0;
		spPointsBufDesc.bStructured = true;

		auto spPointsBufRef = BufferPool::Instance().FindFree(spPointsBufDesc);
		auto spPointsBuf = spPointsBufRef->Get()->Cast<RenderBuffer>();

		{
			auto ps = Shader::FindOrCreate<ExtractSpritePointsPS>();

			ps->SetScalar("spriteThreshold", _spriteThreshold);
			ps->SetSRV("setupTex", setupTex->GetShaderResourceView());
			ps->SetUAV("spPointsBuf", spPointsBuf->GetUnorderedAccessView(0, 0, RENDER_FORMAT_UNKNOWN, BUFFER_UAV_APPEND));
			ps->Flush();

			DrawQuad({}, 0.0f, 0.0f, (float)extractWidth, (float)extractHeight);
		}

		//Render Sprites
		if (!_indirectAgsBuf)
		{
			RenderBufferDesc indirectArgsBufDesc;
			indirectArgsBufDesc.bindFlag = BUFFER_BIND_INDIRECT_ARGS;
			indirectArgsBufDesc.elementSize = 16;
			indirectArgsBufDesc.numElements = 1;
			indirectArgsBufDesc.cpuAccess = 0;
			indirectArgsBufDesc.bStructured = false;

			uint32_t initData[] = { 0, 1, 0, 0 };

			_indirectAgsBuf = Global::GetRenderEngine()->GetRenderFactory()->CreateBuffer();
			_indirectAgsBuf->SetDesc(indirectArgsBufDesc);
			_indirectAgsBuf->Init(initData);
		}

		spPointsBuf->CopyStructureCountTo(_indirectAgsBuf, 0, 0, spPointsBuf->GetDesc().numElements, RENDER_FORMAT_UNKNOWN, BUFFER_UAV_APPEND);

		{
			auto vs = Shader::FindOrCreate<LensBlurVS>();
			auto gs = Shader::FindOrCreate<LensBlurGS>();
			auto ps = Shader::FindOrCreate<LensBlurPS>();

			vs->SetScalar("texSize", target->GetTexSize());
			gs->SetScalar("texSize", target->GetTexSize());

			gs->SetScalar("flareIntensity", _flareIntensity);

			vs->SetSRV("spPointsRenderBuf", spPointsBuf->GetShaderResourceView(0, 0, RENDER_FORMAT_UNKNOWN));

			auto lensTexAsset = Asset::Find<TextureAsset>("Textures/Bokeh_Circle.dds");
			if (!lensTexAsset->IsInit())
				lensTexAsset->Init();
			auto lensTex = lensTexAsset->GetTexture();
			ps->SetSRV("lensTex", lensTex->GetShaderResourceView());

			ps->SetSampler("linearSampler", SamplerTemplate<>::Get());

			vs->Flush();
			gs->Flush();
			ps->Flush();

			auto rc = Global::GetRenderEngine()->GetRenderContext();

			rc->SetVertexBuffer({});
			rc->SetIndexBuffer(nullptr);
			rc->SetPrimitiveTopology(PRIMITIVE_TOPOLOGY_POINTLIST);

			rc->SetViewport(GetTextureQuadViewport(target));

			rc->SetRenderTargets({ target->GetRenderTargetView(0, 0, 1) });
			rc->SetDepthStencil(nullptr);
			rc->SetDepthStencilState(DepthStencilStateTemplate<false>::Get());

			rc->SetBlendState(BlendStateTemplate<false, false, true, BLEND_PARAM_SRC_ALPHA, BLEND_PARAM_ONE, BLEND_OP_ADD>::Get());

			rc->DrawInstancedIndirect(_indirectAgsBuf, 0);

			rc->ResetShader(SHADER_GS);
			rc->SetBlendState(nullptr);
		}
	}