CustomStencilSRV creation process

content

1. F:\UnrealEngine-424\Engine\Source\Runtime\Renderer\Private\PostProcess\SceneRenderTargets.cpp

2. RHICreateShaderResourceView() 在F:\UnrealEngine-424\Engine\Source\Runtime\RHI\Public\RHICommandList.h

3. Also in RHICommandList.h

4. In RHICommandList.cpp

5. Only consider Windows platform, F:\UnrealEngine-424\Engine\Source\Runtime\Windows\D3D11RHI\Private\D3D11Texture.cpp

5.1 D3D11.h

5.2 D3D11Resources.h

5.3 In D3D11Resources.h

5.4  FindShaderResourceDXGIFormat(BaseTextureFormat, bSRGB) 在D3D11RHIPrimitive.h

5.5 VERIFYD3D11RESULT_EX(Direct3DDevice->CreateShaderResourceView(Texture->GetResource(), &SRVDesc, (ID3D11ShaderResourceView**)ShaderResourceView.GetInitReference()), Direct3DDevice);


1. F:\UnrealEngine-424\Engine\Source\Runtime\Renderer\Private\PostProcess\SceneRenderTargets.cpp

IPooledRenderTarget* FSceneRenderTargets::RequestCustomDepth(FRHICommandListImmediate& RHICmdList, bool bPrimitives)
{
	int Value = CVarCustomDepth.GetValueOnRenderThread();
	const bool bCustomDepthPassWritingStencil = IsCustomDepthPassWritingStencil();
	const bool bMobilePath = (CurrentFeatureLevel <= ERHIFeatureLevel::ES3_1);

	if ((Value == 1 && bPrimitives) || Value == 2 || bCustomDepthPassWritingStencil)
	{
		bool bHasValidCustomDepth = (CustomDepth.IsValid() && BufferSize == CustomDepth->GetDesc().Extent && !GFastVRamConfig.bDirty);
		bool bHasValidCustomStencil;
		if (bMobilePath)
		{
			bHasValidCustomStencil = (MobileCustomStencil.IsValid() && BufferSize == MobileCustomStencil->GetDesc().Extent);
		}
		else
		{
			bHasValidCustomStencil = CustomStencilSRV.IsValid();
		}
						
		if (!(bHasValidCustomDepth && bHasValidCustomStencil))
		{
			// Skip depth decompression, custom depth doesn't benefit from it
			// Also disables fast clears, but typically only a small portion of custom depth is written to anyway
			uint32 CustomDepthFlags = TexCreate_NoFastClear;

			// Todo: Could check if writes stencil here and create min viable target
			FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(BufferSize, PF_DepthStencil, FClearValueBinding::DepthFar, CustomDepthFlags, TexCreate_DepthStencilTargetable | TexCreate_ShaderResource, false));
			Desc.Flags |= GFastVRamConfig.CustomDepth;
			GRenderTargetPool.FindFreeElement(RHICmdList, Desc, CustomDepth, TEXT("CustomDepth"), true, ERenderTargetTransience::NonTransient);
			
			if (bMobilePath)
			{
				FPooledRenderTargetDesc MobileCustomStencilDesc(FPooledRenderTargetDesc::Create2DDesc(BufferSize, PF_B8G8R8A8, FClearValueBinding::Transparent, TexCreate_None, TexCreate_RenderTargetable | TexCreate_ShaderResource, false));
				GRenderTargetPool.FindFreeElement(RHICmdList, MobileCustomStencilDesc, MobileCustomStencil, TEXT("MobileCustomStencil"));
			}
			else
			{
				//CustomStencilSRV = RHICreateShaderResourceView((FTexture2DRHIRef&)CustomDepth->GetRenderTargetItem().TargetableTexture, 0, 1, PF_X24_G8);
				CustomStencilSRV = RHICreateShaderResourceView((FTexture2DRHIRef&)CustomDepth->GetRenderTargetItem().TargetableTexture, 0, 1, PF_B8G8R8A8);
			}
		}
		return CustomDepth;
	}

	return 0;
}

2. RHICreateShaderResourceView() 在F:\UnrealEngine-424\Engine\Source\Runtime\RHI\Public\RHICommandList.h

FORCEINLINE FShaderResourceViewRHIRef RHICreateShaderResourceView(FRHITexture* Texture, uint8 MipLevel, uint8 NumMipLevels, uint8 Format)
{
	return FRHICommandListExecutor::GetImmediateCommandList().CreateShaderResourceView(Texture, MipLevel, NumMipLevels, Format);
}

