Exemplo n.º 1
0
        protected internal override void Execute(ParallelizationProvider pp)
        {
            // See if we need to resize the light plane and get the new GBuffer
            Camera        input;
            SceneViewport output;

            Texture2D <TexelFormat.RGBA32Float>[] currentGBuffer;
            geometryPass.GetLightPassParameters(out currentGBuffer, out input, out output);
            Vector2 outputSizePixels = output.SizePixels;

            if (outputSizePixels.X <= 0f || outputSizePixels.Y <= 0f)
            {
                return;
            }
            RenderTargetViewHandle windowRTV; DepthStencilViewHandle windowDSV;
            bool windowStillOpen = output.TargetWindow.GetWindowRTVAndDSV(out windowRTV, out windowDSV);

            if (!windowStillOpen)
            {
                return;
            }
            CheckGeometryPassParameters(currentGBuffer, outputSizePixels);

            // Clear the bloom textures
            QueueRenderCommand(RenderCommand.ClearRenderTarget(preBloomBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(reducedBloomBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(bloomTargetBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(nonDepthOfFieldBackBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(reducedNonDepthOfFieldBackBufferRTV));
            QueueRenderCommand(RenderCommand.ClearRenderTarget(depthOfFieldBackBufferRTV));
            QueueRenderCommand(RenderCommand.ClearDepthStencil(bloomResizeCopyDSDSV));
            QueueRenderCommand(RenderCommand.ClearDepthStencil(dsThrowawayBufferDSV));

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

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

            // Enqueue VS commands
            QueueShaderSwitch(dlLightVS);
            QueueShaderResourceUpdate(dlLightVS, vsResPackage);

            /* =======================================
             * STAGE: DYNAMIC LIGHTING APPLICATION
             * ======================================= */

            // Enqueue FS commands
            Vector4 cameraPos = input.Position;

            ((ConstantBufferBinding)dlLightFS.GetBindingByIdentifier("CameraProperties")).SetValue((byte *)(&cameraPos));
            QueueShaderSwitch(dlLightFS);

            // Set rasterizer state
            QueueRenderCommand(RenderCommand.SetRasterizerState(rsState));
            QueueRenderCommand(RenderCommand.SetViewport(output));

            // Set depth stencil state
            QueueRenderCommand(RenderCommand.SetDepthStencilState(dsState));

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

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(dsThrowawayBufferDSV.ResourceViewHandle, nonDepthOfFieldBackBufferRTV.ResourceViewHandle, preBloomBufferRTV.ResourceViewHandle));

            // Draw lights
            //input = new Camera();
            //input.Position = Vector3.ZERO;
            //input.Orient(Vector3.FORWARD, Vector3.UP);

            var frustum            = input.GetFrustum(output);
            int numLights          = addedLights.Count;
            int numLightsInFrustum = 0;

            for (int i = 0; i < numLights; ++i)
            {
                if (!frustum.IsWithinFrustum(new Sphere(addedLights[i].Position, addedLights[i].Radius)))
                {
                    continue;
                }
                lightPropsWorkspace[numLightsInFrustum++] = addedLights[i].Properties;
            }
            if (numLightsInFrustum > dynamicLightCap)
            {
                dynamicLightComparer.CameraPosition = input.Position;
                Array.Sort(lightPropsWorkspace, 0, numLightsInFrustum, dynamicLightComparer);
                numLightsInFrustum = dynamicLightCap;
            }

            Buffer <LightProperties> lightBuffer = (Buffer <LightProperties>)(((ResourceViewBinding)dlLightFS.GetBindingByIdentifier("LightBuffer")).GetBoundResource().Resource);
            var lightMetaCBuffer = (ConstantBufferBinding)dlLightFS.GetBindingByIdentifier("LightMeta");

            QueueShaderResourceUpdate(dlLightFS, fsResPackage);

            Array.Clear(perTileLightPropCounts, 0, perTileLightPropCounts.Length);



            Vector3 upDir          = input.UpDirection;
            Vector3 downDir        = -input.UpDirection;
            Vector3 rightDir       = upDir.Cross(input.Orientation);
            Vector3 leftDir        = -rightDir;
            var     worldToProjMat = (*((Matrix *)input.GetRecalculatedViewMatrix()) * *((Matrix *)output.GetRecalculatedProjectionMatrix(input)));

            for (int i = 0; i < numLightsInFrustum; ++i)
            {
                var lightProps = lightPropsWorkspace[i];
                //lightProps = new LightProperties(
                //	Vector3.LEFT + Vector3.BACKWARD, 3f, Vector3.ONE
                //);
                var lightCentre    = lightProps.Position;
                var lightTop       = new Vector4(lightCentre + upDir * lightProps.Radius, w: 1f);
                var lightBottom    = new Vector4(lightCentre + downDir * lightProps.Radius, w: 1f);
                var lightLeftmost  = new Vector4(lightCentre + leftDir * lightProps.Radius, w: 1f);
                var lightRightmost = new Vector4(lightCentre + rightDir * lightProps.Radius, w: 1f);

                var lightTopProjspace       = lightTop * worldToProjMat;
                var lightBottomProjspace    = lightBottom * worldToProjMat;
                var lightLeftmostProjspace  = lightLeftmost * worldToProjMat;
                var lightRightmostProjspace = lightRightmost * worldToProjMat;

                var lightTopScreenSpace       = lightTopProjspace / Math.Abs(lightTopProjspace.W);
                var lightBottomScreenSpace    = lightBottomProjspace / Math.Abs(lightBottomProjspace.W);
                var lightLeftmostScreenSpace  = lightLeftmostProjspace / Math.Abs(lightLeftmostProjspace.W);
                var lightRightmostScreenSpace = lightRightmostProjspace / Math.Abs(lightRightmostProjspace.W);

                var xMin = ((float)MathUtils.Clamp(lightLeftmostScreenSpace.X, -1f, 1f) + 1f) * 0.5f;
                var xMax = ((float)MathUtils.Clamp(lightRightmostScreenSpace.X, -1f, 1f) + 1f) * 0.5f;
                var yMin = ((float)MathUtils.Clamp(lightBottomScreenSpace.Y, -1f, 1f) + 1f) * 0.5f;
                var yMax = ((float)MathUtils.Clamp(lightTopScreenSpace.Y, -1f, 1f) + 1f) * 0.5f;

                for (int x = 0; x < LIGHTING_TILE_GRANULARITY; ++x)
                {
                    for (int y = 0; y < LIGHTING_TILE_GRANULARITY; ++y)
                    {
                        var tileXMin = tileOffsetsX[x];
                        var tileXMax = tileOffsetsX[x + 1];
                        var tileYMin = tileOffsetsY[y];
                        var tileYMax = tileOffsetsY[y + 1];

                        if (xMax < tileXMin ||
                            xMin > tileXMax ||
                            yMax < tileYMin ||
                            yMin > tileYMax)
                        {
                            continue;
                        }

                        var bucketIndex = x * LIGHTING_TILE_GRANULARITY + y;
                        perTileLightPropsWorkspace[bucketIndex][perTileLightPropCounts[bucketIndex]++] = lightProps;
                    }
                }
            }

            for (int x = 0; x < LIGHTING_TILE_GRANULARITY; ++x)
            {
                for (int y = 0; y < LIGHTING_TILE_GRANULARITY; ++y)
                {
                    var bucketIndex         = x * LIGHTING_TILE_GRANULARITY + y;
                    var numLightsOnThisTile = perTileLightPropCounts[bucketIndex];

                    if (numLightsOnThisTile == 0)
                    {
                        continue;
                    }

                    var scalars = new Vector4(tileOffsetsX[x], tileOffsetsX[x + 1], tileOffsetsY[y], tileOffsetsY[y + 1]);                     // 0f to 1f, from bottom left corner
                    QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(
                                           lightBuffer,
                                           new ArraySlice <LightProperties>(perTileLightPropsWorkspace[bucketIndex], 0U, (uint)numLightsOnThisTile),
                                           (uint)sizeof(LightProperties)
                                           ));
                    int *numLightsWithPadding = stackalloc int[4];
                    numLightsWithPadding[0] = numLightsOnThisTile;

                    QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightMetaCBuffer, (IntPtr)(numLightsWithPadding)));

                    QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightVSScalarsBufferBinding, (IntPtr)(&scalars)));
                    QueueRenderCommand(RenderCommand.Draw(0, 3U));
                    QueueRenderCommand(RenderCommand.Draw(3, 3U));
                }
            }



            // Unbind gbuffer
            QueueShaderResourceUpdate(dlLightFS, fsUnbindResPackage);

            /* =======================================
             * STAGE: ADD AMBIENT LIGHT (DL FINAL)
             * ======================================= */

            // Switch to finalization shader
            var scalarsFinal = new Vector4(0f, 1f, 0f, 1f);

            QueueRenderCommand(RenderCommand.DiscardWriteShaderConstantBuffer(lightVSScalarsBufferBinding, (IntPtr)(&scalarsFinal)));
            QueueShaderSwitch(dlFinalFS);
            QueueShaderResourceUpdate(dlFinalFS, finalizationShaderResPackage);

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

            // Unbind resources
            QueueShaderResourceUpdate(dlFinalFS, finalizationShaderUnbindResPackage);

            /* =======================================
             * STAGE: OUTLINING
             * ======================================= */

            // Switch to outlining shader
            QueueShaderSwitch(outliningShader);
            QueueShaderResourceUpdate(outliningShader, outliningShaderResPackage);

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

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

            // Unbind resources
            QueueShaderResourceUpdate(outliningShader, outliningShaderUnbindResPackage);

            /* =======================================
             * STAGE: DOWNSCALE PRE-BLOOM BUFFER TEX
             * ======================================= */

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, reducedBloomBufferRTV));

            // Switch to copy shader
            QueueShaderSwitch(copyShader);
            QueueShaderResourceUpdate(copyShader, copyShaderResPackage);

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

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

            // Unbind resources
            QueueShaderResourceUpdate(copyShader, copyShaderUnbindResPackage);

            /* =======================================
             * STAGE: BLOOM RENDER TO BLOOM TARGET
             * ======================================= */

            // Clear DSV
            QueueRenderCommand(RenderCommand.ClearDepthStencil(bloomResizeCopyDSDSV));

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, bloomTargetBufferRTV));

            // Switch to bloom H shader
            QueueShaderSwitch(bloomHShader);
            QueueShaderResourceUpdate(bloomHShader, bloomHShaderResPackage);

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

            // Unbind resources
            QueueShaderResourceUpdate(bloomHShader, bloomHShaderUnbindResPackage);

            // Switch to bloom V shader
            QueueShaderSwitch(bloomVShader);
            QueueShaderResourceUpdate(bloomVShader, bloomVShaderResPackage);

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

            // Unbind resources
            QueueShaderResourceUpdate(bloomVShader, bloomVShaderUnbindResPackage);

            /* =======================================
             * STAGE: COPY BLOOM RESULT ON TO NON-DoF BUFFER
             * ======================================= */

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(dsThrowawayBufferDSV.ResourceViewHandle, nonDepthOfFieldBackBufferRTV));

            // Switch to reverse copy shader
            QueueShaderSwitch(copyReverseShader);
            QueueShaderResourceUpdate(copyReverseShader, copyReverseShaderResPackage);

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

            // Unbind resources
            QueueShaderResourceUpdate(copyReverseShader, copyReverseShaderUnbindResPackage);

            /* =======================================
             * STAGE: DOWNSCALE NON-DoF SCENE
             * ======================================= */

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, reducedNonDepthOfFieldBackBufferRTV));

            // Switch to copy shader
            QueueShaderSwitch(copyShader);
            QueueShaderResourceUpdate(copyShader, copyDoFShaderResPackage);

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

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

            // Unbind resources
            QueueShaderResourceUpdate(copyShader, copyDoFShaderUnbindResPackage);

            /* =======================================
             * STAGE: BLUR NON-DoF SCENE
             * ======================================= */

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(bloomResizeCopyDSDSV, depthOfFieldBackBufferRTV));

            // Switch to copy shader
            QueueShaderSwitch(blurShader);
            QueueShaderResourceUpdate(blurShader, blurShaderResPackage);

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

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

            // Unbind resources
            QueueShaderResourceUpdate(blurShader, blurShaderUnbindResPackage);

            /* =======================================
             * STAGE: RENDER TO BACK BUFFER WITH DoF SELECTION
             * ======================================= */

            // Set up output merger
            QueueRenderCommand(RenderCommand.SetRenderTargets(windowDSV, windowRTV));

            // Switch to copy shader
            QueueShaderSwitch(dofShader);
            QueueShaderResourceUpdate(dofShader, dofShaderResPackage);

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

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

            // Unbind resources
            QueueShaderResourceUpdate(dofShader, dofShaderUnbindResPackage);



            // Flush + present
            FlushRenderCommands();
            if (presentAfterPass)
            {
                PresentBackBuffer(output.TargetWindow);
            }
        }
        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.º 3
