internal void Collect(NativeResource nativeResource) { nativeResourceCollector.Add(NextFenceValue, nativeResource); }
/// <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); }