public override void SetQuick(int row, int column, double value) { int i = row; int j = column; int k = -1; IntArrayList indexList = indexes[i]; if (indexList != null) { k = indexList.BinarySearch(j); } if (k >= 0) { // found if (value == 0) { List <Double> valueList = values[i]; indexList.Remove(k); valueList.Remove(k); int s = indexList.Count; if (s > 2 && s * 3 < indexList.ToArray().Length) { indexList.SetSize(s * 3 / 2); indexList.TrimToSize(); indexList.SetSize(s); valueList.SetSize(s * 3 / 2); valueList.TrimExcess(); valueList.SetSize(s); } } else { values[i][k] = value; } } else { // not found if (value == 0) { return; } k = -k - 1; if (indexList == null) { indexes[i] = new IntArrayList(3); values[i] = new List <Double>(3); } indexes[i].Insert(k, j); values[i].Insert(k, value); } }
/// <summary> /// Clears the storage faster than clear. Only use for value type T /// </summary> public void ClearFast() { m_nextFreeEntry = 0; m_count = 0; m_storage.SetSize(0); m_bins.Clear(); }
public void ReduceLodsCount(int newLodsCount) { VRageRender.MyRenderProxy.Assert(LodSwitchingDistances.Count >= newLodsCount - 1); // the number of lods needs to be greater than count of distances LodSwitchingDistances.SetSize(newLodsCount - 1); }
/// <summary> /// Allocate array of bones from pool. Bones are in the rest (bind) position by default. /// </summary> /// <returns></returns> public List <MyAnimationClip.BoneState> Alloc() { if (m_freeToUse.Count == 0) { var rtn = new List <MyAnimationClip.BoneState>(m_boneCount); rtn.SetSize(m_boneCount); for (int i = 0; i < m_boneCount; i++) { // item not created yet rtn[i] = new MyAnimationClip.BoneState(); // fill will default data rtn[i].Translation = m_restPose[i].Translation; rtn[i].Rotation = m_restPose[i].Rotation; } m_taken.Add(rtn); return(rtn); } else { var rtn = m_freeToUse[m_freeToUse.Count - 1]; m_freeToUse.RemoveAt(m_freeToUse.Count - 1); m_taken.Add(rtn); for (int i = 0; i < m_boneCount; i++) { // item is already created // fill will default data rtn[i].Translation = m_restPose[i].Translation; rtn[i].Rotation = m_restPose[i].Rotation; } return(rtn); } }
/// <summary> /// Allocate array of bones from pool. Bones are in the rest (bind) position by default. /// </summary> /// <returns></returns> public List<MyAnimationClip.BoneState> Alloc() { if (m_freeToUse.Count == 0) { var rtn = new List<MyAnimationClip.BoneState>(m_boneCount); rtn.SetSize(m_boneCount); for (int i = 0; i < m_boneCount; i++) { // item not created yet rtn[i] = new MyAnimationClip.BoneState(); // fill will default data rtn[i].Translation = m_restPose[i].Translation; rtn[i].Rotation = m_restPose[i].Rotation; } m_taken.Add(rtn); return rtn; } else { var rtn = m_freeToUse[m_freeToUse.Count - 1]; m_freeToUse.RemoveAt(m_freeToUse.Count - 1); m_taken.Add(rtn); for (int i = 0; i < m_boneCount; i++) { // item is already created // fill will default data rtn[i].Translation = m_restPose[i].Translation; rtn[i].Rotation = m_restPose[i].Rotation; } return rtn; } }
private void DrawHeader(Rect rect) { rect.height -= GuiTheme.Header.Padding; rect.width -= (GuiTheme.Entry.DeleteButtonPadding + GuiTheme.Buttons.AddOrDeleteWidth) * 2; rect.y += GuiTheme.Header.SizeLabelOffset; // TODO(Matt): Cleanup the size label placement int desiredSize = EditorGUI.DelayedIntField(rect, "Size:", List.count); List.SetSize(desiredSize); // Draw add button rect.x = rect.xMax + GuiTheme.Entry.DeleteButtonPadding; rect.width = GuiTheme.Buttons.AddOrDeleteWidth; if (GUI.Button(rect, GuiTheme.Buttons.AddIcon)) { List.SetSize(List.count + 1); } // Draw delete button rect.x = rect.xMax + GuiTheme.Entry.DeleteButtonPadding; rect.width = GuiTheme.Buttons.AddOrDeleteWidth; // TODO(Matt): Delay delete until next frame bool wasEnabled = GUI.enabled; GUI.enabled = List.count > 0; if (GUI.Button(rect, GuiTheme.Buttons.DeleteIcon)) { Property.DeleteArrayElementAtIndex(List.count - 1); } GUI.enabled = wasEnabled; }
public unsafe void QuerySurfaceParameters(Vector3D localOrigin, ref BoundingBoxD queryBounds, List <Vector3> queries, List <MySurfaceParams> results) { localOrigin -= Planet.PositionLeftBottomCorner; using (Planet.Storage.Pin()) { var bounds = (BoundingBox)queryBounds.Translate(-Planet.PositionLeftBottomCorner); Planet.Provider.Shape.PrepareCache(); Planet.Provider.Material.PrepareRulesForBox(ref bounds); if (results.Capacity != queries.Count) { results.Capacity = queries.Count; } fixed(MySurfaceParams *pars = results.GetInternalArray()) { for (int i = 0; i < queries.Count; ++i) { Planet.Provider.ComputeCombinedMaterialAndSurface(queries[i] + localOrigin, true, out pars[i]); pars[i].Position -= localOrigin; } } results.SetSize(queries.Count); } }
void ClearDsvRtvWriteBindings() { foreach (var pair in State.m_bindings) { var view = pair.Value.WriteView; if (view == MyWriteBindingEnum.RTV || view == MyWriteBindingEnum.DSV) { m_tmpBindingClearList.Add(pair.Key); List <int> keyList = State.m_slotToBindingKeys.GetList(pair.Value.UavSlot); if (keyList != null) { keyList.Remove(pair.Key); if (keyList.Count == 0) { State.m_slotToBindingKeys.Remove(pair.Value.UavSlot); } } } } foreach (int key in m_tmpBindingClearList) { State.m_bindings.Remove(key); } m_tmpBindingClearList.SetSize(0); }
/// <summary> /// Sends a merge job message if mergedMeshId has more than pendingThreshold pending lod meshes. /// </summary> /// <returns>True if message was sent; false otherwise</returns> internal static bool TryStartMerge(this MyMergedLodMeshId mergedLodMeshId, uint clipmapId, int pendingThreshold, List <LodMeshId> outLodMeshesSent, ulong workId) { Debug.Assert(outLodMeshesSent != null && outLodMeshesSent.Count == 0, "Lod mesh list not empty!"); var pendingLodMeshes = mergedLodMeshId.Info.PendingLodMeshes; var mergedLodMeshes = mergedLodMeshId.Info.MergedLodMeshes; bool pendingMeshesOverThreshold = pendingLodMeshes.Count >= pendingThreshold; if (pendingMeshesOverThreshold) { foreach (LodMeshId lodMesh in pendingLodMeshes) { m_tmpBatches.AddArray(lodMesh.Info.DataBatches); outLodMeshesSent.Add(lodMesh); m_tmpMetadata.Add(lodMesh.Info.BatchMetadata); } foreach (LodMeshId lodMesh in mergedLodMeshes) { m_tmpBatches.AddArray(lodMesh.Info.DataBatches); outLodMeshesSent.Add(lodMesh); m_tmpMetadata.Add(lodMesh.Info.BatchMetadata); } pendingLodMeshes.Clear(); mergedLodMeshes.Clear(); MyVoxelCellInfo cellInfo = MyMeshes.GetVoxelInfo(mergedLodMeshId); MyRenderProxy.MergeVoxelMeshes(clipmapId, workId, m_tmpMetadata, new MyCellCoord(cellInfo.Lod, cellInfo.Coord), m_tmpBatches); m_tmpBatches.Clear(); m_tmpMetadata.SetSize(0); } return(pendingMeshesOverThreshold); }
internal void Clear() { m_vertexHelper.SetSize(0); m_indexHelper.SetSize(0); m_positionHelper.SetSize(0); Material0 = -1; Material1 = -1; Material2 = -1; }
/// <summary> /// Adds all internally buffered elements to the receiver's target, then resets the current buffer size to zero. /// </summary> public void Flush() { if (this.size > 0) { list.SetSize(this.size); this.target.AddAllOf(list); this.size = 0; } }
public unsafe void BuildInstanceBuffers(int lod) { ProfilerShort.Begin("Build Instance Buffers"); Dictionary <short, List <MyInstanceData> > instances = new Dictionary <short, List <MyInstanceData> >(); m_modelToItem = new List <short>(DataView.Items.Count); Vector3D offset = SectorCenter - m_render.WorldMatrix.Translation; int maxItems = DataView.Items.Count; fixed(short *instanceIndex = m_modelToItem.GetInternalArray()) fixed(ItemInfo * items = DataView.Items.GetInternalArray()) for (int i = 0; i < maxItems; ++i) { if (items[i].ModelIndex < 0) { continue; } List <MyInstanceData> instanceData; if (!instances.TryGetValue(items[i].ModelIndex, out instanceData)) { instanceData = new List <MyInstanceData>(); instances[items[i].ModelIndex] = instanceData; } Matrix m; Matrix.CreateFromQuaternion(ref items[i].Rotation, out m); m.Translation = items[i].Position + offset; Debug.Assert(instanceData.Count < short.MaxValue); instanceIndex[i] = (short)instanceData.Count; instanceData.Add(new MyInstanceData(m)); } m_modelToItem.SetSize(maxItems); foreach (var modelData in instances) { var model = m_owner.GetModelForId(modelData.Key); if (model != null) { int modelId = MyModel.GetId(model.Model); m_render.AddInstances(modelId, modelData.Value); } else { System.Diagnostics.Debug.Fail("Model shouldnt be null"); } } ProfilerShort.End(); }
public static void SetContents <T>(this List <T> dest, ICollection <T> source) { int sizeFinal = MathHelper.GetNearestBiggerPowerOfTwo(source.Count); if (dest.Capacity < sizeFinal || dest.Capacity * 8 > sizeFinal) { dest.Capacity = sizeFinal; } source.CopyTo(dest.GetInternalArray(), 0); dest.SetSize(source.Count); }
internal void Clear() { if (m_VBs == null) { m_VBs = new Buffer[8]; m_strides = new int[8]; m_CBs = new Buffer[8]; m_bindings = new Dictionary <int, MyBinding>(); m_slotToBindingKeys = new MyListDictionary <int, int>(); m_srvBindings = new MyListDictionary <int, int>(); m_RTVs = new RenderTargetView[8]; m_SRVs = new ShaderResourceView[8]; m_constantsVersion = new Dictionary <Buffer, int>(); m_constantBindings = new Dictionary <MyStageBinding, Buffer>(MyStageBinding.Comparer); m_srvTableBindings = new Dictionary <MyStageSrvBinding, int>(MyStageSrvBinding.Comparer); m_srvBindings1 = new List <MyStageSrvBinding>(); } m_IB = null; m_inputLayout = null; m_ps = null; m_vs = null; m_gs = null; m_RS = null; m_BS = null; m_DS = null; m_stencilRef = 0; Array.Clear(m_VBs, 0, m_VBs.Length); Array.Clear(m_CBs, 0, m_CBs.Length); m_bindings.Clear(); m_slotToBindingKeys.Clear(); m_srvBindings.Clear(); m_constantsVersion.Clear(); m_constantBindings.Clear(); m_srvTableBindings.Clear(); m_srvBindings1.SetSize(0); }
public static void Set <T>(this List <T> list, ICollection <T> collection) { list.Clear(); if (collection.Count == 0) { return; } int sizeFinal = MathHelper.GetNearestBiggerPowerOfTwo(collection.Count); if (list.Capacity < sizeFinal || list.Capacity * 8 > sizeFinal) { list.Capacity = sizeFinal; } var arrrr = list.GetInternalArray(); var count = collection.Count; collection.CopyTo(arrrr, 0); list.SetSize(count); }
internal void Clear() { Bitmask = 0; if (Frustum != null) { DeallocateFrustum(Frustum); Frustum = null; } List.Clear(); IsInsideList.SetSize(0); List2.Clear(); IsInsideList2.SetSize(0); SmallObjects = null; Type = MyFrustumEnum.Unassigned; Index = 0; Ignored = null; }
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; } }
public void SetKeys(params TSource[][] keys) { this.keys = keys; hits.SetSize(keys.Length); maxKeyLength = keys.Max(k => k.Length); }
internal static IBorrowedRtvTexture Run() { ProfilerShort.Begin("MyOutline.Run"); MyGpuProfiler.IC_BeginBlock("MyOutline.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyOutlinePass.Instance.ViewProjection = MyRender11.Environment.Matrices.ViewProjectionAt0; MyOutlinePass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyOutlinePass.Instance.PerFrame(); MyOutlinePass.Instance.Begin(); RC.VertexShader.SetSrvs(0, null, null, null, null, null, null); RC.GeometryShader.SetSrvs(0, null, null, null, null, null, null); RC.PixelShader.SetSrvs(0, null, null, null, null, null, null); RC.ComputeShader.SetSrvs(0, null, null, null, null, null, null); int samples = MyRender11.RenderSettings.AntialiasingMode.SamplesCount(); IBorrowedRtvTexture rgba8_1 = MyManagers.RwTexturesPool.BorrowRtv("MyOutline.Rgba8_1", Format.R8G8B8A8_UNorm_SRgb, samples); RC.ClearRtv(rgba8_1, new SharpDX.Color4(0, 0, 0, 0)); RC.SetRtv(MyGBuffer.Main.DepthStencil, MyDepthStencilAccess.ReadWrite, rgba8_1); float maxThickness = 0f; foreach (var pair in m_outlines) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); MyRenderableComponent renderableComponent; if (actor == null || (renderableComponent = actor.GetRenderable()) == null) { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); continue; } var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod]; var model = renderableComponent.GetModel(); LodMeshId currentModelId; if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId)) { Debug.Fail("Mesh for outlining not found!"); continue; } foreach (MyOutlineDesc descriptor in pair.Value) { if (!renderableComponent.IsRenderedStandAlone) { MyGroupLeafComponent leafComponent = actor.GetGroupLeaf(); MyGroupRootComponent groupComponent = leafComponent.RootGroup; if (groupComponent != null) { RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor, ref maxThickness); } continue; } if (descriptor.SectionIndex == -1) { RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } else { RecordMeshSectionCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } } } MyOutlinePass.Instance.End(); RC.SetBlendState(null); foreach (var outlineKey in m_keysToRemove) { m_outlines.Remove(outlineKey); } m_keysToRemove.SetSize(0); ISrvBindable initialSourceView = rgba8_1; IRtvBindable renderTargetview = rgba8_1; if (maxThickness > 0) { IBorrowedRtvTexture rgba8_2 = MyManagers.RwTexturesPool.BorrowRtv("MyOutline.Rgba8_2", Format.R8G8B8A8_UNorm_SRgb); MyBlur.Run(renderTargetview, rgba8_2, initialSourceView, (int)Math.Round(maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, MyDepthStencilStateManager.TestSkipGrassStencil, MyFoliageRenderingPass.GrassStencilMask); rgba8_2.Release(); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); return(rgba8_1); }
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 Run() { ProfilerShort.Begin("MyOutline.Run"); MyGpuProfiler.IC_BeginBlock("MyOutline.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyOutlinePass.Instance.ViewProjection = MyEnvironment.ViewProjectionAt0; MyOutlinePass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyOutlinePass.Instance.PerFrame(); MyOutlinePass.Instance.Begin(); RC.Clear(); RC.DeviceContext.VertexShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.GeometryShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.PixelShader.SetShaderResources(0, null, null, null, null, null, null); RC.DeviceContext.ComputeShader.SetShaderResources(0, null, null, null, null, null, null); if (MyRender11.MultisamplingEnabled) { RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_ms.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_ms.m_RTV); } else { RC.DeviceContext.ClearRenderTargetView(MyRender11.m_rgba8_1.m_RTV, new SharpDX.Color4(0, 0, 0, 0)); RC.DeviceContext.OutputMerger.SetTargets(MyGBuffer.Main.DepthStencil.m_DSV, MyRender11.m_rgba8_1.m_RTV); } float maxThickness = 0f; foreach (var pair in m_outlines) { MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); MyRenderableComponent renderableComponent; if (actor == null || (renderableComponent = actor.GetRenderable()) == null) { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); continue; } var renderLod = renderableComponent.Lods[renderableComponent.CurrentLod]; var model = renderableComponent.GetModel(); LodMeshId currentModelId; if (!MyMeshes.TryGetLodMesh(model, renderableComponent.CurrentLod, out currentModelId)) { Debug.Fail("Mesh for outlining not found!"); continue; } foreach (MyOutlineDesc descriptor in pair.Value) { if (!renderableComponent.IsRenderedStandAlone) { MyGroupLeafComponent leafComponent = actor.GetGroupLeaf(); MyGroupRootComponent groupComponent = leafComponent.RootGroup; if (groupComponent != null) { RecordMeshPartCommands(model, actor, groupComponent, groupComponent.m_proxy, descriptor, ref maxThickness); } continue; } if (descriptor.SectionIndex == -1) { RecordMeshPartCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } else { RecordMeshSectionCommands(model, currentModelId, renderableComponent, renderLod, descriptor, ref maxThickness); } } } MyOutlinePass.Instance.End(); RC.SetBS(null); foreach (var outlineKey in m_keysToRemove) { m_outlines.Remove(outlineKey); } m_keysToRemove.SetSize(0); ShaderResourceView initialSourceView = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_SRV : MyRender11.m_rgba8_1.m_SRV; RenderTargetView renderTargetview = MyRender11.MultisamplingEnabled ? MyRender11.m_rgba8_ms.m_RTV : MyRender11.m_rgba8_1.m_RTV; if (maxThickness > 0) { MyBlur.Run(renderTargetview, MyRender11.m_rgba8_2.m_RTV, MyRender11.m_rgba8_2.m_SRV, initialSourceView, (int)Math.Round(5 * maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, null, MyFoliageRenderingPass.GrassStencilMask, MyRender11.Settings.BlurCopyOnDepthStencilFail); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); }
public unsafe void ScanItems(int targetLod) { int lodDiff = MinimumScannedLod - targetLod; if (lodDiff < 1) { return; } int startingLod = MinimumScannedLod - 1; int totalItems = m_itemCountTotal; int[] localLodOffsets = new int[lodDiff]; for (int lod = startingLod; lod >= targetLod; --lod) { int count = m_scanHelper.GetItemsForLod(lod); localLodOffsets[lod - targetLod] = totalItems; // Using for cumulative sum totalItems += count; } List <MySurfaceParams> surfaceParams = new List <MySurfaceParams>(totalItems); // Step 1: Generate Points List <Vector3> points = new List <Vector3>(totalItems); /*if (m_environment.ScanningMethod == MyProceduralScanningMethod.Grid) * { * // compute non-centric basis for the grid method. * Vector3 start = -BasisX - BasisY; * * // has to be per lod otherwise we will have gaps. * for (int lod = startingLod; lod >= targetLod; --lod) * { * int relativeLod = lod - targetLod; * int count = lod > targetLod ? localLodOffsets[relativeLod - 1] - localLodOffsets[relativeLod] : totalItems - localLodOffsets[relativeLod]; * float root = (float)Math.Sqrt(count); * * int width = (int)Math.Ceiling(root); * int height = (int)Math.Floor(root); * * float hrecip = .5f / height; * float wrecip = .5f / width; * * Vector3 newBasisX = 2 * BasisX + wrecip; * Vector3 newBasisY = 2 * BasisY + hrecip; * * for (int x = 0; x < width; ++x) * for (int y = 0; y < height; ++y) * { * Vector3 pos = start + newBasisX * ((float)x / width) + newBasisY * ((float)y / height); * pos += newBasisX * m_itemPositionRng.NextFloat(-wrecip, wrecip) + newBasisY * m_itemPositionRng.NextFloat(-hrecip, hrecip); * points.Add(pos); * } * } * } * else*/ { // Random is default for (int i = 0; i < m_itemCountTotal; ++i) { points.Add(ComputeRandomItemPosition()); } } BoundingBoxD box = BoundingBoxD.CreateFromPoints(Bounds); // Step 2: Query surface Provider.Owner.QuerySurfaceParameters(WorldPos, ref box, points, surfaceParams); // Step 3: Select items to spawn Items.Capacity = Items.Count + points.Count; int locationOffset = 0; int itemOffset = 0; fixed(ItemInfo *items = Items.GetInternalArray()) fixed(MySurfaceParams * parms = surfaceParams.GetInternalArray()) for (int lod = startingLod; lod >= targetLod; --lod) { int relativeLod = lod - targetLod; // Count of items in this lod int count = lod > targetLod ? localLodOffsets[relativeLod - 1] - localLodOffsets[relativeLod] : totalItems - localLodOffsets[relativeLod]; // Scan those items. for (int i = 0; i < count; ++i) { //Debug.Assert(itemOffset < points.Count); var definition = GetItemForPosition(ref parms[itemOffset], lod); if (definition != null) { Vector3 up = -parms[itemOffset].Gravity; items[m_totalSpawned].Position = parms[itemOffset].Position; items[m_totalSpawned].ModelIndex = -1; items[m_totalSpawned].Rotation = Quaternion.CreateFromForwardUp(GetRandomPerpendicularVector(ref up, parms[itemOffset].Position.GetHashCode()), up); parms[locationOffset++] = parms[itemOffset]; items[m_totalSpawned].DefinitionIndex = definition.Index; var moduled = GetModule(definition); if (moduled != null) { MyLodEnvironmentItemSet set; if (!moduled.ItemsPerDefinition.TryGetValue(definition.Index, out set)) { moduled.ItemsPerDefinition[definition.Index] = set = new MyLodEnvironmentItemSet() { Items = new List <int>() }; } set.Items.Add(m_totalSpawned); } m_totalSpawned++; Debug.Assert(m_totalSpawned <= m_itemCountTotal); } itemOffset++; } ItemCountForLod[lod] = m_totalSpawned; foreach (var module in m_modules.Values) { if (module == null) { continue; } //if (module.Module.MaximumLodIndex >= relativeLod) foreach (var def in module.ItemsPerDefinition.Keys.ToArray()) { //Debug.Assert(lod <= 15 && lod >= 0); var set = module.ItemsPerDefinition[def]; //set.LodOffsets[lod] = set.Items.Count; module.ItemsPerDefinition[def] = set; } } } Items.SetSize(m_totalSpawned); // Update modules m_scanning = true; foreach (var moduleData in m_modules.Values) { if (moduleData == null) { continue; } moduleData.Module.ProcessItems(moduleData.ItemsPerDefinition, surfaceParams, new[] { 0, 0, 0, 0 }, startingLod, targetLod); } m_scanning = false; MinimumScannedLod = targetLod; }
public override void Close() { InstanceData.SetSize(0); base.Close(); }
public unsafe void QuerySurfaceParameters(Vector3D localOrigin, ref BoundingBoxD queryBounds, List<Vector3> queries, List<MySurfaceParams> results) { localOrigin -= Planet.PositionLeftBottomCorner; using (Planet.Storage.Pin()) { var bounds = (BoundingBox)queryBounds.Translate(-Planet.PositionLeftBottomCorner); Planet.Provider.Shape.PrepareCache(); Planet.Provider.Material.PrepareRulesForBox(ref bounds); if (results.Capacity != queries.Count) { results.Capacity = queries.Count; } fixed (MySurfaceParams* pars = results.GetInternalArray()) { for (int i = 0; i < queries.Count; ++i) { Planet.Provider.ComputeCombinedMaterialAndSurface(queries[i] + localOrigin, true, out pars[i]); pars[i].Position -= localOrigin; } } results.SetSize(queries.Count); } }
internal static void Run(IRtvBindable target, ICustomTexture fxaaTarget, IDepthStencil depthStencilCopy) { if (!HasHighlights) { return; } ProfilerShort.Begin("MyHighlight.Run"); MyGpuProfiler.IC_BeginBlock("MyHighlight.Run"); // set resolved depth/ stencil // render all with proper depth-stencil state // blur // blend to main target testing with stencil again MyHighlightPass.Instance.ViewProjection = MyRender11.Environment.Matrices.ViewProjectionAt0; MyHighlightPass.Instance.Viewport = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); MyHighlightPass.Instance.PerFrame(); MyHighlightPass.Instance.Begin(); RC.VertexShader.SetSrvs(0, null, null, null, null, null, null); RC.GeometryShader.SetSrvs(0, null, null, null, null, null, null); RC.PixelShader.SetSrvs(0, null, null, null, null, null, null); RC.ComputeShader.SetSrvs(0, null, null, null, null, null, null); int samples = MyRender11.RenderSettings.AntialiasingMode.SamplesCount(); IBorrowedRtvTexture rgba8_1 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_1", Format.R8G8B8A8_UNorm_SRgb, samples); RC.ClearRtv(rgba8_1, new SharpDX.Color4(0, 0, 0, 0)); RC.SetRtv(depthStencilCopy, MyDepthStencilAccess.DepthReadOnly, rgba8_1); float maxThickness = 0f; foreach (var pair in m_highlights) { foreach (MyHighlightDesc descriptor in pair.Value) { maxThickness = Math.Max(maxThickness, descriptor.Thickness); } MyActor actor = MyIDTracker <MyActor> .FindByID(pair.Key); if (actor == null) { MyRenderProxy.Fail("The actor cannot be found for highlight. This bug is outside of the renderer."); continue; } MyRenderableComponent renderableComponent = actor.GetRenderable(); MyInstanceComponent instanceComponent = actor.GetInstance(); if (renderableComponent != null) { DrawRenderableComponent(actor, renderableComponent, pair.Value); } else if (instanceComponent != null) { DrawInstanceComponent(instanceComponent, pair.Value); } else { // If an actor has been removed without removing outlines, just remove the outlines too m_keysToRemove.Add(pair.Key); MyRenderProxy.Fail("The actor has been removed, but the highligh is still active. This bug is caused by the issue out of the renderer."); } } MyHighlightPass.Instance.End(); RC.SetBlendState(null); foreach (var outlineKey in m_keysToRemove) { m_highlights.Remove(outlineKey); } m_keysToRemove.SetSize(0); ISrvBindable initialSourceView = rgba8_1; IRtvBindable renderTargetview = rgba8_1; if (maxThickness > 0) { IBorrowedRtvTexture rgba8_2 = MyManagers.RwTexturesPool.BorrowRtv("MyHighlight.Rgba8_2", Format.R8G8B8A8_UNorm_SRgb); MyBlur.Run(renderTargetview, rgba8_2, initialSourceView, (int)Math.Round(maxThickness), MyBlur.MyBlurDensityFunctionType.Exponential, 0.25f, MyDepthStencilStateManager.IgnoreDepthStencil); rgba8_2.Release(); } MyGpuProfiler.IC_EndBlock(); ProfilerShort.End(); BlendHighlight(target, rgba8_1, fxaaTarget, depthStencilCopy); }