Пример #1
0
        public unsafe void Copy_1DTo2D()
        {
            if (!GD.Features.Texture1D)
            {
                return;
            }

            Texture tex1D = RF.CreateTexture(
                TextureDescription.Texture1D(100, 1, 1, PixelFormat.R16_UNorm, TextureUsage.Staging));
            Texture tex2D = RF.CreateTexture(
                TextureDescription.Texture2D(100, 10, 1, 1, PixelFormat.R16_UNorm, TextureUsage.Staging));

            MappedResourceView <ushort> writeView = GD.Map <ushort>(tex1D, MapMode.Write);

            Assert.Equal(tex1D.Width, (uint)writeView.Count);
            for (int i = 0; i < writeView.Count; i++)
            {
                writeView[i] = (ushort)(i * 2);
            }
            GD.Unmap(tex1D);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(
                tex1D, 0, 0, 0, 0, 0,
                tex2D, 0, 5, 0, 0, 0,
                tex1D.Width, 1, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.DisposeWhenIdle(cl);
            GD.WaitForIdle();

            MappedResourceView <ushort> readView = GD.Map <ushort>(tex2D, MapMode.Read);

            for (int i = 0; i < tex2D.Width; i++)
            {
                Assert.Equal((ushort)(i * 2), readView[i, 5]);
            }
            GD.Unmap(tex2D);
        }
Пример #2
0
        private DeviceBuffer GetReadback(DeviceBuffer buffer)
        {
            DeviceBuffer readback;

            if ((buffer.Usage & BufferUsage.Staging) != 0)
            {
                readback = buffer;
            }
            else
            {
                readback = CreateBuffer(buffer.SizeInBytes, BufferUsage.Staging);
                CommandList cl = RF.CreateCommandList();
                cl.Begin();
                cl.CopyBuffer(buffer, 0, readback, 0, buffer.SizeInBytes);
                cl.End();
                GD.SubmitCommands(cl);
                GD.WaitForIdle();
            }

            return(readback);
        }
Пример #3
0
        public void Copy_ArrayToNonArray()
        {
            Texture src = RF.CreateTexture(TextureDescription.Texture2D(
                                               10, 10, 1, 10, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));
            Texture dst = RF.CreateTexture(TextureDescription.Texture2D(
                                               10, 10, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging));

            MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(src, MapMode.Write, 5);

            for (int y = 0; y < src.Height; y++)
            {
                for (int x = 0; x < src.Width; x++)
                {
                    writeView[x, y] = new RgbaByte((byte)x, (byte)y, 0, 1);
                }
            }
            GD.Unmap(src, 5);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(
                src, 0, 0, 0, 0, 5,
                dst, 0, 0, 0, 0, 0,
                10, 10, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(dst, MapMode.Read);

            for (int y = 0; y < dst.Height; y++)
            {
                for (int x = 0; x < dst.Width; x++)
                {
                    Assert.Equal(new RgbaByte((byte)x, (byte)y, 0, 1), readView[x, y]);
                }
            }
            GD.Unmap(dst);
        }
Пример #4
0
        public void ResourceSet_InvalidSlot_Fails()
        {
            DeviceBuffer infoBuffer  = RF.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer));
            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2),
                    new VertexElementDescription("Color_UInt", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UInt4))
            },
                TestShaders.LoadVertexFragment(RF, "UIntVertexAttribs"));

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("InfoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                new ResourceLayoutElementDescription("Ortho", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, infoBuffer, orthoBuffer));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                new OutputDescription(null, new OutputAttachmentDescription(PixelFormat.B8_G8_R8_A8_UNorm)));

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(pipeline);
            Assert.Throws <VeldridException>(() => cl.SetGraphicsResourceSet(1, set));
            Assert.Throws <VeldridException>(() => cl.SetGraphicsResourceSet(2, set));
            Assert.Throws <VeldridException>(() => cl.SetGraphicsResourceSet(3, set));
            cl.End();
        }
Пример #5
0
        public void CommandList_Update_Staging()
        {
            DeviceBuffer staging = RF.CreateBuffer(
                new BufferDescription(1024, BufferUsage.Staging));

            byte[] data = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.UpdateBuffer(staging, 0, data);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <byte> readView = GD.Map <byte>(staging, MapMode.Read);

            for (uint i = 0; i < staging.SizeInBytes; i++)
            {
                Assert.Equal((byte)i, readView[i]);
            }
        }
Пример #6
0
        public unsafe void UpdateBuffer_ZeroSize(BufferUsage usage, bool useCommandListUpdate)
        {
            DeviceBuffer buffer = CreateBuffer(1024, usage);

            byte[] initialData = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
            byte[] otherData   = Enumerable.Range(0, 1024).Select(i => (byte)(i + 10)).ToArray();
            GD.UpdateBuffer(buffer, 0, initialData);

            if (useCommandListUpdate)
            {
                CommandList cl = RF.CreateCommandList();
                cl.Begin();
                fixed(byte *dataPtr = otherData)
                {
                    cl.UpdateBuffer(buffer, 0, (IntPtr)dataPtr, 0);
                }

                cl.End();
                GD.SubmitCommands(cl);
                GD.WaitForIdle();
            }
            else
            {
                fixed(byte *dataPtr = otherData)
                {
                    GD.UpdateBuffer(buffer, 0, (IntPtr)dataPtr, 0);
                }
            }

            DeviceBuffer readback = GetReadback(buffer);

            MappedResourceView <byte> readMap = GD.Map <byte>(readback, MapMode.Read);

            for (int i = 0; i < 1024; i++)
            {
                Assert.Equal((byte)i, readMap[i]);
            }
            GD.Unmap(readback);
        }
