Home | History | Annotate | Download | only in smoke
      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;
     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 
     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);
    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