| /* |
| * Copyright (C) 2016 Google, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef SMOKE_H |
| #define SMOKE_H |
| |
| #include <condition_variable> |
| #include <memory> |
| #include <mutex> |
| #include <string> |
| #include <thread> |
| #include <vector> |
| |
| #include <vulkan/vulkan.h> |
| #include <glm/glm.hpp> |
| |
| #include "Simulation.h" |
| #include "Game.h" |
| |
| class Meshes; |
| |
| class Smoke : public Game { |
| public: |
| Smoke(const std::vector<std::string> &args); |
| ~Smoke(); |
| |
| void attach_shell(Shell &sh); |
| void detach_shell(); |
| |
| void attach_swapchain(); |
| void detach_swapchain(); |
| |
| void on_key(Key key); |
| void on_tick(); |
| |
| void on_frame(float frame_pred); |
| |
| private: |
| class Worker { |
| public: |
| Worker(Smoke &smoke, int index, int object_begin, int object_end); |
| |
| void start(); |
| void stop(); |
| void update_simulation(); |
| void draw_objects(VkFramebuffer fb); |
| void wait_idle(); |
| |
| Smoke &smoke_; |
| |
| const int index_; |
| const int object_begin_; |
| const int object_end_; |
| |
| const float tick_interval_; |
| |
| VkFramebuffer fb_; |
| |
| private: |
| enum State { |
| INIT, |
| IDLE, |
| STEP, |
| DRAW, |
| }; |
| |
| void update_loop(); |
| |
| static void thread_loop(Worker *worker) { worker->update_loop(); } |
| |
| std::thread thread_; |
| std::mutex mutex_; |
| std::condition_variable state_cv_; |
| State state_; |
| }; |
| |
| struct Camera { |
| glm::vec3 eye_pos; |
| glm::mat4 view_projection; |
| |
| Camera(float eye) : eye_pos(eye) {} |
| }; |
| |
| struct FrameData { |
| // signaled when this struct is ready for reuse |
| VkFence fence; |
| |
| VkCommandBuffer primary_cmd; |
| std::vector<VkCommandBuffer> worker_cmds; |
| |
| VkBuffer buf; |
| uint8_t *base; |
| VkDescriptorSet desc_set; |
| }; |
| |
| // called by the constructor |
| void init_workers(); |
| |
| bool multithread_; |
| bool use_push_constants_; |
| |
| // called mostly by on_key |
| void update_camera(); |
| |
| bool sim_paused_; |
| Simulation sim_; |
| Camera camera_; |
| |
| std::vector<std::unique_ptr<Worker>> workers_; |
| |
| // called by attach_shell |
| void create_render_pass(); |
| void create_shader_modules(); |
| void create_descriptor_set_layout(); |
| void create_pipeline_layout(); |
| void create_pipeline(); |
| |
| void create_frame_data(int count); |
| void destroy_frame_data(); |
| void create_fences(); |
| void create_command_buffers(); |
| void create_buffers(); |
| void create_buffer_memory(); |
| void create_descriptor_sets(); |
| |
| VkPhysicalDevice physical_dev_; |
| VkDevice dev_; |
| VkQueue queue_; |
| uint32_t queue_family_; |
| VkFormat format_; |
| |
| VkPhysicalDeviceProperties physical_dev_props_; |
| std::vector<VkMemoryPropertyFlags> mem_flags_; |
| |
| const Meshes *meshes_; |
| |
| VkRenderPass render_pass_; |
| VkShaderModule vs_; |
| VkShaderModule fs_; |
| VkDescriptorSetLayout desc_set_layout_; |
| VkPipelineLayout pipeline_layout_; |
| VkPipeline pipeline_; |
| |
| VkCommandPool primary_cmd_pool_; |
| std::vector<VkCommandPool> worker_cmd_pools_; |
| VkDescriptorPool desc_pool_; |
| VkDeviceMemory frame_data_mem_; |
| VkDeviceSize frame_data_aligned_size_; |
| std::vector<FrameData> frame_data_; |
| int frame_data_index_; |
| |
| VkClearValue render_pass_clear_value_; |
| VkRenderPassBeginInfo render_pass_begin_info_; |
| |
| VkCommandBufferBeginInfo primary_cmd_begin_info_; |
| VkPipelineStageFlags primary_cmd_submit_wait_stages_; |
| VkSubmitInfo primary_cmd_submit_info_; |
| |
| // called by attach_swapchain |
| void prepare_viewport(const VkExtent2D &extent); |
| void prepare_framebuffers(VkSwapchainKHR swapchain); |
| |
| VkExtent2D extent_; |
| VkViewport viewport_; |
| VkRect2D scissor_; |
| |
| std::vector<VkImage> images_; |
| std::vector<VkImageView> image_views_; |
| std::vector<VkFramebuffer> framebuffers_; |
| |
| // called by workers |
| void update_simulation(const Worker &worker); |
| void draw_object(const Simulation::Object &obj, FrameData &data, VkCommandBuffer cmd) const; |
| void draw_objects(Worker &worker); |
| }; |
| |
| #endif // HOLOGRAM_H |