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 SMOKE_H
     24 #define SMOKE_H
     25 
     26 #include <condition_variable>
     27 #include <memory>
     28 #include <mutex>
     29 #include <string>
     30 #include <thread>
     31 #include <vector>
     32 
     33 #include <vulkan/vulkan.h>
     34 #include <glm/glm.hpp>
     35 
     36 #include "Simulation.h"
     37 #include "Game.h"
     38 
     39 class Meshes;
     40 
     41 class Smoke : public Game {
     42 public:
     43     Smoke(const std::vector<std::string> &args);
     44     ~Smoke();
     45 
     46     void attach_shell(Shell &sh);
     47     void detach_shell();
     48 
     49     void attach_swapchain();
     50     void detach_swapchain();
     51 
     52     void on_key(Key key);
     53     void on_tick();
     54 
     55     void on_frame(float frame_pred);
     56 
     57 private:
     58     class Worker {
     59     public:
     60         Worker(Smoke &smoke, int index, int object_begin, int object_end);
     61 
     62         void start();
     63         void stop();
     64         void update_simulation();
     65         void draw_objects(VkFramebuffer fb);
     66         void wait_idle();
     67 
     68         Smoke &smoke_;
     69 
     70         const int index_;
     71         const int object_begin_;
     72         const int object_end_;
     73 
     74         const float tick_interval_;
     75 
     76         VkFramebuffer fb_;
     77 
     78     private:
     79         enum State {
     80             INIT,
     81             IDLE,
     82             STEP,
     83             DRAW,
     84         };
     85 
     86         void update_loop();
     87 
     88         static void thread_loop(Worker *worker) { worker->update_loop(); }
     89 
     90         std::thread thread_;
     91         std::mutex mutex_;
     92         std::condition_variable state_cv_;
     93         State state_;
     94     };
     95 
     96     struct Camera {
     97         glm::vec3 eye_pos;
     98         glm::mat4 view_projection;
     99 
    100         Camera(float eye) : eye_pos(eye) {}
    101     };
    102 
    103     struct FrameData {
    104         // signaled when this struct is ready for reuse
    105         VkFence fence;
    106 
    107         VkCommandBuffer primary_cmd;
    108         std::vector<VkCommandBuffer> worker_cmds;
    109 
    110         VkBuffer buf;
    111         uint8_t *base;
    112         VkDescriptorSet desc_set;
    113     };
    114 
    115     // called by the constructor
    116     void init_workers();
    117 
    118     bool multithread_;
    119     bool use_push_constants_;
    120 
    121     // called mostly by on_key
    122     void update_camera();
    123 
    124     bool sim_paused_;
    125     Simulation sim_;
    126     Camera camera_;
    127 
    128     std::vector<std::unique_ptr<Worker>> workers_;
    129 
    130     // called by attach_shell
    131     void create_render_pass();
    132     void create_shader_modules();
    133     void create_descriptor_set_layout();
    134     void create_pipeline_layout();
    135     void create_pipeline();
    136 
    137     void create_frame_data(int count);
    138     void destroy_frame_data();
    139     void create_fences();
    140     void create_command_buffers();
    141     void create_buffers();
    142     void create_buffer_memory();
    143     void create_descriptor_sets();
    144 
    145     VkPhysicalDevice physical_dev_;
    146     VkDevice dev_;
    147     VkQueue queue_;
    148     uint32_t queue_family_;
    149     VkFormat format_;
    150 
    151     VkPhysicalDeviceProperties physical_dev_props_;
    152     std::vector<VkMemoryPropertyFlags> mem_flags_;
    153 
    154     const Meshes *meshes_;
    155 
    156     VkRenderPass render_pass_;
    157     VkShaderModule vs_;
    158     VkShaderModule fs_;
    159     VkDescriptorSetLayout desc_set_layout_;
    160     VkPipelineLayout pipeline_layout_;
    161     VkPipeline pipeline_;
    162 
    163     VkCommandPool primary_cmd_pool_;
    164     std::vector<VkCommandPool> worker_cmd_pools_;
    165     VkDescriptorPool desc_pool_;
    166     VkDeviceMemory frame_data_mem_;
    167     std::vector<FrameData> frame_data_;
    168     int frame_data_index_;
    169 
    170     VkClearValue render_pass_clear_value_;
    171     VkRenderPassBeginInfo render_pass_begin_info_;
    172 
    173     VkCommandBufferBeginInfo primary_cmd_begin_info_;
    174     VkPipelineStageFlags primary_cmd_submit_wait_stages_;
    175     VkSubmitInfo primary_cmd_submit_info_;
    176 
    177     // called by attach_swapchain
    178     void prepare_viewport(const VkExtent2D &extent);
    179     void prepare_framebuffers(VkSwapchainKHR swapchain);
    180 
    181     VkExtent2D extent_;
    182     VkViewport viewport_;
    183     VkRect2D scissor_;
    184 
    185     std::vector<VkImage> images_;
    186     std::vector<VkImageView> image_views_;
    187     std::vector<VkFramebuffer> framebuffers_;
    188 
    189     // called by workers
    190     void update_simulation(const Worker &worker);
    191     void draw_object(const Simulation::Object &obj, FrameData &data, VkCommandBuffer cmd) const;
    192     void draw_objects(Worker &worker);
    193 };
    194 
    195 #endif // HOLOGRAM_H
    196