diff --git a/src/Generator/ApiData.cs b/src/Generator/ApiData.cs index 6a9d44a..ed9312d 100644 --- a/src/Generator/ApiData.cs +++ b/src/Generator/ApiData.cs @@ -60,6 +60,7 @@ public class ApiFunction { public string Name { get; set; } public bool SetLastError { get; set; } + public string DllImport { get; set; } public ApiDataType ReturnType { get; set; } public List ReturnAttrs { get; set; } diff --git a/src/Generator/Program.cs b/src/Generator/Program.cs index 8d70bb5..4059e9c 100644 --- a/src/Generator/Program.cs +++ b/src/Generator/Program.cs @@ -331,6 +331,7 @@ public static class Program GenerateConstants(writer, api); GenerateTypes(writer, api); + GenerateFunctions(writer, api); } private static void GenerateConstants(CodeWriter writer, ApiData api) @@ -516,6 +517,105 @@ public static class Program writer.WriteLine($"#endregion Com Types"); } + private static void GenerateFunctions(CodeWriter writer, ApiData api) + { + if (api.Functions.Length == 0) + return; + + writer.WriteLine($"#region Functions"); + using (writer.PushBlock($"public static unsafe partial class Apis")) + { + foreach (ApiFunction function in api.Functions) + { + if (function.Name.StartsWith("D3DX11") || + function.Name == "D3DDisassemble11Trace") + continue; + + WriteFunction(writer, api, function); + writer.WriteLine(); + } + } + + writer.WriteLine($"#endregion Functions"); + } + + private static void WriteFunction(CodeWriter writer, ApiData api, ApiFunction function) + { + string returnType = GetTypeName(function.ReturnType); + string functionSuffix = string.Empty; + + if (string.IsNullOrEmpty(function.DllImport) == false) + { + functionSuffix = "static extern "; + writer.WriteLine($"[DllImport(\"{function.DllImport}\", ExactSpelling = true)]"); + } + + StringBuilder argumentBuilder = new(); + StringBuilder argumentsTypesBuilder = new(); + StringBuilder argumentsNameBuilder = new(); + int parameterIndex = 0; + foreach (ApiParameter parameter in function.Params) + { + bool asPointer = false; + string parameterType = default; + if (parameter.Type.Kind == "ApiRef") + { + if (parameter.Type.TargetKind == "FunctionPointer") + { + var functionType = api.Types.First(item => item.Name == parameter.Type.Name && item.Kind == "FunctionPointer"); + parameterType = "delegate* unmanaged[Stdcall]"; + } + else + { + string fullTypeName = $"{parameter.Type.Api}.{parameter.Type.Name}"; + if (!IsEnum(fullTypeName)) + { + asPointer = true; + } + } + } + + if (string.IsNullOrEmpty(parameterType)) + { + parameterType = GetTypeName(parameter.Type, asPointer); + } + + parameterType = NormalizeTypeName(writer.Api, parameterType); + string parameterName = parameter.Name; + + bool isOptional = parameter.Attrs.Any(item => item is string str && str == "Optional"); + if (parameter.Attrs.Any(item => item is string str && str == "ComOutPtr")) + { + if (!IsPrimitive(parameter.Type)) + { + parameterType += "*"; + } + } + + argumentBuilder.Append(parameterType).Append(' ').Append(parameterName); + if (isOptional == true) + { + //argumentBuilder.Append(" = default"); + } + + argumentsTypesBuilder.Append(parameterType); + argumentsNameBuilder.Append(parameterName); + + if (parameterIndex < function.Params.Count - 1) + { + argumentBuilder.Append(", "); + argumentsTypesBuilder.Append(", "); + argumentsNameBuilder.Append(", "); + } + + parameterIndex++; + } + + string argumentsString = argumentBuilder.ToString(); + writer.Write($"public {functionSuffix}{returnType} {function.Name}({argumentsString})"); + writer.WriteLine(";"); + } + private static void GenerateEnum(CodeWriter writer, ApiType enumType, bool autoGenerated) { string csTypeName = GetDataTypeName(enumType.Name, out string enumPrefix); diff --git a/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs b/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs index 22c6fb3..a6136a7 100644 --- a/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs +++ b/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs @@ -39829,3 +39829,14 @@ public unsafe partial struct ID3DX11FFT : ID3DX11FFT.Interface } #endregion Com Types +#region Functions +public static unsafe partial class Apis +{ + [DllImport("d3d11", ExactSpelling = true)] + public static extern HResult D3D11CreateDevice(Graphics.Dxgi.IDXGIAdapter* pAdapter, Graphics.Direct3D.DriverType DriverType, IntPtr Software, CreateDeviceFlag Flags, Graphics.Direct3D.FeatureLevel* pFeatureLevels, uint FeatureLevels, uint SDKVersion, ID3D11Device** ppDevice, Graphics.Direct3D.FeatureLevel* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext); + + [DllImport("d3d11", ExactSpelling = true)] + public static extern HResult D3D11CreateDeviceAndSwapChain(Graphics.Dxgi.IDXGIAdapter* pAdapter, Graphics.Direct3D.DriverType DriverType, IntPtr Software, CreateDeviceFlag Flags, Graphics.Direct3D.FeatureLevel* pFeatureLevels, uint FeatureLevels, uint SDKVersion, Graphics.Dxgi.SwapChainDescription* pSwapChainDesc, Graphics.Dxgi.IDXGISwapChain** ppSwapChain, ID3D11Device** ppDevice, Graphics.Direct3D.FeatureLevel* pFeatureLevel, ID3D11DeviceContext** ppImmediateContext); + +} +#endregion Functions diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi.cs index e50ee4e..030c041 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi.cs @@ -14212,3 +14212,23 @@ public unsafe partial struct IDXGraphicsAnalysis : IDXGraphicsAnalysis.Interface } #endregion Com Types +#region Functions +public static unsafe partial class Apis +{ + [DllImport("dxgi", ExactSpelling = true)] + public static extern HResult CreateDXGIFactory(Guid* riid, void** ppFactory); + + [DllImport("dxgi", ExactSpelling = true)] + public static extern HResult CreateDXGIFactory1(Guid* riid, void** ppFactory); + + [DllImport("dxgi", ExactSpelling = true)] + public static extern HResult CreateDXGIFactory2(uint Flags, Guid* riid, void** ppFactory); + + [DllImport("dxgi", ExactSpelling = true)] + public static extern HResult DXGIGetDebugInterface1(uint Flags, Guid* riid, void** pDebug); + + [DllImport("dxgi", ExactSpelling = true)] + public static extern HResult DXGIDeclareAdapterRemovalSupport(); + +} +#endregion Functions diff --git a/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs b/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs index f06dc54..dd2e729 100644 --- a/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs +++ b/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs @@ -2,6 +2,8 @@ // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. using System.Runtime.CompilerServices; +using Win32.Graphics.Direct3D; +using Win32.Graphics.Dxgi; using static Win32.Graphics.Dxgi.Apis; using static Win32.StringUtilities; @@ -55,3 +57,31 @@ public partial struct AuthenticatedProtectionFlags } } } + +public static unsafe partial class Apis +{ + public static HResult D3D11CreateDevice( + IDXGIAdapter* pAdapter, + DriverType driverType, + CreateDeviceFlag flags, + ReadOnlySpan featureLevels, + ID3D11Device** ppDevice, + FeatureLevel* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext) + { + fixed (FeatureLevel* pfeatureLevels = featureLevels) + { + return D3D11CreateDevice( + pAdapter, + driverType, + IntPtr.Zero, + flags, + pfeatureLevels, + (uint)featureLevels.Length, + D3D11_SDK_VERSION, + ppDevice, + pFeatureLevel, + ppImmediateContext); + } + } +} diff --git a/src/samples/01-ClearScreen/Program.cs b/src/samples/01-ClearScreen/Program.cs index aaa51b7..3ae4c8d 100644 --- a/src/samples/01-ClearScreen/Program.cs +++ b/src/samples/01-ClearScreen/Program.cs @@ -1,10 +1,15 @@ // Copyright © Amer Koleci and Contributors. // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. +using System.Reflection; using System.Runtime.InteropServices; using Win32; using Win32.Graphics.Dxgi; +using Win32.Graphics.Direct3D11; using static Win32.Apis; +using static Win32.Graphics.Dxgi.Apis; +using static Win32.Graphics.Direct3D11.Apis; +using Win32.Graphics.Direct3D; namespace ClearScreen; @@ -19,7 +24,7 @@ public static unsafe class Program using ComPtr factory5 = default; if (factory.CopyTo(&factory5).Success) { - Bool32 isTearingSupported = factory5.Get()->CheckFeatureSupport(Feature.PresentAllowTearing); + bool isTearingSupported = factory5.Get()->CheckFeatureSupport(Win32.Graphics.Dxgi.Feature.PresentAllowTearing); } } @@ -39,21 +44,47 @@ public static unsafe class Program AdapterDescription1 desc = default; adapter.Get()->GetDesc1(&desc); - string name = desc.DescriptionStr; + if ((desc.Flags & AdapterFlags.Software) != AdapterFlags.None) + continue; + + break; + //string name = desc.DescriptionStr; } } - for (uint adapterIndex = 0; + if (adapter.Get() == null) + { + for (uint adapterIndex = 0; factory.Get()->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()).Success; adapterIndex++) - { - AdapterDescription1 desc = default; - adapter.Get()->GetDesc1(&desc); + { + AdapterDescription1 desc = default; + adapter.Get()->GetDesc1(&desc); - string name = desc.DescriptionStr; + if ((desc.Flags & AdapterFlags.Software) != AdapterFlags.None) + continue; + + //string name = desc.DescriptionStr; + break; + } } - } - [DllImport("dxgi", ExactSpelling = true)] - public static extern HResult CreateDXGIFactory1(Guid* riid, void** ppFactory); + ReadOnlySpan featureLevels = stackalloc FeatureLevel[1] + { + FeatureLevel.Level_11_0 + }; + + using ComPtr d3dDevice = default; + FeatureLevel featureLevel; + using ComPtr immediateContext = default; + + D3D11CreateDevice( + (IDXGIAdapter*)adapter.Get(), + DriverType.Hardware, + CreateDeviceFlag.None, + featureLevels, + d3dDevice.GetAddressOf(), + &featureLevel, + immediateContext.GetAddressOf()).ThrowIfFailed(); + } }