Esempio n. 1
0
        private ResourceDescription ConvertToNativeDescription2D()
        {
            var format = (SharpDX.DXGI.Format)textureDescription.Format;
            var flags  = textureDescription.Flags;

            // If the texture is going to be bound on the depth stencil, for to use TypeLess format
            if (IsDepthStencil)
            {
                // Determine TypeLess Format and ShaderResourceView Format
                switch (textureDescription.Format)
                {
                case PixelFormat.D16_UNorm:
                    format = SharpDX.DXGI.Format.R16_Typeless;
                    break;

                case PixelFormat.D32_Float:
                    format = SharpDX.DXGI.Format.R32_Typeless;
                    break;

                case PixelFormat.D24_UNorm_S8_UInt:
                    //format = SharpDX.DXGI.Format.D24_UNorm_S8_UInt;
                    format = SharpDX.DXGI.Format.R24G8_Typeless;
                    break;

                case PixelFormat.D32_Float_S8X24_UInt:
                    format = SharpDX.DXGI.Format.R32G8X24_Typeless;
                    break;

                default:
                    throw new NotSupportedException(String.Format("Unsupported DepthFormat [{0}] for depth buffer", textureDescription.Format));
                }
            }

            return(ResourceDescription.Texture2D(format, textureDescription.Width, textureDescription.Height, (short)textureDescription.ArraySize, (short)textureDescription.MipLevels, (short)textureDescription.MultisampleCount, 0, GetBindFlagsFromTextureFlags(flags)));
        }
Esempio n. 2
0
        internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
        {
            var texture = resource as Texture;

            if (texture != null)
            {
                if (texture.Dimension != TextureDimension.Texture2D)
                {
                    throw new NotImplementedException();
                }

                var width  = region.Right - region.Left;
                var height = region.Bottom - region.Top;

                // TODO D3D12 allocate in upload heap (placed resources?)
                var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                                               ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height),
                                                                               ResourceStates.GenericRead);

                GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair <long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture));

                nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch);

                var parentResource = resource.ParentResource ?? resource;

                // Trigger copy
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination);
                NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null);
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState);
            }
            else
            {
                throw new NotImplementedException();
            }
        }
Esempio n. 3
0
        public void UploadTexture(Texture2D texture, byte[] data)
        {
            ID3D12Resource resourceUpload1 = graphicsDevice.device.CreateCommittedResource <ID3D12Resource>(
                new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0),
                HeapFlags.None,
                ResourceDescription.Texture2D(texture.format, (ulong)texture.width, texture.height, 1, 1),
                ResourceStates.GenericRead);

            graphicsDevice.DestroyResource(resourceUpload1);
            graphicsDevice.DestroyResource(texture.resource);
            texture.resource = graphicsDevice.device.CreateCommittedResource <ID3D12Resource>(
                HeapProperties.DefaultHeapProperties,
                HeapFlags.None,
                ResourceDescription.Texture2D(texture.format, (ulong)texture.width, texture.height, 1, 1),
                ResourceStates.CopyDestination);

            //var ptr = resourceUpload1.Map(0);
            //MemCpy(ptr, data, (uint)data.Length);
            //resourceUpload1.Unmap(0);
            GCHandle gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);

            resourceUpload1.WriteToSubresource(0, data, data.Length / texture.height, data.Length);
            gcHandle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(texture.resource), 0, 0, 0, new TextureCopyLocation(resourceUpload1));
            commandList.ResourceBarrierTransition(texture.resource, ResourceStates.CopyDestination, ResourceStates.GenericRead);
            texture.resourceStates = ResourceStates.GenericRead;
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a depth texture.
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void CreateDepth(int width, int height)
        {
            Width  = width;
            Height = height;


            ClearValue depthOptimizedClearValue = new ClearValue()
            {
                Format       = Format.D32_Float,
                DepthStencil = new DepthStencilValue()
                {
                    Depth = 1.0F, Stencil = 0
                },
            };

            Resource = Device.NativeDevice.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                ResourceDescription.Texture2D(
                    Format.D32_Float, Width, Height,
                    mipLevels: MipLevels,
                    flags: ResourceFlags.AllowDepthStencil),
                ResourceStates.DepthWrite,
                depthOptimizedClearValue);

            NativeDepthStencilView = Device.DepthStencilViewAllocator.Allocate(1);
            Device.NativeDevice.CreateDepthStencilView(Resource, null, NativeDepthStencilView);
        }
Esempio n. 5
0
        public void WriteTextureToRAM(DescriptorHeap shaderRenderViewHeap, TextureType type)
        {
            var tex         = Texture.LoadFromFile(TexturePath[type]);
            var textureData = tex.Data;
            var textureDesc = ResourceDescription.Texture2D(tex.ColorFormat, tex.Width, tex.Height, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
            var texture     = Engine.Instance.Core.Device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                textureDesc,
                ResourceStates.GenericRead, null);
            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);

            texture.WriteToSubresource(0, null, ptr, tex.Width * tex.PixelWdith, textureData.Length);
            Marshal.FreeHGlobal(ptr);
            handle.Free();
            Engine.Instance.Core.Device.CreateShaderResourceView(
                texture,
                new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                }
            },
                shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + ViewStep + (int)type * Engine.Instance.Core.Device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));
        }
