• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
thread_loop(Worker * worker)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 
CameraCamera100         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