• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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