@@ -25,13 +25,13 @@ type IDeviceMemory =
25
25
[<Optional; DefaultParameterValue( 0.5 ) >] priority: float *
26
26
[<Optional; DefaultParameterValue( false ) >] export: bool *
27
27
[<Optional; DefaultParameterValue( true ) >] bind: bool *
28
- [<Optional; DefaultParameterValue( false ) >] mayAlias: bool -> VkBuffer * DevicePtr
28
+ [<Optional; DefaultParameterValue( false ) >] mayAlias: bool -> struct ( VkBuffer * DevicePtr)
29
29
30
30
abstract member CreateImage : info : VkImageCreateInfo byref *
31
31
[<Optional; DefaultParameterValue( 0.5 ) >] priority: float *
32
32
[<Optional; DefaultParameterValue( false ) >] export: bool *
33
33
[<Optional; DefaultParameterValue( true ) >] bind: bool *
34
- [<Optional; DefaultParameterValue( false ) >] mayAlias: bool -> VkImage * DevicePtr
34
+ [<Optional; DefaultParameterValue( false ) >] mayAlias: bool -> struct ( VkImage * DevicePtr)
35
35
36
36
type internal MemoryAllocator ( device : IDevice ) =
37
37
let mutable allocator = VmaAllocator.Zero
@@ -71,51 +71,57 @@ type internal MemoryAllocator (device: IDevice) =
71
71
72
72
let nullPtr = new DevicePtr( device)
73
73
74
- let externalMemoryPools = ConcurrentDictionary< uint32, ExternalMemoryPool>()
74
+ let externalMemoryPools = ConcurrentDictionary< uint32, Lazy < ExternalMemoryPool> >()
75
75
76
- let createBuffer pBufferCreateInfo pAllocationCreateInfo hostVisible alignment export =
76
+ let getExternalMemoryPool memoryTypeIndex =
77
+ externalMemoryPools.GetOrAdd( memoryTypeIndex, fun index ->
78
+ lazy ( new ExternalMemoryPool( allocator, index))
79
+ ) .Value
80
+
81
+ let tryCreateBuffer pBufferCreateInfo pAllocationCreateInfo hostVisible alignment export =
77
82
let mutable buffer = VkBuffer.Null
78
83
let mutable allocation = VmaAllocation.Zero
79
84
80
- Vma.createBufferWithAlignment (
81
- allocator , pBufferCreateInfo , pAllocationCreateInfo , alignment ,
82
- && buffer , && allocation , NativePtr.zero
83
- )
84
- |> checkf " could not create buffer "
85
+ let result =
86
+ Vma.createBufferWithAlignment (
87
+ allocator , pBufferCreateInfo , pAllocationCreateInfo , alignment ,
88
+ && buffer , && allocation , NativePtr.zero
89
+ )
85
90
86
- let ptr = new DevicePtr( device, allocator, allocation, hostVisible, export)
87
- buffer, ptr
91
+ if result = VkResult.Success then
92
+ let ptr = new DevicePtr( device, allocator, allocation, hostVisible, export)
93
+ Result.Ok struct ( buffer, ptr)
94
+ else
95
+ Result.Error result
88
96
89
- let createImage pImageCreateInfo pAllocationCreateInfo hostVisible export =
97
+ let tryCreateImage pImageCreateInfo pAllocationCreateInfo hostVisible export =
90
98
let mutable image = VkImage.Null
91
99
let mutable allocation = VmaAllocation.Zero
92
100
93
- Vma.createImage (
94
- allocator , pImageCreateInfo , pAllocationCreateInfo ,
95
- && image , && allocation , NativePtr.zero
96
- )
97
- |> checkf " could not allocate memory for image "
101
+ let result =
102
+ Vma.createImage (
103
+ allocator , pImageCreateInfo , pAllocationCreateInfo ,
104
+ && image , && allocation , NativePtr.zero
105
+ )
98
106
99
- let ptr = new DevicePtr( device, allocator, allocation, hostVisible, export)
100
- image, ptr
107
+ if result = VkResult.Success then
108
+ let ptr = new DevicePtr( device, allocator, allocation, hostVisible, export)
109
+ Result.Ok struct ( image, ptr)
110
+ else
111
+ Result.Error result
101
112
102
113
let rec createExternalBuffer pBufferCreateInfo ( allocationCreateInfo : _ byref ) hostVisible alignment =
103
114
let mutable memoryTypeIndex = 0 u
104
115
Vma.findMemoryTypeIndexForBufferInfo( allocator, pBufferCreateInfo, && allocationCreateInfo, && memoryTypeIndex)
105
116
|> checkf " could not find memory type for buffer"
106
117
107
- let pool =
108
- externalMemoryPools.GetOrAdd( memoryTypeIndex, fun index ->
109
- new ExternalMemoryPool( allocator, index)
110
- )
118
+ let pool = getExternalMemoryPool memoryTypeIndex
119
+ allocationCreateInfo.pool <- pool.Handle
111
120
112
- try
113
- allocationCreateInfo.pool <- pool.Handle
114
- createBuffer pBufferCreateInfo && allocationCreateInfo hostVisible alignment true
115
-
116
- with :? VulkanException as e ->
117
- Log.warn $" {e.Message}"
118
- allocationCreateInfo.pool <- VmaPool.Zero
121
+ match tryCreateBuffer pBufferCreateInfo && allocationCreateInfo hostVisible alignment true with
122
+ | Result.Ok result -> result
123
+ | Result.Error error ->
124
+ Log.Vulkan.warn $" could not allocate memory for buffer (Error: {error})"
119
125
& allocationCreateInfo.memoryTypeBits &&&= ~~~( 1 u <<< int32 memoryTypeIndex)
120
126
createExternalBuffer pBufferCreateInfo & allocationCreateInfo hostVisible alignment
121
127
@@ -124,18 +130,13 @@ type internal MemoryAllocator (device: IDevice) =
124
130
Vma.findMemoryTypeIndexForImageInfo( allocator, pImageCreateInfo, && allocationCreateInfo, && memoryTypeIndex)
125
131
|> checkf " could not find memory type for image"
126
132
127
- let pool =
128
- externalMemoryPools.GetOrAdd( memoryTypeIndex, fun index ->
129
- new ExternalMemoryPool( allocator, index)
130
- )
131
-
132
- try
133
- allocationCreateInfo.pool <- pool.Handle
134
- createImage pImageCreateInfo && allocationCreateInfo hostVisible true
133
+ let pool = getExternalMemoryPool memoryTypeIndex
134
+ allocationCreateInfo.pool <- pool.Handle
135
135
136
- with :? VulkanException as e ->
137
- Log.warn $" {e.Message}"
138
- allocationCreateInfo.pool <- VmaPool.Zero
136
+ match tryCreateImage pImageCreateInfo && allocationCreateInfo hostVisible true with
137
+ | Result.Ok result -> result
138
+ | Result.Error error ->
139
+ Log.Vulkan.warn $" could not allocate memory for image (Error: {error})"
139
140
& allocationCreateInfo.memoryTypeBits &&&= ~~~( 1 u <<< int32 memoryTypeIndex)
140
141
createExternalImage pImageCreateInfo & allocationCreateInfo hostVisible
141
142
@@ -157,9 +158,10 @@ type internal MemoryAllocator (device: IDevice) =
157
158
& flags |||= VmaAllocationCreateFlags.CanAliasBit
158
159
159
160
{ VmaAllocationCreateInfo.Empty with
160
- flags = flags
161
- usage = usage
162
- priority = float32 priority }
161
+ flags = flags
162
+ usage = usage
163
+ priority = float32 priority
164
+ memoryTypeBits = ~~~ 0 u }
163
165
164
166
member _.NullPtr = nullPtr
165
167
@@ -174,7 +176,11 @@ type internal MemoryAllocator (device: IDevice) =
174
176
if export then
175
177
createExternalBuffer && bufferCreateInfo & allocationCreateInfo hostVisible alignment
176
178
else
177
- createBuffer && bufferCreateInfo && allocationCreateInfo hostVisible alignment false
179
+ match tryCreateBuffer && bufferCreateInfo && allocationCreateInfo hostVisible alignment false with
180
+ | Result.Ok result -> result
181
+ | Result.Error error ->
182
+ error |> checkf " could not allocate memory for buffer"
183
+ Unchecked.defaultof<_>
178
184
179
185
with :? VulkanException ->
180
186
this.PrintUsage Logger.Default
@@ -191,7 +197,11 @@ type internal MemoryAllocator (device: IDevice) =
191
197
if export then
192
198
createExternalImage && imageCreateInfo & allocationCreateInfo hostVisible
193
199
else
194
- createImage && imageCreateInfo && allocationCreateInfo hostVisible false
200
+ match tryCreateImage && imageCreateInfo && allocationCreateInfo hostVisible false with
201
+ | Result.Ok result -> result
202
+ | Result.Error error ->
203
+ error |> checkf " could not allocate memory for image"
204
+ Unchecked.defaultof<_>
195
205
196
206
with :? VulkanException ->
197
207
this.PrintUsage Logger.Default
@@ -240,7 +250,7 @@ type internal MemoryAllocator (device: IDevice) =
240
250
member _.Dispose () =
241
251
if allocator <> VmaAllocator.Zero then
242
252
for KeyValue(_, pool) in externalMemoryPools do
243
- pool.Dispose()
253
+ pool.Value. Dispose()
244
254
245
255
Vma.destroyAllocator allocator
246
256
allocator <- VmaAllocator.Zero
0 commit comments