protected internal override void Execute(ParallelizationProvider pp)
        {
            for (int i = 0; i < NUM_GBUFFER_TEXTURES; ++i)
            {
                if (gBufferViews[i] != null)
                {
                    QueueRenderCommand(RenderCommand.ClearRenderTarget(gBufferViews[i]));
                }
            }
            if (clearOutputBeforePass)
            {
                QueueRenderCommand(RenderCommand.ClearRenderTarget(output.TargetWindow));
                QueueRenderCommand(RenderCommand.ClearDepthStencil(output.TargetWindow));
            }

            Vector2 outputSizePixels = output.SizePixels;

            if (gBuffer[0] == null || gBuffer[0].Width != (uint)outputSizePixels.X || gBuffer[0].Height != (uint)outputSizePixels.Y)
            {
                for (int i = 0; i < NUM_GBUFFER_TEXTURES; ++i)
                {
                    if (gBufferViews[i] != null)
                    {
                        gBufferViews[i].Dispose();
                    }
                    if (gBuffer[i] != null)
                    {
                        gBuffer[i].Dispose();
                    }
                    gBuffer[i]      = gBufferBuilder.WithWidth((uint)outputSizePixels.X).WithHeight((uint)outputSizePixels.Y);
                    gBufferViews[i] = gBuffer[i].CreateRenderTargetView(0U);
                }
            }
            if (primaryDSBuffer == null || primaryDSBuffer.Width != outputSizePixels.X || primaryDSBuffer.Height != outputSizePixels.Y)
            {
                if (primaryDSBuffer != null)
                {
                    primaryDSBuffer.Dispose();
                }
                if (primaryDSBufferDSV != null)
                {
                    primaryDSBufferDSV.Dispose();
                }
                if (primaryDSBufferSRV != null)
                {
                    primaryDSBufferSRV.Dispose();
                }

                primaryDSBuffer    = dsBufferBuilder.WithWidth((uint)outputSizePixels.X).WithHeight((uint)outputSizePixels.Y);
                primaryDSBufferDSV = primaryDSBuffer.CreateDepthStencilView <TexelFormat.DepthStencil>(0U);
                primaryDSBufferSRV = primaryDSBuffer.CreateView <TexelFormat.R24UnormX8Typeless>(0U, 1U);
            }
            previousShadowBufferSRV = shadowPass.ShadowBufferSRV;

            // Clear main DSV
            QueueRenderCommand(RenderCommand.ClearDepthStencil(primaryDSBufferDSV));

            List <GeometryCache> activeCaches = GeometryCache.ActiveCaches;

            foreach (GeometryCache c in activeCaches)
            {
                if (!deferredGeometryVertexShaders.ContainsKey(c))
                {
                    continue;
                }
                currentVS = deferredGeometryVertexShaders[c];

                // Set view/proj matrices
                var vpMatrices = new GeomPassProjViewMatrices {
                    MainCameraVPMat   = (*((Matrix *)Input.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(Input))).Transpose,
                    ShadowCameraVPMat = (*((Matrix *)shadowPass.LightCam.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(shadowPass.LightCam))).Transpose
                };
                byte *vpMatPtr = (byte *)&vpMatrices;
                currentVS.ViewProjMatBinding.SetValue(vpMatPtr);

                // Set state for current cache
                cpuInstanceBufferCurIndex = 0;
                List <SceneLayer> allEnabledLayers = Scene.EnabledLayers;
                uint maxLayer = 0U;
                for (int i = 0; i < allEnabledLayers.Count; ++i)
                {
                    if (allEnabledLayers[i].Index > maxLayer)
                    {
                        maxLayer = allEnabledLayers[i].Index;
                    }
                }
                if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer)
                {
                    currentSceneLayers = new SceneLayer[maxLayer + 1U];
                }
                Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length);
                foreach (SceneLayer layer in allEnabledLayers)
                {
                    currentSceneLayers[layer.Index] = layer;
                }
                currentCache = c;
                ++frameNum;
                Thread.MemoryBarrier();
                currentInstanceData = currentCache.GetModelInstanceData();

                // Set up each thread
                pp.InvokeOnAll(setUpCacheForLocalThreadAct, true);                 // membar here

                // Iterate all model instances (ordered by material)
                pp.Execute((int)currentInstanceData.Length, (int)(currentInstanceData.Length / (pp.NumThreads << 3)) + 1, renderCacheIterateMatAct);

                // Set instance buffer and write to it
                if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length)
                {
                    if (gpuInstanceBuffer != null)
                    {
                        gpuInstanceBuffer.Dispose();
                    }
                    gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create();
                }
                gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer);                 // Happens immediately (required)

                // Unbind shadow buffer
                QueueShaderSwitch(geomFSWithShadowSupport);
                QueueShaderResourceUpdate(geomFSWithShadowSupport, geomFSShadowUnbindPackage);

                // Set instance buffer and flush all commands, first on immediate context, then on each deferred
                SetInstanceBufferAndFlushCommands();
                pp.InvokeOnAll(setInstanceBufferAndFlushCommandsAct, false);
            }
        }
