1 /* 2 * Copyright (C) 2016 Google, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SHELL_H 18 #define SHELL_H 19 20 #include <queue> 21 #include <vector> 22 #include <stdexcept> 23 #include <vulkan/vulkan.h> 24 25 #include "Game.h" 26 27 class Game; 28 29 class Shell { 30 public: 31 Shell(const Shell &sh) = delete; 32 Shell &operator=(const Shell &sh) = delete; 33 virtual ~Shell() {} 34 35 struct BackBuffer { 36 uint32_t image_index; 37 38 VkSemaphore acquire_semaphore; 39 VkSemaphore render_semaphore; 40 41 // signaled when this struct is ready for reuse 42 VkFence present_fence; 43 }; 44 45 struct Context { 46 VkInstance instance; 47 VkDebugReportCallbackEXT debug_report; 48 49 VkPhysicalDevice physical_dev; 50 uint32_t game_queue_family; 51 uint32_t present_queue_family; 52 53 VkDevice dev; 54 VkQueue game_queue; 55 VkQueue present_queue; 56 57 std::queue<BackBuffer> back_buffers; 58 59 VkSurfaceKHR surface; 60 VkSurfaceFormatKHR format; 61 62 VkSwapchainKHR swapchain; 63 VkExtent2D extent; 64 65 BackBuffer acquired_back_buffer; 66 }; 67 const Context &context() const { return ctx_; } 68 69 enum LogPriority { 70 LOG_DEBUG, 71 LOG_INFO, 72 LOG_WARN, 73 LOG_ERR, 74 }; 75 virtual void log(LogPriority priority, const char *msg); 76 77 virtual void run() = 0; 78 virtual void quit() = 0; 79 80 protected: 81 Shell(Game &game); 82 83 void init_vk(); 84 void cleanup_vk(); 85 86 void create_context(); 87 void destroy_context(); 88 89 void resize_swapchain(uint32_t width_hint, uint32_t height_hint); 90 91 void add_game_time(float time); 92 93 void acquire_back_buffer(); 94 void present_back_buffer(); 95 96 Game &game_; 97 const Game::Settings &settings_; 98 99 std::vector<const char *> instance_layers_; 100 std::vector<const char *> instance_extensions_; 101 102 std::vector<const char *> device_extensions_; 103 104 private: 105 bool debug_report_callback(VkDebugReportFlagsEXT flags, 106 VkDebugReportObjectTypeEXT obj_type, 107 uint64_t object, 108 size_t location, 109 int32_t msg_code, 110 const char *layer_prefix, 111 const char *msg); 112 static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report_callback( 113 VkDebugReportFlagsEXT flags, 114 VkDebugReportObjectTypeEXT obj_type, 115 uint64_t object, 116 size_t location, 117 int32_t msg_code, 118 const char *layer_prefix, 119 const char *msg, 120 void *user_data) 121 { 122 Shell *shell = reinterpret_cast<Shell *>(user_data); 123 return shell->debug_report_callback(flags, obj_type, object, location, msg_code, layer_prefix, msg); 124 } 125 126 void assert_all_instance_layers() const; 127 void assert_all_instance_extensions() const; 128 129 bool has_all_device_layers(VkPhysicalDevice phy) const; 130 bool has_all_device_extensions(VkPhysicalDevice phy) const; 131 132 // called by init_vk 133 virtual PFN_vkGetInstanceProcAddr load_vk() = 0; 134 virtual bool can_present(VkPhysicalDevice phy, uint32_t queue_family) = 0; 135 void init_instance(); 136 void init_debug_report(); 137 void init_physical_dev(); 138 139 // called by create_context 140 void create_dev(); 141 void create_back_buffers(); 142 void destroy_back_buffers(); 143 virtual VkSurfaceKHR create_surface(VkInstance instance) = 0; 144 void create_swapchain(); 145 void destroy_swapchain(); 146 147 void fake_present(); 148 149 Context ctx_; 150 151 const float game_tick_; 152 float game_time_; 153 }; 154 155 #endif // SHELL_H 156