Exemplo n.º 1
0
        public void TestGenerateMips()
        {
            LosgapSystem.InvokeOnMaster(() => {
                // Define variables and constants
                const uint WIDTH_TX  = 256U;
                const uint HEIGHT_TX = 128U;
                const uint ARR_LEN   = 4U;
                Texture2DArray <TexelFormat.RGBA8UNorm> sourceTex = TextureFactory.NewTexture2D <TexelFormat.RGBA8UNorm>()
                                                                    .WithWidth(WIDTH_TX)
                                                                    .WithHeight(HEIGHT_TX)
                                                                    .WithMipAllocation(true)
                                                                    .WithMipGenerationTarget(true)
                                                                    .WithPermittedBindings(GPUBindings.ReadableShaderResource | GPUBindings.RenderTarget)
                                                                    .WithUsage(ResourceUsage.Write)
                                                                    .CreateArray(ARR_LEN);

                Texture2DArray <TexelFormat.RGBA8UNorm> copyDestTex = sourceTex.Clone()
                                                                      .WithUsage(ResourceUsage.StagingRead)
                                                                      .WithPermittedBindings(GPUBindings.None)
                                                                      .WithMipGenerationTarget(false)
                                                                      .CreateArray(ARR_LEN);

                // Set up context
                for (uint u = 0U; u < ARR_LEN; u++)
                {
                    sourceTex[u].Write(
                        // ReSharper disable PossibleLossOfFraction No one cares
                        Enumerable.Range(0, (int)TextureUtils.GetSizeTexels(false, WIDTH_TX, HEIGHT_TX))
                        .Select(i => new TexelFormat.RGBA8UNorm {
                        R = 0f, G = 0.33f, B = 0.67f, A = 1f
                    }).ToArray(),
                        // ReSharper restore PossibleLossOfFraction
                        new SubresourceBox(0U, WIDTH_TX, 0U, HEIGHT_TX),
                        0U
                        );
                }

                // Execute
                sourceTex.GenerateMips();
                sourceTex.CopyTo(copyDestTex);

                // Assert outcome
                for (uint u = 0U; u < ARR_LEN; u++)
                {
                    for (uint i = 1U; i < TextureUtils.GetNumMips(WIDTH_TX, HEIGHT_TX); ++i)
                    {
                        IEnumerable <TexelFormat.RGBA8UNorm> outData = copyDestTex[u].Read(i);
                        // ReSharper disable CompareOfFloatsByEqualityOperator Exact equality is fine here
                        Assert.IsTrue(outData.Any(texel => texel.R != 0f || texel.G != 0f || texel.B != 0f || texel.A != 0f));
                        // ReSharper restore CompareOfFloatsByEqualityOperator
                    }
                }

                sourceTex.Dispose();
                copyDestTex.Dispose();
            });
        }
        public unsafe void TestCreation()
        {
            // Define variables and constants
            const uint NUM_TEXTURES     = 10U;
            const uint TEXEL_SIZE_BYTES = 16;
            const uint TEX_WIDTH        = 512U;
            const uint TEX_HEIGHT       = 128U;
            const uint TEX_DEPTH        = 32U;
            uint       numMipsPerTex    = TextureUtils.GetNumMips(TEX_WIDTH, TEX_HEIGHT, TEX_DEPTH);
            IntPtr     mockDataStart    = new IntPtr(100);

            // Set up context


            // Execute
            InitialResourceDataDesc[] initialDataArray = InitialResourceDataDesc.CreateDataArr(
                mockDataStart,
                NUM_TEXTURES,
                numMipsPerTex,
                TEX_WIDTH,
                TEX_HEIGHT,
                TEX_DEPTH,
                TEXEL_SIZE_BYTES
                );

            // Assert outcome
            Assert.AreEqual((int)(NUM_TEXTURES * numMipsPerTex), initialDataArray.Length);
            for (uint tex = 0U; tex < NUM_TEXTURES; ++tex)
            {
                for (uint mip = 0U; mip < numMipsPerTex; ++mip)
                {
                    InitialResourceDataDesc thisDesc = initialDataArray[numMipsPerTex * tex + mip];
                    IntPtr expectedDataStart         = mockDataStart;
                    expectedDataStart += (int)(TextureUtils.GetSize(TEXEL_SIZE_BYTES, true, TEX_WIDTH, TEX_HEIGHT, TEX_DEPTH) * tex);
                    for (uint i = 0U; i < mip; ++i)
                    {
                        uint mipWidth  = TextureUtils.GetDimensionForMipLevel(TEX_WIDTH, i);
                        uint mipHeight = TextureUtils.GetDimensionForMipLevel(TEX_HEIGHT, i);
                        uint mipDepth  = TextureUtils.GetDimensionForMipLevel(TEX_DEPTH, i);
                        expectedDataStart += (int)TextureUtils.GetSize(TEXEL_SIZE_BYTES, false, mipWidth, mipHeight, mipDepth);
                    }

                    Assert.AreEqual(expectedDataStart, thisDesc.Data);
                    Assert.AreEqual(TextureUtils.GetDimensionForMipLevel(TEX_WIDTH, mip) * TEXEL_SIZE_BYTES, thisDesc.DataRowStrideBytes);
                    Assert.AreEqual(
                        TextureUtils.GetDimensionForMipLevel(TEX_WIDTH, mip)
                        * TextureUtils.GetDimensionForMipLevel(TEX_HEIGHT, mip)
                        * TEXEL_SIZE_BYTES,
                        thisDesc.DataSliceStrideBytes
                        );
                }
            }
        }
 internal Texture1DBuilder(ResourceUsage usage, ArraySlice <TTexel>?initialData, GPUBindings permittedBindings,
                           uint width, bool mipAllocation, bool mipGenerationTarget, bool dynamicDetail) : base(usage, initialData)
 {
     Assure.True(typeof(TTexel).IsBlittable());
     Assure.GreaterThan(UnsafeUtils.SizeOf <TTexel>(), 0);
     this.permittedBindings   = permittedBindings;
     this.width               = width;
     this.mipAllocation       = mipAllocation;
     this.mipGenerationTarget = mipGenerationTarget;
     this.dynamicDetail       = dynamicDetail;
     this.numMips             = mipAllocation ? TextureUtils.GetNumMips(width) : 1U;
 }
