internal void Collect(NativeResource nativeResource)
 {
     nativeResourceCollector.Add(NextFenceValue, nativeResource);
 }
Beispiel #2
0
        /// <summary>
        /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataPointer"></param>
        public void Recreate(IntPtr dataPointer)
        {
            // TODO D3D12 where should that go longer term? should it be precomputed for future use? (cost would likely be additional check on SetDescriptorSets/Draw)
            NativeResourceState = ResourceStates.Common;
            var bufferFlags = bufferDescription.BufferFlags;

            if ((bufferFlags & BufferFlags.ConstantBuffer) != 0)
            {
                NativeResourceState |= ResourceStates.VertexAndConstantBuffer;
            }

            if ((bufferFlags & BufferFlags.IndexBuffer) != 0)
            {
                NativeResourceState |= ResourceStates.IndexBuffer;
            }

            if ((bufferFlags & BufferFlags.VertexBuffer) != 0)
            {
                NativeResourceState |= ResourceStates.VertexAndConstantBuffer;
            }

            if ((bufferFlags & BufferFlags.ShaderResource) != 0)
            {
                NativeResourceState |= ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource;
            }

            if ((bufferFlags & BufferFlags.StructuredBuffer) != 0)
            {
                if (bufferDescription.StructureByteStride <= 0)
                {
                    throw new ArgumentException("Element size cannot be less or equal 0 for structured buffer");
                }
            }

            if ((bufferFlags & BufferFlags.ArgumentBuffer) == BufferFlags.ArgumentBuffer)
            {
                NativeResourceState |= ResourceStates.IndirectArgument;
            }

            var heapType = HeapType.Default;

            if (Usage == GraphicsResourceUsage.Staging)
            {
                if (dataPointer != IntPtr.Zero)
                {
                    throw new NotImplementedException("D3D12: Staging buffers can't be created with initial data.");
                }

                heapType            = HeapType.Readback;
                NativeResourceState = ResourceStates.CopyDestination;
            }
            else if (Usage == GraphicsResourceUsage.Dynamic)
            {
                heapType            = HeapType.Upload;
                NativeResourceState = ResourceStates.GenericRead;
            }

            // TODO D3D12 move that to a global allocator in bigger committed resources
            NativeDeviceChild = GraphicsDevice.NativeDevice.CreateCommittedResource(new HeapProperties(heapType), HeapFlags.None, nativeDescription, dataPointer != IntPtr.Zero ? ResourceStates.CopyDestination : NativeResourceState);
            GPUVirtualAddress = NativeResource.GPUVirtualAddress;

            if (dataPointer != IntPtr.Zero)
            {
                if (heapType == HeapType.Upload)
                {
                    var uploadMemory = NativeResource.Map(0);
                    Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes);
                    NativeResource.Unmap(0);
                }
                else
                {
                    // Copy data in upload heap for later copy
                    // TODO D3D12 move that to a shared upload heap
                    SharpDX.Direct3D12.Resource uploadResource;
                    int uploadOffset;
                    var uploadMemory = GraphicsDevice.AllocateUploadBuffer(SizeInBytes, out uploadResource, out uploadOffset);
                    Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes);

                    // TODO D3D12 lock NativeCopyCommandList usages
                    var commandList = GraphicsDevice.NativeCopyCommandList;
                    commandList.Reset(GraphicsDevice.NativeCopyCommandAllocator, null);
                    // Copy from upload heap to actual resource
                    commandList.CopyBufferRegion(NativeResource, 0, uploadResource, uploadOffset, SizeInBytes);

                    // Switch resource to proper read state
                    commandList.ResourceBarrierTransition(NativeResource, 0, ResourceStates.CopyDestination, NativeResourceState);

                    commandList.Close();

                    GraphicsDevice.WaitCopyQueue();
                }
            }

            NativeShaderResourceView  = GetShaderResourceView(ViewFormat);
            NativeUnorderedAccessView = GetUnorderedAccessView(ViewFormat);
        }