Skip to content

Commit 382dfd8

Browse files
committed
Fix handling of external memory blocks
OS handles are not suitable for equality checking as they can be reused.
1 parent 8ead4a9 commit 382dfd8

File tree

7 files changed

+76
-62
lines changed

7 files changed

+76
-62
lines changed

src/Aardvark.Rendering.GL/Core/Context.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ type Context(runtime : IRuntime, createContext : ContextHandle option -> Context
373373
GL.GetInteger(unbox<GetPName> 0x9318)
374374
)
375375

376-
member internal x.ImportMemoryBlock(external : ExternalMemoryBlock) =
376+
member internal x.ImportMemoryBlock(external : IExternalMemoryBlock) =
377377
sharedMemoryManager.Import external
378378

379379
/// <summary>

src/Aardvark.Rendering.GL/Core/SharedMemory.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ open System.Collections.Generic
99
[<AutoOpen>]
1010
module internal SharedMemory =
1111

12-
type SharedMemoryBlock(manager : SharedMemoryManager, handle : int, external : ExternalMemoryBlock) =
12+
type SharedMemoryBlock(manager : SharedMemoryManager, handle : int, external : IExternalMemoryBlock) =
1313
let mutable refCount = 1
1414

1515
member x.Handle = handle
@@ -44,7 +44,7 @@ module internal SharedMemory =
4444
GL.Check "DeleteMemoryObject"
4545
)
4646

47-
member x.Import(external : ExternalMemoryBlock) =
47+
member x.Import(external : IExternalMemoryBlock) =
4848
lock blocks (fun _ ->
4949
match blocks.TryGetValue external.Handle with
5050
| (true, shared) ->

src/Aardvark.Rendering.Vulkan/Core/Memory/DevicePtr.fs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,21 @@ type DevicePtr =
1515
val mutable private allocation : VmaAllocation
1616
val private allocationInfo : VmaAllocationInfo2
1717
val private hostVisible : bool
18-
val mutable private externalHandle : IExternalMemoryHandle
18+
val mutable private externalBlock : ExternalMemoryBlock
1919

2020
internal new (device: IDevice, allocator: VmaAllocator, allocation: VmaAllocation, hostVisible: bool, export: bool) =
2121
let mutable info = VmaAllocationInfo2.Empty
2222
Vma.getAllocationInfo2(allocator, allocation, &&info)
2323

24-
let externalHandle =
24+
let externalBlock =
2525
if export then
26-
if RuntimeInformation.IsOSPlatform OSPlatform.Windows then
27-
ExternalMemory.Win32.getHandle allocator allocation
28-
else
29-
ExternalMemory.Posix.getHandle device.Handle info.allocationInfo.deviceMemory
26+
let handle =
27+
if RuntimeInformation.IsOSPlatform OSPlatform.Windows then
28+
ExternalMemory.Win32.getHandle allocator allocation
29+
else
30+
ExternalMemory.Posix.getHandle device.Handle info.allocationInfo.deviceMemory
31+
32+
new ExternalMemoryBlock(handle, info.allocationInfo.deviceMemory, info.blockSize)
3033
else
3134
null
3235

@@ -35,22 +38,21 @@ type DevicePtr =
3538
allocation = allocation
3639
allocationInfo = info
3740
hostVisible = hostVisible
38-
externalHandle = externalHandle }
41+
externalBlock = externalBlock }
3942

4043
internal new (device: IDevice) =
4144
{ device = device
4245
allocator = VmaAllocator.Zero
4346
allocation = VmaAllocation.Zero
4447
allocationInfo = VmaAllocationInfo2.Empty
4548
hostVisible = false
46-
externalHandle = null }
49+
externalBlock = null }
4750

48-
member this.ExternalBlock =
49-
if isNull this.externalHandle then
51+
member this.ExternalBlock : IExternalMemoryBlock =
52+
if isNull this.externalBlock then
5053
raise <| NotSupportedException("[Vulkan] Cannot access external handle of unexported memory allocation.")
5154

52-
{ Handle = this.externalHandle
53-
SizeInBytes = int64 this.allocationInfo.blockSize }
55+
this.externalBlock
5456

5557
member this.Block = this.allocationInfo.allocationInfo.deviceMemory
5658
member this.BlockSize = this.allocationInfo.blockSize
@@ -115,9 +117,9 @@ type DevicePtr =
115117

116118
member this.Dispose() =
117119
if this.allocation <> 0n then
118-
if this.externalHandle <> null then
119-
this.externalHandle.Dispose()
120-
this.externalHandle <- null
120+
if this.externalBlock <> null then
121+
this.externalBlock.Dispose()
122+
this.externalBlock <- null
121123

122124
Vma.freeMemory(this.allocator, this.allocation)
123125
this.allocation <- 0n

src/Aardvark.Rendering.Vulkan/Core/Memory/ExternalMemory.fs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,39 @@
22

33
open Aardvark.Rendering
44
open Aardvark.Rendering.Vulkan
5+
open System
56
open Vulkan11
67

78
#nowarn "51"
89

10+
[<AllowNullLiteral>]
11+
type internal ExternalMemoryBlock(handle: IExternalMemoryHandle, memory: VkDeviceMemory, sizeInBytes: uint64) =
12+
member _.Handle = handle
13+
member _.Memory = memory
14+
member _.SizeInBytes = sizeInBytes
15+
16+
member _.Dispose() =
17+
handle.Dispose()
18+
19+
member inline private _.Equals(other: ExternalMemoryBlock) =
20+
memory = other.Memory
21+
22+
override this.Equals(obj) =
23+
match obj with
24+
| :? ExternalMemoryBlock as other -> this.Equals(other)
25+
| _ -> false
26+
27+
override this.GetHashCode() =
28+
hash memory.Handle
29+
30+
interface IEquatable<ExternalMemoryBlock> with
31+
member this.Equals(other) = this.Equals(other)
32+
33+
interface IExternalMemoryBlock with
34+
member this.Handle = this.Handle
35+
member this.SizeInBytes = int64 this.SizeInBytes
36+
member this.Dispose() = this.Dispose()
37+
938
module internal ExternalMemory =
1039