Esempio n. 6
0
        public override Texture <SharpDX.Direct3D12.Resource> CreateTexture(TextureContent data)
        {
            DXDebug.CheckAccess(graphicsHost.Device);

            SharpDX.Direct3D12.Resource texture = null;

            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, data.Width, data.Height);

            texture = graphicsHost.Device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(texture, 0, 1);

            // Create the GPU upload buffer.
            var textureUploadHeap = graphicsHost.Device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                                                ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, data.Width, data.Height), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            var handle = GCHandle.Alloc(data.Pixels, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(data.Pixels, 0);

            textureUploadHeap.WriteToSubresource(0, null, ptr, (sizeof(byte) * 4) * data.Width, data.Pixels.Length);
            handle.Free();

            // TODO: Runtime invalid call error below

            //var commandList = graphicsHost.RequestCommandList();
            //commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);
            //commandList.ResourceBarrierTransition(texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            //// Describe and create a SRV for the texture.
            //var srvDesc = new ShaderResourceViewDescription
            //{
            //    Shader4ComponentMapping = DXHelper.DefaultComponentMapping(),
            //    Format = textureDesc.Format,
            //    Dimension = ShaderResourceViewDimension.Texture2D,
            //    Texture2D = { MipLevels = 1 },
            //};

            //graphicsHost.Device.CreateShaderResourceView(texture, srvDesc, graphicsHost.SRVHeap.CPUDescriptorHandleForHeapStart);

            //// Command lists are created in the recording state, but there is nothing
            //// to record yet. The main loop expects it to be closed, so close it now.
            //commandList.Close();

            //graphicsHost.CommandQueue.ExecuteCommandList(commandList);

            textureUploadHeap.Dispose();

            return(new Texture <SharpDX.Direct3D12.Resource>(texture, data.Width, data.Height, data.Left, data.Right, data.Top, data.Bottom, data.IsTransparent));
        }
        public DepthStencilBufferImpl(GraphicsDevice graphicsDevice, int width, int height, float clearValue)
        {
            _graphicsDevice = graphicsDevice;

            var format = SharpDX.DXGI.Format.D32_Float;

            var resourceDescription = ResourceDescription.Texture2D(
                format,
                width,
                height,
                mipLevels: 1,
                flags: ResourceFlags.AllowDepthStencil | ResourceFlags.DenyShaderResource);

            var texture = AddDisposable(graphicsDevice.Device.CreateCommittedResource(
                                            new HeapProperties(HeapType.Default),
                                            HeapFlags.None,
                                            resourceDescription,
                                            ResourceStates.DepthWrite,
                                            new ClearValue
            {
                Format       = format,
                DepthStencil = new DepthStencilValue {
                    Depth = clearValue
                }
            }));

            _descriptorTablePoolEntry = graphicsDevice.DescriptorHeapDsv.Reserve(1);

            graphicsDevice.Device.CreateDepthStencilView(
                texture,
                new DepthStencilViewDescription
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format    = format,
                Flags     = DepthStencilViewFlags.None,
                Texture2D =
                {
                    MipSlice = 0
                }
            },
                _descriptorTablePoolEntry.CpuDescriptorHandle);
        }
Esempio n. 8
0
        private void PlatformConstruct(
            GraphicsDevice graphicsDevice,
            ResourceUploadBatch uploadBatch,
            PixelFormat pixelFormat,
            int width,
            int height,
            TextureMipMapData[] mipMapData)
        {
            var resourceDescription = ResourceDescription.Texture2D(
                pixelFormat.ToDxgiFormat(),
                width,
                height,
                mipLevels: (short)mipMapData.Length);

            DeviceResource = AddDisposable(graphicsDevice.Device.CreateCommittedResource(
                                               new HeapProperties(HeapType.Default),
                                               HeapFlags.None,
                                               resourceDescription,
                                               ResourceStates.CopyDestination));

            var uploadData = new ResourceUploadData <byte> [mipMapData.Length];

            for (var i = 0; i < mipMapData.Length; i++)
            {
                uploadData[i] = new ResourceUploadData <byte>
                {
                    Data        = mipMapData[i].Data,
                    BytesPerRow = mipMapData[i].BytesPerRow
                };
            }

            uploadBatch.Upload(
                DeviceResource,
                uploadData);

            uploadBatch.Transition(
                DeviceResource,
                ResourceStates.CopyDestination,
                ResourceStates.NonPixelShaderResource | ResourceStates.PixelShaderResource);
        }
Esempio n. 9
0
        internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
        {
            var texture = resource as Texture;

            if (texture != null)
            {
                var width  = region.Right - region.Left;
                var height = region.Bottom - region.Top;
                var depth  = region.Back - region.Front;

                ResourceDescription resourceDescription;
                switch (texture.Dimension)
                {
                case TextureDimension.Texture1D:
                    resourceDescription = ResourceDescription.Texture1D((SharpDX.DXGI.Format)texture.Format, width, 1, 1);
                    break;

                case TextureDimension.Texture2D:
                case TextureDimension.TextureCube:
                    resourceDescription = ResourceDescription.Texture2D((SharpDX.DXGI.Format)texture.Format, width, height, 1, 1);
                    break;

                case TextureDimension.Texture3D:
                    resourceDescription = ResourceDescription.Texture3D((SharpDX.DXGI.Format)texture.Format, width, height, (short)depth, 1);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // TODO D3D12 allocate in upload heap (placed resources?)
                var nativeUploadTexture = NativeDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                                               resourceDescription,
                                                                               ResourceStates.GenericRead);


                GraphicsDevice.TemporaryResources.Enqueue(new KeyValuePair <long, Pageable>(GraphicsDevice.NextFenceValue, nativeUploadTexture));

                nativeUploadTexture.WriteToSubresource(0, null, databox.DataPointer, databox.RowPitch, databox.SlicePitch);

                var parentResource = resource.ParentResource ?? resource;

                // Trigger copy
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, parentResource.NativeResourceState, ResourceStates.CopyDestination);
                NativeCommandList.CopyTextureRegion(new TextureCopyLocation(resource.NativeResource, subResourceIndex), region.Left, region.Top, region.Front, new TextureCopyLocation(nativeUploadTexture, 0), null);
                NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, parentResource.NativeResourceState);
            }
            else
            {
                var buffer = resource as Buffer;
                if (buffer != null)
                {
                    SharpDX.Direct3D12.Resource uploadResource;
                    int uploadOffset;
                    var uploadSize   = region.Right - region.Left;
                    var uploadMemory = GraphicsDevice.AllocateUploadBuffer(region.Right - region.Left, out uploadResource, out uploadOffset);

                    Utilities.CopyMemory(uploadMemory, databox.DataPointer, uploadSize);

                    NativeCommandList.ResourceBarrierTransition(resource.NativeResource, resource.NativeResourceState, ResourceStates.CopyDestination);
                    NativeCommandList.CopyBufferRegion(resource.NativeResource, region.Left, uploadResource, uploadOffset, uploadSize);
                    NativeCommandList.ResourceBarrierTransition(resource.NativeResource, ResourceStates.CopyDestination, resource.NativeResourceState);
                }
                else
                {
                    throw new InvalidOperationException("Unknown resource type");
                }
            }
        }