3. Also in RHICommandList.h

	FORCEINLINE FShaderResourceViewRHIRef CreateShaderResourceView(FRHITexture* Texture, uint8 MipLevel, uint8 NumMipLevels, uint8 Format)
	{
		LLM_SCOPE(ELLMTag::RHIMisc);
		const FRHITextureSRVCreateInfo CreateInfo(MipLevel, NumMipLevels, Format);
		return GDynamicRHI->RHICreateShaderResourceView_RenderThread(*this, Texture, CreateInfo);
	}

4. In RHICommandList.cpp

FShaderResourceViewRHIRef FDynamicRHI::RHICreateShaderResourceView_RenderThread(class FRHICommandListImmediate& RHICmdList, FRHITexture* Texture, const FRHITextureSRVCreateInfo& CreateInfo)
{
	CSV_SCOPED_TIMING_STAT(RHITStalls, RHICreateShaderResourceView_RenderThread_Tex2D); // TODO - clean this up
	FScopedRHIThreadStaller StallRHIThread(RHICmdList);
	return GDynamicRHI->RHICreateShaderResourceView(Texture, CreateInfo);
}

5. Only consider Windows platform, F:\UnrealEngine-424\Engine\Source\Runtime\Windows\D3D11RHI\Private\D3D11Texture.cpp

FShaderResourceViewRHIRef FD3D11DynamicRHI::RHICreateShaderResourceView(FRHITexture* TextureRHI, const FRHITextureSRVCreateInfo& CreateInfo)
{
	FD3D11TextureBase* Texture = GetD3D11TextureFromRHITexture(TextureRHI);

	// Create a Shader Resource View
	D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
	DXGI_FORMAT BaseTextureFormat = DXGI_FORMAT_UNKNOWN;

	if (TextureRHI->GetTexture3D() != NULL)
	{
		FD3D11Texture3D* Texture3D = static_cast<FD3D11Texture3D*>(Texture);

		D3D11_TEXTURE3D_DESC TextureDesc;
		Texture3D->GetResource()->GetDesc(&TextureDesc);
		BaseTextureFormat = TextureDesc.Format;

		SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
		SRVDesc.Texture3D.MostDetailedMip = CreateInfo.MipLevel;
		SRVDesc.Texture3D.MipLevels = CreateInfo.NumMipLevels;
	}
	else if (TextureRHI->GetTexture2DArray() != NULL)
	{
		FD3D11Texture2DArray* Texture2DArray = static_cast<FD3D11Texture2DArray*>(Texture);

		D3D11_TEXTURE2D_DESC TextureDesc;
		Texture2DArray->GetResource()->GetDesc(&TextureDesc);
		BaseTextureFormat = TextureDesc.Format;

		SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
		SRVDesc.Texture2DArray.MostDetailedMip = CreateInfo.MipLevel;
		SRVDesc.Texture2DArray.MipLevels = CreateInfo.NumMipLevels;
		SRVDesc.Texture2DArray.FirstArraySlice = CreateInfo.FirstArraySlice;
		SRVDesc.Texture2DArray.ArraySize = (CreateInfo.NumArraySlices == 0 ? TextureDesc.ArraySize : CreateInfo.NumArraySlices);
	}
	else if (TextureRHI->GetTextureCube() != NULL)
	{
		FD3D11TextureCube* TextureCube = static_cast<FD3D11TextureCube*>(Texture);

		D3D11_TEXTURE2D_DESC TextureDesc;
		TextureCube->GetResource()->GetDesc(&TextureDesc);
		BaseTextureFormat = TextureDesc.Format;

		SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
		SRVDesc.TextureCube.MostDetailedMip = CreateInfo.MipLevel;
		SRVDesc.TextureCube.MipLevels = CreateInfo.NumMipLevels;
	}
	else
	{
		FD3D11Texture2D* Texture2D = static_cast<FD3D11Texture2D*>(Texture);

		D3D11_TEXTURE2D_DESC TextureDesc;
		Texture2D->GetResource()->GetDesc(&TextureDesc);
		BaseTextureFormat = TextureDesc.Format;

		if (TextureDesc.SampleDesc.Count > 1)
		{
			///MS textures can't have mips apparently, so nothing else to set.
			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
		}
		else
		{
			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			SRVDesc.Texture2D.MostDetailedMip = CreateInfo.MipLevel;
			SRVDesc.Texture2D.MipLevels = CreateInfo.NumMipLevels;
		}
	}

	// Allow input CreateInfo to override SRGB and/or format
	const bool bBaseSRGB = (TextureRHI->GetFlags() & TexCreate_SRGB) != 0;
	const bool bSRGB = (CreateInfo.SRGBOverride == SRGBO_ForceEnable) || (CreateInfo.SRGBOverride == SRGBO_Default && bBaseSRGB);
	if (CreateInfo.Format != PF_Unknown)
	{
		BaseTextureFormat = (DXGI_FORMAT)GPixelFormats[CreateInfo.Format].PlatformFormat;
	}
	SRVDesc.Format = FindShaderResourceDXGIFormat(BaseTextureFormat, bSRGB);

	// Create a Shader Resource View
	TRefCountPtr<ID3D11ShaderResourceView> ShaderResourceView;
	VERIFYD3D11RESULT_EX(Direct3DDevice->CreateShaderResourceView(Texture->GetResource(), &SRVDesc, (ID3D11ShaderResourceView**)ShaderResourceView.GetInitReference()), Direct3DDevice);

	return new FD3D11ShaderResourceView(ShaderResourceView, Texture);
}

