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