Exemple #1
0
 public DescriptorHandle(ID3D12DescriptorHeap heap, int sizeIncrement, CpuDescriptorHandle cpuHandle, GpuDescriptorHandle gpuHandle)
 {
     Heap          = heap;
     SizeIncrement = sizeIncrement;
     CpuHandle     = cpuHandle;
     GpuHandle     = gpuHandle;
 }
        public DescriptorHandle Allocate(int count)
        {
            if (_currentHeap == null ||
                _remainingFreeHandles < count)
            {
                _currentHeap      = Device.RequestNewHeap(Type, DescriptorsPerHeap);
                _currentCpuHandle = _currentHeap.GetCPUDescriptorHandleForHeapStart();
                if (IsShaderVisible)
                {
                    _currentGpuHandle = _currentHeap.GetGPUDescriptorHandleForHeapStart();
                }

                _remainingFreeHandles = DescriptorsPerHeap;

                if (_descriptorSize == 0)
                {
                    _descriptorSize = Device.D3D12Device.GetDescriptorHandleIncrementSize(Type);
                }
            }

            var cpuHandle = _currentCpuHandle;

            _currentCpuHandle.Ptr += count * _descriptorSize;
            _remainingFreeHandles -= count;

            if (IsShaderVisible)
            {
                var gpuHandle = _currentGpuHandle;
                _currentGpuHandle.Ptr += (long)(count * _descriptorSize);
                return(new DescriptorHandle(_currentHeap, _descriptorSize, cpuHandle, gpuHandle));
            }

            return(new DescriptorHandle(_currentHeap, _descriptorSize, cpuHandle));
        }
Exemple #3
0
        private int BeginFrame()
        {
            // Bind the descriptor heaps
            ID3D12DescriptorHeap[] heaps = new ID3D12DescriptorHeap[] { mpSrvUavHeap };
            mpCmdList.SetDescriptorHeaps(1, heaps);

            return(this.mpSwapChain.GetCurrentBackBufferIndex());
        }
Exemple #4
0
 public void Dispose()
 {
     resource?.Dispose();
     resource = null;
     renderTargetView?.Dispose();
     renderTargetView = null;
     depthStencilView?.Dispose();
     depthStencilView = null;
 }
Exemple #5
0
 public DescriptorHandle(ID3D12DescriptorHeap heap, int sizeIncrement, CpuDescriptorHandle cpuHandle)
 {
     Heap          = heap;
     SizeIncrement = sizeIncrement;
     CpuHandle     = cpuHandle;
     GpuHandle     = new GpuDescriptorHandle
     {
         Ptr = InvalidAddress
     };
 }
