Skip to content

Commit 86dc363

Browse files
authored
Merge pull request #558 from Sergio0694/dev/remove-D3DCompiler-allocations
Remove string allocation in ID3DIncludeForD2DHelpers.Open
2 parents f28fdd0 + a23b438 commit 86dc363

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/ComputeSharp.D2D1/Shaders/Translation/D3DCompiler.ID3DInclude.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
using System;
12
using System.Runtime.CompilerServices;
23
using System.Runtime.InteropServices;
34
using TerraFX.Interop.DirectX;
45
using TerraFX.Interop.Windows;
5-
#if !NET6_0_OR_GREATER
6+
#if NET6_0_OR_GREATER
7+
using MemoryMarshal2 = System.Runtime.InteropServices.MemoryMarshal;
8+
#else
9+
using MemoryMarshal2 = ComputeSharp.NetStandard.MemoryMarshal;
610
using RuntimeHelpers = ComputeSharp.NetStandard.RuntimeHelpers;
711
#endif
812

@@ -82,7 +86,9 @@ private unsafe struct ID3DIncludeForD2DHelpers
8286
[UnmanagedCallersOnly]
8387
public static int Open(ID3DIncludeForD2DHelpers* @this, D3D_INCLUDE_TYPE IncludeType, sbyte* pFileName, void* pParentData, void** ppData, uint* pBytes)
8488
{
85-
if (new string(pFileName) == "d2d1effecthelpers.hlsli")
89+
ReadOnlySpan<byte> fileName = MemoryMarshal2.CreateReadOnlySpanFromNullTerminated((byte*)pFileName);
90+
91+
if (fileName.SequenceEqual("d2d1effecthelpers.hlsli"u8))
8692
{
8793
*ppData = (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(D2D1EffectHelpers.TextUtf8));
8894
*pBytes = (uint)D2D1EffectHelpers.TextUtf8.Length;

src/ComputeSharp.NetStandard/System/Runtime/InteropServices/MemoryMarshal.cs

+21
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,25 @@ public static ref T GetArrayDataReference<T>(T[] array)
1818
{
1919
return ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(array.AsSpan());
2020
}
21+
22+
/// <summary>
23+
/// Creates a new read-only span for a <see langword="null"/>-terminated UTF-8 string.
24+
/// </summary>
25+
/// <param name="value">The pointer to the <see langword="null"/>-terminated string of bytes.</param>
26+
/// <returns>A read-only span representing the specified <see langword="null"/>-terminated string, or an empty span if the pointer is <see langword="null"/>.</returns>
27+
/// <remarks>The returned span does not include the <see langword="null"/> terminator, nor does it validate the well-formedness of the UTF-8 data.</remarks>
28+
/// <exception cref="ArgumentException">The string is longer than <see cref="int.MaxValue"/>.</exception>
29+
public static unsafe ReadOnlySpan<byte> CreateReadOnlySpanFromNullTerminated(byte* value)
30+
{
31+
for (int i = 0; i < int.MaxValue; i++)
32+
{
33+
// Stop when the null-terminator has been found
34+
if (value[i] == 0)
35+
{
36+
return new(value, i);
37+
}
38+
}
39+
40+
throw new ArgumentException("The string must be null-terminated.");
41+
}
2142
}

0 commit comments

Comments
 (0)