Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile Skia with Direct3D on Windows platform #2823

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
16 changes: 16 additions & 0 deletions binding/SkiaSharp/GRBackendRenderTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public GRBackendRenderTarget (int width, int height, int sampleCount, GRVkImageI
CreateVulkan (width, height, sampleCount, vkImageInfo);
}

public GRBackendRenderTarget (int width, int height, GRD3DTextureResourceInfo d3dTextureInfo)
: this (IntPtr.Zero, true)
{
CreateDirect3D (width, height, d3dTextureInfo);
}

#if __IOS__ || __MACOS__

public GRBackendRenderTarget (int width, int height, int sampleCount, GRMtlTextureInfo mtlInfo)
Expand Down Expand Up @@ -57,6 +63,16 @@ private void CreateVulkan (int width, int height, int sampleCount, GRVkImageInfo
}
}

private void CreateDirect3D (int width, int height, GRD3DTextureResourceInfo d3dTextureInfo)
{
var native = d3dTextureInfo.ToNative ();
Handle = SkiaApi.gr_backendrendertarget_new_direct3d (width, height, &native);

if (Handle == IntPtr.Zero) {
throw new InvalidOperationException ("Unable to create a new GRBackendRenderTarget instance.");
}
}

protected override void Dispose (bool disposing) =>
base.Dispose (disposing);

Expand Down
16 changes: 16 additions & 0 deletions binding/SkiaSharp/GRBackendTexture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public GRBackendTexture (int width, int height, GRVkImageInfo vkInfo)
CreateVulkan (width, height, vkInfo);
}

public GRBackendTexture (int width, int height, GRD3DTextureResourceInfo d3dTextureInfo)
: this (IntPtr.Zero, true)
{
CreateDirect3D (width, height, d3dTextureInfo);
}

public GRBackendTexture (int width, int height, bool mipmapped, GRMtlTextureInfo mtlInfo)
: this (IntPtr.Zero, true)
{
Expand Down Expand Up @@ -54,6 +60,16 @@ private void CreateVulkan (int width, int height, GRVkImageInfo vkInfo)
}
}

private void CreateDirect3D (int width, int height, GRD3DTextureResourceInfo d3dTextureInfo)
{
var native = d3dTextureInfo.ToNative ();
Handle = SkiaApi.gr_backendtexture_new_direct3d (width, height, &native);

if (Handle == IntPtr.Zero) {
throw new InvalidOperationException ("Unable to create a new GRBackendTexture instance.");
}
}

protected override void Dispose (bool disposing) =>
base.Dispose (disposing);

Expand Down
15 changes: 15 additions & 0 deletions binding/SkiaSharp/GRContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ public static GRContext CreateVulkan (GRVkBackendContext backendContext, GRConte
}
}

public static GRContext CreateDirect3D (GRD3DBackendContext backendContext) =>
CreateDirect3D (backendContext, null);

public static GRContext CreateDirect3D (GRD3DBackendContext backendContext, GRContextOptions options)
{
if (backendContext == null)
throw new ArgumentNullException (nameof (backendContext));
if (options == null) {
return GetObject (SkiaApi.gr_direct_context_make_direct3d (backendContext.ToNative ()));
} else {
var opts = options.ToNative ();
return GetObject (SkiaApi.gr_direct_context_make_direct3d_with_options (backendContext.ToNative (), &opts));
}
}

// CreateMetal

