FUnorderedAccessViewRHIRef FVulkanDynamicRHI::RHICreateUnorderedAccessView(FTextureRHIParamRef TextureRHI, uint32 MipLevel) { #if 0 FVulkanTextureBase* Base = nullptr; if (auto* Tex2D = TextureRHI->GetTexture2D()) { Base = ResourceCast(Tex2D); } else if (auto* Tex3D = TextureRHI->GetTexture3D()) { Base = ResourceCast(Tex3D); } else if (auto* TexCube = TextureRHI->GetTextureCube()) { Base = ResourceCast(TexCube); } else { ensure(0); } #endif FVulkanUnorderedAccessView* UAV = new FVulkanUnorderedAccessView; UAV->SourceTexture = TextureRHI; UAV->MipIndex = MipLevel; return UAV; }
void FVulkanCommandListContext::RHISetShaderUniformBuffer(FPixelShaderRHIParamRef PixelShader, uint32 BufferIndex, FUniformBufferRHIParamRef BufferRHI) { // Validate if the shader which we are setting is the same as we expect check(&PendingState->GetBoundShaderState().GetShader(SF_Pixel) == ResourceCast(PixelShader)); FVulkanUniformBuffer* UniformBuffer = ResourceCast(BufferRHI); SetShaderUniformBuffer(SF_Pixel, UniformBuffer, BufferIndex); }
void FVulkanCommandListContext::RHISetShaderSampler(FPixelShaderRHIParamRef PixelShaderRHI, uint32 SamplerIndex, FSamplerStateRHIParamRef NewStateRHI) { check(Device); FVulkanBoundShaderState& ShaderState = PendingState->GetBoundShaderState(); check(&ShaderState.GetShader(SF_Pixel) == ResourceCast(PixelShaderRHI)); FVulkanSamplerState* Sampler = ResourceCast(NewStateRHI); ShaderState.SetSamplerState(SF_Pixel, SamplerIndex, Sampler); }
void FVulkanCommandListContext::RHIClearUAV(FUnorderedAccessViewRHIParamRef UnorderedAccessViewRHI, const uint32* Values) { #if 0 FVulkanUnorderedAccessView* UnorderedAccessView = ResourceCast(UnorderedAccessViewRHI); #endif VULKAN_SIGNAL_UNIMPLEMENTED(); }
bool FD3D11DynamicRHI::RHIGetRenderQueryResult(FRenderQueryRHIParamRef QueryRHI,uint64& OutResult,bool bWait) { check(IsInRenderingThread()); FD3D11RenderQuery* Query = ResourceCast(QueryRHI); bool bSuccess = true; if(!Query->bResultIsCached) { bSuccess = GetQueryData(Query->Resource,&Query->Result,sizeof(Query->Result),bWait, Query->QueryType); Query->bResultIsCached = bSuccess; } if(Query->QueryType == RQT_AbsoluteTime) { // GetTimingFrequency is the number of ticks per second uint64 Div = FGPUTiming::GetTimingFrequency() / (1000 * 1000); // convert from GPU specific timestamp to micro sec (1 / 1 000 000 s) which seems a reasonable resolution OutResult = Query->Result / Div; } else { OutResult = Query->Result; } return bSuccess; }
void FVulkanCommandListContext::RHISetRasterizerState(FRasterizerStateRHIParamRef NewStateRHI) { FVulkanRasterizerState* NewState = ResourceCast(NewStateRHI); check(NewState); PendingState->SetRasterizerState(NewState); }
FShaderResourceViewRHIRef FOpenGLDynamicRHI::RHICreateShaderResourceView(FVertexBufferRHIParamRef VertexBufferRHI, uint32 Stride, uint8 Format) { GLuint TextureID = 0; if ( FOpenGL::SupportsResourceView() ) { FOpenGLVertexBuffer* VertexBuffer = ResourceCast(VertexBufferRHI); const uint32 FormatBPP = GPixelFormats[Format].BlockBytes; if (FormatBPP != Stride) { UE_LOG(LogRHI, Fatal,TEXT("OpenGL 3.2 RHI supports only tightly packed texture buffers!")); return new FOpenGLShaderResourceView(this, 0, GL_TEXTURE_BUFFER); } const FOpenGLTextureFormat& GLFormat = GOpenGLTextureFormats[Format]; FOpenGL::GenTextures(1,&TextureID); // Use a texture stage that's not likely to be used for draws, to avoid waiting CachedSetupTextureStage(GetContextStateForCurrentContext(), FOpenGL::GetMaxCombinedTextureImageUnits() - 1, GL_TEXTURE_BUFFER, TextureID, -1, 1); FOpenGL::TexBuffer(GL_TEXTURE_BUFFER, GLFormat.InternalFormat[0], VertexBuffer->Resource); } // No need to restore texture stage; leave it like this, // and the next draw will take care of cleaning it up; or // next operation that needs the stage will switch something else in on it. FShaderResourceViewRHIRef Result = new FOpenGLShaderResourceView(this,TextureID,GL_TEXTURE_BUFFER,VertexBufferRHI,Format); FShaderCache::LogSRV(Result, VertexBufferRHI, Stride, Format); return Result; }
void FD3D11DynamicRHI::RHIEndRenderQuery(FRenderQueryRHIParamRef QueryRHI) { FD3D11RenderQuery* Query = ResourceCast(QueryRHI); Query->bResultIsCached = false; // for occlusion queries, this is redundant with the one in begin Direct3DDeviceIMContext->End(Query->Resource); //@todo - d3d debug spews warnings about OQ's that are being issued but not polled, need to investigate }
void FVulkanCommandListContext::RHISetBlendState(FBlendStateRHIParamRef NewStateRHI, const FLinearColor& BlendFactor) { FVulkanBlendState* NewState = ResourceCast(NewStateRHI); check(NewState); check(Device); PendingState->SetBlendState(NewState); }
void FVulkanCommandListContext::RHISetDepthStencilState(FDepthStencilStateRHIParamRef NewStateRHI, uint32 StencilRef) { FVulkanDepthStencilState* NewState = ResourceCast(NewStateRHI); check(NewState); check(Device); PendingState->SetDepthStencilState(NewState, StencilRef); }
void FVulkanCommandListContext::RHISetUAVParameter(FComputeShaderRHIParamRef ComputeShaderRHI,uint32 UAVIndex,FUnorderedAccessViewRHIParamRef UAVRHI, uint32 InitialCount) { #if 0 FVulkanUnorderedAccessView* UAV = ResourceCast(UAVRHI); #endif VULKAN_SIGNAL_UNIMPLEMENTED(); }
void FVulkanCommandListContext::RHISetStreamSource(uint32 StreamIndex,FVertexBufferRHIParamRef VertexBufferRHI, uint32 Stride, uint32 Offset) { FVulkanVertexBuffer* VertexBuffer = ResourceCast(VertexBufferRHI); if (VertexBuffer != NULL) { PendingState->SetStreamSource(StreamIndex, VertexBuffer, Stride, Offset + VertexBuffer->GetOffset()); } }
void FVulkanCommandListContext::RHISetComputeShader(FComputeShaderRHIParamRef ComputeShaderRHI) { #if 0 FVulkanComputeShader* ComputeShader = ResourceCast(ComputeShaderRHI); #endif VULKAN_SIGNAL_UNIMPLEMENTED(); }
void FVulkanCommandListContext::RHIEndRenderQuery(FRenderQueryRHIParamRef QueryRHI) { #if 0 FVulkanRenderQuery* Query = ResourceCast(QueryRHI); Query->End(); #endif }
FShaderResourceViewRHIRef FVulkanDynamicRHI::RHICreateShaderResourceView(FVertexBufferRHIParamRef VertexBufferRHI, uint32 Stride, uint8 Format) { FVulkanShaderResourceView* SRV = new FVulkanShaderResourceView(Device); // delay the shader view create until we use it, so we just track the source info here SRV->SourceVertexBuffer = ResourceCast(VertexBufferRHI); SRV->BufferViewFormat = (EPixelFormat)Format; return SRV; }
FShaderResourceViewRHIRef FVulkanDynamicRHI::RHICreateShaderResourceView(FTexture2DRHIParamRef Texture2DRHI, uint8 MipLevel) { FVulkanShaderResourceView* SRV = new FVulkanShaderResourceView(Device); // delay the shader view create until we use it, so we just track the source info here SRV->SourceTexture = ResourceCast(Texture2DRHI); SRV->MipLevel = MipLevel; SRV->NumMips = 1; return SRV; }
void FVulkanCommandListContext::RHISetShaderParameter(FPixelShaderRHIParamRef PixelShaderRHI, uint32 BufferIndex, uint32 BaseIndex, uint32 NumBytes, const void* NewValue) { check(Device); FVulkanBoundShaderState& ShaderState = PendingState->GetBoundShaderState(); // Verify shader check(&ShaderState.GetShader(SF_Pixel) == ResourceCast(PixelShaderRHI)); ShaderState.SetShaderParameter(SF_Pixel, BufferIndex, BaseIndex, NumBytes, NewValue); }
FUnorderedAccessViewRHIRef FVulkanDynamicRHI::RHICreateUnorderedAccessView(FVertexBufferRHIParamRef VertexBufferRHI, uint8 Format) { FVulkanVertexBuffer* VertexBuffer = ResourceCast(VertexBufferRHI); // create the UAV buffer to point to the structured buffer's memory FVulkanUnorderedAccessView* UAV = new FVulkanUnorderedAccessView; UAV->SourceVertexBuffer = VertexBuffer; return UAV; }
void FVulkanCommandListContext::RHISetBoundShaderState(FBoundShaderStateRHIParamRef BoundShaderStateRHI) { TRefCountPtr<FVulkanBoundShaderState> BoundShaderState = ResourceCast(BoundShaderStateRHI); // Store in the history so it doesn't get released GBoundShaderStateHistory.Add(BoundShaderState); check(Device); PendingState->SetBoundShaderState(BoundShaderState); }
void FVulkanCommandListContext::RHISetShaderTexture(FPixelShaderRHIParamRef PixelShaderRHI, uint32 TextureIndex, FTextureRHIParamRef NewTextureRHI) { check(Device); FVulkanBoundShaderState& BSS = PendingState->GetBoundShaderState(); // Verify presence of a pixel shader and it has to be the same shader check(ResourceCast(PixelShaderRHI) == &BSS.GetShader(SF_Pixel)); FVulkanTextureBase* VulkanTexture = GetVulkanTextureFromRHITexture(NewTextureRHI); BSS.SetTexture(SF_Pixel, TextureIndex, VulkanTexture); }
void FOpenGLDynamicRHI::RHIResizeViewport(FViewportRHIParamRef ViewportRHI,uint32 SizeX,uint32 SizeY,bool bIsFullscreen) { FOpenGLViewport* Viewport = ResourceCast(ViewportRHI); check( IsInGameThread() ); //#if !PLATFORM_MAC // SCOPED_SUSPEND_RENDERING_THREAD(true); //#endif Viewport->Resize(SizeX,SizeY,bIsFullscreen); }
FShaderResourceViewRHIRef FVulkanDynamicRHI::RHICreateShaderResourceView(FStructuredBufferRHIParamRef StructuredBufferRHI) { #if 0 FVulkanStructuredBuffer* StructuredBuffer = ResourceCast(StructuredBufferRHI); FVulkanShaderResourceView* SRV = new FVulkanShaderResourceView; return SRV; #else VULKAN_SIGNAL_UNIMPLEMENTED(); return nullptr; #endif }
void FVulkanCommandListContext::RHIDispatchIndirectComputeShader(FVertexBufferRHIParamRef ArgumentBufferRHI, uint32 ArgumentOffset) { #if 0 FVulkanVertexBuffer* ArgumentBuffer = ResourceCast(ArgumentBufferRHI); #endif VULKAN_SIGNAL_UNIMPLEMENTED(); //if (IsImmediate()) { VulkanRHI::GManager.GPUProfilingData.RegisterGPUWork(1); } }
void FVulkanCommandListContext::RHIDrawIndexedPrimitiveIndirect(uint32 PrimitiveType,FIndexBufferRHIParamRef IndexBufferRHI,FVertexBufferRHIParamRef ArgumentBufferRHI,uint32 ArgumentOffset) { check(Device); SCOPE_CYCLE_COUNTER(STAT_VulkanDrawCallTime); #if 0 //@NOTE: don't prepare draw without actually drawing #if !PLATFORM_ANDROID PendingState->PrepareDraw(UEToVulkanType((EPrimitiveType)PrimitiveType)); FVulkanIndexBuffer* IndexBuffer = ResourceCast(IndexBufferRHI); #if 0 FVulkanVertexBuffer* ArgumentBuffer = ResourceCast(ArgumentBufferRHI); #endif #endif #endif VULKAN_SIGNAL_UNIMPLEMENTED(); if (IsImmediate()) { VulkanRHI::GManager.GPUProfilingData.RegisterGPUWork(0); } }
FUnorderedAccessViewRHIRef FD3D11DynamicRHI::RHICreateUnorderedAccessView(FStructuredBufferRHIParamRef StructuredBufferRHI, bool bUseUAVCounter, bool bAppendBuffer) { FD3D11StructuredBuffer* StructuredBuffer = ResourceCast(StructuredBufferRHI); D3D11_BUFFER_DESC BufferDesc; StructuredBuffer->Resource->GetDesc(&BufferDesc); const bool bByteAccessBuffer = (BufferDesc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) != 0; D3D11_UNORDERED_ACCESS_VIEW_DESC UAVDesc; UAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; UAVDesc.Format = DXGI_FORMAT_UNKNOWN; if (BufferDesc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) { UAVDesc.Format = DXGI_FORMAT_R32_UINT; } else if (bByteAccessBuffer) { UAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; } UAVDesc.Buffer.FirstElement = 0; // For byte access buffers and indirect draw argument buffers, GetDesc returns a StructureByteStride of 0 even though we created it with 4 const uint32 EffectiveStride = BufferDesc.StructureByteStride == 0 ? 4 : BufferDesc.StructureByteStride; UAVDesc.Buffer.NumElements = BufferDesc.ByteWidth / EffectiveStride; UAVDesc.Buffer.Flags = 0; if (bUseUAVCounter) { UAVDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_COUNTER; } if (bAppendBuffer) { UAVDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_APPEND; } if (bByteAccessBuffer) { UAVDesc.Buffer.Flags |= D3D11_BUFFER_UAV_FLAG_RAW; } TRefCountPtr<ID3D11UnorderedAccessView> UnorderedAccessView; VERIFYD3D11RESULT(Direct3DDevice->CreateUnorderedAccessView(StructuredBuffer->Resource,&UAVDesc,(ID3D11UnorderedAccessView**)UnorderedAccessView.GetInitReference())); return new FD3D11UnorderedAccessView(UnorderedAccessView,StructuredBuffer); }
// Occlusion/Timer queries. void FD3D11DynamicRHI::RHIBeginRenderQuery(FRenderQueryRHIParamRef QueryRHI) { FD3D11RenderQuery* Query = ResourceCast(QueryRHI); if(Query->QueryType == RQT_Occlusion) { Query->bResultIsCached = false; Direct3DDeviceIMContext->Begin(Query->Resource); } else { // not supported/needed for RQT_AbsoluteTime check(0); } }
FUnorderedAccessViewRHIRef FVulkanDynamicRHI::RHICreateUnorderedAccessView(FStructuredBufferRHIParamRef StructuredBufferRHI, bool bUseUAVCounter, bool bAppendBuffer) { #if 0 FVulkanStructuredBuffer* StructuredBuffer = ResourceCast(StructuredBufferRHI); // create the UAV buffer to point to the structured buffer's memory FVulkanUnorderedAccessView* UAV = new FVulkanUnorderedAccessView; UAV->SourceStructuredBuffer = StructuredBuffer; return UAV; #else VULKAN_SIGNAL_UNIMPLEMENTED(); return nullptr; #endif }
void FD3D11DynamicRHI::RHIUnlockStructuredBuffer(FStructuredBufferRHIParamRef StructuredBufferRHI) { FD3D11StructuredBuffer* StructuredBuffer = ResourceCast(StructuredBufferRHI); // 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); // Find the outstanding lock for this VB. FD3D11LockedKey LockedKey(StructuredBuffer->Resource); FD3D11LockedData* LockedData = OutstandingLocks.Find(LockedKey); check(LockedData); if(bIsDynamic) { // If the VB is dynamic, its memory was mapped directly; unmap it. Direct3DDeviceIMContext->Unmap(StructuredBuffer->Resource,0); } else { // If the static VB lock involved a staging resource, it was locked for reading. if(LockedData->StagingResource) { // Unmap the staging buffer's memory. ID3D11Buffer* StagingBuffer = (ID3D11Buffer*)LockedData->StagingResource.GetReference(); Direct3DDeviceIMContext->Unmap(StagingBuffer,0); } else { // Copy the contents of the temporary memory buffer allocated for writing into the VB. Direct3DDeviceIMContext->UpdateSubresource(StructuredBuffer->Resource,LockedKey.Subresource,NULL,LockedData->GetData(),LockedData->Pitch,0); // Check the copy is finished before freeing... Direct3DDeviceIMContext->Flush(); // Free the temporary memory buffer. LockedData->FreeData(); } } // Remove the FD3D11LockedData from the lock map. // If the lock involved a staging resource, this releases it. OutstandingLocks.Remove(LockedKey); }
void FOpenGLDynamicRHI::RHIBeginDrawingViewport(FViewportRHIParamRef ViewportRHI, FTextureRHIParamRef RenderTarget) { VERIFY_GL_SCOPE(); FOpenGLViewport* Viewport = ResourceCast(ViewportRHI); SCOPE_CYCLE_COUNTER(STAT_OpenGLPresentTime); check(!DrawingViewport); DrawingViewport = Viewport; bRevertToSharedContextAfterDrawingViewport = false; EOpenGLCurrentContext CurrentContext = PlatformOpenGLCurrentContext( PlatformDevice ); if( CurrentContext != CONTEXT_Rendering ) { check(CurrentContext == CONTEXT_Shared); check(!bIsRenderingContextAcquired || !GUseThreadedRendering); bRevertToSharedContextAfterDrawingViewport = true; PlatformRenderingContextSetup(PlatformDevice); } if(!GPUProfilingData.FrameTiming.IsInitialized()) { GPUProfilingData.FrameTiming.InitResource(); } // Set the render target and viewport. if( RenderTarget ) { FRHIRenderTargetView RTV(RenderTarget); RHISetRenderTargets(1, &RTV, nullptr, 0, NULL); } else { FRHIRenderTargetView RTV(DrawingViewport->GetBackBuffer()); RHISetRenderTargets(1, &RTV, nullptr, 0, NULL); } }
void FVulkanShaderResourceView::UpdateView() { // update the buffer view for dynamic VB backed buffers (or if it was never set) if (SourceVertexBuffer != nullptr) { if (SourceVertexBuffer->IsVolatile() && VolatileLockCounter != SourceVertexBuffer->GetVolatileLockCounter()) { BufferView = nullptr; VolatileLockCounter = SourceVertexBuffer->GetVolatileLockCounter(); } if (BufferView == nullptr || SourceVertexBuffer->IsDynamic()) { SCOPE_CYCLE_COUNTER(STAT_VulkanSRVUpdateTime); // thanks to ref counting, overwriting the buffer will toss the old view BufferView = new FVulkanBufferView(Device); BufferView->Create(SourceVertexBuffer.GetReference(), BufferViewFormat, SourceVertexBuffer->GetOffset(), SourceVertexBuffer->GetSize()); } } else { if (TextureView.View == VK_NULL_HANDLE) { EPixelFormat Format = (BufferViewFormat == PF_Unknown) ? SourceTexture->GetFormat() : BufferViewFormat; if (FRHITexture2D* Tex2D = SourceTexture->GetTexture2D()) { FVulkanTexture2D* VTex2D = ResourceCast(Tex2D); TextureView.Create(*Device, VTex2D->Surface.Image, VK_IMAGE_VIEW_TYPE_2D, VTex2D->Surface.GetPartialAspectMask(), Format, UEToVkFormat(Format, false), MipLevel, NumMips, 0, 1); } else { ensure(0); } } } }