Skip to content

Commit b1f04fa

Browse files
authored
Improve and fix async compute sample (#1366)
* GLTF images without name use uri as name This allow to set a debug name for images for textures * Use VKLayerSettings to configure validation layers Validation layers configuration options are not ignored * Image memory barrier do not ignore queue families * Fix compilation warning due to float conversion * Fix validation error in synchronization barrier * Document existing queue transfer barriers * Rename final to is_final to avoid using a keyword * Fix validation error in semaphore. * Add missing queue transfer barrier * Improve comments * Clang format * Address comments in PR * Fix warning about load store op size
1 parent 270bd1f commit b1f04fa

File tree

9 files changed

+318
-130
lines changed

9 files changed

+318
-130
lines changed

framework/common/hpp_vk_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ struct HPPImageMemoryBarrier
4747
vk::AccessFlags dst_access_mask;
4848
vk::ImageLayout old_layout = vk::ImageLayout::eUndefined;
4949
vk::ImageLayout new_layout = vk::ImageLayout::eUndefined;
50-
uint32_t old_queue_family = VK_QUEUE_FAMILY_IGNORED;
51-
uint32_t new_queue_family = VK_QUEUE_FAMILY_IGNORED;
50+
uint32_t src_queue_family = VK_QUEUE_FAMILY_IGNORED;
51+
uint32_t dst_queue_family = VK_QUEUE_FAMILY_IGNORED;
5252
};
5353

5454
struct HPPLoadStoreInfo

framework/common/vk_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ struct ImageMemoryBarrier
175175

176176
VkImageLayout new_layout{VK_IMAGE_LAYOUT_UNDEFINED};
177177

178-
uint32_t old_queue_family{VK_QUEUE_FAMILY_IGNORED};
178+
uint32_t src_queue_family{VK_QUEUE_FAMILY_IGNORED};
179179

180-
uint32_t new_queue_family{VK_QUEUE_FAMILY_IGNORED};
180+
uint32_t dst_queue_family{VK_QUEUE_FAMILY_IGNORED};
181181
};
182182