Exemplo n.º 4
0
        public void TestGetNumMips()
        {
            // Define variables and constants


            // Set up context


            // Execute


            // Assert outcome
            Assert.AreEqual(6U, TextureUtils.GetNumMips(32U));
            Assert.AreEqual(1U, TextureUtils.GetNumMips(1U));
            Assert.AreEqual(6U, TextureUtils.GetNumMips(1U, 32U));
            Assert.AreEqual(8U, TextureUtils.GetNumMips(64U, 32U, 128U));
        }
        public void TestCreationWithInitialData()
        {
            // Define variables and constants
            const uint TEXTURE_WIDTH  = 1 << 6;
            const uint TEXTURE_HEIGHT = 1 << 4;
            const uint TEXTURE_DEPTH  = 1 << 3;
            Texture3DBuilder <TexelFormat.RGBA8UInt> texBuilder = TextureFactory.NewTexture3D <TexelFormat.RGBA8UInt>()
                                                                  .WithUsage(ResourceUsage.StagingRead)
                                                                  .WithPermittedBindings(GPUBindings.None)
                                                                  .WithWidth(TEXTURE_WIDTH)
                                                                  .WithHeight(TEXTURE_HEIGHT)
                                                                  .WithDepth(TEXTURE_DEPTH);

            TexelFormat.RGBA8UInt[]           initialDataA = new TexelFormat.RGBA8UInt[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_DEPTH];
            TexelFormat.RGBA8UInt[]           initialDataB = new TexelFormat.RGBA8UInt[TextureUtils.GetSizeTexels(true, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH)];
            Texture3D <TexelFormat.RGBA8UInt> testTextureA, testTextureB;

            TexelArray3D <TexelFormat.RGBA8UInt> texAData;

            TexelArray3D <TexelFormat.RGBA8UInt>[] texBData = new TexelArray3D <TexelFormat.RGBA8UInt> [TextureUtils.GetNumMips(TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH)];

            // Set up context
            for (uint i = 0; i < initialDataA.Length; ++i)
            {
                initialDataA[i].R = (byte)i;
                initialDataA[i].G = (byte)(i * 2);
                initialDataA[i].B = (byte)(i * 3);
                initialDataA[i].A = (byte)(i * 4);
            }
            testTextureA = texBuilder.WithInitialData(initialDataA).Create();

            uint mipWidth   = TEXTURE_WIDTH;
            uint mipHeight  = TEXTURE_HEIGHT;
            uint mipDepth   = TEXTURE_DEPTH;
            uint texelIndex = 0U;

            while (mipWidth > 1U || mipHeight > 1U || mipDepth > 1U)
            {
                for (uint w = 0; w < mipDepth; ++w)
                {
                    for (uint v = 0; v < mipHeight; ++v)
                    {
                        for (uint u = 0; u < mipWidth; ++u, ++texelIndex)
                        {
                            initialDataB[texelIndex].R = (byte)(u + mipWidth + v + mipHeight + w + mipDepth);
                            initialDataB[texelIndex].G = (byte)(u + mipWidth + v + mipHeight + w + mipDepth * 2);
                            initialDataB[texelIndex].B = (byte)(u + mipWidth + v + mipHeight + w + mipDepth * 3);
                            initialDataB[texelIndex].A = (byte)(u + mipWidth + v + mipHeight + w + mipDepth * 4);
                        }
                    }
                }
                mipWidth  = Math.Max(1U, mipWidth >> 1);
                mipHeight = Math.Max(1U, mipHeight >> 1);
                mipDepth  = Math.Max(1U, mipDepth >> 1);
            }
            initialDataB[initialDataB.Length - 1] = new TexelFormat.RGBA8UInt {
                R = 3, G = 4, B = 5, A = 6
            };
            testTextureB = texBuilder.WithMipAllocation(true).WithInitialData(initialDataB).Create();

            // Execute
            texAData = testTextureA.Read(0U);
            for (uint i = 0; i < texBData.Length; ++i)
            {
                texBData[i] = testTextureB.Read(i);
            }

            // Assert outcome
            for (uint i = 0; i < texAData.Width; ++i)
            {
                Assert.AreEqual((byte)i, initialDataA[i].R);
                Assert.AreEqual((byte)(i * 2), initialDataA[i].G);
                Assert.AreEqual((byte)(i * 3), initialDataA[i].B);
                Assert.AreEqual((byte)(i * 4), initialDataA[i].A);
            }

            for (uint mipIndex = 0U; mipIndex < testTextureB.NumMips; ++mipIndex)
            {
                for (uint w = 0; w < testTextureB.MipDepth(mipIndex); ++w)
                {
                    for (uint v = 0; v < testTextureB.MipHeight(mipIndex); ++v)
                    {
                        for (uint u = 0; u < testTextureB.MipWidth(mipIndex); ++u)
                        {
                            Assert.AreEqual((byte)(u + testTextureB.MipWidth(mipIndex) + v + testTextureB.MipHeight(mipIndex) + w + testTextureB.MipDepth(mipIndex)), texBData[mipIndex][u, v, w].R);
                            Assert.AreEqual((byte)(u + testTextureB.MipWidth(mipIndex) + v + testTextureB.MipHeight(mipIndex) + w + testTextureB.MipDepth(mipIndex) * 2), texBData[mipIndex][u, v, w].G);
                            Assert.AreEqual((byte)(u + testTextureB.MipWidth(mipIndex) + v + testTextureB.MipHeight(mipIndex) + w + testTextureB.MipDepth(mipIndex) * 3), texBData[mipIndex][u, v, w].B);
                            Assert.AreEqual((byte)(u + testTextureB.MipWidth(mipIndex) + v + testTextureB.MipHeight(mipIndex) + w + testTextureB.MipDepth(mipIndex) * 4), texBData[mipIndex][u, v, w].A);
                        }
                    }
                }
            }

            testTextureA.Dispose();
            testTextureB.Dispose();
        }
        public void TestCreationParameters()
        {
            // Define variables and constants
            var defaultBuilder = TextureFactory.NewTexture3D <TexelFormat.RGBA32UInt>().WithUsage(ResourceUsage.DiscardWrite)
                                 .WithWidth(100).WithHeight(256).WithDepth(8);
            var withStagingUsage      = defaultBuilder.WithUsage(ResourceUsage.StagingReadWrite).WithPermittedBindings(GPUBindings.None);
            var withReadWriteBindings = defaultBuilder.WithUsage(ResourceUsage.Write).WithPermittedBindings(GPUBindings.ReadableShaderResource | GPUBindings.WritableShaderResource);
            var withDifferentFormat   = defaultBuilder.WithTexelFormat <TexelFormat.Int8>();
            var withWidth300          = defaultBuilder.WithWidth(300);
            var withMipAllocation     = defaultBuilder.WithUsage(ResourceUsage.Write).WithWidth(1 << 9).WithMipAllocation(true);
            var withDynDetail         = withMipAllocation.WithDynamicDetail(true);
            var withMipGen            = withMipAllocation
                                        .WithUsage(ResourceUsage.Write)
                                        .WithPermittedBindings(GPUBindings.RenderTarget | GPUBindings.ReadableShaderResource)
                                        .WithMipGenerationTarget(true)
                                        .WithTexelFormat <TexelFormat.RGBA8UNorm>();

            // Set up context

            // Execute

            // Assert outcome
            ITexture3D tex = withStagingUsage.Create();

            Assert.AreEqual(ResourceUsage.StagingReadWrite, tex.Usage);
            tex.Dispose();
            tex = withReadWriteBindings.Create();
            Assert.AreEqual(GPUBindings.ReadableShaderResource | GPUBindings.WritableShaderResource, tex.PermittedBindings);
            tex.Dispose();
            tex = withDifferentFormat.Create();
            Assert.AreEqual(typeof(TexelFormat.Int8), tex.TexelFormat);
            tex.Dispose();
            tex = withWidth300.Create();
            Assert.AreEqual(300U, tex.Width);
            tex.Dispose();
            tex = withMipAllocation.Create();
            Assert.AreEqual(TextureUtils.GetNumMips(1 << 9, 256), tex.NumMips);
            tex.Dispose();
            tex = withDynDetail.Create();
            Assert.AreEqual(true, tex.IsGlobalDetailTarget);
            tex.Dispose();
            tex = withMipGen.Create();
            Assert.AreEqual(true, tex.IsMipGenTarget);
            tex.Dispose();

#if !DEVELOPMENT && !RELEASE
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithUsage(ResourceUsage.Immutable)
                .WithInitialData(null)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithUsage(ResourceUsage.DiscardWrite)
                .WithPermittedBindings(GPUBindings.None)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithUsage(ResourceUsage.StagingRead)
                .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithWidth(0U)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(true)
                .WithWidth(140)
                .WithHeight(1U)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(true)
                .WithMipGenerationTarget(true)
                .WithWidth(1 << 4)
                .WithHeight(1 << 4)
                .WithUsage(ResourceUsage.Write)
                .WithPermittedBindings(GPUBindings.None)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(false)
                .WithMipGenerationTarget(true)
                .WithWidth(1 << 4)
                .WithHeight(1 << 4)
                .WithUsage(ResourceUsage.Write)
                .WithPermittedBindings(GPUBindings.RenderTarget | GPUBindings.ReadableShaderResource)
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(true)
                .WithMipGenerationTarget(true)
                .WithWidth(1 << 4)
                .WithHeight(1 << 4)
                .WithUsage(ResourceUsage.Write)
                .WithPermittedBindings(GPUBindings.RenderTarget | GPUBindings.ReadableShaderResource)
                .WithInitialData(new TexelFormat.Float32[(1 << 5) - 1])
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(true)
                .WithWidth(1 << 4)
                .WithHeight(1 << 4)
                .WithUsage(ResourceUsage.Immutable)
                .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                .WithInitialData(new TexelFormat.Float32[1 << 4])
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
            try {
                TextureFactory.NewTexture3D <TexelFormat.Float32>()
                .WithMipAllocation(false)
                .WithWidth(1 << 4)
                .WithHeight(1 << 4)
                .WithUsage(ResourceUsage.Immutable)
                .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                .WithInitialData(new TexelFormat.Float32[(1 << 5) - 1])
                .Create();
                Assert.Fail();
            }
            catch (AssuranceFailedException) { }
#endif
        }