public static GRContext CreateMetal (GRMtlBackendContext backendContext) =>
Expand Down
24 changes: 24 additions & 0 deletions binding/SkiaSharp/GRD3DBackendContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace SkiaSharp
{
public class GRD3DBackendContext
{
public nint Adapter { get; set; }
public nint Device { get; set; }
public nint Queue { get; set; }
public bool ProtectedContext { get; set; }

internal GrD3DBackendContextNative ToNative ()
{
return new GrD3DBackendContextNative {
fAdapter = Adapter,
fDevice = Device,
fQueue = Queue,
fProtectedContext = ProtectedContext ? (byte)1 : (byte)0
};
}
}
}
30 changes: 30 additions & 0 deletions binding/SkiaSharp/GRD3DTextureResourceInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace SkiaSharp
{
public class GRD3DTextureResourceInfo
{
public nint Resource { get; set; }
public uint ResourceState { get; set; }
public uint Format { get; set; }
public uint SampleCount { get; set; }
public uint LevelCount { get; set; }
public uint SampleQualityPattern { get; set; }
public bool Protected { get; set; }

internal GrD3DTextureResourceInfoNative ToNative ()
{
return new GrD3DTextureResourceInfoNative {
fResource = Resource,
fResourceState = ResourceState,
fFormat = Format,
fSampleCount = SampleCount,
fLevelCount = LevelCount,
fSampleQualityPattern = SampleQualityPattern,
fProtected = Protected ? (byte)1 : (byte)0
};
}
}
}
162 changes: 161 additions & 1 deletion binding/SkiaSharp/SkiaApi.generated.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.InteropServices;

#region Namespaces
Expand All @@ -8,8 +8,14 @@

#region Class declarations

using d3d_alloc_t = System.IntPtr;
using d3d_d12_command_queue_t = System.IntPtr;
using d3d_d12_device_t = System.IntPtr;
using d3d_d12_resource_t = System.IntPtr;
using d3d_dxgi_adapter_t = System.IntPtr;
using gr_backendrendertarget_t = System.IntPtr;
using gr_backendtexture_t = System.IntPtr;
using gr_d3d_memory_allocator_t = System.IntPtr;
using gr_direct_context_t = System.IntPtr;
using gr_glinterface_t = System.IntPtr;
using gr_recording_context_t = System.IntPtr;
Expand Down Expand Up @@ -223,6 +229,20 @@ internal static bool gr_backendrendertarget_is_valid (gr_backendrendertarget_t r
(gr_backendrendertarget_is_valid_delegate ??= GetSymbol<Delegates.gr_backendrendertarget_is_valid> ("gr_backendrendertarget_is_valid")).Invoke (rendertarget);
#endif

// gr_backendrendertarget_t* gr_backendrendertarget_new_direct3d(int width, int height, const gr_d3d_textureresourceinfo_t* d3dInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_backendrendertarget_t gr_backendrendertarget_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_backendrendertarget_t gr_backendrendertarget_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo);
}
private static Delegates.gr_backendrendertarget_new_direct3d gr_backendrendertarget_new_direct3d_delegate;
internal static gr_backendrendertarget_t gr_backendrendertarget_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo) =>
(gr_backendrendertarget_new_direct3d_delegate ??= GetSymbol<Delegates.gr_backendrendertarget_new_direct3d> ("gr_backendrendertarget_new_direct3d")).Invoke (width, height, d3dInfo);
#endif

// gr_backendrendertarget_t* gr_backendrendertarget_new_gl(int width, int height, int samples, int stencils, const gr_gl_framebufferinfo_t* glInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -369,6 +389,20 @@ internal static bool gr_backendtexture_is_valid (gr_backendtexture_t texture) =>
(gr_backendtexture_is_valid_delegate ??= GetSymbol<Delegates.gr_backendtexture_is_valid> ("gr_backendtexture_is_valid")).Invoke (texture);
#endif

// gr_backendtexture_t* gr_backendtexture_new_direct3d(int width, int height, const gr_d3d_textureresourceinfo_t* d3dInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_backendtexture_t gr_backendtexture_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_backendtexture_t gr_backendtexture_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo);
}
private static Delegates.gr_backendtexture_new_direct3d gr_backendtexture_new_direct3d_delegate;
internal static gr_backendtexture_t gr_backendtexture_new_direct3d (Int32 width, Int32 height, GrD3DTextureResourceInfoNative* d3dInfo) =>
(gr_backendtexture_new_direct3d_delegate ??= GetSymbol<Delegates.gr_backendtexture_new_direct3d> ("gr_backendtexture_new_direct3d")).Invoke (width, height, d3dInfo);
#endif