Esempio n. 10
0
        public void Initialize(Int32 width, Int32 height, IntPtr outputHandle)
        {
            // provide a convinent syntax that ensures the correct use of IDisposable objects
            // only factory is enabled in this scope
            using (var factory = new Factory4())
            {
                m_Desc = new SwapChainDescription()
                {
                    BufferCount       = FrameCount,
                    ModeDescription   = new ModeDescription(width, height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                    Usage             = Usage.RenderTargetOutput,
                    OutputHandle      = outputHandle,
                    SwapEffect        = SwapEffect.FlipDiscard,
                    SampleDescription = new SampleDescription(1, 0), //@TODO enable 4xMSAA
                    IsWindowed        = true,
                };

                using (var tempSwapChain = new SwapChain(factory, m_CommandListPoolRef.CommandQueue, m_Desc))
                // @TODO - temporary
                //CommandQueue cmdQueue = H1Global<H1ManagedRenderer>.Instance.m_CommandQueue;
                //using (var tempSwapChain = new SwapChain(factory, cmdQueue, m_Desc))
                {
                    m_DXGISwapChain = tempSwapChain.QueryInterface <SwapChain3>();
                }
            }

            // set the back buffer resources
            for (Int32 n = 0; n < FrameCount; ++n)
            {
                m_BackBuffers.Add(m_DXGISwapChain.GetBackBuffer <SharpDX.Direct3D12.Resource>(n));
            }

            // @TODO need to move this chunk of codes to SwapChain
            #region Temp
            //@TODO - temp
            //H1DX12Device deviceDX12 = m_CommandListPoolRef.Device;
            H1DX12Device deviceDX12 = H1Global <H1ManagedRenderer> .Instance.Dx12Device;

            // create RTV descriptor heap
            deviceDX12.RenderTargetDescriptorCache.Initialize(deviceDX12.Device, FrameCount, false, H1ViewType.RenderTargetView);

            // create DSV descriptor heap
            deviceDX12.DepthStencilDescriptorCache.Initialize(deviceDX12.Device, 1, false, H1ViewType.DepthStencilView);

            // create CBV descriptor heap
            //H1DescriptorHeap generalHeap = new H1DescriptorHeap();
            //generalHeap.Initialize(m_Device, 2, true, H1ViewType.ConstantBufferView);
            //m_GlobalDescriptorHeaps.Add(generalHeap);

            // create frame resource
            // 1. RTV
            for (Int32 n = 0; n < FrameCount; ++n)
            {
                // get available alloc cpu address (internally update cursor in H1DescriptorHeap)
                CpuDescriptorHandle         rtvHandle      = deviceDX12.RenderTargetDescriptorCache.GetAvailableAllocCpuAddress();
                SharpDX.Direct3D12.Resource resourceForRTV = GetBackBuffer(n);
                deviceDX12.Device.CreateRenderTargetView(resourceForRTV, null, rtvHandle);
            }

            // 2. DSV
            DepthStencilViewDescription dsvDesc = new DepthStencilViewDescription();
            dsvDesc.Format    = SharpDX.DXGI.Format.D32_Float;
            dsvDesc.Dimension = DepthStencilViewDimension.Texture2D;
            dsvDesc.Flags     = DepthStencilViewFlags.None;

            ClearValue depthOptimizedClearValue = new ClearValue();
            depthOptimizedClearValue.Format               = SharpDX.DXGI.Format.D32_Float;
            depthOptimizedClearValue.DepthStencil.Depth   = 1.0f;
            depthOptimizedClearValue.DepthStencil.Stencil = 0;

            m_DepthStencil = deviceDX12.Device.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                ResourceDescription.Texture2D(SharpDX.DXGI.Format.D32_Float, width, height, 1, 0, 1, 0, ResourceFlags.AllowDepthStencil),
                ResourceStates.DepthWrite,
                depthOptimizedClearValue);

            CpuDescriptorHandle dsvHandle = deviceDX12.DepthStencilDescriptorCache.GetAvailableAllocCpuAddress();
            deviceDX12.Device.CreateDepthStencilView(m_DepthStencil, dsvDesc, dsvHandle);

            #endregion
        }