Exemplo n.º 7
0
        public unsafe ITexture2D Create()
        {
            Assure.NotNull(filePath, "You must supply a file path to load a texture.");
            string fullFilePath = Path.Combine(Path.GetFullPath(LosgapSystem.InstallationDirectory.ToString()), filePath);

            Assure.True(IOUtils.IsValidFilePath(fullFilePath), "Invalid file path: " + fullFilePath);
            Assure.True(File.Exists(fullFilePath), "File does not exist: " + fullFilePath);
            Assure.False(
                (usage == ResourceUsage.Immutable || usage == ResourceUsage.DiscardWrite) && permittedBindings == GPUBindings.None,
                "An immutable or discard-write resource with no permitted bindings is useless."
                );
            Assure.False(
                usage.GetUsage() == 0x3 && permittedBindings != GPUBindings.None,
                "Staging resources can not be bound to the pipeline."
                );
            Assure.False((usage == ResourceUsage.DiscardWrite || usage == ResourceUsage.Immutable) &&
                         ((permittedBindings & GPUBindings.RenderTarget) > 0 ||
                          (permittedBindings & GPUBindings.DepthStencilTarget) > 0 ||
                          (permittedBindings & GPUBindings.WritableShaderResource) > 0),
                         "Can not bind an immutable or discard-write texture as a render target or depth stencil target, or as a GPU-writeable shader resource."
                         );

            Texture2DResourceHandle outResHandle;
            uint           outWidth;
            uint           outHeight;
            ResourceFormat outFormat;


            InteropUtils.CallNative(NativeMethods.ResourceFactory_LoadTexture2D,
                                    RenderingModule.Device,
                                    fullFilePath,
                                    (InteropBool)mipAllocation,
                                    usage.GetUsage(),
                                    usage.GetCPUUsage(),
                                    (PipelineBindings)permittedBindings,
                                    (InteropBool)mipGenerationTarget,
                                    (InteropBool)dynamicDetail,
                                    (IntPtr)(&outResHandle),
                                    (IntPtr)(&outWidth),
                                    (IntPtr)(&outHeight),
                                    (IntPtr)(&outFormat)
                                    ).ThrowOnFailure();

            Type texelFormat = null;

            foreach (Type texelType in TexelFormat.AllFormats.Keys.Except(typeof(TexelFormat.RenderTarget), typeof(TexelFormat.DepthStencil)))
            {
                if ((ResourceFormat)texelType.GetCustomAttribute <TexelFormatMetadataAttribute>().ResourceFormatIndex == outFormat)
                {
                    texelFormat = texelType;
                    break;
                }
            }
            if (texelFormat == null)
            {
                throw new InvalidOperationException("The format for the loaded texture (" + outFormat + ") is not supported.");
            }

            Type tex2DType      = typeof(Texture2D <>).MakeGenericType(texelFormat);
            uint texelSizeBytes = texelFormat.GetCustomAttribute <TexelFormatMetadataAttribute>().FormatSizeBytes;

            try {
                return(Activator.CreateInstance(
                           tex2DType, BindingFlags.NonPublic | BindingFlags.Instance, null,
                           new object[] {
                    (ResourceHandle)outResHandle,
                    usage,
                    (ByteSize)(outWidth * outHeight * texelSizeBytes),
                    permittedBindings,
                    false,
                    mipGenerationTarget,
                    dynamicDetail,
                    outWidth,
                    outHeight,
                    texelSizeBytes,
                    mipAllocation,
                    mipAllocation ? TextureUtils.GetNumMips(outWidth, outHeight) : 1U,
                    0U,
                    false
                },
                           CultureInfo.InvariantCulture
                           ) as ITexture2D);
            }
            catch (Exception e) {
                throw new InvalidOperationException("Could not load texture as a " + texelFormat.Name + " due to an instantiation error.", e);
            }
        }
