FShaderResourceViewRHIRef FOpenGLDynamicRHI::RHICreateShaderResourceView(FVertexBufferRHIParamRef VertexBufferRHI, uint32 Stride, uint8 Format) { GLuint TextureID = 0; if ( FOpenGL::SupportsResourceView() ) { DYNAMIC_CAST_OPENGLRESOURCE(VertexBuffer,VertexBuffer); 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. return new FOpenGLShaderResourceView(this,TextureID,GL_TEXTURE_BUFFER); }
void FOpenGLDynamicRHI::RHIResizeViewport(FViewportRHIParamRef ViewportRHI,uint32 SizeX,uint32 SizeY,bool bIsFullscreen) { DYNAMIC_CAST_OPENGLRESOURCE(Viewport,Viewport); check( IsInGameThread() ); //#if !PLATFORM_MAC // SCOPED_SUSPEND_RENDERING_THREAD(true); //#endif Viewport->Resize(SizeX,SizeY,bIsFullscreen); }
void FOpenGLDynamicRHI::RHIBeginDrawingViewport(FViewportRHIParamRef ViewportRHI, FTextureRHIParamRef RenderTarget) { VERIFY_GL_SCOPE(); DYNAMIC_CAST_OPENGLRESOURCE(Viewport,Viewport); 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, FTextureRHIRef(), 0, NULL); } else { FRHIRenderTargetView RTV(DrawingViewport->GetBackBuffer()); RHISetRenderTargets(1, &RTV, FTextureRHIRef(), 0, NULL); } }
FOpenGLVertexBufferUnorderedAccessView::FOpenGLVertexBufferUnorderedAccessView( FOpenGLDynamicRHI* InOpenGLRHI, FVertexBufferRHIParamRef InVertexBufferRHI, uint8 Format): VertexBufferRHI(InVertexBufferRHI), OpenGLRHI(InOpenGLRHI) { VERIFY_GL_SCOPE(); DYNAMIC_CAST_OPENGLRESOURCE(VertexBuffer, InVertexBuffer); const FOpenGLTextureFormat& GLFormat = GOpenGLTextureFormats[Format]; GLuint TextureID = 0; FOpenGL::GenTextures(1,&TextureID); // Use a texture stage that's not likely to be used for draws, to avoid waiting OpenGLRHI->CachedSetupTextureStage(OpenGLRHI->GetContextStateForCurrentContext(), FOpenGL::GetMaxCombinedTextureImageUnits() - 1, GL_TEXTURE_BUFFER, TextureID, -1, 1); FOpenGL::TexBuffer(GL_TEXTURE_BUFFER, GLFormat.InternalFormat[0], InVertexBuffer->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. this->Resource = TextureID; this->Format = GLFormat.InternalFormat[0]; }
FTexture2DRHIRef FOpenGLDynamicRHI::RHIGetViewportBackBuffer(FViewportRHIParamRef ViewportRHI) { DYNAMIC_CAST_OPENGLRESOURCE(Viewport,Viewport); return Viewport->GetBackBuffer(); }
void FOpenGLDynamicRHI::RHIEndDrawingViewport(FViewportRHIParamRef ViewportRHI,bool bPresent,bool bLockToVsync) { VERIFY_GL_SCOPE(); DYNAMIC_CAST_OPENGLRESOURCE(Viewport,Viewport); SCOPE_CYCLE_COUNTER(STAT_OpenGLPresentTime); check(DrawingViewport.GetReference() == Viewport); FOpenGLTexture2D* BackBuffer = Viewport->GetBackBuffer(); uint32 IdleStart = FPlatformTime::Cycles(); PlatformBlitToViewport(PlatformDevice, Viewport->OpenGLContext, BackBuffer->GetSizeX(), BackBuffer->GetSizeY(), bPresent, bLockToVsync, RHIOpenGLConsoleVariables::SyncInterval ); DrawingViewport = NULL; // Don't wait on the GPU when using SLI, let the driver determine how many frames behind the GPU should be allowed to get if (GNumActiveGPUsForRendering == 1) { static const auto CFinishFrameVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FinishCurrentFrame")); if (!CFinishFrameVar->GetValueOnRenderThread()) { // Wait for the GPU to finish rendering the previous frame before finishing this frame. Viewport->WaitForFrameEventCompletion(); Viewport->IssueFrameEvent(); } else { // Finish current frame immediately to reduce latency Viewport->IssueFrameEvent(); Viewport->WaitForFrameEventCompletion(); } // If the input latency timer has been triggered, block until the GPU is completely // finished displaying this frame and calculate the delta time. if ( GInputLatencyTimer.RenderThreadTrigger ) { Viewport->WaitForFrameEventCompletion(); uint32 EndTime = FPlatformTime::Cycles(); GInputLatencyTimer.DeltaTime = EndTime - GInputLatencyTimer.StartTime; GInputLatencyTimer.RenderThreadTrigger = false; } } GRenderThreadIdle[ERenderThreadIdleTypes::WaitingForGPUPresent] += FPlatformTime::Cycles() - IdleStart; if (bRevertToSharedContextAfterDrawingViewport) { PlatformSharedContextSetup(PlatformDevice); bRevertToSharedContextAfterDrawingViewport = false; } }
FUnorderedAccessViewRHIRef FOpenGLDynamicRHI::RHICreateUnorderedAccessView(FTextureRHIParamRef TextureRHI) { DYNAMIC_CAST_OPENGLRESOURCE(Texture,Texture); check(Texture->GetFlags() & TexCreate_UAV); return new FOpenGLTextureUnorderedAccessView(TextureRHI); }
FUnorderedAccessViewRHIRef FOpenGLDynamicRHI::RHICreateUnorderedAccessView(FStructuredBufferRHIParamRef StructuredBufferRHI, bool bUseUAVCounter, bool bAppendBuffer) { DYNAMIC_CAST_OPENGLRESOURCE(StructuredBuffer,StructuredBuffer); UE_LOG(LogRHI, Fatal,TEXT("%s not implemented yet"),ANSI_TO_TCHAR(__FUNCTION__)); return new FOpenGLUnorderedAccessView(); }
FShaderResourceViewRHIRef FOpenGLDynamicRHI::RHICreateShaderResourceView(FStructuredBufferRHIParamRef StructuredBufferRHI) { DYNAMIC_CAST_OPENGLRESOURCE(StructuredBuffer,StructuredBuffer); UE_LOG(LogRHI, Fatal,TEXT("OpenGL RHI doesn't support RHICreateShaderResourceView yet!")); return new FOpenGLShaderResourceView(this,0,GL_TEXTURE_BUFFER); }
FUnorderedAccessViewRHIRef FOpenGLDynamicRHI::RHICreateUnorderedAccessView(FVertexBufferRHIParamRef VertexBufferRHI,uint8 Format) { DYNAMIC_CAST_OPENGLRESOURCE(VertexBuffer,VertexBuffer); return new FOpenGLVertexBufferUnorderedAccessView(this, VertexBufferRHI, Format); }