Esempio n. 11
0
        public void BuildPSO(Device3 device, GraphicsCommandList commandList)
        {
            World        = Matrix.Translation(-2.5f, -2.5f, -2.5f);
            buffer.World = World;
            light        = new Lighting
            {
                GlobalAmbientX = 1,
                GlobalAmbientY = 1,
                GlobalAmbientZ = 1,
                KaX            = .1f,
                KaY            = .1f,
                KaZ            = .1f,
                KdX            = .5f,
                KdY            = .5f,
                KdZ            = .5f,
                KeX            = .25f,
                KeY            = .25f,
                KeZ            = .25f,
                KsX            = .1f,
                KsY            = .1f,
                KsZ            = .1f,
                LightColorX    = 1,
                LightColorY    = 1,
                LightColorZ    = 1,
                LightPositionX = 10,
                LightPositionY = 10,
                LightPositionZ = 10,
                shininess      = 5
            };

            DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc);

            //setup descriptor ranges
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0
                                                               } };

            //Get sampler state setup
            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter           = Filter.MinimumMinMagMipPoint,
                AddressU         = TextureAddressMode.Border,
                AddressV         = TextureAddressMode.Border,
                AddressW         = TextureAddressMode.Border,
                MipLODBias       = 0,
                MaxAnisotropy    = 0,
                ComparisonFunc   = Comparison.Never,
                BorderColor      = StaticBorderColor.TransparentBlack,
                MinLOD           = 0.0f,
                MaxLOD           = float.MaxValue,
                ShaderRegister   = 0,
                RegisterSpace    = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000);
            View       = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY);
            World      = Matrix.Translation(-2.5f, -2.5f, -2.5f);

            DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _objectViewHeap   = device.CreateDescriptorHeap(cbvHeapDesc);
            _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc);

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) };


            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });

            _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout           = new InputLayoutDescription(inputElementDescs),
                RootSignature         = _rootSignature,
                VertexShader          = vertexShader,
                PixelShader           = pixelShader,
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilFormat    = SharpDX.DXGI.Format.D24_UNorm_S8_UInt,
                DepthStencilState     = DepthStencilStateDescription.Default(),
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            _pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                //Front
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ
                },

                //Back
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ
                },

                //Left
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX
                },

                //Right
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX
                },

                //Top
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY
                },

                //Bottom
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = _vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            _vertexBuffer.Unmap(0);

            _indicies = new int[] { 0, 1, 2,
                                    3, 2, 1,
                                    6, 5, 4,
                                    5, 6, 7,

                                    10, 9, 8,
                                    9, 10, 11,
                                    12, 13, 14,
                                    15, 14, 13,

                                    18, 17, 16,
                                    17, 18, 19,
                                    20, 21, 22,
                                    23, 22, 21 };

            int indBufferSize = Utilities.SizeOf(_indicies);

            _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead);

            IntPtr pIndBegin = _indexBuffer.Map(0);
            Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length);
            _indexBuffer.Unmap(0);

            _indexBufferView = new IndexBufferView()
            {
                BufferLocation = _indexBuffer.GPUVirtualAddress,
                Format         = Format.R32_UInt,
                SizeInBytes    = indBufferSize
            };

            // Initialize the vertex buffer view.
            _vertexBufferView = new VertexBufferView
            {
                BufferLocation = _vertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = vertexBufferSize
            };

            _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <ObjectData>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ObjectData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _objectPointer = _objectBuffer.Map(0);
            Utilities.Write(_objectPointer, ref buffer);

            _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <Lighting>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _lightingPointer = _lightingBuffer.Map(0);
            Utilities.Write(_lightingPointer, ref light);

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight);
            _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart);

            _resources = new[] { new GraphicsResource()
                                 {
                                     Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView
                                 } };
        }