// gr_backendtexture_t* gr_backendtexture_new_gl(int width, int height, bool mipmapped, const gr_gl_textureinfo_t* glInfo)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -525,6 +559,34 @@ internal static bool gr_direct_context_is_abandoned (gr_direct_context_t context
(gr_direct_context_is_abandoned_delegate ??= GetSymbol<Delegates.gr_direct_context_is_abandoned> ("gr_direct_context_is_abandoned")).Invoke (context);
#endif

// gr_direct_context_t* gr_direct_context_make_direct3d(const gr_d3d_backendcontext_t d3dBackendContext)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_direct_context_t gr_direct_context_make_direct3d (GrD3DBackendContextNative d3dBackendContext);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_direct_context_t gr_direct_context_make_direct3d (GrD3DBackendContextNative d3dBackendContext);
}
private static Delegates.gr_direct_context_make_direct3d gr_direct_context_make_direct3d_delegate;
internal static gr_direct_context_t gr_direct_context_make_direct3d (GrD3DBackendContextNative d3dBackendContext) =>
(gr_direct_context_make_direct3d_delegate ??= GetSymbol<Delegates.gr_direct_context_make_direct3d> ("gr_direct_context_make_direct3d")).Invoke (d3dBackendContext);
#endif

// gr_direct_context_t* gr_direct_context_make_direct3d_with_options(const gr_d3d_backendcontext_t d3dBackendContext, const gr_context_options_t* options)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern gr_direct_context_t gr_direct_context_make_direct3d_with_options (GrD3DBackendContextNative d3dBackendContext, GRContextOptionsNative* options);
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate gr_direct_context_t gr_direct_context_make_direct3d_with_options (GrD3DBackendContextNative d3dBackendContext, GRContextOptionsNative* options);
}
private static Delegates.gr_direct_context_make_direct3d_with_options gr_direct_context_make_direct3d_with_options_delegate;
internal static gr_direct_context_t gr_direct_context_make_direct3d_with_options (GrD3DBackendContextNative d3dBackendContext, GRContextOptionsNative* options) =>
(gr_direct_context_make_direct3d_with_options_delegate ??= GetSymbol<Delegates.gr_direct_context_make_direct3d_with_options> ("gr_direct_context_make_direct3d_with_options")).Invoke (d3dBackendContext, options);
#endif

// gr_direct_context_t* gr_direct_context_make_gl(const gr_glinterface_t* glInterface)
#if !USE_DELEGATES
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
Expand Down Expand Up @@ -12801,6 +12863,104 @@ public readonly override int GetHashCode ()

}

// gr_d3d_backendcontext_t
[StructLayout (LayoutKind.Sequential)]
internal unsafe partial struct GrD3DBackendContextNative : IEquatable<GrD3DBackendContextNative> {
// public d3d_dxgi_adapter_t* fAdapter
public d3d_dxgi_adapter_t fAdapter;

// public d3d_d12_device_t* fDevice
public d3d_d12_device_t fDevice;

// public d3d_d12_command_queue_t* fQueue
public d3d_d12_command_queue_t fQueue;

// public gr_d3d_memory_allocator_t* fMemoryAllocator
public gr_d3d_memory_allocator_t fMemoryAllocator;

// public bool fProtectedContext
public Byte fProtectedContext;

public readonly bool Equals (GrD3DBackendContextNative obj) =>
fAdapter == obj.fAdapter && fDevice == obj.fDevice && fQueue == obj.fQueue && fMemoryAllocator == obj.fMemoryAllocator && fProtectedContext == obj.fProtectedContext;

public readonly override bool Equals (object obj) =>
obj is GrD3DBackendContextNative f && Equals (f);

public static bool operator == (GrD3DBackendContextNative left, GrD3DBackendContextNative right) =>
left.Equals (right);

public static bool operator != (GrD3DBackendContextNative left, GrD3DBackendContextNative right) =>
!left.Equals (right);

public readonly override int GetHashCode ()
{
var hash = new HashCode ();
hash.Add (fAdapter);
hash.Add (fDevice);
hash.Add (fQueue);
hash.Add (fMemoryAllocator);
hash.Add (fProtectedContext);
return hash.ToHashCode ();
}

}

