public void TestTransform()
        {
            // Define variables and constants
            ModelInstanceManager     mim   = new ModelInstanceManager();
            ConstantBuffer <Vector4> fsCB  = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            FragmentShader           fs    = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsCB));
            Material            testMat    = new Material("TestMat", fs);
            SceneLayer          testLayer  = Scene.CreateLayer("TestLayer");
            ModelInstanceHandle testHandle = mim.AllocateInstance(testMat.Index, 0U, testLayer.Index, Transform.DEFAULT_TRANSFORM);

            // Set up context


            // Execute
            testHandle.Transform = new Transform(Vector3.ONE * 4f, Quaternion.IDENTITY, Vector3.ONE * -15f);

            // Assert outcome
            Assert.AreEqual(new Transform(Vector3.ONE * 4f, Quaternion.IDENTITY, Vector3.ONE * -15f), testHandle.Transform);
            testHandle.Dispose();
            testLayer.Dispose();
            mim.Dispose();
            testMat.Dispose();
            fs.Dispose();
            fsCB.Dispose();
        }
Exemple #2
0
        public void TestCopyTo()
        {
            // Define variables and constants
            ConstantBuffer <decimal> srcBuffer = BufferFactory.NewConstantBuffer <decimal>()
                                                 .WithUsage(ResourceUsage.Immutable)
                                                 .WithInitialData(13515m);
            ConstantBuffer <decimal> dstBuffer = srcBuffer.Clone()
                                                 .WithUsage(ResourceUsage.DiscardWrite);

            // Set up context


            // Execute
            srcBuffer.CopyTo(dstBuffer);
            srcBuffer.CopyTo(dstBuffer);

            try {
                dstBuffer.CopyTo(srcBuffer);
                Assert.Fail();
            }
            catch (ResourceOperationUnavailableException) { }

            // Assert outcome
            Assert.IsFalse(srcBuffer.CanBeCopyDestination);
            Assert.IsTrue(dstBuffer.CanBeCopyDestination);

            srcBuffer.Dispose();
            dstBuffer.Dispose();
        }
        public unsafe void TestShaderResourcePackage()
        {
            ConstantBuffer <Vector4> matColorBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            TextureSampler           textureSampler = new TextureSampler(TextureFilterType.Anisotropic, TextureWrapMode.Border, AnisotropicFilteringLevel.EightTimes);
            FragmentShader           testFS         = new FragmentShader(
                @"Tests\SimpleFS.cso",
                new ConstantBufferBinding(0U, "MaterialColor", matColorBuffer),
                new TextureSamplerBinding(0U, "DefaultSampler")
                );

            Material testMaterial = new Material("Test Material", testFS);

            testMaterial.SetMaterialConstantValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"), Vector4.ONE);
            testMaterial.SetMaterialResource((TextureSamplerBinding)testFS.GetBindingByIdentifier("DefaultSampler"), textureSampler);

            ShaderResourcePackage shaderResourcePackage = testMaterial.FragmentShaderResourcePackage;

            Assert.AreEqual(Vector4.ONE, *((Vector4 *)shaderResourcePackage.GetValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"))));
            Assert.AreEqual(textureSampler, shaderResourcePackage.GetValue((TextureSamplerBinding)testFS.GetBindingByIdentifier("DefaultSampler")));

            testFS.Dispose();
            matColorBuffer.Dispose();
            testMaterial.Dispose();
            textureSampler.Dispose();
        }
Exemple #4
0
        public void TestBindingMethods()
        {
            ConstantBuffer <Matrix> testBuffer = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);

            IShaderResourceBinding[] bindingArr =
            {
                new TextureSamplerBinding(0U, "TS0"),
                new TextureSamplerBinding(1U, "TS1"),
                new TextureSamplerBinding(5U, "TS5"),
                new ResourceViewBinding(0U,   "RV0"),
                new ResourceViewBinding(2U,   "RV2"),
                new ConstantBufferBinding(3U, "CB3", testBuffer)
            };

            Shader shader = new FragmentShader(@"Tests\SimpleFS.cso", bindingArr);

            Assert.AreEqual(bindingArr[0], shader.GetBindingByIdentifier("TS0"));
            Assert.AreEqual(bindingArr[1], shader.GetBindingByIdentifier("TS1"));
            Assert.AreEqual(bindingArr[2], shader.GetBindingByIdentifier("TS5"));
            Assert.AreEqual(bindingArr[3], shader.GetBindingByIdentifier("RV0"));
            Assert.AreEqual(bindingArr[4], shader.GetBindingByIdentifier("RV2"));
            Assert.AreEqual(bindingArr[5], shader.GetBindingByIdentifier("CB3"));

            Assert.IsTrue(shader.ContainsBinding("TS0"));
            Assert.IsTrue(shader.ContainsBinding("TS1"));
            Assert.IsFalse(shader.ContainsBinding("TS2"));

            Assert.IsTrue(shader.ContainsBinding(bindingArr[0]));
            Assert.IsTrue(shader.ContainsBinding(bindingArr[1]));
            Assert.IsFalse(shader.ContainsBinding(new TextureSamplerBinding(0U, "TS0")));

            shader.Dispose();
            testBuffer.Dispose();
        }
Exemple #5
0
        public void TestCreation()
        {
            // Define variables and constants
            ConstantBuffer <SixteenByteStruct> defaultBuffer   = BufferFactory.NewConstantBuffer <SixteenByteStruct>();
            ConstantBuffer <SixteenByteStruct> freqWriteBuffer = defaultBuffer.Clone().WithUsage(ResourceUsage.DiscardWrite);
            ConstantBuffer <SixteenByteStruct> initDataBuffer  = defaultBuffer.Clone().WithInitialData(new SixteenByteStruct(1f, 2f, 3f, 4f));

            // Set up context

            // Execute

            // Assert outcome
            Assert.AreEqual(ResourceUsage.Immutable, defaultBuffer.Usage);
            Assert.AreEqual(ResourceUsage.DiscardWrite, freqWriteBuffer.Usage);
            Assert.AreEqual(defaultBuffer.Usage, initDataBuffer.Usage);
            Assert.AreEqual(16L, initDataBuffer.Size.InBytes);

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

            defaultBuffer.Dispose();
            freqWriteBuffer.Dispose();
            initDataBuffer.Dispose();
        }
        public void TestIsValid()
        {
            SceneLayer testLayer  = Scene.CreateLayer("Test layer");
            Window     testWindow = new Window("Test window");
            ConstantBuffer <Matrix> instanceBuffer = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            VertexShader            testShader     = VertexShader.NewDefaultShader(instanceBuffer);
            HUDPass testPass = new HUDPass("Test pass");

            Assert.IsFalse(testPass.IsValid);
            testPass.Input = new Camera();
            testPass.AddLayer(testLayer);
            testPass.Output       = testWindow;
            testPass.VertexShader = testShader;
            Assert.IsFalse(testPass.IsValid);
            testPass.RasterizerState   = new RasterizerState(true, TriangleCullMode.FrontfaceCulling, false);
            testPass.DepthStencilState = new DepthStencilState();
            Assert.IsTrue(testPass.IsValid);
            testPass.RasterizerState.Dispose();
            Assert.IsFalse(testPass.IsValid);

            testPass.DepthStencilState.Dispose();
            testPass.Dispose();
            testShader.Dispose();
            instanceBuffer.Dispose();
            testWindow.Close();
            testLayer.Dispose();
        }
Exemple #7
0
        public void TestProperties()
        {
            ConstantBuffer <Matrix> testBuffer = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            Shader shader = new FragmentShader(
                @"Tests\SimpleFS.cso",
                new TextureSamplerBinding(0U, "TS0"),
                new TextureSamplerBinding(1U, "TS1"),
                new TextureSamplerBinding(5U, "TS5"),
                new ResourceViewBinding(0U, "RV0"),
                new ResourceViewBinding(2U, "RV2"),
                new ConstantBufferBinding(3U, "CB3", testBuffer)
                );

            Assert.AreEqual("SimpleFS", shader.Name);
            Assert.AreEqual(6, shader.ResourceBindings.Length);
            Assert.IsTrue(((TextureSamplerBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "TS0")).SlotIndex == 0U);
            Assert.IsTrue(((TextureSamplerBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "TS1")).SlotIndex == 1U);
            Assert.IsTrue(((TextureSamplerBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "TS5")).SlotIndex == 5U);
            Assert.IsTrue(((ResourceViewBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "RV0")).SlotIndex == 0U);
            Assert.IsTrue(((ResourceViewBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "RV2")).SlotIndex == 2U);
            Assert.IsTrue(((ConstantBufferBinding)shader.ResourceBindings.Single(bind => bind.Identifier == "CB3")).SlotIndex == 3U);

            shader.Dispose();
            testBuffer.Dispose();
        }
Exemple #8
0
        public void TestDiscardWrite()
        {
            // Define variables and constants
            ConstantBuffer <decimal> testBuffer = BufferFactory.NewConstantBuffer <decimal>()
                                                  .WithUsage(ResourceUsage.DiscardWrite);

            // Set up context


            // Execute
            testBuffer.DiscardWrite(15m);

            // Assert outcome
            Assert.IsTrue(testBuffer.CanDiscardWrite);

            testBuffer.Dispose();
        }
        public void TestSetInputLayout()
        {
            GeometryCacheBuilder <DefaultVertex> gcb = new GeometryCacheBuilder <DefaultVertex>();

            gcb.AddModel("TSIL_a", new DefaultVertex[] { new DefaultVertex(Vector3.ONE) }, new uint[] { 0U });
            GeometryCache           cache  = gcb.Build();
            ConstantBuffer <Matrix> vpMat  = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            VertexShader            shader = new VertexShader(
                @"Tests\SimpleVS.cso",
                new VertexInputBinding(0U, "INSTANCE_TRANSFORM"),
                new ConstantBufferBinding(0U, "CameraTransform", vpMat),
                new VertexInputBinding(1U, "POSITION")
                );

            GeometryInputLayout gil = cache.GetInputLayout(shader);

            RenderCommand testCommand = RenderCommand.SetInputLayout(gil);

            Assert.AreEqual(RenderCommandInstruction.SetInputLayout, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)gil.ResourceHandle, testCommand.Arg1);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetInputLayout(null);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            shader.Dispose();
            vpMat.Dispose();
            cache.Dispose();
            gil.Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetInputLayout(gil);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
        public unsafe void TestDiscardWriteShaderConstantBuffer()
        {
            ConstantBuffer <Vector4> cb  = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            ConstantBufferBinding    cbb = new ConstantBufferBinding(0U, "CB0", cb);
            Vector4 initialValue         = Vector4.FORWARD;

            cbb.SetValue((byte *)(&initialValue));

            RenderCommand testCommand = RenderCommand.DiscardWriteShaderConstantBuffer(cbb, cbb.CurValuePtr);

            Assert.AreEqual(RenderCommandInstruction.CBDiscardWrite, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)cbb.GetBoundResource().ResourceHandle, testCommand.Arg1);
            Assert.AreEqual(*((Vector4 *)cbb.CurValuePtr), *((Vector4 *)new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg2, sizeof(long)))));
            Assert.AreEqual((RenderCommandArgument)cbb.BufferSizeBytes, testCommand.Arg3);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.DiscardWriteShaderConstantBuffer(null, cbb.CurValuePtr);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }

            try {
                RenderCommand.DiscardWriteShaderConstantBuffer(cbb, IntPtr.Zero);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            (cbb as IDisposable).Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.DiscardWriteShaderConstantBuffer(cbb, cbb.CurValuePtr);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            cb.Dispose();
        }
        public void TestSettingMaterialProperties()
        {
            ConstantBuffer <Vector4> matColorBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            TextureSampler           textureSampler = new TextureSampler(TextureFilterType.Anisotropic, TextureWrapMode.Border, AnisotropicFilteringLevel.EightTimes);
            FragmentShader           testFS         = new FragmentShader(
                @"Tests\SimpleFS.cso",
                new ConstantBufferBinding(0U, "MaterialColor", matColorBuffer),
                new TextureSamplerBinding(0U, "DefaultSampler")
                );

            Material testMaterial = new Material("Test Material", testFS);

            testMaterial.SetMaterialConstantValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"), Vector4.ONE);
            testMaterial.SetMaterialResource((TextureSamplerBinding)testFS.GetBindingByIdentifier("DefaultSampler"), textureSampler);

#if !DEVELOPMENT && !RELEASE
            ConstantBufferBinding cb = new ConstantBufferBinding(1U, "Test", matColorBuffer);
            try {
                testMaterial.SetMaterialConstantValue(cb, Vector4.RIGHT);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            finally {
                (cb as IDisposable).Dispose();
            }

            try {
                testMaterial.SetMaterialConstantValue((ConstantBufferBinding)testFS.GetBindingByIdentifier("MaterialColor"), Matrix.IDENTITY);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            testFS.Dispose();
            matColorBuffer.Dispose();
            testMaterial.Dispose();
            textureSampler.Dispose();
        }
        public unsafe void SetShaderConstantBuffers()
        {
            ConstantBuffer <Vector4> cb0 = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            ConstantBuffer <Matrix>  cb1 = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);

            Shader shader = new FragmentShader(
                @"Tests\SimpleFS.cso",
                new ConstantBufferBinding(0U, "CB0", cb0),
                new ConstantBufferBinding(1U, "CB1", cb1)
                );

            RenderCommand testCommand = RenderCommand.SetShaderConstantBuffers(shader);

            Assert.AreEqual(RenderCommandInstruction.FSSetCBuffers, testCommand.Instruction);
            ResourceHandle *resHandleArray = (ResourceHandle *)new IntPtr(UnsafeUtils.Reinterpret <RenderCommandArgument, long>(testCommand.Arg1, sizeof(long)));

            Assert.AreEqual(cb0.ResourceHandle, resHandleArray[0]);
            Assert.AreEqual(cb1.ResourceHandle, resHandleArray[1]);
            Assert.AreEqual((RenderCommandArgument)shader.NumConstantBufferSlots, testCommand.Arg2);

            shader.Dispose();
            cb1.Dispose();
            cb0.Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetShaderConstantBuffers(null);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }

            try {
                RenderCommand.SetShaderConstantBuffers(shader);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
        public void TestSetShader()
        {
            ConstantBuffer <Matrix> vpMat = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            VertexShader            vs    = VertexShader.NewDefaultShader(vpMat);

            ConstantBuffer <Vector4> colorVec = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            FragmentShader           fs       = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", colorVec));

            RenderCommand testCommand = RenderCommand.SetShader(vs);

            Assert.AreEqual(RenderCommandInstruction.VSSetShader, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)vs.Handle, testCommand.Arg1);

            testCommand = RenderCommand.SetShader(fs);
            Assert.AreEqual(RenderCommandInstruction.FSSetShader, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)fs.Handle, testCommand.Arg1);

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetShader(null);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            vs.Dispose();
            fs.Dispose();
            vpMat.Dispose();
            colorVec.Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                RenderCommand.SetShader(fs);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
Exemple #14
0
        public void TestClone()
        {
            // Define variables and constants
            const ResourceUsage      USAGE       = ResourceUsage.DiscardWrite;
            ConstantBuffer <decimal> firstBuffer = BufferFactory.NewConstantBuffer <decimal>().WithUsage(USAGE);

            // Set up context


            // Execute
            ConstantBuffer <decimal> secondBuffer = firstBuffer.Clone();
            ConstantBuffer <decimal> thirdBuffer  = secondBuffer.Clone().WithInitialData(10516m);

            // Assert outcome
            Assert.AreEqual(USAGE, secondBuffer.Usage);
            Assert.AreEqual(firstBuffer.Usage, secondBuffer.Usage);
            Assert.AreEqual(firstBuffer.Size, secondBuffer.Size);

            Assert.AreEqual(USAGE, thirdBuffer.Usage);

            firstBuffer.Dispose();
            secondBuffer.Dispose();
            thirdBuffer.Dispose();
        }
        public void TestAllMethods()
        {
            // Define variables and constants
            ModelInstanceManager testMIM          = new ModelInstanceManager();
            const int            NUM_ALLOCATIONS  = 3000;
            const int            NUM_MODELS       = 7;
            const int            NUM_MATERIALS    = 11;
            const int            NUM_SCENE_LAYERS = 3;

            ConstantBuffer <Vector4> fsCBuffer = BufferFactory.NewConstantBuffer <Vector4>().WithUsage(ResourceUsage.DiscardWrite);
            FragmentShader           testFS    = new FragmentShader(@"Tests\SimpleFS.cso", new ConstantBufferBinding(0U, "MaterialProperties", fsCBuffer));

            Material[] materials = new Material[NUM_MATERIALS];
            for (int i = 0; i < NUM_MATERIALS; ++i)
            {
                materials[i] = new Material(i.ToString(), testFS);
            }

            // Set up context
            ModelInstanceHandle[] instances = new ModelInstanceHandle[NUM_ALLOCATIONS];

            // Execute
            for (int i = 0; i < NUM_ALLOCATIONS; i++)
            {
                Transform initialTransform = new Transform(
                    Vector3.ONE * i,
                    Quaternion.FromAxialRotation(Vector3.ONE * (i + 1), MathUtils.PI),
                    Vector3.ONE * -i
                    );
                instances[i] = testMIM.AllocateInstance(materials[i % NUM_MATERIALS].Index, (uint)i % NUM_MODELS, (uint)i % NUM_SCENE_LAYERS, initialTransform);
            }

            for (int i = 0; i < NUM_ALLOCATIONS; i += 2)
            {
                instances[i].Transform = instances[i].Transform.With(scale: Vector3.FORWARD * i);
            }

            // Assert outcome
            RenderingModule.RenderStateBarrier.FreezeMutations();
            ArraySlice <KeyValuePair <Material, ModelInstanceManager.MIDArray> > midData = testMIM.GetModelInstanceData();

            RenderingModule.RenderStateBarrier.UnfreezeMutations();
            Assert.AreEqual(NUM_ALLOCATIONS, midData.Sum(kvp => {
                unsafe {
                    int val = 0;
                    for (int i = 0; i < kvp.Value.Length; ++i)
                    {
                        if (kvp.Value.Data[i].InUse)
                        {
                            ++val;
                        }
                    }
                    return(val);
                }
            }));

            unsafe {
                foreach (KeyValuePair <Material, ModelInstanceManager.MIDArray> kvp in midData)
                {
                    Assert.IsTrue(materials.Contains(kvp.Key));
                    for (uint i = 0U; i < kvp.Value.Length; ++i)
                    {
                        if (!kvp.Value.Data[i].InUse)
                        {
                            continue;
                        }
                        Assert.AreEqual(1, instances.Count(mih => mih.Transform == kvp.Value.Data[i].Transform));
                    }
                }
            }

            materials.ForEach(mat => mat.Dispose());
            testFS.Dispose();
            fsCBuffer.Dispose();
        }
        public unsafe void TestGetInputLayout()
        {
            // Define variables and constants
            const int FAKE_CACHE_ID = 1351618;

            IVertexBuffer[] buffers = new IVertexBuffer[2];
            buffers[0] = BufferFactory.NewVertexBuffer <Vector3>()
                         .WithInitialData(new[] { Vector3.ONE * 0f, Vector3.ONE * 1f, Vector3.ONE * 2f, Vector3.ONE * 3f, Vector3.ONE * 4f, Vector3.ONE * 5f })
                         .WithUsage(ResourceUsage.Immutable)
                         .Create();
            buffers[1] = BufferFactory.NewVertexBuffer <float>()
                         .WithInitialData(new[] { 0f, 1f, 2f, 3f, 4f, 5f })
                         .WithUsage(ResourceUsage.Immutable)
                         .Create();
            string[]         semantics = { "POSITION", "RANDOM_FLOATS" };
            ResourceFormat[] formats   = { ResourceFormat.R32G32B32Float, ResourceFormat.R32G32Float };
            IndexBuffer      indices   = BufferFactory.NewIndexBuffer()
                                         .WithInitialData(new uint[] { 0, 1, 2, 1, 2, 0, 2, 1, 0, 3, 4, 5, 4, 5, 3, 5, 3, 4, 5, 3, 4 })
                                         .WithUsage(ResourceUsage.Immutable);
            AlignedAllocation <uint> componentStartPointsAlloc = AlignedAllocation <uint> .AllocArray(7L, 3);

            *(((uint *)componentStartPointsAlloc.AlignedPointer) + 0) = 0U;
            *(((uint *)componentStartPointsAlloc.AlignedPointer) + 1) = 3U;
            *(((uint *)componentStartPointsAlloc.AlignedPointer) + 2) = 6U;
            AlignedAllocation <uint> indexStartPointsAlloc = AlignedAllocation <uint> .AllocArray(7L, 3);

            *(((uint *)indexStartPointsAlloc.AlignedPointer) + 0) = 0U;
            *(((uint *)indexStartPointsAlloc.AlignedPointer) + 1) = 9U;
            *(((uint *)indexStartPointsAlloc.AlignedPointer) + 2) = 21U;
            Dictionary <string, ModelHandle> modelNameMap = new Dictionary <string, ModelHandle>()
            {
                { FAKE_CACHE_ID + "A", new ModelHandle(FAKE_CACHE_ID, 0U) },
                { FAKE_CACHE_ID + "B", new ModelHandle(FAKE_CACHE_ID, 1U) }
            };
            const uint NUM_MODELS = 2;

            // Set up context
            GeometryCache cache = new GeometryCache(
                buffers, semantics, formats,
                indices, componentStartPointsAlloc, indexStartPointsAlloc,
                NUM_MODELS, typeof(Vector4), FAKE_CACHE_ID, modelNameMap
                );

            ConstantBuffer <Matrix> instanceCBuffer = BufferFactory.NewConstantBuffer <Matrix>().WithUsage(ResourceUsage.DiscardWrite);
            VertexShader            vs1             = new VertexShader(
                @"Tests\SimpleVS.cso",
                new VertexInputBinding(0U, "INSTANCE_TRANSFORM"),
                new ConstantBufferBinding(0U, "CameraTransform", instanceCBuffer),
                new VertexInputBinding(1U, "POSITION")
                );
            VertexShader vs2 = new VertexShader(
                @"Tests\SimpleVS.cso",
                new VertexInputBinding(0U, "INSTANCE_TRANSFORM"),
                new ConstantBufferBinding(0U, "CameraTransform", instanceCBuffer),
                new VertexInputBinding(1U, "RANDOM_FLOATS"),
                new VertexInputBinding(2U, "POSITION")
                );
            VertexShader vs3 = new VertexShader(
                @"Tests\SimpleVS.cso",
                new VertexInputBinding(0U, "INSTANCE"),
                new ConstantBufferBinding(0U, "VPTransform", instanceCBuffer),
                new VertexInputBinding(1U, "TEXCOORD")
                );

            // Execute
            GeometryInputLayout inputLayout1 = cache.GetInputLayout(vs1);
            GeometryInputLayout inputLayout2 = cache.GetInputLayout(vs2);

            try {
                cache.GetInputLayout(vs3);
                Assert.Fail();
            }
            catch (InvalidOperationException) { }

            // Assert outcome
            Assert.AreEqual(cache, inputLayout1.AssociatedCache);
            Assert.AreEqual(cache, inputLayout2.AssociatedCache);

            Assert.AreEqual(vs1, inputLayout1.AssociatedShader);
            Assert.AreEqual(vs2, inputLayout2.AssociatedShader);

            KeyValuePair <VertexInputBinding, IVertexBuffer>[] boundCompBuffers = inputLayout1.BoundComponentBuffers;
            Assert.AreEqual(buffers[0], boundCompBuffers.First(kvp => kvp.Key == vs1.GetBindingByIdentifier("POSITION")).Value);
            Assert.IsFalse(boundCompBuffers.Any(kvp => kvp.Value == buffers[1]));

            boundCompBuffers = inputLayout2.BoundComponentBuffers;
            Assert.AreEqual(buffers[0], boundCompBuffers.First(kvp => kvp.Key == vs2.GetBindingByIdentifier("POSITION")).Value);
            Assert.AreEqual(buffers[1], boundCompBuffers.First(kvp => kvp.Key == vs2.GetBindingByIdentifier("RANDOM_FLOATS")).Value);

            Assert.AreEqual(inputLayout1, cache.GetInputLayout(vs1));
            Assert.AreEqual(inputLayout2, cache.GetInputLayout(vs2));

            cache.Dispose();
            inputLayout2.Dispose();
            inputLayout1.Dispose();
            vs1.Dispose();
            vs2.Dispose();
            vs3.Dispose();
            instanceCBuffer.Dispose();
            indices.Dispose();
            buffers[1].Dispose();
            buffers[0].Dispose();
        }
        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();
        }
        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
        }