Esempio n. 12
0
        public void BuildPSO(Device3 device, GraphicsCommandList commandList)
        {
            buffer = new CBuffer()
            {
                Rows    = 3,
                Columns = 5
            };

            DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _constantBufferViewHeap = device.CreateDescriptorHeap(cbvHeapDesc);


            DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc);

            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0
                                                               } };

            //Get sampler state setup
            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter           = Filter.MinimumMinMagMipPoint,
                AddressU         = TextureAddressMode.Border,
                AddressV         = TextureAddressMode.Border,
                AddressW         = TextureAddressMode.Border,
                MipLODBias       = 0,
                MaxAnisotropy    = 0,
                ComparisonFunc   = Comparison.Never,
                BorderColor      = StaticBorderColor.TransparentBlack,
                MinLOD           = 0.0f,
                MaxLOD           = float.MaxValue,
                ShaderRegister   = 0,
                RegisterSpace    = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges),
                                                                   new RootParameter(ShaderVisibility.Pixel, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView) };


            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });

            _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = _rootSignature,
                VertexShader       = vertexShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            _pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                new Vertex()
                {
                    position = new Vector3(-0.5f, -0.5f, 0.5f), texCoord = new Vector2(1.0f, 1.0f)
                },
                new Vertex()
                {
                    position = new Vector3(-0.5f, 0.5f, 0.5f), texCoord = new Vector2(1.0f, 0.0f)
                },
                new Vertex()
                {
                    position = new Vector3(0.5f, -0.5f, 0.5f), texCoord = new Vector2(0.0f, 1.0f)
                },
                new Vertex()
                {
                    position = new Vector3(0.5f, 0.5f, 0.5f), texCoord = new Vector2(0.0f, 0.0f)
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = _vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            _vertexBuffer.Unmap(0);

            _indicies = new int[] { 0, 1, 2,
                                    3, 2, 1 };

            int indBufferSize = Utilities.SizeOf(_indicies);

            _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead);

            IntPtr pIndBegin = _indexBuffer.Map(0);
            Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length);
            _indexBuffer.Unmap(0);

            _indexBufferView = new IndexBufferView()
            {
                BufferLocation = _indexBuffer.GPUVirtualAddress,
                Format         = Format.R32_UInt,
                SizeInBytes    = indBufferSize
            };

            // Initialize the vertex buffer view.
            _vertexBufferView = new VertexBufferView
            {
                BufferLocation = _vertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = vertexBufferSize
            };

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight);
            _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart);

            _constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = _constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <CBuffer>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, _constantBufferViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _constantBufferPointer = _constantBuffer.Map(0);
            Utilities.Write(_constantBufferPointer, ref buffer);

            _resources = new[] { new GraphicsResource()
                                 {
                                     Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _constantBuffer, Register = 1, type = ResourceType.ConstantBufferView
                                 } };
        }
        private void BuildModelResources()
        {
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            };

            device.CreateConstantBufferView(cbDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            constantBufferData = new ConstantBufferData
            {
                World     = Matrix.Identity,
                View      = Matrix.Identity,
                Project   = Matrix.Identity,
                TexsCount = 1
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            //build mesh controll buffer

            meshCtrBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = meshCtrBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <MeshCtrBufferData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbDesc, meshCtrBufferViewHeap.CPUDescriptorHandleForHeapStart);

            meshCtrBufferData = new MeshCtrBufferData
            {
                TexsCount = 1
            };

            meshCtrBufferPointer = meshCtrBuffer.Map(0);
            Utilities.Write(meshCtrBufferPointer, ref meshCtrBufferData);

            //model test
            var   modePath = "../../models/MikuDeepSea/";
            Model model    = Model.LoadFromFile(modePath + "DeepSeaGirl.x");

            Vertex[]       triangleVertices;
            int[]          triangleIndexes;
            List <Texture> texs;

            byte[]              textureData;
            GCHandle            handle;
            IntPtr              ptr;
            ResourceDescription textureDesc;
            //int viewStep = 0;
            int viewStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            bufferViews = new List <BufferView>();

            foreach (ModelComponent m in model.Components)
            {
                if (m.TexturePath != null)
                {
                    texs = Texture.LoadFromFile(modePath, m.TexturePath);
                }
                else
                {
                    continue;
                    //texs = Texture.LoadFromFile(modePath, "tex/jacket.png");
                }

                int texsCount = 0;
                foreach (Texture tex in texs)
                {
                    textureData = tex.Data;
                    textureDesc = ResourceDescription.Texture2D(tex.ColorFormat, tex.Width, tex.Height, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
                    // Create the texture.
                    // Describe and create a Texture2D.
                    texture = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        textureDesc,
                        ResourceStates.GenericRead, null);

                    // Copy data to the intermediate upload heap and then schedule a copy
                    // from the upload heap to the Texture2D.

                    handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
                    ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
                    texture.WriteToSubresource(0, null, ptr, tex.Width * tex.PixelWdith, textureData.Length);
                    handle.Free();

                    // Describe and create a SRV for the texture.
                    device.CreateShaderResourceView(
                        texture,
                        new ShaderResourceViewDescription
                    {
                        Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                        Format    = textureDesc.Format,
                        Dimension = ShaderResourceViewDimension.Texture2D,
                        Texture2D =
                        {
                            MipLevels           = 1,
                            MostDetailedMip     = 0,
                            PlaneSlice          = 0,
                            ResourceMinLODClamp = 0.0f
                        }
                    },
                        shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + viewStep + texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

                    texsCount++;
                    //break;
                }

                triangleVertices = (new Func <Vertex[]>(() =>
                {
                    var v = new Vertex[m.Vertices.Length];
                    for (int i = 0; i < m.Vertices.Length; i++)
                    {
                        v[i].Position = m.Vertices[i];
                        v[i].TexCoord = m.UV[i];
                        v[i].Normal = m.Normals[i];
                        //v[i].Tangent = m.Tangents[i];
                        //v[i].BiTangent = m.BiTangents[i];
                        v[i].Diffuse = m.Diffuse;
                        v[i].emissive = m.Emissive;
                        v[i].Specular = m.Specular;
                    }
                    return(v);
                }))();
                triangleIndexes = m.Indices;

                // build vertex buffer
                vertexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleVertices)),
                    ResourceStates.GenericRead);
                Utilities.Write(vertexBuffer.Map(0), triangleVertices, 0, triangleVertices.Length);
                vertexBuffer.Unmap(0);

                // build index buffer
                indexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleIndexes)),
                    ResourceStates.GenericRead);
                Utilities.Write(indexBuffer.Map(0), triangleIndexes, 0, triangleIndexes.Length);
                indexBuffer.Unmap(0);

                bufferViews.Add(new BufferView()
                {
                    vertexBufferView = new VertexBufferView()
                    {
                        BufferLocation = vertexBuffer.GPUVirtualAddress,
                        StrideInBytes  = Utilities.SizeOf <Vertex>(),
                        SizeInBytes    = Utilities.SizeOf(triangleVertices)
                    },
                    indexBufferView = new IndexBufferView()
                    {
                        BufferLocation = indexBuffer.GPUVirtualAddress,
                        SizeInBytes    = Utilities.SizeOf(triangleIndexes),
                        Format         = Format.R32_UInt
                    },
                    IndexCount = triangleIndexes.Length,
                    ViewStep   = viewStep,
                    TexsCount  = texsCount
                });

                viewStep += texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            }

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter             = Filter.MinMagMipLinear,
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                MaximumAnisotropy  = 0,
                MaximumLod         = float.MaxValue,
                MinimumLod         = -float.MaxValue,
                MipLodBias         = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);
        }
        private void BuildTerrainResouces()
        {
            float[] HeightMapData = new float[100 * 100];
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    HeightMapData[i * 100 + j] = Convert.ToSingle(Math.Cos(Math.PI * 2 * i) * Math.Sin(Math.PI * 2 * j));
                }
            }
            var Tex = Texture.LoadFromFile("../../", "Terrain.jpg");

            ResourceDescription HeighMapDesc       = ResourceDescription.Texture2D(Format.R32_Float, 100, 100, 1);
            ResourceDescription TerrainTextureDesc = ResourceDescription.Texture2D(Tex[0].ColorFormat, Tex[0].Width, Tex[0].Height, 1);

            HeightMap = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                HeighMapDesc,
                ResourceStates.GenericRead, null);
            TerrainTexture = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                HeighMapDesc,
                ResourceStates.GenericRead, null);
            TerrainCBF = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(1024 * 64),
                ResourceStates.GenericRead);

            GCHandle handle = GCHandle.Alloc(HeightMapData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(HeightMapData, 0);

            HeightMap.WriteToSubresource(0, null, ptr, 100 * 4, HeightMapData.Length);
            handle.Free();

            handle = GCHandle.Alloc(Tex[0].Data, GCHandleType.Pinned);
            ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(Tex[0].Data, 0);
            TerrainTexture.WriteToSubresource(0, null, ptr, Tex[0].Width * Tex[0].PixelWdith, Tex[0].Data.Length);
            handle.Free();

            device.CreateShaderResourceView(
                HeightMap,
                new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                Format    = HeighMapDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                }
            },
                terrainHeap.CPUDescriptorHandleForHeapStart);

            device.CreateShaderResourceView(
                TerrainTexture,
                new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                Format    = HeighMapDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                }
            },
                terrainHeap.CPUDescriptorHandleForHeapStart +
                device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

            //==========
            TerrainCBF = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);
            device.CreateConstantBufferView(
                new ConstantBufferViewDescription()
            {
                BufferLocation = TerrainCBF.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            },
                terrainHeap.CPUDescriptorHandleForHeapStart +
                device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView) * 2);

            TerrainCBFData = new ConstantBufferData
            {
                World     = Matrix.Identity,
                View      = Matrix.Identity,
                Project   = Matrix.Identity,
                TexsCount = 1
            };

            TerrainCBFPointer = TerrainCBF.Map(0);

            Vertex[] TerrainVertex = new Vertex[100 * 100];
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    TerrainVertex[i * 100 + j].Position = new Vector3(i, 0, j);
                    TerrainVertex[i * 100 + j].TexCoord = new Vector2(i / 2 == 0? 0 : 1, j / 2 == 0? 0 : 1);
                }
            }
            TerrainVertexBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(Utilities.SizeOf(TerrainVertex)),
                ResourceStates.GenericRead);
            Utilities.Write(TerrainVertexBuffer.Map(0), TerrainVertex, 0, TerrainVertex.Length);
            vertexBuffer.Unmap(0);

            TerrainVertexBufferView = new VertexBufferView()
            {
                BufferLocation = TerrainVertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = Utilities.SizeOf(TerrainVertex)
            };
        }