Пример #7
0
        public unsafe void Copy_BC3_Unorm()
        {
            Texture copySrc = RF.CreateTexture(TextureDescription.Texture2D(
                                                   64, 64, 1, 1, PixelFormat.BC3_UNorm, TextureUsage.Staging));
            Texture copyDst = RF.CreateTexture(TextureDescription.Texture2D(
                                                   64, 64, 1, 1, PixelFormat.BC3_UNorm, TextureUsage.Staging));

            uint totalDataSize = copySrc.Width * copySrc.Height;

            byte[] data = new byte[totalDataSize];

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (byte)i;
            }

            fixed(byte *dataPtr = data)
            {
                GD.UpdateTexture(copySrc, (IntPtr)dataPtr, totalDataSize, 0, 0, 0, copySrc.Width, copySrc.Height, 1, 0, 0);
            }

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyTexture(
                copySrc, 0, 0, 0, 0, 0,
                copyDst, 0, 0, 0, 0, 0,
                copySrc.Width, copySrc.Height, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();
            MappedResourceView <byte> view = GD.Map <byte>(copyDst, MapMode.Read);

            for (int i = 0; i < data.Length; i++)
            {
                Assert.Equal(view[i], data[i]);
            }
        }
Пример #8
0
        public void Update_Dynamic_NonZeroOffset()
        {
            DeviceBuffer dynamic = RF.CreateBuffer(
                new BufferDescription(1024, BufferUsage.Dynamic | BufferUsage.UniformBuffer));

            byte[] initialData = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
            GD.UpdateBuffer(dynamic, 0, initialData);

            byte[]      replacementData = Enumerable.Repeat((byte)255, 512).ToArray();
            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.UpdateBuffer(dynamic, 512, replacementData);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer dst = RF.CreateBuffer(
                new BufferDescription(1024, BufferUsage.Staging));

            cl.Begin();
            cl.CopyBuffer(dynamic, 0, dst, 0, dynamic.SizeInBytes);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <byte> readView = GD.Map <byte>(dst, MapMode.Read);

            for (uint i = 0; i < 512; i++)
            {
                Assert.Equal((byte)i, readView[i]);
            }

            for (uint i = 512; i < 1024; i++)
            {
                Assert.Equal((byte)255, readView[i]);
            }
        }
Пример #9
0
        public void UpdateUniform_Offset_CommandList(BufferUsage usage)
        {
            DeviceBuffer buffer = CreateBuffer(128, usage);
            CommandList  cl     = RF.CreateCommandList();

            cl.Begin();
            Matrix4x4 mat1 = new Matrix4x4(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);

            cl.UpdateBuffer(buffer, 0, ref mat1);
            Matrix4x4 mat2 = new Matrix4x4(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);

            cl.UpdateBuffer(buffer, 64, ref mat2);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(buffer);
            MappedResourceView <Matrix4x4> readView = GD.Map <Matrix4x4>(readback, MapMode.Read);

            Assert.Equal(mat1, readView[0]);
            Assert.Equal(mat2, readView[1]);
            GD.Unmap(readback);
        }
Пример #10
0
        public void CommandList_UpdateNonStaging_Unaligned(BufferUsage usage, uint bufferSize, uint dataSize, uint offset)
        {
            DeviceBuffer buffer = CreateBuffer(bufferSize, usage);

            byte[]      data = Enumerable.Range(0, (int)dataSize).Select(i => (byte)i).ToArray();
            CommandList cl   = RF.CreateCommandList();

            cl.Begin();
            cl.UpdateBuffer(buffer, offset, data);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(buffer);
            MappedResourceView <byte> readView = GD.Map <byte>(readback, MapMode.Read);

            for (uint i = 0; i < dataSize; i++)
            {
                byte expected = data[i];
                byte actual   = readView[i + offset];
                Assert.Equal(expected, actual);
            }
            GD.Unmap(readback);
        }
Пример #11
0
        public unsafe void UnusualSize()
        {
            DeviceBuffer src = RF.CreateBuffer(
                new BufferDescription(208, BufferUsage.UniformBuffer));
            DeviceBuffer dst = RF.CreateBuffer(
                new BufferDescription(208, BufferUsage.Staging));

            byte[] data = Enumerable.Range(0, 208).Select(i => (byte)(i * 150)).ToArray();
            GD.UpdateBuffer(src, 0, data);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyBuffer(src, 0, dst, 0, src.SizeInBytes);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();
            MappedResource readMap = GD.Map(dst, MapMode.Read);

            for (int i = 0; i < readMap.SizeInBytes; i++)
            {
                Assert.Equal((byte)(i * 150), ((byte *)readMap.Data)[i]);
            }
        }
