diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index bd24ef8db..78cc2dfbe 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -13,6 +13,15 @@ - [Vulkan] Removed unused `Pipeline` type - [Vulkan] Removed `TextureFormat.ofGLSLType` +### 5.4.11 +- [Application.WPF.GL] SharingRenderControl implementation now uses Silk.NET.Direct3D9 instead of SharpDX +- Removed SharpDX dependency +- Re-added dynamic shader caches +- Fixed multi-threading issue in PrimitiveValueConverter +- [Sg] Use single value attributes for IndexedGeometry +- [IndexedGeometry] Fixed Union() and added ToIndexed() overload +- [IndexedGeometry] Added overload Clone() for deep copy + ### 5.4.10 - [OpenVR] changed GL texture submit to 2 textures (previously side by side, issue with Quest 3) - [GL] Improved querying of supported sample counts diff --git a/paket.dependencies b/paket.dependencies index f23e2e126..fe712c7c2 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -32,7 +32,6 @@ nuget CommonMark.NET ~> 0.15.1 nuget GLSLangSharp ~> 0.4.14 nuget Unofficial.LibTessDotNet ~> 2.0.2 -nuget SharpDX.Direct3D9 ~> 4.0.1 nuget AssimpNet ~> 5.0.0-beta1 nuget Offler ~> 2.0.3 nuget FSharp.Data ~> 4.2.10 @@ -41,6 +40,7 @@ nuget Unofficial.OpenTK ~> 3.0.21 nuget Unofficial.OpenTK.GLControl ~> 3.0.21 nuget Silk.NET.GLFW = 2.15.0 nuget Silk.NET.Core = 2.15.0 +nuget Silk.NET.Direct3D9 = 2.15.0 nuget SharpZipLib ~> 1.4.1 diff --git a/paket.lock b/paket.lock index a84934c2c..70e04202f 100644 --- a/paket.lock +++ b/paket.lock @@ -128,22 +128,12 @@ NUGET System.Runtime.InteropServices.RuntimeInformation (>= 4.3) - restriction: || (== net471) (&& (== net6.0) (>= net461)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== netstandard2.0) (>= net461)) System.Text.Encodings.Web (>= 6.0) System.Text.Json (>= 6.0) - Microsoft.NETCore.App (2.2.8) - restriction: || (&& (== net471) (>= netcoreapp1.0)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) - Microsoft.NETCore.DotNetHostPolicy (>= 2.2.8) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.Platforms (>= 2.2.4) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.Targets (>= 2.0) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - NETStandard.Library (>= 2.0.3) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.DotNetAppHost (6.0.5) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.DotNetHostPolicy (6.0.5) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.DotNetHostResolver (>= 6.0.5) - Microsoft.NETCore.DotNetHostResolver (6.0.5) - restriction: || (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp2.2)) - Microsoft.NETCore.DotNetAppHost (>= 6.0.5) - Microsoft.NETCore.Platforms (6.0.3) - restriction: || (&& (== net471) (< net45)) (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) - Microsoft.NETCore.Targets (5.0) - restriction: || (&& (== net471) (< net45)) (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) + Microsoft.NETCore.Platforms (6.0.3) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) + Microsoft.NETCore.Targets (5.0) - restriction: || (&& (== net471) (< net45)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) Microsoft.NETFramework.ReferenceAssemblies (1.0) Microsoft.NETFramework.ReferenceAssemblies.net471 (>= 1.0) - restriction: || (== net471) (&& (== net6.0) (>= net471)) (&& (== net6.0-windows7.0) (>= net471)) (&& (== netstandard2.0) (>= net471)) Microsoft.NETFramework.ReferenceAssemblies.net471 (1.0.2) - restriction: || (== net471) (&& (== net6.0) (>= net471)) (&& (== net6.0-windows7.0) (>= net471)) (&& (== netstandard2.0) (>= net471)) - NETStandard.Library (2.0.3) - restriction: || (&& (== net471) (< net35)) (&& (== net471) (< net40)) (&& (== net471) (>= netcoreapp2.2)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) + NETStandard.Library (2.0.3) - restriction: || (&& (== net471) (< net35)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) Microsoft.NETCore.Platforms (>= 1.1) Newtonsoft.Json (13.0.1) Offler (2.0.9) @@ -152,12 +142,6 @@ NUGET FSharp.Core (>= 4.7) FSys (>= 0.0.1 < 0.1) Newtonsoft.Json (>= 12.0.3) - SharpDX (4.2) - NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net471) (< net40)) (== net6.0) (== net6.0-windows7.0) (== netstandard2.0) - SharpDX.Direct3D9 (4.0.1) - Microsoft.NETCore.App (>= 1.0.5) - restriction: || (&& (== net471) (>= netcoreapp1.0)) (== net6.0) (== net6.0-windows7.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) - NETStandard.Library (>= 1.6.1) - restriction: || (&& (== net471) (== net6.0)) (&& (== net471) (== net6.0-windows7.0)) (&& (== net471) (< net40)) (&& (== net6.0) (< netcoreapp1.0)) (&& (== net6.0-windows7.0) (< netcoreapp1.0)) (== netstandard2.0) - SharpDX (>= 4.0.1) SharpZipLib (1.4.2) System.Memory (>= 4.5.4) - restriction: || (== net471) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.2) - restriction: || (== net471) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) @@ -169,9 +153,15 @@ NUGET System.Memory (>= 4.5.4) System.Numerics.Vectors (>= 4.5) System.Runtime.CompilerServices.Unsafe (>= 6.0) + Silk.NET.Direct3D9 (2.15) + Silk.NET.Core (>= 2.15) + Silk.NET.Maths (>= 2.15) Silk.NET.GLFW (2.15) Silk.NET.Core (>= 2.15) Ultz.Native.GLFW (>= 3.3.3.1) + Silk.NET.Maths (2.21) + Microsoft.Bcl.HashCode (>= 1.1.1) - restriction: || (== net471) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) + Ultz.Bcl.Half (>= 1.0) - restriction: || (== net471) (&& (== net6.0) (< net5.0)) (&& (== net6.0) (>= net6.0-android)) (&& (== net6.0) (>= net6.0-ios)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< net5.0)) (&& (== net6.0-windows7.0) (>= net6.0-android)) (&& (== net6.0-windows7.0) (>= net6.0-ios)) (&& (== net6.0-windows7.0) (< netcoreapp3.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) SixLabors.ImageSharp (2.1.3) System.Buffers (>= 4.5.1) - restriction: || (== net471) (&& (== net6.0) (>= net472)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0-windows7.0) (>= net472)) (&& (== net6.0-windows7.0) (< netcoreapp2.1)) (== netstandard2.0) System.Memory (>= 4.5.4) - restriction: || (== net471) (&& (== net6.0) (>= net472)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0-windows7.0) (>= net472)) (&& (== net6.0-windows7.0) (< netcoreapp2.1)) (== netstandard2.0) @@ -319,6 +309,11 @@ NUGET System.Threading.Tasks.Extensions (4.5.4) - restriction: || (== net471) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== net6.0-windows7.0) (< netcoreapp3.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (== net471) (&& (== net6.0) (>= net461)) (&& (== net6.0) (< netcoreapp2.1)) (&& (== net6.0) (< netstandard1.0)) (&& (== net6.0) (< netstandard2.0)) (&& (== net6.0) (>= wp8)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== net6.0-windows7.0) (< netcoreapp2.1)) (&& (== net6.0-windows7.0) (< netstandard1.0)) (&& (== net6.0-windows7.0) (< netstandard2.0)) (&& (== net6.0-windows7.0) (>= wp8)) (== netstandard2.0) System.ValueTuple (4.5) - restriction: || (== net471) (&& (== net6.0) (>= net461)) (&& (== net6.0-windows7.0) (>= net461)) (&& (== netstandard2.0) (>= net461)) + Ultz.Bcl.Half (1.0) - restriction: || (== net471) (&& (== net6.0) (< net5.0)) (&& (== net6.0) (>= net6.0-android)) (&& (== net6.0) (>= net6.0-ios)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< net5.0)) (&& (== net6.0-windows7.0) (>= net6.0-android)) (&& (== net6.0-windows7.0) (>= net6.0-ios)) (&& (== net6.0-windows7.0) (< netcoreapp3.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) + Ultz.Bcl.Half.Fallback (>= 1.0) - restriction: || (== net471) (&& (== net6.0) (< net5.0)) (&& (== net6.0-windows7.0) (< net5.0)) (== netstandard2.0) + Ultz.Bcl.Half.Fallback (1.0) - restriction: || (== net471) (&& (== net6.0) (< net5.0)) (&& (== net6.0) (< netcoreapp3.1)) (&& (== net6.0) (< netstandard2.1)) (&& (== net6.0-windows7.0) (< net5.0)) (&& (== net6.0-windows7.0) (< netcoreapp3.1)) (&& (== net6.0-windows7.0) (< netstandard2.1)) (== netstandard2.0) + System.Memory (>= 4.5.4) + System.Runtime.CompilerServices.Unsafe (>= 4.7.1) Ultz.Native.GLFW (3.3.3.1) Unofficial.LibTessDotNet (2.0.2) Unofficial.OpenTK (3.0.21) diff --git a/src/Aardvark.GPGPU/Primitives.fs b/src/Aardvark.GPGPU/Primitives.fs index 7017275a4..fc9b50b0d 100644 --- a/src/Aardvark.GPGPU/Primitives.fs +++ b/src/Aardvark.GPGPU/Primitives.fs @@ -1133,23 +1133,23 @@ type private MapReduceImage<'b when 'b : unmanaged>(runtime : IComputeRuntime, r member x.Dispose() = x.Dispose() type private ExpressionCache() = - let store = System.Collections.Concurrent.ConcurrentDictionary, obj>() + let store = System.Collections.Concurrent.ConcurrentDictionary, Lazy>() member x.GetOrCreate(e : Expr<'a>, create : Expr<'a> -> 'b) = let hash = [ Expr.ComputeHash e ] store.GetOrAdd(hash, fun _ -> - create e :> obj - ) |> unbox<'b> + lazy (create e :> obj) + ).Value |> unbox<'b> member x.GetOrCreate(a : Expr<'a>, b : Expr<'b>, create : Expr<'a> -> Expr<'b> -> 'c) = let hash = [ Expr.ComputeHash a; Expr.ComputeHash b ] store.GetOrAdd(hash, fun _ -> - create a b :> obj - ) |> unbox<'c> + lazy (create a b :> obj) + ).Value |> unbox<'c> member x.Dispose() = for KeyValue(_, obj) in store do - match obj with + match obj.Value with | :? IDisposable as d -> d.Dispose() | _ -> () diff --git a/src/Aardvark.Rendering.GL/Management/ResourceCache.fs b/src/Aardvark.Rendering.GL/Management/ResourceCache.fs index 1efcb5b6b..e57f5429a 100644 --- a/src/Aardvark.Rendering.GL/Management/ResourceCache.fs +++ b/src/Aardvark.Rendering.GL/Management/ResourceCache.fs @@ -153,7 +153,7 @@ type internal Resource<'Handle, 'View when 'View : unmanaged>(kind : ResourceKin member x.Pointer = pointer and internal ResourceCache<'Handle, 'View when 'View : unmanaged>(parent : Option>, renderTaskLock : Option) = - let store = ConcurrentDictionary, Resource<'Handle, 'View>>() + let store = ConcurrentDictionary, Lazy>>() static let handleNonPrimitive = not typeof<'Handle>.IsPrimitive && not typeof<'Handle>.IsEnum @@ -184,16 +184,18 @@ and internal ResourceCache<'Handle, 'View when 'View : unmanaged>(parent : Optio member x.TryGet(key : list) = match store.TryGetValue(key) with - | (true, v) -> Some v + | (true, v) -> Some v.Value | _ -> None member x.GetOrCreateLocal(key : list, create : unit -> Resource<'Handle, 'View>) = let resource = store.GetOrAdd(key, fun _ -> - let res = create() - res.OnDispose.Add(fun () -> store.TryRemove key |> ignore) - res - ) + lazy ( + let res = create() + res.OnDispose.Add(fun () -> store.TryRemove key |> ignore) + res + ) + ).Value resource.AddRef() resource :> IResource<_,_> @@ -330,5 +332,5 @@ and internal ResourceCache<'Handle, 'View when 'View : unmanaged>(parent : Optio let remaining = store |> Seq.map (fun (KeyValue(_,r)) -> r) |> Seq.toArray for r in remaining do Log.warn "leaking resource: %A" r - r.ForceDispose() + r.Value.ForceDispose() store.Clear() \ No newline at end of file diff --git a/src/Aardvark.Rendering.GL/Management/ResourceManager.fs b/src/Aardvark.Rendering.GL/Management/ResourceManager.fs index 218a8f578..f62207128 100644 --- a/src/Aardvark.Rendering.GL/Management/ResourceManager.fs +++ b/src/Aardvark.Rendering.GL/Management/ResourceManager.fs @@ -203,7 +203,7 @@ type ResourceManager private (parent : Option, ctx : Context, r let textureArrayCache = UnaryCache, _>( - fun _arr -> ConcurrentDictionary[]>() + fun _arr -> ConcurrentDictionary[]>>() ) let staticSamplerStateCache = ConcurrentDictionary>() @@ -397,18 +397,20 @@ type ResourceManager private (parent : Option, ctx : Context, r let properties = samplerType.Properties innerCache.GetOrAdd((slotCount, properties), fun _ -> - Array.init slotCount (fun i -> - let arr = - textureArray |> AVal.map (fun t -> - if i < t.Length then - t.[i] - else - nullTexture - ) - - x.CreateTexture(arr, properties) + lazy ( + Array.init slotCount (fun i -> + let arr = + textureArray |> AVal.map (fun t -> + if i < t.Length then + t.[i] + else + nullTexture + ) + + x.CreateTexture(arr, properties) + ) ) - ) + ).Value member x.CreateSampler (sam : aval) = samplerCache.GetOrCreate(sam, fun () -> { diff --git a/src/Aardvark.Rendering.GL/Resources/Textures/TextureCopy.fs b/src/Aardvark.Rendering.GL/Resources/Textures/TextureCopy.fs index 441aec211..a303625c8 100644 --- a/src/Aardvark.Rendering.GL/Resources/Textures/TextureCopy.fs +++ b/src/Aardvark.Rendering.GL/Resources/Textures/TextureCopy.fs @@ -67,19 +67,27 @@ module internal TextureCopyUtilities = [] module private CopyDispatch = + open System.Collections.Concurrent type private Dispatcher() = - static member CopyNativeToNative<'T when 'T : unmanaged>(src : nativeint, srcInfo : Tensor4Info, dst : nativeint, dstInfo : Tensor4Info) = copyBytes<'T> src srcInfo dst dstInfo - module Method = + module CopyNativeToNative = + type Delegate = delegate of nativeint * Tensor4Info * nativeint * Tensor4Info -> unit let private flags = BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public - let copyNativeToNative = typeof.GetMethod("CopyNativeToNative", flags) + let private definition = typeof.GetMethod(nameof Dispatcher.CopyNativeToNative, flags) + let private delegates = ConcurrentDictionary() + + let getDelegate (t: Type) = + delegates.GetOrAdd(t, fun t -> + let mi = definition.MakeGenericMethod [| t |] + unbox <| Delegate.CreateDelegate(typeof, null, mi) + ) let copyBytesTyped (elementType : Type) (src : nativeint) (srcInfo : Tensor4Info) (dst : nativeint) (dstInfo : Tensor4Info) = - let mi = Method.copyNativeToNative.MakeGenericMethod [| elementType |] - mi.Invoke(null, [| src; srcInfo; dst; dstInfo |]) |> ignore + let del = CopyNativeToNative.getDelegate elementType + del.Invoke(src, srcInfo, dst, dstInfo) let copyBytesWithSize (elementSize : int) (src : nativeint) (srcInfo : Tensor4Info) (dst : nativeint) (dstInfo : Tensor4Info) = copyBytesTyped StructTypes.types.[elementSize] src srcInfo dst dstInfo diff --git a/src/Aardvark.Rendering.GL/Runtime/GeometryPool.fs b/src/Aardvark.Rendering.GL/Runtime/GeometryPool.fs index 211eb45e9..d545b9cba 100644 --- a/src/Aardvark.Rendering.GL/Runtime/GeometryPool.fs +++ b/src/Aardvark.Rendering.GL/Runtime/GeometryPool.fs @@ -903,9 +903,9 @@ module GeometryPoolData = if a % b = 0 then a / b else 1 + a / b - static let cullingCache = System.Collections.Concurrent.ConcurrentDictionary() - static let boundCache = System.Collections.Concurrent.ConcurrentDictionary() - + static let cullingCache = System.Collections.Concurrent.ConcurrentDictionary>() + static let boundCache = System.Collections.Concurrent.ConcurrentDictionary>() + let initialCapacity = Fun.NextPowerOfTwo initialCapacity let adjust (call : DrawCallInfo) = if indexed then @@ -963,10 +963,12 @@ module GeometryPoolData = do if bounds then culling <- cullingCache.GetOrAdd(ctx, fun ctx -> - let cs = ComputeShader.ofFunction (V3i(1024, 1024, 1024)) CullingShader.culling - let shader = ctx.CreateComputeProgram cs - shader - ) + lazy ( + let cs = ComputeShader.ofFunction (V3i(1024, 1024, 1024)) CullingShader.culling + let shader = ctx.CreateComputeProgram cs + shader + ) + ).Value infoSlot <- culling.Interface.storageBuffers.["infos"].ssbBinding boundSlot <- culling.Interface.storageBuffers.["bounds"].ssbBinding @@ -980,21 +982,23 @@ module GeometryPoolData = countOffset <- nativeint countField.ufOffset boxShader <- boundCache.GetOrAdd(ctx, fun ctx -> - let effect = - FShade.Effect.compose [ - Effect.ofFunction CullingShader.renderBounds - Effect.ofFunction (DefaultSurfaces.constantColor C4f.Red) - ] - - let compile() = - effect - |> Effect.link signature IndexedGeometryMode.LineList false - |> ModuleCompiler.compileGLSL ctx.FShadeBackend - - match ctx.TryGetOrCompileEffect(effect.Id, signature, IndexedGeometryMode.LineList, compile) with - | Success v -> v - | Error e -> failwith e - ) + lazy ( + let effect = + FShade.Effect.compose [ + Effect.ofFunction CullingShader.renderBounds + Effect.ofFunction (DefaultSurfaces.constantColor C4f.Red) + ] + + let compile() = + effect + |> Effect.link signature IndexedGeometryMode.LineList false + |> ModuleCompiler.compileGLSL ctx.FShadeBackend + + match ctx.TryGetOrCompileEffect(effect.Id, signature, IndexedGeometryMode.LineList, compile) with + | Success v -> v + | Error e -> failwith e + ) + ).Value boxBoundSlot <- boxShader.Interface.storageBuffers |> Seq.pick (fun (KeyValue(a,b)) -> if a = "Bounds" then Some b.ssbBinding else None) boxViewProjSlot <- boxShader.Interface.storageBuffers |> Seq.pick (fun (KeyValue(a,b)) -> if a = "ViewProjs" then Some b.ssbBinding else None) diff --git a/src/Aardvark.Rendering.Text/Font.fs b/src/Aardvark.Rendering.Text/Font.fs index 579e8fdb1..57690ea21 100644 --- a/src/Aardvark.Rendering.Text/Font.fs +++ b/src/Aardvark.Rendering.Text/Font.fs @@ -503,7 +503,7 @@ type Font private(impl : FontImpl, family : string, style : FontStyle) = new(family : string) = Font(family, FontStyle.Regular) type ShapeCache(r : IRuntime) = - static let cache = ConcurrentDictionary() + static let cache = ConcurrentDictionary>() let types = Map.ofList [ @@ -515,9 +515,9 @@ type ShapeCache(r : IRuntime) = let ranges = ConcurrentDictionary() - let surfaceCache = ConcurrentDictionary() - let boundarySurfaceCache = ConcurrentDictionary() - let billboardSurfaceCache = ConcurrentDictionary() + let surfaceCache = ConcurrentDictionary>() + let boundarySurfaceCache = ConcurrentDictionary>() + let billboardSurfaceCache = ConcurrentDictionary>() let effect = FShade.Effect.compose [ @@ -562,41 +562,47 @@ type ShapeCache(r : IRuntime) = ] let surface (s : IFramebufferSignature) = - surfaceCache.GetOrAdd(s, fun s -> - r.PrepareEffect( - s, [ - Path.Shader.pathVertex |> toEffect - Path.Shader.pathFragment |> toEffect - ] + surfaceCache.GetOrAdd(s, fun s -> + lazy ( + r.PrepareEffect( + s, [ + Path.Shader.pathVertex |> toEffect + Path.Shader.pathFragment |> toEffect + ] + ) ) - ) + ).Value let boundarySurface (s : IFramebufferSignature) = boundarySurfaceCache.GetOrAdd(s, fun s -> - r.PrepareEffect( - s, [ - Path.Shader.boundaryVertex |> toEffect - Path.Shader.boundary |> toEffect - ] + lazy ( + r.PrepareEffect( + s, [ + Path.Shader.boundaryVertex |> toEffect + Path.Shader.boundary |> toEffect + ] + ) ) - ) + ).Value let billboardSurface (s : IFramebufferSignature) = billboardSurfaceCache.GetOrAdd(s, fun s -> - r.PrepareEffect( - s, [ - Path.Shader.pathVertexBillboard |> toEffect - Path.Shader.boundary |> toEffect - ] + lazy ( + r.PrepareEffect( + s, [ + Path.Shader.pathVertexBillboard |> toEffect + Path.Shader.boundary |> toEffect + ] + ) ) - ) + ).Value do r.OnDispose.Add(fun () -> - for x in boundarySurfaceCache.Values do r.DeleteSurface x - for x in surfaceCache.Values do r.DeleteSurface x - for x in billboardSurfaceCache.Values do r.DeleteSurface x + for x in boundarySurfaceCache.Values do r.DeleteSurface x.Value + for x in surfaceCache.Values do r.DeleteSurface x.Value + for x in billboardSurfaceCache.Values do r.DeleteSurface x.Value pool.Dispose() ranges.Clear() cache.Clear() @@ -617,8 +623,8 @@ type ShapeCache(r : IRuntime) = static member GetOrCreateCache(r : IRuntime) = cache.GetOrAdd(r, fun r -> - new ShapeCache(r) - ) + lazy (new ShapeCache(r)) + ).Value member x.Effect = effect member x.InstancedEffect = instancedEffect diff --git a/src/Aardvark.Rendering.Vulkan/Resources/Buffers/Buffer.fs b/src/Aardvark.Rendering.Vulkan/Resources/Buffers/Buffer.fs index 6a5856213..d41c9b630 100644 --- a/src/Aardvark.Rendering.Vulkan/Resources/Buffers/Buffer.fs +++ b/src/Aardvark.Rendering.Vulkan/Resources/Buffers/Buffer.fs @@ -345,23 +345,25 @@ module Buffer = new Buffer(device, handle, ptr, size, flags) - let private emptyBuffers = ConcurrentDictionary() + let private emptyBuffers = ConcurrentDictionary>() let empty (export : bool) (usage : VkBufferUsageFlags) (memory : DeviceHeap) = let key = (memory, export, usage) let buffer = emptyBuffers.GetOrAdd(key, fun (memory, export, usage) -> - let device = memory.Device - let buffer = memory |> createInternal true export 1UL usage 256L + lazy ( + let device = memory.Device + let buffer = memory |> createInternal true export 1UL usage 256L - device.OnDispose.Add (fun () -> - emptyBuffers.TryRemove key |> ignore - buffer.Dispose() - ) + device.OnDispose.Add (fun () -> + emptyBuffers.TryRemove key |> ignore + buffer.Dispose() + ) - buffer - ) + buffer + ) + ).Value buffer.AddReference() buffer diff --git a/src/Aardvark.Rendering/Resources/Buffers/SingleValueBuffer.fs b/src/Aardvark.Rendering/Resources/Buffers/SingleValueBuffer.fs index 140ba56ba..fb372a517 100644 --- a/src/Aardvark.Rendering/Resources/Buffers/SingleValueBuffer.fs +++ b/src/Aardvark.Rendering/Resources/Buffers/SingleValueBuffer.fs @@ -66,17 +66,26 @@ module SingleValueBuffer = [] module private GenericDispatch = open System.Reflection + open System.Collections.Concurrent [] type Dispatcher() = static member ToSingleValueBuffer<'T when 'T : unmanaged>(value: obj) : ISingleValueBuffer = SingleValueBuffer<'T>(unbox<'T> value) - module Method = + module ToSingleValueBuffer = + type Delegate = delegate of obj -> ISingleValueBuffer let private flags = BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public - let toSingleValueBuffer = typeof.GetMethod("ToSingleValueBuffer", flags) + let private definition = typeof.GetMethod(nameof Dispatcher.ToSingleValueBuffer, flags) + let private delegates = ConcurrentDictionary() + + let getDelegate (t: Type) = + delegates.GetOrAdd(t, fun t -> + let mi = definition.MakeGenericMethod [| t |] + unbox <| Delegate.CreateDelegate(typeof, null, mi) + ) /// Creates a single value buffer from an untyped value. let create (value: obj) = - let mi = Method.toSingleValueBuffer.MakeGenericMethod [| value.GetType() |] - mi.Invoke(null, [| value |]) |> unbox \ No newline at end of file + let del = ToSingleValueBuffer.getDelegate <| value.GetType() + del.Invoke(value) \ No newline at end of file diff --git a/src/Aardvark.Rendering/Runtime/Compute/MutableInputBinding.fs b/src/Aardvark.Rendering/Runtime/Compute/MutableInputBinding.fs index 370c4ff18..24a2acb8c 100644 --- a/src/Aardvark.Rendering/Runtime/Compute/MutableInputBinding.fs +++ b/src/Aardvark.Rendering/Runtime/Compute/MutableInputBinding.fs @@ -6,6 +6,7 @@ open Aardvark.Base open System open System.Reflection open System.Collections.Generic +open System.Collections.Concurrent open System.Runtime.CompilerServices module private MutableComputeBindingInternals = @@ -18,23 +19,41 @@ module private MutableComputeBindingInternals = [] module private Dispatch = + let private flags = BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public type private Dispatcher() = - static member Create<'T>() = AVal.init Unchecked.defaultof<'T> - static member Change(cval : ChangeableValue<'T>, value : 'T) = cval.Value <- value - - module Method = - let private flags = BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public - let create = typeof.GetMethod("Create", flags) - let change = typeof.GetMethod("Change", flags) - - let create (contentType : Type) = - let mi = Method.create.MakeGenericMethod [| contentType |] - mi.Invoke(null, [||]) |> unbox - - let change (value : obj) (cval : IAdaptiveValue) = - let mi = Method.change.MakeGenericMethod [| cval.ContentType |] - mi.Invoke(null, [| cval; value |]) |> ignore + static member Create<'T>() : IAdaptiveValue = AVal.init Unchecked.defaultof<'T> + static member Change<'T>(cval: IAdaptiveValue, value: obj) = (unbox> cval).Value <- unbox<'T> value + + module Create = + type Delegate = delegate of unit -> IAdaptiveValue + let private definition = typeof.GetMethod(nameof Dispatcher.Create, flags) + let private delegates = ConcurrentDictionary() + + let getDelegate (t: Type) = + delegates.GetOrAdd(t, fun t -> + let mi = definition.MakeGenericMethod [| t |] + unbox <| Delegate.CreateDelegate(typeof, null, mi) + ) + + module Change = + type Delegate = delegate of IAdaptiveValue * obj -> unit + let private definition = typeof.GetMethod(nameof Dispatcher.Change, flags) + let private delegates = ConcurrentDictionary() + + let getDelegate (t: Type) = + delegates.GetOrAdd(t, fun t -> + let mi = definition.MakeGenericMethod [| t |] + unbox <| Delegate.CreateDelegate(typeof, null, mi) + ) + + let create (contentType: Type) : IAdaptiveValue = + let del = Create.getDelegate contentType + del.Invoke() + + let change (value: obj) (cval: IAdaptiveValue) = + let del = Change.getDelegate cval.ContentType + del.Invoke(cval, value) // When an input is first set, the provided value might be of a specialized type. // The type of that value determines the content type of cval value that is created at that point. diff --git a/src/Application/Aardvark.Application.WPF.GL/SharingRenderControl.fs b/src/Application/Aardvark.Application.WPF.GL/SharingRenderControl.fs index 58a6c9fa1..53d8ca2a9 100644 --- a/src/Application/Aardvark.Application.WPF.GL/SharingRenderControl.fs +++ b/src/Application/Aardvark.Application.WPF.GL/SharingRenderControl.fs @@ -14,6 +14,9 @@ open Aardvark.Application open System.Windows.Threading open System.Security open System.Threading +open Microsoft.FSharp.NativeInterop + +#nowarn "9" [] module private DXSharingHelpers = @@ -173,40 +176,63 @@ module WGLDXExtensions = let worked = wglDXUnlockObjectsNV.Invoke(hDevice, objects.Length, pObjects) if not worked then fail "could not unlock objects" + [] module WGLDXContextExtensions = - type ShareContext private(ctx : Context, d3d : SharpDX.Direct3D9.Direct3DEx, device : SharpDX.Direct3D9.DeviceEx, shareDevice : WglDxShareDevice) = + let inline spanny<'a when 'a : unmanaged> (ptr : nativeptr<'a>) = + System.Span<'a>(NativePtr.toVoidPtr ptr, 1) + + open Silk.NET.Direct3D9 + type ShareContext private(ctx : Context, d3d : nativeptr, device : nativeptr, shareDevice : WglDxShareDevice) = static member Create(ctx : Context) = use __ = ctx.ResourceLock - let d3d = new SharpDX.Direct3D9.Direct3DEx() - let device = + + let d3d = D3D9.GetApi() + let mutable d3d9exptr = Unchecked.defaultof<_> + let _ = d3d.Direct3DCreate9Ex(32u, &d3d9exptr) + let d3d = d3d9exptr //System.Span(NativePtr.toVoidPtr d3d9exptr, 1) + + let pDevice = let hndl = GetDesktopWindow() - let parameters = - SharpDX.Direct3D9.PresentParameters( - BackBufferWidth = 10, - BackBufferHeight = 10, - BackBufferFormat = SharpDX.Direct3D9.Format.A8R8G8B8, - BackBufferCount = 0, - MultiSampleType = SharpDX.Direct3D9.MultisampleType.None, - MultiSampleQuality = 0, - SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard, - Windowed = SharpDX.Mathematics.Interop.RawBool(true), - DeviceWindowHandle = hndl, - PresentationInterval = SharpDX.Direct3D9.PresentInterval.Default + let mutable parameters = + PresentParameters( + backBufferWidth = Nullable 10u, + backBufferHeight = Nullable 10u , + backBufferFormat = Nullable Format.FmtA8R8G8B8, + backBufferCount = Nullable 0u, + multiSampleType = Nullable MultisampleType.MultisampleNone, + multiSampleQuality = Nullable 0u, + swapEffect = Nullable Swapeffect.SwapeffectDiscard, + windowed = Nullable 1,// SharpDX.Mathematics.Interop.RawBool(true), + //deviceWindowHandle = hndl, + hDeviceWindow = Nullable hndl, + presentationInterval = Nullable 0u//PresentInterval.Default ) + //SharpDX.Direct3D9.CreateFlags.FpuPreserve ||| + //SharpDX.Direct3D9.CreateFlags.HardwareVertexProcessing ||| + //SharpDX.Direct3D9.CreateFlags.Multithreaded + let createFlags = 0x4u ||| 0x2u ||| 0x40u + let mutable dev = Unchecked.defaultof<_> + printfn "before" + let result = + spanny(d3d).[0].CreateDeviceEx( + 0u, + Devtype.DevtypeHal, + 0n, + createFlags, + ¶meters, + NativePtr.zero, + &dev + ) + if result <> 0 then + raise <| Marshal.GetExceptionForHR(result) + printfn "after " + dev + let shareDevice = WGL.OpenDevice(NativePtr.toNativeInt pDevice) - new SharpDX.Direct3D9.DeviceEx( - d3d, 0, - SharpDX.Direct3D9.DeviceType.Hardware, 0n, - SharpDX.Direct3D9.CreateFlags.FpuPreserve ||| SharpDX.Direct3D9.CreateFlags.HardwareVertexProcessing ||| - SharpDX.Direct3D9.CreateFlags.Multithreaded, - parameters - ) - let shareDevice = WGL.OpenDevice(device.NativePointer) - - ShareContext(ctx, d3d, device, shareDevice) + ShareContext(ctx, d3d, pDevice, shareDevice) @@ -218,7 +244,7 @@ module WGLDXContextExtensions = let private shareContexts = System.Runtime.CompilerServices.ConditionalWeakTable() - type D3DRenderbuffer(ctx : ShareContext, resolveBuffer : int, renderBuffer : int, size : V2i, fmt : TextureFormat, samples : int, dxSurface : SharpDX.Direct3D9.Surface, shareHandle : WglDxShareHandle) = + type D3DRenderbuffer(ctx : ShareContext, resolveBuffer : int, renderBuffer : int, size : V2i, fmt : TextureFormat, samples : int, dxSurface : nativeptr, shareHandle : WglDxShareHandle) = inherit Aardvark.Rendering.GL.Renderbuffer(ctx.Context, renderBuffer, size, fmt, samples, 0L) let mutable shareHandle = shareHandle @@ -293,7 +319,7 @@ module WGLDXContextExtensions = use __ = ctx.Context.ResourceLock WGL.UnregisterObject(ctx.ShareDevice, shareHandle) shareHandle <- WglDxShareHandle.Null - dxSurface.Dispose() + spanny(dxSurface).[0].Release() |> ignore GL.DeleteRenderbuffer(resolveBuffer) GL.DeleteRenderbuffer(renderBuffer) x.Handle <- 0 @@ -303,8 +329,8 @@ module WGLDXContextExtensions = let private dxFormat = LookupTable.lookupTable [ - TextureFormat.Rgba8, SharpDX.Direct3D9.Format.A8R8G8B8 - TextureFormat.Depth24Stencil8, SharpDX.Direct3D9.Format.D24S8 + TextureFormat.Rgba8, Format.FmtA8R8G8B8 + TextureFormat.Depth24Stencil8, Format.FmtD24S8 ] type Context with @@ -324,14 +350,15 @@ module WGLDXContextExtensions = let dxFormat = dxFormat format let ctx = x.ShareContext - let mutable wddmHandle = 0n - let surface = - SharpDX.Direct3D9.Surface.CreateRenderTarget( - ctx.Device, - size.X, size.Y, + let mutable wddmHandle = Unchecked.defaultof<_> + let mutable surface = Unchecked.defaultof<_> + let _ = + spanny(ctx.Device).[0].CreateRenderTarget( + uint32 size.X, uint32 size.Y, dxFormat, - SharpDX.Direct3D9.MultisampleType.None, 0, - true, + MultisampleType.MultisampleNone, 0u, + 1, + &surface, &wddmHandle ) @@ -359,8 +386,8 @@ module WGLDXContextExtensions = - WGL.SetResourceShareHandle(surface.NativePointer, wddmHandle) - let shareHandle = WGL.RegisterObject(ctx.ShareDevice, surface.NativePointer, resolveBuffer, All.Renderbuffer, WglDXAccess.WriteDiscard) + WGL.SetResourceShareHandle(NativePtr.toNativeInt surface, NativePtr.toNativeInt (NativePtr.ofVoidPtr wddmHandle)) + let shareHandle = WGL.RegisterObject(ctx.ShareDevice, NativePtr.toNativeInt surface, resolveBuffer, All.Renderbuffer, WglDXAccess.WriteDiscard) //let shareHandle = WglDxShareHandle.Null // let mutable ssamples = 0 @@ -526,7 +553,7 @@ type OpenGlSharingRenderControl(runtime : Runtime, samples : int) as this = use __ = ctx.RenderingLock(handle) img.Lock() c.Lock() - img.SetBackBuffer(Interop.D3DResourceType.IDirect3DSurface9, c.Surface.NativePointer) + img.SetBackBuffer(Interop.D3DResourceType.IDirect3DSurface9, NativePtr.toNativeInt c.Surface) c.Unlock() img.AddDirtyRect(Int32Rect(0,0,img.PixelWidth, img.PixelHeight)) diff --git a/src/Application/Aardvark.Application.WPF.GL/paket.references b/src/Application/Aardvark.Application.WPF.GL/paket.references index ab399674c..4046bfe31 100644 --- a/src/Application/Aardvark.Application.WPF.GL/paket.references +++ b/src/Application/Aardvark.Application.WPF.GL/paket.references @@ -2,7 +2,7 @@ Aardvark.Base.Essentials Aardvark.Base.Incremental FShade.Core Aardvark.Base.Runtime -SharpDX.Direct3D9 +Silk.NET.Direct3D9 FSharp.Core FShade.GLSL Unofficial.OpenTK diff --git a/src/Examples (netcore)/01 - Hello Wpf/01 - Hello Wpf.csproj b/src/Examples (netcore)/01 - Hello Wpf/01 - Hello Wpf.csproj index 4db3015c0..e97b2a726 100644 --- a/src/Examples (netcore)/01 - Hello Wpf/01 - Hello Wpf.csproj +++ b/src/Examples (netcore)/01 - Hello Wpf/01 - Hello Wpf.csproj @@ -1,7 +1,7 @@  - WinExe + Exe net6.0-windows _01___Hello_Wpf enable diff --git a/src/Examples (netcore)/01 - Hello Wpf/MainWindow.xaml.cs b/src/Examples (netcore)/01 - Hello Wpf/MainWindow.xaml.cs index 3cb62468e..792c25e7f 100644 --- a/src/Examples (netcore)/01 - Hello Wpf/MainWindow.xaml.cs +++ b/src/Examples (netcore)/01 - Hello Wpf/MainWindow.xaml.cs @@ -23,6 +23,7 @@ using Aardvark.Rendering.CSharp; using Aardvark.Rendering; using Effects = Aardvark.Rendering.Effects; +using Aardvark.Application.WPF; namespace _01___Hello_Wpf { @@ -35,6 +36,8 @@ public MainWindow() { Aardvark.Base.Aardvark.Init(); // initialize aardvark base modules + Config.useSharingControl = true; + var app = new Aardvark.Application.WPF.OpenGlApplication(true); InitializeComponent(); app.Initialize(renderControl, 1); @@ -52,11 +55,12 @@ public MainWindow() var currentAngle = 0.0; var angle = renderControl.Time.Map(t => { - if (checkBox.IsChecked!.Value) - { - return currentAngle += 0.001; - } - else return currentAngle; + return currentAngle += 0.001; + //if (checkBox.IsChecked!.Value) + //{ + // return currentAngle += 0.001; + //} + //else return currentAngle; }); var rotatingTrafo = angle.Map(Trafo3d.RotationZ);