目录
1. F:\UnrealEngine-424\Engine\Source\Runtime\Renderer\Private\PostProcess\SceneRenderTargets.cpp
5. 只考虑Windows平台,F:\UnrealEngine-424\Engine\Source\Runtime\Windows\D3D11RHI\Private\D3D11Texture.cpp
5.4 FindShaderResourceDXGIFormat(BaseTextureFormat, bSRGB) 在D3D11RHIPrimitive.h
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. 也在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. 在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. 只考虑Windows平台,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 在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;
}