mirror of
https://github.com/amerkoleci/Vortice.Win32.git
synced 2026-01-14 08:06:02 +08:00
WIP: Some test for string marshalling (based on TerraFX)
This commit is contained in:
@@ -2,9 +2,66 @@
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||
|
||||
using static Win32.Graphics.Dxgi.Apis;
|
||||
using static Win32.StringUtilities;
|
||||
|
||||
namespace Win32.Graphics.Dxgi;
|
||||
|
||||
public unsafe partial struct AdapterDescription
|
||||
{
|
||||
/// <include file='../Generated/DXGI.xml' path='doc/member[@name="DXGI_ADAPTER_DESC::Description"]/*' />
|
||||
public readonly string DescriptionStr
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (ushort* ptr = Description)
|
||||
{
|
||||
return GetString(ptr, 128) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe partial struct AdapterDescription1
|
||||
{
|
||||
/// <include file='../Generated/DXGI.xml' path='doc/member[@name="DXGI_ADAPTER_DESC1::Description"]/*' />
|
||||
public readonly string DescriptionStr
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (ushort* ptr = Description)
|
||||
{
|
||||
return GetString(ptr, 128) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe partial struct AdapterDescription2
|
||||
{
|
||||
public readonly ReadOnlySpan<ushort> DescriptionSpan
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (ushort* ptr = Description)
|
||||
{
|
||||
return GetUtf16Span(ptr, 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='../Generated/DXGI.xml' path='doc/member[@name="DXGI_ADAPTER_DESC2::Description"]/*' />
|
||||
public readonly string DescriptionStr
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (ushort* ptr = Description)
|
||||
{
|
||||
return GetString(ptr, 128) ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe partial struct IDXGIFactory5
|
||||
{
|
||||
public TFeature CheckFeatureSupport<TFeature>(Feature feature)
|
||||
|
||||
@@ -23,6 +23,17 @@ internal static class MemoryMarshal
|
||||
return ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(span);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a reference to the 0th element of <paramref name="array"/>. If the array is empty, returns a reference
|
||||
/// to where the 0th element would have been stored. Such a reference may be used for pinning but must never be dereferenced.
|
||||
/// </summary>
|
||||
/// <exception cref="NullReferenceException"><paramref name="array"/> is <see langword="null"/>.</exception>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetArrayDataReference<T>(T[] array)
|
||||
{
|
||||
return ref global::System.Runtime.InteropServices.MemoryMarshal.GetReference(array.AsSpan());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="Span{T}"/> from a given reference.
|
||||
/// </summary>
|
||||
@@ -34,6 +45,18 @@ internal static class MemoryMarshal
|
||||
{
|
||||
return new(Unsafe.AsPointer(ref value), length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="ReadOnlySpan{T}"/> from a given reference.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of reference to wrap.</typeparam>
|
||||
/// <param name="value">The target reference.</param>
|
||||
/// <param name="length">The length of the <see cref="Span{T}"/> to create.</param>
|
||||
/// <returns>A new <see cref="Span{T}"/> wrapping <paramref name="value"/>.</returns>
|
||||
public static unsafe ReadOnlySpan<T> CreateReadOnlySpan<T>(ref T value, int length)
|
||||
{
|
||||
return new(Unsafe.AsPointer(ref value), length);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
176
src/Vortice.Win32/StringUtilities.cs
Normal file
176
src/Vortice.Win32/StringUtilities.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright © Amer Koleci and Contributors.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||
// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using static Win32.UnsafeUtilities;
|
||||
|
||||
namespace Win32;
|
||||
|
||||
/// <summary>
|
||||
/// Provides a set of methods to supplement for <see cref="string" />.
|
||||
/// </summary>
|
||||
public static unsafe class StringUtilities
|
||||
{
|
||||
public static string? GetString(sbyte* pointer, int maxLength = -1)
|
||||
{
|
||||
return GetUtf8Span(pointer, maxLength).GetString();
|
||||
}
|
||||
|
||||
public static string? GetString(ushort* pointer, int maxLength = -1)
|
||||
{
|
||||
return GetUtf16Span(pointer, maxLength).GetString();
|
||||
}
|
||||
|
||||
/// <summary>Gets a null-terminated sequence of UTF8 characters for a string.</summary>
|
||||
/// <param name="source">The string for which to get the null-terminated UTF8 character sequence.</param>
|
||||
/// <returns>A null-terminated UTF8 character sequence created from <paramref name="source" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<sbyte> GetUtf8Span(this string? source)
|
||||
{
|
||||
ReadOnlySpan<byte> result;
|
||||
|
||||
if (source is not null)
|
||||
{
|
||||
int maxLength = Encoding.UTF8.GetMaxByteCount(source.Length);
|
||||
#if NET6_0_OR_GREATER
|
||||
var bytes = new byte[maxLength + 1];
|
||||
var length = Encoding.UTF8.GetBytes(source, bytes);
|
||||
result = bytes.AsSpan(0, length);
|
||||
#else
|
||||
byte* bytes = stackalloc byte[maxLength + 1];
|
||||
fixed (char* namePtr = source)
|
||||
{
|
||||
Encoding.UTF8.GetBytes(namePtr, source.Length, bytes, maxLength);
|
||||
}
|
||||
bytes[maxLength] = 0;
|
||||
result = new(bytes, source.Length);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result.As<byte, sbyte>();
|
||||
}
|
||||
|
||||
/// <summary>Gets a span for a null-terminated UTF8 character sequence.</summary>
|
||||
/// <param name="source">The pointer to a null-terminated UTF8 character sequence.</param>
|
||||
/// <param name="maxLength">The maxmimum length of <paramref name="source" /> or <c>-1</c> if the maximum length is unknown.</param>
|
||||
/// <returns>A span that starts at <paramref name="source" /> and extends to <paramref name="maxLength" /> or the first null character, whichever comes first.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<sbyte> GetUtf8Span(sbyte* source, int maxLength = -1)
|
||||
=> (source != null) ? GetUtf8Span(in source[0], maxLength) : null;
|
||||
|
||||
/// <summary>Gets a span for a null-terminated UTF8 character sequence.</summary>
|
||||
/// <param name="source">The reference to a null-terminated UTF8 character sequence.</param>
|
||||
/// <param name="maxLength">The maxmimum length of <paramref name="source" /> or <c>-1</c> if the maximum length is unknown.</param>
|
||||
/// <returns>A span that starts at <paramref name="source" /> and extends to <paramref name="maxLength" /> or the first null character, whichever comes first.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<sbyte> GetUtf8Span(in sbyte source, int maxLength = -1)
|
||||
{
|
||||
ReadOnlySpan<sbyte> result;
|
||||
|
||||
if (!IsNullRef(in source))
|
||||
{
|
||||
if (maxLength < 0)
|
||||
{
|
||||
maxLength = int.MaxValue;
|
||||
}
|
||||
|
||||
result = CreateReadOnlySpan(in source, maxLength);
|
||||
var length = result.IndexOf((sbyte)'\0');
|
||||
|
||||
if (length != -1)
|
||||
{
|
||||
result = result.Slice(0, length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Gets a null-terminated sequence of UTF16 characters for a string.</summary>
|
||||
/// <param name="source">The string for which to get the null-terminated UTF16 character sequence.</param>
|
||||
/// <returns>A null-terminated UTF16 character sequence created from <paramref name="source" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<ushort> GetUtf16Span(this string? source) => source.AsSpan().As<char, ushort>();
|
||||
|
||||
/// <summary>Marshals a null-terminated UTF16 string to a <see cref="ReadOnlySpan{UInt16}" />.</summary>
|
||||
/// <param name="source">The pointer to a null-terminated UTF16 string.</param>
|
||||
/// <param name="maxLength">The maxmimum length of <paramref name="source" /> or <c>-1</c> if the maximum length is unknown.</param>
|
||||
/// <returns>A <see cref="ReadOnlySpan{UInt16}" /> that starts at <paramref name="source" /> and extends to <paramref name="maxLength" /> or the first null character, whichever comes first.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<ushort> GetUtf16Span(ushort* source, int maxLength = -1)
|
||||
=> (source != null) ? GetUtf16Span(in source[0], maxLength) : null;
|
||||
|
||||
/// <summary>Marshals a null-terminated UTF16 string to a <see cref="ReadOnlySpan{UInt16}" />.</summary>
|
||||
/// <param name="source">The reference to a null-terminated UTF16 string.</param>
|
||||
/// <param name="maxLength">The maxmimum length of <paramref name="source" /> or <c>-1</c> if the maximum length is unknown.</param>
|
||||
/// <returns>A <see cref="ReadOnlySpan{UInt16}" /> that starts at <paramref name="source" /> and extends to <paramref name="maxLength" /> or the first null character, whichever comes first.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<ushort> GetUtf16Span(in ushort source, int maxLength = -1)
|
||||
{
|
||||
ReadOnlySpan<ushort> result;
|
||||
|
||||
if (!IsNullRef(in source))
|
||||
{
|
||||
if (maxLength < 0)
|
||||
{
|
||||
maxLength = int.MaxValue;
|
||||
}
|
||||
|
||||
result = CreateReadOnlySpan(in source, maxLength);
|
||||
var length = result.IndexOf('\0');
|
||||
|
||||
if (length != -1)
|
||||
{
|
||||
result = result.Slice(0, length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Gets a string for a given span.</summary>
|
||||
/// <param name="span">The span for which to create the string.</param>
|
||||
/// <returns>A string created from <paramref name="span" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static string? GetString(this ReadOnlySpan<ushort> span)
|
||||
{
|
||||
if (span.GetPointer() == null)
|
||||
return null;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
return new string(span.As<ushort, char>());
|
||||
#else
|
||||
return new string(span.As<ushort, char>().GetPointer(), 0, span.Length);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Gets a string for a given span.</summary>
|
||||
/// <param name="span">The span for which to create the string.</param>
|
||||
/// <returns>A string created from <paramref name="span" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static string? GetString(this ReadOnlySpan<sbyte> span)
|
||||
{
|
||||
if (span.GetPointer() == null)
|
||||
return null;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
return Encoding.UTF8.GetString(span.As<sbyte, byte>());
|
||||
#else
|
||||
return Encoding.UTF8.GetString(span.As<sbyte, byte>().GetPointer(), span.Length);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
171
src/Vortice.Win32/UnsafeUtilities.cs
Normal file
171
src/Vortice.Win32/UnsafeUtilities.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information.
|
||||
// Copyright © Amer Koleci and Contributors.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#if !NET6_0_OR_GREATER
|
||||
using MemoryMarshal = Win32.MemoryMarshal;
|
||||
#endif
|
||||
|
||||
namespace Win32;
|
||||
|
||||
/// <summary>Provides a set of methods to supplement or replace <see cref="Unsafe" /> and <see cref="MemoryMarshal" />.</summary>
|
||||
public static unsafe class UnsafeUtilities
|
||||
{
|
||||
/// <inheritdoc cref="Unsafe.As{T}(object)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
#if NET6_0_OR_GREATER
|
||||
[return: NotNullIfNotNull("o")]
|
||||
#endif
|
||||
public static T? As<T>(this object? o)
|
||||
where T : class?
|
||||
{
|
||||
//Assert(o is null or T);
|
||||
return Unsafe.As<T>(o);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Unsafe.As{TFrom, TTo}(ref TFrom)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref TTo As<TFrom, TTo>(ref TFrom source)
|
||||
=> ref Unsafe.As<TFrom, TTo>(ref source);
|
||||
|
||||
/// <inheritdoc cref="Unsafe.As{TFrom, TTo}(ref TFrom)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Span<TTo> As<TFrom, TTo>(this Span<TFrom> span)
|
||||
where TFrom : unmanaged
|
||||
where TTo : unmanaged
|
||||
{
|
||||
//Assert(AssertionsEnabled && (SizeOf<TFrom>() == SizeOf<TTo>()));
|
||||
return CreateSpan(ref As<TFrom, TTo>(ref span.GetReference()), span.Length);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Unsafe.As{TFrom, TTo}(ref TFrom)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<TTo> As<TFrom, TTo>(this ReadOnlySpan<TFrom> span)
|
||||
where TFrom : unmanaged
|
||||
where TTo : unmanaged
|
||||
{
|
||||
//Assert(AssertionsEnabled && (SizeOf<TFrom>() == SizeOf<TTo>()));
|
||||
return CreateReadOnlySpan(in AsReadOnly<TFrom, TTo>(in span.GetReference()), span.Length);
|
||||
}
|
||||
|
||||
/// <summary>Reinterprets the given native integer as a reference.</summary>
|
||||
/// <typeparam name="T">The type of the reference.</typeparam>
|
||||
/// <param name="source">The native integer to reinterpret.</param>
|
||||
/// <returns>A reference to a value of type <typeparamref name="T" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(nint source) => ref Unsafe.AsRef<T>((void*)source);
|
||||
|
||||
/// <summary>Reinterprets the given native unsigned integer as a reference.</summary>
|
||||
/// <typeparam name="T">The type of the reference.</typeparam>
|
||||
/// <param name="source">The native unsigned integer to reinterpret.</param>
|
||||
/// <returns>A reference to a value of type <typeparamref name="T" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(nuint source) => ref Unsafe.AsRef<T>((void*)source);
|
||||
|
||||
/// <inheritdoc cref="Unsafe.AsRef{T}(in T)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(in T source) => ref Unsafe.AsRef(in source);
|
||||
|
||||
/// <inheritdoc cref="Unsafe.AsRef{T}(in T)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref TTo AsRef<TFrom, TTo>(in TFrom source)
|
||||
{
|
||||
ref var mutable = ref AsRef(in source);
|
||||
return ref As<TFrom, TTo>(ref mutable);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Unsafe.AsPointer{T}(ref T)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T* AsPointer<T>(ref T source)
|
||||
where T : unmanaged => (T*)Unsafe.AsPointer(ref source);
|
||||
|
||||
/// <inheritdoc cref="Unsafe.As{TFrom, TTo}(ref TFrom)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref readonly TTo AsReadOnly<TFrom, TTo>(in TFrom source)
|
||||
=> ref Unsafe.As<TFrom, TTo>(ref AsRef(in source));
|
||||
|
||||
/// <inheritdoc cref="Unsafe.AsPointer{T}(ref T)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T* AsReadOnlyPointer<T>(in T source)
|
||||
where T : unmanaged => AsPointer(ref AsRef(in source));
|
||||
|
||||
/// <inheritdoc cref="Unsafe.AsRef{T}(void*)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T AsRef<T>(void* source) => ref Unsafe.AsRef<T>(source);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetArrayDataReference{T}(T[])" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this T[] array) => ref MemoryMarshal.GetArrayDataReference(array);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetArrayDataReference{T}(T[])" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this T[] array, int index) => ref Unsafe.Add(ref array.GetReference(), index);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetArrayDataReference{T}(T[])" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this T[] array, nuint index) => ref Unsafe.Add(ref array.GetReference(), index);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(Span{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this Span<T> span) => ref MemoryMarshal.GetReference(span);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(Span{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this Span<T> span, int index) => ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(Span{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetReference<T>(this Span<T> span, nuint index) => ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(ReadOnlySpan{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref readonly T GetReference<T>(this ReadOnlySpan<T> span) => ref MemoryMarshal.GetReference(span);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(ReadOnlySpan{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref readonly T GetReference<T>(this ReadOnlySpan<T> span, int index) => ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.GetReference{T}(ReadOnlySpan{T})" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref readonly T GetReference<T>(this ReadOnlySpan<T> span, nuint index) => ref Unsafe.Add(ref MemoryMarshal.GetReference(span), index);
|
||||
|
||||
/// <summary>Determines if a given reference to a value of type <typeparamref name="T" /> is not a null reference.</summary>
|
||||
/// <typeparam name="T">The type of the reference</typeparam>
|
||||
/// <param name="source">The reference to check.</param>
|
||||
/// <returns><c>true</c> if <paramref name="source" /> is not a null reference; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsNotNullRef<T>(in T source) => !IsNullRef(in source);
|
||||
|
||||
/// <inheritdoc cref="Unsafe.IsNullRef{T}(ref T)" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsNullRef<T>(in T source) => Unsafe.IsNullRef(ref AsRef(in source));
|
||||
|
||||
/// <inheritdoc cref="Unsafe.NullRef{T}" />
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T NullRef<T>() => ref Unsafe.NullRef<T>();
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.CreateSpan{T}(ref T, int)" />
|
||||
public static Span<T> CreateSpan<T>(ref T reference, int length) => MemoryMarshal.CreateSpan(ref reference, length);
|
||||
|
||||
/// <inheritdoc cref="MemoryMarshal.CreateReadOnlySpan{T}(ref T, int)" />
|
||||
public static ReadOnlySpan<T> CreateReadOnlySpan<T>(in T reference, int length) => MemoryMarshal.CreateReadOnlySpan(ref AsRef(in reference), length);
|
||||
|
||||
/// <summary>Returns a pointer to the element of the span at index zero.</summary>
|
||||
/// <typeparam name="T">The type of items in <paramref name="span" />.</typeparam>
|
||||
/// <param name="span">The span from which the pointer is retrieved.</param>
|
||||
/// <returns>A pointer to the item at index zero of <paramref name="span" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T* GetPointer<T>(this Span<T> span)
|
||||
where T : unmanaged => AsPointer(ref span.GetReference());
|
||||
|
||||
/// <summary>Returns a pointer to the element of the span at index zero.</summary>
|
||||
/// <typeparam name="T">The type of items in <paramref name="span" />.</typeparam>
|
||||
/// <param name="span">The span from which the pointer is retrieved.</param>
|
||||
/// <returns>A pointer to the item at index zero of <paramref name="span" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T* GetPointer<T>(this ReadOnlySpan<T> span)
|
||||
where T : unmanaged => AsPointer(ref AsRef(in span.GetReference()));
|
||||
}
|
||||
@@ -12,6 +12,9 @@ public static unsafe class Program
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
string test = StringUtilities.GetString(new sbyte[] { (sbyte)'A', (sbyte)'B', (sbyte)'C' });
|
||||
test = StringUtilities.GetString(new ushort[] { 'A', 'B', 'C' });
|
||||
|
||||
using ComPtr<IDXGIFactory1> factory = default;
|
||||
HResult hr = CreateDXGIFactory1(__uuidof<IDXGIFactory4>(), (void**)&factory);
|
||||
|
||||
@@ -24,15 +27,34 @@ public static unsafe class Program
|
||||
}
|
||||
|
||||
using ComPtr<IDXGIAdapter1> adapter = default;
|
||||
|
||||
using ComPtr<IDXGIFactory6> factory6 = default;
|
||||
if (factory.CopyTo(&factory6).Success)
|
||||
{
|
||||
for (uint adapterIndex = 0;
|
||||
factory6.Get()->EnumAdapterByGpuPreference(
|
||||
adapterIndex,
|
||||
GpuPreference.HighPerformance,
|
||||
__uuidof<IDXGIAdapter1>(),
|
||||
(void**)adapter.ReleaseAndGetAddressOf()).Success;
|
||||
adapterIndex++)
|
||||
{
|
||||
AdapterDescription1 desc = default;
|
||||
adapter.Get()->GetDesc1(&desc);
|
||||
|
||||
string name = desc.DescriptionStr;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint adapterIndex = 0;
|
||||
factory.Get()->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()).Success;
|
||||
adapterIndex++)
|
||||
{
|
||||
AdapterDescription1 desc = default;
|
||||
adapter.Get()->GetDesc1(&desc);
|
||||
|
||||
string name = desc.DescriptionStr;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[DllImport("dxgi", ExactSpelling = true)]
|
||||
|
||||
Reference in New Issue
Block a user