Пример #12
0
        public void FillBuffer_WithOffsets(uint srcSetMultiple, uint srcBindingMultiple, uint dstSetMultiple, uint dstBindingMultiple, bool combinedLayout)
        {
            if (!GD.Features.ComputeShader)
            {
                return;
            }
            Debug.Assert((GD.StructuredBufferMinOffsetAlignment % sizeof(uint)) == 0);

            uint valueCount        = 512;
            uint dataSize          = valueCount * sizeof(uint);
            uint totalSrcAlignment = GD.StructuredBufferMinOffsetAlignment * (srcSetMultiple + srcBindingMultiple);
            uint totalDstAlignment = GD.StructuredBufferMinOffsetAlignment * (dstSetMultiple + dstBindingMultiple);

            DeviceBuffer copySrc = RF.CreateBuffer(
                new BufferDescription(totalSrcAlignment + dataSize, BufferUsage.StructuredBufferReadOnly, sizeof(uint)));
            DeviceBuffer copyDst = RF.CreateBuffer(
                new BufferDescription(totalDstAlignment + dataSize, BufferUsage.StructuredBufferReadWrite, sizeof(uint)));

            ResourceLayout[] layouts;
            ResourceSet[]    sets;

            DeviceBufferRange srcRange = new DeviceBufferRange(copySrc, srcSetMultiple * GD.StructuredBufferMinOffsetAlignment, dataSize);
            DeviceBufferRange dstRange = new DeviceBufferRange(copyDst, dstSetMultiple * GD.StructuredBufferMinOffsetAlignment, dataSize);

            if (combinedLayout)
            {
                layouts = new[]
                {
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopySrc",
                                                    ResourceKind.StructuredBufferReadOnly,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding),
                                                new ResourceLayoutElementDescription(
                                                    "CopyDst",
                                                    ResourceKind.StructuredBufferReadWrite,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding)))
                };
                sets = new[]
                {
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[0], srcRange, dstRange))
                };
            }
            else
            {
                layouts = new[]
                {
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopySrc",
                                                    ResourceKind.StructuredBufferReadOnly,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding))),
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopyDst",
                                                    ResourceKind.StructuredBufferReadWrite,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding)))
                };
                sets = new[]
                {
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[0], srcRange)),
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[1], dstRange)),
                };
            }

            Pipeline pipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                             TestShaders.LoadCompute(RF, combinedLayout ? "FillBuffer" : "FillBuffer_SeparateLayout"),
                                                             layouts,
                                                             1, 1, 1));

            uint[] srcData = Enumerable.Range(0, (int)copySrc.SizeInBytes / sizeof(uint)).Select(i => (uint)i).ToArray();
            GD.UpdateBuffer(copySrc, 0, srcData);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(pipeline);
            if (combinedLayout)
            {
                uint[] offsets = new[]
                {
                    srcBindingMultiple *GD.StructuredBufferMinOffsetAlignment,
                       dstBindingMultiple *GD.StructuredBufferMinOffsetAlignment
                };
                cl.SetComputeResourceSet(0, sets[0], offsets);
            }
            else
            {
                uint offset = srcBindingMultiple * GD.StructuredBufferMinOffsetAlignment;
                cl.SetComputeResourceSet(0, sets[0], 1, ref offset);
                offset = dstBindingMultiple * GD.StructuredBufferMinOffsetAlignment;
                cl.SetComputeResourceSet(1, sets[1], 1, ref offset);
            }
            cl.Dispatch(512, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(copyDst);

            MappedResourceView <uint> readView = GD.Map <uint>(readback, MapMode.Read);
            for (uint i = 0; i < valueCount; i++)
            {
                uint srcIndex = totalSrcAlignment / sizeof(uint) + i;
                uint expected = srcData[(int)srcIndex];

                uint dstIndex = totalDstAlignment / sizeof(uint) + i;
                uint actual   = readView[dstIndex];

                Assert.Equal(expected, actual);
            }
            GD.Unmap(readback);
        }
Пример #13
0
        public void BasicCompute()
        {
            if (!GD.Features.ComputeShader)
            {
                return;
            }

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("Params", ResourceKind.UniformBuffer, ShaderStages.Compute),
                                                                new ResourceLayoutElementDescription("Source", ResourceKind.StructuredBufferReadWrite, ShaderStages.Compute),
                                                                new ResourceLayoutElementDescription("Destination", ResourceKind.StructuredBufferReadWrite, ShaderStages.Compute)));

            uint         width             = 1024;
            uint         height            = 1024;
            DeviceBuffer paramsBuffer      = RF.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <BasicComputeTestParams>(), BufferUsage.UniformBuffer));
            DeviceBuffer sourceBuffer      = RF.CreateBuffer(new BufferDescription(width * height * 4, BufferUsage.StructuredBufferReadWrite, 4));
            DeviceBuffer destinationBuffer = RF.CreateBuffer(new BufferDescription(width * height * 4, BufferUsage.StructuredBufferReadWrite, 4));

            GD.UpdateBuffer(paramsBuffer, 0, new BasicComputeTestParams {
                Width = width, Height = height
            });

            float[] sourceData = new float[width * height];
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int index = y * (int)width + x;
                    sourceData[index] = index;
                }
            }
            GD.UpdateBuffer(sourceBuffer, 0, sourceData);

            ResourceSet rs = RF.CreateResourceSet(new ResourceSetDescription(layout, paramsBuffer, sourceBuffer, destinationBuffer));

            Pipeline pipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                             TestShaders.LoadCompute(RF, "BasicComputeTest"),
                                                             layout,
                                                             16, 16, 1));

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(pipeline);
            cl.SetComputeResourceSet(0, rs);
            cl.Dispatch(width / 16, width / 16, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer sourceReadback      = GetReadback(sourceBuffer);
            DeviceBuffer destinationReadback = GetReadback(destinationBuffer);

            MappedResourceView <float> sourceReadView      = GD.Map <float>(sourceReadback, MapMode.Read);
            MappedResourceView <float> destinationReadView = GD.Map <float>(destinationReadback, MapMode.Read);

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int index = y * (int)width + x;
                    Assert.Equal(2 * sourceData[index], sourceReadView[index]);
                    Assert.Equal(sourceData[index], destinationReadView[index]);
                }
            }

            GD.Unmap(sourceReadback);
            GD.Unmap(destinationReadback);
        }