5.1 D3D11.h

typedef struct D3D11_TEXTURE2D_DESC
    {
    UINT Width;
    UINT Height;
    UINT MipLevels;
    UINT ArraySize;
    DXGI_FORMAT Format;
    DXGI_SAMPLE_DESC SampleDesc;
    D3D11_USAGE Usage;
    UINT BindFlags;
    UINT CPUAccessFlags;
    UINT MiscFlags;
    } 	D3D11_TEXTURE2D_DESC;

5.2 D3D11Resources.h

/** Given a pointer to a RHI texture that was created by the D3D11 RHI, returns a pointer to the FD3D11TextureBase it encapsulates. */
FORCEINLINE FD3D11TextureBase* GetD3D11TextureFromRHITexture(FRHITexture* Texture)
{
	if (!Texture)
	{
		return NULL;
	}
	FD3D11TextureBase* Result((FD3D11TextureBase*)Texture->GetTextureBaseRHI());
	check(Result);
	return Result;
}

5.3 In D3D11Resources.h

/** Shader resource view class. */
class FD3D11ShaderResourceView : public FRHIShaderResourceView
{
public:
	
	TRefCountPtr<ID3D11ShaderResourceView> View;
	TRefCountPtr<FD3D11BaseShaderResource> Resource;

	FD3D11ShaderResourceView(ID3D11ShaderResourceView* InView,FD3D11BaseShaderResource* InResource)
	: View(InView)
	, Resource(InResource)
	{}

	void Rename(ID3D11ShaderResourceView* InView, FD3D11BaseShaderResource* InResource)
	{
		View = InView;
		Resource = InResource;
	}
};

5.4  FindShaderResourceDXGIFormat(BaseTextureFormat, bSRGB) 在D3D11RHIPrimitive.h

/** Find an appropriate DXGI format for the input format and SRGB setting. */
inline DXGI_FORMAT FindShaderResourceDXGIFormat(DXGI_FORMAT InFormat,bool bSRGB)
{
	if(bSRGB)
	{
		switch(InFormat)
		{
		case DXGI_FORMAT_B8G8R8A8_TYPELESS:    return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
		case DXGI_FORMAT_R8G8B8A8_TYPELESS:    return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
		case DXGI_FORMAT_BC1_TYPELESS:         return DXGI_FORMAT_BC1_UNORM_SRGB;
		case DXGI_FORMAT_BC2_TYPELESS:         return DXGI_FORMAT_BC2_UNORM_SRGB;
		case DXGI_FORMAT_BC3_TYPELESS:         return DXGI_FORMAT_BC3_UNORM_SRGB;
		case DXGI_FORMAT_BC7_TYPELESS:         return DXGI_FORMAT_BC7_UNORM_SRGB;
		};
	}
	else
	{
		switch(InFormat)
		{
		case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM;
		case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UNORM;
		case DXGI_FORMAT_BC1_TYPELESS:      return DXGI_FORMAT_BC1_UNORM;
		case DXGI_FORMAT_BC2_TYPELESS:      return DXGI_FORMAT_BC2_UNORM;
		case DXGI_FORMAT_BC3_TYPELESS:      return DXGI_FORMAT_BC3_UNORM;
		case DXGI_FORMAT_BC7_TYPELESS:      return DXGI_FORMAT_BC7_UNORM;
		};
	}
	switch(InFormat)
	{
		case DXGI_FORMAT_R24G8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
		case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_FLOAT;
		case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UNORM;
		// Changing Depth Buffers to 32 bit on Dingo as D24S8 is actually implemented as a 32 bit buffer in the hardware
		case DXGI_FORMAT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; 
	}
	return InFormat;
}

5.5 VERIFYD3D11RESULT_EX(Direct3DDevice->CreateShaderResourceView(Texture->GetResource(), &SRVDesc, (ID3D11ShaderResourceView**)ShaderResourceView.GetInitReference()), Direct3DDevice);

Guess you like

Origin blog.csdn.net/sh15285118586/article/details/117235804#comments_16814827