Exemple #6
0
        private void CreateShaderResources()
        {
            HeapProperties heapProperties = new HeapProperties(HeapType.Default, CpuPageProperty.Unknown, MemoryPool.Unknown, 0, 0);

            // Create the output resource. The dimensions and format should match the swap-chain
            ResourceDescription resDesc = new ResourceDescription();

            resDesc.Alignment               = 0;
            resDesc.DepthOrArraySize        = 1;
            resDesc.Dimension               = ResourceDimension.Texture2D;
            resDesc.Flags                   = ResourceFlags.AllowUnorderedAccess;
            resDesc.Format                  = Format.R8G8B8A8_UNorm;
            resDesc.Width                   = Window.Width;
            resDesc.Height                  = Window.Height;
            resDesc.Layout                  = TextureLayout.Unknown;
            resDesc.MipLevels               = 1;
            resDesc.SampleDescription       = new SampleDescription();
            resDesc.SampleDescription.Count = 1;

            outputResource = device.CreateCommittedResource(heapProperties, HeapFlags.None, resDesc, ResourceStates.CopySource, null);

            // Create an SRV/UAV descriptor heap. Need 2 entries - 1 SRV for the scene and 1 UAV for the output
            srvUavHeap = CreateDescriptorHeap(device, 2, 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;
            device.CreateUnorderedAccessView(outputResource, null, uavDesc, srvUavHeap.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                  = 5768; // D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
            srvDesc.RaytracingAccelerationStructure          = new RaytracingAccelerationStructureShaderResourceView();
            srvDesc.RaytracingAccelerationStructure.Location = topLevelAS.GPUVirtualAddress;

            CpuDescriptorHandle srvHandle = srvUavHeap.GetCPUDescriptorHandleForHeapStart();

            srvHandle.Ptr += device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateShaderResourceView(null, srvDesc, srvHandle);
        }
Exemple #7
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 descriptor heap. Need 2 entries - 1 SRV for the scene and 1 UAV for the output
            mpSrvUavHeap = this.context.CreateDescriptorHeap(mpDevice, 2, 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);
        }
Exemple #8
0
        internal CpuDescriptorHandle Allocate(int count)
        {
            if (currentHeap == null || remainingHandles < count)
            {
                DescriptorHeapDescription descriptorHeapDescription = new DescriptorHeapDescription()
                {
                    Flags           = DescriptorHeapFlags.None,
                    Type            = DescriptorHeapType,
                    DescriptorCount = DescriptorPerHeap,
                    NodeMask        = 1,
                };

                currentHeap      = GraphicsDevice.NativeDevice.CreateDescriptorHeap <ID3D12DescriptorHeap>(descriptorHeapDescription);
                remainingHandles = DescriptorPerHeap;
                currentHandle    = currentHeap.GetCPUDescriptorHandleForHeapStart();
            }

            CpuDescriptorHandle result = currentHandle;

            currentHandle.Ptr += DescriptorSize;
            remainingHandles  -= count;

            return(result);
        }
Exemple #9
0
        public CpuDescriptorHandle CreateRTV(ID3D12Device5 pDevice, ID3D12Resource pResource, ID3D12DescriptorHeap pHeap, ref uint usedHeapEntries, Format format)
        {
            RenderTargetViewDescription desc = new RenderTargetViewDescription();

            desc.ViewDimension      = RenderTargetViewDimension.Texture2D;
            desc.Format             = format;
            desc.Texture2D          = new Texture2DRenderTargetView();
            desc.Texture2D.MipSlice = 0;
            CpuDescriptorHandle rtvHandle = pHeap.GetCPUDescriptorHandleForHeapStart();

            rtvHandle.Ptr += usedHeapEntries * pDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);
            usedHeapEntries++;
            pDevice.CreateRenderTargetView(pResource, desc, rtvHandle);
            return(rtvHandle);
        }
Exemple #10
0
        private CpuDescriptorHandle CreateRenderTargetView(ID3D12Device device, ID3D12Resource swapChainBuffer, ID3D12DescriptorHeap heap,
                                                           ref uint usedEntries, Format format)
        {
            RenderTargetViewDescription viewDesc = new RenderTargetViewDescription();

            viewDesc.ViewDimension      = RenderTargetViewDimension.Texture2D;
            viewDesc.Format             = format;
            viewDesc.Texture2D          = new Texture2DRenderTargetView();
            viewDesc.Texture2D.MipSlice = 0;

            CpuDescriptorHandle handle = heap.GetCPUDescriptorHandleForHeapStart();

            handle.Ptr += usedEntries * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);
            usedEntries++;

            device.CreateRenderTargetView(swapChainBuffer, viewDesc, handle);
            return(handle);
        }