// gr_d3d_textureresourceinfo_t
[StructLayout (LayoutKind.Sequential)]
internal unsafe partial struct GrD3DTextureResourceInfoNative : IEquatable<GrD3DTextureResourceInfoNative> {
// public d3d_d12_resource_t* fResource
public d3d_d12_resource_t fResource;

// public d3d_alloc_t* fAlloc
public d3d_alloc_t fAlloc;

// public uint32_t fResourceState
public UInt32 fResourceState;

// public uint32_t fFormat
public UInt32 fFormat;

// public uint32_t fSampleCount
public UInt32 fSampleCount;

// public uint32_t fLevelCount
public UInt32 fLevelCount;

// public unsigned int fSampleQualityPattern
public UInt32 fSampleQualityPattern;

// public bool fProtected
public Byte fProtected;

public readonly bool Equals (GrD3DTextureResourceInfoNative obj) =>
fResource == obj.fResource && fAlloc == obj.fAlloc && fResourceState == obj.fResourceState && fFormat == obj.fFormat && fSampleCount == obj.fSampleCount && fLevelCount == obj.fLevelCount && fSampleQualityPattern == obj.fSampleQualityPattern && fProtected == obj.fProtected;

public readonly override bool Equals (object obj) =>
obj is GrD3DTextureResourceInfoNative f && Equals (f);

public static bool operator == (GrD3DTextureResourceInfoNative left, GrD3DTextureResourceInfoNative right) =>
left.Equals (right);

public static bool operator != (GrD3DTextureResourceInfoNative left, GrD3DTextureResourceInfoNative right) =>
!left.Equals (right);

public readonly override int GetHashCode ()
{
var hash = new HashCode ();
hash.Add (fResource);
hash.Add (fAlloc);
hash.Add (fResourceState);
hash.Add (fFormat);
hash.Add (fSampleCount);
hash.Add (fLevelCount);
hash.Add (fSampleQualityPattern);
hash.Add (fProtected);
return hash.ToHashCode ();
}

}

// gr_gl_framebufferinfo_t
[StructLayout (LayoutKind.Sequential)]
public unsafe partial struct GRGlFramebufferInfo : IEquatable<GRGlFramebufferInfo> {
Expand Down
1 change: 1 addition & 0 deletions native/windows/build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Task("libSkiaSharp")
$"skia_use_system_zlib=false " +
$"skia_enable_skottie=true " +
$"skia_use_vulkan={SUPPORT_VULKAN} ".ToLower () +
$"skia_use_direct3d=true " +
clang +
win_vcvars_version +
$"extra_cflags=[ '-DSKIA_C_DLL', '/MT{d}', '/EHsc', '/Z7', '-D_HAS_AUTO_PTR_ETC=1' ] " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vortice.Direct3D12;
using Vortice.DXGI;

namespace SkiaSharp
{
public class GRDirect3DBackendContext : GRD3DBackendContext
{
private IDXGIAdapter1 _adapter;
public new IDXGIAdapter1 Adapter { get => _adapter; set { _adapter = value; base.Adapter = value?.NativePointer ?? default; } }

private ID3D12Device2 _device;
public new ID3D12Device2 Device { get => _device; set { _device = value; base.Device = value?.NativePointer ?? default; } }

private ID3D12CommandQueue _queue;
public new ID3D12CommandQueue Queue { get => _queue; set { _queue = value; base.Queue = value?.NativePointer ?? default; } }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vortice.Direct3D12;
using Vortice.DXGI;

namespace SkiaSharp
{
public class GRDirect3DTextureInfo : GRD3DTextureResourceInfo
{
private ID3D12Resource _resource;
public new ID3D12Resource Resource { get => _resource; set { _resource = value; base.Resource = value?.NativePointer ?? default; } }
public new ResourceStates ResourceState { get => (ResourceStates)base.ResourceState; set => base.ResourceState = (uint)value; }
public new Format Format { get => (Format)base.Format; set => base.Format = (uint)value; }

}
}
Loading