Пример #14
0
        public void ComputeShader3dTexture()
        {
            // Just a dumb compute shader that fills a 3D texture with the same value from a uniform multiplied by the depth.
            string shaderText = @"
#version 450
layout(set = 0, binding = 0, rgba32f) uniform image3D TextureToFill;
layout(set = 0, binding = 1) uniform FillValueBuffer
{
    float FillValue;
    float Padding1;
    float Padding2;
    float Padding3;
};
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
    ivec3 textureCoordinate = ivec3(gl_GlobalInvocationID.xyz);
    float dataToStore = FillValue * (textureCoordinate.z + 1);

    imageStore(TextureToFill, textureCoordinate, vec4(dataToStore));
}
";

            const float FillValue         = 42.42f;
            const uint  OutputTextureSize = 32;

            using Shader computeShader = RF.CreateFromSpirv(new ShaderDescription(
                                                                ShaderStages.Compute,
                                                                Encoding.ASCII.GetBytes(shaderText),
                                                                "main"));

            using ResourceLayout computeLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                             new ResourceLayoutElementDescription("TextureToFill", ResourceKind.TextureReadWrite, ShaderStages.Compute),
                                                                             new ResourceLayoutElementDescription("FillValueBuffer", ResourceKind.UniformBuffer, ShaderStages.Compute)));

            using Pipeline computePipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                                          computeShader,
                                                                          computeLayout,
                                                                          16, 16, 1));

            using DeviceBuffer fillValueBuffer = RF.CreateBuffer(new BufferDescription((uint)Marshal.SizeOf <FillValueStruct>(), BufferUsage.UniformBuffer));

            // Create our output texture.
            using Texture computeTargetTexture = RF.CreateTexture(TextureDescription.Texture3D(
                                                                      OutputTextureSize,
                                                                      OutputTextureSize,
                                                                      OutputTextureSize,
                                                                      1,
                                                                      PixelFormat.R32_G32_B32_A32_Float,
                                                                      TextureUsage.Sampled | TextureUsage.Storage));

            using TextureView computeTargetTextureView = RF.CreateTextureView(computeTargetTexture);

            using ResourceSet computeResourceSet = RF.CreateResourceSet(new ResourceSetDescription(
                                                                            computeLayout,
                                                                            computeTargetTextureView,
                                                                            fillValueBuffer));

            using CommandList cl = RF.CreateCommandList();
            cl.Begin();

            cl.UpdateBuffer(fillValueBuffer, 0, new FillValueStruct(FillValue));

            // Use the compute shader to fill the texture.
            cl.SetPipeline(computePipeline);
            cl.SetComputeResourceSet(0, computeResourceSet);
            const uint GroupDivisorXY = 16;

            cl.Dispatch(OutputTextureSize / GroupDivisorXY, OutputTextureSize / GroupDivisorXY, OutputTextureSize);

            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            // Read back from our texture and make sure it has been properly filled.
            for (uint depth = 0; depth < computeTargetTexture.Depth; depth++)
            {
                RgbaFloat expectedFillValue = new RgbaFloat(new System.Numerics.Vector4(FillValue * (depth + 1)));
                int       notFilledCount    = CountTexelsNotFilledAtDepth(GD, computeTargetTexture, expectedFillValue, depth);

                if (notFilledCount == 0)
                {
                    // Expected behavior:
                    Console.WriteLine($"All texels were properly set at depth {depth}");
                }
                else
                {
                    // Unexpected behavior:
                    uint totalTexels = computeTargetTexture.Width * computeTargetTexture.Height;
                    throw new Exception($"{notFilledCount} of {totalTexels} texels were not properly set at depth {depth}");
                }
            }
        }
Пример #15
0
        public void SampleTexture1D(bool arrayTexture)
        {
            if (!GD.Features.Texture1D)
            {
                return;
            }

            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            string SetName = arrayTexture ? "FullScreenTriSampleTextureArray" : "FullScreenTriSampleTexture";
            ShaderSetDescription shaderSet = new ShaderSetDescription(
                Array.Empty <VertexLayoutDescription>(),
                TestShaders.LoadVertexFragment(RF, SetName));

            uint    layers = arrayTexture ? 10u : 1u;
            Texture tex1D  = RF.CreateTexture(
                TextureDescription.Texture1D(128, 1, layers, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Sampled));

            RgbaFloat[] colors = new RgbaFloat[tex1D.Width];
            for (int i = 0; i < colors.Length; i++)
            {
                colors[i] = RgbaFloat.Pink;
            }
            GD.UpdateTexture(tex1D, colors, 0, 0, 0, tex1D.Width, 1, 1, 0, 0);

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("Tex", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                new ResourceLayoutElementDescription("Smp", ResourceKind.Sampler, ShaderStages.Fragment)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, tex1D, GD.PointSampler));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.CullNone,
                PrimitiveTopology.TriangleList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetFramebuffer(framebuffer);
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.SetPipeline(pipeline);
            cl.SetGraphicsResourceSet(0, set);
            cl.Draw(3);
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            for (int x = 0; x < staging.Width; x++)
            {
                Assert.Equal(RgbaFloat.Pink, readView[x, 0]);
            }
            GD.Unmap(staging);
        }