Exemplo n.º 8
0
        public void TestCreateDefaultViewForTextures()
        {
            const uint         TEST_TEXTURE_WIDTH  = 128U;
            const uint         TEST_TEXTURE_HEIGHT = 64U;
            const uint         TEST_TEXTURE_DEPTH  = 32U;
            const uint         TEST_ARRAY_LEN      = 10U;
            IResource          testResource;
            ShaderResourceView testSRV;

            testResource = TextureFactory.NewTexture1D <TexelFormat.RGB32Float>()
                           .WithDynamicDetail(false)
                           .WithMipAllocation(true)
                           .WithMipGenerationTarget(false)
                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                           .WithUsage(ResourceUsage.Write)
                           .WithWidth(TEST_TEXTURE_WIDTH)
                           .Create();
            testSRV = ((ITexture)testResource).CreateView();
            Assert.IsFalse(testSRV.ResourceOrViewDisposed);
            Assert.AreEqual(testResource, testSRV.Resource);
            Assert.AreEqual(0U, ((ShaderTextureResourceView)testSRV).FirstMipIndex);
            Assert.AreEqual(TextureUtils.GetNumMips(TEST_TEXTURE_WIDTH), ((ShaderTextureResourceView)testSRV).NumMips);
            testResource.Dispose();
            Assert.IsTrue(testSRV.ResourceOrViewDisposed);
            testSRV.Dispose();
            Assert.IsTrue(testSRV.IsDisposed);

            testResource = TextureFactory.NewTexture2D <TexelFormat.RGB32Float>()
                           .WithDynamicDetail(false)
                           .WithMipAllocation(true)
                           .WithMipGenerationTarget(false)
                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                           .WithUsage(ResourceUsage.Write)
                           .WithWidth(TEST_TEXTURE_WIDTH)
                           .WithHeight(TEST_TEXTURE_HEIGHT)
                           .Create();
            testSRV = ((ITexture)testResource).CreateView();
            Assert.IsFalse(testSRV.ResourceOrViewDisposed);
            Assert.AreEqual(testResource, testSRV.Resource);
            Assert.AreEqual(0U, ((ShaderTextureResourceView)testSRV).FirstMipIndex);
            Assert.AreEqual(TextureUtils.GetNumMips(TEST_TEXTURE_WIDTH, TEST_TEXTURE_HEIGHT), ((ShaderTextureResourceView)testSRV).NumMips);
            testResource.Dispose();
            Assert.IsTrue(testSRV.ResourceOrViewDisposed);
            testSRV.Dispose();
            Assert.IsTrue(testSRV.IsDisposed);

            testResource = TextureFactory.NewTexture3D <TexelFormat.RGB32Float>()
                           .WithDynamicDetail(false)
                           .WithMipAllocation(true)
                           .WithMipGenerationTarget(false)
                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                           .WithUsage(ResourceUsage.Write)
                           .WithWidth(TEST_TEXTURE_WIDTH)
                           .WithHeight(TEST_TEXTURE_HEIGHT)
                           .WithDepth(TEST_TEXTURE_DEPTH)
                           .Create();
            testSRV = ((ITexture)testResource).CreateView();
            Assert.IsFalse(testSRV.ResourceOrViewDisposed);
            Assert.AreEqual(testResource, testSRV.Resource);
            Assert.AreEqual(0U, ((ShaderTextureResourceView)testSRV).FirstMipIndex);
            Assert.AreEqual(TextureUtils.GetNumMips(TEST_TEXTURE_WIDTH, TEST_TEXTURE_HEIGHT, TEST_TEXTURE_DEPTH), ((ShaderTextureResourceView)testSRV).NumMips);
            testResource.Dispose();
            Assert.IsTrue(testSRV.ResourceOrViewDisposed);
            testSRV.Dispose();
            Assert.IsTrue(testSRV.IsDisposed);

            testResource = TextureFactory.NewTexture1D <TexelFormat.RGB32Float>()
                           .WithDynamicDetail(false)
                           .WithMipAllocation(true)
                           .WithMipGenerationTarget(false)
                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                           .WithUsage(ResourceUsage.Write)
                           .WithWidth(TEST_TEXTURE_WIDTH)
                           .CreateArray(TEST_ARRAY_LEN);
            testSRV = ((ITextureArray)testResource).CreateView();
            Assert.IsFalse(testSRV.ResourceOrViewDisposed);
            Assert.AreEqual(testResource, testSRV.Resource);
            Assert.AreEqual(0U, ((ShaderTextureArrayResourceView)testSRV).FirstMipIndex);
            Assert.AreEqual(TextureUtils.GetNumMips(TEST_TEXTURE_WIDTH), ((ShaderTextureArrayResourceView)testSRV).NumMips);
            Assert.AreEqual(0U, ((ShaderTextureArrayResourceView)testSRV).FirstArrayElementIndex);
            Assert.AreEqual(TEST_ARRAY_LEN, ((ShaderTextureArrayResourceView)testSRV).NumArrayElements);
            testResource.Dispose();
            Assert.IsTrue(testSRV.ResourceOrViewDisposed);
            testSRV.Dispose();
            Assert.IsTrue(testSRV.IsDisposed);

            testResource = TextureFactory.NewTexture2D <TexelFormat.RGB32Float>()
                           .WithDynamicDetail(false)
                           .WithMipAllocation(true)
                           .WithMipGenerationTarget(false)
                           .WithPermittedBindings(GPUBindings.ReadableShaderResource)
                           .WithUsage(ResourceUsage.Write)
                           .WithWidth(TEST_TEXTURE_WIDTH)
                           .WithHeight(TEST_TEXTURE_HEIGHT)
                           .CreateArray(TEST_ARRAY_LEN);
            testSRV = ((ITextureArray)testResource).CreateView();
            Assert.IsFalse(testSRV.ResourceOrViewDisposed);
            Assert.AreEqual(testResource, testSRV.Resource);
            Assert.AreEqual(0U, ((ShaderTextureArrayResourceView)testSRV).FirstMipIndex);
            Assert.AreEqual(TextureUtils.GetNumMips(TEST_TEXTURE_WIDTH, TEST_TEXTURE_HEIGHT), ((ShaderTextureArrayResourceView)testSRV).NumMips);
            Assert.AreEqual(0U, ((ShaderTextureArrayResourceView)testSRV).FirstArrayElementIndex);
            Assert.AreEqual(TEST_ARRAY_LEN, ((ShaderTextureArrayResourceView)testSRV).NumArrayElements);
            testResource.Dispose();
            Assert.IsTrue(testSRV.ResourceOrViewDisposed);
            testSRV.Dispose();
            Assert.IsTrue(testSRV.IsDisposed);
        }
        public void TestCreationWithInitialData()
        {
            // Define variables and constants
            const uint TEXTURE_WIDTH = 1 << 6;
            Texture1DBuilder <TexelFormat.RGBA8UInt> texBuilder = TextureFactory.NewTexture1D <TexelFormat.RGBA8UInt>()
                                                                  .WithUsage(ResourceUsage.StagingRead)
                                                                  .WithPermittedBindings(GPUBindings.None)
                                                                  .WithWidth(TEXTURE_WIDTH);

            TexelFormat.RGBA8UInt[]           initialDataA = new TexelFormat.RGBA8UInt[TEXTURE_WIDTH];
            TexelFormat.RGBA8UInt[]           initialDataB = new TexelFormat.RGBA8UInt[(TEXTURE_WIDTH << 1) - 1];
            Texture1D <TexelFormat.RGBA8UInt> testTextureA, testTextureB;

            TexelArray1D <TexelFormat.RGBA8UInt> texAData;

            TexelArray1D <TexelFormat.RGBA8UInt>[] texBData = new TexelArray1D <TexelFormat.RGBA8UInt> [TextureUtils.GetNumMips(TEXTURE_WIDTH)];

            // Set up context
            for (uint i = 0; i < initialDataA.Length; ++i)
            {
                initialDataA[i].R = (byte)i;
                initialDataA[i].G = (byte)(i * 2);
                initialDataA[i].B = (byte)(i * 3);
                initialDataA[i].A = (byte)(i * 4);
            }
            testTextureA = texBuilder.WithInitialData(initialDataA).Create();

            uint mipWidth   = TEXTURE_WIDTH;
            uint texelIndex = 0U;

            while (mipWidth > 0)
            {
                for (uint i = 0; i < mipWidth; ++i, ++texelIndex)
                {
                    initialDataB[texelIndex].R = (byte)(i + mipWidth);
                    initialDataB[texelIndex].G = (byte)(i * 2 + mipWidth);
                    initialDataB[texelIndex].B = (byte)(i * 3 + mipWidth);
                    initialDataB[texelIndex].A = (byte)(i * 4 + mipWidth);
                }
                mipWidth >>= 1;
            }
            testTextureB = texBuilder.WithMipAllocation(true).WithInitialData(initialDataB).Create();



            // Execute
            texAData = testTextureA.Read(0U);
            for (uint i = 0; i < texBData.Length; ++i)
            {
                texBData[i] = testTextureB.Read(i);
            }

            // Assert outcome
            for (uint i = 0; i < texAData.Width; ++i)
            {
                Assert.AreEqual((byte)i, initialDataA[i].R);
                Assert.AreEqual((byte)(i * 2), initialDataA[i].G);
                Assert.AreEqual((byte)(i * 3), initialDataA[i].B);
                Assert.AreEqual((byte)(i * 4), initialDataA[i].A);
            }

            mipWidth   = TEXTURE_WIDTH;
            texelIndex = 0U;
            while (mipWidth > 0)
            {
                for (uint i = 0; i < mipWidth; ++i, ++texelIndex)
                {
                    Assert.AreEqual((byte)(i + mipWidth), initialDataB[texelIndex].R);
                    Assert.AreEqual((byte)(i * 2 + mipWidth), initialDataB[texelIndex].G);
                    Assert.AreEqual((byte)(i * 3 + mipWidth), initialDataB[texelIndex].B);
                    Assert.AreEqual((byte)(i * 4 + mipWidth), initialDataB[texelIndex].A);
                }
                mipWidth >>= 1;
            }

            testTextureA.Dispose();
            testTextureB.Dispose();
        }