-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.in
168 lines (130 loc) · 5.84 KB
/
README.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
## Background
The `jcoronado` package provides a very thin layer over the [Vulkan](https://www.vulkan.org/)
API that intends to provide some degree of memory and type safety. The intention
of the package is to make Vulkan feel like a Java API, without sacrificing
performance. Internally, the package uses the excellent [LWJGL3](https://www.lwjgl.org/)
Vulkan bindings, and adds a thin layer of immutable types and interfaces.
## Features
* Type-safe [Vulkan](https://www.vulkan.org/) frontend
* Strong separation of API and implementation to allow for switching to different bindings at compile-time
* Extensive use of `try-with-resources` to prevent resource leaks
* Strongly-typed interfaces with a heavy emphasis on immutable value types
* Type-safe extension mechanism
* Fully documented (JavaDoc)
* Example code included
* [OSGi](https://www.osgi.org/) ready.
* [JPMS](https://en.wikipedia.org/wiki/Java_Platform_Module_System) ready.
* ISC license
## Requirements
The `jcoronado` package currently targets Vulkan 1.3 and up. Some optional
device features are _required_ by the package.
### synchronization2
The package requires the `synchronization2` feature to be available and enabled.
This is necessary to avoid having a lot of branching code paths around queue
submission and render passes.
At the time of writing, according to the
[Vulkan hardware database](https://vulkan.gpuinfo.org/listdevicescoverage.php?core=1.3&feature=synchronization2&platform=all),
this feature is available on `99.82%` of hardware.
### timelineSemaphore
The package requires the `timelineSemaphore` feature to be available and
enabled. This is necessary because timeline semaphores are a mandatory part
of the API exposed by the package.
At the time of writing, according to the
[Vulkan hardware database](https://vulkan.gpuinfo.org/listdevicescoverage.php?core=1.2&feature=timelineSemaphore&platform=all),
this feature is available on `99.88%` of hardware.
## Building
Install a Vulkan SDK. On Linux, there will be almost certainly be distribution
packages available with names such as `vulkan-validationlayers`, `vulkan-tools`,
etc. On Windows, install the [LunarG SDK](https://vulkan.lunarg.com/). On
Windows, ensure that you have the right vendor drivers installed for your
graphics card; if you don't do this, the library (and the test suite) will
raise exceptions with messages such as "Missing `vulkan-1.dll`".
Then run:
```
$ mvn clean package
```
If this step fails, it's a bug. Please report it!
## Utilities
### com.io7m.jcoronado.utility.allocation_tracker
The `com.io7m.jcoronado.utility.allocation_tracker` module provides a simple
implementation of the `VulkanHostAllocatorType` interface that simply delegates
an existing allocator (such as `jemalloc`) but also tracks the current amount
of memory allocated for every allocation type.
Simply instantiate a `VulkanHostAllocatorTracker` instance and use it anywhere
the API accepts a `VulkanHostAllocatorType`.
### com.io7m.jcoronado.utility.swapchain
The `com.io7m.jcoronado.utility.swapchain` module provides a utility for
managing the [swapchain](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_swapchain.html)
correctly.
Swapchain management is notoriously difficult, with many pitfalls and sharp
edges. The `JCSwapchainManager` class provides a class for correctly creating
swapchains, automatically recreating them if they become suboptimal or
out-of-date, and acquiring and presenting images.
The class requires the use of the
[VK_EXT_swapchain_maintenance1](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_EXT_swapchain_maintenance1.html)
extension to fix serious design flaws in the original `VK_KHR_swapchain` API.
Briefly, create a swapchain:
```
final var swapChainManager =
resources.add(
JCSwapchainManager.create(
JCSwapchainConfiguration.builder()
.setDevice(device)
.setGraphicsQueue(graphicsQueue)
.setPresentationQueue(presentationQueue)
.setSurface(surface)
.setSurfaceExtension(khrSurfaceExt)
.setSwapChainExtension(khrSwapchainExt)
.addSurfaceAlphaFlags(VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
.addImageUsageFlags(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.addImageUsageFlags(VK_IMAGE_USAGE_TRANSFER_DST_BIT)
.addPreferredModes(VK_PRESENT_MODE_MAILBOX_KHR)
.addPreferredModes(VK_PRESENT_MODE_FIFO_KHR)
.addPreferredModes(VK_PRESENT_MODE_IMMEDIATE_KHR)
.build()
)
);
```
Acquire images in the rendering loop:
```
while (rendering) {
try (var image = swapChainManager.acquire()) {
render(image);
image.present();
}
}
```
When an image is acquired or presented, the current swapchain may be detected
as being suboptimal or out-of-date. When this happens, a new swapchain is
created internally and the old one is (eventually) deleted.
On many operating systems, dragging a window's resize box can result in
a flurry of updates that will result in hundreds of swapchain instances being
created and deleted. For best results, disable rendering during window resize
events. As an example, when using [GLFW](https://www.glfw.org/):
```
AtomicBoolean windowIsResizing;
GLFW.glfwSetWindowSizeCallback(
window,
GLFWWindowSizeCallback.create((_, _, _) -> {
windowIsResizing.set(true);
})
);
while (rendering) {
this.windowIsResizing.set(false);
GLFW.glfwPollEvents();
if (!windowIsResizing.get()) {
try (var image = swapChainManager.acquire()) {
render(image);
image.present();
}
} else {
pauseOneFrame();
}
}
```
By avoiding rendering during window resizes, we effectively avoid creating
and destroying swapchains for the intermediate window sizes. When the window
eventually stops resizing, we'll automatically create a suitable swapchain
for the final size.
See the [HelloSwapChain](com.io7m.jcoronado.examples/src/main/java/com/io7m/jcoronado/examples/HelloSwapChain.java)
example.