183183
/**

framework/core/command_buffer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,13 +979,13 @@ inline void CommandBuffer<bindingType>::image_memory_barrier_impl(vkb::core::HPP
979979
subresource_range.aspectMask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil;
980980
}
981981

982-
// actively ignore queue family indices provided by memory_barrier !!
982+
// This can cause a queue family ownership transfer. Check the async_compute sample.
983983
vk::ImageMemoryBarrier image_memory_barrier{.srcAccessMask = memory_barrier.src_access_mask,
984984
.dstAccessMask = memory_barrier.dst_access_mask,
985985
.oldLayout = memory_barrier.old_layout,
986986
.newLayout = memory_barrier.new_layout,
987-
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
988-
.dstQueueFamilyIndex = vk::QueueFamilyIgnored,
987+
.srcQueueFamilyIndex = memory_barrier.src_queue_family,
988+
.dstQueueFamilyIndex = memory_barrier.dst_queue_family,
989989
.image = image_view.get_image().get_handle(),
990990
.subresourceRange = subresource_range};
991991

framework/core/hpp_instance.cpp

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,36 @@ bool enable_extension(const char *requested_exte
139139
return is_available;
140140
}
141141

142+
bool enable_layer_setting(const vk::LayerSettingEXT &requested_layer_setting,
143+
const std::vector<const char *> &enabled_layers,
144+
std::vector<vk::LayerSettingEXT> &enabled_layer_settings)
145+
{
146+
// We are checking if the layer is available.
147+
// Vulkan does not provide a reflection API for layer settings. Layer settings are described in each layer JSON manifest.
148+
bool is_available =
149+
std::ranges::any_of(enabled_layers,
150+
[&requested_layer_setting](auto const &available_layer) { return strcmp(available_layer, requested_layer_setting.pLayerName) == 0; });
151+
if (!is_available)
152+
{
153+
LOGW("Layer: {} not found. Disabling layer setting: {}", requested_layer_setting.pLayerName, requested_layer_setting.pSettingName);
154+
return false;
155+
}
156+
157+
bool is_already_enabled =
158+
std::ranges::any_of(enabled_layer_settings,
159+
[&requested_layer_setting](VkLayerSettingEXT const &enabled_layer_setting) { return (strcmp(requested_layer_setting.pLayerName, enabled_layer_setting.pLayerName) == 0) && (strcmp(requested_layer_setting.pSettingName, enabled_layer_setting.pSettingName) == 0); });
160+
161+
if (is_already_enabled)
162+
{
163+
LOGW("Ignoring duplicated layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName);
164+
return false;
165+
}
166+
167+
LOGI("Enabling layer setting {} in layer {}.", requested_layer_setting.pSettingName, requested_layer_setting.pLayerName);
168+
enabled_layer_settings.push_back(requested_layer_setting);
169+
return true;
170+
}
171+
142172
bool enable_layer(const char *requested_layer,
143173
const std::vector<vk::LayerProperties> &available_layers,
144174
std::vector<const char *> &enabled_layers)
@@ -169,7 +199,7 @@ bool enable_layer(const char *requested_layer,
169199
HPPInstance::HPPInstance(const std::string &application_name,
170200
const std::unordered_map<const char *, bool> &requested_extensions,
171201
const std::unordered_map<const char *, bool> &requested_layers,
172-
const std::vector<vk::LayerSettingEXT> &required_layer_settings,
202+
const std::vector<vk::LayerSettingEXT> &requested_layer_settings,
173203
uint32_t api_version)
174204
{
175205
std::vector<vk::ExtensionProperties> available_instance_extensions = vk::enumerateInstanceExtensionProperties();
@@ -194,14 +224,16 @@ HPPInstance::HPPInstance(const std::string &applicati
194224
bool portability_enumeration_available = enable_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, available_instance_extensions, enabled_extensions);
195225
#endif
196226

197-
#ifdef USE_VALIDATION_LAYER_FEATURES
227+
#ifdef USE_VALIDATION_LAYERS
228+
const char *validation_layer_name = "VK_LAYER_KHRONOS_validation";
229+
# ifdef USE_VALIDATION_LAYER_FEATURES
198230
bool validation_features = false;
199231
{
200-
std::vector<vk::ExtensionProperties> available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties(std::string("VK_LAYER_KHRONOS_validation"));
201-
202-
enable_extension(VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions);
232+
std::vector<vk::ExtensionProperties> available_layer_instance_extensions = vk::enumerateInstanceExtensionProperties(std::string(validation_layer_name));
233+
validation_features = enable_extension(VK_EXT_LAYER_SETTINGS_EXTENSION_NAME, available_layer_instance_extensions, enabled_extensions);
203234
}
204-
#endif
235+
# endif // USE_VALIDATION_LAYER_FEATURES
236+
#endif // USE_VALIDATION_LAYERS
205237

206238
// Specific surface extensions are obtained from Window::get_required_surface_extensions
207239
// They are already added to requested_extensions by VulkanSample::prepare
@@ -257,7 +289,7 @@ HPPInstance::HPPInstance(const std::string &applicati
257289
#ifdef USE_VALIDATION_LAYERS
258290
// NOTE: It's important to have the validation layer as the last one here!!!!
259291
// Otherwise, device creation fails !?!
260-
enable_layer("VK_LAYER_KHRONOS_validation", supported_layers, enabled_layers);
292+
enable_layer(validation_layer_name, supported_layers, enabled_layers);
261293
#endif
262294

263295
vk::ApplicationInfo app_info{.pApplicationName = application_name.c_str(), .pEngineName = "Vulkan Samples", .apiVersion = api_version};
@@ -268,6 +300,13 @@ HPPInstance::HPPInstance(const std::string &applicati
268300
.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size()),
269301
.ppEnabledExtensionNames = enabled_extensions.data()};
270302

303+
std::vector<vk::LayerSettingEXT> enabled_layer_settings;
304+
305+
for (const vk::LayerSettingEXT &layer_setting : requested_layer_settings)
306+
{
307+
enable_layer_setting(layer_setting, enabled_layers, enabled_layer_settings);
308+
}
309+
271310
#ifdef USE_VALIDATION_LAYERS
272311
vk::DebugUtilsMessengerCreateInfoEXT debug_utils_create_info;
273312
vk::DebugReportCallbackCreateInfoEXT debug_report_create_info;
@@ -297,31 +336,52 @@ HPPInstance::HPPInstance(const std::string &applicati
297336
}
298337
#endif
299338

339+
// Some of the specialized layers need to be enabled explicitly
340+
// The validation layer does not need to be enabled in code and it can also be configured using the vulkan configurator.
300341
#ifdef USE_VALIDATION_LAYER_FEATURES
301-
vk::ValidationFeaturesEXT validation_features_info;
302-
std::vector<vk::ValidationFeatureEnableEXT> enable_features{};
342+
343+
# if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED)
344+
const VkBool32 setting_validate_gpuav = VK_TRUE;
303345
if (validation_features)
304346
{
305-
# if defined(VKB_VALIDATION_LAYERS_GPU_ASSISTED)
306-
enable_features.push_back(vk::ValidationFeatureEnableEXT::eGpuAssistedReserveBindingSlot);
307-
enable_features.push_back(vk::ValidationFeatureEnableEXT::eGpuAssisted);
347+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "gpuav_enable", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_gpuav), enabled_layers, enabled_layer_settings);
348+
}
308349
# endif
350+
309351
# if defined(VKB_VALIDATION_LAYERS_BEST_PRACTICES)
310-
enable_features.push_back(vk::ValidationFeatureEnableEXT::eBestPractices);
352+
const VkBool32 setting_validate_best_practices = VK_TRUE;
353+
const VkBool32 setting_validate_best_practices_arm = VK_TRUE;
354+
const VkBool32 setting_validate_best_practices_amd = VK_TRUE;
355+
const VkBool32 setting_validate_best_practices_img = VK_TRUE;
356+
const VkBool32 setting_validate_best_practices_nvidia = VK_TRUE;
357+
if (validation_features)
358+
{
359+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_best_practices", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices), enabled_layers, enabled_layer_settings);
360+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_best_practices_arm", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_arm), enabled_layers, enabled_layer_settings);
361+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_best_practices_amd", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_amd), enabled_layers, enabled_layer_settings);
362+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_best_practices_img", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_img), enabled_layers, enabled_layer_settings);
363+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_best_practices_nvidia", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_best_practices_nvidia), enabled_layers, enabled_layer_settings);
364+
}
311365
# endif
312-
validation_features_info.setEnabledValidationFeatures(enable_features);
313-
validation_features_info.pNext = instance_info.pNext;
314-
instance_info.pNext = &validation_features_info;
366+
367+
# if defined(VKB_VALIDATION_LAYERS_SYNCHRONIZATION)
368+
const VkBool32 setting_validate_sync = VK_TRUE;
369+
const VkBool32 setting_validate_sync_heuristics = VK_TRUE;
370+
if (validation_features)
371+
{
372+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "validate_sync", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_sync), enabled_layers, enabled_layer_settings);
373+
enable_layer_setting(vk::LayerSettingEXT(validation_layer_name, "syncval_shader_accesses_heuristic", vk::LayerSettingTypeEXT::eBool32, 1, &setting_validate_sync_heuristics), enabled_layers, enabled_layer_settings);
315374
}
375+
# endif
316376
#endif
317377

318378
vk::LayerSettingsCreateInfoEXT layerSettingsCreateInfo;
319379

320380
// If layer settings are defined, then activate the sample's required layer settings during instance creation
321-
if (required_layer_settings.size() > 0)
381+
if (enabled_layer_settings.size() > 0)
322382
{
323-
layerSettingsCreateInfo.settingCount = static_cast<uint32_t>(required_layer_settings.size());
324-
layerSettingsCreateInfo.pSettings = required_layer_settings.data();
383+
layerSettingsCreateInfo.settingCount = static_cast<uint32_t>(enabled_layer_settings.size());
384+
layerSettingsCreateInfo.pSettings = enabled_layer_settings.data();
325385
layerSettingsCreateInfo.pNext = instance_info.pNext;
326386
instance_info.pNext = &layerSettingsCreateInfo;
327387
}

framework/core/hpp_instance.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ class HPPInstance
4848
* @param application_name The name of the application
4949
* @param requested_extensions The extensions requested to be enabled
5050
* @param requested_layers The validation layers to be enabled
51-
* @param required_layer_settings The layer settings to be enabled
51+
* @param requested_layer_settings The layer settings to be enabled
5252
* @param api_version The Vulkan API version that the instance will be using
5353
* @throws runtime_error if the required extensions and validation layers are not found
5454
*/
5555
HPPInstance(const std::string &application_name,
56-
const std::unordered_map<const char *, bool> &requested_extensions = {},
57-
const std::unordered_map<const char *, bool> &requested_layers = {},
58-
const std::vector<vk::LayerSettingEXT> &required_layer_settings = {},
59-
uint32_t api_version = VK_API_VERSION_1_1);
56+
const std::unordered_map<const char *, bool> &requested_extensions = {},
57+
const std::unordered_map<const char *, bool> &requested_layers = {},
58+
const std::vector<vk::LayerSettingEXT> &requested_layer_settings = {},
59+
uint32_t api_version = VK_API_VERSION_1_1);
6060

6161
/**
6262
* @brief Queries the GPUs of a vk::Instance that is already created

0 commit comments

Comments
 (0)