Пример #16
0
        public void Points_WithUShortNormColor()
        {
            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));
            Matrix4x4    orthoMatrix = Matrix4x4.CreateOrthographicOffCenter(
                0,
                framebuffer.Width,
                framebuffer.Height,
                0,
                -1,
                1);

            GD.UpdateBuffer(orthoBuffer, 0, ref orthoMatrix);

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2),
                    new VertexElementDescription("Color", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UShort4_Norm))
            },
                TestShaders.LoadVertexFragment(RF, "U16NormVertexAttribs"));

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("Ortho", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, orthoBuffer));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            VertexCPU_UShortNorm[] vertices = new VertexCPU_UShortNorm[]
            {
                new VertexCPU_UShortNorm
                {
                    Position = new Vector2(0.5f, 0.5f),
                    R        = UShortNorm(0.25f),
                    G        = UShortNorm(0.5f),
                    B        = UShortNorm(0.75f),
                },
                new VertexCPU_UShortNorm
                {
                    Position = new Vector2(10.5f, 12.5f),
                    R        = UShortNorm(0.25f),
                    G        = UShortNorm(0.5f),
                    B        = UShortNorm(0.75f),
                },
                new VertexCPU_UShortNorm
                {
                    Position = new Vector2(25.5f, 35.5f),
                    R        = UShortNorm(0.75f),
                    G        = UShortNorm(0.5f),
                    B        = UShortNorm(0.25f),
                },
                new VertexCPU_UShortNorm
                {
                    Position = new Vector2(49.5f, 49.5f),
                    R        = UShortNorm(0.15f),
                    G        = UShortNorm(0.25f),
                    B        = UShortNorm(0.35f),
                },
            };

            DeviceBuffer vb = RF.CreateBuffer(
                new BufferDescription((uint)(Unsafe.SizeOf <VertexCPU_UShortNorm>() * vertices.Length), BufferUsage.VertexBuffer));

            GD.UpdateBuffer(vb, 0, vertices);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetFramebuffer(framebuffer);
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.SetPipeline(pipeline);
            cl.SetVertexBuffer(0, vb);
            cl.SetGraphicsResourceSet(0, set);
            cl.Draw((uint)vertices.Length);
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            foreach (VertexCPU_UShortNorm vertex in vertices)
            {
                uint x = (uint)vertex.Position.X;
                uint y = (uint)vertex.Position.Y;
                if (!GD.IsUvOriginTopLeft || GD.IsClipSpaceYInverted)
                {
                    y = framebuffer.Height - y - 1;
                }

                RgbaFloat expectedColor = new RgbaFloat(
                    vertex.R / (float)ushort.MaxValue,
                    vertex.G / (float)ushort.MaxValue,
                    vertex.B / (float)ushort.MaxValue,
                    1);
                Assert.Equal(expectedColor, readView[x, y], RgbaFloatFuzzyComparer.Instance);
            }
            GD.Unmap(staging);
        }
Пример #17
0
        public void Points_WithFloat16Color()
        {
            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            DeviceBuffer infoBuffer  = RF.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer));
            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));
            Matrix4x4    orthoMatrix = Matrix4x4.CreateOrthographicOffCenter(
                0,
                framebuffer.Width,
                framebuffer.Height,
                0,
                -1,
                1);

            GD.UpdateBuffer(orthoBuffer, 0, ref orthoMatrix);

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2),
                    new VertexElementDescription("Color_Half", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Half4))
            },
                TestShaders.LoadVertexFragment(RF, "F16VertexAttribs"));

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("InfoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                new ResourceLayoutElementDescription("OrthoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, infoBuffer, orthoBuffer));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            uint colorNormalizationFactor = 2500;

            const ushort f16_375  = 0x5DDC; // 375.0
            const ushort f16_500  = 0x5FD0; // 500.0
            const ushort f16_625  = 0x60E2; // 625.0
            const ushort f16_875  = 0x62D6; // 875.0
            const ushort f16_1250 = 0x64E2; // 1250.0
            const ushort f16_1875 = 0x6753; // 1875.0

            VertexCPU_UShort[] vertices = new VertexCPU_UShort[]
            {
                new VertexCPU_UShort
                {
                    Position = new Vector2(0.5f, 0.5f),
                    R        = f16_625,
                    G        = f16_1250,
                    B        = f16_1875,
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(10.5f, 12.5f),
                    R        = f16_625,
                    G        = f16_1250,
                    B        = f16_1875,
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(25.5f, 35.5f),
                    R        = f16_1875,
                    G        = f16_1250,
                    B        = f16_625,
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(49.5f, 49.5f),
                    R        = f16_375,
                    G        = f16_500,
                    B        = f16_875,
                },
            };

            RgbaFloat[] expectedColors = new[]
            {
                new RgbaFloat(
                    625.0f / colorNormalizationFactor,
                    1250.0f / colorNormalizationFactor,
                    1875.0f / colorNormalizationFactor,
                    1),
                new RgbaFloat(
                    625.0f / colorNormalizationFactor,
                    1250.0f / colorNormalizationFactor,
                    1875.0f / colorNormalizationFactor,
                    1),
                new RgbaFloat(
                    1875.0f / colorNormalizationFactor,
                    1250.0f / colorNormalizationFactor,
                    625.0f / colorNormalizationFactor,
                    1),
                new RgbaFloat(
                    375.0f / colorNormalizationFactor,
                    500.0f / colorNormalizationFactor,
                    875.0f / colorNormalizationFactor,
                    1),
            };

            DeviceBuffer vb = RF.CreateBuffer(
                new BufferDescription((uint)(Unsafe.SizeOf <UIntVertexAttribsVertex>() * vertices.Length), BufferUsage.VertexBuffer));

            GD.UpdateBuffer(vb, 0, vertices);
            GD.UpdateBuffer(infoBuffer, 0, new UIntVertexAttribsInfo {
                ColorNormalizationFactor = colorNormalizationFactor
            });

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetFramebuffer(framebuffer);
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.SetPipeline(pipeline);
            cl.SetVertexBuffer(0, vb);
            cl.SetGraphicsResourceSet(0, set);
            cl.Draw((uint)vertices.Length);
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            for (int i = 0; i < vertices.Length; i++)
            {
                VertexCPU_UShort vertex = vertices[i];
                uint             x      = (uint)vertex.Position.X;
                uint             y      = (uint)vertex.Position.Y;
                if (!GD.IsUvOriginTopLeft || GD.IsClipSpaceYInverted)
                {
                    y = framebuffer.Height - y - 1;
                }

                RgbaFloat expectedColor = expectedColors[i];
                Assert.Equal(expectedColor, readView[x, y], RgbaFloatFuzzyComparer.Instance);
            }
            GD.Unmap(staging);
        }
