/// <summary> /// Creates a new <see cref="TransferBuffer{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/> associated with the current instance.</param> /// <param name="length">The number of items to store in the current buffer.</param> /// <param name="resourceType">The resource type for the current buffer.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected TransferBuffer(GraphicsDevice device, int length, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); // The maximum length is set such that the aligned buffer size can't exceed uint.MaxValue Guard.IsBetweenOrEqualTo(length, 1, (uint.MaxValue / (uint)sizeof(T)) & ~255, nameof(length)); GraphicsDevice = device; Length = length; ulong sizeInBytes = (uint)length * (uint)sizeof(T); #if NET6_0_OR_GREATER this.allocation = device.Allocator->CreateResource(device.Pool, resourceType, allocationMode, sizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); #else this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, sizeInBytes, device.IsCacheCoherentUMA); #endif device.RegisterAllocatedResource(); this.mappedData = (T *)this.d3D12Resource.Get()->Map().Pointer; this.d3D12Resource.Get()->SetName(this); }
/// <summary> /// Creates a new <see cref="Texture2D{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="ComputeSharp.GraphicsDevice"/> associated with the current instance.</param> /// <param name="height">The height of the texture.</param> /// <param name="width">The width of the texture.</param> /// <param name="resourceType">The resource type for the current texture.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> /// <param name="d3D12FormatSupport">The format support for the current texture type.</param> private protected Texture2D(GraphicsDevice device, int width, int height, ResourceType resourceType, AllocationMode allocationMode, D3D12_FORMAT_SUPPORT1 d3D12FormatSupport) { device.ThrowIfDisposed(); Guard.IsBetweenOrEqualTo(width, 1, FX.D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, FX.D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, nameof(height)); if (!device.D3D12Device->IsDxgiFormatSupported(DXGIFormatHelper.GetForType <T>(), d3D12FormatSupport)) { UnsupportedTextureTypeException.ThrowForTexture2D <T>(); } GraphicsDevice = device; if (device.IsCacheCoherentUMA) { this.d3D12Resource = device.D3D12Device->CreateCommittedResource( resourceType, allocationMode, DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, true, out this.d3D12ResourceState); } else { this.allocation = device.Allocator->CreateResource( resourceType, allocationMode, DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, out this.d3D12ResourceState); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); } this.d3D12CommandListType = this.d3D12ResourceState == D3D12_RESOURCE_STATE_COMMON ? D3D12_COMMAND_LIST_TYPE_COPY : D3D12_COMMAND_LIST_TYPE_COMPUTE; device.D3D12Device->GetCopyableFootprint( DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, out this.d3D12PlacedSubresourceFootprint, out _, out _); device.RentShaderResourceViewDescriptorHandles(out D3D12CpuDescriptorHandle, out D3D12GpuDescriptorHandle); switch (resourceType) { case ResourceType.ReadOnly: device.D3D12Device->CreateShaderResourceView(this.d3D12Resource.Get(), DXGIFormatHelper.GetForType <T>(), D3D12_SRV_DIMENSION_TEXTURE2D, D3D12CpuDescriptorHandle); break; case ResourceType.ReadWrite: device.D3D12Device->CreateUnorderedAccessView(this.d3D12Resource.Get(), DXGIFormatHelper.GetForType <T>(), D3D12_UAV_DIMENSION_TEXTURE2D, D3D12CpuDescriptorHandle); break; } this.d3D12Resource.Get()->SetName(this); }
/// <summary> /// Creates a new <see cref="Buffer{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/> associated with the current instance.</param> /// <param name="length">The number of items to store in the current buffer.</param> /// <param name="elementSizeInBytes">The size in bytes of each buffer item (including padding, if any).</param> /// <param name="resourceType">The resource type for the current buffer.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected Buffer(GraphicsDevice device, int length, uint elementSizeInBytes, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); if (resourceType == ResourceType.Constant) { Guard.IsBetweenOrEqualTo(length, 1, D3D12.D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT, nameof(length)); } else { // The maximum length is set such that the aligned buffer size can't exceed uint.MaxValue Guard.IsBetweenOrEqualTo(length, 1, (uint.MaxValue / elementSizeInBytes) & ~255, nameof(length)); } if (TypeInfo <T> .IsDoubleOrContainsDoubles && device.D3D12Device->CheckFeatureSupport <D3D12_FEATURE_DATA_D3D12_OPTIONS>(D3D12_FEATURE_D3D12_OPTIONS).DoublePrecisionFloatShaderOps == 0) { UnsupportedDoubleOperationsException.Throw <T>(); } nint usableSizeInBytes = checked ((nint)(length * elementSizeInBytes)); nint effectiveSizeInBytes = resourceType == ResourceType.Constant ? AlignmentHelper.Pad(usableSizeInBytes, D3D12.D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT) : usableSizeInBytes; SizeInBytes = usableSizeInBytes; GraphicsDevice = device; Length = length; #if NET6_0_OR_GREATER this.allocation = device.Allocator->CreateResource(device.Pool, resourceType, allocationMode, (ulong)effectiveSizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); #else this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, (ulong)effectiveSizeInBytes, device.IsCacheCoherentUMA); #endif device.RegisterAllocatedResource(); device.RentShaderResourceViewDescriptorHandles(out this.d3D12ResourceDescriptorHandles); device.RentShaderResourceViewDescriptorHandles(out this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView); switch (resourceType) { case ResourceType.Constant: device.D3D12Device->CreateConstantBufferView(this.d3D12Resource.Get(), effectiveSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); break; case ResourceType.ReadOnly: device.D3D12Device->CreateShaderResourceView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); break; case ResourceType.ReadWrite: device.D3D12Device->CreateUnorderedAccessView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, this.d3D12ResourceDescriptorHandles.D3D12CpuDescriptorHandle); device.D3D12Device->CreateUnorderedAccessViewForClear( this.d3D12Resource.Get(), DXGI_FORMAT_R32_UINT, (uint)(usableSizeInBytes / sizeof(uint)), this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView.D3D12CpuDescriptorHandle, this.d3D12ResourceDescriptorHandlesForTypedUnorderedAccessView.D3D12CpuDescriptorHandleNonShaderVisible); break; } this.d3D12Resource.Get()->SetName(this); }
/// <summary> /// Creates a new <see cref="TransferTexture2D{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="ComputeSharp.GraphicsDevice"/> associated with the current instance.</param> /// <param name="height">The height of the texture.</param> /// <param name="width">The width of the texture.</param> /// <param name="resourceType">The resource type for the current texture.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected TransferTexture2D(GraphicsDevice device, int width, int height, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); Guard.IsBetweenOrEqualTo(width, 1, FX.D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, FX.D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION, nameof(height)); if (!device.D3D12Device->IsDxgiFormatSupported(DXGIFormatHelper.GetForType <T>(), D3D12_FORMAT_SUPPORT1_TEXTURE2D)) { UnsupportedTextureTypeException.ThrowForTexture2D <T>(); } GraphicsDevice = device; device.D3D12Device->GetCopyableFootprint( DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, out this.d3D12PlacedSubresourceFootprint, out _, out ulong totalSizeInBytes); if (device.IsCacheCoherentUMA) { this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, allocationMode, totalSizeInBytes, true); } else { this.allocation = device.Allocator->CreateResource(resourceType, allocationMode, totalSizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); } this.mappedData = (T *)this.d3D12Resource.Get()->Map().Pointer; this.d3D12Resource.Get()->SetName(this); }
/// <summary> /// Creates a new <see cref="StructuredBuffer{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/> associated with the current instance.</param> /// <param name="length">The number of items to store in the current buffer.</param> /// <param name="resourceType">The buffer type for the current buffer.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected unsafe StructuredBuffer(GraphicsDevice device, int length, ResourceType resourceType, AllocationMode allocationMode) : base(device, length, (uint)sizeof(T), resourceType, allocationMode) { }
/// <summary> /// Creates a new <see cref="Buffer{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="GraphicsDevice"/> associated with the current instance.</param> /// <param name="length">The number of items to store in the current buffer.</param> /// <param name="elementSizeInBytes">The size in bytes of each buffer item (including padding, if any).</param> /// <param name="resourceType">The resource type for the current buffer.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected Buffer(GraphicsDevice device, int length, uint elementSizeInBytes, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); if (resourceType == ResourceType.Constant) { Guard.IsBetweenOrEqualTo(length, 1, FX.D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT, nameof(length)); } else { // The maximum length is set such that the aligned buffer size can't exceed uint.MaxValue Guard.IsBetweenOrEqualTo(length, 1, (uint.MaxValue / elementSizeInBytes) & ~255, nameof(length)); } SizeInBytes = checked ((nint)(length * elementSizeInBytes)); GraphicsDevice = device; Length = length; if (device.IsCacheCoherentUMA) { this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, allocationMode, (ulong)SizeInBytes, true); } else { this.allocation = device.Allocator->CreateResource(resourceType, allocationMode, (ulong)SizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); } device.RentShaderResourceViewDescriptorHandles(out D3D12CpuDescriptorHandle, out D3D12GpuDescriptorHandle); switch (resourceType) { case ResourceType.Constant: device.D3D12Device->CreateConstantBufferView(this.d3D12Resource.Get(), SizeInBytes, D3D12CpuDescriptorHandle); break; case ResourceType.ReadOnly: device.D3D12Device->CreateShaderResourceView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, D3D12CpuDescriptorHandle); break; case ResourceType.ReadWrite: device.D3D12Device->CreateUnorderedAccessView(this.d3D12Resource.Get(), (uint)length, elementSizeInBytes, D3D12CpuDescriptorHandle); break; } this.d3D12Resource.Get()->SetName(this); }
/// <summary> /// Creates a new <see cref="TransferTexture3D{T}"/> instance with the specified parameters. /// </summary> /// <param name="device">The <see cref="ComputeSharp.GraphicsDevice"/> associated with the current instance.</param> /// <param name="height">The height of the texture.</param> /// <param name="width">The width of the texture.</param> /// <param name="depth">The depth of the texture.</param> /// <param name="resourceType">The resource type for the current texture.</param> /// <param name="allocationMode">The allocation mode to use for the new resource.</param> private protected TransferTexture3D(GraphicsDevice device, int width, int height, int depth, ResourceType resourceType, AllocationMode allocationMode) { device.ThrowIfDisposed(); Guard.IsBetweenOrEqualTo(width, 1, D3D12.D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION); Guard.IsBetweenOrEqualTo(height, 1, D3D12.D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION); Guard.IsBetweenOrEqualTo(depth, 1, D3D12.D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION); if (!device.D3D12Device->IsDxgiFormatSupported(DXGIFormatHelper.GetForType <T>(), D3D12_FORMAT_SUPPORT1_TEXTURE3D)) { UnsupportedTextureTypeException.ThrowForTexture3D <T>(); } GraphicsDevice = device; device.D3D12Device->GetCopyableFootprint( DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, (ushort)depth, out this.d3D12PlacedSubresourceFootprint, out _, out ulong totalSizeInBytes); #if NET6_0_OR_GREATER this.allocation = device.Allocator->CreateResource(device.Pool, resourceType, allocationMode, totalSizeInBytes); this.d3D12Resource = new ComPtr <ID3D12Resource>(this.allocation.Get()->GetResource()); #else this.d3D12Resource = device.D3D12Device->CreateCommittedResource(resourceType, totalSizeInBytes, device.IsCacheCoherentUMA); #endif device.RegisterAllocatedResource(); this.mappedData = (T *)this.d3D12Resource.Get()->Map().Pointer; this.d3D12Resource.Get()->SetName(this); }