Exemple #11
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 SceneContantBuffer, 1 primitiveConstantBuffer
            mpSrvUavHeap = this.context.CreateDescriptorHeap(mpDevice, 6, 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);

            // CB Scene
            Vector3   cameraPosition = new Vector3(0, 1, -7);
            Matrix4x4 view           = Matrix4x4.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.UnitY);
            Matrix4x4 proj           = Matrix4x4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)mSwapChainRect.Width / mSwapChainRect.Height, 0.1f, 1000f);
            Matrix4x4 viewProj       = Matrix4x4.Multiply(view, proj);

            Matrix4x4.Invert(viewProj, out Matrix4x4 projectionToWorld);
            SceneConstantBuffer sceneConstantBuffer = new SceneConstantBuffer()
            {
                projectionToWorld = Matrix4x4.Transpose(projectionToWorld),
                cameraPosition    = cameraPosition,
                lightPosition     = new Vector3(0.0f, 1.0f, -2.0f),
                lightDiffuseColor = new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
                lightAmbientColor = new Vector4(0.1f, 0.1f, 0.1f, 1.0f),
                backgroundColor   = new Vector4(0.4f, 0.6f, 0.2f, 1.0f),
                MaxRecursionDepth = 4,
            };

            sceneCB = this.acs.CreateBuffer(mpDevice, (uint)Unsafe.SizeOf <SceneConstantBuffer>(), ResourceFlags.None, ResourceStates.GenericRead, AccelerationStructures.kUploadHeapProps);
            IntPtr pData;

            pData = sceneCB.Map(0, null);
            Helpers.MemCpy(pData, sceneConstantBuffer, (uint)Unsafe.SizeOf <SceneConstantBuffer>());
            sceneCB.Unmap(0, null);

            var sceneCBV = new ConstantBufferViewDescription()
            {
                BufferLocation = sceneCB.GPUVirtualAddress,
                SizeInBytes    = (Unsafe.SizeOf <SceneConstantBuffer>() + 255) & ~255,
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            sceneCBVHandle = srvHandle;
            mpDevice.CreateConstantBufferView(sceneCBV, sceneCBVHandle);

            // CB Primitive
            PrimitiveConstantBuffer primitiveConstantBuffer = new PrimitiveConstantBuffer()
            {
                diffuseColor     = new Vector4(0.8f, 0f, 0f, 1.0f),
                inShadowRadiance = 0.35f,
                diffuseCoef      = 0.1f,
                specularCoef     = 0.7f,
                specularPower    = 50,
                reflectanceCoef  = 0.7f,
            };

            ID3D12Resource primitiveCB = this.acs.CreateBuffer(mpDevice, (uint)Unsafe.SizeOf <PrimitiveConstantBuffer>(), ResourceFlags.None, ResourceStates.GenericRead, AccelerationStructures.kUploadHeapProps);
            IntPtr         pData2;

            pData2 = primitiveCB.Map(0, null);
            Helpers.MemCpy(pData2, primitiveConstantBuffer, (uint)Unsafe.SizeOf <PrimitiveConstantBuffer>());
            primitiveCB.Unmap(0, null);

            var primitiveCBV = new ConstantBufferViewDescription()
            {
                BufferLocation = primitiveCB.GPUVirtualAddress,
                SizeInBytes    = (Unsafe.SizeOf <PrimitiveConstantBuffer>() + 255) & ~255,
            };

            srvHandle.Ptr += mpDevice.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            var primitiveCBVHandle = srvHandle;

            mpDevice.CreateConstantBufferView(primitiveCBV, primitiveCBVHandle);
        }
Exemple #12
0
 public void Dispose()
 {
     currentHeap?.Dispose();
     currentHeap = null;
 }
 public void Dispose()
 {
     heap?.Dispose();
     heap = null;
 }
Exemple #14
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);
        }
