protected override void BeforeDelete() { base.BeforeDelete(); if (Render is MyRenderComponentPlanet) { (Render as MyRenderComponentPlanet).CancelAllRequests(); } if (m_planetEnvironmentSectors != null) { foreach (var sector in m_planetEnvironmentSectors) { sector.Value.CloseSector(); m_planetSectorsPool.Deallocate(sector.Value); } } if (m_physicsShapes != null) { foreach (var voxelMap in m_physicsShapes) { MySession.Static.VoxelMaps.RemoveVoxelMap(voxelMap.Value); voxelMap.Value.RemoveFromGamePruningStructure(); } } MySession.Static.VoxelMaps.RemoveVoxelMap(this); Storage.DataProvider.ReleaseHeightMaps(); m_storage = null; }
protected override void BeforeDelete() { base.BeforeDelete(); if (m_physicsShapes != null) { foreach (var voxelMap in m_physicsShapes) { voxelMap.Value.Close(); } } if (Render is MyRenderComponentPlanet) { (Render as MyRenderComponentPlanet).CancelAllRequests(); } if (m_planetEnvironmentSectors != null) { foreach (var sector in m_planetEnvironmentSectors) { sector.Value.CloseSector(); m_planetSectorsPool.Deallocate(sector.Value); } } m_storage = null; MySession.Static.VoxelMaps.RemoveVoxelMap(this); }
public void Clear() { foreach (var entry in m_groups) { entry.Value.Clear(); m_listAllocator.Deallocate(entry.Value); } m_groups.Clear(); m_totalItemCounter = 0; m_solvedItemCounter = 0; }
protected override void OnComplete() { base.OnComplete(); if (MyPrecalcComponent.Loaded && !m_isCancelled) { Debug.Assert(m_targetPhysics.RunningBatchTask == this); m_targetPhysics.OnBatchTaskComplete(m_newShapes); } foreach (var newShape in m_newShapes.Values) { if (!newShape.Base.IsZero) { newShape.Base.RemoveReference(); } } if (m_targetPhysics.RunningBatchTask == this) { m_targetPhysics.RunningBatchTask = null; } m_targetPhysics = null; CellBatch.Clear(); m_newShapes.Clear(); m_isCancelled = false; m_instancePool.Deallocate(this); }
private void OnComplete() { m_args.CompletionCallback(m_args.Cell, m_result); m_args = default(Args); m_result = null; m_instancePool.Deallocate(this); }
protected override void OnComplete() { base.OnComplete(); bool restartWork = false; if (MyPrecalcComponent.Loaded && !m_isCancelled && m_args.Storage != null) { // Update render even if results are not valid. Not updating may result in geometry staying the same for too long. if (IsValid) MyRenderProxy.UpdateClipmapCell(m_args.ClipmapId, ref m_metadata, ref m_batches); else { // recompute the whole things when results are not valid restartWork = true; } } else Debug.Assert(m_isCancelled, "Clipmap request collector wont know this job finished!"); if (!m_isCancelled) { m_args.RenderWorkTracker.Complete(m_args.WorkId); } m_batches.Clear(); if (restartWork) { Start(m_args); } else { m_args = default(Args); m_instancePool.Deallocate(this); } }
protected override void OnComplete() { base.OnComplete(); if (((MySession.Static != null) == MySession.Static.GetComponent <MyPrecalcComponent>().Loaded) && !this.m_isCancelled) { this.m_targetPhysics.OnBatchTaskComplete(this.m_newShapes, this.Lod); } foreach (HkBvCompressedMeshShape shape in this.m_newShapes.Values) { HkShape shape2 = shape.Base; if (!shape2.IsZero) { shape.Base.RemoveReference(); } } if (ReferenceEquals(this.m_targetPhysics.RunningBatchTask[this.Lod], this)) { this.m_targetPhysics.RunningBatchTask[this.Lod] = null; } this.m_targetPhysics = null; this.CellBatch.Clear(); this.m_newShapes.Clear(); this.m_isCancelled = false; m_instancePool.Deallocate(this); }
private void OnComplete() { ProfilerShort.Begin("MyOreDetectorComponent - OnComplete"); m_args.CompletionCallback(m_args.Cell, m_result); m_args = default(Args); m_result = null; m_instancePool.Deallocate(this); ProfilerShort.End(); }
protected override void OnComplete() { base.OnComplete(); System.Diagnostics.Debug.Assert(m_clonedShapes.Count > 0); if (MyDestructionData.Static != null && MyDestructionData.Static.BlockShapePool != null) { MyDestructionData.Static.BlockShapePool.EnqueShapes(m_args.DefId, m_clonedShapes); } m_clonedShapes.Clear(); m_args.Tracker.Complete(m_args.DefId); m_args = default(Args); m_isCanceled = false; m_instancePool.Deallocate(this); }
protected override void OnComplete() { base.OnComplete(); bool restartWork = false; if (MyPrecalcComponent.Loaded && !m_isCancelled && m_args.Storage != null) { // Update render even if results are not valid. Not updating may result in geometry staying the same for too long. MyRenderProxy.UpdateClipmapCell( m_args.ClipmapId, m_args.Cell, m_batches, m_positionOffset, m_positionScale, m_localBoundingBox); if (!IsValid) { // recompute the whole things when results are not valid restartWork = true; } } if (!m_isCancelled) { m_args.RenderWorkTracker.Complete(m_args.WorkId); } m_batches.Clear(); if (restartWork) { Start(m_args); } else { m_args = default(Args); m_instancePool.Deallocate(this); } }
protected override void OnComplete() { base.OnComplete(); if (MyPrecalcComponent.Loaded && !m_isCancelled) { m_args.TargetPhysics.OnTaskComplete(m_args.GeometryCell, m_result); } if (!m_isCancelled) { m_args.Tracker.Complete(m_args.GeometryCell); } if (!m_result.Base.IsZero) { m_result.Base.RemoveReference(); } m_args = default(Args); m_isCancelled = false; m_result = (HkBvCompressedMeshShape)HkShape.Empty; m_instancePool.Deallocate(this); }
protected void RemoveTriangle(MyNavigationTriangle tri) { m_mesh.RemoveFace(tri.Index); m_triPool.Deallocate(tri); }
internal static void Release(MySingleInstance instance) { instance.ReleaseLodProxies(); m_objectPool.Deallocate(instance); }
/** * Scan sectors arround entities in planet and update them accordingly. */ private void UpdateSectors(bool serial, ref BoundingBoxD box) { // Prepare sectors for update foreach (var sp in m_planetEnvironmentSectors) { sp.Value.PrepareForUpdate(); } // Find all entities, spawn physics arround ships and players, spawn graphics arround cameras ProfilerShort.Begin("Update Sectors"); MyGamePruningStructure.GetTopMostEntitiesInBox(ref box, m_entities, MyEntityQueryType.Dynamic); foreach (var entity in m_entities) { // entity is MyPlanet || entity is MyVoxelMap || entity is MyEnvironmentItems should all be static // If any of that changes keep in mind they must be skipped // It is also important to avoid adding physics where there are no clusters, otherwise the entities won't get activated properly. if (entity.MarkedForClose || entity.Physics == null || entity.Physics.IsStatic) { continue; } Vector3 position = entity.PositionComp.GetPosition() - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); var predictionOffset = ComputePredictionOffset(entity); if (CanSpawnFlora && RUN_SECTORS && distanceSq >= Ranges.PLANET_PHYSICS_SCAN_MIN && distanceSq <= Ranges.PLANET_PHYSICS_SCAN_MAX) { ProfilerShort.Begin("EntitySpawn"); position += predictionOffset; MyPlanetSectorId sectId; GetSectorIdAt(position, out sectId); MyPlanetEnvironmentSector sector; if (!m_planetEnvironmentSectors.TryGetValue(sectId, out sector) || !sector.HasEntity) { ForEachSector(position, SECTOR_PHYSICS_EXTENT + SECTOR_KEEP_INFLATE, SectorPhysicsDelegate); } if ((sector != null || m_planetEnvironmentSectors.TryGetValue(sectId, out sector)) && !sector.ShouldClose) { // Make sure other entities in same sector do not cause new scans. sector.HasEntity = true; } ProfilerShort.End(); } } if (CanSpawnFlora && RUN_SECTORS) { ProfilerShort.Begin("MainCameraSpawn"); Vector3D position = MySector.MainCamera.Position - WorldMatrix.Translation; double distanceSq = position.LengthSquared(); if (distanceSq > Ranges.PLANET_GRAPHICS_SCAN_MIN && distanceSq < Ranges.PLANET_GRAPHICS_SCAN_MAX) { ForEachSector(position, SECTOR_LOD1_EXTENT + SECTOR_KEEP_INFLATE, SectorGraphicsDelegate); } ProfilerShort.End(); // Remove sectors marked for removal and enqueue sectors with pending operations. ProfilerShort.Begin("Recycle Sectors"); m_sectorsToRemove.Clear(); foreach (var sp in m_planetEnvironmentSectors) { var sector = sp.Value; using (sector.AcquireStatusLock()) { sector.EvaluateOperations(); if (sector.ShouldClose) { if ((sector.PendingOperations & MyPlanetEnvironmentSector.SERIAL_OPERATIONS_MASK) != 0) { // This will close the sector here if necessary. sector.DoSerialWork(false); } Debug.Assert(sector.IsClosed); m_planetSectorsPool.Deallocate(sector); m_sectorsToRemove.Add(sp.Key); } else if (sector.ParallelPending) { if (!sector.IsQueuedParallel && sector.ParallelPending) { sector.IsQueuedParallel = true; SectorsToWorkParallel.Enqueue(sector); } } else if (sector.SerialPending && !sector.IsQueuedSerial) { SectorsToWorkSerial.Enqueue(sector); sector.IsQueuedSerial = true; } } } // Remove from the dictionary all the sectors that were closed foreach (var sector in m_sectorsToRemove) { m_planetEnvironmentSectors.Remove(sector); } ProfilerShort.End(); ProfilerShort.Begin("Schedule Tasks"); // Lastly we start the sectors worker if any work is left in the queue. if (!m_sectorsWorking) { if (SectorsToWorkParallel.Count > 0) { m_sectorsWorking = true; if (serial) { ParallelWorkCallback(); SerialWorkCallback(); } else { Parallel.Start(m_parallelWorkDelegate, m_serialWorkDelegate); } } else { SerialWorkCallback(); } } ProfilerShort.End(); } ProfilerShort.End(); WrapCounters(); }
private bool AddCell(Vector3I cellPos) { MyCellCoord coord = new MyCellCoord(NAVMESH_LOD, cellPos); var geometry = m_voxelMap.Storage.Geometry; MyVoxelGeometry.CellData data = geometry.GetCell(ref coord); if (data == null) { m_processedCells.Add(ref cellPos); m_higherLevelHelper.AddExplored(ref cellPos); return(false); } ulong packedCoord = coord.PackId64(); List <DebugDrawEdge> debugEdgesList = new List <DebugDrawEdge>(); m_debugCellEdges[packedCoord] = debugEdgesList; MyVoxelPathfinding.CellId cellId = new MyVoxelPathfinding.CellId() { VoxelMap = m_voxelMap, Pos = cellPos }; MyTrace.Send(TraceWindow.Ai, "Adding cell " + cellPos); m_connectionHelper.ClearCell(); m_vertexMapping.Init(data.VoxelVerticesCount); // Prepare list of possibly intersecting cube grids for voxel-grid navmesh intersection testing Vector3D bbMin = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (new Vector3D(-0.125) + cellPos)); Vector3D bbMax = m_voxelMap.PositionLeftBottomCorner + (m_cellSize * (Vector3D.One + cellPos)); BoundingBoxD cellBB = new BoundingBoxD(bbMin, bbMax); m_tmpGridList.Clear(); m_navmeshCoordinator.PrepareVoxelTriangleTests(cellBB, m_tmpGridList); Vector3D voxelMapCenter = m_voxelMap.PositionComp.GetPosition(); Vector3 centerDisplacement = voxelMapCenter - m_voxelMap.PositionLeftBottomCorner; // This is needed for correct edge classification - to tell, whether the edges are inner or outer edges of the cell ProfilerShort.Begin("Triangle preprocessing"); for (int i = 0; i < data.VoxelTrianglesCount; i++) { short a = data.VoxelTriangles[i].VertexIndex0; short b = data.VoxelTriangles[i].VertexIndex1; short c = data.VoxelTriangles[i].VertexIndex2; Vector3 aPos, bPos, cPos; Vector3 vert; data.GetUnpackedPosition(a, out vert); aPos = vert - centerDisplacement; data.GetUnpackedPosition(b, out vert); bPos = vert - centerDisplacement; data.GetUnpackedPosition(c, out vert); cPos = vert - centerDisplacement; bool invalidTriangle = false; if ((bPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(a, b); invalidTriangle = true; } if ((cPos - aPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(a, c); invalidTriangle = true; } if ((cPos - bPos).LengthSquared() <= MyVoxelConnectionHelper.OUTER_EDGE_EPSILON_SQ) { m_vertexMapping.Union(b, c); invalidTriangle = true; } if (invalidTriangle) { continue; } m_connectionHelper.PreprocessInnerEdge(a, b); m_connectionHelper.PreprocessInnerEdge(b, c); m_connectionHelper.PreprocessInnerEdge(c, a); } ProfilerShort.End(); ProfilerShort.Begin("Free face sorting"); // Ensure that the faces have increasing index numbers Mesh.SortFreeFaces(); ProfilerShort.End(); m_higherLevelHelper.OpenNewCell(coord); ProfilerShort.Begin("Adding triangles"); for (int i = 0; i < data.VoxelTrianglesCount; i++) { short a = data.VoxelTriangles[i].VertexIndex0; short b = data.VoxelTriangles[i].VertexIndex1; short c = data.VoxelTriangles[i].VertexIndex2; short setA = (short)m_vertexMapping.Find(a); short setB = (short)m_vertexMapping.Find(b); short setC = (short)m_vertexMapping.Find(c); if (setA == setB || setB == setC || setA == setC) { continue; } Vector3 aPos, bPos, cPos; Vector3 vert; data.GetUnpackedPosition(setA, out vert); aPos = vert - centerDisplacement; data.GetUnpackedPosition(setB, out vert); bPos = vert - centerDisplacement; data.GetUnpackedPosition(setC, out vert); cPos = vert - centerDisplacement; if (MyFakes.NAVMESH_PRESUMES_DOWNWARD_GRAVITY) { Vector3 normal = (cPos - aPos).Cross(bPos - aPos); normal.Normalize(); if (normal.Dot(ref Vector3.Up) <= Math.Cos(MathHelper.ToRadians(54.0f))) { continue; } } Vector3D aTformed = aPos + voxelMapCenter; Vector3D bTformed = bPos + voxelMapCenter; Vector3D cTformed = cPos + voxelMapCenter; bool intersecting = false; m_tmpLinkCandidates.Clear(); m_navmeshCoordinator.TestVoxelNavmeshTriangle(ref aTformed, ref bTformed, ref cTformed, m_tmpGridList, m_tmpLinkCandidates, out intersecting); if (intersecting) { m_tmpLinkCandidates.Clear(); continue; } if (!m_connectionHelper.IsInnerEdge(a, b)) { debugEdgesList.Add(new DebugDrawEdge(aTformed, bTformed)); } if (!m_connectionHelper.IsInnerEdge(b, c)) { debugEdgesList.Add(new DebugDrawEdge(bTformed, cTformed)); } if (!m_connectionHelper.IsInnerEdge(c, a)) { debugEdgesList.Add(new DebugDrawEdge(cTformed, aTformed)); } int edgeAB = m_connectionHelper.TryGetAndRemoveEdgeIndex(b, a, ref bPos, ref aPos); int edgeBC = m_connectionHelper.TryGetAndRemoveEdgeIndex(c, b, ref cPos, ref bPos); int edgeCA = m_connectionHelper.TryGetAndRemoveEdgeIndex(a, c, ref aPos, ref cPos); int formerAB = edgeAB; int formerBC = edgeBC; int formerCA = edgeCA; ProfilerShort.Begin("AddTriangle"); var tri = AddTriangle(ref aPos, ref bPos, ref cPos, ref edgeAB, ref edgeBC, ref edgeCA); ProfilerShort.End(); CheckMeshConsistency(); m_higherLevelHelper.AddTriangle(tri.Index); if (formerAB == -1) { m_connectionHelper.AddEdgeIndex(a, b, ref aPos, ref bPos, edgeAB); } if (formerBC == -1) { m_connectionHelper.AddEdgeIndex(b, c, ref bPos, ref cPos, edgeBC); } if (formerCA == -1) { m_connectionHelper.AddEdgeIndex(c, a, ref cPos, ref aPos, edgeCA); } // TODO: Instead of this, just add the tri into a list of tris that want to connect with the link candidates //m_navmeshCoordinator.TryAddVoxelNavmeshLinks(tri, cellId, m_tmpLinkCandidates); foreach (var candidate in m_tmpLinkCandidates) { List <MyNavigationPrimitive> primitives = null; if (!m_tmpCubeLinkCandidates.TryGetValue(candidate, out primitives)) { primitives = m_primitiveListPool.Allocate(); m_tmpCubeLinkCandidates.Add(candidate, primitives); } primitives.Add(tri); } m_tmpLinkCandidates.Clear(); } ProfilerShort.End(); m_tmpGridList.Clear(); m_connectionHelper.ClearCell(); m_vertexMapping.Clear(); Debug.Assert(!m_processedCells.Contains(ref cellPos)); m_processedCells.Add(ref cellPos); m_higherLevelHelper.AddExplored(ref cellPos); // Find connected components in the current cell's subgraph of the navigation mesh m_higherLevelHelper.ProcessCellComponents(); m_higherLevelHelper.CloseCell(); // Create navmesh links using the navmesh coordinator, taking into consideration the high level components m_navmeshCoordinator.TryAddVoxelNavmeshLinks2(cellId, m_tmpCubeLinkCandidates); m_navmeshCoordinator.UpdateVoxelNavmeshCellHighLevelLinks(cellId); foreach (var candidate in m_tmpCubeLinkCandidates) { candidate.Value.Clear(); m_primitiveListPool.Deallocate(candidate.Value); } m_tmpCubeLinkCandidates.Clear(); return(true); }
internal void DeallocateFrustum(BoundingFrustumD frustum) { m_frustumPool.Deallocate(frustum); }
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_sortListPool.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_sortListPool.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]; for (int queueIndex = 0; queueIndex < m_affectedQueueIds.Count; ++queueIndex) { var queueId = m_affectedQueueIds[queueIndex]; var item = new MyRenderCullResultFlat { SortKey = sortKey, RenderProxy = renderableProxy, }; 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"); foreach (var flatCullResults in m_passElements) { foreach (MyRenderCullResultFlat element in flatCullResults) { List <MyRenderCullResultFlat> sortList; if (m_tmpSortListDictionary.TryGetValue(element.SortKey, out sortList)) { sortList.Add(element); } else { sortList = m_sortListPool.Allocate(); sortList.Add(element); m_tmpSortListDictionary.Add(element.SortKey, sortList); } } flatCullResults.Clear(); foreach (var sortList in m_tmpSortListDictionary.Values) { flatCullResults.AddList(sortList); sortList.SetSize(0); m_sortListPool.Deallocate(sortList); } m_tmpSortListDictionary.Clear(); } 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(MyRenderContextPool.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(MyRenderContextPool.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) { MyObjectPoolManager.Deallocate(renderWork); } m_workList.Clear(); }