void RemoveTransition(MyInstanceLodId instanceLodId) { MyLodTransitionData transitionData = null; if (m_activeTransitions.TryGetValue(instanceLodId, out transitionData)) { MyObjectPoolManager.Deallocate(transitionData); m_activeTransitions.Remove(instanceLodId); } }
internal void DeallocateProxies() { if (RenderableProxies != null) { foreach (var renderableProxy in RenderableProxies) { MyObjectPoolManager.Deallocate(renderableProxy); } RenderableProxies = null; } }
internal void ReleaseProxies() { if (RenderableProxies != null) { for (int proxyIndex = 0; proxyIndex < RenderableProxies.Length; ++proxyIndex) { MyObjectPoolManager.Deallocate(RenderableProxies[proxyIndex]); RenderableProxies[proxyIndex] = null; } } RenderableProxiesForLodTransition = null; }
internal void Reset() { for (int frustumCullQueryIndex = 0; frustumCullQueryIndex < Size; ++frustumCullQueryIndex) { FrustumCullQueries[frustumCullQueryIndex].Clear(); if (RenderingPasses[frustumCullQueryIndex] != null) { MyObjectPoolManager.Deallocate(RenderingPasses[frustumCullQueryIndex]); RenderingPasses[frustumCullQueryIndex] = null; } } Size = 0; }
internal void AddForwardPass(ref Matrix offsetedViewProjection, ref MatrixD viewProjection, MyViewport viewport, DepthStencilView dsv, RenderTargetView rtv) { int frustumMask = AddFrustum(ref viewProjection); MyForwardPass pass = MyObjectPoolManager.Allocate <MyForwardPass>(); pass.ProcessingMask = frustumMask; pass.ViewProjection = offsetedViewProjection; pass.Viewport = viewport; pass.DSV = dsv; pass.RTV = rtv; pass.PerFrame(); RenderingPasses[Size - 1] = pass; }
internal void AddMainViewPass(MyViewport viewport, MyGBuffer gbuffer) { int frustumMask = AddFrustum(ref MyRender11.Environment.ViewProjectionD); FrustumCullQueries[Size - 1].Type = MyFrustumEnum.MainFrustum; var pass = MyObjectPoolManager.Allocate <MyGBufferPass>(); pass.ProcessingMask = frustumMask; pass.ViewProjection = MyRender11.Environment.ViewProjectionAt0; pass.Viewport = viewport; pass.GBuffer = gbuffer; pass.PerFrame(); RenderingPasses[Size - 1] = pass; }
internal void AddForwardPass(ref Matrix offsetedViewProjection, ref MatrixD viewProjection, MyViewport viewport, IDsvBindable dsv, IRtvBindable rtv) { int frustumMask = AddFrustum(ref viewProjection); MyForwardPass pass = MyObjectPoolManager.Allocate <MyForwardPass>(); pass.DebugName = "EnvironmentProbe"; pass.ProcessingMask = frustumMask; pass.ViewProjection = offsetedViewProjection; pass.Viewport = viewport; pass.Dsv = dsv; pass.Rtv = rtv; pass.PerFrame(); RenderingPasses[Size - 1] = pass; }
internal void AddDepthPass(ref MatrixD worldToProjection, Matrix viewProjectionLocal, MyViewport viewport, DepthStencilView depthTarget, bool isCascade, string debugName) { int frustumMask = AddFrustum(ref worldToProjection); MyDepthPass pass = MyObjectPoolManager.Allocate <MyDepthPass>(); pass.DebugName = debugName; pass.ProcessingMask = frustumMask; pass.ViewProjection = viewProjectionLocal; pass.Viewport = viewport; pass.DSV = depthTarget; pass.DefaultRasterizer = isCascade ? MyRender11.m_cascadesRasterizerState : MyRender11.m_shadowRasterizerState; pass.PerFrame(); RenderingPasses[Size - 1] = pass; }
/// <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(); }
private void RemoveInstance(MySingleInstance instance) { Debug.Assert(instance != null, "RemoveInstance called for null instance!"); if (instance == null) { return; } Debug.Assert(instance.BtreeProxy != -1 && instance.CullProxy != null); if (instance.BtreeProxy != -1) { MyScene.DynamicRenderablesDBVH.RemoveProxy(instance.BtreeProxy); instance.BtreeProxy = -1; } if (instance.CullProxy != null) { MyObjectPoolManager.Deallocate(instance.CullProxy); instance.CullProxy = null; } }
internal virtual MyRenderingPass Fork() { var renderPass = (MyRenderingPass)MyObjectPoolManager.Allocate(this.GetType()); renderPass.m_RC = m_RC; if (renderPass.Locals != null) { renderPass.Locals.Clear(); } renderPass.Stats = default(MyPassStats); renderPass.m_joined = m_joined; renderPass.m_currentProfilingBlock_renderableType = -1; renderPass.m_currentProfilingBlock_renderableMaterial = string.Empty; renderPass.m_isImmediate = m_isImmediate; renderPass.ViewProjection = ViewProjection; renderPass.Viewport = Viewport; renderPass.DebugName = DebugName; renderPass.ProcessingMask = ProcessingMask; return(renderPass); }
internal void AllocateProxies(int allocationSize) { if (RenderableProxies == null || allocationSize != RenderableProxies.Length) { DeallocateProxies(); RenderableProxies = new MyRenderableProxy[allocationSize]; SortingKeys = new UInt64[allocationSize]; } else if (RenderableProxies != null) { for (int proxyIndex = 0; proxyIndex < RenderableProxies.Length; ++proxyIndex) { MyObjectPoolManager.Deallocate(RenderableProxies[proxyIndex]); } } for (int proxyIndex = 0; proxyIndex < allocationSize; ++proxyIndex) { RenderableProxies[proxyIndex] = MyObjectPoolManager.Allocate <MyRenderableProxy>(); } }
internal override bool RebuildLodProxy(int lodNum, bool skinningEnabled, MySkinningComponent skinning) { Debug.Assert(Mesh.Info.LodsNum == 1); MyRenderLod lod = null; int partCount; LodMeshId lodMesh = new LodMeshId(); MyMergedLodMeshId mergedLodMesh = new MyMergedLodMeshId(); VertexLayoutId vertexLayout; bool isMergedMesh = MyMeshes.IsMergedVoxelMesh(Mesh); if (!isMergedMesh) { if (!Owner.IsVisible) { return(false); } lodMesh = MyMeshes.GetLodMesh(Mesh, 0); vertexLayout = lodMesh.VertexLayout; partCount = lodMesh.Info.PartsNum; } else { mergedLodMesh = MyMeshes.GetMergedLodMesh(Mesh, 0); if (mergedLodMesh.VertexLayout == VertexLayoutId.NULL || mergedLodMesh.Info.MergedLodMeshes.Count == 0) { return(false); } partCount = mergedLodMesh.Info.PartsNum; vertexLayout = mergedLodMesh.VertexLayout; } MyObjectPoolManager.Init(ref m_lods[lodNum]); lod = m_lods[lodNum]; lod.VertexLayout1 = vertexLayout; // Hide proxies when they will already be rendered in a merged mesh if (!MyMeshes.IsLodMeshMerged(lodMesh)) { AddToRenderables(); } Debug.Assert(partCount > 0); lod.VertexShaderFlags = MyShaderUnifiedFlags.USE_VOXEL_DATA | MyShaderUnifiedFlags.USE_VOXEL_MORPHING | MyShaderUnifiedFlags.DITHERED; bool initializeProxies = true; //isMergedMesh || !MyMeshes.IsLodMeshMerged(lodMesh); bool initializeDepthProxy = true; //!isMergedMesh && Num > 0; int numToInitialize = (initializeProxies ? partCount : 0) + (initializeDepthProxy ? 1 : 0); if (numToInitialize > 0) { lod.AllocateProxies(numToInitialize); } AnyDrawOutsideViewDistance = false; int constantBufferSize = GetConstantBufferSize(lod, skinningEnabled); if (initializeProxies) { for (int partIndex = 0; partIndex < partCount; partIndex++) { CreateRenderableProxyForPart(lodNum, constantBufferSize, partIndex, partIndex, false); } } if (initializeDepthProxy) { CreateRenderableProxyForPart(lodNum, constantBufferSize, numToInitialize - 1, 0, true); } return(true); }
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(); }