Skip to content

Commit 0605ba7

Browse files
committed
Only add available layers
1 parent 49c5619 commit 0605ba7

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

guide/src/shader_objects/shader_program.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,33 @@ m_instance = vk::createInstanceUnique(instance_ci);
3535
This layer <em>is not</em> part of standard Vulkan driver installs, you must package the layer with the application for it to run on environments without Vulkan SDK / Vulkan Configurator. Read more <a href="https://docs.vulkan.org/samples/latest/samples/extensions/shader_object/README.html#_emulation_layer">here</a>.
3636
</div>
3737

38+
Since desired layers may not be available, we can set up a defensive check:
39+
40+
```cpp
41+
[[nodiscard]] auto get_layers(std::span<char const* const> desired)
42+
-> std::vector<char const*> {
43+
auto ret = std::vector<char const*>{};
44+
ret.reserve(desired.size());
45+
auto const available = vk::enumerateInstanceLayerProperties();
46+
for (char const* layer : desired) {
47+
auto const pred = [layer = std::string_view{layer}](
48+
vk::LayerProperties const& properties) {
49+
return properties.layerName == layer;
50+
};
51+
if (std::ranges::find_if(available, pred) == available.end()) {
52+
std::println("[lvk] [WARNING] Vulkan Layer '{}' not found", layer);
53+
continue;
54+
}
55+
ret.push_back(layer);
56+
}
57+
return ret;
58+
}
59+
60+
// ...
61+
auto const layers = get_layers(layers_v);
62+
instance_ci.setPEnabledLayerNames(layers);
63+
```
64+
3865
## `class ShaderObject`
3966
4067
We will encapsulate both vertex and fragment shaders into a single `ShaderProgram`, which will also bind the shaders before a draw, and expose/set various dynamic states.

src/app.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,25 @@ namespace {
2424
return fs::current_path();
2525
}
2626

27+
[[nodiscard]] auto get_layers(std::span<char const* const> desired)
28+
-> std::vector<char const*> {
29+
auto ret = std::vector<char const*>{};
30+
ret.reserve(desired.size());
31+
auto const available = vk::enumerateInstanceLayerProperties();
32+
for (char const* layer : desired) {
33+
auto const pred = [layer = std::string_view{layer}](
34+
vk::LayerProperties const& properties) {
35+
return properties.layerName == layer;
36+
};
37+
if (std::ranges::find_if(available, pred) == available.end()) {
38+
std::println("[lvk] [WARNING] Vulkan Layer '{}' not found", layer);
39+
continue;
40+
}
41+
ret.push_back(layer);
42+
}
43+
return ret;
44+
}
45+
2746
[[nodiscard]] auto to_spir_v(fs::path const& path)
2847
-> std::vector<std::uint32_t> {
2948
// open the file at the end, to get the total size.
@@ -91,7 +110,8 @@ void App::create_instance() {
91110
static constexpr auto layers_v = std::array{
92111
"VK_LAYER_KHRONOS_shader_object",
93112
};
94-
instance_ci.setPEnabledLayerNames(layers_v);
113+
auto const layers = get_layers(layers_v);
114+
instance_ci.setPEnabledLayerNames(layers);
95115

96116
m_instance = vk::createInstanceUnique(instance_ci);
97117
// initialize the dispatcher against the created Instance.

0 commit comments

Comments
 (0)