• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,
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);
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)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