blob: 822d1419acab92c627623dc9acb0d103d7e24e7c [file] [log] [blame]
Tony Barbour2f18b292016-02-25 15:44:10 -07001/*
2 * Copyright (C) 2016 Google, Inc.
3 *
Jon Ashburn43b53e82016-04-19 11:30:31 -06004 * 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
Tony Barbour2f18b292016-02-25 15:44:10 -07007 *
Jon Ashburn43b53e82016-04-19 11:30:31 -06008 * http://www.apache.org/licenses/LICENSE-2.0
Tony Barbour2f18b292016-02-25 15:44:10 -07009 *
Jon Ashburn43b53e82016-04-19 11:30:31 -060010 * 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.
Tony Barbour2f18b292016-02-25 15:44:10 -070015 */
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
33class Meshes;
34
35class Smoke : public Game {
Mark Lobodzinskibc9caa52017-01-26 12:16:30 -070036 public:
Tony Barbour2f18b292016-02-25 15:44:10 -070037 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
Mark Lobodzinskibc9caa52017-01-26 12:16:30 -070051 private:
Tony Barbour2f18b292016-02-25 15:44:10 -070052 class Worker {
Mark Lobodzinskibc9caa52017-01-26 12:16:30 -070053 public:
Tony Barbour2f18b292016-02-25 15:44:10 -070054 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
Mark Lobodzinskibc9caa52017-01-26 12:16:30 -070072 private:
Tony Barbour2f18b292016-02-25 15:44:10 -070073 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_;
joey-lunarg1c889642017-01-10 15:55:49 -0700161 VkDeviceSize frame_data_aligned_size_;
Tony Barbour2f18b292016-02-25 15:44:10 -0700162 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