void FSimpleElementCollector::DrawBatchedElements(FRHICommandList& RHICmdList, const FSceneView& View, FTexture2DRHIRef DepthTexture, EBlendModeFilter::Type Filter) const { // Mobile HDR does not execute post process, so does not need to render flipped const bool bNeedToSwitchVerticalAxis = RHINeedsToSwitchVerticalAxis(View.GetShaderPlatform()) && !bIsMobileHDR; // Draw the batched elements. BatchedElements.Draw( RHICmdList, View.GetFeatureLevel(), bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), View.Family->EngineShowFlags.HitProxies, 1.0f, &View, DepthTexture, Filter ); }
void FForwardShadingSceneRenderer::RenderForwardShadingBasePass(FRHICommandListImmediate& RHICmdList) { SCOPED_DRAW_EVENT(RHICmdList, BasePass, DEC_SCENE_ITEMS); SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime); EBasePassSort::Type SortMode = GetSortMode(); int32 MaxDraws = GMaxBasePassDraws.GetValueOnRenderThread(); if (MaxDraws <= 0) { MaxDraws = MAX_int32; } if (SortMode == EBasePassSort::SortStateBuckets) { SCOPE_CYCLE_COUNTER(STAT_SortStaticDrawLists); for (int32 DrawType = 0; DrawType < FScene::EBasePass_MAX; DrawType++) { Scene->BasePassForForwardShadingLowQualityLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingMovableDirectionalLightCSMDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingMovableDirectionalLightDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); Scene->BasePassForForwardShadingNoLightMapDrawList[DrawType].SortFrontToBack(Views[0].ViewLocation); } } // Draw the scene's emissive and light-map color. for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++) { SCOPED_CONDITIONAL_DRAW_EVENTF(RHICmdList, EventView, Views.Num() > 1, DEC_SCENE_ITEMS, TEXT("View%d"), ViewIndex); FViewInfo& View = Views[ViewIndex]; // Opaque blending RHICmdList.SetBlendState(TStaticBlendStateWriteMask<CW_RGBA>::GetRHI()); // Note, this is a reversed Z depth surface, using CF_GreaterEqual. RHICmdList.SetDepthStencilState(TStaticDepthStencilState<true, CF_GreaterEqual>::GetRHI()); RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1); { // Render the base pass static data if (SortMode == EBasePassSort::SortPerMesh) { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); MaxDraws -= Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingMovableDirectionalLightCSMDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingMovableDirectionalLightDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Default].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); } else { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingMovableDirectionalLightCSMDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingMovableDirectionalLightDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Default].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); } } { SCOPE_CYCLE_COUNTER(STAT_DynamicPrimitiveDrawTime); SCOPED_DRAW_EVENT(RHICmdList, Dynamic, DEC_SCENE_ITEMS); const bool bUseGetMeshElements = ShouldUseGetDynamicMeshElements(); if (bUseGetMeshElements) { FBasePassForwardOpaqueDrawingPolicyFactory::ContextType Context(ESceneRenderTargetsMode::DontSet); for (int32 MeshBatchIndex = 0; MeshBatchIndex < View.DynamicMeshElements.Num(); MeshBatchIndex++) { const FMeshBatchAndRelevance& MeshBatchAndRelevance = View.DynamicMeshElements[MeshBatchIndex]; if (MeshBatchAndRelevance.bHasOpaqueOrMaskedMaterial || ViewFamily.EngineShowFlags.Wireframe) { const FMeshBatch& MeshBatch = *MeshBatchAndRelevance.Mesh; FBasePassForwardOpaqueDrawingPolicyFactory::DrawDynamicMesh(RHICmdList, View, Context, MeshBatch, false, true, MeshBatchAndRelevance.PrimitiveSceneProxy, MeshBatch.BatchHitProxyId); } } View.SimpleElementCollector.DrawBatchedElements(RHICmdList, View, NULL, EBlendModeFilter::OpaqueAndMasked); } else if (View.VisibleDynamicPrimitives.Num() > 0) { // Draw the dynamic non-occluded primitives using a base pass drawing policy. TDynamicPrimitiveDrawer<FBasePassForwardOpaqueDrawingPolicyFactory> Drawer(RHICmdList, &View, FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), true); for (int32 PrimitiveIndex = 0; PrimitiveIndex < View.VisibleDynamicPrimitives.Num(); PrimitiveIndex++) { const FPrimitiveSceneInfo* PrimitiveSceneInfo = View.VisibleDynamicPrimitives[PrimitiveIndex]; int32 PrimitiveId = PrimitiveSceneInfo->GetIndex(); const FPrimitiveViewRelevance& PrimitiveViewRelevance = View.PrimitiveViewRelevanceMap[PrimitiveId]; const bool bVisible = View.PrimitiveVisibilityMap[PrimitiveId]; // Only draw the primitive if it's visible if (bVisible && // only draw opaque and masked primitives if wireframe is disabled (PrimitiveViewRelevance.bOpaqueRelevance || ViewFamily.EngineShowFlags.Wireframe)) { FScopeCycleCounter Context(PrimitiveSceneInfo->Proxy->GetStatId()); Drawer.SetPrimitive(PrimitiveSceneInfo->Proxy); PrimitiveSceneInfo->Proxy->DrawDynamicElements(&Drawer, &View); } } } const bool bNeedToSwitchVerticalAxis = RHINeedsToSwitchVerticalAxis(GShaderPlatformForFeatureLevel[FeatureLevel]); // Draw the base pass for the view's batched mesh elements. DrawViewElements<FBasePassForwardOpaqueDrawingPolicyFactory>(RHICmdList, View, FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), SDPG_World, true); // Draw the view's batched simple elements(lines, sprites, etc). View.BatchedViewElements.Draw(RHICmdList, FeatureLevel, bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false); // Draw foreground objects last DrawViewElements<FBasePassForwardOpaqueDrawingPolicyFactory>(RHICmdList, View, FBasePassForwardOpaqueDrawingPolicyFactory::ContextType(ESceneRenderTargetsMode::DontSet), SDPG_Foreground, true); // Draw the view's batched simple elements(lines, sprites, etc). View.TopBatchedViewElements.Draw(RHICmdList, FeatureLevel, bNeedToSwitchVerticalAxis, View.ViewProjectionMatrix, View.ViewRect.Width(), View.ViewRect.Height(), false); } // Issue static draw list masked draw calls last, as PVR wants it if (SortMode == EBasePassSort::SortPerMesh) { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); MaxDraws -= Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingMovableDirectionalLightCSMDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility, MaxDraws); MaxDraws -= Scene->BasePassForForwardShadingMovableDirectionalLightDrawList[FScene::EBasePass_Masked].DrawVisibleFrontToBack(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility,MaxDraws); } else { SCOPE_CYCLE_COUNTER(STAT_StaticDrawListDrawTime); Scene->BasePassForForwardShadingNoLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingLowQualityLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDistanceFieldShadowMapLightMapDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingDirectionalLightAndSHIndirectDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingMovableDirectionalLightCSMDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View, View.StaticMeshVisibilityMap, View.StaticMeshBatchVisibility); Scene->BasePassForForwardShadingMovableDirectionalLightDrawList[FScene::EBasePass_Masked].DrawVisible(RHICmdList, View,View.StaticMeshVisibilityMap,View.StaticMeshBatchVisibility); } } }
void FSlateRHIRenderingPolicy::DrawElements(FRHICommandListImmediate& RHICmdList, FSlateBackBuffer& BackBuffer, const FMatrix& ViewProjectionMatrix, const TArray<FSlateRenderBatch>& RenderBatches, bool bAllowSwitchVerticalAxis) { SCOPE_CYCLE_COUNTER( STAT_SlateDrawTime ); // Should only be called by the rendering thread check(IsInRenderingThread()); TSlateElementVertexBuffer<FSlateVertex>& VertexBuffer = VertexBuffers[CurrentBufferIndex]; FSlateElementIndexBuffer& IndexBuffer = IndexBuffers[CurrentBufferIndex]; float TimeSeconds = FPlatformTime::Seconds() - GStartTime; float RealTimeSeconds = FPlatformTime::Seconds() - GStartTime; float DeltaTimeSeconds = FApp::GetDeltaTime(); static const FEngineShowFlags DefaultShowFlags(ESFIM_Game); const float DisplayGamma = bGammaCorrect ? GEngine ? GEngine->GetDisplayGamma() : 2.2f : 1.0f; FSceneViewFamilyContext SceneViewContext ( FSceneViewFamily::ConstructionValues ( &BackBuffer, NULL, DefaultShowFlags ) .SetWorldTimes( TimeSeconds, RealTimeSeconds, DeltaTimeSeconds ) .SetGammaCorrection( DisplayGamma ) ); FSceneView* SceneView = NULL; TShaderMapRef<FSlateElementVS> VertexShader(GetGlobalShaderMap(GMaxRHIFeatureLevel)); // Disabled stencil test state FDepthStencilStateRHIRef DSOff = TStaticDepthStencilState<false,CF_Always>::GetRHI(); FSamplerStateRHIRef BilinearClamp = TStaticSamplerState<SF_Bilinear,AM_Clamp,AM_Clamp,AM_Clamp>::GetRHI(); if (GRHISupportsBaseVertexIndex) { RHICmdList.SetStreamSource(0, VertexBuffer.VertexBufferRHI, sizeof(FSlateVertex), 0); } // Draw each element for( int32 BatchIndex = 0; BatchIndex < RenderBatches.Num(); ++BatchIndex ) { const FSlateRenderBatch& RenderBatch = RenderBatches[BatchIndex]; const FSlateShaderResource* ShaderResource = RenderBatch.Texture; const ESlateBatchDrawFlag::Type DrawFlags = RenderBatch.DrawFlags; const ESlateDrawEffect::Type DrawEffects = RenderBatch.DrawEffects; const ESlateShader::Type ShaderType = RenderBatch.ShaderType; const FShaderParams& ShaderParams = RenderBatch.ShaderParams; if( !RenderBatch.CustomDrawer.IsValid() ) { check(RenderBatch.NumIndices > 0); if( !ShaderResource || ShaderResource->GetType() != ESlateShaderResource::Material ) { FSlateElementPS* PixelShader = GetTexturePixelShader(ShaderType, DrawEffects); RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState( GSlateVertexDeclaration.VertexDeclarationRHI, VertexShader->GetVertexShader(), nullptr, nullptr, PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); VertexShader->SetViewProjection(RHICmdList, ViewProjectionMatrix); VertexShader->SetVerticalAxisMultiplier(RHICmdList, bAllowSwitchVerticalAxis && RHINeedsToSwitchVerticalAxis(GShaderPlatformForFeatureLevel[GMaxRHIFeatureLevel]) ? -1.0f : 1.0f ); #if !DEBUG_OVERDRAW RHICmdList.SetBlendState( (RenderBatch.DrawFlags & ESlateBatchDrawFlag::NoBlending) ? TStaticBlendState<>::GetRHI() : TStaticBlendState<CW_RGBA, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha, BO_Add, BF_InverseDestAlpha, BF_One>::GetRHI() ); #else RHICmdList.SetBlendState(TStaticBlendState<CW_RGB, BO_Add, BF_One, BF_One, BO_Add, BF_Zero, BF_InverseSourceAlpha>::GetRHI()); #endif // Disable stencil testing by default RHICmdList.SetDepthStencilState(DSOff); if (DrawFlags & ESlateBatchDrawFlag::Wireframe) { RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Wireframe, CM_None, true>::GetRHI()); } else { RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None, true>::GetRHI()); } if (RenderBatch.ScissorRect.IsSet()) { RHICmdList.SetScissorRect(true, RenderBatch.ScissorRect.GetValue().Left, RenderBatch.ScissorRect.GetValue().Top, RenderBatch.ScissorRect.GetValue().Right, RenderBatch.ScissorRect.GetValue().Bottom); } else { RHICmdList.SetScissorRect(false, 0, 0, 0, 0); } FTexture2DRHIRef TextureRHI; if(ShaderResource) { TextureRHI = ((TSlateTexture<FTexture2DRHIRef>*)ShaderResource)->GetTypedResource(); } if( ShaderResource && IsValidRef( TextureRHI ) ) { FSamplerStateRHIRef SamplerState; if( DrawFlags == (ESlateBatchDrawFlag::TileU | ESlateBatchDrawFlag::TileV) ) { SamplerState = TStaticSamplerState<SF_Bilinear, AM_Wrap, AM_Wrap, AM_Wrap>::GetRHI(); } else if (DrawFlags & ESlateBatchDrawFlag::TileU) { SamplerState = TStaticSamplerState<SF_Bilinear, AM_Wrap, AM_Clamp, AM_Wrap>::GetRHI(); } else if (DrawFlags & ESlateBatchDrawFlag::TileV) { SamplerState = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Wrap, AM_Wrap>::GetRHI(); } else { SamplerState = BilinearClamp; } PixelShader->SetTexture(RHICmdList, TextureRHI, SamplerState); } else { PixelShader->SetTexture(RHICmdList, GWhiteTexture->TextureRHI, BilinearClamp); } PixelShader->SetShaderParams(RHICmdList, ShaderParams.PixelParams); PixelShader->SetDisplayGamma(RHICmdList, (DrawFlags & ESlateBatchDrawFlag::NoGamma) ? 1.0f : DisplayGamma); uint32 PrimitiveCount = RenderBatch.DrawPrimitiveType == ESlateDrawPrimitive::LineList ? RenderBatch.NumIndices / 2 : RenderBatch.NumIndices / 3; // for RHIs that can't handle VertexOffset, we need to offset the stream source each time if (!GRHISupportsBaseVertexIndex) { RHICmdList.SetStreamSource(0, VertexBuffer.VertexBufferRHI, sizeof(FSlateVertex), RenderBatch.VertexOffset * sizeof(FSlateVertex)); RHICmdList.DrawIndexedPrimitive(IndexBuffer.IndexBufferRHI, GetRHIPrimitiveType(RenderBatch.DrawPrimitiveType), 0, 0, RenderBatch.NumVertices, RenderBatch.IndexOffset, PrimitiveCount, 1); } else { RHICmdList.DrawIndexedPrimitive(IndexBuffer.IndexBufferRHI, GetRHIPrimitiveType(RenderBatch.DrawPrimitiveType), RenderBatch.VertexOffset, 0, RenderBatch.NumVertices, RenderBatch.IndexOffset, PrimitiveCount, 1); } } else if (ShaderResource && ShaderResource->GetType() == ESlateShaderResource::Material && GEngine) { // Note: This code is only executed if the engine is loaded (in early loading screens attemping to use a material is unsupported if (!SceneView) { SceneView = &CreateSceneView(SceneViewContext, BackBuffer, ViewProjectionMatrix); } FSlateMaterialResource* MaterialShaderResource = (FSlateMaterialResource*)ShaderResource; FMaterialRenderProxy* MaterialRenderProxy = MaterialShaderResource->GetRenderProxy(); const FMaterial* Material = MaterialRenderProxy->GetMaterial(SceneView->GetFeatureLevel()); FSlateMaterialShaderPS* PixelShader = GetMaterialPixelShader( Material, ShaderType, DrawEffects ); if( PixelShader ) { RHICmdList.SetLocalBoundShaderState(RHICmdList.BuildLocalBoundShaderState( GSlateVertexDeclaration.VertexDeclarationRHI, VertexShader->GetVertexShader(), nullptr, nullptr, PixelShader->GetPixelShader(), FGeometryShaderRHIRef())); PixelShader->SetParameters(RHICmdList, *SceneView, MaterialRenderProxy, Material, DisplayGamma, ShaderParams.PixelParams); PixelShader->SetDisplayGamma(RHICmdList, (DrawFlags & ESlateBatchDrawFlag::NoGamma) ? 1.0f : DisplayGamma); FSlateShaderResource* MaskResource = MaterialShaderResource->GetTextureMaskResource(); if( MaskResource ) { RHICmdList.SetBlendState(TStaticBlendState<CW_RGBA, BO_Add, BF_SourceAlpha, BF_InverseSourceAlpha, BO_Add, BF_InverseDestAlpha, BF_One>::GetRHI()); FTexture2DRHIRef TextureRHI; TextureRHI = ((TSlateTexture<FTexture2DRHIRef>*)MaskResource)->GetTypedResource(); PixelShader->SetAdditionalTexture(RHICmdList, TextureRHI, BilinearClamp); } VertexShader->SetViewProjection( RHICmdList, ViewProjectionMatrix ); uint32 PrimitiveCount = RenderBatch.DrawPrimitiveType == ESlateDrawPrimitive::LineList ? RenderBatch.NumIndices / 2 : RenderBatch.NumIndices / 3; // for RHIs that can't handle VertexOffset, we need to offset the stream source each time if (!GRHISupportsBaseVertexIndex) { RHICmdList.SetStreamSource(0, VertexBuffer.VertexBufferRHI, sizeof(FSlateVertex), RenderBatch.VertexOffset * sizeof(FSlateVertex)); RHICmdList.DrawIndexedPrimitive(IndexBuffer.IndexBufferRHI, GetRHIPrimitiveType(RenderBatch.DrawPrimitiveType), 0, 0, RenderBatch.NumVertices, RenderBatch.IndexOffset, PrimitiveCount, 1); } else { RHICmdList.DrawIndexedPrimitive(IndexBuffer.IndexBufferRHI, GetRHIPrimitiveType(RenderBatch.DrawPrimitiveType), RenderBatch.VertexOffset, 0, RenderBatch.NumVertices, RenderBatch.IndexOffset, PrimitiveCount, 1); } } } } else { TSharedPtr<ICustomSlateElement, ESPMode::ThreadSafe> CustomDrawer = RenderBatch.CustomDrawer.Pin(); if (CustomDrawer.IsValid()) { // This element is custom and has no Slate geometry. Tell it to render itself now CustomDrawer->DrawRenderThread(RHICmdList, &BackBuffer.GetRenderTargetTexture()); // Something may have messed with the viewport size so set it back to the full target. RHICmdList.SetViewport( 0,0,0,BackBuffer.GetSizeXY().X, BackBuffer.GetSizeXY().Y, 0.0f ); RHICmdList.SetStreamSource(0, VertexBuffer.VertexBufferRHI, sizeof(FSlateVertex), 0); } } } CurrentBufferIndex = (CurrentBufferIndex + 1) % SlateRHIConstants::NumBuffers; }