Exemplo n.º 2
0
        protected internal override void Execute(ParallelizationProvider pp)
        {
            DepthStencilViewHandle _;

            if (!output.TargetWindow.GetWindowRTVAndDSV(out windowRTVH, out _))
            {
                return;
            }

            List <GeometryCache> activeCaches = GeometryCache.ActiveCaches;

            foreach (GeometryCache c in activeCaches)
            {
                // Set view/proj matrix
                Matrix vpMat    = (*((Matrix *)Input.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(Input))).Transpose;
                byte * vpMapPtr = (byte *)&vpMat;
                VertexShader.ViewProjMatBinding.SetValue(vpMapPtr);

                // Set state for current cache
                cpuInstanceBufferCurIndex = 0;
                List <SceneLayer> allEnabledLayers = Scene.EnabledLayers;
                uint maxLayer = 0U;
                for (int i = 0; i < allEnabledLayers.Count; ++i)
                {
                    if (allEnabledLayers[i].Index > maxLayer)
                    {
                        maxLayer = allEnabledLayers[i].Index;
                    }
                }
                if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer)
                {
                    currentSceneLayers = new SceneLayer[maxLayer + 1U];
                }
                Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length);
                foreach (SceneLayer layer in allEnabledLayers)
                {
                    currentSceneLayers[layer.Index] = layer;
                }
                currentCache = c;
                ++frameNum;
                Thread.MemoryBarrier();
                currentInstanceData = currentCache.GetModelInstanceData();

                // Set up each thread
                pp.InvokeOnAll(setUpCacheForLocalThreadAct, true);                 // also emits a membar

                // Iterate all model instances (ordered by material)
                pp.Execute((int)currentInstanceData.Length, (int)(currentInstanceData.Length / (pp.NumThreads << 3)) + 1, renderCacheIterateMatAct);

                // Set instance buffer and write to it
                if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length)
                {
                    if (gpuInstanceBuffer != null)
                    {
                        gpuInstanceBuffer.Dispose();
                    }
                    gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create();
                }
                gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer);                 // Happens immediately (required)

                // Set instance buffer and flush all commands, first on immediate context, then on each deferred
                SetInstanceBufferAndFlushCommands();
                pp.InvokeOnAll(setInstanceBufferAndFlushCommandsAct, false);
            }

            // Present
            FlushRenderCommands();
            if (presentAfterPass)
            {
                PresentBackBuffer(Output.TargetWindow);
            }
        }
        public unsafe void TestCreateAndDestroyInstance()
        {
            // Define variables and constants
            const int NUM_INSTANCES = 1000;

            var gcb = new GeometryCacheBuilder <TestVertex>();

            gcb.AddModel("TCADI_a", new[] { new TestVertex(Vector3.ONE), new TestVertex(Vector3.LEFT), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U });
            gcb.AddModel("TCADI_b", new[] { new TestVertex(Vector3.RIGHT), new TestVertex(Vector3.UP), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U });
            gcb.AddModel("TCADI_c", new[] { new TestVertex(Vector3.ZERO), new TestVertex(Vector3.DOWN), }, new[] { 0U, 1U, 1U, 0U, 1U, 0U });
            GeometryCache testCache = gcb.Build();

            SceneLayer testLayerA = Scene.CreateLayer("Test Layer A");
            SceneLayer testLayerB = Scene.CreateLayer("Test Layer B");
            ConstantBuffer <Vector4> fsColorBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            FragmentShader           fs            = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsColorBuffer));
            Material testMatA = new Material("Brick", fs);
            Material testMatB = new Material("Wood", fs);

            // Set up context


            // Execute
            ModelInstanceHandle[] instanceArr = new ModelInstanceHandle[NUM_INSTANCES];
            for (int i = 0; i < NUM_INSTANCES; ++i)
            {
                Transform transform = new Transform(
                    Vector3.ONE * i,
                    Quaternion.FromAxialRotation(Vector3.UP, i),
                    Vector3.ONE * -i
                    );
                if (i % 5 == 0)
                {
                    instanceArr[i] = testLayerA.CreateModelInstance(new ModelHandle(testCache.ID, (uint)(i % 3)), (i % 2 == 0 ? testMatA : testMatB), transform);
                }
                else
                {
                    instanceArr[i] = testLayerB.CreateModelInstance(new ModelHandle(testCache.ID, (uint)(i % 3)), (i % 2 == 0 ? testMatA : testMatB), transform);
                }
            }

            // Assert outcome
            RenderingModule.RenderStateBarrier.FreezeMutations();             // Cheeky, but we have to on debug mode (and it's re-entrant for now, so no problem)
            var instanceData = testCache.GetModelInstanceData();

            for (int i = 0; i < NUM_INSTANCES; ++i)
            {
                Material instanceMaterial = Material.GetMaterialByIndex(instanceArr[i].MaterialIndex);
                ModelInstanceManager.MIDArray materialDataArray = instanceData.First(kvp => kvp.Key == instanceMaterial).Value;

                Assert.AreEqual((i % 2 == 0 ? testMatA : testMatB), instanceMaterial);
                Assert.AreEqual((i % 5 == 0 ? testLayerA : testLayerB), Scene.GetLayerByIndex(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].SceneLayerIndex));
                Assert.IsTrue(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].InUse);
                Assert.AreEqual((uint)(i % 3), materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].ModelIndex);
                Assert.AreEqual(
                    new Transform(
                        Vector3.ONE * i,
                        Quaternion.FromAxialRotation(Vector3.UP, i),
                        Vector3.ONE * -i
                        ),
                    instanceArr[i].Transform
                    );
                Assert.AreEqual(instanceArr[i].Transform, materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].Transform);

                instanceArr[i].Dispose();
                Assert.IsFalse(materialDataArray.Data[GetMIHInstanceIndex(instanceArr[i])].InUse);
            }

            RenderingModule.RenderStateBarrier.UnfreezeMutations();

            testCache.Dispose();
            testMatA.Dispose();
            testMatB.Dispose();
            testLayerA.Dispose();
            testLayerB.Dispose();
            fs.Dispose();
            fsColorBuffer.Dispose();
        }
        protected internal override void Execute(ParallelizationProvider pp)
        {
            // Set up buffers
            if (!output.TargetWindow.GetWindowRTVAndDSV(out windowRTVH, out windowDSVH))
            {
                return;
            }
            Vector2 viewportSizePixels = output.TargetWindow.AddedViewports.First().SizePixels;

            if (viewportSizePixels.X <= 0f || viewportSizePixels.Y <= 0f)
            {
                return;
            }
            SetUpBuffers(viewportSizePixels);

            // Clear pre-glow buffer
            QueueRenderCommand(RenderCommand.ClearRenderTarget(preGlowTargetBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(glowSrcBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(glowDstBufferRTV));

            List <GeometryCache> activeCaches = GeometryCache.ActiveCaches;

            foreach (GeometryCache c in activeCaches)
            {
                // Set view/proj matrix
                Matrix vpMat    = (*((Matrix *)Input.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(Input))).Transpose;
                byte * vpMapPtr = (byte *)&vpMat;
                VertexShader.ViewProjMatBinding.SetValue(vpMapPtr);

                // Set state for current cache
                cpuInstanceBufferCurIndex = 0;
                List <SceneLayer> allEnabledLayers = Scene.EnabledLayers;
                uint maxLayer = 0U;
                for (int i = 0; i < allEnabledLayers.Count; ++i)
                {
                    if (allEnabledLayers[i].Index > maxLayer)
                    {
                        maxLayer = allEnabledLayers[i].Index;
                    }
                }
                if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer)
                {
                    currentSceneLayers = new SceneLayer[maxLayer + 1U];
                }
                Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length);
                foreach (SceneLayer layer in allEnabledLayers)
                {
                    currentSceneLayers[layer.Index] = layer;
                }
                currentCache = c;
                ++frameNum;
                Thread.MemoryBarrier();
                currentInstanceData = currentCache.GetModelInstanceData();

                // Set up each thread
                SetUpCacheForLocalThread();

                // Iterate all model instances (ordered by material && ZIndex)
                //if (instanceDataSortSpace.Length < currentInstanceData.Length) instanceDataSortSpace = new KeyValuePair<Material, ModelInstanceManager.MIDArray>[currentInstanceData.Length * 2];
                //for (int i = 0; i < currentInstanceData.Length; i += 2) {
                //	var a = currentInstanceData[i];
                //	if (currentInstanceData.Length == i + 1) {
                //		if (currentInstanceData.Length >= 3) {
                //			if (a.Key.ZIndex < instanceDataSortSpace[i - 2].Key.ZIndex) {
                //				instanceDataSortSpace[i] = instanceDataSortSpace[i - 1];
                //				instanceDataSortSpace[i - 1] = instanceDataSortSpace[i - 2];
                //				instanceDataSortSpace[i - 2] = a;
                //			}
                //			else if (a.Key.ZIndex < instanceDataSortSpace[i - 1].Key.ZIndex) {
                //				instanceDataSortSpace[i] = instanceDataSortSpace[i - 1];
                //				instanceDataSortSpace[i - 1] = a;
                //			}
                //			else instanceDataSortSpace[i] = a;
                //		}
                //		else instanceDataSortSpace[i] = a;
                //	}
                //	else {
                //		var b = currentInstanceData[i + 1];
                //		if (a.Key.ZIndex <= b.Key.ZIndex) {
                //			instanceDataSortSpace[i] = a;
                //			instanceDataSortSpace[i + 1] = b;
                //		}
                //		else {
                //			instanceDataSortSpace[i] = b;
                //			instanceDataSortSpace[i + 1] = a;
                //		}
                //	}
                //}
                Array.Sort(currentInstanceData.ContainingArray, 0, (int)currentInstanceData.Length, zIndexComparer);
                foreach (KeyValuePair <Material, ModelInstanceManager.MIDArray> material in currentInstanceData)
                {
                    for (int i = 0; i < currentInstanceData.Length; ++i)
                    {
                        if (currentInstanceData[i].Value == material.Value && currentInstanceData[i].Key == material.Key)
                        {
                            RenderCache_IterateMaterial(i);
                            break;
                        }
                    }
                }

                // Set instance buffer and write to it
                if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length)
                {
                    if (gpuInstanceBuffer != null)
                    {
                        gpuInstanceBuffer.Dispose();
                    }
                    gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create();
                }
                gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer);                 // Happens immediately (required)

                // Set instance buffer and flush all commands, first on immediate context, then on each deferred
                SetInstanceBufferAndFlushCommands();
            }

            ///* =============================================
            // * PREPARE FOR GLOW
            // * ============================================= */

            //// Clear glow buffers
            //QueueRenderCommand(RenderCommand.ClearRenderTarget(glowSrcBufferRTV));

            //// Set blend state
            //QueueRenderCommand(RenderCommand.SetBlendState(glowBlendState));

            //// Set topology
            //QueueRenderCommand(RenderCommand.SetPrimitiveTopology(RenderCommand.DEFAULT_PRIMITIVE_TOPOLOGY));

            //// Set input layout
            //QueueRenderCommand(RenderCommand.SetInputLayout(glowPlaneInputLayout));

            //// Enqueue VS commands
            //QueueShaderSwitch(glowVS);
            //QueueShaderResourceUpdate(glowVS);

            ///* =============================================
            // * DOWNSCALE TO GLOW SRC BUFFER
            // * ============================================= */

            //// Set up output merger
            //QueueRenderCommand(RenderCommand.SetRenderTargets(glowDSBufferDSV, glowSrcBufferRTV));

            //// Switch to copy shader
            //QueueShaderSwitch(scaleDownShader);
            //QueueShaderResourceUpdate(scaleDownShader, scaleDownShaderResPkg);

            //// Draw fullscreen triangles
            //QueueRenderCommand(RenderCommand.Draw(0, 3U));
            //QueueRenderCommand(RenderCommand.Draw(3, 3U));

            //// Unbind resources
            //QueueShaderResourceUpdate(scaleDownShader, scaleDownShaderResUnbindPkg);

            ///* =============================================
            // * RENDER GLOW
            // * ============================================= */

            //// Set up output merger
            //QueueRenderCommand(RenderCommand.SetRenderTargets(glowDSBufferDSV, glowDstBufferRTV));

            //// Switch to glow shader
            //QueueShaderSwitch(glowShader);
            //QueueShaderResourceUpdate(glowShader, glowShaderVResPkg);

            //// Set blend state
            //QueueRenderCommand(RenderCommand.SetBlendState(dstMergeBlend));

            //// Draw fullscreen triangles
            //QueueRenderCommand(RenderCommand.Draw(0, 3U));
            //QueueRenderCommand(RenderCommand.Draw(3, 3U));

            //// Unbind resources
            //QueueShaderResourceUpdate(glowShader, glowShaderVResUnbindPkg);

            ///* =============================================
            // * UPSCALE TO BACK BUFFER
            // * ============================================= */

            //// Set up output merger
            //QueueRenderCommand(RenderCommand.SetRenderTargets(output.TargetWindow));

            //// Switch to copy shader
            //QueueShaderSwitch(scaleUpShader);
            //QueueShaderResourceUpdate(scaleUpShader, scaleUpShaderResPkg);

            //// Draw fullscreen triangles
            //QueueRenderCommand(RenderCommand.Draw(0, 3U));
            //QueueRenderCommand(RenderCommand.Draw(3, 3U));

            //// Unbind resources
            //QueueShaderResourceUpdate(scaleUpShader, scaleUpShaderResUnbindPkg);

            // Present
            FlushRenderCommands();
            if (presentAfterPass)
            {
                PresentBackBuffer(Output.TargetWindow);
            }
        }
