FBlendStateRHIRef FD3D11DynamicRHI::RHICreateBlendState(const FBlendStateInitializerRHI& Initializer) { D3D11_BLEND_DESC BlendDesc; FMemory::Memzero(&BlendDesc,sizeof(D3D11_BLEND_DESC)); BlendDesc.AlphaToCoverageEnable = false; BlendDesc.IndependentBlendEnable = Initializer.bUseIndependentRenderTargetBlendStates; static_assert(MaxSimultaneousRenderTargets <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, "Too many MRTs."); for(uint32 RenderTargetIndex = 0;RenderTargetIndex < MaxSimultaneousRenderTargets;++RenderTargetIndex) { const FBlendStateInitializerRHI::FRenderTarget& RenderTargetInitializer = Initializer.RenderTargets[RenderTargetIndex]; D3D11_RENDER_TARGET_BLEND_DESC& RenderTarget = BlendDesc.RenderTarget[RenderTargetIndex]; RenderTarget.BlendEnable = RenderTargetInitializer.ColorBlendOp != BO_Add || RenderTargetInitializer.ColorDestBlend != BF_Zero || RenderTargetInitializer.ColorSrcBlend != BF_One || RenderTargetInitializer.AlphaBlendOp != BO_Add || RenderTargetInitializer.AlphaDestBlend != BF_Zero || RenderTargetInitializer.AlphaSrcBlend != BF_One; RenderTarget.BlendOp = TranslateBlendOp(RenderTargetInitializer.ColorBlendOp); RenderTarget.SrcBlend = TranslateBlendFactor(RenderTargetInitializer.ColorSrcBlend); RenderTarget.DestBlend = TranslateBlendFactor(RenderTargetInitializer.ColorDestBlend); RenderTarget.BlendOpAlpha = TranslateBlendOp(RenderTargetInitializer.AlphaBlendOp); RenderTarget.SrcBlendAlpha = TranslateBlendFactor(RenderTargetInitializer.AlphaSrcBlend); RenderTarget.DestBlendAlpha = TranslateBlendFactor(RenderTargetInitializer.AlphaDestBlend); RenderTarget.RenderTargetWriteMask = ((RenderTargetInitializer.ColorWriteMask & CW_RED) ? D3D11_COLOR_WRITE_ENABLE_RED : 0) | ((RenderTargetInitializer.ColorWriteMask & CW_GREEN) ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0) | ((RenderTargetInitializer.ColorWriteMask & CW_BLUE) ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0) | ((RenderTargetInitializer.ColorWriteMask & CW_ALPHA) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0); } FD3D11BlendState* BlendState = new FD3D11BlendState; VERIFYD3D11RESULT_EX(Direct3DDevice->CreateBlendState(&BlendDesc,BlendState->Resource.GetInitReference()), Direct3DDevice); return BlendState; }
void FWinD3D11ConstantBuffer::InitDynamicRHI() { TRefCountPtr<ID3D11Buffer> CBuffer = NULL; D3D11_BUFFER_DESC BufferDesc; ZeroMemory( &BufferDesc, sizeof( D3D11_BUFFER_DESC ) ); // Verify constant buffer ByteWidth requirements check(MaxSize <= D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT && (MaxSize % 16) == 0); BufferDesc.ByteWidth = MaxSize; BufferDesc.Usage = D3D11_USAGE_DEFAULT; BufferDesc.CPUAccessFlags = 0; BufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; BufferDesc.MiscFlags = 0; Buffers = new TRefCountPtr<ID3D11Buffer>[NumSubBuffers]; CurrentSubBuffer = 0; for(uint32 s = 0;s < NumSubBuffers;s++) { VERIFYD3D11RESULT_EX(D3DRHI->GetDevice()->CreateBuffer(&BufferDesc, NULL, Buffers[s].GetInitReference()), D3DRHI->GetDevice()); UpdateBufferStats(Buffers[s],true); BufferDesc.ByteWidth = Align(BufferDesc.ByteWidth / 2, 16); } FD3D11ConstantBuffer::InitDynamicRHI(); }
void FD3D11Viewport::Resize(uint32 InSizeX,uint32 InSizeY,bool bInIsFullscreen) { // Unbind any dangling references to resources D3DRHI->ClearState(); if (IsValidRef(CustomPresent)) { CustomPresent->OnBackBufferResize(); } // Release our backbuffer reference, as required by DXGI before calling ResizeBuffers. if (IsValidRef(BackBuffer)) { check(BackBuffer->GetRefCount() == 1); checkComRefCount(BackBuffer->GetResource(),1); checkComRefCount(BackBuffer->GetRenderTargetView(0, -1),1); checkComRefCount(BackBuffer->GetShaderResourceView(),1); } BackBuffer.SafeRelease(); if(SizeX != InSizeX || SizeY != InSizeY) { SizeX = InSizeX; SizeY = InSizeY; check(SizeX > 0); check(SizeY > 0); // Resize the swap chain. VERIFYD3D11RESULT_EX(SwapChain->ResizeBuffers(1,SizeX,SizeY,(DXGI_FORMAT)FD3D11Viewport::GetBackBufferFormat(),DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH), D3DRHI->GetDevice()); if(bInIsFullscreen) { DXGI_MODE_DESC BufferDesc = SetupDXGI_MODE_DESC(); if (FAILED(SwapChain->ResizeTarget(&BufferDesc))) { ConditionalResetSwapChain(true); } } } if(bIsFullscreen != bInIsFullscreen) { bIsFullscreen = bInIsFullscreen; bIsValid = false; // Use ConditionalResetSwapChain to call SetFullscreenState, to handle the failure case. // Ignore the viewport's focus state; since Resize is called as the result of a user action we assume authority without waiting for Focus. ConditionalResetSwapChain(true); } // Create a RHI surface to represent the viewport's back buffer. BackBuffer = GetSwapChainSurface(D3DRHI,SwapChain); }
/** * Creates a FD3D11Surface to represent a swap chain's back buffer. */ FD3D11Texture2D* GetSwapChainSurface(FD3D11DynamicRHI* D3DRHI,IDXGISwapChain* SwapChain) { // Grab the back buffer TRefCountPtr<ID3D11Texture2D> BackBufferResource; VERIFYD3D11RESULT_EX(SwapChain->GetBuffer(0,IID_ID3D11Texture2D,(void**)BackBufferResource.GetInitReference()), D3DRHI->GetDevice()); // create the render target view TRefCountPtr<ID3D11RenderTargetView> BackBufferRenderTargetView; D3D11_RENDER_TARGET_VIEW_DESC RTVDesc; RTVDesc.Format = DXGI_FORMAT_UNKNOWN; RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; RTVDesc.Texture2D.MipSlice = 0; VERIFYD3D11RESULT(D3DRHI->GetDevice()->CreateRenderTargetView(BackBufferResource,&RTVDesc,BackBufferRenderTargetView.GetInitReference())); D3D11_TEXTURE2D_DESC TextureDesc; BackBufferResource->GetDesc(&TextureDesc); TArray<TRefCountPtr<ID3D11RenderTargetView> > RenderTargetViews; RenderTargetViews.Add(BackBufferRenderTargetView); // create a shader resource view to allow using the backbuffer as a texture TRefCountPtr<ID3D11ShaderResourceView> BackBufferShaderResourceView; D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; SRVDesc.Format = DXGI_FORMAT_UNKNOWN; SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; SRVDesc.Texture2D.MostDetailedMip = 0; SRVDesc.Texture2D.MipLevels = 1; VERIFYD3D11RESULT(D3DRHI->GetDevice()->CreateShaderResourceView(BackBufferResource,&SRVDesc,BackBufferShaderResourceView.GetInitReference())); FD3D11Texture2D* NewTexture = new FD3D11Texture2D( D3DRHI, BackBufferResource, BackBufferShaderResourceView, false, 1, RenderTargetViews, NULL, TextureDesc.Width, TextureDesc.Height, 1, 1, 1, PF_A2B10G10R10, false, false, false ); D3D11TextureAllocated2D(*NewTexture); NewTexture->DoNoDeferDelete(); return NewTexture; }
FDepthStencilStateRHIRef FD3D11DynamicRHI::RHICreateDepthStencilState(const FDepthStencilStateInitializerRHI& Initializer) { FD3D11DepthStencilState* DepthStencilState = new FD3D11DepthStencilState; D3D11_DEPTH_STENCIL_DESC DepthStencilDesc; FMemory::Memzero(&DepthStencilDesc,sizeof(D3D11_DEPTH_STENCIL_DESC)); // depth part DepthStencilDesc.DepthEnable = Initializer.DepthTest != CF_Always || Initializer.bEnableDepthWrite; DepthStencilDesc.DepthWriteMask = Initializer.bEnableDepthWrite ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; DepthStencilDesc.DepthFunc = TranslateCompareFunction(Initializer.DepthTest); // stencil part DepthStencilDesc.StencilEnable = Initializer.bEnableFrontFaceStencil || Initializer.bEnableBackFaceStencil; DepthStencilDesc.StencilReadMask = Initializer.StencilReadMask; DepthStencilDesc.StencilWriteMask = Initializer.StencilWriteMask; DepthStencilDesc.FrontFace.StencilFunc = TranslateCompareFunction(Initializer.FrontFaceStencilTest); DepthStencilDesc.FrontFace.StencilFailOp = TranslateStencilOp(Initializer.FrontFaceStencilFailStencilOp); DepthStencilDesc.FrontFace.StencilDepthFailOp = TranslateStencilOp(Initializer.FrontFaceDepthFailStencilOp); DepthStencilDesc.FrontFace.StencilPassOp = TranslateStencilOp(Initializer.FrontFacePassStencilOp); if( Initializer.bEnableBackFaceStencil ) { DepthStencilDesc.BackFace.StencilFunc = TranslateCompareFunction(Initializer.BackFaceStencilTest); DepthStencilDesc.BackFace.StencilFailOp = TranslateStencilOp(Initializer.BackFaceStencilFailStencilOp); DepthStencilDesc.BackFace.StencilDepthFailOp = TranslateStencilOp(Initializer.BackFaceDepthFailStencilOp); DepthStencilDesc.BackFace.StencilPassOp = TranslateStencilOp(Initializer.BackFacePassStencilOp); } else { DepthStencilDesc.BackFace = DepthStencilDesc.FrontFace; } const bool bStencilOpIsKeep = Initializer.FrontFaceStencilFailStencilOp == SO_Keep && Initializer.FrontFaceDepthFailStencilOp == SO_Keep && Initializer.FrontFacePassStencilOp == SO_Keep && Initializer.BackFaceStencilFailStencilOp == SO_Keep && Initializer.BackFaceDepthFailStencilOp == SO_Keep && Initializer.BackFacePassStencilOp == SO_Keep; const bool bMayWriteStencil = Initializer.StencilWriteMask != 0 && !bStencilOpIsKeep; DepthStencilState->AccessType.SetDepthStencilWrite(Initializer.bEnableDepthWrite, bMayWriteStencil); VERIFYD3D11RESULT_EX(Direct3DDevice->CreateDepthStencilState(&DepthStencilDesc,DepthStencilState->Resource.GetInitReference()), Direct3DDevice); return DepthStencilState; }
FRasterizerStateRHIRef FD3D11DynamicRHI::RHICreateRasterizerState(const FRasterizerStateInitializerRHI& Initializer) { D3D11_RASTERIZER_DESC RasterizerDesc; FMemory::Memzero(&RasterizerDesc,sizeof(D3D11_RASTERIZER_DESC)); RasterizerDesc.CullMode = TranslateCullMode(Initializer.CullMode); RasterizerDesc.FillMode = TranslateFillMode(Initializer.FillMode); RasterizerDesc.SlopeScaledDepthBias = Initializer.SlopeScaleDepthBias; RasterizerDesc.FrontCounterClockwise = true; RasterizerDesc.DepthBias = FMath::FloorToInt(Initializer.DepthBias * (float)(1 << 24)); RasterizerDesc.DepthClipEnable = true; RasterizerDesc.MultisampleEnable = Initializer.bAllowMSAA; RasterizerDesc.ScissorEnable = true; FD3D11RasterizerState* RasterizerState = new FD3D11RasterizerState; VERIFYD3D11RESULT_EX(Direct3DDevice->CreateRasterizerState(&RasterizerDesc,RasterizerState->Resource.GetInitReference()), Direct3DDevice); return RasterizerState; }
void* FD3D11DynamicRHI::RHILockStructuredBuffer(FStructuredBufferRHIParamRef StructuredBufferRHI,uint32 Offset,uint32 Size,EResourceLockMode LockMode) { FD3D11StructuredBuffer* StructuredBuffer = ResourceCast(StructuredBufferRHI); // If this resource is bound to the device, unbind it ConditionalClearShaderResource(StructuredBuffer); // Determine whether the Structured buffer is dynamic or not. D3D11_BUFFER_DESC Desc; StructuredBuffer->Resource->GetDesc(&Desc); const bool bIsDynamic = (Desc.Usage == D3D11_USAGE_DYNAMIC); FD3D11LockedKey LockedKey(StructuredBuffer->Resource); FD3D11LockedData LockedData; if(bIsDynamic) { check(LockMode == RLM_WriteOnly); // If the buffer is dynamic, map its memory for writing. D3D11_MAPPED_SUBRESOURCE MappedSubresource; VERIFYD3D11RESULT_EX(Direct3DDeviceIMContext->Map(StructuredBuffer->Resource,0,D3D11_MAP_WRITE_DISCARD,0,&MappedSubresource), Direct3DDevice); LockedData.SetData(MappedSubresource.pData); LockedData.Pitch = MappedSubresource.RowPitch; } else { if(LockMode == RLM_ReadOnly) { // If the static buffer is being locked for reading, create a staging buffer. D3D11_BUFFER_DESC StagingBufferDesc; ZeroMemory( &StagingBufferDesc, sizeof( D3D11_BUFFER_DESC ) ); StagingBufferDesc.ByteWidth = Size; StagingBufferDesc.Usage = D3D11_USAGE_STAGING; StagingBufferDesc.BindFlags = 0; StagingBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; StagingBufferDesc.MiscFlags = 0; TRefCountPtr<ID3D11Buffer> StagingStructuredBuffer; VERIFYD3D11RESULT_EX(Direct3DDevice->CreateBuffer(&StagingBufferDesc,NULL,StagingStructuredBuffer.GetInitReference()), Direct3DDevice); LockedData.StagingResource = StagingStructuredBuffer; // Copy the contents of the Structured buffer to the staging buffer. Direct3DDeviceIMContext->CopyResource(StagingStructuredBuffer,StructuredBuffer->Resource); // Map the staging buffer's memory for reading. D3D11_MAPPED_SUBRESOURCE MappedSubresource; VERIFYD3D11RESULT_EX(Direct3DDeviceIMContext->Map(StagingStructuredBuffer,0,D3D11_MAP_READ,0,&MappedSubresource), Direct3DDevice); LockedData.SetData(MappedSubresource.pData); LockedData.Pitch = MappedSubresource.RowPitch; } else { // If the static buffer is being locked for writing, allocate memory for the contents to be written to. LockedData.AllocData(Desc.ByteWidth); LockedData.Pitch = Desc.ByteWidth; } } // Add the lock to the lock map. OutstandingLocks.Add(LockedKey,LockedData); // Return the offset pointer return (void*)((uint8*)LockedData.GetData() + Offset); }
FStructuredBufferRHIRef FD3D11DynamicRHI::RHICreateStructuredBuffer(uint32 Stride,uint32 Size,uint32 InUsage, FRHIResourceCreateInfo& CreateInfo) { // Explicitly check that the size is nonzero before allowing CreateStructuredBuffer to opaquely fail. check(Size > 0); // Check for values that will cause D3D calls to fail check(Size / Stride > 0 && Size % Stride == 0); D3D11_BUFFER_DESC Desc; ZeroMemory( &Desc, sizeof( D3D11_BUFFER_DESC ) ); Desc.ByteWidth = Size; Desc.Usage = (InUsage & BUF_AnyDynamic) ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT; Desc.BindFlags = 0; if(InUsage & BUF_ShaderResource) { // Setup bind flags so we can create a view to read from the buffer in a shader. Desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; } if (InUsage & BUF_UnorderedAccess) { // Setup bind flags so we can create a writeable UAV to the buffer Desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; } if (InUsage & BUF_StreamOutput) { Desc.BindFlags |= D3D11_BIND_STREAM_OUTPUT; } Desc.CPUAccessFlags = (InUsage & BUF_AnyDynamic) ? D3D11_CPU_ACCESS_WRITE : 0; Desc.MiscFlags = 0; if (InUsage & BUF_DrawIndirect) { Desc.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; } else { if (InUsage & BUF_ByteAddressBuffer) { Desc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS; } else { Desc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; } } Desc.StructureByteStride = Stride; if (FPlatformProperties::SupportsFastVRAMMemory()) { if (InUsage & BUF_FastVRAM) { FFastVRAMAllocator::GetFastVRAMAllocator()->AllocUAVBuffer(Desc); } } // If a resource array was provided for the resource, create the resource pre-populated D3D11_SUBRESOURCE_DATA InitData; D3D11_SUBRESOURCE_DATA* pInitData = NULL; if(CreateInfo.ResourceArray) { check(Size == CreateInfo.ResourceArray->GetResourceDataSize()); InitData.pSysMem = CreateInfo.ResourceArray->GetResourceData(); InitData.SysMemPitch = Size; InitData.SysMemSlicePitch = 0; pInitData = &InitData; } TRefCountPtr<ID3D11Buffer> StructuredBufferResource; VERIFYD3D11RESULT_EX(Direct3DDevice->CreateBuffer(&Desc,pInitData,StructuredBufferResource.GetInitReference()), Direct3DDevice); UpdateBufferStats(StructuredBufferResource, true); if(CreateInfo.ResourceArray) { // Discard the resource array's contents. CreateInfo.ResourceArray->Discard(); } return new FD3D11StructuredBuffer(StructuredBufferResource,Stride,Size,InUsage); }
FSamplerStateRHIRef FD3D11DynamicRHI::RHICreateSamplerState(const FSamplerStateInitializerRHI& Initializer) { D3D11_SAMPLER_DESC SamplerDesc; FMemory::Memzero(&SamplerDesc,sizeof(D3D11_SAMPLER_DESC)); SamplerDesc.AddressU = TranslateAddressMode(Initializer.AddressU); SamplerDesc.AddressV = TranslateAddressMode(Initializer.AddressV); SamplerDesc.AddressW = TranslateAddressMode(Initializer.AddressW); SamplerDesc.MipLODBias = Initializer.MipBias; SamplerDesc.MaxAnisotropy = ComputeAnisotropyRT(Initializer.MaxAnisotropy); SamplerDesc.MinLOD = Initializer.MinMipLevel; SamplerDesc.MaxLOD = Initializer.MaxMipLevel; // Determine whether we should use one of the comparison modes const bool bComparisonEnabled = Initializer.SamplerComparisonFunction != SCF_Never; switch(Initializer.Filter) { case SF_AnisotropicLinear: case SF_AnisotropicPoint: if (SamplerDesc.MaxAnisotropy == 1) { SamplerDesc.Filter = bComparisonEnabled ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_LINEAR; } else { // D3D11 doesn't allow using point filtering for mip filter when using anisotropic filtering SamplerDesc.Filter = bComparisonEnabled ? D3D11_FILTER_COMPARISON_ANISOTROPIC : D3D11_FILTER_ANISOTROPIC; } break; case SF_Trilinear: SamplerDesc.Filter = bComparisonEnabled ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_LINEAR; break; case SF_Bilinear: SamplerDesc.Filter = bComparisonEnabled ? D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; break; case SF_Point: SamplerDesc.Filter = bComparisonEnabled ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_POINT; break; } const FLinearColor LinearBorderColor = FColor(Initializer.BorderColor); SamplerDesc.BorderColor[0] = LinearBorderColor.R; SamplerDesc.BorderColor[1] = LinearBorderColor.G; SamplerDesc.BorderColor[2] = LinearBorderColor.B; SamplerDesc.BorderColor[3] = LinearBorderColor.A; SamplerDesc.ComparisonFunc = TranslateSamplerCompareFunction(Initializer.SamplerComparisonFunction); // D3D11 will return the same pointer if the particular state description was already created TRefCountPtr<ID3D11SamplerState> SamplerStateHandle; VERIFYD3D11RESULT_EX(Direct3DDevice->CreateSamplerState(&SamplerDesc, SamplerStateHandle.GetInitReference()), Direct3DDevice); FD3D11SamplerState** Found = GSamplerStateCache.Find(SamplerStateHandle); if (Found) { return *Found; } FD3D11SamplerState* SamplerState = new FD3D11SamplerState; SamplerState->Resource = SamplerStateHandle; // Manually add reference as we control the creation/destructions SamplerState->AddRef(); GSamplerStateCache.Add(SamplerStateHandle.GetReference(), SamplerState); return SamplerState; }
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_EX(InD3D11RHI->GetDevice()->CreateRenderTargetView(InResource, &RTVDesc, RenderTargetView.GetInitReference()), InD3D11RHI->GetDevice()); 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_EX(InD3D11RHI->GetDevice()->CreateShaderResourceView(InResource, &SRVDesc, ShaderResourceView.GetInitReference()), InD3D11RHI->GetDevice()); 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, FClearValueBinding::None ); if (InFlags & TexCreate_RenderTargetable) { NewTexture->SetCurrentGPUAccess(EResourceTransitionAccess::EWritable); } return NewTexture; }
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; }