Пример #18
0
        public void ComputeGeneratedTexture()
        {
            if (!GD.Features.ComputeShader)
            {
                return;
            }

            uint width  = 4;
            uint height = 1;
            TextureDescription texDesc = TextureDescription.Texture2D(
                width, height,
                1,
                1,
                PixelFormat.R32_G32_B32_A32_Float,
                TextureUsage.Sampled | TextureUsage.Storage);
            Texture computeOutput = RF.CreateTexture(texDesc);

            texDesc.Usage = TextureUsage.RenderTarget;
            Texture     finalOutput = RF.CreateTexture(texDesc);
            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, finalOutput));

            ResourceLayout computeLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                       new ResourceLayoutElementDescription("ComputeOutput", ResourceKind.TextureReadWrite, ShaderStages.Compute)));
            ResourceSet computeSet = RF.CreateResourceSet(new ResourceSetDescription(computeLayout, computeOutput));

            Pipeline computePipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                                    TestShaders.LoadCompute(RF, "ComputeTextureGenerator"),
                                                                    computeLayout,
                                                                    4, 1, 1));

            ResourceLayout graphicsLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                        new ResourceLayoutElementDescription("Input", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                        new ResourceLayoutElementDescription("InputSampler", ResourceKind.Sampler, ShaderStages.Fragment)));
            ResourceSet graphicsSet = RF.CreateResourceSet(new ResourceSetDescription(graphicsLayout, computeOutput, GD.PointSampler));

            Pipeline graphicsPipeline = RF.CreateGraphicsPipeline(new GraphicsPipelineDescription(
                                                                      BlendStateDescription.SingleOverrideBlend,
                                                                      DepthStencilStateDescription.Disabled,
                                                                      RasterizerStateDescription.CullNone,
                                                                      PrimitiveTopology.TriangleStrip,
                                                                      new ShaderSetDescription(
                                                                          Array.Empty <VertexLayoutDescription>(),
                                                                          TestShaders.LoadVertexFragment(RF, "FullScreenBlit")),
                                                                      graphicsLayout,
                                                                      framebuffer.OutputDescription));

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(computePipeline);
            cl.SetComputeResourceSet(0, computeSet);
            cl.Dispatch(1, 1, 1);
            cl.SetFramebuffer(framebuffer);
            cl.ClearColorTarget(0, new RgbaFloat());
            cl.SetPipeline(graphicsPipeline);
            cl.SetGraphicsResourceSet(0, graphicsSet);
            cl.Draw(4);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            Texture readback = GetReadback(finalOutput);
            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(readback, MapMode.Read);

            Assert.Equal(RgbaFloat.Red, readView[0, 0]);
            Assert.Equal(RgbaFloat.Green, readView[1, 0]);
            Assert.Equal(RgbaFloat.Blue, readView[2, 0]);
            Assert.Equal(RgbaFloat.White, readView[3, 0]);
            GD.Unmap(readback);
        }
