public MyRenderProfiler GetRenderProfiler() { return(MyRender11.GetRenderProfiler()); }
internal static void Present() { if (m_swapchain != null) { if (m_screenshot.HasValue) { if (m_screenshot.Value.SizeMult == VRageMath.Vector2.One) { MyCopyToRT.ClearAlpha(Backbuffer); SaveScreenshotFromResource(Backbuffer.m_resource); } else { TakeCustomSizedScreenshot(m_screenshot.Value.SizeMult); } } MyRender11.GetRenderProfiler().StartProfilingBlock("Waiting for present"); try { m_swapchain.Present(MyRender11.m_settings.VSync ? 1 : 0, 0); m_consecutivePresentFails = 0; if (m_presentTimer == null) { m_presentTimer = new Stopwatch(); } else { m_presentTimer.Stop(); if (m_presentTimes.Count >= PresentTimesStored) { m_presentTimes.Dequeue(); } m_presentTimes.Enqueue(m_presentTimer.ElapsedMilliseconds); } m_presentTimer.Restart(); } catch (SharpDXException e) { MyRender11.Log.WriteLine("Device removed - resetting device"); HandleDeviceReset(); MyRender11.Log.WriteLine("Device removed - resetting completed"); m_consecutivePresentFails++; if (m_consecutivePresentFails == 5) { MyRender11.Log.WriteLine("Present failed"); MyRender11.Log.IncreaseIndent(); if (e.Descriptor == SharpDX.DXGI.ResultCode.DeviceRemoved) { MyRender11.Log.WriteLine("Device removed: " + Device.DeviceRemovedReason); } var timings = ""; while (m_presentTimes.Count > 0) { timings += m_presentTimes.Dequeue(); if (m_presentTimes.Count > 0) { timings += ", "; } } MyRender11.Log.WriteLine("Last present timings = [ " + timings + " ]"); MyRender11.Log.DecreaseIndent(); } } MyRender11.GetRenderProfiler().EndProfilingBlock(); if (m_profilingStarted) { MyGpuProfiler.IC_EndBlock(); } MyGpuProfiler.EndFrame(); MyGpuProfiler.StartFrame(); m_profilingStarted = true; // waiting for change to fullscreen - window migh overlap or some other dxgi excuse to fail :( TryChangeToFullscreen(); } }
private static void DrawGameScene(bool blitToBackbuffer) { ResetStats(); MyCommon.UpdateFrameConstants(); // todo: shouldn't be necessary if (true) { MyImmediateRC.RC.Clear(); MyImmediateRC.RC.Context.ClearState(); } MyRender11.GetRenderProfiler().StartProfilingBlock("MyGeometryRenderer.Render"); MyGpuProfiler.IC_BeginBlock("MyGeometryRenderer.Render"); MyGeometryRenderer.Render(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); // cleanup context atfer deferred lists if (MyRender11.DeferredContextsEnabled) { MyImmediateRC.RC.Clear(); } // todo: shouldn't be necessary if (true) { MyImmediateRC.RC.Clear(); MyImmediateRC.RC.Context.ClearState(); } MyRender11.GetRenderProfiler().StartProfilingBlock("Render decals"); MyGpuProfiler.IC_BeginBlock("Render decals"); MyRender11.CopyGbufferToScratch(); MyScreenDecals.Draw(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Render foliage"); MyGpuProfiler.IC_BeginBlock("Render foliage"); MyFoliageRenderer.Render(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MySceneMaterials.MoveToGPU(); MyRender11.GetRenderProfiler().StartProfilingBlock("Postprocessing"); MyGpuProfiler.IC_BeginBlock("Postprocessing"); if (MultisamplingEnabled) { MyRender11.Context.ClearDepthStencilView(MyScreenDependants.m_resolvedDepth.m_DSV, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1, 0); MyGpuProfiler.IC_BeginBlock("MarkAAEdges"); MyAAEdgeMarking.Run(); MyGpuProfiler.IC_EndBlock(); MyDepthResolve.Run(MyScreenDependants.m_resolvedDepth, MyGBuffer.Main.DepthStencil.Depth); } MyGpuProfiler.IC_BeginBlock("MarkCascades"); MyShadows.MarkCascadesInStencil(); MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Shadows resolve"); MyShadowsResolve.Run(); MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("SSAO"); if (Postprocess.EnableSsao) { MySSAO.Run(MyScreenDependants.m_ambientOcclusion, MyGBuffer.Main, MyRender11.MultisamplingEnabled ? MyScreenDependants.m_resolvedDepth.Depth : MyGBuffer.Main.DepthStencil.Depth); } else { MyRender11.Context.ClearRenderTargetView(MyScreenDependants.m_ambientOcclusion.m_RTV, Color4.White); } MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Lights"); MyLightRendering.Render(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Billboards"); MyGpuProfiler.IC_BeginBlock("Billboards"); MyRender11.Context.ClearRenderTargetView((MyScreenDependants.m_particlesRT as IRenderTargetBindable).RTV, new Color4(0, 0, 0, 0)); if (MyRender11.MultisamplingEnabled) { MyBillboardRenderer.Render(MyScreenDependants.m_particlesRT, MyScreenDependants.m_resolvedDepth, MyScreenDependants.m_resolvedDepth.Depth); } else { MyBillboardRenderer.Render(MyScreenDependants.m_particlesRT, MyGBuffer.Main.DepthStencil, MyGBuffer.Main.DepthStencil.Depth); } MyBlendTargets.Run(MyGBuffer.Main.Get(MyGbufferSlot.LBuffer), MyScreenDependants.m_particlesRT); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyGpuProfiler.IC_BeginBlock("Luminance reduction"); MyBindableResource avgLum = null; if (MyRender11.MultisamplingEnabled) { //MyLBufferResolve.Run(MyGBuffer.Main.Get(MyGbufferSlot.LBufferResolved), MyGBuffer.Main.Get(MyGbufferSlot.LBuffer), MyGBuffer.Main.DepthStencil.Stencil); MyImmediateRC.RC.Context.ResolveSubresource(MyGBuffer.Main.Get(MyGbufferSlot.LBuffer).m_resource, 0, MyGBuffer.Main.Get(MyGbufferSlot.LBufferResolved).m_resource, 0, SharpDX.DXGI.Format.R11G11B10_Float); } if (m_resetEyeAdaptation) { MyImmediateRC.RC.Context.ClearUnorderedAccessView(m_prevLum.m_UAV, Int4.Zero); m_resetEyeAdaptation = false; } avgLum = MyLuminanceAverage.Run(m_reduce0, m_reduce1, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer), m_prevLum, m_localLum); MyGpuProfiler.IC_EndBlock(); if (MyRender11.Settings.DispalyHdrDebug) { var src = MyGBuffer.Main.Get(MyGbufferSlot.LBuffer) as MyRenderTarget; MyHdrDebugTools.CreateHistogram(src.m_SRV, src.m_resolution, src.m_samples.X); } MyGpuProfiler.IC_BeginBlock("Bloom"); var bloom = MyBloom.Run(MyGBuffer.Main.Get(MyGbufferSlot.LBuffer), avgLum); MyGpuProfiler.IC_EndBlock(); MyBindableResource tonemapped; if (MyRender11.FxaaEnabled) { tonemapped = m_rgba8_linear; } else { tonemapped = m_uav3; } MyGpuProfiler.IC_BeginBlock("Tone mapping"); MyToneMapping.Run(tonemapped, MyGBuffer.Main.Get(MyGbufferSlot.LBuffer), avgLum, bloom, MyRender11.Settings.EnableTonemapping && Postprocess.EnableTonemapping); MyGpuProfiler.IC_EndBlock(); MyBindableResource renderedImage; if (MyRender11.FxaaEnabled) { MyGpuProfiler.IC_BeginBlock("FXAA"); MyFXAA.Run(m_rgba8_0.GetView(new MyViewKey { Fmt = SharpDX.DXGI.Format.R8G8B8A8_UNorm, View = MyViewEnum.RtvView }), tonemapped); MyGpuProfiler.IC_EndBlock(); renderedImage = m_rgba8_0.GetView(new MyViewKey { Fmt = SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, View = MyViewEnum.SrvView }); } else { //renderedImage = (tonemapped as MyCustomTexture).GetView(new MyViewKey { Fmt = SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, View = MyViewEnum.SrvView }); renderedImage = tonemapped; } m_finalImage = renderedImage; if (blitToBackbuffer) { MyCopyToRT.Run(Backbuffer, renderedImage); } if (MyRender11.Settings.DispalyHdrDebug) { MyHdrDebugTools.DisplayHistogram(Backbuffer.m_RTV, (avgLum as IShaderResourceBindable).SRV); } MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); }
private static void UpdateSceneFrame() { var desc = new RasterizerStateDescription(); desc.FillMode = FillMode.Solid; desc.CullMode = CullMode.None; desc.IsFrontCounterClockwise = true; desc.DepthBias = 25000; desc.DepthBiasClamp = 2; desc.SlopeScaledDepthBias = 1; MyPipelineStates.Modify(m_shadowRasterizerState, desc); MyMeshes.Load(); QueryTexturesFromEntities(); MyTextures.Load(); GatherTextures(); MyComponents.UpdateCullProxies(); MyComponents.ProcessEntities(); MyComponents.SendVisible(); MyBillboardRenderer.OnFrameStart(); MyRender11.GetRenderProfiler().StartProfilingBlock("RebuildProxies"); foreach (var renderable in MyComponentFactory <MyRenderableComponent> .GetAll()) { renderable.RebuildRenderProxies(); } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateProxies"); UpdateActors(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyBigMeshTable.Table.MoveToGPU(); MyRender11.GetRenderProfiler().StartProfilingBlock("Update merged groups"); MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateBeforeDraw"); foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll()) { r.UpdateBeforeDraw(); } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("MoveToGPU"); foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll()) { foreach (var val in r.m_materialGroups.Values) { // optimize: keep list+set for updating val.MoveToGPU(); } } MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Fill foliage streams"); MyGpuProfiler.IC_BeginBlock("Fill foliage streams"); MyGPUFoliageGenerating.GetInstance().PerFrame(); MyGPUFoliageGenerating.GetInstance().Begin(); foreach (var foliage in MyComponentFactory <MyFoliageComponent> .GetAll()) { if (foliage.m_owner.CalculateCameraDistance() < MyRender11.RenderSettings.FoliageDetails.GrassDrawDistance()) { foliage.FillStreams(); } else { foliage.InvalidateStreams(); } } MyGPUFoliageGenerating.GetInstance().End(); MyGpuProfiler.IC_EndBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyCommon.MoveToNextFrame(); }
internal unsafe static void Render(MyBindableResource dst, MyBindableResource depth, MyBindableResource depthRead) { if (!MyRender11.DebugOverrides.BillboardsDynamic) { OnFrameStart(); } m_stats.Clear(); MyRender11.GetRenderProfiler().StartProfilingBlock("Gather"); Gather(); MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().StartProfilingBlock("Draw"); TransferData(); RC.SetupScreenViewport(); RC.BindDepthRT(depth, DepthStencilAccess.ReadOnly, dst); RC.SetBS(MyRender11.BlendAlphaPremult); RC.SetRS(MyRender11.m_nocullRasterizerState); RC.BindRawSRV(104, m_SB.Srv); RC.BindSRV(1, depthRead); RC.SetCB(2, MyCommon.GetObjectCB(sizeof(Matrix) * MaxCustomProjections)); RC.SetDS(MyDepthStencilState.DefaultDepthState); RC.SetCB(4, MyRender11.DynamicShadows.ShadowCascades.CascadeConstantBuffer); RC.DeviceContext.VertexShader.SetSampler(MyCommon.SHADOW_SAMPLER_SLOT, MyRender11.m_shadowmapSamplerState); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.CASCADES_SM_SLOT, MyRender11.DynamicShadows.ShadowCascades.CascadeShadowmapArray.ShaderView); RC.DeviceContext.VertexShader.SetSamplers(0, MyRender11.StandardSamplers); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.SKYBOX_IBL_SLOT, MyRender11.IsIntelBrokenCubemapsWorkaround ? MyTextures.GetView(MyTextures.IntelFallbackCubeTexId) : MyEnvironmentProbe.Instance.cubemapPrefiltered.ShaderView); RC.DeviceContext.VertexShader.SetShaderResource(MyCommon.SKYBOX2_IBL_SLOT, MyTextures.GetView(MyTextures.GetTexture(MyEnvironment.NightSkyboxPrefiltered, MyTextureEnum.CUBEMAP, true))); RC.SetVB(0, m_VB.Buffer, m_VB.Stride); RC.SetIB(m_IB.Buffer, m_IB.Format); RC.SetIL(m_inputLayout); for (int i = 0; i < m_batches.Count; i++) { // first part of batches contain sorted billboards and they read depth // second part of batches contain unsorted billboards and they ignore depth // switch here: if (m_batches[i].Offset == m_sortedBillboardsNum) { //RC.BindDepthRT(null, DepthStencilAccess.ReadOnly, dst); } if (m_batches[i].Lit) { RC.SetVS(m_vsLit); if (m_batches[i].AlphaCutout) { RC.SetPS(m_psAlphaCutoutAndLit); } else { RC.SetPS(m_psLit); } } else if (m_batches[i].AlphaCutout) { RC.SetVS(m_vs); RC.SetPS(m_psAlphaCutout); } else { RC.SetVS(m_vs); RC.SetPS(m_ps); } RC.BindRawSRV(0, m_batches[i].Texture); RC.DeviceContext.DrawIndexed(m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); ++RC.Stats.BillboardDrawIndexed; } m_stats.Billboards += m_sorted + m_unsorted; RC.SetRS(null); RC.SetBS(null); m_batches.Clear(); MyRender11.GatherStats(m_stats); MyRender11.GetRenderProfiler().EndProfilingBlock(); }
private static void ProcessDrawMessage(MyRenderMessageBase drawMessage) { switch (drawMessage.MessageType) { case MyRenderMessageEnum.SpriteScissorPush: { var msg = drawMessage as MyRenderMessageSpriteScissorPush; MySpritesRenderer.ScissorStackPush(msg.ScreenRectangle); break; } case MyRenderMessageEnum.SpriteScissorPop: { MySpritesRenderer.ScissorStackPop(); break; } case MyRenderMessageEnum.DrawSprite: { MyRenderMessageDrawSprite sprite = (MyRenderMessageDrawSprite)drawMessage; MySpritesRenderer.AddSingleSprite(MyTextures.GetTexture(sprite.Texture, MyTextureEnum.GUI, waitTillLoaded: sprite.WaitTillLoaded), sprite.Color, sprite.Origin, sprite.RightVector, sprite.SourceRectangle, sprite.DestinationRectangle); break; } case MyRenderMessageEnum.DrawSpriteNormalized: { MyRenderMessageDrawSpriteNormalized sprite = (MyRenderMessageDrawSpriteNormalized)drawMessage; var rotation = sprite.Rotation; if (sprite.RotationSpeed != 0) { rotation += sprite.RotationSpeed * (float)(MyRender11.CurrentDrawTime - MyRender11.CurrentUpdateTime).Seconds; } Vector2 rightVector = rotation != 0f ? new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)) : sprite.RightVector; int safeGuiSizeY = MyRender11.ResolutionI.Y; int safeGuiSizeX = (int)(safeGuiSizeY * 1.3333f); // This will mantain same aspect ratio for GUI elements var safeGuiRectangle = new VRageMath.Rectangle(MyRender11.ResolutionI.X / 2 - safeGuiSizeX / 2, 0, safeGuiSizeX, safeGuiSizeY); var safeScreenScale = (float)safeGuiSizeY / MyRenderGuiConstants.REFERENCE_SCREEN_HEIGHT; float fixedScale = sprite.Scale * safeScreenScale; var tex = MyTextures.GetTexture(sprite.Texture, MyTextureEnum.GUI, true); var normalizedCoord = sprite.NormalizedCoord; var screenCoord = new Vector2(safeGuiRectangle.Left + safeGuiRectangle.Width * normalizedCoord.X, safeGuiRectangle.Top + safeGuiRectangle.Height * normalizedCoord.Y); var sizeInPixels = MyTextures.GetSize(tex); var sizeInPixelsScaled = sizeInPixels * fixedScale; Vector2 alignedScreenCoord = screenCoord; var drawAlign = sprite.DrawAlign; if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP) { // Nothing to do as position is already at this point } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER) { // Move position to the texture center alignedScreenCoord -= sizeInPixelsScaled / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP) { alignedScreenCoord.X -= sizeInPixelsScaled.X / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_BOTTOM) { alignedScreenCoord.X -= sizeInPixelsScaled.X / 2.0f; alignedScreenCoord.Y -= sizeInPixelsScaled.Y; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_BOTTOM) { alignedScreenCoord -= sizeInPixelsScaled; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER) { alignedScreenCoord.Y -= sizeInPixelsScaled.Y / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_CENTER) { alignedScreenCoord.X -= sizeInPixelsScaled.X; alignedScreenCoord.Y -= sizeInPixelsScaled.Y / 2.0f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_BOTTOM) { alignedScreenCoord.Y -= sizeInPixelsScaled.Y; // *0.75f; } else if (drawAlign == MyGuiDrawAlignEnum.HORISONTAL_RIGHT_AND_VERTICAL_TOP) { alignedScreenCoord.X -= sizeInPixelsScaled.X; } screenCoord = alignedScreenCoord; var rect = new RectangleF(screenCoord.X, screenCoord.Y, fixedScale * sizeInPixels.X, fixedScale * sizeInPixels.Y); Vector2 origin; if (sprite.OriginNormalized.HasValue) { origin = sprite.OriginNormalized.Value * sizeInPixels; } else { origin = sizeInPixels / 2; } sprite.OriginNormalized = sprite.OriginNormalized ?? new Vector2(0.5f); MySpritesRenderer.AddSingleSprite(MyTextures.GetTexture(sprite.Texture, MyTextureEnum.GUI, waitTillLoaded: sprite.WaitTillLoaded), sprite.Color, origin, rightVector, null, rect); break; } case MyRenderMessageEnum.DrawSpriteAtlas: { MyRenderMessageDrawSpriteAtlas sprite = (MyRenderMessageDrawSpriteAtlas)drawMessage; var tex = MyTextures.GetTexture(sprite.Texture, MyTextureEnum.GUI, true); var textureSize = MyTextures.GetSize(tex); Rectangle?sourceRect = new Rectangle( (int)(textureSize.X * sprite.TextureOffset.X), (int)(textureSize.Y * sprite.TextureOffset.Y), (int)(textureSize.X * sprite.TextureSize.X), (int)(textureSize.Y * sprite.TextureSize.Y)); VRageMath.RectangleF destRect = new VRageMath.RectangleF( (sprite.Position.X) * sprite.Scale.X, (sprite.Position.Y) * sprite.Scale.Y, sprite.HalfSize.X * sprite.Scale.X * 2, sprite.HalfSize.Y * sprite.Scale.Y * 2); Vector2 origin = new Vector2(textureSize.X * sprite.TextureSize.X * 0.5f, textureSize.Y * sprite.TextureSize.Y * 0.5f); MySpritesRenderer.AddSingleSprite(MyTextures.GetTexture(sprite.Texture, MyTextureEnum.GUI, true), sprite.Color, origin, sprite.RightVector, sourceRect, destRect); break; } case MyRenderMessageEnum.DrawString: { var message = drawMessage as MyRenderMessageDrawString; var font = MyRender11.GetFont(message.FontIndex); font.DrawString( message.ScreenCoord, message.ColorMask, message.Text, message.ScreenScale, message.ScreenMaxWidth); break; } case MyRenderMessageEnum.DrawScene: { UpdateSceneFrame(); ProfilerShort.Begin("DrawScene"); DrawGameScene(Backbuffer); ProfilerShort.Begin("TransferPerformanceStats"); TransferPerformanceStats(); ProfilerShort.End(); ProfilerShort.End(); ProfilerShort.Begin("Draw scene debug"); MyGpuProfiler.IC_BeginBlock("Draw scene debug"); DrawSceneDebug(); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); ProfilerShort.Begin("ProcessDebugMessages"); ProcessDebugMessages(); ProfilerShort.End(); ProfilerShort.Begin("MyDebugRenderer.Draw"); MyGpuProfiler.IC_BeginBlock("MyDebugRenderer.Draw"); MyDebugRenderer.Draw(MyRender11.Backbuffer); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); var testingDepth = MyRender11.MultisamplingEnabled ? MyScreenDependants.m_resolvedDepth : MyGBuffer.Main.DepthStencil; ProfilerShort.Begin("MyPrimitivesRenderer.Draw"); MyGpuProfiler.IC_BeginBlock("MyPrimitivesRenderer.Draw"); MyPrimitivesRenderer.Draw(MyRender11.Backbuffer, testingDepth); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); ProfilerShort.Begin("MyLinesRenderer.Draw"); MyGpuProfiler.IC_BeginBlock("MyLinesRenderer.Draw"); MyLinesRenderer.Draw(MyRender11.Backbuffer, testingDepth); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); if (m_screenshot.HasValue && m_screenshot.Value.IgnoreSprites) { if (m_screenshot.Value.SizeMult == Vector2.One) { SaveScreenshotFromResource(Backbuffer.m_resource); } else { TakeCustomSizedScreenshot(m_screenshot.Value.SizeMult); } } ProfilerShort.Begin("MySpritesRenderer.Draw"); MyGpuProfiler.IC_BeginBlock("MySpritesRenderer.Draw"); MySpritesRenderer.Draw(MyRender11.Backbuffer.m_RTV, new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y)); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); if (MyRenderProxy.DRAW_RENDER_STATS) { MyRender11.GetRenderProfiler().StartProfilingBlock("MyRenderStatsDraw.Draw"); MyRenderStatsDraw.Draw(MyRenderStats.m_stats, 0.6f, VRageMath.Color.Yellow); ProfilerShort.End(); } break; } } }
internal static void DispatchCulling() { //MyPerformanceCounter.PerCameraDraw11Write.RenderableObjectsNum = MyRenderablesBoundingTree.m_tree.CountLeaves(MyRenderablesBoundingTree.m_tree.GetRoot()); MyRender11.GetRenderProfiler().StartProfilingBlock("CreateTasksAndWait"); List <Task> tasks = new List <Task>(); for (int i = 1; i < m_cullQuery.Size; i++) { m_cullQuery.FrustumQuery[i].List.Clear(); m_cullQuery.FrustumQuery[i].IsInsideList.Clear(); tasks.Add(Parallel.Start(new MyCullingWork(m_cullQuery.FrustumQuery[i]))); } if (m_cullQuery.Size > 0) { m_cullQuery.FrustumQuery[0].List.Clear(); m_cullQuery.FrustumQuery[0].IsInsideList.Clear(); new MyCullingWork(m_cullQuery.FrustumQuery[0]).DoWork(); } foreach (var task in tasks) { task.Wait(); } MyRender11.GetRenderProfiler().EndProfilingBlock(); //bool ok = false; //for (int i = 0; i < m_cullQuery.Size; i++ ) //{ // if(m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.MainFrustum) // { // foreach(var e in m_cullQuery.FrustumQuery[i].List) // { // if(e.Proxies[0].Parent.m_owner.ID == 1417) // { // ok = true; break; // } // } // } //} //var x = 7; MyRender11.GetRenderProfiler().StartProfilingBlock("ProcessResults"); for (int i = 0; i < m_cullQuery.Size; i++) { if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.MainFrustum) { MyPerformanceCounter.PerCameraDraw11Write.ViewFrustumObjectsNum = m_cullQuery.FrustumQuery[i].List.Count; int N = m_cullQuery.FrustumQuery[i].List.Count; for (int j = 0; j < N; j++) { foreach (var proxy in m_cullQuery.FrustumQuery[i].List[j].Proxies) { proxy.ObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex); } } } else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade0) { MyPerformanceCounter.PerCameraDraw11Write.Cascade0ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count; // m_inCascade0.Clear(); int N = m_cullQuery.FrustumQuery[i].List.Count; for (int j = 0; j < N; j++) { if (m_cullQuery.FrustumQuery[i].IsInsideList[j]) { var item = m_cullQuery.FrustumQuery[i].List[j]; m_inCascade0.Add(item); } } // m_inCascade0_2.Clear(); N = m_cullQuery.FrustumQuery[i].List2.Count; for (int j = 0; j < N; j++) { if (m_cullQuery.FrustumQuery[i].IsInsideList2[j]) { var item = m_cullQuery.FrustumQuery[i].List2[j]; m_inCascade0_2.Add(item); } } } else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade1) { // m_inCascade1.Clear(); var list = m_cullQuery.FrustumQuery[i].List; int N = list.Count; for (int j = 0; j < N; j++) { var item = list[j]; if (m_inCascade0.Contains(item)) { // drop list.RemoveAtFast(j); j--; N--; } else if (m_cullQuery.FrustumQuery[i].IsInsideList[j]) { m_inCascade1.Add(item); } } // m_inCascade1_2.Clear(); var list2 = m_cullQuery.FrustumQuery[i].List2; N = list2.Count; for (int j = 0; j < N; j++) { var item = list2[j]; if (m_inCascade0_2.Contains(item)) { // drop list2.RemoveAtFast(j); j--; N--; } else if (m_cullQuery.FrustumQuery[i].IsInsideList2[j]) { m_inCascade1_2.Add(item); } } MyPerformanceCounter.PerCameraDraw11Write.Cascade1ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count; } else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade2) { // m_inCascade2.Clear(); var list = m_cullQuery.FrustumQuery[i].List; int N = list.Count; for (int j = 0; j < N; j++) { var item = list[j]; if (m_inCascade0.Contains(item) || m_inCascade1.Contains(item)) { // drop list.RemoveAtFast(j); j--; N--; } else if (m_cullQuery.FrustumQuery[i].IsInsideList[j]) { m_inCascade2.Add(item); } } // m_inCascade2_2.Clear(); var list2 = m_cullQuery.FrustumQuery[i].List2; N = list2.Count; for (int j = 0; j < N; j++) { var item = list2[j]; if (m_inCascade0_2.Contains(item) || m_inCascade1_2.Contains(item)) { // drop list2.RemoveAtFast(j); j--; N--; } else if (m_cullQuery.FrustumQuery[i].IsInsideList2[j]) { m_inCascade2_2.Add(item); } } MyPerformanceCounter.PerCameraDraw11Write.Cascade2ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count; } else if (m_cullQuery.FrustumQuery[i].Type == MyFrustumEnum.Cascade3) { var list = m_cullQuery.FrustumQuery[i].List; int N = list.Count; for (int j = 0; j < N; j++) { var item = list[j]; if (m_inCascade0.Contains(item) || m_inCascade1.Contains(item) || m_inCascade2.Contains(item)) { // drop list.RemoveAtFast(j); j--; N--; } } // var list2 = m_cullQuery.FrustumQuery[i].List2; N = list2.Count; for (int j = 0; j < N; j++) { var item = list2[j]; if (m_inCascade0_2.Contains(item) || m_inCascade1_2.Contains(item) || m_inCascade2_2.Contains(item)) { // drop list2.RemoveAtFast(j); j--; N--; } } MyPerformanceCounter.PerCameraDraw11Write.Cascade3ObjectsNum = m_cullQuery.FrustumQuery[i].List.Count; } if (m_cullQuery.FrustumQuery[i].Ignored != null) { var list = m_cullQuery.FrustumQuery[i].List; int N = list.Count; for (int j = 0; j < N; j++) { if (list[j].Proxies.Length > 0 && m_cullQuery.FrustumQuery[i].Ignored.Contains(list[j].Proxies[0].Parent.m_owner.ID)) { list.RemoveAtFast(j); j--; N--; } } } } MyRender11.GetRenderProfiler().EndProfilingBlock(); }
internal unsafe static void Render(ISrvBindable depthRead) { if (!MyRender11.DebugOverrides.BillboardsDynamic && !MyRender11.DebugOverrides.BillboardsStatic) { return; } if (m_batches.Count == 0) { return; } MyRender11.GetRenderProfiler().StartProfilingBlock("Draw"); TransferDataCustomProjections(); TransferDataBillboards(0, BillboardCountSafe, ref m_arrayDataBillboards); RC.PixelShader.SetSrv(1, depthRead); BindResourcesCommon(); for (int i = 0; i < m_batches.Count; i++) { // first part of batches contain sorted billboards and they read depth // second part of batches contain unsorted billboards and they ignore depth // switch here: if (m_batches[i].Offset == m_sortedCount) { //RC.BindDepthRT(null, DepthStencilAccess.ReadOnly, dst); } if (MyRender11.Settings.DisplayTransparencyHeatMap) { RC.VertexShader.Set(m_vs); RC.PixelShader.Set(MyRender11.DebugOverrides.OIT ? m_psDebugUniformAccumOIT : m_psDebugUniformAccum); } else if (m_batches[i].Lit) { RC.VertexShader.Set(m_vsLit); if (m_batches[i].AlphaCutout) { RC.PixelShader.Set(MyRender11.DebugOverrides.OIT ? m_psAlphaCutoutAndLitOIT : m_psAlphaCutoutAndLit); } else { RC.PixelShader.Set(MyRender11.DebugOverrides.OIT ? m_psLitOIT : m_psLit); } } else if (m_batches[i].AlphaCutout) { RC.VertexShader.Set(m_vs); RC.PixelShader.Set(MyRender11.DebugOverrides.OIT ? m_psAlphaCutoutOIT : m_psAlphaCutout); } else { RC.VertexShader.Set(m_vs); RC.PixelShader.Set(MyRender11.DebugOverrides.OIT ? m_psOIT : m_ps); } ISrvBindable texture = m_batches[i].Texture; RC.PixelShader.SetSrv(0, texture); if (!MyStereoRender.Enable) { RC.DrawIndexed(m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); } else { MyStereoRender.DrawIndexedBillboards(RC, m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); } IBorrowedRtvTexture borrowedTexture = texture as IBorrowedRtvTexture; if (borrowedTexture != null) { borrowedTexture.Release(); } MyStatsUpdater.Passes.DrawBillboards++; } m_stats.Billboards += BillboardCountSafe; RC.SetRasterizerState(null); MyRender11.GatherPassStats(1298737, "Billboards", m_stats); MyRender11.GetRenderProfiler().EndProfilingBlock(); }
internal static void Dispatch_LoopPassThenObject(List <MyRenderingPass> queues, MyCullQuery cullingResults, Queue <CommandList> accumulator) { MyRender11.GetRenderProfiler().StartProfilingBlock("PrepareWork"); m_workList.Clear(); accumulator.Clear(); List <List <MyRenderCullResultFlat> > passElements = new List <List <MyRenderCullResultFlat> >(); List <MyRenderableProxy_2[]> passElements2 = new List <MyRenderableProxy_2[]>(); foreach (var q in queues) { if (!MyRender11.DeferredContextsEnabled) { q.SetImmediate(true); } passElements.Add(new List <MyRenderCullResultFlat>()); passElements2.Add(null); } //bool okAfterCull = false; for (int i = 0; i < cullingResults.Size; i++) { var affectedQueueIds = new List <int>(); for (int j = 0; j < queues.Count; j++) { if ((queues[j].ProcessingMask & cullingResults.FrustumQuery[i].Bitmask) > 0) { affectedQueueIds.Add(j); } } //if (cullingResults.FrustumQuery[i].Type == MyFrustumEnum.MainFrustum) //{ // foreach (var e in cullingResults.FrustumQuery[i].List) // { // if (e.Proxies[0].Parent.m_owner.ID == 1417) // { // okAfterCull = true; // break; // } // } //} // proxy var list = cullingResults.FrustumQuery[i].List; for (int j = 0; j < list.Count; j++) { for (int k = 0; k < list[j].Proxies.Length; k++) { var proxy = list[j].Proxies[k]; var sortKey = list[j].SortingKeys[k]; for (int l = 0; l < affectedQueueIds.Count; l++) { var item = new MyRenderCullResultFlat(); item.renderProxy = proxy; item.sortKey = sortKey; passElements[affectedQueueIds[l]].Add(item); } } } // proxy 2 var list2 = cullingResults.FrustumQuery[i].List2; // flatten and sort List <UInt64> flattenedKeys = new List <ulong>(); List <int> indirection = new List <int>(); List <Tuple <int, int> > location = new List <Tuple <int, int> >(); int c = 0; for (int a = 0; a < list2.Count; a++) { for (int b = 0; b < list2[a].SortingKeys.Length; b++) { flattenedKeys.Add(list2[a].SortingKeys[b]); indirection.Add(c++); location.Add(Tuple.Create(a, b)); } } MyRenderableProxy_2[] flattenedProxies = new MyRenderableProxy_2[c]; var comparerer = new MySortingKeysComparerer(); comparerer.Values = flattenedKeys; indirection.Sort(0, indirection.Count, comparerer); for (int e = 0; e < c; e++) { var l = location[indirection[e]]; flattenedProxies[e] = list2[l.Item1].Proxies[l.Item2]; } for (int l = 0; l < affectedQueueIds.Count; l++) { passElements2[affectedQueueIds[l]] = flattenedProxies; } } foreach (var list in passElements) { list.Sort(MyCullResultsComparer.Instance); } //var okAfterSort = false; //for (int i = 0; i < queues.Count; i++ ) //{ // if (queues[i] as MyGBufferPass != null) // { // foreach (var e in passElements[i]) // { // if (e.renderProxy.Parent.m_owner.ID == 1417) // { // okAfterSort = true; // break; // } // } // } //} int jobsNum = GetRenderingThreadsNum(); // always amortize this path MyRender11.GetRenderProfiler().StartProfilingBlock("WorkAmortization"); //passElements.RemoveAll(x => x.Count == 0); int workSum = 0; foreach (var list in passElements) { workSum += list.Count; } int batchWork = (workSum + jobsNum - 1) / jobsNum; //var renderingWork = new MyRenderingWork_LoopPassObject(); var subworks = new List <MyRenderingWorkItem>(); int work = 0; for (int i = 0; i < passElements.Count; i++) { var list = passElements[i]; int passBegin = 0; subworks.Add(new MyRenderingWorkItem { Pass = queues[i].Fork(), List2 = passElements2[i] }); while (passBegin < list.Count) { var toTake = Math.Min(list.Count - passBegin, batchWork - work); var workItem = new MyRenderingWorkItem(); if (toTake < list.Count) { workItem.Pass = queues[i].Fork(); } else { workItem.Pass = queues[i]; } workItem.Renderables = list; workItem.Begin = passBegin; workItem.End = passBegin + toTake; //renderingWork.m_subworks.Add(workItem); subworks.Add(workItem); passBegin += toTake; work += toTake; if (work == batchWork) { if (MyRender11.DeferredContextsEnabled) { m_workList.Add(new MyRenderingWork_LoopPassThenObject(MyRenderContextPool.AcquireRC(), subworks)); } else { m_workList.Add(new MyRenderingWork_LoopPassThenObject(subworks)); } work = 0; subworks = new List <MyRenderingWorkItem>(); ///renderingWork = new MyRenderingWork_LoopPassObject(, subworks); } } } if (subworks.Count > 0) { if (MyRender11.DeferredContextsEnabled) { m_workList.Add(new MyRenderingWork_LoopPassThenObject(MyRenderContextPool.AcquireRC(), subworks)); } else { m_workList.Add(new MyRenderingWork_LoopPassThenObject(subworks)); } } //bool okInWorklist = false; //foreach(var wl in m_workList) //{ // var impl = wl as MyRenderingWork_LoopPassThenObject; // foreach(var sub in impl.m_subworks) // { // if((sub.Pass as MyGBufferPass) != null && sub.Renderables != null) // { // foreach(var r in sub.Renderables) // { // if(r.renderProxy.Parent.m_owner.ID == 1417) // { // okInWorklist = true; // break; // } // } // } // } //} MyRender11.GetRenderProfiler().EndProfilingBlock(); MyRender11.GetRenderProfiler().EndProfilingBlock(); ScheduleAndWait(accumulator); }
internal static void Dispatch_LoopObjectThenPass(List <MyRenderingPass> queues, MyCullQuery cullingResults, Queue <CommandList> accumulator) { MyRender11.GetRenderProfiler().StartProfilingBlock("PrepareWork"); m_workList.Clear(); m_indirection.Clear(); accumulator.Clear(); for (int i = 0; i < cullingResults.Size; i++) { var list = cullingResults.FrustumQuery[i].List; for (int j = 0; j < list.Count; j++) { for (int k = 0; k < list[j].Proxies.Length; k++) { var proxy = list[j].Proxies[k]; var sortKey = list[j].SortingKeys[k]; int index; if (!m_indirection.TryGetValue(proxy, out index)) { index = m_indirection.Count; m_indirection[proxy] = index; m_renderList[index].sortKey = sortKey; m_renderList[index].renderProxy = proxy; m_renderList[index].ProcessingMask = new BitVector32(); } // merge results m_renderList[index].ProcessingMask = new BitVector32(cullingResults.FrustumQuery[i].Bitmask | m_renderList[index].ProcessingMask.Data); } } } m_renderElementsNum = m_indirection.Count; Array.Sort(m_renderList, 0, m_renderElementsNum, MyCullResultsComparer.Instance); int jobsNum = GetRenderingThreadsNum(); if (MyRender11.Settings.AmortizeBatchWork) { MyRender11.GetRenderProfiler().StartProfilingBlock("WorkAmortization"); // calc approximated sum of work int workSum = 0; for (int i = 0; i < m_renderElementsNum; i++) { for (int p = 0; p < queues.Count; p++) { var union = (queues[p].ProcessingMask & m_renderList[i].ProcessingMask.Data); workSum += NumberOfSetBits(union); } } int batchWork = (workSum + jobsNum - 1) / jobsNum; int from = 0; int work = 0; for (int i = 0; i < m_renderElementsNum; i++) { for (int p = 0; p < queues.Count; p++) { var union = (queues[p].ProcessingMask & m_renderList[i].ProcessingMask.Data); work += NumberOfSetBits(union); } if (work > batchWork) { List <MyRenderingPass> contextCopy = new List <MyRenderingPass>(); foreach (var q in queues) { contextCopy.Add(q.ForkWithNewContext()); } m_workList.Add(new MyRenderingWork_LoopObjectThenPass(m_renderList, from, i, contextCopy)); from = i; work = 0; } } if (work > 0) { List <MyRenderingPass> contextCopy = new List <MyRenderingPass>(); foreach (var q in queues) { contextCopy.Add(q.ForkWithNewContext()); } m_workList.Add(new MyRenderingWork_LoopObjectThenPass(m_renderList, from, m_renderElementsNum, contextCopy)); } MyRender11.GetRenderProfiler().EndProfilingBlock(); } else { int batchWork = (m_renderElementsNum + jobsNum - 1) / jobsNum; for (int i = 0; i < jobsNum; i++) { List <MyRenderingPass> contextCopy = new List <MyRenderingPass>(); foreach (var q in queues) { contextCopy.Add(q.ForkWithNewContext()); } m_workList.Add(new MyRenderingWork_LoopObjectThenPass(m_renderList, i * batchWork, Math.Min((i + 1) * batchWork, m_renderElementsNum), contextCopy)); } } MyRender11.GetRenderProfiler().EndProfilingBlock(); ScheduleAndWait(accumulator); }
internal unsafe static void Render(MyBindableResource depthRead) { if (!MyRender11.DebugOverrides.BillboardsDynamic && !MyRender11.DebugOverrides.BillboardsStatic) { return; } m_stats.Clear(); MyRender11.GetRenderProfiler().StartProfilingBlock("Gather"); Gather(); MyRender11.GetRenderProfiler().EndProfilingBlock(); if (m_batches.Count == 0) { return; } MyRender11.GetRenderProfiler().StartProfilingBlock("Draw"); TransferDataCustomProjections(); TransferDataBillboards(BillboardCountSafe, ref m_arrayDataBillboards); RC.BindSRV(1, depthRead); BindResourcesCommon(); for (int i = 0; i < m_batches.Count; i++) { // first part of batches contain sorted billboards and they read depth // second part of batches contain unsorted billboards and they ignore depth // switch here: if (m_batches[i].Offset == m_sortedCount) { //RC.BindDepthRT(null, DepthStencilAccess.ReadOnly, dst); } if (m_batches[i].Lit) { RC.SetVS(m_vsLit); if (m_batches[i].AlphaCutout) { RC.SetPS(MyRender11.DebugOverrides.OIT ? m_psAlphaCutoutAndLitOIT : m_psAlphaCutoutAndLit); } else { RC.SetPS(MyRender11.DebugOverrides.OIT ? m_psLitOIT : m_psLit); } } else if (m_batches[i].AlphaCutout) { RC.SetVS(m_vs); RC.SetPS(MyRender11.DebugOverrides.OIT ? m_psAlphaCutoutOIT : m_psAlphaCutout); } else { RC.SetVS(m_vs); RC.SetPS(MyRender11.DebugOverrides.OIT ? m_psOIT : m_ps); } RC.BindRawSRV(0, m_batches[i].Texture); if (!MyStereoRender.Enable) { RC.DeviceContext.DrawIndexed(m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); } else { MyStereoRender.DrawIndexedBillboards(RC, m_batches[i].Num * 6, m_batches[i].Offset * 6, 0); } ++RC.Stats.BillboardDrawIndexed; } m_stats.Billboards += BillboardCountSafe; RC.SetRS(null); MyRender11.GatherStats(m_stats); MyRender11.GetRenderProfiler().EndProfilingBlock(); }