• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 Google, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef SHELL_H
24 #define SHELL_H
25 
26 #include <queue>
27 #include <vector>
28 #include <stdexcept>
29 #include <vulkan/vulkan.h>
30 
31 #include "Game.h"
32 
33 class Game;
34 
35 class Shell {
36 public:
37     Shell(const Shell &sh) = delete;
38     Shell &operator=(const Shell &sh) = delete;
~Shell()39     virtual ~Shell() {}
40 
41     struct BackBuffer {
42         uint32_t image_index;
43 
44         VkSemaphore acquire_semaphore;
45         VkSemaphore render_semaphore;
46 
47         // signaled when this struct is ready for reuse
48         VkFence present_fence;
49     };
50 
51     struct Context {
52         VkInstance instance;
53         VkDebugReportCallbackEXT debug_report;
54 
55         VkPhysicalDevice physical_dev;
56         uint32_t game_queue_family;
57         uint32_t present_queue_family;
58 
59         VkDevice dev;
60         VkQueue game_queue;
61         VkQueue present_queue;
62 
63         std::queue<BackBuffer> back_buffers;
64 
65         VkSurfaceKHR surface;
66         VkSurfaceFormatKHR format;
67 
68         VkSwapchainKHR swapchain;
69         VkExtent2D extent;
70 
71         BackBuffer acquired_back_buffer;
72     };
context()73     const Context &context() const { return ctx_; }
74 
75     enum LogPriority {
76         LOG_DEBUG,
77         LOG_INFO,
78         LOG_WARN,
79         LOG_ERR,
80     };
81     virtual void log(LogPriority priority, const char *msg);
82 
83     virtual void run() = 0;
84     virtual void quit() = 0;
85 
86 protected:
87     Shell(Game &game);
88 
89     void init_vk();
90     void cleanup_vk();
91 
92     void create_context();
93     void destroy_context();
94 
95     void resize_swapchain(uint32_t width_hint, uint32_t height_hint);
96 
97     void add_game_time(float time);
98 
99     void acquire_back_buffer();
100     void present_back_buffer();
101 
102     Game &game_;
103     const Game::Settings &settings_;
104 
105     std::vector<const char *> instance_layers_;
106     std::vector<const char *> instance_extensions_;
107 
108     std::vector<const char *> device_layers_;
109     std::vector<const char *> device_extensions_;
110 
111 private:
112     bool debug_report_callback(VkDebugReportFlagsEXT flags,
113                                VkDebugReportObjectTypeEXT obj_type,
114                                uint64_t object,
115                                size_t location,
116                                int32_t msg_code,
117                                const char *layer_prefix,
118                                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)119     static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report_callback(
120                                VkDebugReportFlagsEXT flags,
121                                VkDebugReportObjectTypeEXT obj_type,
122                                uint64_t object,
123                                size_t location,
124                                int32_t msg_code,
125                                const char *layer_prefix,
126                                const char *msg,
127                                void *user_data)
128     {
129         Shell *shell = reinterpret_cast<Shell *>(user_data);
130         return shell->debug_report_callback(flags, obj_type, object, location, msg_code, layer_prefix, msg);
131     }
132 
133     void assert_all_instance_layers() const;
134     void assert_all_instance_extensions() const;
135 
136     bool has_all_device_layers(VkPhysicalDevice phy) const;
137     bool has_all_device_extensions(VkPhysicalDevice phy) const;
138 
139     // called by init_vk
140     virtual PFN_vkGetInstanceProcAddr load_vk() = 0;
141     virtual bool can_present(VkPhysicalDevice phy, uint32_t queue_family) = 0;
142     void init_instance();
143     void init_debug_report();
144     void init_physical_dev();
145 
146     // called by create_context
147     void create_dev();
148     void create_back_buffers();
149     void destroy_back_buffers();
150     virtual VkSurfaceKHR create_surface(VkInstance instance) = 0;
151     void create_swapchain();
152     void destroy_swapchain();
153 
154     void fake_present();
155 
156     Context ctx_;
157 
158     const float game_tick_;
159     float game_time_;
160 };
161 
162 #endif // SHELL_H
163