Пример #19
0
        public unsafe void Copy_Compressed_Array(bool separateLayerCopies)
        {
            PixelFormat format = PixelFormat.BC3_UNorm;

            if (!GD.GetPixelFormatSupport(format, TextureType.Texture2D, TextureUsage.Sampled))
            {
                return;
            }

            TextureDescription texDesc = TextureDescription.Texture2D(
                16, 16,
                1, 4,
                format,
                TextureUsage.Sampled);

            Texture copySrc = RF.CreateTexture(texDesc);

            texDesc.Usage = TextureUsage.Staging;
            Texture copyDst = RF.CreateTexture(texDesc);

            for (uint layer = 0; layer < copySrc.ArrayLayers; layer++)
            {
                int    byteCount = 16 * 16;
                byte[] data      = Enumerable.Range(0, byteCount).Select(i => (byte)(i + layer)).ToArray();
                GD.UpdateTexture(
                    copySrc,
                    data,
                    0, 0, 0,
                    16, 16, 1,
                    0, layer);
            }

            CommandList copyCL = RF.CreateCommandList();

            copyCL.Begin();
            if (separateLayerCopies)
            {
                for (uint layer = 0; layer < copySrc.ArrayLayers; layer++)
                {
                    copyCL.CopyTexture(copySrc, 0, 0, 0, 0, layer, copyDst, 0, 0, 0, 0, layer, 16, 16, 1, 1);
                }
            }
            else
            {
                copyCL.CopyTexture(copySrc, 0, 0, 0, 0, 0, copyDst, 0, 0, 0, 0, 0, 16, 16, 1, copySrc.ArrayLayers);
            }
            copyCL.End();
            Fence fence = RF.CreateFence(false);

            GD.SubmitCommands(copyCL, fence);
            GD.WaitForFence(fence);

            for (uint layer = 0; layer < copyDst.ArrayLayers; layer++)
            {
                MappedResource map     = GD.Map(copyDst, MapMode.Read, layer);
                byte *         basePtr = (byte *)map.Data;

                int  index   = 0;
                uint rowSize = 64;
                uint numRows = 4;
                for (uint row = 0; row < numRows; row++)
                {
                    byte *rowBase = basePtr + (row * map.RowPitch);
                    for (uint x = 0; x < rowSize; x++)
                    {
                        Assert.Equal((byte)(index + layer), rowBase[x]);
                        index += 1;
                    }
                }

                GD.Unmap(copyDst, layer);
            }
        }
Пример #20
0
        public void Points_WithUShortColor()
        {
            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            DeviceBuffer infoBuffer  = RF.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer));
            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));
            Matrix4x4    orthoMatrix = Matrix4x4.CreateOrthographicOffCenter(
                0,
                framebuffer.Width,
                framebuffer.Height,
                0,
                -1,
                1);

            GD.UpdateBuffer(orthoBuffer, 0, ref orthoMatrix);

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float2),
                    new VertexElementDescription("Color_UInt", VertexElementSemantic.Color, VertexElementFormat.UShort4))
            },
                new Shader[]
            {
                TestShaders.Load(RF, "U16VertexAttribs", ShaderStages.Vertex, "VS"),
                TestShaders.Load(RF, "U16VertexAttribs", ShaderStages.Fragment, "FS")
            });

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("InfoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                new ResourceLayoutElementDescription("Ortho", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, infoBuffer, orthoBuffer));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            uint colorNormalizationFactor = 2500;

            VertexCPU_UShort[] vertices = new VertexCPU_UShort[]
            {
                new VertexCPU_UShort
                {
                    Position = new Vector2(0.5f, 0.5f),
                    R        = (ushort)(0.25f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.75f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(10.5f, 12.5f),
                    R        = (ushort)(0.25f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.75f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(25.5f, 35.5f),
                    R        = (ushort)(0.75f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.25f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(49.5f, 49.5f),
                    R        = (ushort)(0.15f * colorNormalizationFactor),
                    G        = (ushort)(0.2f * colorNormalizationFactor),
                    B        = (ushort)(0.35f * colorNormalizationFactor),
                },
            };

            DeviceBuffer vb = RF.CreateBuffer(
                new BufferDescription((uint)(Unsafe.SizeOf <UIntVertexAttribs.Vertex>() * vertices.Length), BufferUsage.VertexBuffer));

            GD.UpdateBuffer(vb, 0, vertices);
            GD.UpdateBuffer(infoBuffer, 0, new UIntVertexAttribs.Info {
                ColorNormalizationFactor = colorNormalizationFactor
            });

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetFramebuffer(framebuffer);
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.SetPipeline(pipeline);
            cl.SetVertexBuffer(0, vb);
            cl.SetGraphicsResourceSet(0, set);
            cl.Draw((uint)vertices.Length);
            cl.SetFramebuffer(GD.SwapchainFramebuffer);
            cl.ClearColorTarget(0, RgbaFloat.Red);
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            foreach (VertexCPU_UShort vertex in vertices)
            {
                uint x = (uint)vertex.Position.X;
                uint y = (uint)vertex.Position.Y;
                if (GD.BackendType == GraphicsBackend.OpenGL)
                {
                    y = framebuffer.Height - y - 1;
                }

                RgbaFloat expectedColor = new RgbaFloat(
                    vertex.R / (float)colorNormalizationFactor,
                    vertex.G / (float)colorNormalizationFactor,
                    vertex.B / (float)colorNormalizationFactor,
                    1);
                Assert.Equal(expectedColor, readView[x, y], RgbaFloatFuzzyComparer.Instance);
            }
            GD.Unmap(staging);
        }
Пример #21
0
        public unsafe void Points_WithTexture_UpdateUnrelated(bool useTextureView)
        {
            // This is a regression test for the case where a user modifies an unrelated texture
            // at a time after a ResourceSet containing a texture has been bound. The OpenGL
            // backend was caching texture state improperly, resulting in wrong textures being sampled.

            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));
            Matrix4x4    orthoMatrix = Matrix4x4.CreateOrthographicOffCenter(
                0,
                framebuffer.Width,
                framebuffer.Height,
                0,
                -1,
                1);

            GD.UpdateBuffer(orthoBuffer, 0, ref orthoMatrix);

            Texture sampledTexture = RF.CreateTexture(
                TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Sampled));

            RgbaFloat white = RgbaFloat.White;

            GD.UpdateTexture(sampledTexture, (IntPtr)(&white), (uint)Unsafe.SizeOf <RgbaFloat>(), 0, 0, 0, 1, 1, 1, 0, 0);

            Texture shouldntBeSampledTexture = RF.CreateTexture(
                TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Sampled));

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2))
            },
                TestShaders.LoadVertexFragment(RF, "TexturedPoints"));

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("Ortho", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                new ResourceLayoutElementDescription("Tex", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                new ResourceLayoutElementDescription("Smp", ResourceKind.Sampler, ShaderStages.Fragment)));

            ResourceSet set;

            if (useTextureView)
            {
                TextureView view = RF.CreateTextureView(sampledTexture);
                set = RF.CreateResourceSet(new ResourceSetDescription(layout, orthoBuffer, view, GD.PointSampler));
            }
            else
            {
                set = RF.CreateResourceSet(new ResourceSetDescription(layout, orthoBuffer, sampledTexture, GD.PointSampler));
            }

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            Vector2[] vertices = new Vector2[]
            {
                new Vector2(0.5f, 0.5f),
                new Vector2(15.5f, 15.5f),
                new Vector2(25.5f, 26.5f),
                new Vector2(3.5f, 25.5f),
            };

            DeviceBuffer vb = RF.CreateBuffer(
                new BufferDescription((uint)(Unsafe.SizeOf <Vector2>() * vertices.Length), BufferUsage.VertexBuffer));

            GD.UpdateBuffer(vb, 0, vertices);

            CommandList cl = RF.CreateCommandList();

            for (int i = 0; i < 2; i++)
            {
                cl.Begin();
                cl.SetFramebuffer(framebuffer);
                cl.ClearColorTarget(0, RgbaFloat.Black);
                cl.SetPipeline(pipeline);
                cl.SetVertexBuffer(0, vb);
                cl.SetGraphicsResourceSet(0, set);

                // Modify an unrelated texture.
                // This must have no observable effect on the next draw call.
                RgbaFloat pink = RgbaFloat.Pink;
                GD.UpdateTexture(shouldntBeSampledTexture,
                                 (IntPtr)(&pink), (uint)Unsafe.SizeOf <RgbaFloat>(),
                                 0, 0, 0,
                                 1, 1, 1,
                                 0, 0);

                cl.Draw((uint)vertices.Length);
                cl.End();
                GD.SubmitCommands(cl);
                GD.WaitForIdle();
            }

            cl.Begin();
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            foreach (Vector2 vertex in vertices)
            {
                uint x = (uint)vertex.X;
                uint y = (uint)vertex.Y;
                if (!GD.IsUvOriginTopLeft || GD.IsClipSpaceYInverted)
                {
                    y = framebuffer.Height - y - 1;
                }

                Assert.Equal(white, readView[x, y], RgbaFloatFuzzyComparer.Instance);
            }
            GD.Unmap(staging);
        }
