aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMika Väinölä <33728696+mvainola@users.noreply.github.com>2019-10-28 19:40:06 +0200
committerdan sinclair <dsinclair@google.com>2019-10-28 13:40:06 -0400
commit34bb13d2747ec8c3ba1deca3d1c5c5f5f5dffa45 (patch)
tree2107e51975d2518edbe9b9cdb3ea4570d72c76e8
parent40fce113d6fec2ee35cf1c3574bcdb8e0129c373 (diff)
downloadamber-34bb13d2747ec8c3ba1deca3d1c5c5f5f5dffa45.tar.gz
Add Vulkan device selection support (#698)
Add the `-D` command line option for selecting a physical Vulkan device to run with. Only choose from enumerated physical devices in ChooseVulkanPhysicalDevice and move feature and extension checks to a new CheckVulkanPhysicalDeviceRequirements function. Issue #619
-rw-r--r--samples/amber.cc17
-rw-r--r--samples/config_helper.cc3
-rw-r--r--samples/config_helper.h2
-rw-r--r--samples/config_helper_dawn.cc1
-rw-r--r--samples/config_helper_dawn.h1
-rw-r--r--samples/config_helper_vulkan.cc164
-rw-r--r--samples/config_helper_vulkan.h11
7 files changed, 130 insertions, 69 deletions
diff --git a/samples/amber.cc b/samples/amber.cc
index cb085c6..6e7af87 100644
--- a/samples/amber.cc
+++ b/samples/amber.cc
@@ -49,6 +49,7 @@ struct Options {
uint32_t engine_major = 1;
uint32_t engine_minor = 0;
int32_t fence_timeout = -1;
+ int32_t selected_device = -1;
bool parse_only = false;
bool pipeline_create_only = false;
bool disable_validation_layer = false;
@@ -70,6 +71,7 @@ const char kUsage[] = R"(Usage: amber [options] SCRIPT [SCRIPTS...]
-ps -- Parse input files, create pipelines; Don't execute.
-q -- Disable summary output.
-d -- Disable validation layers.
+ -D <ID> -- ID of device to run with (Vulkan only).
-f <value> -- Sets the fence timeout value to |value|
-t <spirv_env> -- The target SPIR-V environment e.g., spv1.3, vulkan1.1.
If a SPIR-V environment, assume the lowest version of Vulkan that
@@ -146,6 +148,20 @@ bool ParseArgs(const std::vector<std::string>& args, Options* opts) {
<< std::endl;
return false;
}
+ } else if (arg == "-D") {
+ ++i;
+ if (i >= args.size()) {
+ std::cerr << "Missing ID for -D argument." << std::endl;
+ return false;
+ }
+
+ int32_t val = std::stoi(std::string(args[i]));
+ if (val < 0) {
+ std::cerr << "Device ID must be non-negative" << std::endl;
+ return false;
+ }
+ opts->selected_device = val;
+
} else if (arg == "-f") {
++i;
if (i >= args.size()) {
@@ -405,6 +421,7 @@ int main(int argc, const char** argv) {
amber::Result r = config_helper.CreateConfig(
amber_options.engine, options.engine_major, options.engine_minor,
+ options.selected_device,
std::vector<std::string>(required_features.begin(),
required_features.end()),
std::vector<std::string>(required_instance_extensions.begin(),
diff --git a/samples/config_helper.cc b/samples/config_helper.cc
index a1a8016..4cceb85 100644
--- a/samples/config_helper.cc
+++ b/samples/config_helper.cc
@@ -40,6 +40,7 @@ amber::Result ConfigHelper::CreateConfig(
amber::EngineType engine,
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
@@ -67,7 +68,7 @@ amber::Result ConfigHelper::CreateConfig(
return amber::Result("Unable to create config helper");
return impl_->CreateConfig(
- engine_major, engine_minor, required_features,
+ engine_major, engine_minor, selected_device, required_features,
required_instance_extensions, required_device_extensions,
disable_validation_layer, show_version_info, config);
}
diff --git a/samples/config_helper.h b/samples/config_helper.h
index cc351d6..fbed9ef 100644
--- a/samples/config_helper.h
+++ b/samples/config_helper.h
@@ -35,6 +35,7 @@ class ConfigHelperImpl {
virtual amber::Result CreateConfig(
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
@@ -58,6 +59,7 @@ class ConfigHelper {
amber::EngineType engine,
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
diff --git a/samples/config_helper_dawn.cc b/samples/config_helper_dawn.cc
index b160756..6fbb079 100644
--- a/samples/config_helper_dawn.cc
+++ b/samples/config_helper_dawn.cc
@@ -51,6 +51,7 @@ void PrintDeviceError(DawnErrorType errorType, const char* message, void*) {
amber::Result ConfigHelperDawn::CreateConfig(
uint32_t,
uint32_t,
+ int32_t,
const std::vector<std::string>&,
const std::vector<std::string>&,
const std::vector<std::string>&,
diff --git a/samples/config_helper_dawn.h b/samples/config_helper_dawn.h
index 1f0fdff..8e8c56c 100644
--- a/samples/config_helper_dawn.h
+++ b/samples/config_helper_dawn.h
@@ -39,6 +39,7 @@ class ConfigHelperDawn : public ConfigHelperImpl {
amber::Result CreateConfig(
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
diff --git a/samples/config_helper_vulkan.cc b/samples/config_helper_vulkan.cc
index 551fc12..9cc1c73 100644
--- a/samples/config_helper_vulkan.cc
+++ b/samples/config_helper_vulkan.cc
@@ -699,9 +699,85 @@ amber::Result ConfigHelperVulkan::CreateDebugReportCallback() {
return {};
}
-amber::Result ConfigHelperVulkan::ChooseVulkanPhysicalDevice(
+amber::Result ConfigHelperVulkan::CheckVulkanPhysicalDeviceRequirements(
+ const VkPhysicalDevice physical_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_extensions) {
+ VkPhysicalDeviceFeatures required_vulkan_features =
+ VkPhysicalDeviceFeatures();
+
+ if (use_physical_device_features2_) {
+ VkPhysicalDeviceVariablePointerFeaturesKHR var_ptrs =
+ VkPhysicalDeviceVariablePointerFeaturesKHR();
+ var_ptrs.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
+ var_ptrs.pNext = nullptr;
+
+ VkPhysicalDeviceFeatures2KHR features2 = VkPhysicalDeviceFeatures2KHR();
+ features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
+ features2.pNext = &var_ptrs;
+
+ auto vkGetPhysicalDeviceFeatures2KHR =
+ reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(
+ vkGetInstanceProcAddr(vulkan_instance_,
+ "vkGetPhysicalDeviceFeatures2KHR"));
+ vkGetPhysicalDeviceFeatures2KHR(physical_device, &features2);
+ available_features_ = features2.features;
+
+ std::vector<std::string> required_features1;
+ for (const auto& feature : required_features) {
+ // No dot means this is a features1 feature.
+ if (feature.find_first_of('.') == std::string::npos) {
+ required_features1.push_back(feature);
+ continue;
+ }
+
+ if (feature == kVariablePointers &&
+ var_ptrs.variablePointers != VK_TRUE) {
+ continue;
+ }
+ if (feature == kVariablePointersStorageBuffer &&
+ var_ptrs.variablePointersStorageBuffer != VK_TRUE) {
+ continue;
+ }
+ }
+
+ amber::Result r =
+ NamesToVulkanFeatures(required_features1, &required_vulkan_features);
+ if (!r.IsSuccess())
+ return r;
+
+ } else {
+ amber::Result r =
+ NamesToVulkanFeatures(required_features, &required_vulkan_features);
+ if (!r.IsSuccess())
+ return r;
+
+ vkGetPhysicalDeviceFeatures(physical_device, &available_features_);
+ }
+ if (!AreAllRequiredFeaturesSupported(available_features_,
+ required_vulkan_features)) {
+ return amber::Result("Device does not support all required features");
+ }
+
+ available_device_extensions_ = GetAvailableDeviceExtensions(physical_device);
+ if (!AreAllExtensionsSupported(available_device_extensions_,
+ required_extensions)) {
+ return amber::Result("Device does not support all required extensions");
+ }
+
+ vulkan_queue_family_index_ = ChooseQueueFamilyIndex(physical_device);
+ if (vulkan_queue_family_index_ == std::numeric_limits<uint32_t>::max()) {
+ return amber::Result("Device does not support required queue flags");
+ }
+
+ return {};
+}
+
+amber::Result ConfigHelperVulkan::ChooseVulkanPhysicalDevice(
+ const std::vector<std::string>& required_features,
+ const std::vector<std::string>& required_extensions,
+ const int32_t selected_device) {
uint32_t count = 0;
std::vector<VkPhysicalDevice> physical_devices;
@@ -716,72 +792,24 @@ amber::Result ConfigHelperVulkan::ChooseVulkanPhysicalDevice(
return amber::Result("Unable to enumerate physical devices");
}
- VkPhysicalDeviceFeatures required_vulkan_features =
- VkPhysicalDeviceFeatures();
- for (uint32_t i = 0; i < count; ++i) {
- if (use_physical_device_features2_) {
- VkPhysicalDeviceVariablePointerFeaturesKHR var_ptrs =
- VkPhysicalDeviceVariablePointerFeaturesKHR();
- var_ptrs.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
- var_ptrs.pNext = nullptr;
-
- VkPhysicalDeviceFeatures2KHR features2 = VkPhysicalDeviceFeatures2KHR();
- features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
- features2.pNext = &var_ptrs;
-
- auto vkGetPhysicalDeviceFeatures2KHR =
- reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(
- vkGetInstanceProcAddr(vulkan_instance_,
- "vkGetPhysicalDeviceFeatures2KHR"));
- vkGetPhysicalDeviceFeatures2KHR(physical_devices[i], &features2);
- available_features_ = features2.features;
-
- std::vector<std::string> required_features1;
- for (const auto& feature : required_features) {
- // No dot means this is a features1 feature.
- if (feature.find_first_of('.') == std::string::npos) {
- required_features1.push_back(feature);
- continue;
- }
-
- if (feature == kVariablePointers &&
- var_ptrs.variablePointers != VK_TRUE) {
- continue;
- }
- if (feature == kVariablePointersStorageBuffer &&
- var_ptrs.variablePointersStorageBuffer != VK_TRUE) {
- continue;
- }
- }
-
- amber::Result r =
- NamesToVulkanFeatures(required_features1, &required_vulkan_features);
- if (!r.IsSuccess())
- return r;
-
- } else {
- amber::Result r =
- NamesToVulkanFeatures(required_features, &required_vulkan_features);
- if (!r.IsSuccess())
- return r;
-
- vkGetPhysicalDeviceFeatures(physical_devices[i], &available_features_);
- }
- if (!AreAllRequiredFeaturesSupported(available_features_,
- required_vulkan_features)) {
- continue;
- }
-
- available_device_extensions_ =
- GetAvailableDeviceExtensions(physical_devices[i]);
- if (!AreAllExtensionsSupported(available_device_extensions_,
- required_extensions)) {
- continue;
+ if (selected_device > -1) {
+ uint32_t deviceID = static_cast<uint32_t>(selected_device);
+ if (deviceID >= count) {
+ return amber::Result("Unable to find Vulkan device with ID " +
+ std::to_string(deviceID));
}
-
- vulkan_queue_family_index_ = ChooseQueueFamilyIndex(physical_devices[i]);
- if (vulkan_queue_family_index_ != std::numeric_limits<uint32_t>::max()) {
+ amber::Result r = CheckVulkanPhysicalDeviceRequirements(
+ physical_devices[deviceID], required_features, required_extensions);
+ if (!r.IsSuccess())
+ return r;
+ vulkan_physical_device_ = physical_devices[deviceID];
+ return {};
+ } else {
+ for (uint32_t i = 0; i < count; ++i) {
+ amber::Result r = CheckVulkanPhysicalDeviceRequirements(
+ physical_devices[i], required_features, required_extensions);
+ if (!r.IsSuccess())
+ continue;
vulkan_physical_device_ = physical_devices[i];
return {};
}
@@ -909,6 +937,7 @@ void ConfigHelperVulkan::DumpPhysicalDeviceInfo() {
amber::Result ConfigHelperVulkan::CreateConfig(
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
@@ -927,7 +956,8 @@ amber::Result ConfigHelperVulkan::CreateConfig(
return r;
}
- r = ChooseVulkanPhysicalDevice(required_features, required_device_extensions);
+ r = ChooseVulkanPhysicalDevice(required_features, required_device_extensions,
+ selected_device);
if (!r.IsSuccess())
return r;
diff --git a/samples/config_helper_vulkan.h b/samples/config_helper_vulkan.h
index d0d312d..6c19fbc 100644
--- a/samples/config_helper_vulkan.h
+++ b/samples/config_helper_vulkan.h
@@ -44,6 +44,7 @@ class ConfigHelperVulkan : public ConfigHelperImpl {
amber::Result CreateConfig(
uint32_t engine_major,
uint32_t engine_minor,
+ int32_t selected_device,
const std::vector<std::string>& required_features,
const std::vector<std::string>& required_instance_extensions,
const std::vector<std::string>& required_device_extensions,
@@ -63,11 +64,19 @@ class ConfigHelperVulkan : public ConfigHelperImpl {
/// via debugCallback() function in config_helper_vulkan.cc.
amber::Result CreateDebugReportCallback();
+ /// Check if |physical_device| supports both
+ /// |required_features| and |required_extensions|.
+ amber::Result CheckVulkanPhysicalDeviceRequirements(
+ const VkPhysicalDevice physical_device,
+ const std::vector<std::string>& required_features,
+ const std::vector<std::string>& required_extensions);
+
/// Choose Vulkan physical device that supports both
/// |required_features| and |required_extensions|.
amber::Result ChooseVulkanPhysicalDevice(
const std::vector<std::string>& required_features,
- const std::vector<std::string>& required_extensions);
+ const std::vector<std::string>& required_extensions,
+ const int32_t selected_device);
/// Create Vulkan logical device that enables both
/// |required_features| and |required_extensions|.