Skip to content

Commit 931178d

Browse files
committed
[Vulkan] Fix swapchain creation for Wayland
VkSurfaceCapabilitiesKHR.currentExtent is 0xFFFFFFFF when using Wayland. This commit fixes swapchain creation to properly handle this case.
1 parent 9d90ab5 commit 931178d

4 files changed

Lines changed: 73 additions & 50 deletions

File tree

RELEASE_NOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
- [Vulkan] Fixed swapchain creation for Wayland
2+
13
### 5.6.0
24
- https://github.com/aardvark-platform/aardvark.rendering/wiki/Aardvark-Rendering-5.6-changelog
35

src/Aardvark.Rendering.Vulkan/Swapchain/Surface.fs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ type Surface(device : Device, handle : VkSurfaceKHR) =
9797

9898
let physical = device.PhysicalDevice
9999
let family = device.GraphicsFamily
100-
101100

102101
let supported =
103102
native {
@@ -107,25 +106,34 @@ type Surface(device : Device, handle : VkSurfaceKHR) =
107106
return !!ptr
108107
}
109108

110-
let surfaceCaps =
111-
if supported <> 0u then
112-
native {
113-
let! pSurfaceCaps = VkSurfaceCapabilitiesKHR()
114-
VkRaw.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical.Handle, handle, pSurfaceCaps)
115-
|> check "could not get Surface capabilities"
116-
return !!pSurfaceCaps
117-
}
118-
else
119-
VkSurfaceCapabilitiesKHR()
120-
109+
let getSurfaceCaps() =
110+
let mutable result = VkSurfaceCapabilitiesKHR.Empty
111+
112+
if supported = VkTrue then
113+
use ptr = fixed &result
114+
VkRaw.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical.Handle, handle, ptr)
115+
|> check "could not get Surface capabilities"
116+
else
117+
result.minImageCount <- 1u
118+
result.maxImageCount <- UInt32.MaxValue
119+
result.maxImageArrayLayers <- UInt32.MaxValue
120+
result.maxImageExtent <- VkExtent2D(UInt32.MaxValue, UInt32.MaxValue)
121+
122+
result
123+
124+
let toInt =
125+
min <| (uint32 Int32.MaxValue) >> int
126+
127+
let surfaceCaps = getSurfaceCaps()
128+
121129
let supportedTransforms = unbox<VkSurfaceTransformFlagsKHR> (int surfaceCaps.supportedTransforms) |> VkSurfaceTransformFlagsKHR.toImageTrafos
122130
let supportedCompositeAlpha = unbox<VkCompositeAlphaFlagsKHR> (int surfaceCaps.supportedCompositeAlpha)
123131
let supportedUsage = surfaceCaps.supportedUsageFlags
124-
let minSize = V2i(int surfaceCaps.minImageExtent.width, int surfaceCaps.minImageExtent.height)
125-
let maxSize = V2i(int surfaceCaps.maxImageExtent.width, int surfaceCaps.maxImageExtent.height)
126-
let maxSlices = int surfaceCaps.maxImageArrayLayers
127-
let minImageCount = int surfaceCaps.minImageCount
128-
let maxImageCount = int surfaceCaps.maxImageCount
132+
let minSize = V2i(toInt surfaceCaps.minImageExtent.width, toInt surfaceCaps.minImageExtent.height)
133+
let maxSize = V2i(toInt surfaceCaps.maxImageExtent.width, toInt surfaceCaps.maxImageExtent.height)
134+
let maxSlices = toInt surfaceCaps.maxImageArrayLayers
135+
let minImageCount = toInt surfaceCaps.minImageCount
136+
let maxImageCount = toInt surfaceCaps.maxImageCount
129137

130138

131139
let presentModes =
@@ -184,20 +192,18 @@ type Surface(device : Device, handle : VkSurfaceKHR) =
184192
member x.MaxArraySlices = maxSlices
185193
member x.MinImageCount = minImageCount
186194
member x.MaxImageCount = maxImageCount
187-
195+
188196
member x.Size =
189197
if supported <> 0u && handle.IsValid then
190-
let surfaceCaps =
191-
native {
192-
let! ptr = VkSurfaceCapabilitiesKHR()
193-
VkRaw.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical.Handle, handle, ptr)
194-
|> check "could not get Surface capabilities"
195-
return !!ptr
196-
}
197-
V2i(int surfaceCaps.currentExtent.width, int surfaceCaps.currentExtent.height)
198+
let surfaceCaps = getSurfaceCaps()
199+
let size = V2ui(surfaceCaps.currentExtent.width, surfaceCaps.currentExtent.height)
200+
if size <> V2ui(0xFFFFFFFFu) then
201+
V2i(toInt size.X, toInt size.Y)
202+
else
203+
V2i.Zero // See doc for VkSurfaceCapabilitiesKHR.currentExtent
198204
else
199205
V2i.Zero
200-
206+
201207
member x.HasCompositeAlpha (t : VkCompositeAlphaFlagsKHR) = (t &&& supportedCompositeAlpha) = t
202208
member x.HasUsage (t : VkImageUsageFlags) = (t &&& supportedUsage) = t
203209

src/Aardvark.Rendering.Vulkan/Swapchain/Swapchain.fs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,32 @@
33
open System
44
open Aardvark.Base
55
open Aardvark.Rendering
6-
open FSharp.Data.Adaptive
76
open Aardvark.Rendering.Vulkan
87
open System.Runtime.CompilerServices
9-
open Microsoft.FSharp.NativeInterop
108
open KHRSwapchain
119
open KHRSurface
1210

1311
#nowarn "9"
1412
#nowarn "51"
1513