1140
module Win32 =

src/Aardvark.Rendering.Vulkan/Resources/Buffers/Buffer.fs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,18 @@ type Buffer =
5252
type internal ExportedBuffer =
5353
class
5454
inherit Buffer
55-
56-
member x.ExternalMemory =
57-
{ Block = x.Memory.ExternalBlock
58-
Offset = int64 x.Memory.Offset
59-
Size = int64 x.Memory.Size }
55+
val public ExternalMemory : ExternalMemory
6056

6157
interface IExportedBackendBuffer with
6258
member x.Memory = x.ExternalMemory
6359

64-
new(device, handle, memory, size, usage) =
65-
{ inherit Buffer(device, handle, memory, size, usage) }
60+
new(device, handle, memory: DevicePtr, size, usage) =
61+
let externalMemory =
62+
{ Block = memory.ExternalBlock
63+
Offset = int64 memory.Offset
64+
Size = int64 memory.Size }
65+
66+
{ inherit Buffer(device, handle, memory, size, usage); ExternalMemory = externalMemory }
6667
end
6768

6869
type BufferView =

src/Aardvark.Rendering.Vulkan/Resources/Image/Image.fs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,7 @@ and internal ExportedImage =
204204
class
205205
inherit Image
206206
val public PreferArray : bool
207-
208-
member x.ExternalMemory =
209-
{ Block = x.Memory.ExternalBlock
210-
Offset = int64 x.Memory.Offset
211-
Size = int64 x.Memory.Size }
207+
val public ExternalMemory : ExternalMemory
212208

213209
member x.IsArray =
214210
x.Count > 1 || x.PreferArray
@@ -217,12 +213,19 @@ and internal ExportedImage =
217213
member x.IsArray = x.IsArray
218214
member x.Memory = x.ExternalMemory
219215

220-
new(device, handle, size, levels, layers, samples, dimension, format, preferArray, memory, layout,
216+
new(device, handle, size, levels, layers, samples, dimension, format, preferArray, memory: DevicePtr, layout,
221217
[<Optional; DefaultParameterValue(VkImageLayout.ShaderReadOnlyOptimal)>] samplerLayout : VkImageLayout,
222218
[<Optional; DefaultParameterValue(null : VkImage[])>] peerHandles : VkImage[]) =
219+
220+
let externalMemory =
221+
{ Block = memory.ExternalBlock
222+
Offset = int64 memory.Offset
223+
Size = int64 memory.Size }
224+
223225
{
224226
inherit Image(device, handle, size, levels, layers, samples, dimension, format, memory, layout, samplerLayout, peerHandles)
225227
PreferArray = preferArray
228+
ExternalMemory = externalMemory
226229
}
227230

228231
end

src/Aardvark.Rendering/Resources/Buffers/ExternalMemory.fs

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ open System.Threading
66
open System.Runtime.InteropServices
77

88
/// Interface for external memory handles.
9-
[<AllowNullLiteral>]
109
type IExternalMemoryHandle =
1110
inherit IDisposable
1211
abstract member IsValid : bool
1312

13+
/// Interface for blocks of external memory.
14+
[<AllowNullLiteral>]
15+
type IExternalMemoryBlock =
16+
inherit IDisposable
17+
abstract member Handle : IExternalMemoryHandle
18+
abstract member SizeInBytes : int64
19+
1420
[<AutoOpen>]
1521
module NativePlatformHandles =
1622

@@ -25,7 +31,7 @@ module NativePlatformHandles =
2531
extern int close(int fd)
2632

2733
[<AbstractClass>]
28-
type NativeHandle<'T when 'T : equality>(handle : 'T) =
34+
type NativeHandle<'T>(handle : 'T) =
2935
let mutable isValid = 1
3036

3137
member x.IsValid = isValid = 1
@@ -45,17 +51,6 @@ module NativePlatformHandles =
4551
if not <| x.CloseHandle() then
4652
Log.warn "Could not close external memory handle."
4753

48-
override x.Equals(other : obj) =
49-
match other with
50-
| :? NativeHandle<'T> as o -> handle = o.Handle
51-
| _ -> false
52-
53-
override x.GetHashCode() =
54-
hash handle
55-
56-
interface IEquatable<NativeHandle<'T>> with
57-
member x.Equals(o) = handle = o.Handle
58-
5954
interface IExternalMemoryHandle with
6055
member x.IsValid = x.IsValid
6156
member x.Dispose() = x.Dispose()
@@ -70,28 +65,12 @@ module NativePlatformHandles =
7065

7166
override x.CloseHandle() = Posix.close handle = 0
7267

73-
74-
/// Represents a block of external memory.
75-
type ExternalMemoryBlock =
76-
{
77-
/// The handle of the memory block.
78-
Handle : IExternalMemoryHandle
79-
80-
/// The size of the memory block (in bytes).
81-
SizeInBytes : int64
82-
}
83-
84-
member x.Dispose() =
85-
x.Handle.Dispose()
86-
87-
interface IDisposable with
88-
member x.Dispose() = x.Dispose()
89-
9068
/// Represents a region of an external memory block.
69+
[<Struct>]
9170
type ExternalMemory =
9271
{
9372
/// The external memory block.
94-
Block : ExternalMemoryBlock
73+
Block : IExternalMemoryBlock
9574

9675
/// Start offset of the memory region (in bytes).
9776
Offset : int64

0 commit comments

Comments
 (0)