0
 /// <summary>
 /// Called from the <see cref="LosgapSystem.MasterThread"/> when this render pass should execute.
 /// Before this method is called, mutations on the <see cref="RenderingModule.RenderStateBarrier"/> are frozen; and will remain frozen
 /// until this method returns.
 /// </summary>
 /// <param name="pp">The parallelization provider currently in use by the system, providing a way to utilise all cores of the system.</param>
 protected internal abstract void Execute(ParallelizationProvider pp);
Exemplo n.º 4
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);
            }
        }
        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.º 6
0
        /// <summary>
        /// Called by the <see cref="LosgapSystem"/> when it is time for this module to 'tick'. At this point, the module should execute
        /// its logic for the current frame.
        /// </summary>
        /// <param name="parallelizationProvider">An object that facilitates multithreaded execution of state. Never null.</param>
        /// <param name="deltaMs">The time, in milliseconds, that has elapsed since the last invocation of this method.</param>
        void ILosgapModule.PipelineIterate(ParallelizationProvider parallelizationProvider, long deltaMs)
        {
            float deltaSecs = deltaMs * 0.001f;
            bool  pausePhysicsLocal;

            lock (staticMutationLock) {
                foreach (var toBeAdded in entitiesToBeAdded)
                {
                    entityList.Add(toBeAdded);
                }
                foreach (var toBeRemoved in entitiesToBeRemoved)
                {
                    entityList.Remove(toBeRemoved);
                }

                entitiesToBeRemoved.Clear();
                entitiesToBeAdded.Clear();
                pausePhysicsLocal = pausePhysics;
            }
            if (!pausePhysicsLocal)
            {
                PhysicsManager.Tick(deltaSecs);
                PhysicsManager.GetCollisionPairs(collisionPairList);

                lock (staticMutationLock) {
                    foreach (KVP <PhysicsBodyHandle, PhysicsBodyHandle> pair in collisionPairList)
                    {
                        if (KeyContainedInCRB(pair.Key))
                        {
                            Entity other = null;
                            if (KeyContainedInCRB(pair.Value))
                            {
                                other = collisionReportableBodies[pair.Value];
                            }
                            else
                            {
                                for (int i = 0; i < entityList.Count; ++i)
                                {
                                    if (entityList[i].PhysicsBody == pair.Value)
                                    {
                                        other = entityList[i];
                                        break;
                                    }
                                }
                            }
                            if (other != null)
                            {
                                collisionReportableBodies[pair.Key].TouchDetected(other);
                            }
                        }
                        if (KeyContainedInCRB(pair.Value))
                        {
                            Entity other = null;
                            if (KeyContainedInCRB(pair.Key))
                            {
                                other = collisionReportableBodies[pair.Key];
                            }
                            else
                            {
                                for (int i = 0; i < entityList.Count; ++i)
                                {
                                    if (entityList[i].PhysicsBody == pair.Key)
                                    {
                                        other = entityList[i];
                                        break;
                                    }
                                }
                            }
                            if (other != null)
                            {
                                collisionReportableBodies[pair.Value].TouchDetected(other);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < entityList.Count; ++i)
            {
                entityList[i].SynchronizedTick(deltaSecs);
            }

            OnPostTick(deltaSecs);

            elapsedTime += deltaSecs;
        }
        //private static readonly Dictionary<RenderPass, int> passCountDict = new Dictionary<RenderPass, int>();
        //private static readonly Dictionary<RenderPass, double> passTimeDict = new Dictionary<RenderPass, double>();
        //private static readonly Stopwatch timer = Stopwatch.StartNew();

        unsafe void ILosgapModule.PipelineIterate(ParallelizationProvider parallelizationProvider, long deltaMs)
        {
#if CODE_ANALYSIS // Required because for some reason we can't ignore this one in source. Justification: parallelizationProvider will never be null.
            if (parallelizationProvider == null)
            {
                throw new ArgumentNullException("parallelizationProvider");
            }
#endif
            openWindowCopySpace.Clear();
            for (int i = 0; i < Window.OpenWindows.Count; ++i)
            {
                openWindowCopySpace.Add(Window.OpenWindows[i]);
            }
            foreach (var win in openWindowCopySpace)
            {
                win.HydrateMessagePump();
                if (!win.IsClosed)
                {
                    win.Clear();                                // If check because HydrateMessagePump can close the window
                }
            }

            RenderStateBarrier.FreezeMutations();
            bool singleThreadedModeEnabled = parallelizationProvider.ForceSingleThreadedMode;
            try {
                if (!MtRenderingSupported)
                {
                    parallelizationProvider.ForceSingleThreadedMode = true;
                }
                for (int p = 0; p < activePasses.Count; ++p)
                {
                    RenderPass currentPass = activePasses[p];
                    if (!currentPass.IsEnabled)
                    {
                        continue;
                    }
                    if (!currentPass.IsValid)
                    {
                        Logger.Debug(currentPass + " will be skipped as it not in a valid configuration.");
                        continue;
                    }

                    //var timeBefore = timer.Elapsed;
                    currentPass.OnPrePass();
                    currentPass.Execute(parallelizationProvider);
                    currentPass.OnPostPass();
                    //if (!passCountDict.ContainsKey(currentPass)) {
                    //	passCountDict.Add(currentPass, 0);
                    //	passTimeDict.Add(currentPass, 0d);
                    //}
                    //passTimeDict[currentPass] += (timer.Elapsed - timeBefore).TotalMilliseconds;
                    //if (++passCountDict[currentPass] == 1000) {
                    //	Logger.Log("Pass '" + currentPass + "' avg time = " + (passTimeDict[currentPass] / 1000d) + "ms");
                    //	passCountDict[currentPass] = 0;
                    //	passTimeDict[currentPass] = 0d;
                    //}
                }
            }
            finally {
                parallelizationProvider.ForceSingleThreadedMode = singleThreadedModeEnabled;
                RenderStateBarrier.UnfreezeMutations();
            }
        }
Exemplo n.º 8
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);
            }
        }