Пример #22
0
        public void ComputeGeneratedVertices()
        {
            if (!GD.Features.ComputeShader)
            {
                return;
            }

            uint    width  = 512;
            uint    height = 512;
            Texture output = RF.CreateTexture(
                TextureDescription.Texture2D(width, height, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, output));

            uint         vertexSize = (uint)Unsafe.SizeOf <ColoredVertex>();
            DeviceBuffer buffer     = RF.CreateBuffer(new BufferDescription(
                                                          vertexSize * 4,
                                                          BufferUsage.StructuredBufferReadWrite,
                                                          vertexSize,
                                                          true));

            ResourceLayout computeLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                       new ResourceLayoutElementDescription("OutputVertices", ResourceKind.StructuredBufferReadWrite, ShaderStages.Compute)));
            ResourceSet computeSet = RF.CreateResourceSet(new ResourceSetDescription(computeLayout, buffer));

            Pipeline computePipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                                    TestShaders.LoadCompute(RF, "ComputeColoredQuadGenerator"),
                                                                    computeLayout,
                                                                    1, 1, 1));

            ResourceLayout graphicsLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                        new ResourceLayoutElementDescription("InputVertices", ResourceKind.StructuredBufferReadOnly, ShaderStages.Vertex)));
            ResourceSet graphicsSet = RF.CreateResourceSet(new ResourceSetDescription(graphicsLayout, buffer));

            Pipeline graphicsPipeline = RF.CreateGraphicsPipeline(new GraphicsPipelineDescription(
                                                                      BlendStateDescription.SingleOverrideBlend,
                                                                      DepthStencilStateDescription.Disabled,
                                                                      RasterizerStateDescription.Default,
                                                                      PrimitiveTopology.TriangleStrip,
                                                                      new ShaderSetDescription(
                                                                          Array.Empty <VertexLayoutDescription>(),
                                                                          TestShaders.LoadVertexFragment(RF, "ColoredQuadRenderer")),
                                                                      graphicsLayout,
                                                                      framebuffer.OutputDescription));

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(computePipeline);
            cl.SetComputeResourceSet(0, computeSet);
            cl.Dispatch(1, 1, 1);
            cl.SetFramebuffer(framebuffer);
            cl.ClearColorTarget(0, new RgbaFloat());
            cl.SetPipeline(graphicsPipeline);
            cl.SetGraphicsResourceSet(0, graphicsSet);
            cl.Draw(4);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            Texture readback = GetReadback(output);
            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(readback, MapMode.Read);

            for (uint y = 0; y < height; y++)
            {
                for (uint x = 0; x < width; x++)
                {
                    Assert.Equal(RgbaFloat.Red, readView[x, y]);
                }
            }
            GD.Unmap(readback);
        }