// 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(); }
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 }