Exemple #15
0
        protected Application(bool useDirect3D12)
        {
            _wndProc = ProcessWindowMessage;
            var wndClassEx = new WNDCLASSEX
            {
                Size                  = Unsafe.SizeOf <WNDCLASSEX>(),
                Styles                = WindowClassStyles.CS_HREDRAW | WindowClassStyles.CS_VREDRAW | WindowClassStyles.CS_OWNDC,
                WindowProc            = _wndProc,
                InstanceHandle        = HInstance,
                CursorHandle          = LoadCursor(IntPtr.Zero, SystemCursor.IDC_ARROW),
                BackgroundBrushHandle = IntPtr.Zero,
                IconHandle            = IntPtr.Zero,
                ClassName             = WndClassName,
            };

            var atom = RegisterClassEx(ref wndClassEx);

            if (atom == 0)
            {
                throw new InvalidOperationException(
                          $"Failed to register window class. Error: {Marshal.GetLastWin32Error()}"
                          );
            }

            Window = new Window("Vortice", 800, 600);

            if (useDirect3D12 &&
                !ID3D12Device.IsSupported(null, FeatureLevel.Level_11_0))
            {
                useDirect3D12 = false;
            }

            var debugFactory = false;

#if DEBUG
            if (useDirect3D12)
            {
                if (D3D12GetDebugInterface <ID3D12Debug>(out var debug).Success)
                {
                    debug.EnableDebugLayer();
                    debugFactory = true;
                }
            }
#endif

            if (useDirect3D12)
            {
                if (CreateDXGIFactory2(debugFactory, out IDXGIFactory4 dxgiFactory4).Failure)
                {
                    throw new InvalidOperationException("Cannot create IDXGIFactory4");
                }

                _dxgiFactory = dxgiFactory4;
            }
            else
            {
                if (CreateDXGIFactory2(debugFactory, out _dxgiFactory).Failure)
                {
                    throw new InvalidOperationException("Cannot create IDXGIFactory4");
                }
            }

            if (useDirect3D12)
            {
                Debug.Assert(D3D12CreateDevice(null, FeatureLevel.Level_11_0, out _d3d12Device).Success);

                _d3d12CommandQueue = _d3d12Device.CreateCommandQueue(new CommandQueueDescription(CommandListType.Direct, CommandQueuePriority.Normal));
            }
            else
            {
                var featureLevels = new FeatureLevel[]
                {
                    FeatureLevel.Level_11_1,
                    FeatureLevel.Level_11_0
                };
                Debug.Assert(ID3D11Device.TryCreate(
                                 null,
                                 DriverType.Hardware,
                                 DeviceCreationFlags.BgraSupport,
                                 featureLevels,
                                 out _d3d11Device,
                                 out _d3d11DeviceContext).Success);
            }

            var swapChainDesc = new SwapChainDescription1
            {
                BufferCount       = FrameCount,
                Width             = Window.Width,
                Height            = Window.Height,
                Format            = Format.B8G8R8A8_UNorm,
                Usage             = Vortice.Usage.RenderTargetOutput,
                SwapEffect        = SwapEffect.FlipDiscard,
                SampleDescription = new SampleDescription(1, 0)
            };

            SwapChain = DXGIFactory.CreateSwapChainForHwnd(_d3d12CommandQueue, Window.Handle, swapChainDesc);
            DXGIFactory.MakeWindowAssociation(Window.Handle, WindowAssociationFlags.IgnoreAltEnter);

            if (useDirect3D12)
            {
                SwapChain3  = SwapChain.QueryInterface <IDXGISwapChain3>();
                _frameIndex = SwapChain3.GetCurrentBackBufferIndex();
            }

            _rtvHeap           = _d3d12Device.CreateDescriptorHeap(new DescriptorHeapDescription(DescriptorHeapType.RenderTargetView, FrameCount));
            _rtvDescriptorSize = _d3d12Device.GetDescriptorHandleIncrementSize(DescriptorHeapType.RenderTargetView);

            // Create frame resources.
            {
                var rtvHandle = _rtvHeap.GetCPUDescriptorHandleForHeapStart();

                // Create a RTV for each frame.
                _renderTargets = new ID3D12Resource[FrameCount];
                for (var i = 0; i < FrameCount; i++)
                {
                    _renderTargets[i] = SwapChain.GetBuffer <ID3D12Resource>(i);
                    _d3d12Device.CreateRenderTargetView(_renderTargets[i], null, rtvHandle);
                    rtvHandle += _rtvDescriptorSize;
                }
            }

            _commandAllocator = _d3d12Device.CreateCommandAllocator(CommandListType.Direct);
            _commandList      = _d3d12Device.CreateCommandList(CommandListType.Direct, _commandAllocator);
            _commandList.Close();

            // Create synchronization objects.
            _d3d12Fence = _d3d12Device.CreateFence(0);
            _fenceValue = 1;
            _fenceEvent = new AutoResetEvent(false);
        }