예제 #1
0
        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);
            }
        }
예제 #3
0
        /// <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();
        }
예제 #4
0
        /// <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();
        }
예제 #5
0
        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();
 }
예제 #7
0
 internal MyGeometryRenderer(MyDynamicAABBTreeD renderablesDBVH, MyShadows shadowHandler)
 {
     m_renderablesDBVH     = renderablesDBVH;
     m_shadowHandler       = shadowHandler;
     m_cullQuery           = new MyCullQuery();
     m_visibilityCuller    = new MyFrustumCuller();
     m_renderingDispatcher = new MyRenderingDispatcher();
 }
예제 #8
0
        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);
                    }
                }
            }
        }
예제 #9
0
        internal void PerformCulling(MyCullQuery cullQuery, MyDynamicAABBTreeD renderableBVH)
        {
            ProfilerShort.Begin("DispatchCulling");
            DispatchCullQuery(cullQuery, renderableBVH);

            ProfilerShort.BeginNextBlock("ProcessCullResults");
            ProcessCullQueryResults(cullQuery);
            ProfilerShort.End();
        }
예제 #10
0
        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);
            }
        }
예제 #12
0
        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);
                }
            }
        }
예제 #13
0
        internal void ImmediateProbe(MyCullQuery cullQuery)
        {
            // reset
            state = 0;

            var prevState = state;

            StepUpdateProbe(cullQuery);
            while (prevState != state)
            {
                prevState = state;
                StepUpdateProbe(cullQuery);
            }
        }
예제 #14
0
        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;
        }
예제 #15
0
        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();
        }
예제 #17
0
        // 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();
        }
예제 #18
0
        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;
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        /// <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;
        }
예제 #22
0
        /// <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;
            }
        }
예제 #24
0
        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);
        }
예제 #26
0
        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);
        }
예제 #28
0
        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;
        }
예제 #29
0
 protected override void ProcessCullQueryResults(MyCullQuery cullQuery)
 {
     throw new NotImplementedException();
 }
예제 #30
0
 protected override void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables)
 {
     throw new NotImplementedException();
 }
예제 #31
0
 protected abstract void ProcessCullQueryResults(MyCullQuery cullQuery);
예제 #32
0
        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);
        }
예제 #33
0
        internal void PerformCulling(MyCullQuery cullQuery, MyDynamicAABBTreeD renderableBVH)
        {
            ProfilerShort.Begin("DispatchCulling");
            DispatchCullQuery(cullQuery, renderableBVH);

            ProfilerShort.BeginNextBlock("ProcessCullResults");
            ProcessCullQueryResults(cullQuery);
            ProfilerShort.End();
        }
예제 #34
0
        // 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);
        }
예제 #35
0
 protected abstract void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables);
예제 #36
0
        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);
            }
        }
예제 #38
0
 protected abstract void ProcessCullQueryResults(MyCullQuery 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);
        }
예제 #40
0
        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;
            }
        }
예제 #41
0
 protected abstract void DispatchCullQuery(MyCullQuery frustumCullQueries, MyDynamicAABBTreeD renderables);