Esempio n. 15
0
        /// <summary>
        /// Loads a texture from a file.
        /// </summary>
        /// <param name="filename"></param>
        public void Load(string filename)
        {
            var library = Injector.Global.Resolve <Library>();

            Bitmap bitmap;

            using (var stream = library.OpenRead(filename))
            {
                bitmap = new Bitmap(stream);
            }

            Width      = bitmap.Width;
            Height     = bitmap.Height;
            Depth      = 1;
            Dimensions = 2;
            MipLevels  = (short)Math.Floor(Math.Log(Math.Min(Width, Height), 2));
            // MipLevels = 1;

            // create resources

            var imageFormat         = Format.B8G8R8A8_UNorm;
            var resourceDescription =
                ResourceDescription.Texture2D(imageFormat, Width, Height, mipLevels: MipLevels);

            Resource = Device.NativeDevice.CreateCommittedResource(
                new HeapProperties(HeapType.Default),
                HeapFlags.None,
                resourceDescription,
                ResourceStates.CopyDestination);

            UploadResource = Device.NativeDevice.CreateCommittedResource(
                new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0),
                HeapFlags.None,
                resourceDescription,
                ResourceStates.GenericRead);

            // Copy into upload buffer.
            BitmapData data = bitmap.LockBits(
                new Rectangle(0, 0, Width, Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);

            UploadResource.WriteToSubresource(
                0,
                new ResourceRegion()
            {
                Back   = 1,
                Right  = Width,
                Bottom = Height,
            },
                data.Scan0,
                Width * 4,
                Width * Height * 4);

            bitmap.UnlockBits(data);

            // Generate mipmaps on CPU.
            for (int i = 1; i < MipLevels; i++)
            {
                int    mipWidth  = Width / (1 << i);
                int    mipHeight = Height / (1 << i);
                Bitmap mipMap    = new Bitmap(bitmap, new Size(mipWidth, mipHeight));
                data = mipMap.LockBits(
                    new Rectangle(0, 0, mipWidth, mipHeight),
                    ImageLockMode.ReadOnly,
                    PixelFormat.Format32bppArgb);

                UploadResource.WriteToSubresource(
                    i,
                    new ResourceRegion()
                {
                    Back   = 1,
                    Right  = mipWidth,
                    Bottom = mipHeight,
                },
                    data.Scan0,
                    mipWidth * 4,
                    mipWidth * mipHeight * 4);

                mipMap.UnlockBits(data);
                mipMap.Dispose();
            }

            bitmap.Dispose();

            Device.UploadQueue.Enqueue(this);
        }
        public override void Load(string path2)
        {
            if (done)
            {
                return;
            }
            done = true;

            Bitmap bm = new Bitmap(path);

            Width  = bm.Width;
            Height = bm.Height;
            Depth  = 4;

            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, Width, Height);

            texture = DXGlobal.device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1);

            // Create the GPU upload buffer.
            var textureUploadHeap = DXGlobal.device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, Width, Height), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = new byte[Width * Height * 4];

            int loc = 0;

            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    var pix = bm.GetPixel(x, y);
                    textureData[loc++] = 0xff; //pix.R;
                    textureData[loc++] = 0xff; //pix.G;
                    textureData[loc++] = 0xff; // pix.B;
                    textureData[loc++] = 0xff;
                }
            }

            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);

            textureUploadHeap.WriteToSubresource(0, null, ptr, Depth * Width, textureData.Length);
            handle.Free();
            //   DXGlobal.Display.CommandList.Close();
            DXGlobal.Display.CommandList.Reset(DXGlobal.Display.DirectCmdListAlloc, Effect.Effect._pip);

            DXGlobal.Display.CommandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            DXGlobal.Display.CommandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D = { MipLevels = 1 },
            };
            var srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            DescriptorHeap srvH = DXGlobal.device.CreateDescriptorHeap(srvHeapDesc);


            DXGlobal.device.CreateShaderResourceView(texture, srvDesc, srvH.CPUDescriptorHandleForHeapStart);



            DXGlobal.Display.CommandList.Close();
            DXGlobal.Display.CommandQueue.ExecuteCommandList(DXGlobal.Display.CommandList);
            DXGlobal.Display.FlushCommandQueue();
        }
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0
                                                               } };

            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter           = Filter.MinimumMinMagMipPoint,
                AddressU         = TextureAddressMode.Border,
                AddressV         = TextureAddressMode.Border,
                AddressW         = TextureAddressMode.Border,
                MipLODBias       = 0,
                MaxAnisotropy    = 0,
                ComparisonFunc   = Comparison.Never,
                BorderColor      = StaticBorderColor.TransparentBlack,
                MinLOD           = 0.0f,
                MaxLOD           = float.MaxValue,
                ShaderRegister   = 0,
                RegisterSpace    = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges) };


            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = rootSignature,
                VertexShader       = vertexShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                new Vertex()
                {
                    position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), uv = new Vector2(0.5f, 0.0f)
                },
                new Vertex()
                {
                    position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), uv = new Vector2(1.0f, 1.0f)
                },
                new Vertex()
                {
                    position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), uv = new Vector2(0.0f, 1.0f)
                },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            commandQueue.ExecuteCommandList(commandList);

            // Create synchronization objects.
            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);


            WaitForPreviousFrame();

            //release temp texture
            textureUploadHeap.Dispose();
        }
        private ResourceDescription ConvertToNativeDescription2D()
        {
            var format = (SharpDX.DXGI.Format)textureDescription.Format;
            var flags  = textureDescription.Flags;

            // If the texture is going to be bound on the depth stencil, for to use TypeLess format
            if (IsDepthStencil)
            {
                if (IsShaderResource && GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_10_0)
                {
                    throw new NotSupportedException(String.Format("ShaderResourceView for DepthStencil Textures are not supported for Graphics profile < 10.0 (Current: [{0}])", GraphicsDevice.Features.CurrentProfile));
                }
                else
                {
                    // Determine TypeLess Format and ShaderResourceView Format
                    if (GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_10_0)
                    {
                        switch (textureDescription.Format)
                        {
                        case PixelFormat.D16_UNorm:
                            format = SharpDX.DXGI.Format.D16_UNorm;
                            break;

                        case PixelFormat.D32_Float:
                            format = SharpDX.DXGI.Format.D32_Float;
                            break;

                        case PixelFormat.D24_UNorm_S8_UInt:
                            format = SharpDX.DXGI.Format.D24_UNorm_S8_UInt;
                            break;

                        case PixelFormat.D32_Float_S8X24_UInt:
                            format = SharpDX.DXGI.Format.D32_Float_S8X24_UInt;
                            break;

                        default:
                            throw new NotSupportedException(String.Format("Unsupported DepthFormat [{0}] for depth buffer", textureDescription.Format));
                        }
                    }
                    else
                    {
                        switch (textureDescription.Format)
                        {
                        case PixelFormat.D16_UNorm:
                            format = SharpDX.DXGI.Format.R16_Typeless;
                            break;

                        case PixelFormat.D32_Float:
                            format = SharpDX.DXGI.Format.R32_Typeless;
                            break;

                        case PixelFormat.D24_UNorm_S8_UInt:
                            //format = SharpDX.DXGI.Format.D24_UNorm_S8_UInt;
                            format = SharpDX.DXGI.Format.R24G8_Typeless;
                            break;

                        case PixelFormat.D32_Float_S8X24_UInt:
                            format = SharpDX.DXGI.Format.R32G8X24_Typeless;
                            break;

                        default:
                            throw new NotSupportedException(String.Format("Unsupported DepthFormat [{0}] for depth buffer", textureDescription.Format));
                        }
                    }
                }
            }

            return(ResourceDescription.Texture2D(format, textureDescription.Width, textureDescription.Height, (short)textureDescription.ArraySize, (short)textureDescription.MipLevels, (short)textureDescription.MultiSampleLevel, 0, GetBindFlagsFromTextureFlags(flags)));
        }
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(

                RootSignatureFlags.AllowInputAssemblerInputLayout,
                // Root Parameters
                new[]
            {
                new RootParameter(ShaderVisibility.All,
                                  new []
                {
                    new DescriptorRange()
                    {
                        RangeType       = DescriptorRangeType.ShaderResourceView,
                        DescriptorCount = 1,
                        OffsetInDescriptorsFromTableStart = int.MinValue,
                        BaseShaderRegister = 0
                    },
                    new DescriptorRange()
                    {
                        RangeType       = DescriptorRangeType.ConstantBufferView,
                        DescriptorCount = 1,
                        OffsetInDescriptorsFromTableStart = int.MinValue + 1,
                        BaseShaderRegister = 0
                    }
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.Sampler,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                }),
            });

            //// Samplers
            //new[]
            //{
            //    new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
            //    {
            //        Filter = Filter.MinimumMinMagMipPoint,
            //        AddressUVW = TextureAddressMode.Border,
            //    }
            //});

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
#endif

