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 show_version_info,
53       std::unique_ptr<amber::EngineConfig>* config) override;
54 
55  private:
56   /// Create Vulkan instance.
57   amber::Result CreateVulkanInstance(
58       uint32_t engine_major,
59       uint32_t engine_minor,
60       std::vector<std::string> required_instance_extensions,
61       bool disable_validation_layer);
62 
63   /// Create |vulkan_callback_| that reports validation layer errors
64   /// via debugCallback() function in config_helper_vulkan.cc.
65   amber::Result CreateDebugReportCallback();
66 
67   /// Check if |physical_device| supports both
68   /// |required_features| and |required_extensions|.
69   amber::Result CheckVulkanPhysicalDeviceRequirements(
70       const VkPhysicalDevice physical_device,
71       const std::vector<std::string>& required_features,
72       const std::vector<std::string>& required_extensions);
73 
74   /// Choose Vulkan physical device that supports both
75   /// |required_features| and |required_extensions|.
76   amber::Result ChooseVulkanPhysicalDevice(
77       const std::vector<std::string>& required_features,
78       const std::vector<std::string>& required_extensions,
79       const int32_t selected_device);
80 
81   /// Create Vulkan logical device that enables both
82   /// |required_features| and |required_extensions|.
83   amber::Result CreateVulkanDevice(
84       const std::vector<std::string>& required_features,
85       const std::vector<std::string>& required_extensions);
86 
87   /// Sets up the device creation to use VkPhysicalDeviceFeatures.
88   amber::Result CreateDeviceWithFeatures1(
89       const std::vector<std::string>& required_features,
90       VkDeviceCreateInfo* info);
91   /// Sets up the device creation to use VkPhysicalDeviceFeatures2KHR.
92   amber::Result CreateDeviceWithFeatures2(
93       const std::vector<std::string>& required_features,
94       VkDeviceCreateInfo* info);
95 
96   /// Creates the physical device given the device |info|.
97   amber::Result DoCreateDevice(VkDeviceCreateInfo* info);
98 
99   /// Writes information related to the vulkan instance to stdout.
100   void DumpPhysicalDeviceInfo();
101 
102   VkInstance vulkan_instance_ = VK_NULL_HANDLE;
103   VkDebugReportCallbackEXT vulkan_callback_ = VK_NULL_HANDLE;
104   VkPhysicalDevice vulkan_physical_device_ = VK_NULL_HANDLE;
105   std::vector<std::string> available_instance_extensions_;
106   std::vector<std::string> available_device_extensions_;
107   uint32_t vulkan_queue_family_index_ = std::numeric_limits<uint32_t>::max();
108   VkQueue vulkan_queue_ = VK_NULL_HANDLE;
109   VkDevice vulkan_device_ = VK_NULL_HANDLE;
110 
111   bool supports_get_physical_device_properties2_ = false;
112   bool supports_shader_float16_int8_ = false;
113   bool supports_shader_8bit_storage_ = false;
114   bool supports_shader_16bit_storage_ = false;
115   bool supports_subgroup_size_control_ = false;
116   bool supports_shader_subgroup_extended_types_ = false;
117   VkPhysicalDeviceFeatures available_features_;
118   VkPhysicalDeviceFeatures2KHR available_features2_;
119   VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers_feature_;
120   VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_feature_;
121   VkPhysicalDevice8BitStorageFeaturesKHR storage_8bit_feature_;
122   VkPhysicalDevice16BitStorageFeaturesKHR storage_16bit_feature_;
123   VkPhysicalDeviceSubgroupSizeControlFeaturesEXT subgroup_size_control_feature_;
124   VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
125       shader_subgroup_extended_types_feature_;
126 };
127 
128 }  // namespace sample
129 
130 #pragma clang diagnostic pop
131 
132 #endif  // SAMPLES_CONFIG_HELPER_VULKAN_H_
133