public unsafe void TestSetShaderVertexBuffers() { VertexBufferBuilder <Vector3> vbBuilder = BufferFactory.NewVertexBuffer <Vector3>() .WithLength(100U) .WithUsage(ResourceUsage.DiscardWrite); VertexBuffer <Vector3> vb0 = vbBuilder.Create(); VertexBuffer <Vector2> vb2 = vbBuilder.WithVertexType <Vector2>().Create(); ConstantBuffer <Matrix> vpTransBuffer = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite); VertexShader shader = new VertexShader( @"Tests\SimpleVS.cso", new VertexInputBinding(8U, "Instance"), new ConstantBufferBinding(0U, "VPTB", vpTransBuffer), new VertexInputBinding(0U, "VB0"), new VertexInputBinding(1U, "VB1"), new VertexInputBinding(2U, "VB2") ); Dictionary <VertexInputBinding, IVertexBuffer> vbDict = new Dictionary <VertexInputBinding, IVertexBuffer>(); vbDict[shader.InputBindings[0]] = vb0; vbDict[shader.InputBindings[2]] = vb2; RenderCommand testCommand = RenderCommand.SetShaderVertexBuffers(shader, vbDict); Assert.AreEqual(RenderCommandInstruction.SetVertexBuffers, testCommand.Instruction); ResourceHandle *resHandleArray = (ResourceHandle *)new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg1, sizeof(long))); Assert.AreEqual(vb0.ResourceHandle, resHandleArray[0]); Assert.AreEqual(ResourceHandle.NULL, resHandleArray[1]); Assert.AreEqual(vb2.ResourceHandle, resHandleArray[2]); uint *bufferStrideArray = (uint *)new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg2, sizeof(long))); Assert.AreEqual((uint)sizeof(Vector3), bufferStrideArray[0]); Assert.AreEqual(0U, bufferStrideArray[1]); Assert.AreEqual((uint)sizeof(Vector2), bufferStrideArray[2]); Assert.AreEqual((RenderCommandArgument)9U, testCommand.Arg3); #if !DEVELOPMENT && !RELEASE try { RenderCommand.SetShaderVertexBuffers(null, vbDict); Assert.Fail(); } catch (AssuranceFailedException) { } try { RenderCommand.SetShaderVertexBuffers(shader, null); Assert.Fail(); } catch (AssuranceFailedException) { } #endif vb0.Dispose(); vb2.Dispose(); vpTransBuffer.Dispose(); vpTransBuffer.Dispose(); #if !DEVELOPMENT && !RELEASE try { RenderCommand.SetShaderVertexBuffers(shader, vbDict); Assert.Fail(); } catch (AssuranceFailedException) { } #endif shader.Dispose(); #if !DEVELOPMENT && !RELEASE try { RenderCommand.SetShaderVertexBuffers(shader, new Dictionary <VertexInputBinding, IVertexBuffer>()); Assert.Fail(); } catch (AssuranceFailedException) { } #endif }
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); } }