#if DEBUG
            //var result = SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug);
            var geometryShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            var inputElementDescs = new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = rootSignature,
                VertexShader       = vertexShader,
                GeometryShader     = geometryShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = true,
                    DepthComparison  = Comparison.LessEqual,
                    DepthWriteMask   = DepthWriteMask.All,
                    IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);
            commandList.Close();

            // build vertex buffer

            var triangleVertices = new[]
            {
                //TOP
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                //BOTTOM
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                //LEFT
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(1f, 1f)
                },
                //RIGHT
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(0f, 1f)
                },
                //FRONT
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                //BACK
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(0f, 1f)
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            // build index buffer

            var triangleIndexes = new uint[]
            {
                0, 1, 2,
                0, 2, 3,

                4, 6, 5,
                4, 7, 6,

                8, 9, 10,
                8, 10, 11,

                12, 14, 13,
                12, 15, 14,

                16, 18, 17,
                16, 19, 18,

                20, 21, 22,
                20, 22, 23
            };

            int indexBufferSize = Utilities.SizeOf(triangleIndexes);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, triangleIndexes, 0, triangleIndexes.Length);
            indexBuffer.Unmap(0);

            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.SizeInBytes    = indexBufferSize;
            indexBufferView.Format         = Format.R32_UInt;

            // Create the texture.
            // Describe and create a Texture2D.
            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, textureDesc, ResourceStates.GenericRead, null);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = Utilities.ReadStream(new FileStream("../../texture1.dds", FileMode.Open));

            texture.Name = "Texture";

            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            texture.WriteToSubresource(0, null, ptr, TextureWidth * 4, textureData.Length);
            handle.Free();

            // Describe and create a SRV for the texture.
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),

                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                },
            };

            device.CreateShaderResourceView(texture, srvDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart);

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter             = Filter.MinMagMipLinear,
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                MaximumAnisotropy  = 0,
                MaximumLod         = float.MaxValue,
                MinimumLod         = -float.MaxValue,
                MipLodBias         = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);

            // build constant buffer

            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            };
            var srvCbvStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateConstantBufferView(cbDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart + srvCbvStep);

            constantBufferData = new ConstantBufferData
            {
                Project = Matrix.Identity
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // build depth buffer

            DescriptorHeapDescription descDescriptorHeapDSB = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Type            = DescriptorHeapType.DepthStencilView,
                Flags           = DescriptorHeapFlags.None
            };

            DescriptorHeap      descriptorHeapDSB = device.CreateDescriptorHeap(descDescriptorHeapDSB);
            ResourceDescription descDepth         = new ResourceDescription()
            {
                Dimension         = ResourceDimension.Texture2D,
                DepthOrArraySize  = 1,
                MipLevels         = 0,
                Flags             = ResourceFlags.AllowDepthStencil,
                Width             = (int)viewport.Width,
                Height            = (int)viewport.Height,
                Format            = Format.R32_Typeless,
                Layout            = TextureLayout.Unknown,
                SampleDescription = new SampleDescription()
                {
                    Count = 1
                }
            };

            ClearValue dsvClearValue = new ClearValue()
            {
                Format       = Format.D32_Float,
                DepthStencil = new DepthStencilValue()
                {
                    Depth   = 1.0f,
                    Stencil = 0
                }
            };

            Resource renderTargetDepth = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, descDepth, ResourceStates.GenericRead, dsvClearValue);

            DepthStencilViewDescription depthDSV = new DepthStencilViewDescription()
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format    = Format.D32_Float,
                Texture2D = new DepthStencilViewDescription.Texture2DResource()
                {
                    MipSlice = 0
                }
            };

            device.CreateDepthStencilView(renderTargetDepth, depthDSV, descriptorHeapDSB.CPUDescriptorHandleForHeapStart);
            handleDSV = descriptorHeapDSB.CPUDescriptorHandleForHeapStart;

            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;
            fenceEvent = new AutoResetEvent(false);
        }
