You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-11 13:10:58 +00:00
Merge pull request #47552 from szymonm-google/validation_layers_android
Validation layers on Android
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||||
#define APP_SHORT_NAME "GodotEngine"
|
#define APP_SHORT_NAME "GodotEngine"
|
||||||
@@ -193,7 +194,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_report_callback(
|
|||||||
return VK_FALSE;
|
return VK_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_names, uint32_t layer_count, VkLayerProperties *layers) {
|
VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char *const *check_names, uint32_t layer_count, VkLayerProperties *layers) {
|
||||||
for (uint32_t i = 0; i < check_count; i++) {
|
for (uint32_t i = 0; i < check_count; i++) {
|
||||||
VkBool32 found = 0;
|
VkBool32 found = 0;
|
||||||
for (uint32_t j = 0; j < layer_count; j++) {
|
for (uint32_t j = 0; j < layer_count; j++) {
|
||||||
@@ -210,20 +211,36 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error VulkanContext::_create_validation_layers() {
|
Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const char *const **names) {
|
||||||
|
static const std::vector<std::vector<const char *>> instance_validation_layers_alt{
|
||||||
|
// Preferred set of validation layers
|
||||||
|
{ "VK_LAYER_KHRONOS_validation" },
|
||||||
|
|
||||||
|
// Alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
|
||||||
|
{ "VK_LAYER_LUNARG_standard_validation" },
|
||||||
|
|
||||||
|
// Alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
|
||||||
|
{ "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear out-arguments
|
||||||
|
*count = 0;
|
||||||
|
if (names != nullptr) {
|
||||||
|
*names = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult err;
|
VkResult err;
|
||||||
const char *instance_validation_layers_alt1[] = { "VK_LAYER_KHRONOS_validation" };
|
uint32_t instance_layer_count;
|
||||||
const char *instance_validation_layers_alt2[] = { "VK_LAYER_LUNARG_standard_validation" };
|
|
||||||
const char *instance_validation_layers_alt3[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" };
|
|
||||||
|
|
||||||
uint32_t instance_layer_count = 0;
|
|
||||||
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
|
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
|
||||||
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
|
if (err) {
|
||||||
|
ERR_FAIL_V(ERR_CANT_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance_layer_count < 1) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
VkBool32 validation_found = 0;
|
|
||||||
uint32_t validation_layer_count = 0;
|
|
||||||
const char **instance_validation_layers = nullptr;
|
|
||||||
if (instance_layer_count > 0) {
|
|
||||||
VkLayerProperties *instance_layers = (VkLayerProperties *)malloc(sizeof(VkLayerProperties) * instance_layer_count);
|
VkLayerProperties *instance_layers = (VkLayerProperties *)malloc(sizeof(VkLayerProperties) * instance_layer_count);
|
||||||
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers);
|
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -231,35 +248,17 @@ Error VulkanContext::_create_validation_layers() {
|
|||||||
ERR_FAIL_V(ERR_CANT_CREATE);
|
ERR_FAIL_V(ERR_CANT_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
|
for (uint32_t i = 0; i < instance_validation_layers_alt.size(); i++) {
|
||||||
instance_validation_layers = instance_validation_layers_alt1;
|
if (_check_layers(instance_validation_layers_alt[i].size(), instance_validation_layers_alt[i].data(), instance_layer_count, instance_layers)) {
|
||||||
validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
|
*count = instance_validation_layers_alt[i].size();
|
||||||
|
if (names != nullptr) {
|
||||||
// use alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
|
*names = instance_validation_layers_alt[i].data();
|
||||||
if (!validation_found) {
|
}
|
||||||
validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
|
break;
|
||||||
instance_validation_layers = instance_validation_layers_alt2;
|
|
||||||
validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// use alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
|
|
||||||
if (!validation_found) {
|
|
||||||
validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt3);
|
|
||||||
instance_validation_layers = instance_validation_layers_alt3;
|
|
||||||
validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(instance_layers);
|
free(instance_layers);
|
||||||
}
|
|
||||||
|
|
||||||
if (validation_found) {
|
|
||||||
enabled_layer_count = validation_layer_count;
|
|
||||||
for (uint32_t i = 0; i < validation_layer_count; i++) {
|
|
||||||
enabled_layers[i] = instance_validation_layers[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ERR_CANT_CREATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -301,7 +300,6 @@ Error VulkanContext::_initialize_extensions() {
|
|||||||
uint32_t instance_extension_count = 0;
|
uint32_t instance_extension_count = 0;
|
||||||
|
|
||||||
enabled_extension_count = 0;
|
enabled_extension_count = 0;
|
||||||
enabled_layer_count = 0;
|
|
||||||
enabled_debug_utils = false;
|
enabled_debug_utils = false;
|
||||||
enabled_debug_report = false;
|
enabled_debug_report = false;
|
||||||
/* Look for instance extensions */
|
/* Look for instance extensions */
|
||||||
@@ -330,7 +328,7 @@ Error VulkanContext::_initialize_extensions() {
|
|||||||
extension_names[enabled_extension_count++] = _get_platform_surface_extension();
|
extension_names[enabled_extension_count++] = _get_platform_surface_extension();
|
||||||
}
|
}
|
||||||
if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extensionName)) {
|
if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extensionName)) {
|
||||||
if (use_validation_layers) {
|
if (_use_validation_layers()) {
|
||||||
extension_names[enabled_extension_count++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
extension_names[enabled_extension_count++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
||||||
enabled_debug_report = true;
|
enabled_debug_report = true;
|
||||||
}
|
}
|
||||||
@@ -542,11 +540,6 @@ Error VulkanContext::_create_physical_device() {
|
|||||||
/* obtain version */
|
/* obtain version */
|
||||||
_obtain_vulkan_version();
|
_obtain_vulkan_version();
|
||||||
|
|
||||||
/* Look for validation layers */
|
|
||||||
if (use_validation_layers) {
|
|
||||||
_create_validation_layers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialise extensions */
|
/* initialise extensions */
|
||||||
{
|
{
|
||||||
Error err = _initialize_extensions();
|
Error err = _initialize_extensions();
|
||||||
@@ -567,16 +560,14 @@ Error VulkanContext::_create_physical_device() {
|
|||||||
/*engineVersion*/ 0,
|
/*engineVersion*/ 0,
|
||||||
/*apiVersion*/ VK_MAKE_VERSION(vulkan_major, vulkan_minor, 0)
|
/*apiVersion*/ VK_MAKE_VERSION(vulkan_major, vulkan_minor, 0)
|
||||||
};
|
};
|
||||||
VkInstanceCreateInfo inst_info = {
|
VkInstanceCreateInfo inst_info{};
|
||||||
/*sType*/ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
/*pNext*/ nullptr,
|
inst_info.pApplicationInfo = &app;
|
||||||
/*flags*/ 0,
|
inst_info.enabledExtensionCount = enabled_extension_count;
|
||||||
/*pApplicationInfo*/ &app,
|
inst_info.ppEnabledExtensionNames = (const char *const *)extension_names;
|
||||||
/*enabledLayerCount*/ enabled_layer_count,
|
if (_use_validation_layers()) {
|
||||||
/*ppEnabledLayerNames*/ (const char *const *)enabled_layers,
|
_get_preferred_validation_layers(&inst_info.enabledLayerCount, &inst_info.ppEnabledLayerNames);
|
||||||
/*enabledExtensionCount*/ enabled_extension_count,
|
}
|
||||||
/*ppEnabledExtensionNames*/ (const char *const *)extension_names,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is info for a temp callback to use during CreateInstance.
|
* This is info for a temp callback to use during CreateInstance.
|
||||||
@@ -1077,6 +1068,10 @@ Error VulkanContext::_create_semaphores() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VulkanContext::_use_validation_layers() {
|
||||||
|
return Engine::get_singleton()->is_validation_layers_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) {
|
Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) {
|
||||||
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
|
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
|
||||||
|
|
||||||
@@ -2008,8 +2003,6 @@ String VulkanContext::get_device_pipeline_cache_uuid() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VulkanContext::VulkanContext() {
|
VulkanContext::VulkanContext() {
|
||||||
use_validation_layers = Engine::get_singleton()->is_validation_layers_enabled();
|
|
||||||
|
|
||||||
command_buffer_queue.resize(1); // First one is always the setup command.
|
command_buffer_queue.resize(1); // First one is always the setup command.
|
||||||
command_buffer_queue.write[0] = nullptr;
|
command_buffer_queue.write[0] = nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,9 +151,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool enabled_debug_report = false;
|
bool enabled_debug_report = false;
|
||||||
|
|
||||||
uint32_t enabled_layer_count = 0;
|
|
||||||
const char *enabled_layers[MAX_LAYERS];
|
|
||||||
|
|
||||||
PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
|
PFN_vkCreateDebugUtilsMessengerEXT CreateDebugUtilsMessengerEXT;
|
||||||
PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
|
PFN_vkDestroyDebugUtilsMessengerEXT DestroyDebugUtilsMessengerEXT;
|
||||||
PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
|
PFN_vkSubmitDebugUtilsMessageEXT SubmitDebugUtilsMessageEXT;
|
||||||
@@ -180,11 +177,10 @@ private:
|
|||||||
VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE;
|
VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE;
|
||||||
|
|
||||||
Error _obtain_vulkan_version();
|
Error _obtain_vulkan_version();
|
||||||
Error _create_validation_layers();
|
|
||||||
Error _initialize_extensions();
|
Error _initialize_extensions();
|
||||||
Error _check_capabilities();
|
Error _check_capabilities();
|
||||||
|
|
||||||
VkBool32 _check_layers(uint32_t check_count, const char **check_names, uint32_t layer_count, VkLayerProperties *layers);
|
VkBool32 _check_layers(uint32_t check_count, const char *const *check_names, uint32_t layer_count, VkLayerProperties *layers);
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(
|
static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(
|
||||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||||
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||||
@@ -217,11 +213,12 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
virtual const char *_get_platform_surface_extension() const = 0;
|
virtual const char *_get_platform_surface_extension() const = 0;
|
||||||
|
|
||||||
// Enabled via command line argument.
|
|
||||||
bool use_validation_layers = false;
|
|
||||||
|
|
||||||
virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height);
|
virtual Error _window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height);
|
||||||
|
|
||||||
|
virtual bool _use_validation_layers();
|
||||||
|
|
||||||
|
Error _get_preferred_validation_layers(uint32_t *count, const char *const **names);
|
||||||
|
|
||||||
VkInstance _get_instance() {
|
VkInstance _get_instance() {
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ android {
|
|||||||
aidl.srcDirs = ['aidl']
|
aidl.srcDirs = ['aidl']
|
||||||
assets.srcDirs = ['assets']
|
assets.srcDirs = ['assets']
|
||||||
}
|
}
|
||||||
debug.jniLibs.srcDirs = ['libs/debug']
|
debug.jniLibs.srcDirs = ['libs/debug', 'libs/debug/vulkan_validation_layers']
|
||||||
release.jniLibs.srcDirs = ['libs/release']
|
release.jniLibs.srcDirs = ['libs/release']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,10 +52,10 @@ int VulkanContextAndroid::window_create(ANativeWindow *p_window, int p_width, in
|
|||||||
return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
|
return _window_create(DisplayServer::MAIN_WINDOW_ID, surface, p_width, p_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanContextAndroid::VulkanContextAndroid() {
|
bool VulkanContextAndroid::_use_validation_layers() {
|
||||||
// TODO: fix validation layers
|
uint32_t count = 0;
|
||||||
use_validation_layers = false;
|
_get_preferred_validation_layers(&count, nullptr);
|
||||||
}
|
|
||||||
|
|
||||||
VulkanContextAndroid::~VulkanContextAndroid() {
|
// On Android, we use validation layers automatically if they were explicitly linked with the app.
|
||||||
|
return count > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,13 +36,16 @@
|
|||||||
struct ANativeWindow;
|
struct ANativeWindow;
|
||||||
|
|
||||||
class VulkanContextAndroid : public VulkanContext {
|
class VulkanContextAndroid : public VulkanContext {
|
||||||
virtual const char *_get_platform_surface_extension() const;
|
virtual const char *_get_platform_surface_extension() const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int window_create(ANativeWindow *p_window, int p_width, int p_height);
|
int window_create(ANativeWindow *p_window, int p_width, int p_height);
|
||||||
|
|
||||||
VulkanContextAndroid();
|
VulkanContextAndroid() = default;
|
||||||
~VulkanContextAndroid();
|
~VulkanContextAndroid() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool _use_validation_layers() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VULKAN_CONTEXT_ANDROID_H
|
#endif // VULKAN_CONTEXT_ANDROID_H
|
||||||
|
|||||||
Reference in New Issue
Block a user