示例#1
0
        // ReSharper disable once UnusedMember.Local Is used through reflection
        private void FillComponentBuffer <TComponent>(FieldInfo component, int componentIndex,
                                                      IBuffer[] vertexComponentBuffers, string[] vertexComponentSemantics, ResourceFormat[] vertexComponentFormats) where TComponent : struct
        {
            TComponent[] initialData = new TComponent[vertices.Count];

            for (int i = 0; i < vertices.Count; ++i)
            {
                initialData[i] = (TComponent)component.GetValue(vertices[i]);
            }

            VertexBuffer <TComponent> componentBuffer = BufferFactory.NewVertexBuffer <TComponent>()
                                                        .WithInitialData(initialData)
                                                        .WithUsage(ResourceUsage.Immutable);

            vertexComponentBuffers[componentIndex]   = componentBuffer;
            vertexComponentSemantics[componentIndex] = component.GetCustomAttribute <VertexComponentAttribute>().SemanticName;
            ResourceFormat componentFormat = (ResourceFormat)component.GetCustomAttribute <VertexComponentAttribute>().D3DResourceFormat;

            if (componentFormat == ResourceFormat.Unknown)
            {
                componentFormat = BaseResource.GetFormatForType(typeof(TComponent));
                if (componentFormat == ResourceFormat.Unknown)
                {
                    throw new InvalidOperationException("Could not discern resource format for type '" + typeof(TComponent).Name + "' " +
                                                        "with semantic '" + vertexComponentSemantics[componentIndex] + "', " +
                                                        "please specify a resource format using the \"D3DResourceFormat\" field of the VertexComponent attribute.");
                }
            }
            vertexComponentFormats[componentIndex] = componentFormat;
        }
        public void TestWrite()
        {
            // Define variables and constants
            VertexBuffer <int> testBuffer = BufferFactory.NewVertexBuffer <int>()
                                            .WithUsage(ResourceUsage.Write)
                                            .WithLength(300);

            // Set up context


            // Execute
            testBuffer.Write(Enumerable.Range(0, 300).ToArray(), 0);
            testBuffer.Write(Enumerable.Range(0, 200).ToArray(), 100);
            testBuffer.Write(new ArraySlice <int>(Enumerable.Range(0, 200).ToArray(), 50, 50), 24);


#if !DEVELOPMENT && !RELEASE
            try {
                testBuffer.Write(new ArraySlice <int>(Enumerable.Range(0, 200).ToArray(), 50), 250);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

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

            testBuffer.Dispose();
        }
        public void TestClone()
        {
            // Define variables and constants
            const ResourceUsage USAGE        = ResourceUsage.Write;
            const uint          NUM_VERTICES = 21515;
            VertexBuffer <int>  firstBuffer  = BufferFactory.NewVertexBuffer <int>().WithUsage(USAGE).WithLength(NUM_VERTICES);

            // Set up context


            // Execute
            VertexBuffer <int>  secondBuffer = firstBuffer.Clone();
            VertexBuffer <long> thirdBuffer  = secondBuffer.Clone().WithVertexType <long>();

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

            Assert.AreEqual(USAGE, thirdBuffer.Usage);
            Assert.AreEqual(secondBuffer.Length, thirdBuffer.Length);

            firstBuffer.Dispose();
            secondBuffer.Dispose();
            thirdBuffer.Dispose();
        }
示例#4
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();
        }
        public void TestSetInstanceBuffer()
        {
            const uint            INPUT_SLOT     = 3U;
            VertexBuffer <Matrix> instanceBuffer = BufferFactory.NewVertexBuffer <Matrix>()
                                                   .WithLength(10U)
                                                   .WithUsage(ResourceUsage.DiscardWrite);

            RenderCommand testCommand = RenderCommand.SetInstanceBuffer(instanceBuffer, INPUT_SLOT);

            Assert.AreEqual(RenderCommandInstruction.SetInstanceBuffer, testCommand.Instruction);
            Assert.AreEqual((RenderCommandArgument)(IntPtr)instanceBuffer.ResourceHandle, testCommand.Arg1);
            Assert.AreEqual((RenderCommandArgument)INPUT_SLOT, testCommand.Arg2);

            instanceBuffer.Dispose();

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

            try {
                RenderCommand.SetInstanceBuffer(instanceBuffer, INPUT_SLOT);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
        public unsafe void TestProperties()
        {
            // Define variables and constants
            const int FAKE_CACHE_ID = 1351617;

            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 <Vector2>()
                         .WithInitialData(new[] { Vector2.ONE * 0f, Vector2.ONE * 1f, Vector2.ONE * 2f, Vector2.ONE * 3f, Vector2.ONE * 4f, Vector2.ONE * 5f })
                         .WithUsage(ResourceUsage.Immutable)
                         .Create();
            string[]         semantics = { "POSITION", "TEXCOORD" };
            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(FakeVertex), FAKE_CACHE_ID, modelNameMap
                );


            // Execute


            // Assert outcome
            Assert.AreEqual(buffers[0], cache.VertexBuffers[0]);
            Assert.AreEqual(buffers[1], cache.VertexBuffers[1]);
            Assert.AreEqual(semantics[0], cache.VertexSemantics[0]);
            Assert.AreEqual(semantics[1], cache.VertexSemantics[1]);
            Assert.AreEqual(formats[0], cache.VertexFormats[0]);
            Assert.AreEqual(formats[1], cache.VertexFormats[1]);
            Assert.AreEqual(indices, cache.IndexBuffer);

            cache.Dispose();
        }
        public void TestCopyTo()
        {
            // Define variables and constants
            VertexBuffer <float> srcBuffer = BufferFactory.NewVertexBuffer <float>()
                                             .WithUsage(ResourceUsage.Immutable)
                                             .WithInitialData(Enumerable.Range(0, 3000).Select(@int => (float)@int).ToArray());
            VertexBuffer <float> dstBuffer = srcBuffer.Clone()
                                             .WithUsage(ResourceUsage.DiscardWrite);

            // Set up context


            // Execute
            srcBuffer.CopyTo(dstBuffer);
            srcBuffer.CopyTo(dstBuffer, 100, 2000, 500);

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

#if !DEVELOPMENT && !RELEASE
            try {
                srcBuffer.CopyTo(dstBuffer, 1600, 2000, 500);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }

            try {
                srcBuffer.CopyTo(dstBuffer, 0, 2000, 2000);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

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

            srcBuffer.Dispose();
            dstBuffer.Dispose();
        }
        public unsafe void TestGetModelBufferValues()
        {
            // Define variables and constants
            const int FAKE_CACHE_ID = 1351616;

            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 <Vector2>()
                         .WithInitialData(new[] { Vector2.ONE * 0f, Vector2.ONE * 1f, Vector2.ONE * 2f, Vector2.ONE * 3f, Vector2.ONE * 4f, Vector2.ONE * 5f })
                         .WithUsage(ResourceUsage.Immutable)
                         .Create();
            string[]         semantics = { "POSITION", "TEXCOORD" };
            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;

            uint outVBStartIndex, outIBStartIndex, outVBCount, outIBCount;

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

            // Execute
            cache.GetModelBufferValues(0U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);

            // Assert outcome
            Assert.AreEqual(0U, outVBStartIndex);
            Assert.AreEqual(0U, outIBStartIndex);
            Assert.AreEqual(3U, outVBCount);
            Assert.AreEqual(9U, outIBCount);

            cache.GetModelBufferValues(1U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);

            Assert.AreEqual(3U, outVBStartIndex);
            Assert.AreEqual(9U, outIBStartIndex);
            Assert.AreEqual(3U, outVBCount);
            Assert.AreEqual(12U, outIBCount);

#if !DEVELOPMENT && !RELEASE
            try {
                cache.GetModelBufferValues(2U, out outVBStartIndex, out outIBStartIndex, out outVBCount, out outIBCount);
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif

            cache.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 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
        }