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 thread_loop(Worker * worker)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 CameraCamera94 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 std::vector<FrameData> frame_data_; 162 int frame_data_index_; 163 164 VkClearValue render_pass_clear_value_; 165 VkRenderPassBeginInfo render_pass_begin_info_; 166 167 VkCommandBufferBeginInfo primary_cmd_begin_info_; 168 VkPipelineStageFlags primary_cmd_submit_wait_stages_; 169 VkSubmitInfo primary_cmd_submit_info_; 170 171 // called by attach_swapchain 172 void prepare_viewport(const VkExtent2D &extent); 173 void prepare_framebuffers(VkSwapchainKHR swapchain); 174 175 VkExtent2D extent_; 176 VkViewport viewport_; 177 VkRect2D scissor_; 178 179 std::vector<VkImage> images_; 180 std::vector<VkImageView> image_views_; 181 std::vector<VkFramebuffer> framebuffers_; 182 183 // called by workers 184 void update_simulation(const Worker &worker); 185 void draw_object(const Simulation::Object &obj, FrameData &data, VkCommandBuffer cmd) const; 186 void draw_objects(Worker &worker); 187 }; 188 189 #endif // HOLOGRAM_H 190