internal static void UpdateEnvironmentProbes(MyCullQuery cullQuery) { if (MyRender11.IsIntelBrokenCubemapsWorkaround) { return; } if (m_cubemapDepth == RwTexId.NULL) { m_cubemapDepth = MyRwTextures.CreateShadowmapArray(MyEnvironmentProbe.CubeMapResolution, MyEnvironmentProbe.CubeMapResolution, 6, Format.R24G8_Typeless, Format.D24_UNorm_S8_UInt, Format.R24_UNorm_X8_Typeless); } if (Instance.cubemapPrefiltered == RwTexId.NULL) { Instance.cubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.workCubemap = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Probe"); Instance.workCubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.prevWorkCubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.ImmediateProbe(cullQuery); } else { Instance.StepUpdateProbe(cullQuery); } }
internal static void PrepareCullQuery(MyCullQuery cullQuery, ListReader <MyShadowmapQuery> shadowmapQueries, bool updateEnvironmentMap) { cullQuery.AddMainViewPass(new MyViewport(MyRender11.ViewportResolution), MyGBuffer.Main); foreach (var shadowmapQuery in shadowmapQueries) { bool isCascade = shadowmapQuery.QueryType == MyFrustumEnum.ShadowCascade; var matrix = shadowmapQuery.ProjectionInfo.WorldToProjection; cullQuery.AddDepthPass(ref matrix, shadowmapQuery.ProjectionInfo.CurrentLocalToProjection, shadowmapQuery.Viewport, shadowmapQuery.DepthBuffer, isCascade, ToString(shadowmapQuery.QueryType)); if (isCascade) { var smallCulling = new MyCullingSmallObjects { ProjectionDir = shadowmapQuery.ProjectionDir, ProjectionFactor = shadowmapQuery.ProjectionFactor, SkipThreshold = MyRenderProxy.Settings.ShadowCascadeSmallSkipThresholds[shadowmapQuery.CascadeIndex] }; cullQuery.FrustumCullQueries[cullQuery.Size - 1].SmallObjects = smallCulling; cullQuery.FrustumCullQueries[cullQuery.Size - 1].CascadeIndex = shadowmapQuery.CascadeIndex; } cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = shadowmapQuery.QueryType; cullQuery.FrustumCullQueries[cullQuery.Size - 1].Ignored = shadowmapQuery.IgnoredEntities; } if (updateEnvironmentMap) { MyEnvironmentProbe.UpdateEnvironmentProbes(cullQuery); } }
/// <summary> /// Goes through all renderables and adds the ones that are in the given frustums to the lists in frustumCullQuery /// </summary> protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables) { ProfilerShort.Begin("DispatchFrustumCulling"); for (int frustumQueryIndex = 1; frustumQueryIndex < frustumCullQueries.Size; ++frustumQueryIndex) { var cullWork = MyObjectPoolManager.Allocate<MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[frustumQueryIndex], renderables); m_tmpCullingTasks.Add(Parallel.Start(cullWork)); } if (frustumCullQueries.Size > 0) { var cullWork = MyObjectPoolManager.Allocate<MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[0], renderables); cullWork.DoWork(); } foreach (Task cullingTask in m_tmpCullingTasks) { cullingTask.Wait(); } m_tmpCullingTasks.Clear(); foreach (MyFrustumCullingWork cullWork in m_tmpAllocatedWork) { MyObjectPoolManager.Deallocate(cullWork); } m_tmpAllocatedWork.Clear(); ProfilerShort.End(); }
/// <summary> /// Goes through all renderables and adds the ones that are in the given frustums to the lists in frustumCullQuery /// </summary> protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables) { ProfilerShort.Begin("DispatchFrustumCulling"); for (int frustumQueryIndex = 1; frustumQueryIndex < frustumCullQueries.Size; ++frustumQueryIndex) { var cullWork = MyObjectPoolManager.Allocate <MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[frustumQueryIndex], renderables); m_tmpCullingTasks.Add(Parallel.Start(cullWork)); } if (frustumCullQueries.Size > 0) { var cullWork = MyObjectPoolManager.Allocate <MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[0], renderables); cullWork.DoWork(); } foreach (Task cullingTask in m_tmpCullingTasks) { cullingTask.Wait(); } m_tmpCullingTasks.Clear(); foreach (MyFrustumCullingWork cullWork in m_tmpAllocatedWork) { MyObjectPoolManager.Deallocate(cullWork); } m_tmpAllocatedWork.Clear(); ProfilerShort.End(); }
void AddAllProbes(MyCullQuery cullQuery) { m_position = MyRender11.Environment.Matrices.CameraPosition; for (int i = 0; i < 6; i++) AddProbe(i, cullQuery); }
internal MyGeometryRenderer(MyDynamicAABBTreeD renderablesDBVH, MyShadows shadowHandler) { m_renderablesDBVH = renderablesDBVH; m_shadowHandler = shadowHandler; m_cullQuery = new MyCullQuery(); m_visibilityCuller = new MyFrustumCuller(); m_renderingDispatcher = new MyRenderingDispatcher(); }
internal void UpdateCullQuery(MyCullQuery cullQuery) { if (MyRender11.IsIntelBrokenCubemapsWorkaround) { return; } if (m_isInit == false) { m_isInit = true; // compute mipmapLevels int mipmapLevels = 0; for (int tmp = MyEnvironmentProbe.CubeMapResolution; tmp != 1;) { mipmapLevels++; tmp = tmp / 2 + tmp % 2; } MyArrayTextureManager texManager = MyManagers.ArrayTextures; Cubemap = texManager.CreateUavCube("MyEnvironmentProbe.CubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_workCubemap = texManager.CreateUavCube("MyEnvironmentProbe.WorkCubemap", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_workCubemapPrefiltered = texManager.CreateUavCube( "MyEnvironmentProbe.WorkCubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_prevWorkCubemapPrefiltered = texManager.CreateUavCube("MyEnvironmentProbe.PrevWorkCubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); CubemapDepth = MyManagers.ArrayTextures.CreateDepthCube("MyEnvironmentProbe.CubemapDepth", MyEnvironmentProbe.CubeMapResolution, Format.R24G8_Typeless, Format.R24_UNorm_X8_Typeless, Format.D24_UNorm_S8_UInt); m_lastUpdateTime = MyTimeSpan.Zero; m_state = 0; AddAllProbes(cullQuery); } else { if (m_lastUpdateTime == MyTimeSpan.Zero) { AddAllProbes(cullQuery); } else { if (m_state == 0) { m_position = MyRender11.Environment.Matrices.CameraPosition; } if (m_state < 6) { AddProbe(m_state, cullQuery); } } } }
internal void PerformCulling(MyCullQuery cullQuery, MyDynamicAABBTreeD renderableBVH) { ProfilerShort.Begin("DispatchCulling"); DispatchCullQuery(cullQuery, renderableBVH); ProfilerShort.BeginNextBlock("ProcessCullResults"); ProcessCullQueryResults(cullQuery); ProfilerShort.End(); }
void AddAllProbes(MyCullQuery cullQuery) { m_position = MyRender11.Environment.Matrices.CameraPosition; for (int i = 0; i < 6; i++) { AddProbe(i, cullQuery); } }
internal void ImmediateProbe(MyCullQuery cullQuery) { // reset state = 0; var prevState = state; StepUpdateProbe(cullQuery); while (prevState != state) { prevState = state; StepUpdateProbe(cullQuery); } }
internal void UpdateCullQuery(MyCullQuery cullQuery) { if (MyRender11.IsIntelBrokenCubemapsWorkaround) return; if (m_isInit == false) { m_isInit = true; // compute mipmapLevels int mipmapLevels = 0; for (int tmp = MyEnvironmentProbe.CubeMapResolution; tmp != 1;) { mipmapLevels++; tmp = tmp/2 + tmp%2; } MyArrayTextureManager texManager = MyManagers.ArrayTextures; Cubemap = texManager.CreateUavCube("MyEnvironmentProbe.CubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_workCubemap = texManager.CreateUavCube("MyEnvironmentProbe.WorkCubemap", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_workCubemapPrefiltered = texManager.CreateUavCube( "MyEnvironmentProbe.WorkCubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); m_prevWorkCubemapPrefiltered = texManager.CreateUavCube("MyEnvironmentProbe.PrevWorkCubemapPrefiltered", MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, mipmapLevels); CubemapDepth = MyManagers.ArrayTextures.CreateDepthCube("MyEnvironmentProbe.CubemapDepth", MyEnvironmentProbe.CubeMapResolution, Format.R24G8_Typeless, Format.R24_UNorm_X8_Typeless, Format.D24_UNorm_S8_UInt); m_lastUpdateTime = MyTimeSpan.Zero; m_state = 0; AddAllProbes(cullQuery); } else { if (m_lastUpdateTime == MyTimeSpan.Zero) AddAllProbes(cullQuery); else { if (m_state == 0) m_position = MyRender11.Environment.Matrices.CameraPosition; if (m_state < 6) AddProbe(m_state, cullQuery); } } }
void AddProbe(int nProbe, MyCullQuery cullQuery) { MyImmediateRC.RC.ClearDsv(CubemapDepth.SubresourceDsv(nProbe), DepthStencilClearFlags.Depth, 1, 0); MyImmediateRC.RC.ClearRtv(m_workCubemap.SubresourceRtv(nProbe), Color4.Black); var localViewProj = PrepareLocalEnvironmentMatrix(MyRender11.Environment.Matrices.CameraPosition - m_position, new Vector2I(CubeMapResolution, CubeMapResolution), nProbe, MyRender11.Settings.EnvMapDepth); var viewProj = MatrixD.CreateTranslation(-m_position)*localViewProj; cullQuery.AddForwardPass(ref localViewProj, ref viewProj, new MyViewport(0, 0, CubeMapResolution, CubeMapResolution), CubemapDepth.SubresourceDsv(nProbe), m_workCubemap.SubresourceRtv(nProbe)); cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = MyFrustumEnum.EnvironmentProbe; }
void AddProbe(int nProbe, MyCullQuery cullQuery) { MyImmediateRC.RC.ClearDsv(CubemapDepth.SubresourceDsv(nProbe), DepthStencilClearFlags.Depth, 1, 0); MyImmediateRC.RC.ClearRtv(m_workCubemap.SubresourceRtv(nProbe), Color4.Black); var localViewProj = PrepareLocalEnvironmentMatrix(MyRender11.Environment.Matrices.CameraPosition - m_position, new Vector2I(CubeMapResolution, CubeMapResolution), nProbe, MyRender11.Settings.EnvMapDepth); var viewProj = MatrixD.CreateTranslation(-m_position) * localViewProj; cullQuery.AddForwardPass(ref localViewProj, ref viewProj, new MyViewport(0, 0, CubeMapResolution, CubeMapResolution), CubemapDepth.SubresourceDsv(nProbe), m_workCubemap.SubresourceRtv(nProbe)); cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = MyFrustumEnum.EnvironmentProbe; }
// Sends information about the visible objects in cullQuery to MyRenderProxy void SendOutputMessages(MyCullQuery cullQuery) { ProfilerShort.Begin("SendOutputMessages"); ProfilerShort.Begin("FrustumEntities"); for (int cullQueryIndex = 0; cullQueryIndex < cullQuery.Size; ++cullQueryIndex ) { var frustumQuery = cullQuery.FrustumCullQueries[cullQueryIndex]; foreach (MyCullProxy cullProxy in frustumQuery.List) { MyRenderProxy.VisibleObjectsWrite.Add(cullProxy.OwnerID); } } ProfilerShort.End(); ProfilerShort.End(); }
// Sends information about the visible objects in cullQuery to MyRenderProxy void SendOutputMessages(MyCullQuery cullQuery) { ProfilerShort.Begin("SendOutputMessages"); ProfilerShort.Begin("FrustumEntities"); for (int cullQueryIndex = 0; cullQueryIndex < cullQuery.Size; ++cullQueryIndex) { var frustumQuery = cullQuery.FrustumCullQueries[cullQueryIndex]; foreach (MyCullProxy cullProxy in frustumQuery.List) { MyRenderProxy.VisibleObjectsWrite.Add(cullProxy.OwnerID); } } ProfilerShort.End(); ProfilerShort.End(); }
static void AddShadowmapQueryIntoCullQuery(MyCullQuery cullQuery, MyShadowmapQuery shadowmapQuery) { cullQuery.AddDepthPass(shadowmapQuery); if (shadowmapQuery.QueryType == MyFrustumEnum.ShadowCascade) { var smallCulling = new MyCullingSmallObjects { ProjectionFactor = shadowmapQuery.ProjectionFactor, // <- this disables culling of objects depending on the previous cascade SkipThreshold = MyManagers.Shadow.GetSettingsSmallObjectSkipping(shadowmapQuery.Index), }; cullQuery.FrustumCullQueries[cullQuery.Size - 1].SmallObjects = smallCulling; } cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = shadowmapQuery.QueryType; cullQuery.FrustumCullQueries[cullQuery.Size - 1].Index = shadowmapQuery.Index; cullQuery.FrustumCullQueries[cullQuery.Size - 1].Ignored = shadowmapQuery.IgnoredEntities; }
internal static void PrepareCullQuery(MyCullQuery cullQuery, ListReader <MyShadowmapQuery> shadowmapQueries, bool updateEnvironmentMap) { cullQuery.AddMainViewPass(new MyViewport(MyRender11.ViewportResolution), MyGBuffer.Main); foreach (var shadowmapQuery in shadowmapQueries) // old shadowing system { AddShadowmapQueryIntoCullQuery(cullQuery, shadowmapQuery); } //m_tmpShadowmapQueries.Clear(); //MyManagers.ShadowCore.PrepareShadowmapQueries(ref m_tmpShadowmapQueries); //foreach (var shadowmapQuery in m_tmpShadowmapQueries) // new shadowing system // AddShadowmapQueryIntoCullQuery(cullQuery, shadowmapQuery); if (updateEnvironmentMap) { MyManagers.EnvironmentProbe.UpdateCullQuery(cullQuery); } }
/// <summary> /// Goes through all renderables and adds the ones that are in the given frustums to the lists in frustumCullQuery /// </summary> protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables) { ProfilerShort.Begin("DispatchFrustumCulling"); for (int frustumQueryIndex = 1; frustumQueryIndex < frustumCullQueries.Size; ++frustumQueryIndex) { var cullWork = MyObjectPoolManager.Allocate <MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[frustumQueryIndex], renderables); m_tmpCullingTasks.Add(Parallel.Start(cullWork)); } if (frustumCullQueries.Size > 0) { var cullWork = MyObjectPoolManager.Allocate <MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[0], renderables); cullWork.DoWork(); } foreach (Task cullingTask in m_tmpCullingTasks) { cullingTask.Wait(); } m_tmpCullingTasks.Clear(); int i = 0; foreach (MyFrustumCullingWork cullWork in m_tmpAllocatedWork) { ProfilerShort.Begin(frustumCullQueries.FrustumCullQueries[i].Type.ToString()); ProfilerShort.End(frustumCullQueries.FrustumCullQueries[i].List.Count + frustumCullQueries.FrustumCullQueries[i].List2.Count, new VRage.Library.Utils.MyTimeSpan(cullWork.Elapsed)); MyObjectPoolManager.Deallocate(cullWork); i++; } m_tmpAllocatedWork.Clear(); ProfilerShort.End(); }
static void AddShadowmapQueryIntoCullQuery(MyCullQuery cullQuery, MyShadowmapQuery shadowmapQuery) { bool isCascade = shadowmapQuery.QueryType == MyFrustumEnum.ShadowCascade; var matrix = shadowmapQuery.ProjectionInfo.WorldToProjection; cullQuery.AddDepthPass(ref matrix, shadowmapQuery.ProjectionInfo.CurrentLocalToProjection, shadowmapQuery.Viewport, shadowmapQuery.DepthBuffer, isCascade, ToString(shadowmapQuery.QueryType)); if (isCascade) { var smallCulling = new MyCullingSmallObjects { ProjectionFactor = shadowmapQuery.ProjectionFactor, // <- this disables culling of objects depending on the previous cascade SkipThreshold = MyManagers.Shadow.GetSettingsSmallObjectSkipping(shadowmapQuery.CascadeIndex), }; cullQuery.FrustumCullQueries[cullQuery.Size - 1].SmallObjects = smallCulling; cullQuery.FrustumCullQueries[cullQuery.Size - 1].CascadeIndex = shadowmapQuery.CascadeIndex; } cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = shadowmapQuery.QueryType; cullQuery.FrustumCullQueries[cullQuery.Size - 1].Ignored = shadowmapQuery.IgnoredEntities; }
/// <summary> /// Goes through all renderables and adds the ones that are in the given frustums to the lists in frustumCullQuery /// </summary> protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables) { ProfilerShort.Begin("DispatchFrustumCulling"); for (int frustumQueryIndex = 1; frustumQueryIndex < frustumCullQueries.Size; ++frustumQueryIndex) { var cullWork = MyObjectPoolManager.Allocate<MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[frustumQueryIndex], renderables); m_tmpCullingTasks.Add(Parallel.Start(cullWork)); } if (frustumCullQueries.Size > 0) { var cullWork = MyObjectPoolManager.Allocate<MyFrustumCullingWork>(); m_tmpAllocatedWork.Add(cullWork); cullWork.Init(frustumCullQueries.FrustumCullQueries[0], renderables); cullWork.DoWork(); } foreach (Task cullingTask in m_tmpCullingTasks) { cullingTask.Wait(); } m_tmpCullingTasks.Clear(); int i = 0; foreach (MyFrustumCullingWork cullWork in m_tmpAllocatedWork) { ProfilerShort.Begin(frustumCullQueries.FrustumCullQueries[i].Type.ToString()); ProfilerShort.End(frustumCullQueries.FrustumCullQueries[i].List.Count + frustumCullQueries.FrustumCullQueries[i].List2.Count, new VRage.Library.Utils.MyTimeSpan(cullWork.Elapsed)); MyObjectPoolManager.Deallocate(cullWork); i++; } m_tmpAllocatedWork.Clear(); ProfilerShort.End(); }
internal void StepUpdateProbe(MyCullQuery cullQuery) { if (state == 0) { position = MyRender11.Environment.CameraPosition;// +Vector3.UnitY * 4; } if (state < 6) { int faceId = state; MyImmediateRC.RC.DeviceContext.ClearDepthStencilView(m_cubemapDepth.SubresourceDsv(faceId), DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1, 0); MyImmediateRC.RC.DeviceContext.ClearRenderTargetView(workCubemap.SubresourceRtv(faceId), new Color4(0, 0, 0, 0)); var localViewProj = PrepareLocalEnvironmentMatrix(MyRender11.Environment.CameraPosition - position, new Vector2I(CubeMapResolution, CubeMapResolution), faceId, 10000.0f); var viewProj = MatrixD.CreateTranslation(-position) * localViewProj; cullQuery.AddForwardPass(ref localViewProj, ref viewProj, new MyViewport(0, 0, CubeMapResolution, CubeMapResolution), m_cubemapDepth.SubresourceDsv(faceId), workCubemap.SubresourceRtv(faceId)); ++state; return; } }
internal void StepUpdateProbe(MyCullQuery cullQuery) { if (state == 0) { position = MyEnvironment.CameraPosition;// +Vector3.UnitY * 4; } if (state < 6) { int faceId = state; MyImmediateRC.RC.DeviceContext.ClearDepthStencilView(m_cubemapDepth.SubresourceDsv(faceId), DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1, 0); MyImmediateRC.RC.DeviceContext.ClearRenderTargetView(workCubemap.SubresourceRtv(faceId), new Color4(0, 0, 0, 0)); var localViewProj = PrepareLocalEnvironmentMatrix(MyEnvironment.CameraPosition - position, new Vector2I(CubeMapResolution, CubeMapResolution), faceId, 10000.0f); var viewProj = MatrixD.CreateTranslation(-position) * localViewProj; cullQuery.AddForwardPass(ref localViewProj, ref viewProj, new MyViewport(0, 0, CubeMapResolution, CubeMapResolution), m_cubemapDepth.SubresourceDsv(faceId), workCubemap.SubresourceRtv(faceId)); ++state; return; } }
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 void RecordCommandLists(MyCullQuery processedCullQuery, Queue <CommandList> outCommandLists) { ProfilerShort.Begin("PrepareWork"); ProfilerShort.Begin("Init"); Debug.Assert(m_workList.Count == 0, "Work list not cleared after use!"); foreach (List <MyRenderCullResultFlat> cullResults in m_passElements) { cullResults.Clear(); m_resultListPool.Deallocate(cullResults); } m_passElements.Clear(); m_passElements2.Clear(); for (int renderPassIndex = 0; renderPassIndex < processedCullQuery.Size; ++renderPassIndex) { if (!MyRender11.DeferredContextsEnabled) { processedCullQuery.RenderingPasses[renderPassIndex].SetImmediate(true); } m_passElements.Add(m_resultListPool.Allocate()); m_passElements2.Add(null); } ProfilerShort.BeginNextBlock("Flatten"); for (int i = 0; i < processedCullQuery.Size; ++i) { m_affectedQueueIds.SetSize(0); var frustumQuery = processedCullQuery.FrustumCullQueries[i]; for (int renderPassIndex = 0; renderPassIndex < processedCullQuery.Size; renderPassIndex++) { if ((processedCullQuery.RenderingPasses[renderPassIndex].ProcessingMask & frustumQuery.Bitmask) > 0) { m_affectedQueueIds.Add(renderPassIndex); } } var cullProxies = frustumQuery.List; var queryType = frustumQuery.Type; foreach (MyCullProxy cullProxy in cullProxies) { var renderableProxies = cullProxy.RenderableProxies; if (renderableProxies == null) { continue; } for (int proxyIndex = 0; proxyIndex < renderableProxies.Length; ++proxyIndex) { var flag = renderableProxies[proxyIndex].DrawSubmesh.Flags; if (queryType == MyFrustumEnum.MainFrustum) { if ((flag & MyDrawSubmesh.MySubmeshFlags.Gbuffer) != MyDrawSubmesh.MySubmeshFlags.Gbuffer) { continue; } } else if (queryType == MyFrustumEnum.ShadowCascade || queryType == MyFrustumEnum.ShadowProjection) { if ((flag & MyDrawSubmesh.MySubmeshFlags.Depth) != MyDrawSubmesh.MySubmeshFlags.Depth) { continue; } } MyRenderableProxy renderableProxy = renderableProxies[proxyIndex]; ulong sortKey = cullProxy.SortingKeys[proxyIndex]; var item = new MyRenderCullResultFlat { SortKey = sortKey, RenderProxy = renderableProxy, }; if (renderableProxy.Material != MyMeshMaterialId.NULL && renderableProxy.Material.Info.Technique == MyMeshDrawTechnique.GLASS) { if (queryType == MyFrustumEnum.MainFrustum) { MyStaticGlassRenderer.Renderables.Add(item); } continue; } for (int queueIndex = 0; queueIndex < m_affectedQueueIds.Count; ++queueIndex) { var queueId = m_affectedQueueIds[queueIndex]; m_passElements[queueId].Add(item); } } } // proxy 2 var list2 = frustumQuery.List2; // flatten and sort m_flattenedKeys.SetSize(0); m_indirectionList.SetSize(0); m_location.SetSize(0); int indirectionCounter = 0; for (int list2Index = 0; list2Index < list2.Count; ++list2Index) { for (int sortKeyIndex = 0; sortKeyIndex < list2[list2Index].SortingKeys.Length; sortKeyIndex++) { m_flattenedKeys.Add(list2[list2Index].SortingKeys[sortKeyIndex]); m_indirectionList.Add(indirectionCounter++); m_location.Add(MyTuple.Create(list2Index, sortKeyIndex)); } } MyRenderableProxy_2[] flattenedProxies = null; if (indirectionCounter > 0) { flattenedProxies = new MyRenderableProxy_2[indirectionCounter]; } m_sortingKeysComparer.Values = m_flattenedKeys; m_indirectionList.Sort(0, m_indirectionList.Count, m_sortingKeysComparer); if (flattenedProxies != null) { for (int e = 0; e < indirectionCounter; e++) { var l = m_location[m_indirectionList[e]]; flattenedProxies[e] = list2[l.Item1].Proxies[l.Item2]; } } for (int l = 0; l < m_affectedQueueIds.Count; l++) { m_passElements2[m_affectedQueueIds[l]] = flattenedProxies; } } ProfilerShort.BeginNextBlock("Sort"); m_tmpSortListDictionary.Clear(); m_resultSortedKeys.Clear(); for (int i = 0; i < m_passElements.Count; i++) { var flatCullResults = m_passElements[i]; foreach (MyRenderCullResultFlat element in flatCullResults) { List <MyPassCullResult> sortList; if (!m_tmpSortListDictionary.TryGetValue(element.SortKey, out sortList)) { sortList = m_sortListPool.Allocate(); m_tmpSortListDictionary.Add(element.SortKey, sortList); m_resultSortedKeys.Add(element.SortKey); } sortList.Add(new MyPassCullResult() { PassIndex = i, CullResult = element }); } flatCullResults.Clear(); } m_resultSortedKeys.Sort(); foreach (ulong sortKey in m_resultSortedKeys) { List <MyPassCullResult> sortList = m_tmpSortListDictionary[sortKey]; foreach (var result in sortList) { m_passElements[result.PassIndex].Add(result.CullResult); } sortList.SetSize(0); m_sortListPool.Deallocate(sortList); } int jobsNum = GetRenderingThreadsNum(); // always amortize this path ProfilerShort.BeginNextBlock("WorkAmortization"); //passElements.RemoveAll(x => x.Count == 0); int workSum = 0; foreach (var list in m_passElements) { workSum += list.Count; } int batchWork = (workSum + jobsNum - 1) / jobsNum; Debug.Assert(m_subworks.Count == 0); int work = 0; for (int passElementIndex = 0; passElementIndex < m_passElements.Count; ++passElementIndex) { var flatCullResults = m_passElements[passElementIndex]; if (flatCullResults.Count == 0) { MyObjectPoolManager.Deallocate(processedCullQuery.RenderingPasses[passElementIndex]); processedCullQuery.RenderingPasses[passElementIndex] = null; if (m_passElements2[passElementIndex] == null || m_passElements2[passElementIndex].Length == 0) { continue; } } if (processedCullQuery.RenderingPasses[passElementIndex] == null) { continue; } int passBegin = 0; if (m_passElements2[passElementIndex] != null && m_passElements2[passElementIndex].Length > 0) { m_subworks.Add(new MyRenderingWorkItem { Pass = processedCullQuery.RenderingPasses[passElementIndex].Fork(), List2 = m_passElements2[passElementIndex] }); } while (passBegin < flatCullResults.Count) { int toTake = Math.Min(flatCullResults.Count - passBegin, batchWork - work); var workItem = new MyRenderingWorkItem { Renderables = flatCullResults, Begin = passBegin, End = passBegin + toTake }; if (toTake < flatCullResults.Count && workItem.End != workItem.Renderables.Count) { workItem.Pass = processedCullQuery.RenderingPasses[passElementIndex].Fork(); } else { workItem.Pass = processedCullQuery.RenderingPasses[passElementIndex]; processedCullQuery.RenderingPasses[passElementIndex] = null; // Consume the pass so it doesn't get cleaned up later with the cull query, but instead with the work item } m_subworks.Add(workItem); passBegin += toTake; work += toTake; Debug.Assert(work <= batchWork); if (work != batchWork) { continue; } if (MyRender11.DeferredContextsEnabled) { var renderWork = MyObjectPoolManager.Allocate <MyRenderingWorkRecordCommands>(); renderWork.Init(MyManagers.DeferredRCs.AcquireRC(), m_subworks); m_workList.Add(renderWork); } else { var renderWork = MyObjectPoolManager.Allocate <MyRenderingWorkRecordCommands>(); renderWork.Init(m_subworks); m_workList.Add(renderWork); } work = 0; m_subworks.Clear(); } } if (m_subworks.Count > 0) { if (MyRender11.DeferredContextsEnabled) { var renderWork = MyObjectPoolManager.Allocate <MyRenderingWorkRecordCommands>(); renderWork.Init(MyManagers.DeferredRCs.AcquireRC(), m_subworks); m_workList.Add(renderWork); } else { var renderWork = MyObjectPoolManager.Allocate <MyRenderingWorkRecordCommands>(); renderWork.Init(m_subworks); m_workList.Add(renderWork); } m_subworks.Clear(); } ProfilerShort.End(); ProfilerShort.End(); DoRecordingWork(outCommandLists); foreach (var renderWork in m_workList) { foreach (var pass in renderWork.Passes) { ProfilerShort.Begin(pass.DebugName); ProfilerShort.End(0, new VRage.Library.Utils.MyTimeSpan(pass.Elapsed)); } MyObjectPoolManager.Deallocate(renderWork); } m_workList.Clear(); }
internal static void PrepareCullQuery(MyCullQuery cullQuery, ListReader<MyShadowmapQuery> shadowmapQueries, bool updateEnvironmentMap) { cullQuery.AddMainViewPass(new MyViewport(MyRender11.ViewportResolution), MyGBuffer.Main); foreach (var shadowmapQuery in shadowmapQueries) { bool isCascade = shadowmapQuery.QueryType == MyFrustumEnum.ShadowCascade; var matrix = shadowmapQuery.ProjectionInfo.WorldToProjection; cullQuery.AddDepthPass(ref matrix, shadowmapQuery.ProjectionInfo.CurrentLocalToProjection, shadowmapQuery.Viewport, shadowmapQuery.DepthBuffer, isCascade, ToString(shadowmapQuery.QueryType)); if (isCascade) { var smallCulling = new MyCullingSmallObjects { ProjectionDir = shadowmapQuery.ProjectionDir, ProjectionFactor = shadowmapQuery.ProjectionFactor, SkipThreshold = MyRenderProxy.Settings.ShadowCascadeSmallSkipThresholds[shadowmapQuery.CascadeIndex] }; cullQuery.FrustumCullQueries[cullQuery.Size - 1].SmallObjects = smallCulling; cullQuery.FrustumCullQueries[cullQuery.Size - 1].CascadeIndex = shadowmapQuery.CascadeIndex; } cullQuery.FrustumCullQueries[cullQuery.Size - 1].Type = shadowmapQuery.QueryType; cullQuery.FrustumCullQueries[cullQuery.Size - 1].Ignored = shadowmapQuery.IgnoredEntities; } if (updateEnvironmentMap) MyEnvironmentProbe.UpdateEnvironmentProbes(cullQuery); }
protected override void ProcessCullQueryResults(MyCullQuery cullQuery) { throw new NotImplementedException(); }
protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables) { throw new NotImplementedException(); }
protected abstract void ProcessCullQueryResults(MyCullQuery cullQuery);
internal static void PrepareCullQuery(MyCullQuery cullQuery, ListReader<MyShadowmapQuery> shadowmapQueries, bool updateEnvironmentMap) { cullQuery.AddMainViewPass(new MyViewport(MyRender11.ViewportResolution), MyGBuffer.Main); foreach (var shadowmapQuery in shadowmapQueries) // old shadowing system AddShadowmapQueryIntoCullQuery(cullQuery, shadowmapQuery); //m_tmpShadowmapQueries.Clear(); //MyManagers.ShadowCore.PrepareShadowmapQueries(ref m_tmpShadowmapQueries); //foreach (var shadowmapQuery in m_tmpShadowmapQueries) // new shadowing system // AddShadowmapQueryIntoCullQuery(cullQuery, shadowmapQuery); if (updateEnvironmentMap) MyManagers.EnvironmentProbe.UpdateCullQuery(cullQuery); }
// Returns the final image and copies it to renderTarget if non-null private static IRtvTexture DrawGameScene(IRtvBindable renderTarget, out IBorrowedRtvTexture debugAmbientOcclusion) { MyGpuProfiler.IC_BeginBlockAlways("ClearAndGeometryRender"); PrepareGameScene(); // todo: shouldn't be necessary if (true) { ProfilerShort.Begin("Clear"); MyRender11.RC.ClearState(); ProfilerShort.End(); } if (MyStereoRender.Enable && MyStereoRender.EnableUsingStencilMask) { ProfilerShort.Begin("MyStereoStencilMask.Draw"); MyGpuProfiler.IC_BeginBlock("MyStereoStencilMask.Draw"); MyStereoStencilMask.Draw(); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); } ProfilerShort.Begin("MyLights.Update"); MyLights.Update(); ProfilerShort.End(); ProfilerShort.Begin("DynamicGeometryRenderer"); MyCullQuery cullQuery = m_dynamicGeometryRenderer.PrepareCullQuery(true); // it is used to share rendering settings between the old and the new pipeline ProfilerShort.End(); MyGpuProfiler.IC_BeginBlock("NewGeometryRenderer"); ProfilerShort.Begin("NewGeometryRenderer"); IGeometrySrvStrategy geometrySrvStrategy = MyManagers.GeometrySrvResolver.GetGeometrySrvStrategy(); if (MyDebugGeometryStage2.EnableNewGeometryPipeline) { MyManagers.GeometryRenderer.Render(cullQuery, geometrySrvStrategy); } ProfilerShort.End(); MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("MyGeometryRenderer.Render"); Debug.Assert(m_commandLists.Count == 0, "Not all command lists executed last frame!"); ProfilerShort.Begin("DynamicGeometryRenderer"); m_dynamicGeometryRenderer.Render(m_commandLists); ProfilerShort.End(); // End function block if (MyScene.SeparateGeometry) { ProfilerShort.Begin("StaticGeometryRenderer"); m_staticGeometryRenderer.Render(m_commandLists); // , false); ProfilerShort.End(); // End function block } SendGlobalOutputMessages(); ExecuteCommandLists(m_commandLists); MyGpuProfiler.IC_EndBlock(); #if !UNSHARPER_TMP MyManagers.EnvironmentProbe.FinalizeEnvProbes(); #endif // cleanup context atfer deferred lists if (true) { ProfilerShort.Begin("Clear3"); MyRender11.RC.ClearState(); ProfilerShort.End(); } MyGpuProfiler.IC_EndBlockAlways(); IBorrowedRtvTexture gbuffer1Copy = MyGBuffer.Main.GetGbuffer1CopyRtv(); ProfilerShort.Begin("Render decals - Opaque"); MyGpuProfiler.IC_BeginBlock("Render decals - Opaque"); MyScreenDecals.Draw(gbuffer1Copy, false); MyGpuProfiler.IC_EndBlock(); IBorrowedDepthStencilTexture depthStencilCopy = null; // Highlights need the depth state before foliage if (MyHighlight.HasHighlights) { depthStencilCopy = MyGBuffer.Main.GetDepthStencilCopyRtv(); } ProfilerShort.BeginNextBlock("Render foliage"); MyGpuProfiler.IC_BeginBlockAlways("RenderFoliage"); m_foliageRenderer.Render(); MyGpuProfiler.IC_EndBlockAlways(); MyGpuProfiler.IC_BeginBlock("GBuffer Resolve"); ProfilerShort.BeginNextBlock("MySceneMaterials.MoveToGPU"); MySceneMaterials.MoveToGPU(); MyRender11.RC.ResetTargets(); IBorrowedRtvTexture ambientOcclusionRtv = MyManagers.RwTexturesPool.BorrowRtv("MyScreenDependants.AmbientOcclusion", ResolutionI.X, ResolutionI.Y, SharpDX.DXGI.Format.R8_UNorm); debugAmbientOcclusion = ambientOcclusionRtv; // Pass the texture to the outside int nPasses = MyStereoRender.Enable ? 2 : 1; for (int i = 0; i < nPasses; i++) { if (MyStereoRender.Enable) { MyStereoRender.RenderRegion = i == 0 ? MyStereoRegion.LEFT : MyStereoRegion.RIGHT; } MyGBuffer.Main.ResolveMultisample(); ProfilerShort.BeginNextBlock("Shadows"); MyGpuProfiler.IC_BeginBlockAlways("Shadows"); IBorrowedUavTexture postProcessedShadows; if (MyScene.SeparateGeometry) { MyShadowCascadesPostProcess.Combine(MyShadowCascades.CombineShadowmapArray, DynamicShadows.ShadowCascades, StaticShadows.ShadowCascades); postProcessedShadows = DynamicShadows.ShadowCascades.PostProcess(MyShadowCascades.CombineShadowmapArray); //MyShadowCascadesPostProcess.Combine(MyShadowCascades.CombineShadowmapArray, // DynamicShadows.ShadowCascades, StaticShadows.ShadowCascades); //postProcessedShadows = // DynamicShadows.ShadowCascades.PostProcess(MyShadowCascades.CombineShadowmapArray); } else { postProcessedShadows = DynamicShadows.ShadowCascades.PostProcess(DynamicShadows.ShadowCascades.CascadeShadowmapArray); //postProcessedShadows = MyManagers.Shadow.Evaluate(); } MyGpuProfiler.IC_EndBlockAlways(); if (MySSAO.Params.Enabled && Settings.User.AmbientOcclusionEnabled && m_debugOverrides.Postprocessing && m_debugOverrides.SSAO) { ProfilerShort.BeginNextBlock("SSAO"); MyGpuProfiler.IC_BeginBlockAlways("SSAO"); MySSAO.Run(ambientOcclusionRtv, MyGBuffer.Main); if (MySSAO.Params.UseBlur) { IBorrowedRtvTexture ambientOcclusionHelper = MyManagers.RwTexturesPool.BorrowRtv("MyScreenDependants.AmbientOcclusionHelper", ResolutionI.X, ResolutionI.Y, SharpDX.DXGI.Format.R8_UNorm); MyBlur.Run(ambientOcclusionRtv, ambientOcclusionHelper, ambientOcclusionRtv, clearColor: Color4.White); ambientOcclusionHelper.Release(); } MyGpuProfiler.IC_EndBlockAlways(); } else if (MyHBAO.Params.Enabled && Settings.User.AmbientOcclusionEnabled && m_debugOverrides.Postprocessing && m_debugOverrides.SSAO) { ProfilerShort.BeginNextBlock("HBAO"); MyGpuProfiler.IC_BeginBlock("HBAO"); MyHBAO.Run(ambientOcclusionRtv, MyGBuffer.Main); MyGpuProfiler.IC_EndBlock(); } else { MyRender11.RC.ClearRtv(ambientOcclusionRtv, Color4.White); } ProfilerShort.BeginNextBlock("Lights"); MyGpuProfiler.IC_BeginBlockAlways("Lights"); if (m_debugOverrides.Lighting) { MyLightsRendering.Render(postProcessedShadows, ambientOcclusionRtv); } MyGpuProfiler.IC_EndBlockAlways(); postProcessedShadows.Release(); if (MyRender11.DebugOverrides.Flares) { MyLightsRendering.DrawFlares(); } } MyStereoRender.RenderRegion = MyStereoRegion.FULLSCREEN; MyGpuProfiler.IC_EndBlock(); ProfilerShort.BeginNextBlock("Occlusion Queries"); MyGpuProfiler.IC_BeginBlock("Occlusion Queries"); MyOcclusionQueryRenderer.Render(RC, MyGBuffer.Main.ResolvedDepthStencil, MyGBuffer.Main.LBuffer); MyGpuProfiler.IC_EndBlock(); // Rendering for VR is solved inside of Transparent rendering ProfilerShort.BeginNextBlock("Transparent Pass"); MyGpuProfiler.IC_BeginBlockAlways("TransparentPass"); if (m_debugOverrides.Transparent) { MyTransparentRendering.Render(gbuffer1Copy); } MyGpuProfiler.IC_EndBlockAlways(); gbuffer1Copy.Release(); ProfilerShort.BeginNextBlock("PostProcess"); MyGpuProfiler.IC_BeginBlockAlways("PostProcess"); MyGpuProfiler.IC_BeginBlock("Luminance reduction"); IBorrowedUavTexture avgLum = null; if (MyRender11.Postprocess.EnableEyeAdaptation) { if (m_resetEyeAdaptation) { MyLuminanceAverage.Reset(); m_resetEyeAdaptation = false; } avgLum = MyLuminanceAverage.Run(MyGBuffer.Main.LBuffer); } else { avgLum = MyLuminanceAverage.Skip(); } MyGpuProfiler.IC_EndBlock(); IBorrowedUavTexture histogram = null; if (MyRender11.Settings.DisplayHistogram) { histogram = MyHdrDebugTools.CreateHistogram(MyGBuffer.Main.LBuffer, MyGBuffer.Main.SamplesCount); } if (MyRender11.Settings.DisplayHdrIntensity) { MyHdrDebugTools.DisplayHdrIntensity(MyGBuffer.Main.LBuffer); } MyGpuProfiler.IC_BeginBlock("Bloom"); IBorrowedUavTexture bloom; if (m_debugOverrides.Postprocessing && m_debugOverrides.Bloom) { bloom = MyBloom.Run(MyGBuffer.Main.LBuffer, MyGBuffer.Main.GBuffer2, MyGBuffer.Main.ResolvedDepthStencil.SrvDepth); } else { bloom = MyManagers.RwTexturesPool.BorrowUav("bloom_EightScreenUavHDR", MyRender11.ResolutionI.X / 8, MyRender11.ResolutionI.Y / 8, MyGBuffer.LBufferFormat); MyRender11.RC.ClearRtv(bloom, Color4.Black); } MyGpuProfiler.IC_EndBlock(); MyGpuProfiler.IC_BeginBlock("Tone mapping"); IBorrowedUavTexture tonemapped = MyToneMapping.Run(MyGBuffer.Main.LBuffer, avgLum, bloom, Postprocess.EnableTonemapping && m_debugOverrides.Postprocessing && m_debugOverrides.Tonemapping); bloom.Release(); MyGpuProfiler.IC_EndBlock(); IRtvTexture renderedImage; IBorrowedCustomTexture fxaaTarget = null; bool fxaa = MyRender11.FxaaEnabled; if (fxaa) { fxaaTarget = MyManagers.RwTexturesPool.BorrowCustom("MyRender11.FXAA.Rgb8"); MyGpuProfiler.IC_BeginBlock("FXAA"); MyFXAA.Run(fxaaTarget.Linear, tonemapped); MyGpuProfiler.IC_EndBlock(); renderedImage = fxaaTarget.SRgb; } else { renderedImage = tonemapped; } ProfilerShort.Begin("MyHighlight.Run"); MyHighlight.Run(renderedImage, fxaaTarget, depthStencilCopy); ProfilerShort.End(); if (depthStencilCopy != null) { depthStencilCopy.Release(); } if (renderTarget != null) { MyCopyToRT.Run(renderTarget, renderedImage); } if (MyRender11.Settings.DisplayHistogram) { if (renderTarget != null && avgLum != null) { MyHdrDebugTools.DisplayHistogram(renderTarget, avgLum, histogram); } } MyGpuProfiler.IC_EndBlockAlways(); ProfilerShort.End(); if (fxaaTarget != null) { fxaaTarget.Release(); } if (histogram != null) { histogram.Release(); } avgLum.Release(); tonemapped.Release(); // HOTFIX: MyDebugTextureDisplay uses borrowed textures. If we place MyDebugTextureDisplay to the different location, we will have problem with borrowed textures (comment by Michal) ProfilerShort.Begin("MyDebugTextureDisplay.Draw"); MyGpuProfiler.IC_BeginBlock("MyDebugTextureDisplay.Draw"); MyDebugTextureDisplay.Draw(MyRender11.Backbuffer); MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); return(renderedImage); }
protected abstract void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables);
protected override void ProcessCullQueryResults(MyCullQuery cullQuery) { ProfilerShort.Begin("Reset"); foreach (MyFrustumCullQuery frustumQuery in cullQuery.FrustumCullQueries) { var cullProxies = frustumQuery.List; foreach (MyCullProxy cullProxy in cullProxies) { cullProxy.Updated = false; cullProxy.FirstFullyContainingCascadeIndex = uint.MaxValue; } } ProfilerShort.End(); foreach (var frustumQuery in cullQuery.FrustumCullQueries) { ProfilerShort.Begin("Distance cull and update"); var cullProxies = frustumQuery.List; bool isShadowFrustum = (frustumQuery.Type == MyFrustumEnum.ShadowCascade) || (frustumQuery.Type == MyFrustumEnum.ShadowProjection); for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { MyCullProxy cullProxy = cullProxies[cullProxyIndex]; if (cullProxy == null || cullProxy.RenderableProxies == null || cullProxy.RenderableProxies.Length == 0 || cullProxy.RenderableProxies[0].Parent == null || !cullProxy.RenderableProxies[0].Parent.IsVisible) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } if (!cullProxy.Updated) { var renderableComponent = cullProxy.Parent; if (renderableComponent != null) { renderableComponent.OnFrameUpdate(); if (renderableComponent.IsCulled) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } renderableComponent.UpdateInstanceLods(); } // Proxies can get removed in UpdateInstanceLods if (cullProxy.RenderableProxies == null) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } foreach (MyRenderableProxy proxy in cullProxy.RenderableProxies) { bool shouldCastShadows = proxy.Flags.HasFlags(MyRenderableProxyFlags.CastShadows) && (proxy.Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance) || frustumQuery.CascadeIndex < 4); if (isShadowFrustum && !shouldCastShadows) { m_tmpIndicesToRemove.Add(cullProxyIndex); break; } var worldMat = proxy.WorldMatrix; worldMat.Translation -= MyRender11.Environment.Matrices.CameraPosition; proxy.CommonObjectData.LocalMatrix = worldMat; proxy.CommonObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex); } cullProxy.Updated = true; } } for (int removeIndex = m_tmpIndicesToRemove.Count - 1; removeIndex >= 0; --removeIndex) { cullProxies.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]); frustumQuery.IsInsideList.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]); } m_tmpIndicesToRemove.SetSize(0); ProfilerShort.BeginNextBlock("Culling by query type"); if (frustumQuery.Type == MyFrustumEnum.MainFrustum) { MyStatsUpdater.Passes.GBufferObjects += cullProxies.Count; int tris = 0; for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { var cullProxy = cullProxies[cullProxyIndex]; if (cullProxy.RenderableProxies != null) foreach (var renderableProxy in cullProxy.RenderableProxies) tris += (renderableProxy.InstanceCount > 0 ? renderableProxy.InstanceCount : 1) * renderableProxy.DrawSubmesh.IndexCount / 3; } MyStatsUpdater.Passes.GBufferTris += tris; } else if (frustumQuery.Type == MyFrustumEnum.ShadowCascade) { while (m_shadowCascadeProxies2.Count < MyShadowCascades.Settings.NewData.CascadesCount) m_shadowCascadeProxies2.Add(new HashSet<MyCullProxy_2>()); bool isHighCascade = frustumQuery.CascadeIndex < 3; // List 1 for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { var cullProxy = cullProxies[cullProxyIndex]; if ((isHighCascade && (cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex - 1)) || (!isHighCascade && cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex) || cullProxy.RenderableProxies == null) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } else { foreach (var renderableProxy in cullProxy.RenderableProxies) { MyStatsUpdater.CSMObjects[frustumQuery.CascadeIndex]++; MyStatsUpdater.CSMTris[frustumQuery.CascadeIndex] += (renderableProxy.InstanceCount > 0 ? renderableProxy.InstanceCount : 1) * renderableProxy.DrawSubmesh.IndexCount / 3; } if (frustumQuery.IsInsideList[cullProxyIndex]) { cullProxy.FirstFullyContainingCascadeIndex = (uint)frustumQuery.CascadeIndex; } } } // List 2 var cullProxies2 = frustumQuery.List2; m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Clear(); for (int cullProxyIndex = 0; cullProxyIndex < cullProxies2.Count; ++cullProxyIndex) { var cullProxy2 = cullProxies2[cullProxyIndex]; bool containedInHigherCascade = false; // Cull items if they're fully contained in higher resolution cascades for (int hashSetIndex = 0; hashSetIndex < frustumQuery.CascadeIndex; ++hashSetIndex) { if (m_shadowCascadeProxies2[hashSetIndex].Contains(cullProxy2)) { cullProxies2.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList2.RemoveAtFast(cullProxyIndex); --cullProxyIndex; containedInHigherCascade = true; break; } } if (!containedInHigherCascade && frustumQuery.IsInsideList2[cullProxyIndex]) { m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Add(cullProxy2); } } } else if (frustumQuery.Type == MyFrustumEnum.ShadowProjection) { for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { var cullProxy = frustumQuery.List[cullProxyIndex]; if (cullProxy.RenderableProxies == null) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } foreach (var proxy in cullProxy.RenderableProxies) { MyStatsUpdater.Passes.ShadowProjectionObjects++; MyStatsUpdater.Passes.ShadowProjectionTris += Math.Max(proxy.InstanceCount, 1) * proxy.DrawSubmesh.IndexCount / 3; } } } ProfilerShort.End(); if (frustumQuery.Ignored != null) { for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; cullProxyIndex++) { if ((cullProxies[cullProxyIndex].RenderableProxies == null || cullProxies[cullProxyIndex].RenderableProxies.Length == 0 || cullProxies[cullProxyIndex].RenderableProxies[0] == null) || (frustumQuery.Ignored.Contains(cullProxies[cullProxyIndex].RenderableProxies[0].Parent.Owner.ID))) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } } } } }
internal static void UpdateEnvironmentProbes(MyCullQuery cullQuery) { if (MyRender11.IsIntelBrokenCubemapsWorkaround) return; if (m_cubemapDepth == RwTexId.NULL) { m_cubemapDepth = MyRwTextures.CreateShadowmapArray(MyEnvironmentProbe.CubeMapResolution, MyEnvironmentProbe.CubeMapResolution, 6, Format.R24G8_Typeless, Format.D24_UNorm_S8_UInt, Format.R24_UNorm_X8_Typeless); } if (Instance.cubemapPrefiltered == RwTexId.NULL) { Instance.cubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.workCubemap = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Probe"); Instance.workCubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.prevWorkCubemapPrefiltered = MyRwTextures.CreateCubemap(MyEnvironmentProbe.CubeMapResolution, Format.R16G16B16A16_Float, "Environment Prefiltered Probe"); Instance.ImmediateProbe(cullQuery); } else { Instance.StepUpdateProbe(cullQuery); } }
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); }
protected override void ProcessCullQueryResults(MyCullQuery cullQuery) { ProfilerShort.Begin("Reset"); foreach (MyFrustumCullQuery frustumQuery in cullQuery.FrustumCullQueries) { var cullProxies = frustumQuery.List; foreach (MyCullProxy cullProxy in cullProxies) { cullProxy.Updated = false; cullProxy.FirstFullyContainingCascadeIndex = uint.MaxValue; } } ProfilerShort.End(); foreach (var frustumQuery in cullQuery.FrustumCullQueries) { ProfilerShort.Begin("Distance cull and update"); var cullProxies = frustumQuery.List; bool isShadowFrustum = (frustumQuery.Type == MyFrustumEnum.ShadowCascade) || (frustumQuery.Type == MyFrustumEnum.ShadowProjection); for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { MyCullProxy cullProxy = cullProxies[cullProxyIndex]; if (cullProxy == null || cullProxy.RenderableProxies == null || cullProxy.RenderableProxies.Length == 0 || cullProxy.RenderableProxies[0].Parent == null || !cullProxy.RenderableProxies[0].Parent.IsVisible) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } if (!cullProxy.Updated) { var renderableComponent = cullProxy.Parent; if (renderableComponent != null) { renderableComponent.OnFrameUpdate(); if (renderableComponent.IsCulled) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } renderableComponent.UpdateInstanceLods(); } // Proxies can get removed in UpdateInstanceLods if (cullProxy.RenderableProxies == null) { m_tmpIndicesToRemove.Add(cullProxyIndex); continue; } foreach (MyRenderableProxy proxy in cullProxy.RenderableProxies) { bool shouldCastShadows = proxy.Flags.HasFlags(MyRenderableProxyFlags.CastShadows) && (proxy.Flags.HasFlags(MyRenderableProxyFlags.DrawOutsideViewDistance) || frustumQuery.CascadeIndex < 4); if (isShadowFrustum && !shouldCastShadows) { m_tmpIndicesToRemove.Add(cullProxyIndex); break; } var worldMat = proxy.WorldMatrix; worldMat.Translation -= MyEnvironment.CameraPosition; proxy.CommonObjectData.LocalMatrix = worldMat; proxy.CommonObjectData.MaterialIndex = MySceneMaterials.GetDrawMaterialIndex(proxy.PerMaterialIndex); } cullProxy.Updated = true; } } for (int removeIndex = m_tmpIndicesToRemove.Count - 1; removeIndex >= 0; --removeIndex) { cullProxies.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]); frustumQuery.IsInsideList.RemoveAtFast(m_tmpIndicesToRemove[removeIndex]); } m_tmpIndicesToRemove.SetSize(0); ProfilerShort.BeginNextBlock("Culling by query type"); if (frustumQuery.Type == MyFrustumEnum.MainFrustum) { MyPerformanceCounter.PerCameraDraw11Write.ViewFrustumObjectsNum = frustumQuery.List.Count; } else if (frustumQuery.Type == MyFrustumEnum.ShadowCascade) { while (m_shadowCascadeProxies2.Count < MyRenderProxy.Settings.ShadowCascadeCount) { m_shadowCascadeProxies2.Add(new HashSet <MyCullProxy_2>()); } bool isHighCascade = frustumQuery.CascadeIndex < 3; if (cullProxies.Count == 0) { MyShadowCascades.ShadowCascadeObjectsCounter[frustumQuery.CascadeIndex] = 0; MyShadowCascades.ShadowCascadeTriangleCounter[frustumQuery.CascadeIndex] = 0; } // List 1 for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { var cullProxy = cullProxies[cullProxyIndex]; if ((isHighCascade && (cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex - 1)) || (!isHighCascade && cullProxy.FirstFullyContainingCascadeIndex < frustumQuery.CascadeIndex) || cullProxy.RenderableProxies == null) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } else { foreach (var renderableProxy in cullProxy.RenderableProxies) { MyShadowCascades.ShadowCascadeTriangleCounter[frustumQuery.CascadeIndex] += (renderableProxy.InstanceCount > 0 ? renderableProxy.InstanceCount : 1) * renderableProxy.DrawSubmesh.IndexCount / 3; } if (frustumQuery.IsInsideList[cullProxyIndex]) { cullProxy.FirstFullyContainingCascadeIndex = (uint)frustumQuery.CascadeIndex; } } } // List 2 var cullProxies2 = frustumQuery.List2; m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Clear(); for (int cullProxyIndex = 0; cullProxyIndex < cullProxies2.Count; ++cullProxyIndex) { var cullProxy2 = cullProxies2[cullProxyIndex]; bool containedInHigherCascade = false; // Cull items if they're fully contained in higher resolution cascades for (int hashSetIndex = 0; hashSetIndex < frustumQuery.CascadeIndex; ++hashSetIndex) { if (m_shadowCascadeProxies2[hashSetIndex].Contains(cullProxy2)) { cullProxies2.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList2.RemoveAtFast(cullProxyIndex); --cullProxyIndex; containedInHigherCascade = true; break; } } if (!containedInHigherCascade && frustumQuery.IsInsideList2[cullProxyIndex]) { m_shadowCascadeProxies2[frustumQuery.CascadeIndex].Add(cullProxy2); } } MyShadowCascades.ShadowCascadeObjectsCounter[frustumQuery.CascadeIndex] = cullProxies.Count; } else if (frustumQuery.Type == MyFrustumEnum.ShadowProjection) { MyShadows.OtherShadowsTriangleCounter = 0; for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; ++cullProxyIndex) { var cullProxy = frustumQuery.List[cullProxyIndex]; if (cullProxy.RenderableProxies == null) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } foreach (var proxy in cullProxy.RenderableProxies) { MyShadows.OtherShadowsTriangleCounter += Math.Max(proxy.InstanceCount, 1) * proxy.DrawSubmesh.IndexCount / 3; } } } ProfilerShort.End(); if (frustumQuery.Ignored != null) { for (int cullProxyIndex = 0; cullProxyIndex < cullProxies.Count; cullProxyIndex++) { if ((cullProxies[cullProxyIndex].RenderableProxies == null || cullProxies[cullProxyIndex].RenderableProxies.Length == 0 || cullProxies[cullProxyIndex].RenderableProxies[0] == null) || (frustumQuery.Ignored.Contains(cullProxies[cullProxyIndex].RenderableProxies[0].Parent.Owner.ID))) { cullProxies.RemoveAtFast(cullProxyIndex); frustumQuery.IsInsideList.RemoveAtFast(cullProxyIndex); --cullProxyIndex; continue; } } } } for (int cascadeIndex = 0; cascadeIndex < MyRenderProxy.Settings.ShadowCascadeCount; ++cascadeIndex) { if (MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex] >= 0) { MyPerformanceCounter.PerCameraDraw11Write.ShadowCascadeObjectsNum[cascadeIndex] = MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex]; MyShadowCascades.ShadowCascadeObjectsCounter[cascadeIndex] = -1; } if (MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex] >= 0) { MyPerformanceCounter.PerCameraDraw11Write.ShadowCascadeTriangles[cascadeIndex] = MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex]; MyShadowCascades.ShadowCascadeTriangleCounter[cascadeIndex] = -1; } } if (MyShadows.OtherShadowsTriangleCounter >= 0) { MyPerformanceCounter.PerCameraDraw11Write.OtherShadowTriangles = MyShadows.OtherShadowsTriangleCounter; MyShadows.OtherShadowsTriangleCounter = -1; } }