예제 #1
0
        public void TestCreation()
        {
            // Define variables and constants
            VertexBufferBuilder <int>  defaultBuilder           = BufferFactory.NewVertexBuffer <int>().WithLength(1);
            VertexBufferBuilder <int>  builderWithFrequentWrite = defaultBuilder.WithUsage(ResourceUsage.DiscardWrite);
            VertexBufferBuilder <int>  builderWith300Verts      = builderWithFrequentWrite.WithLength(300);
            VertexBufferBuilder <int>  builderWithInitData      = defaultBuilder.WithInitialData(Enumerable.Range(0, 10).ToArray());
            VertexBufferBuilder <long> builderWith200LongVert   = builderWithFrequentWrite.WithVertexType <long>().WithLength(200);

            // Set up context


            // Execute
            VertexBuffer <int>  withFreqWriteBuffer = builderWithFrequentWrite;
            VertexBuffer <int>  with300VertBuffer   = builderWith300Verts;
            VertexBuffer <int>  withInitDataBuffer  = builderWithInitData;
            VertexBuffer <long> with200LongBuffer   = builderWith200LongVert;

            // Assert outcome
            Assert.AreEqual(ResourceUsage.DiscardWrite, withFreqWriteBuffer.Usage);
            Assert.AreEqual(300U, with300VertBuffer.Length);
            Assert.AreEqual(10U, withInitDataBuffer.Length);
            Assert.AreEqual(200U * sizeof(long), with200LongBuffer.Size.InBytes);

            try {
                builderWithInitData.WithUsage(ResourceUsage.StagingRead);
                Assert.Fail();
            }
            catch (ArgumentException) { }

            withFreqWriteBuffer.Dispose();
            with300VertBuffer.Dispose();
            withInitDataBuffer.Dispose();
            with200LongBuffer.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);
            }
        }
예제 #3
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);
            }
        }
예제 #4
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);
            }
        }