Skip to content

Commit

Permalink
Merge pull request #368 from Sergio0694/dev/transfer-buffer-double-su…
Browse files Browse the repository at this point in the history
…pport-checks

Add double feature support check to TransferBuffer<T> constructor
  • Loading branch information
Sergio0694 authored Aug 28, 2022
2 parents ca17662 + a850b1f commit 1da016a
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,7 @@ public static ReadWriteTexture3D<T, TPixel> AllocateReadWriteTexture3D<T, TPixel
/// <param name="length">The length of the buffer to allocate.</param>
/// <param name="allocationMode">The allocation mode to use for the new resource.</param>
/// <returns>A <see cref="ReadOnlyBuffer{T}"/> instance of size <paramref name="length"/>.</returns>
[RequiresUnreferencedCode("This method reads type info of all fields of the resource element type (recursively).")]
public static UploadBuffer<T> AllocateUploadBuffer<T>(this GraphicsDevice device, int length, AllocationMode allocationMode = AllocationMode.Default)
where T : unmanaged
{
Expand Down Expand Up @@ -1126,6 +1127,7 @@ public static UploadTexture3D<T> AllocateUploadTexture3D<T>(this GraphicsDevice
/// <param name="length">The length of the buffer to allocate.</param>
/// <param name="allocationMode">The allocation mode to use for the new resource.</param>
/// <returns>A <see cref="ReadBackBuffer{T}"/> instance of size <paramref name="length"/>.</returns>
[RequiresUnreferencedCode("This method reads type info of all fields of the resource element type (recursively).")]
public static ReadBackBuffer<T> AllocateReadBackBuffer<T>(this GraphicsDevice device, int length, AllocationMode allocationMode = AllocationMode.Default)
where T : unmanaged
{
Expand Down
10 changes: 10 additions & 0 deletions src/ComputeSharp/Graphics/Resources/Abstract/TransferBuffer{T}.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System;
using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using CommunityToolkit.Diagnostics;
using ComputeSharp.Exceptions;
using ComputeSharp.Graphics.Extensions;
using ComputeSharp.Graphics.Helpers;
using ComputeSharp.Interop;
using TerraFX.Interop.DirectX;
using TerraFX.Interop.Windows;
using static TerraFX.Interop.DirectX.D3D12_FEATURE;
using ResourceType = ComputeSharp.Graphics.Resources.Enums.ResourceType;

namespace ComputeSharp.Resources;
Expand Down Expand Up @@ -42,6 +45,7 @@ public abstract unsafe class TransferBuffer<T> : NativeObject, IGraphicsResource
/// <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>
[RequiresUnreferencedCode("This method reads type info of all fields of the resource element type (recursively).")]
private protected TransferBuffer(GraphicsDevice device, int length, ResourceType resourceType, AllocationMode allocationMode)
{
// The maximum length is set such that the aligned buffer size can't exceed uint.MaxValue
Expand All @@ -51,6 +55,12 @@ private protected TransferBuffer(GraphicsDevice device, int length, ResourceType

device.ThrowIfDeviceLost();

if (TypeInfo<T>.IsDoubleOrContainsDoubles &&
device.D3D12Device->CheckFeatureSupport<D3D12_FEATURE_DATA_D3D12_OPTIONS>(D3D12_FEATURE_D3D12_OPTIONS).DoublePrecisionFloatShaderOps == 0)
{
UnsupportedDoubleOperationException.Throw<T>();
}

GraphicsDevice = device;
Length = length;

Expand Down
2 changes: 2 additions & 0 deletions src/ComputeSharp/Graphics/Resources/ReadBackBuffer{T}.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using ComputeSharp.Graphics.Resources.Enums;
using ComputeSharp.Resources;
using ComputeSharp.Resources.Debug;
Expand All @@ -20,6 +21,7 @@ public sealed class ReadBackBuffer<T> : TransferBuffer<T>
/// <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="allocationMode">The allocation mode to use for the new resource.</param>
[RequiresUnreferencedCode("This method reads type info of all fields of the resource element type (recursively).")]
internal ReadBackBuffer(GraphicsDevice device, int length, AllocationMode allocationMode)
: base(device, length, ResourceType.ReadBack, allocationMode)
{
Expand Down
2 changes: 2 additions & 0 deletions src/ComputeSharp/Graphics/Resources/UploadBuffer{T}.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using ComputeSharp.Graphics.Resources.Enums;
using ComputeSharp.Resources;
using ComputeSharp.Resources.Debug;
Expand All @@ -20,6 +21,7 @@ public sealed class UploadBuffer<T> : TransferBuffer<T>
/// <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="allocationMode">The allocation mode to use for the new resource.</param>
[RequiresUnreferencedCode("This method reads type info of all fields of the resource element type (recursively).")]
internal UploadBuffer(GraphicsDevice device, int length, AllocationMode allocationMode)
: base(device, length, ResourceType.Upload, allocationMode)
{
Expand Down
19 changes: 18 additions & 1 deletion tests/ComputeSharp.Tests/BufferTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ public void Execute()
[Resource(typeof(ReadOnlyBuffer<>))]
[Resource(typeof(ReadWriteBuffer<>))]
[ExpectedException(typeof(UnsupportedDoubleOperationException))]
public void Dispatch_ReadWriteBuffer_DoublePrecision_ThrowsExceptionIfUnsupported(Device device, Type resourceType)
public void Dispatch_Buffer_DoublePrecision_ThrowsExceptionIfUnsupported(Device device, Type resourceType)
{
if (device.Get().IsDoublePrecisionSupportAvailable())
{
Expand All @@ -399,4 +399,21 @@ public void Dispatch_ReadWriteBuffer_DoublePrecision_ThrowsExceptionIfUnsupporte

Assert.Fail();
}

[CombinatorialTestMethod]
[AllDevices]
[Resource(typeof(UploadBuffer<>))]
[Resource(typeof(ReadBackBuffer<>))]
[ExpectedException(typeof(UnsupportedDoubleOperationException))]
public void Dispatch_TransferBuffer_DoublePrecision_ThrowsExceptionIfUnsupported(Device device, Type resourceType)
{
if (device.Get().IsDoublePrecisionSupportAvailable())
{
Assert.Inconclusive();
}

using TransferBuffer<double> buffer = device.Get().AllocateTransferBuffer<double>(resourceType, 32);

Assert.Fail();
}
}

0 comments on commit 1da016a

Please sign in to comment.