blob: 44bd4812c4244f30718a5ef5f3453ac38dadcdc5 [file] [log] [blame]
Tony Barbour2f18b292016-02-25 15:44:10 -07001/*
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
39class Meshes;
40
41class Smoke : public Game {
42public:
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
57private:
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