1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SAMPLES_CONFIG_HELPER_VULKAN_H_
16 #define SAMPLES_CONFIG_HELPER_VULKAN_H_
17 
18 #include <vulkan/vulkan.h>
19 
20 #include <limits>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include "amber/amber.h"
26 #include "amber/amber_vulkan.h"
27 #include "samples/config_helper.h"
28 
29 #pragma clang diagnostic push
30 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
31 
32 namespace sample {
33 
34 /// Child class of ConfigHelperImpl for Vulkan.
35 class ConfigHelperVulkan : public ConfigHelperImpl {
36  public:
37   ConfigHelperVulkan();
38   ~ConfigHelperVulkan() override;
39 
40   /// Create Vulkan instance and device and return them as
41   /// amber::VulkanEngineConfig. Required Vulkan device features and
42   /// extensions are given in |required_features| and
43   /// |required_extensions|, respectively.
44   amber::Result CreateConfig(
45       uint32_t engine_major,
46       uint32_t engine_minor,
47       int32_t selected_device,
48       const std::vector<std::string>& required_features,
49       const std::vector<std::string>& required_instance_extensions,
50       const std::vector<std::string>& required_device_extensions,
51       bool disable_validation_layer,
52       bool enable_pipeline_runtime_layer,
53       bool show_version_info,
54       std::unique_ptr<amber::EngineConfig>* config) override;
55 
56  private:
57   /// Create Vulkan instance.
58   amber::Result CreateVulkanInstance(
59       uint32_t engine_major,
60       uint32_t engine_minor,
61       std::vector<std::string> required_instance_extensions,
62       bool disable_validation_layer,
63       bool enable_pipeline_runtime_layer);
64 
65   /// Create |vulkan_callback_| that reports validation layer errors
66   /// via debugCallback() function in config_helper_vulkan.cc.
67   amber::Result CreateDebugReportCallback();
68 
69   /// Check if |physical_device| supports both
70   /// |required_features| and |required_extensions|.
71   amber::Result CheckVulkanPhysicalDeviceRequirements(
72       const VkPhysicalDevice physical_device,
73       const std::vector<std::string>& required_features,
74       const std::vector<std::string>& required_extensions);
75 
76   /// Choose Vulkan physical device that supports both
77   /// |required_features| and |required_extensions|.
78   amber::Result ChooseVulkanPhysicalDevice(
79       const std::vector<std::string>& required_features,
80       const std::vector<std::string>& required_extensions,
81       const int32_t selected_device);
82 
83   /// Create Vulkan logical device that enables both
84   /// |required_features| and |required_extensions|.
85   amber::Result CreateVulkanDevice(
86       const std::vector<std::string>& required_features,
87       const std::vector<std::string>& required_extensions);
88 
89   /// Sets up the device creation to use VkPhysicalDeviceFeatures.
90   amber::Result CreateDeviceWithFeatures1(
91       const std::vector<std::string>& required_features,
92       VkDeviceCreateInfo* info);
93   /// Sets up the device creation to use VkPhysicalDeviceFeatures2KHR.
94   amber::Result CreateDeviceWithFeatures2(
95       const std::vector<std::string>& required_features,
96       VkDeviceCreateInfo* info);
97 
98   /// Creates the physical device given the device |info|.
99   amber::Result DoCreateDevice(VkDeviceCreateInfo* info);
100 
101   /// Writes information related to the vulkan instance to stdout.
102   void DumpPhysicalDeviceInfo();
103 
104   VkInstance vulkan_instance_ = VK_NULL_HANDLE;
105   VkDebugReportCallbackEXT vulkan_callback_ = VK_NULL_HANDLE;
106   VkPhysicalDevice vulkan_physical_device_ = VK_NULL_HANDLE;
107   std::vector<std::string> available_instance_extensions_;
108   std::vector<std::string> available_device_extensions_;
109   uint32_t vulkan_queue_family_index_ = std::numeric_limits<uint32_t>::max();
110   VkQueue vulkan_queue_ = VK_NULL_HANDLE;
111   VkDevice vulkan_device_ = VK_NULL_HANDLE;
112 
113   bool supports_get_physical_device_properties2_ = false;
114   bool supports_shader_float16_int8_ = false;
115   bool supports_shader_8bit_storage_ = false;
116   bool supports_shader_16bit_storage_ = false;
117   bool supports_subgroup_size_control_ = false;
118   bool supports_shader_subgroup_extended_types_ = false;
119   VkPhysicalDeviceFeatures available_features_;
120   VkPhysicalDeviceFeatures2KHR available_features2_;
121   VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers_feature_;
122   VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_feature_;
123   VkPhysicalDevice8BitStorageFeaturesKHR storage_8bit_feature_;
124   VkPhysicalDevice16BitStorageFeaturesKHR storage_16bit_feature_;
125   VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_size_control_feature_;
126   VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
127       shader_subgroup_extended_types_feature_;
128 };
129 
130 }  // namespace sample
131 
132 #pragma clang diagnostic pop
133 
134 #endif  // SAMPLES_CONFIG_HELPER_VULKAN_H_
135