16-
[<AutoOpen>]
14+
[<AutoOpen>]
1715
module ImageTrafoExtensions =
1816
type Box3i with
1917
member x.Transformed(t : ImageTrafo) =
2018
match t with
21-
| ImageTrafo.Identity ->
22-
x
19+
| ImageTrafo.Identity ->
20+
x
2321

24-
| ImageTrafo.MirrorX ->
25-
Box3i(V3i(x.Max.X, x.Min.Y, x.Min.Z), V3i(x.Min.X, x.Max.Y, x.Max.Z))
26-
27-
| ImageTrafo.MirrorY ->
28-
Box3i(V3i(x.Min.X, x.Max.Y, x.Min.Z), V3i(x.Max.X, x.Min.Y, x.Max.Z))
22+
| ImageTrafo.MirrorX ->
23+
Box3i(V3i(x.Max.X, x.Min.Y, x.Min.Z), V3i(x.Min.X, x.Max.Y, x.Max.Z))
2924

30-
| _ ->
31-
failwithf "box cannot be transformed using %A" t
25+
| ImageTrafo.MirrorY ->
26+
Box3i(V3i(x.Min.X, x.Max.Y, x.Min.Z), V3i(x.Max.X, x.Min.Y, x.Max.Z))
27+
28+
| _ ->
29+
failwithf "box cannot be transformed using %A" t
3230

33-
type Swapchain(device : Device, description : SwapchainDescription) =
31+
type Swapchain(device : Device, initialSize : V2i, description : SwapchainDescription) =
3432
let fence = device.CreateFence()
3533
let surface = description.surface
3634
let renderPass = description.renderPass
@@ -179,7 +177,11 @@ type Swapchain(device : Device, description : SwapchainDescription) =
179177

180178
let update() =
181179
if surface.Handle.IsValid && disposed = 0 then
182-
let newSize = surface.Size
180+
let newSize =
181+
let surfaceSize = surface.Size
182+
let currentSize = if surfaceSize <> V2i.Zero then surfaceSize else initialSize
183+
currentSize |> clamp surface.MinSize surface.MaxSize
184+
183185
if newSize <> size || handle.IsNull then
184186
// delete old things
185187

@@ -193,7 +195,7 @@ type Swapchain(device : Device, description : SwapchainDescription) =
193195
buffers |> Array.iter Disposable.dispose
194196

195197
//handle, buffers, framebuffer, resolvedView
196-
let (newHandle, newBuffers, newFramebuffer, newResolvedImage) = recreate handle newSize
198+
let newHandle, newBuffers, newFramebuffer, newResolvedImage = recreate handle newSize
197199
if handle.IsValid then VkRaw.vkDestroySwapchainKHR(device.Handle, handle, NativePtr.zero)
198200

199201
handle <- newHandle
@@ -203,6 +205,10 @@ type Swapchain(device : Device, description : SwapchainDescription) =
203205
resolvedImage <- newResolvedImage
204206
currentBuffer <- 0u
205207

208+
[<Obsolete>]
209+
new (device : Device, description : SwapchainDescription) =
210+
new Swapchain(device, V2i(1024, 768), description)
211+
206212
member x.Size = update(); size
207213
member x.Description = description
208214
member x.Samples = description.samples
@@ -384,12 +390,21 @@ type Swapchain(device : Device, description : SwapchainDescription) =
384390

385391
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
386392
module Swapchain =
393+
394+
let create2 (size : V2i) (description : SwapchainDescription) (device : Device) =
395+
new Swapchain(device, size, description)
396+
397+
[<Obsolete("Use Swapchain.create2 instead.")>]
387398
let create (desc : SwapchainDescription) (device : Device) =
388-
new Swapchain(device, desc)
399+
create2 (V2i(1024, 768)) desc device
389400

390401
[<AbstractClass; Sealed; Extension>]
391402
type DeviceSwapchainExtensions private() =
392403

404+
[<Extension>]
405+
static member CreateSwapchain(this : Device, size : V2i, description : SwapchainDescription) =
406+
this |> Swapchain.create2 size description
407+
393408
[<Extension>]
394409
static member CreateSwapchain(this : Device, description : SwapchainDescription) =
395-
this |> Swapchain.create description
410+
this.CreateSwapchain(V2i(1024, 768), description)

src/Application/Aardvark.Application.Slim.Vulkan/Application.fs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ module private Vulkan =
6262
device.CreateSwapchainDescription(surf, graphicsMode)
6363

6464
{ new IWindowSurface with
65-
override __.Signature =
65+
override _.Signature =
6666
description.renderPass :> IFramebufferSignature
6767
override this.CreateSwapchain(size: V2i) =
68-
let swap = device.CreateSwapchain(description)
68+
let swap = device.CreateSwapchain(size, description)
6969
{ new ISwapchain with
7070
override this.Dispose() =
7171
swap.Dispose()
@@ -87,16 +87,16 @@ module private Vulkan =
8787

8888
let interop =
8989
{ new IWindowInterop with
90-
override __.Boot(_) =
90+
override _.Boot(_) =
9191
()
9292

93-
override __.CreateSurface(runtime : IRuntime, cfg: WindowConfig, glfw: Glfw, win: nativeptr<WindowHandle>) =
93+
override _.CreateSurface(runtime : IRuntime, cfg: WindowConfig, glfw: Glfw, win: nativeptr<WindowHandle>) =
9494
createSurface (runtime :?> _) cfg glfw win
9595

96-
override __.WindowHints(cfg: WindowConfig, glfw: Glfw) =
96+
override _.WindowHints(cfg: WindowConfig, glfw: Glfw) =
9797
glfw.WindowHint(WindowHintClientApi.ClientApi, ClientApi.NoApi)
9898

99-
override __.Dispose() =
99+
override _.Dispose() =
100100
()
101101
}
102102

0 commit comments

Comments
 (0)