FUnorderedAccessViewRHIRef FD3D11DynamicRHI::RHICreateUnorderedAccessView(FTextureRHIParamRef TextureRHI) { FD3D11TextureBase* Texture = GetD3D11TextureFromRHITexture(TextureRHI); D3D11_UNORDERED_ACCESS_VIEW_DESC UAVDesc; if (TextureRHI->GetTexture3D() != NULL) { FD3D11Texture3D* Texture3D = (FD3D11Texture3D*)Texture; UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; UAVDesc.Texture3D.MipSlice = 0; UAVDesc.Texture3D.FirstWSlice = 0; UAVDesc.Texture3D.WSize = Texture3D->GetSizeZ(); } else { UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; UAVDesc.Texture2D.MipSlice = 0; } UAVDesc.Format = FindShaderResourceDXGIFormat((DXGI_FORMAT)GPixelFormats[TextureRHI->GetFormat()].PlatformFormat, false); TRefCountPtr<ID3D11UnorderedAccessView> UnorderedAccessView; VERIFYD3D11RESULT(Direct3DDevice->CreateUnorderedAccessView(Texture->GetResource(),&UAVDesc,(ID3D11UnorderedAccessView**)UnorderedAccessView.GetInitReference())); return new FD3D11UnorderedAccessView(UnorderedAccessView,Texture); }
FUnorderedAccessViewRHIRef FD3D12DynamicRHI::RHICreateUnorderedAccessView(FTextureRHIParamRef TextureRHI, uint32 MipLevel) { FD3D12TextureBase* Texture = GetD3D11TextureFromRHITexture(TextureRHI); D3D12_UNORDERED_ACCESS_VIEW_DESC UAVDesc ={}; const DXGI_FORMAT PlatformResourceFormat = (DXGI_FORMAT)GPixelFormats[TextureRHI->GetFormat()].PlatformFormat; UAVDesc.Format = FindShaderResourceDXGIFormat(PlatformResourceFormat, false); if (TextureRHI->GetTexture3D() != NULL) { FD3D12Texture3D* Texture3D = (FD3D12Texture3D*)Texture; UAVDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; UAVDesc.Texture3D.MipSlice = MipLevel; UAVDesc.Texture3D.FirstWSlice = 0; UAVDesc.Texture3D.WSize = Texture3D->GetSizeZ() >> MipLevel; }
FShaderResourceViewRHIRef FD3D11DynamicRHI::RHICreateShaderResourceView(FVertexBufferRHIParamRef VertexBufferRHI, uint32 Stride, uint8 Format) { DYNAMIC_CAST_D3D11RESOURCE(VertexBuffer,VertexBuffer); check(VertexBuffer); check(VertexBuffer->Resource); D3D11_BUFFER_DESC BufferDesc; VertexBuffer->Resource->GetDesc(&BufferDesc); // Create a Shader Resource View D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; FMemory::Memzero(SRVDesc); SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; SRVDesc.Buffer.FirstElement = 0; SRVDesc.Format = FindShaderResourceDXGIFormat((DXGI_FORMAT)GPixelFormats[Format].PlatformFormat,false); SRVDesc.Buffer.NumElements = BufferDesc.ByteWidth / Stride; TRefCountPtr<ID3D11ShaderResourceView> ShaderResourceView; HRESULT hr = Direct3DDevice->CreateShaderResourceView(VertexBuffer->Resource, &SRVDesc, (ID3D11ShaderResourceView**)ShaderResourceView.GetInitReference()); if (FAILED(hr)) { if (hr == E_OUTOFMEMORY) { // There appears to be a driver bug that causes SRV creation to fail with an OOM error and then succeed on the next call. hr = Direct3DDevice->CreateShaderResourceView(VertexBuffer->Resource, &SRVDesc, (ID3D11ShaderResourceView**)ShaderResourceView.GetInitReference()); } if (FAILED(hr)) { UE_LOG(LogD3D11RHI,Error,TEXT("Failed to create shader resource view for vertex buffer: ByteWidth=%d NumElements=%d"),BufferDesc.ByteWidth,BufferDesc.ByteWidth / Stride); VerifyD3D11Result(hr,"Direct3DDevice->CreateShaderResourceView",__FILE__,__LINE__,Direct3DDevice); } } return new FD3D11ShaderResourceView(ShaderResourceView,VertexBuffer); }
static FD3D11Texture2D* D3D11CreateTexture2DAlias( FD3D11DynamicRHI* InD3D11RHI, ID3D11Texture2D* InResource, ID3D11ShaderResourceView* InShaderResourceView, uint32 InSizeX, uint32 InSizeY, uint32 InSizeZ, uint32 InNumMips, uint32 InNumSamples, EPixelFormat InFormat, uint32 InFlags) { const bool bSRGB = (InFlags & TexCreate_SRGB) != 0; const DXGI_FORMAT PlatformResourceFormat = (DXGI_FORMAT)GPixelFormats[InFormat].PlatformFormat; const DXGI_FORMAT PlatformShaderResourceFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); const DXGI_FORMAT PlatformRenderTargetFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); D3D11_RTV_DIMENSION RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; if (InNumSamples > 1) { RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } TArray<TRefCountPtr<ID3D11RenderTargetView> > RenderTargetViews; if (InFlags & TexCreate_RenderTargetable) { // Create a render target view for each mip for (uint32 MipIndex = 0; MipIndex < InNumMips; MipIndex++) { check(!(InFlags & TexCreate_TargetArraySlicesIndependently)); // not supported D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; FMemory::Memzero(&RTVDesc, sizeof(RTVDesc)); RTVDesc.Format = PlatformRenderTargetFormat; RTVDesc.ViewDimension = RenderTargetViewDimension; RTVDesc.Texture2D.MipSlice = MipIndex; TRefCountPtr<ID3D11RenderTargetView> RenderTargetView; VERIFYD3D11RESULT(InD3D11RHI->GetDevice()->CreateRenderTargetView(InResource, &RTVDesc, RenderTargetView.GetInitReference())); RenderTargetViews.Add(RenderTargetView); } } TRefCountPtr<ID3D11ShaderResourceView> ShaderResourceView; // Create a shader resource view for the texture. if (!InShaderResourceView && (InFlags & TexCreate_ShaderResource)) { D3D11_SRV_DIMENSION ShaderResourceViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; SRVDesc.Format = PlatformShaderResourceFormat; SRVDesc.ViewDimension = ShaderResourceViewDimension; SRVDesc.Texture2D.MostDetailedMip = 0; SRVDesc.Texture2D.MipLevels = InNumMips; VERIFYD3D11RESULT(InD3D11RHI->GetDevice()->CreateShaderResourceView(InResource, &SRVDesc, ShaderResourceView.GetInitReference())); check(IsValidRef(ShaderResourceView)); } else { ShaderResourceView = InShaderResourceView; } FD3D11Texture2D* NewTexture = new FD3D11Texture2D( InD3D11RHI, InResource, ShaderResourceView, false, 1, RenderTargetViews, /*DepthStencilViews=*/ NULL, InSizeX, InSizeY, InSizeZ, InNumMips, InNumSamples, InFormat, /*bInCubemap=*/ false, InFlags, /*bPooledTexture=*/ false ); return NewTexture; }
FD3D11Texture2DSet* FD3D11Texture2DSet::D3D11CreateTexture2DSet( FD3D11DynamicRHI* InD3D11RHI, ovrSwapTextureSet* InTextureSet, const D3D11_TEXTURE2D_DESC& InDsDesc, EPixelFormat InFormat, uint32 InFlags ) { check(InTextureSet); TArray<TRefCountPtr<ID3D11RenderTargetView> > RenderTargetViews; FD3D11Texture2DSet* NewTextureSet = new FD3D11Texture2DSet( InD3D11RHI, nullptr, nullptr, false, 1, RenderTargetViews, /*DepthStencilViews=*/ NULL, InDsDesc.Width, InDsDesc.Height, 0, InDsDesc.MipLevels, InDsDesc.SampleDesc.Count, InFormat, /*bInCubemap=*/ false, InFlags, /*bPooledTexture=*/ false ); const uint32 TexCount = InTextureSet->TextureCount; const bool bSRGB = (InFlags & TexCreate_SRGB) != 0; const DXGI_FORMAT PlatformResourceFormat = (DXGI_FORMAT)GPixelFormats[InFormat].PlatformFormat; const DXGI_FORMAT PlatformShaderResourceFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); const DXGI_FORMAT PlatformRenderTargetFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); D3D11_RTV_DIMENSION RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; if (InDsDesc.SampleDesc.Count > 1) { RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } for (uint32 i = 0; i < TexCount; ++i) { ovrD3D11Texture D3DTex; D3DTex.Texture = InTextureSet->Textures[i]; TArray<TRefCountPtr<ID3D11RenderTargetView> > RenderTargetViews; if (InFlags & TexCreate_RenderTargetable) { // Create a render target view for each mip for (uint32 MipIndex = 0; MipIndex < InDsDesc.MipLevels; MipIndex++) { check(!(InFlags & TexCreate_TargetArraySlicesIndependently)); // not supported D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; FMemory::Memzero(&RTVDesc, sizeof(RTVDesc)); RTVDesc.Format = PlatformRenderTargetFormat; RTVDesc.ViewDimension = RenderTargetViewDimension; RTVDesc.Texture2D.MipSlice = MipIndex; TRefCountPtr<ID3D11RenderTargetView> RenderTargetView; VERIFYD3D11RESULT(InD3D11RHI->GetDevice()->CreateRenderTargetView(D3DTex.D3D11.pTexture, &RTVDesc, RenderTargetView.GetInitReference())); RenderTargetViews.Add(RenderTargetView); } } TRefCountPtr<ID3D11ShaderResourceView> ShaderResourceView = D3DTex.D3D11.pSRView; // Create a shader resource view for the texture. if (!ShaderResourceView && (InFlags & TexCreate_ShaderResource)) { D3D11_SRV_DIMENSION ShaderResourceViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; SRVDesc.Format = PlatformShaderResourceFormat; SRVDesc.ViewDimension = ShaderResourceViewDimension; SRVDesc.Texture2D.MostDetailedMip = 0; SRVDesc.Texture2D.MipLevels = InDsDesc.MipLevels; VERIFYD3D11RESULT(InD3D11RHI->GetDevice()->CreateShaderResourceView(D3DTex.D3D11.pTexture, &SRVDesc, ShaderResourceView.GetInitReference())); check(IsValidRef(ShaderResourceView)); } NewTextureSet->AddTexture(D3DTex.D3D11.pTexture, ShaderResourceView, &RenderTargetViews); } NewTextureSet->TextureSet = InTextureSet; NewTextureSet->InitWithCurrentElement(); return NewTextureSet; }
FD3D11Texture2DSet* FD3D11Texture2DSet::D3D11CreateTexture2DSet( FD3D11DynamicRHI* InD3D11RHI, const FOvrSessionSharedPtr& InOvrSession, ovrTextureSwapChain InTextureSet, const D3D11_TEXTURE2D_DESC& InDsDesc, EPixelFormat InFormat, uint32 InFlags ) { FOvrSessionShared::AutoSession OvrSession(InOvrSession); check(InTextureSet); TArray<TRefCountPtr<ID3D11RenderTargetView> > TextureSetRenderTargetViews; FD3D11Texture2DSet* NewTextureSet = new FD3D11Texture2DSet( InD3D11RHI, nullptr, nullptr, false, 1, TextureSetRenderTargetViews, /*DepthStencilViews=*/ NULL, InDsDesc.Width, InDsDesc.Height, 0, InDsDesc.MipLevels, InDsDesc.SampleDesc.Count, InFormat, /*bInCubemap=*/ false, InFlags, /*bPooledTexture=*/ false ); int TexCount; ovr_GetTextureSwapChainLength(OvrSession, InTextureSet, &TexCount); const bool bSRGB = (InFlags & TexCreate_SRGB) != 0; const DXGI_FORMAT PlatformResourceFormat = (DXGI_FORMAT)GPixelFormats[InFormat].PlatformFormat; const DXGI_FORMAT PlatformShaderResourceFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); const DXGI_FORMAT PlatformRenderTargetFormat = FindShaderResourceDXGIFormat(PlatformResourceFormat, bSRGB); D3D11_RTV_DIMENSION RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; if (InDsDesc.SampleDesc.Count > 1) { RenderTargetViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } for (int32 i = 0; i < TexCount; ++i) { TRefCountPtr<ID3D11Texture2D> pD3DTexture; ovrResult res = ovr_GetTextureSwapChainBufferDX(OvrSession, InTextureSet, i, IID_PPV_ARGS(pD3DTexture.GetInitReference())); if (!OVR_SUCCESS(res)) { UE_LOG(LogHMD, Error, TEXT("ovr_GetTextureSwapChainBufferDX failed, error = %d"), int(res)); return nullptr; } TArray<TRefCountPtr<ID3D11RenderTargetView> > RenderTargetViews; if (InFlags & TexCreate_RenderTargetable) { // Create a render target view for each mip for (uint32 MipIndex = 0; MipIndex < InDsDesc.MipLevels; MipIndex++) { check(!(InFlags & TexCreate_TargetArraySlicesIndependently)); // not supported D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; FMemory::Memzero(&RTVDesc, sizeof(RTVDesc)); RTVDesc.Format = PlatformRenderTargetFormat; RTVDesc.ViewDimension = RenderTargetViewDimension; RTVDesc.Texture2D.MipSlice = MipIndex; TRefCountPtr<ID3D11RenderTargetView> RenderTargetView; VERIFYD3D11RESULT_EX(InD3D11RHI->GetDevice()->CreateRenderTargetView(pD3DTexture, &RTVDesc, RenderTargetView.GetInitReference()), InD3D11RHI->GetDevice()); RenderTargetViews.Add(RenderTargetView); } } TRefCountPtr<ID3D11ShaderResourceView> ShaderResourceView; // Create a shader resource view for the texture. if (InFlags & TexCreate_ShaderResource) { D3D11_SRV_DIMENSION ShaderResourceViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; SRVDesc.Format = PlatformShaderResourceFormat; SRVDesc.ViewDimension = ShaderResourceViewDimension; SRVDesc.Texture2D.MostDetailedMip = 0; SRVDesc.Texture2D.MipLevels = InDsDesc.MipLevels; VERIFYD3D11RESULT_EX(InD3D11RHI->GetDevice()->CreateShaderResourceView(pD3DTexture, &SRVDesc, ShaderResourceView.GetInitReference()), InD3D11RHI->GetDevice()); check(IsValidRef(ShaderResourceView)); } NewTextureSet->AddTexture(pD3DTexture, ShaderResourceView, &RenderTargetViews); } if (InFlags & TexCreate_RenderTargetable) { NewTextureSet->SetCurrentGPUAccess(EResourceTransitionAccess::EWritable); } NewTextureSet->TextureSet = InTextureSet; NewTextureSet->InitWithCurrentElement(0); return NewTextureSet; }