Esempio n. 20
0
        public void CreateShaderResources()
        {
            // Create the output resource. The dimensions and format should match the swap-chain
            ResourceDescription resDesc = new ResourceDescription();

            resDesc.DepthOrArraySize  = 1;
            resDesc.Dimension         = ResourceDimension.Texture2D;
            resDesc.Format            = Format.R8G8B8A8_UNorm; // The backbuffer is actually DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, but sRGB formats can't be used with UAVs. We will convert to sRGB ourselves in the shader
            resDesc.Flags             = ResourceFlags.AllowUnorderedAccess;
            resDesc.Height            = mSwapChainRect.Height;
            resDesc.Layout            = TextureLayout.Unknown;
            resDesc.MipLevels         = 1;
            resDesc.SampleDescription = new SampleDescription(1, 0);
            resDesc.Width             = mSwapChainRect.Width;
            mpOutputResource          = mpDevice.CreateCommittedResource(AccelerationStructures.kDefaultHeapProps, HeapFlags.None, resDesc, ResourceStates.CopySource, null); // Starting as copy-source to simplify onFrameRender()

            // Create an SRV/UAV/VertexSRV/IndexSRV descriptor heap. Need 5 entries - 1 SRV for the scene, 1 UAV for the output, 1 SRV for VertexBuffer, 1 SRV for IndexBuffer, 1 SRV for texture
            mpSrvUavHeap = this.context.CreateDescriptorHeap(mpDevice, 5, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, true);

            // Create the UAV. Based on the root signature we created it should be the first entry
            UnorderedAccessViewDescription uavDesc = new UnorderedAccessViewDescription();

            uavDesc.ViewDimension = UnorderedAccessViewDimension.Texture2D;
            mpDevice.CreateUnorderedAccessView(mpOutputResource, null, uavDesc, mpSrvUavHeap.GetCPUDescriptorHandleForHeapStart());

            // Create the TLAS SRV right after the UAV. Note that we are using a different SRV desc here
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription();

            srvDesc.ViewDimension                            = ShaderResourceViewDimension.RaytracingAccelerationStructure;
            srvDesc.Shader4ComponentMapping                  = D3D12DefaultShader4ComponentMapping;
            srvDesc.RaytracingAccelerationStructure          = new RaytracingAccelerationStructureShaderResourceView();
            srvDesc.RaytracingAccelerationStructure.Location = mpTopLevelAS.GPUVirtualAddress;
            CpuDescriptorHandle srvHandle = mpSrvUavHeap.GetCPUDescriptorHandleForHeapStart();

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            mpDevice.CreateShaderResourceView(null, srvDesc, srvHandle);

            // Index SRV
            var indexSRVDesc = new ShaderResourceViewDescription()
            {
                ViewDimension           = ShaderResourceViewDimension.Buffer,
                Shader4ComponentMapping = D3D12DefaultShader4ComponentMapping,
                Format = Format.R32_Typeless,
                Buffer =
                {
                    NumElements         = (int)(this.acs.IndexCount * 2 / 4),
                    Flags               = BufferShaderResourceViewFlags.Raw,
                    StructureByteStride =                                  0,
                }
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            indexSRVHandle = srvHandle;
            mpDevice.CreateShaderResourceView(this.acs.IndexBuffer, indexSRVDesc, indexSRVHandle);

            // Vertex SRV
            var vertexSRVDesc = new ShaderResourceViewDescription()
            {
                ViewDimension           = ShaderResourceViewDimension.Buffer,
                Shader4ComponentMapping = D3D12DefaultShader4ComponentMapping,
                Format = Format.Unknown,
                Buffer =
                {
                    NumElements         = (int)this.acs.VertexCount,
                    Flags               = BufferShaderResourceViewFlags.None,
                    StructureByteStride = Unsafe.SizeOf <VertexPositionNormalTangentTexture>(),
                }
            };

            srvHandle.Ptr  += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            vertexSRVHandle = srvHandle;
            mpDevice.CreateShaderResourceView(this.acs.VertexBuffer, vertexSRVDesc, vertexSRVHandle);

            // Texture
            var image       = TextureHelper.Load("GLTF/Default_albedo.jpg");
            var textureDesc = ResourceDescription.Texture2D(image.Format, (int)image.Width, (int)image.Height);

            this.texture = this.mpDevice.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            // Create the GPU upload buffer.
            var textureUploadHeap = mpDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, textureDesc, ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = image.Data;

            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);

            textureUploadHeap.WriteToSubresource(0, null, ptr, (int)(image.TexturePixelSize * image.Width), textureData.Length);
            handle.Free();

            mpCmdList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            mpCmdList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            var textureSRVDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3D12DefaultShader4ComponentMapping,
                Format        = textureDesc.Format,
                ViewDimension = ShaderResourceViewDimension.Texture2D,
                Texture2D     = { MipLevels = 1 },
            };

            srvHandle.Ptr   += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            textureSRVHandle = srvHandle;
            this.mpDevice.CreateShaderResourceView(this.texture, textureSRVDesc, textureSRVHandle);
        }