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; ~Shell()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 }; context()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, VkDebugReportObjectTypeEXT obj_type, uint64_t object, size_t location, 106 int32_t msg_code, const char *layer_prefix, const char *msg); debug_report_callback(VkDebugReportFlagsEXT flags,VkDebugReportObjectTypeEXT obj_type,uint64_t object,size_t location,int32_t msg_code,const char * layer_prefix,const char * msg,void * user_data)107 static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report_callback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT obj_type, 108 uint64_t object, size_t location, int32_t msg_code, 109 const char *layer_prefix, const char *msg, void *user_data) { 110 Shell *shell = reinterpret_cast<Shell *>(user_data); 111 return shell->debug_report_callback(flags, obj_type, object, location, msg_code, layer_prefix, msg); 112 } 113 114 void assert_all_instance_layers() const; 115 void assert_all_instance_extensions() const; 116 117 bool has_all_device_layers(VkPhysicalDevice phy) const; 118 bool has_all_device_extensions(VkPhysicalDevice phy) const; 119 120 // called by init_vk 121 virtual PFN_vkGetInstanceProcAddr load_vk() = 0; 122 virtual bool can_present(VkPhysicalDevice phy, uint32_t queue_family) = 0; 123 void init_instance(); 124 void init_debug_report(); 125 void init_physical_dev(); 126 127 // called by create_context 128 void create_dev(); 129 void create_back_buffers(); 130 void destroy_back_buffers(); 131 virtual VkSurfaceKHR create_surface(VkInstance instance) = 0; 132 void create_swapchain(); 133 void destroy_swapchain(); 134 135 void fake_present(); 136 137 Context ctx_; 138 139 const float game_tick_; 140 float game_time_; 141 }; 142 143 #endif // SHELL_H 144