Exemplo n.º 5
0
        protected internal unsafe override void Execute(ParallelizationProvider pp)
        {
            // See if we need to resize the depth buffer
            Vector2 viewportDimensions = output.SizePixels;

            if (viewportDimensions.X < 1f || viewportDimensions.Y < 1f)
            {
                return;
            }
            uint viewportX = (uint)viewportDimensions.X;
            uint viewportY = (uint)viewportDimensions.Y;

            if (shadowBuffer == null || shadowBufferDSV == null || shadowBufferDSV.ResourceOrViewDisposed ||
                shadowBufferSRV == null || shadowBufferSRV.ResourceOrViewDisposed ||
                shadowBuffer.Width != viewportX || shadowBuffer.Height != viewportY)
            {
                if (shadowBufferDSV != null && !shadowBufferDSV.IsDisposed)
                {
                    shadowBufferDSV.Dispose();
                }
                if (shadowBuffer != null && !shadowBuffer.IsDisposed)
                {
                    shadowBuffer.Dispose();
                }
                shadowBuffer    = shadowBufferBuilder.WithWidth(viewportX).WithHeight(viewportY);
                shadowBufferDSV = shadowBuffer.CreateDepthStencilView <TexelFormat.DepthStencil>(0U);
                shadowBufferSRV = shadowBuffer.CreateView <TexelFormat.R24UnormX8Typeless>(0U, 1U);
            }

            // Clear the depth buffer
            QueueRenderCommand(RenderCommand.ClearDepthStencil(shadowBufferDSV));

            List <GeometryCache> activeCaches = GeometryCache.ActiveCaches;

            foreach (GeometryCache c in activeCaches)
            {
                // Set view/proj matrix
                Matrix vpMat    = (*((Matrix *)lightCam.GetRecalculatedViewMatrix()) * *((Matrix *)Output.GetRecalculatedProjectionMatrix(lightCam))).Transpose;
                byte * vpMapPtr = (byte *)&vpMat;
                shadowVS.ViewProjMatBinding.SetValue(vpMapPtr);

                // Set state for current cache
                cpuInstanceBufferCurIndex = 0;
                List <SceneLayer> allEnabledLayers = Scene.EnabledLayers;
                uint maxLayer = 0U;
                for (int i = 0; i < allEnabledLayers.Count; ++i)
                {
                    if (allEnabledLayers[i].Index > maxLayer)
                    {
                        maxLayer = allEnabledLayers[i].Index;
                    }
                }
                if (allEnabledLayers.Count > 0 && currentSceneLayers.Length <= maxLayer)
                {
                    currentSceneLayers = new SceneLayer[maxLayer + 1U];
                }
                Array.Clear(currentSceneLayers, 0, currentSceneLayers.Length);
                foreach (SceneLayer layer in allEnabledLayers)
                {
                    currentSceneLayers[layer.Index] = layer;
                }
                currentCache = c;
                ++frameNum;
                Thread.MemoryBarrier();
                currentInstanceData = currentCache.GetModelInstanceData();

                // Set up each thread
                pp.InvokeOnAll(setUpCacheForLocalThreadAct, true);                 // membar here

                // Iterate all model instances (ordered by material)
                pp.Execute((int)currentInstanceData.Length, (int)(currentInstanceData.Length / (pp.NumThreads << 3)) + 1, renderCacheIterateMatAct);

                // Set instance buffer and write to it
                if (gpuInstanceBuffer == null || gpuInstanceBuffer.Length < cpuInstanceBuffer.Length)
                {
                    if (gpuInstanceBuffer != null)
                    {
                        gpuInstanceBuffer.Dispose();
                    }
                    gpuInstanceBuffer = gpuInstanceBufferBuilder.WithLength((uint)cpuInstanceBuffer.Length).Create();
                }
                gpuInstanceBuffer.DiscardWrite(cpuInstanceBuffer);                 // Happens immediately (required)

                // Set instance buffer and flush all commands, first on immediate context, then on each deferred
                SetInstanceBufferAndFlushCommands();
                pp.InvokeOnAll(setInstanceBufferAndFlushCommandsAct, false);
            }
        }