blob: 2aa0b6f48804ce3b31ceafc0a3fd979a7507496d [file] [log] [blame]
Tony Barbour2f18b292016-02-25 15:44:10 -07001/*
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
33class Game;
34
35class Shell {
36public:
37 Shell(const Shell &sh) = delete;
38 Shell &operator=(const Shell &sh) = delete;
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 };
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
86protected:
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
111private:
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);
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